From 40e4b160dfd27c0fd0bda82f43f92e96caffcac3 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Tue, 10 Oct 2023 15:43:37 +0200 Subject: [PATCH 01/28] sync with left over changes --- src/lib/include/paradiso/globals.hpp | 1 + src/lib/include/paradiso/matrixbase.hpp | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib/include/paradiso/globals.hpp b/src/lib/include/paradiso/globals.hpp index 2927821..3c126ed 100644 --- a/src/lib/include/paradiso/globals.hpp +++ b/src/lib/include/paradiso/globals.hpp @@ -37,6 +37,7 @@ #include #include +#include diff --git a/src/lib/include/paradiso/matrixbase.hpp b/src/lib/include/paradiso/matrixbase.hpp index 5e77268..491102b 100644 --- a/src/lib/include/paradiso/matrixbase.hpp +++ b/src/lib/include/paradiso/matrixbase.hpp @@ -25,8 +25,6 @@ #include -#include - namespace paradiso { template struct MatrixBase { From 5e6630a92dde6c29c5e34649be829599a7874cf0 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Tue, 10 Oct 2023 17:59:48 +0200 Subject: [PATCH 02/28] refactored example by Robin --- README.de.md | 3 +- README.md | 3 +- examples/CMakeLists.txt | 2 +- examples/flappy_bird/CMakeLists.txt | 11 -- examples/flappy_bird/image_loader.cpp | 72 --------- examples/flappy_bird/lib/image_loader.hpp | 24 --- examples/quickwings/CMakeLists.txt | 20 +++ .../assets/background-day.png | Bin .../assets/base.png | Bin .../assets/pipe-green.png | Bin .../assets/yellowbird-downflap.png | Bin .../assets/yellowbird-midflap.png | Bin .../assets/yellowbird-upflap.png | Bin .../quickwings.cpp} | 35 +++-- src/lib/CMakeLists.txt | 4 + src/lib/include/paradiso/bitmap_io.hpp | 56 +++++++ src/lib/src/bitmap_io.cpp | 141 ++++++++++++++++++ .../lib/src/vendor/stb}/stb_image.h | 0 18 files changed, 247 insertions(+), 124 deletions(-) delete mode 100644 examples/flappy_bird/CMakeLists.txt delete mode 100644 examples/flappy_bird/image_loader.cpp delete mode 100644 examples/flappy_bird/lib/image_loader.hpp create mode 100644 examples/quickwings/CMakeLists.txt rename examples/{flappy_bird => quickwings}/assets/background-day.png (100%) rename examples/{flappy_bird => quickwings}/assets/base.png (100%) rename examples/{flappy_bird => quickwings}/assets/pipe-green.png (100%) rename examples/{flappy_bird => quickwings}/assets/yellowbird-downflap.png (100%) rename examples/{flappy_bird => quickwings}/assets/yellowbird-midflap.png (100%) rename examples/{flappy_bird => quickwings}/assets/yellowbird-upflap.png (100%) rename examples/{flappy_bird/flappy_bird.cpp => quickwings/quickwings.cpp} (90%) create mode 100644 src/lib/include/paradiso/bitmap_io.hpp create mode 100644 src/lib/src/bitmap_io.cpp rename {examples/flappy_bird/lib => src/lib/src/vendor/stb}/stb_image.h (100%) diff --git a/README.de.md b/README.de.md index de42551..1b90222 100644 --- a/README.de.md +++ b/README.de.md @@ -25,4 +25,5 @@ ParadiSO wird mit den notwendigen Komponenten geliefert. Diese sollte jedoch hie ## Zuarbeiten -* [TimePlex](https://code.technotecture.net/Timeplex) \ No newline at end of file +* [Tim Gtzelmann](https://code.technotecture.net/Timeplex) +* [Robin Rottstdt](https://code.technotecture.net/robin_rottstaedt) \ No newline at end of file diff --git a/README.md b/README.md index 2117b39..6c3929a 100644 --- a/README.md +++ b/README.md @@ -25,4 +25,5 @@ ParadiSO comes with batteries included. However, it should be mentioned here: ## Contributors -* [TimePlex](https://code.technotecture.net/Timeplex) \ No newline at end of file +* [Tim Götzelmann](https://code.technotecture.net/Timeplex) +* [Robin Rottstädt](https://code.technotecture.net/robin_rottstaedt) \ No newline at end of file diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f51da6f..9d4c49a 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,3 +1,3 @@ add_subdirectory(simple) add_subdirectory(pong) -add_subdirectory(flappy_bird) \ No newline at end of file +add_subdirectory(quickwings) \ No newline at end of file diff --git a/examples/flappy_bird/CMakeLists.txt b/examples/flappy_bird/CMakeLists.txt deleted file mode 100644 index 5a15e09..0000000 --- a/examples/flappy_bird/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -file(GLOB_RECURSE flappy_bird_src "*.cpp") -file(GLOB_RECURSE flappy_bird_lib "lib/*.hpp" "lib/*.h") -file(GLOB_RECURSE flappy_bird_assets "assets/*") - -add_executable(flappy_bird ${flappy_bird_src} ${flappy_bird_lib}) -target_link_libraries(flappy_bird paradiso_core) - -add_custom_command(TARGET flappy_bird POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_SOURCE_DIR}/assets/ $/assets) - \ No newline at end of file diff --git a/examples/flappy_bird/image_loader.cpp b/examples/flappy_bird/image_loader.cpp deleted file mode 100644 index cbde797..0000000 --- a/examples/flappy_bird/image_loader.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include - -#include -#include -#include -#include - -// STB image loading -#define STB_IMAGE_IMPLEMENTATION -#include "lib/stb_image.h" - -#include "lib/image_loader.hpp" - -std::unordered_map image_loader::image_cache = - std::unordered_map(); - -paradiso::Bitmap image_loader::load(const std::string& filename) { - if (image_cache.find(filename) == image_cache.end()) { - std::string path = ASSET_PATH + filename; - std::cout << "Loading " << path << std::endl; - auto data = readBMP(path); - image_cache[filename] = data; - } - return image_cache[filename]; -} - -paradiso::Bitmap image_loader::readBMP(std::string& filename) { - // Load with stb_image - stbi_set_flip_vertically_on_load(true); // flip y axis for OpenGL - int width, height, channels; - unsigned char* image = - stbi_load(filename.c_str(), &width, &height, &channels, 4); - int size = width * height; - - if (!image) - throw std::runtime_error("Error loading image"); - - // Convert to Vector of RGBA - std::vector rgba = std::vector(size); - for (int i = 0; i < size; i++) { - // get rgba values - int pos = i * 4; - int r = image[pos + 0]; - int g = image[pos + 1]; - int b = image[pos + 2]; - int a = image[pos + 3]; - - // bug in from_rgba. it expects bgra, not rgba - auto val = paradiso::RGBA::from_rgba(b, g, r, a); - rgba[i] = val; - } - - // rotate image by 90 degrees CW - std::vector rotated = std::vector(size); - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - - int pos = y * width + x; - int pos_rotated = x * height + (height - y - 1); - rotated[pos_rotated] = rgba[pos]; - } - } - - // free image - stbi_image_free(image); - - return paradiso::Bitmap::from_data( - paradiso::Size{static_cast(height), - static_cast(width)}, - rotated); -} diff --git a/examples/flappy_bird/lib/image_loader.hpp b/examples/flappy_bird/lib/image_loader.hpp deleted file mode 100644 index 52e1847..0000000 --- a/examples/flappy_bird/lib/image_loader.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include - -#include -#include -#include - -class image_loader { - public: - /** - * @brief loads an Image from a file - * @param[in] filename path to file - * @return bitmap from file - */ - static paradiso::Bitmap load(const std::string& filename); - - private: - static inline const std::string ASSET_PATH = "assets/"; - - static std::unordered_map image_cache; - - static paradiso::Bitmap readBMP(std::string& filename); -}; \ No newline at end of file diff --git a/examples/quickwings/CMakeLists.txt b/examples/quickwings/CMakeLists.txt new file mode 100644 index 0000000..0b5ffe2 --- /dev/null +++ b/examples/quickwings/CMakeLists.txt @@ -0,0 +1,20 @@ +set(quickwings_srcs quickwings.cpp) +set(quickwings_assets + assets/background-day.png + assets/base.png + assets/pipe-green.png + assets/yellowbird-downflap.png + assets/yellowbird-midflap.png + assets/yellowbird-upflap.png + ) + +set_source_files_properties(${quickwings_assets} PROPERTIES HEADER_FILE_ONLY TRUE) + +add_executable(quickwings ${quickwings_srcs} ${quickwings_assets}) + +target_link_libraries(quickwings paradiso_core) + +add_custom_command(TARGET quickwings POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_SOURCE_DIR}/assets/ $/assets) + \ No newline at end of file diff --git a/examples/flappy_bird/assets/background-day.png b/examples/quickwings/assets/background-day.png similarity index 100% rename from examples/flappy_bird/assets/background-day.png rename to examples/quickwings/assets/background-day.png diff --git a/examples/flappy_bird/assets/base.png b/examples/quickwings/assets/base.png similarity index 100% rename from examples/flappy_bird/assets/base.png rename to examples/quickwings/assets/base.png diff --git a/examples/flappy_bird/assets/pipe-green.png b/examples/quickwings/assets/pipe-green.png similarity index 100% rename from examples/flappy_bird/assets/pipe-green.png rename to examples/quickwings/assets/pipe-green.png diff --git a/examples/flappy_bird/assets/yellowbird-downflap.png b/examples/quickwings/assets/yellowbird-downflap.png similarity index 100% rename from examples/flappy_bird/assets/yellowbird-downflap.png rename to examples/quickwings/assets/yellowbird-downflap.png diff --git a/examples/flappy_bird/assets/yellowbird-midflap.png b/examples/quickwings/assets/yellowbird-midflap.png similarity index 100% rename from examples/flappy_bird/assets/yellowbird-midflap.png rename to examples/quickwings/assets/yellowbird-midflap.png diff --git a/examples/flappy_bird/assets/yellowbird-upflap.png b/examples/quickwings/assets/yellowbird-upflap.png similarity index 100% rename from examples/flappy_bird/assets/yellowbird-upflap.png rename to examples/quickwings/assets/yellowbird-upflap.png diff --git a/examples/flappy_bird/flappy_bird.cpp b/examples/quickwings/quickwings.cpp similarity index 90% rename from examples/flappy_bird/flappy_bird.cpp rename to examples/quickwings/quickwings.cpp index 357bb5d..cd25735 100644 --- a/examples/flappy_bird/flappy_bird.cpp +++ b/examples/quickwings/quickwings.cpp @@ -1,11 +1,12 @@ /** * paradiso - Paradigmen der Softwareentwicklung * - * (c) Copyright 2023 Hartmut Seichter + * (c) Copyright 2023 Hartmut Seichter, Robin Rottstädt * */ #include +#include #include #include #include @@ -17,9 +18,10 @@ #include #include #include +#include #include -#include "lib/image_loader.hpp" +// #include "lib/image_loader.hpp" const int frame_rate = 60; @@ -33,7 +35,7 @@ struct Background { Background() { auto backgroundImage = - image_loader::load(std::string("background-day.png")); + paradiso::BitmapIO::get().load("background-day.png"); backgroundLeft = paradiso::Sprite{ .bitmap = backgroundImage, .pivot = paradiso::Vector2::make(0.0f, 0.0f), @@ -43,7 +45,7 @@ struct Background { .pivot = paradiso::Vector2::make(2.0f, 0.0f), .scale = paradiso::Vector2::make(1.01f, 1.0f)}; - auto grassImage = image_loader::load(std::string("base.png")); + auto grassImage = paradiso::BitmapIO::get().load("base.png"); grassLeft = paradiso::Sprite{ .bitmap = grassImage, .pivot = paradiso::Vector2::make(0.0f, -1.0f), @@ -77,7 +79,7 @@ struct Grass { paradiso::Sprite* scrolling[2] = {&grassLeft, &grassRight}; Grass() { - auto grassImage = image_loader::load(std::string("base.png")); + auto grassImage = paradiso::BitmapIO::get().load(std::string("base.png")); grassLeft = paradiso::Sprite{ .bitmap = grassImage, .pivot = paradiso::Vector2::make(0.0f, -0.9f), @@ -104,7 +106,7 @@ struct Grass { paradiso::Renderer renderer{}; }; -struct FlappyBird { +struct QuickWings { paradiso::Renderer renderer1{}; paradiso::Renderer renderer2{}; @@ -131,24 +133,24 @@ struct FlappyBird { float rotation = 0.0f; - FlappyBird() { + QuickWings() { float scaleh = 0.07f; float scalew = scaleh * 1.416666666666667f; birds = { paradiso::Sprite{ .bitmap = - image_loader::load(std::string("yellowbird-downflap.png")), + paradiso::BitmapIO::get().load("yellowbird-downflap.png"), .pivot = paradiso::Vector2::make(0.0f, 0.0f), .scale = paradiso::Vector2::make(scalew, scaleh)}, paradiso::Sprite{ .bitmap = - image_loader::load(std::string("yellowbird-midflap.png")), + paradiso::BitmapIO::get().load("yellowbird-midflap.png"), .pivot = paradiso::Vector2::make(0.0f, 0.0f), .scale = paradiso::Vector2::make(scalew, scaleh)}, paradiso::Sprite{ .bitmap = - image_loader::load(std::string("yellowbird-upflap.png")), + paradiso::BitmapIO::get().load("yellowbird-upflap.png"), .pivot = paradiso::Vector2::make(0.0f, 0.0f), .scale = paradiso::Vector2::make(scalew, scaleh)}}; } @@ -266,11 +268,16 @@ auto main() -> int { // nothing beats a classic look ctx.set_clearcolor(paradiso::RGBA::from_rgb(0x00, 0x00, 0x00)); + + // Asset loader bekommt den Pfad + + paradiso::BitmapIO::get().set_path("assets"); + // Load auto background = Background{}; auto grass = Grass{}; - auto flappyBird = FlappyBird{}; + auto quickwingsapp = QuickWings{}; // timer @@ -285,13 +292,13 @@ auto main() -> int { auto t1 = std::chrono::high_resolution_clock::now(); // Keyboard and state change - flappyBird.on_keyboard(w.keyboard_input()); - flappyBird.update(); + quickwingsapp.on_keyboard(w.keyboard_input()); + quickwingsapp.update(); // Draw background.draw(shader); grass.draw(shader); - flappyBird.draw(shader); + quickwingsapp.draw(shader); // wait for frame rate auto t2 = std::chrono::high_resolution_clock::now(); diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index d437135..cde0660 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -8,6 +8,7 @@ add_subdirectory(src/vendor/glad) add_subdirectory(src/vendor/glfw-3.3.8) set(paradiso_srcs + src/bitmap_io.cpp src/shader.cpp src/window.cpp src/renderer.cpp @@ -18,6 +19,7 @@ set(paradiso_srcs set(paradiso_incs include/paradiso/aabb.hpp include/paradiso/bitmap.hpp + include/paradiso/bitmap_io.hpp include/paradiso/geometry.hpp include/paradiso/sprite.hpp include/paradiso/shader.hpp @@ -35,6 +37,8 @@ target_include_directories( paradiso_core PUBLIC include + PRIVATE + src/vendor/stb ) target_link_libraries( diff --git a/src/lib/include/paradiso/bitmap_io.hpp b/src/lib/include/paradiso/bitmap_io.hpp new file mode 100644 index 0000000..0ed2cff --- /dev/null +++ b/src/lib/include/paradiso/bitmap_io.hpp @@ -0,0 +1,56 @@ +/* + * Copyright 2023 Hartmut Seichter + * + * 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. + * + */ +#ifndef PARADISO_BITMAP_IO_HPP +#define PARADISO_BITMAP_IO_HPP + +#include + +#include +#include + +namespace paradiso { + +struct BitmapIO { + + static BitmapIO& get(); + + Bitmap load(std::string_view filename, bool ignore_cache = false) const; + + void set_path(std::string_view path); + + std::string path() const; + + private: + + struct Impl; + std::unique_ptr impl_; + + BitmapIO(); + ~BitmapIO() = default; + BitmapIO(const BitmapIO&) = delete; + BitmapIO(BitmapIO&&) = delete; +}; + +} // namespace paradiso + +#endif \ No newline at end of file diff --git a/src/lib/src/bitmap_io.cpp b/src/lib/src/bitmap_io.cpp new file mode 100644 index 0000000..0afdb21 --- /dev/null +++ b/src/lib/src/bitmap_io.cpp @@ -0,0 +1,141 @@ +/* + * Copyright 2023 Hartmut Seichter + * + * 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. + * + */ + +// based on image_loader by Robin Rottstädt + +#include "paradiso/bitmap_io.hpp" +#include "paradiso/bitmap.hpp" + +#include + +// STB image loading +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +#include +#include + +namespace paradiso { + +struct BitmapIO::Impl { + + std::filesystem::path asset_path_ = {}; + + using BitmapCacheType = std::unordered_map; + + BitmapCacheType cache_; + + static Bitmap read(std::string_view filename) { + + // Load with stb_image + stbi_set_flip_vertically_on_load(true); // flip y axis for OpenGL + + int width{}, height{}, channels{}; + + auto stb_free = [](uint8_t* data) { stbi_image_free(data); }; + + if (std::unique_ptr image{ + stbi_load(filename.data(), &width, &height, &channels, 0)}; + image.get()) { + + int size = width * height; + + // Convert to Vector of RGBA + std::vector rgba = + std::vector(size); + for (int i = 0; i < size; i++) { + // get rgba values + int pos = i * 4; + int r = image.get()[pos + 0]; + int g = image.get()[pos + 1]; + int b = image.get()[pos + 2]; + int a = image.get()[pos + 3]; + + // bug in from_rgba. it expects bgra, not rgba + auto val = paradiso::RGBA::from_rgba(b, g, r, a); + rgba[i] = val; + } + + // rotate image by 90 degrees CW + std::vector rotated = + std::vector(size); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + + int pos = y * width + x; + int pos_rotated = x * height + (height - y - 1); + rotated[pos_rotated] = rgba[pos]; + } + } + + return paradiso::Bitmap::from_data( + paradiso::Size{static_cast(height), + static_cast(width)}, + rotated); + } else { + std::cerr << "cannot load " << filename << '\n'; + } + + return Bitmap(); // well, no exception ... + } + + Bitmap load(std::string_view filename) { + if (cache_.find(filename) == cache_.end()) { + + auto asset_filepath = asset_path_ / std::filesystem::path(filename); + + std::cout << "Loading " << asset_filepath << std::endl; + + // moving to C++23 this should be replaced with + // std::expected + auto data = read(asset_filepath.c_str()); + + cache_[filename] = data; + } + return cache_[filename.data()]; + } +}; + +BitmapIO::BitmapIO() : impl_{std::make_unique()} {} + +BitmapIO& BitmapIO::get() { + static BitmapIO instance; + return instance; +} + +Bitmap BitmapIO::load(std::string_view filename, bool ignore_cache) const { + return impl_->load(filename); +} + +void BitmapIO::set_path(std::string_view path) +{ + impl_->asset_path_ = path; +} + +std::string BitmapIO::path() const +{ + return impl_->asset_path_; +} + + +} // namespace paradiso \ No newline at end of file diff --git a/examples/flappy_bird/lib/stb_image.h b/src/lib/src/vendor/stb/stb_image.h similarity index 100% rename from examples/flappy_bird/lib/stb_image.h rename to src/lib/src/vendor/stb/stb_image.h From 97697d2d7aa9f714786db95b80a9a3c707d5cfc4 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Tue, 10 Oct 2023 18:05:38 +0200 Subject: [PATCH 03/28] fix readme --- README.de.md | 9 +++++---- README.md | 11 ++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/README.de.md b/README.de.md index 1b90222..e9f89f6 100644 --- a/README.de.md +++ b/README.de.md @@ -1,4 +1,4 @@ -# ParadisSO - eine minimale 2D-Grafikengine +# ParadiSO - eine minimale 2D-Grafikengine **ParadiSO** wurde als stark abgespeckte 2D-Version meiner `pixwerx`-Engine konzipiert. *ParadiSO* verfolgt einen minimalistischen Ansatz fr 2D-Grafik zu Bildungszwecken. Es verwendet modernes C++ und ein datengetriebenes Design, jedoch keine ECS (Entity Component System). @@ -22,8 +22,9 @@ ParadiSO wird mit den notwendigen Komponenten geliefert. Diese sollte jedoch hie - [GLFW 3.3.8](https://github.com/glfw/glfw) - [GLAD](https://github.com/Dav1dde/glad) +- [STB image](https://github.com/nothings/stb) -## Zuarbeiten +## Beitrge -* [Tim Gtzelmann](https://code.technotecture.net/Timeplex) -* [Robin Rottstdt](https://code.technotecture.net/robin_rottstaedt) \ No newline at end of file +* [Tim Gtzelmann](https://code.technotecture.net/Timeplex) Windows Build +* [Robin Rottstdt](https://code.technotecture.net/robin_rottstaedt) Flappy Bird Clone, Bitmap Loader \ No newline at end of file diff --git a/README.md b/README.md index 6c3929a..ff66b09 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ParadisSO - a minimal 2D graphics engine +# ParadiSO - a minimal 2D graphics engine **ParadiSO** was conceived as a heavily stripped down 2D version of my `pixwerx` engine. *ParadiSO* mimics a minimalistic approach to 2D graphics for educational purposes. It uses modern C++ and a data-driven design, but no ECS. @@ -20,10 +20,11 @@ Because this engine should show some patterns and design concepts it tries to av ParadiSO comes with batteries included. However, it should be mentioned here: -* [GLFW 3.3.8](https://github.com/glfw/glfw) -* [GLAD](https://github.com/Dav1dde/glad) +- [GLFW 3.3.8](https://github.com/glfw/glfw) +- [GLAD](https://github.com/Dav1dde/glad) +- [STB image](https://github.com/nothings/stb) ## Contributors -* [Tim Götzelmann](https://code.technotecture.net/Timeplex) -* [Robin Rottstädt](https://code.technotecture.net/robin_rottstaedt) \ No newline at end of file +* [Tim Götzelmann](https://code.technotecture.net/Timeplex) Windows Build +* [Robin Rottstädt](https://code.technotecture.net/robin_rottstaedt) Flappy Bird Clone, Bitmap Loader \ No newline at end of file From ddb62cb395ea3e8cd83d66a28361e5e800d94736 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Wed, 11 Oct 2023 14:08:19 +0200 Subject: [PATCH 04/28] fix for Visual Studio Build Tool 2022 --- src/lib/src/bitmap_io.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/src/bitmap_io.cpp b/src/lib/src/bitmap_io.cpp index 0afdb21..fabfda3 100644 --- a/src/lib/src/bitmap_io.cpp +++ b/src/lib/src/bitmap_io.cpp @@ -108,7 +108,7 @@ struct BitmapIO::Impl { // moving to C++23 this should be replaced with // std::expected - auto data = read(asset_filepath.c_str()); + auto data = read(asset_filepath.generic_string()); cache_[filename] = data; } @@ -134,7 +134,7 @@ void BitmapIO::set_path(std::string_view path) std::string BitmapIO::path() const { - return impl_->asset_path_; + return impl_->asset_path_.generic_string(); } From b9c7ce3b4875e88fd1d832075c7591b43088cb8a Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Wed, 11 Oct 2023 14:17:51 +0200 Subject: [PATCH 05/28] update readme in regard of toolchains --- README.de.md | 28 +++++++++++++++++++--------- README.md | 11 +++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/README.de.md b/README.de.md index e9f89f6..6b3d0d6 100644 --- a/README.de.md +++ b/README.de.md @@ -1,30 +1,40 @@ # ParadiSO - eine minimale 2D-Grafikengine -**ParadiSO** wurde als stark abgespeckte 2D-Version meiner `pixwerx`-Engine konzipiert. *ParadiSO* verfolgt einen minimalistischen Ansatz fr 2D-Grafik zu Bildungszwecken. Es verwendet modernes C++ und ein datengetriebenes Design, jedoch keine ECS (Entity Component System). +**ParadiSO** wurde als stark abgespeckte 2D-Version meiner `pixwerx`-Engine konzipiert. *ParadiSO* verfolgt einen minimalistischen Ansatz f�r 2D-Grafik zu Bildungszwecken. Es verwendet modernes C++ und ein datengetriebenes Design, jedoch keine ECS (Entity Component System). ## Bildungszwecke -Einige Argumente fr seinen Bildungsaspekt: +Einige Argumente f�r seinen Bildungsaspekt: - Kombination verschiedener Konzepte und Paradigmen zur Erstellung ausdrucksstarker, aber knappen Codes - Stark von Rust-Code inspiriert -- Fr den mathematischen Code wird eine sofortige Auswertung verwendet (keine Expression-Templates), jedoch mit der Verwendung von `constexpr`, um eventuelle Performance-Overheads auszugleichen und optimale Vektorisierung zu erreichen. +- F�r den mathematischen Code wird eine sofortige Auswertung verwendet (keine Expression-Templates), jedoch mit der Verwendung von `constexpr`, um eventuelle Performance-Overheads auszugleichen und optimale Vektorisierung zu erreichen. - Versteckt alte `C`-APIs hinter einer modernisierten Fassade - Es lehnt sich stark an die STL und ihre Algorithmen an ## Minimalistisch -Da diese Engine einige Muster und Designkonzepte zeigen soll, versucht sie, unntigen Ballast zu vermeiden. +Da diese Engine einige Muster und Designkonzepte zeigen soll, versucht sie, unn�tigen Ballast zu vermeiden. -## Abhngigkeiten +## Abh�ngigkeiten -ParadiSO wird mit den notwendigen Komponenten geliefert. Diese sollte jedoch hier erwhnt werden: +ParadiSO wird mit den notwendigen Komponenten geliefert. Diese sollte jedoch hier erw�hnt werden: - [GLFW 3.3.8](https://github.com/glfw/glfw) - [GLAD](https://github.com/Dav1dde/glad) - [STB image](https://github.com/nothings/stb) -## Beitrge +## Toolchains -* [Tim Gtzelmann](https://code.technotecture.net/Timeplex) Windows Build -* [Robin Rottstdt](https://code.technotecture.net/robin_rottstaedt) Flappy Bird Clone, Bitmap Loader \ No newline at end of file +ParadiSO kann auf verschiedenen Plattformen gebaut werden + +- Windows (Visual Studio Build Tools 2022) +- MacOS (clang 14 or later) +- Linux (clang 14 or later, gcc 13.2.1) + +Andere Kombinationen sind möglich aber nicht getestet. + +## Beitr�ge + +* [Tim G�tzelmann](https://code.technotecture.net/Timeplex) Windows Build +* [Robin Rottst�dt](https://code.technotecture.net/robin_rottstaedt) Flappy Bird Clone, Bitmap Loader \ No newline at end of file diff --git a/README.md b/README.md index ff66b09..6f3f006 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,17 @@ ParadiSO comes with batteries included. However, it should be mentioned here: - [GLAD](https://github.com/Dav1dde/glad) - [STB image](https://github.com/nothings/stb) +## Toolchains + +ParadiSO is being developed to work on all major desktop systems. + +- Windows (Visual Studio Build Tools 2022) +- MacOS (clang 14 or later) +- Linux (clang 14 or later, gcc 13.2.1) + +Other combinations might work but are untested. + + ## Contributors * [Tim Götzelmann](https://code.technotecture.net/Timeplex) Windows Build From 2a42731628bf7428dd0444ac2fbd0802059e540d Mon Sep 17 00:00:00 2001 From: _brxxh <11dac2t@huhn-online.de> Date: Thu, 23 Nov 2023 17:49:07 +0100 Subject: [PATCH 06/28] fixed quickwings, added me to readme, fixed readme --- README.de.md | 39 ++++---- README.md | 32 +++---- examples/quickwings/assets/background-day.png | Bin 7026 -> 10361 bytes examples/quickwings/assets/base.png | Bin 470 -> 2300 bytes examples/quickwings/assets/blank.png | Bin 0 -> 466 bytes examples/quickwings/assets/gameover.png | Bin 0 -> 758 bytes examples/quickwings/assets/message.png | Bin 0 -> 1602 bytes examples/quickwings/quickwings.cpp | 89 ++++++++++++------ 8 files changed, 94 insertions(+), 66 deletions(-) create mode 100644 examples/quickwings/assets/blank.png create mode 100644 examples/quickwings/assets/gameover.png create mode 100644 examples/quickwings/assets/message.png diff --git a/README.de.md b/README.de.md index 6b3d0d6..274cee6 100644 --- a/README.de.md +++ b/README.de.md @@ -1,40 +1,41 @@ # ParadiSO - eine minimale 2D-Grafikengine -**ParadiSO** wurde als stark abgespeckte 2D-Version meiner `pixwerx`-Engine konzipiert. *ParadiSO* verfolgt einen minimalistischen Ansatz f�r 2D-Grafik zu Bildungszwecken. Es verwendet modernes C++ und ein datengetriebenes Design, jedoch keine ECS (Entity Component System). +**ParadiSO** wurde als stark abgespeckte 2D-Version meiner `pixwerx`-Engine konzipiert. _ParadiSO_ verfolgt einen minimalistischen Ansatz für 2D-Grafik zu Bildungszwecken. Es verwendet modernes C++ und ein datengetriebenes Design, jedoch keine ECS (Entity Component System). ## Bildungszwecke -Einige Argumente f�r seinen Bildungsaspekt: +Einige Argumente für seinen Bildungsaspekt: -- Kombination verschiedener Konzepte und Paradigmen zur Erstellung ausdrucksstarker, aber knappen Codes -- Stark von Rust-Code inspiriert -- F�r den mathematischen Code wird eine sofortige Auswertung verwendet (keine Expression-Templates), jedoch mit der Verwendung von `constexpr`, um eventuelle Performance-Overheads auszugleichen und optimale Vektorisierung zu erreichen. -- Versteckt alte `C`-APIs hinter einer modernisierten Fassade -- Es lehnt sich stark an die STL und ihre Algorithmen an +- Kombination verschiedener Konzepte und Paradigmen zur Erstellung ausdrucksstarker, aber knappen Codes +- Stark von Rust-Code inspiriert +- Für den mathematischen Code wird eine sofortige Auswertung verwendet (keine Expression-Templates), jedoch mit der Verwendung von `constexpr`, um eventuelle Performance-Overheads auszugleichen und optimale Vektorisierung zu erreichen. +- Versteckt alte `C`-APIs hinter einer modernisierten Fassade +- Es lehnt sich stark an die STL und ihre Algorithmen an ## Minimalistisch -Da diese Engine einige Muster und Designkonzepte zeigen soll, versucht sie, unn�tigen Ballast zu vermeiden. +Da diese Engine einige Muster und Designkonzepte zeigen soll, versucht sie, unnötigen Ballast zu vermeiden. -## Abh�ngigkeiten +## Abhängigkeiten -ParadiSO wird mit den notwendigen Komponenten geliefert. Diese sollte jedoch hier erw�hnt werden: +ParadiSO wird mit den notwendigen Komponenten geliefert. Diese sollte jedoch hier erwähnt werden: -- [GLFW 3.3.8](https://github.com/glfw/glfw) -- [GLAD](https://github.com/Dav1dde/glad) -- [STB image](https://github.com/nothings/stb) +- [GLFW 3.3.8](https://github.com/glfw/glfw) +- [GLAD](https://github.com/Dav1dde/glad) +- [STB image](https://github.com/nothings/stb) ## Toolchains ParadiSO kann auf verschiedenen Plattformen gebaut werden -- Windows (Visual Studio Build Tools 2022) -- MacOS (clang 14 or later) -- Linux (clang 14 or later, gcc 13.2.1) +- Windows (Visual Studio Build Tools 2022) +- MacOS (clang 14 or later) +- Linux (clang 14 or later, gcc 13.2.1) Andere Kombinationen sind möglich aber nicht getestet. -## Beitr�ge +## Beiträge -* [Tim G�tzelmann](https://code.technotecture.net/Timeplex) Windows Build -* [Robin Rottst�dt](https://code.technotecture.net/robin_rottstaedt) Flappy Bird Clone, Bitmap Loader \ No newline at end of file +- [Tim Götzelmann](https://code.technotecture.net/Timeplex) Windows Build +- [Robin Rottstädt](https://code.technotecture.net/robin_rottstaedt) Flappy Bird Clone, Bitmap Loader +- [brxxh](https://code.technotecture.net/brxxh) Flappy Bird Clone diff --git a/README.md b/README.md index 6f3f006..07828bc 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,41 @@ # ParadiSO - a minimal 2D graphics engine -**ParadiSO** was conceived as a heavily stripped down 2D version of my `pixwerx` engine. *ParadiSO* mimics a minimalistic approach to 2D graphics for educational purposes. It uses modern C++ and a data-driven design, but no ECS. +**ParadiSO** was conceived as a heavily stripped down 2D version of my `pixwerx` engine. _ParadiSO_ mimics a minimalistic approach to 2D graphics for educational purposes. It uses modern C++ and a data-driven design, but no ECS. ## Educational Some arguments for its educational side: -* mix and match of various concepts and paradigms to write expressive but concise code -* heavily inspired by Rust code -* math code is eager evaluation but `constexpr` to compensate overheads -* hides old-style `C` APIs behind a renovated facade -* it leans heavily on the STL and its algorithms +- mix and match of various concepts and paradigms to write expressive but concise code +- heavily inspired by Rust code +- math code is eager evaluation but `constexpr` to compensate overheads +- hides old-style `C` APIs behind a renovated facade +- it leans heavily on the STL and its algorithms ## Minimal -Because this engine should show some patterns and design concepts it tries to avoid adding unnecessary bloat. +Because this engine should show some patterns and design concepts it tries to avoid adding unnecessary bloat. ## Dependencies ParadiSO comes with batteries included. However, it should be mentioned here: -- [GLFW 3.3.8](https://github.com/glfw/glfw) -- [GLAD](https://github.com/Dav1dde/glad) -- [STB image](https://github.com/nothings/stb) +- [GLFW 3.3.8](https://github.com/glfw/glfw) +- [GLAD](https://github.com/Dav1dde/glad) +- [STB image](https://github.com/nothings/stb) ## Toolchains ParadiSO is being developed to work on all major desktop systems. -- Windows (Visual Studio Build Tools 2022) -- MacOS (clang 14 or later) -- Linux (clang 14 or later, gcc 13.2.1) +- Windows (Visual Studio Build Tools 2022) +- MacOS (clang 14 or later) +- Linux (clang 14 or later, gcc 13.2.1) Other combinations might work but are untested. - ## Contributors -* [Tim Götzelmann](https://code.technotecture.net/Timeplex) Windows Build -* [Robin Rottstädt](https://code.technotecture.net/robin_rottstaedt) Flappy Bird Clone, Bitmap Loader \ No newline at end of file +- [Tim Götzelmann](https://code.technotecture.net/Timeplex) Windows Build +- [Robin Rottstädt](https://code.technotecture.net/robin_rottstaedt) Flappy Bird Clone, Bitmap Loader +- [brxxh](https://code.technotecture.net/brxxh) Flappy Bird Clone diff --git a/examples/quickwings/assets/background-day.png b/examples/quickwings/assets/background-day.png index afcb5ec982a3de74cb9186f6af3ba329d63a22bb..f9ed139c84f87b86b0ea31e47c729fde44f8b70d 100644 GIT binary patch literal 10361 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 literal 7026 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 b$3|uR-wMAWen9IL0NxiM9{6v+|M9;7ImZIa diff --git a/examples/quickwings/assets/base.png b/examples/quickwings/assets/base.png index c374f2b34f2d8a75f74641775970314b462cb337..2ba45d32091724ae7160522722bb3cfa63d3a345 100644 GIT binary patch literal 2300 zcmeAS@N?(olHy`uVBq!ia0y~yU|IlV7jUov$%Atb9cEx)%*%9k4#-SSW?;~mSUT~% zHcO(!ar@mJI-W8r?Urv&HGW$B6ZoJ&!ug)=2L@6IasHQwyG?$l97%Z~1N_Wz9G zPrWoV4zrSpJzp+3mU+m7UKn)RFbxXnPX_t$m{u=kX zWTZCC$lLYp#+8t!`s>Ga6+`oXg{=So{_jqu?rGUhD;z6sY?1YkSf;q~(akRN*4t<2 z?9-@Gxbyl%!=dS3=1g@#b9jIFZk+7Z=N$3%$|n08KMtmy)8zQh;m-YYQshkcTF=R$ zb7oGvrMa7Xx{C0Tiv}7SUF7=hR=S>ilOJDy)BNP73ZKf`YaVqdd;9I#yJ*^y)vBh- zyHx$>g--qb-sbL^3ketYYVwu#@B1&+{44jztxtc?JKz6r)ijIULO<;9=}DJQ?0yj) zs=JF{_jN&4;ME>ki`xx-)zRf&Hial#&pCPEG^fe(g>R*#o;R=2dMMgV7lM`SSr1K$x4W}K?cC(XdXZsO_U7*Y}U_O4@AaG=QX zhb~O-4tI7a@ZD|X;44+lJFru_P<)+JSMhd5QLQTrRNk}X)t`OvdP{%#q3gx(|K6YM z_+9?qp1pT}DmpYUFfy@l2q*|}+H}6saE5Um9{45v|9o9sIN&T?$pp?B4QW@n1Qnnn zcYGb}YpY8yvV1xEdAj(?yMKPvUHp8neqJ~K{A9-0uWRf-JS^5p_`jw8mi_aIZx(*{ z7ryZG{-Mbr+rTDpv+!Lm-(k562>rrO=Y79m?*88Vrt!_$>)oGE|9twVX}tc`pGizs z|7TZBg1XWnq4B^omMdp30%764ORHu-{vsT?|JwSm*0H+#cHWq@Y5&h>sZY)I)fPl+ zpL@>Qe|!Gh^R=O$zJLGr{Pmsrz7EfA z-*|$91L(j;R;K^H4tLjp;B)QMXMb7cUt4ZB_3zn#Y4w};-<1EyVe{>0Dw9=w_dFF? z7)2-)*fW|+8UW#p^(&6=v;6nlb8Y%X?v`F>lMyeYkY-d}bfU^vWsifj-2WMLqj z{L{E=;XV=Lcw=8zSGN0sZJZ-Kt`bxdn5>dM z2|!}fq2Yj5*tQ2tg3Nxa?K}(@w*_|$U0^?Xv1vA1yK~%sYIPWOjdX@lNm=OvSxHuMQ zZcl>yjA?}&ER70yu(Dj35^V^JR7S=S{!#BSjmF++;^Yt*QF-r!^v4(B@hP)|n1Gck NgQu&X%Q~loCIAIj%eDXj literal 470 zcmeAS@N?(olHy`uVBq!ia0y~yUG}$vdpD;3|NsAJp`$ub4P%nGy9>KmV#jMBhqJ&VvY3H^?+6GpPSxg< z1`4v5c>21sKW64(U=n`*OLYfOXql&rV@SoVx91!=nHU*Z1GOU#a)oVZ5`81@cw_el z_QdChXJ3}N|8|*uxqK%3FN-Rz*Q7`oU(j#<^uFNA z%(zmZi&aZpBT7;dOH!?pi&B9UgOP!urLKXouAyOwp@o%!k(HsPwt<FVdQ&MBb@03g?$h5!Hn diff --git a/examples/quickwings/assets/blank.png b/examples/quickwings/assets/blank.png new file mode 100644 index 0000000000000000000000000000000000000000..5c1b88f4045da9b1d191fb5b907e85fca4542ce3 GIT binary patch literal 466 zcmV;@0WJQCP)q)jWdF(fHcTm=^g!9jHK zYw#cFD!3{Lf+C2xx%;(9iRZS37SS7S&cl1}dpLOmp+wHidrcFNw|zGmk7)~wOIph- zZG?%?&ZusB&g9HYf`8Z7Jq@bfMOCl=@BO*jQ)$nHhF0M*({X)anTEu=?Py0Ddwy1G zkL+GNlEjIjVNhU|96nL0wq*9VZ@BE6W=%Y%yd8?T;>eH{?~tek>6(^miJq1xM^WYe zJ5SFV9jSB=$DsK+2;TdlWfw|2LGXPX1f>&be1c26=3kSX#y>^hscC(O5ZQ$DtD0u) z!NnGIKRUXrm!(G8Av~=QQY`6?zK#qG8~eHcB(ehe3dtTp zz6=aistgPb%?u1b{{!il3=E|P3=FRl7#OT(0Cnb1ia+WGRBI666XN>+KTrui5MtpD zL_lSK7I-{KkT{)kY#vZKPf3tpFwlA?HfDB44p#0zv)_qt0E#mvdAqwXbg;^L06Clm z9+AZi4BWyX%*Zfnjs#GUy~NYkmHja@4+E3%^IxhvfO@8Rx;Tb-9KSmKVD4c99@ni- z6IhviFD!5n&tUW5pQ+GrG24IE0*Ai6X|3ym)-4d-(xeqFXn{4@1l2{lx8d|iC} zkYKRyDWm<|FFuJ}t9rC^!>{QK4!%0C_*=p+*QX@Q8NAMrYM7qS=$9^Qwf?+pTIsI| zCGtVCjI$QCr5u>jz3JY^c_IhCZ`zXJ&A6fT0E68$WkKP!K@C=i3qLkKP;jW-pxkV6 zz?bQSrNym=jgA5V*M2e{xG(ZRiXrZawnOAgF@|`zH@~7B{=7TI{HpTWi=PdjLO+T# z4oU-o9h?Opt8>ukAa*&$cI$lNeYxFSSTa(s+Mk@;w!X`6s)5n8c(H zn*t+EwZt`|BqgyV)hf9t6-Y4{85mmX8W`&u8ip8JSQ!{u8Cq%^m{}PZJk+v0jG`eo aKP5A*61Rp4<&E_~4Gf;HelF{r5}E*LS`Uf< literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/message.png b/examples/quickwings/assets/message.png new file mode 100644 index 0000000000000000000000000000000000000000..9243ab58b2910ae63393eb28ac5867237826d7e0 GIT binary patch literal 1602 zcmZ{kdpOg39LIldIW|ifigMOTTMu)YOPX;kovjgbzqjPBo3RiTT`cC3OLY=0TXb=Y zmBic&vucSriOh8gtz-$C)XuLz&mZUeJm2T_d4Im2_xE}K@qNCT?ye*lL=OT00L;me z;0clo018lLC9o>A@?e5cj&dM70KmgM=vs&hsJDeVdXfR)G!g*L(*Zyx2RR1-2^awQ z7z_ZoLIBtlbL9|kA2_?i-Nl;-QZ5Ilel2e-X?1lKl>S5hK)K`K;GpMjqTCSnWz$Ym z@K`zC)71+Mpw0Jr1l|WIggTQ53UWo0F;J+*ItIi602KafD*!icZU&pG@lIr-sz^y4 zP=wE{BEj^^%T5Fb@1%F1N66Hh7%d>!v!o_uAmJMNo1$^yoJv9 z&8+QAN{w_yCR4T3J^s6vxOB+tc1jB+pUik+ROrlGR)1gAr}jdlH1ID!()zr71gJpf4^jw zX7D}I?w^tkxt~WQdo)tH@Gatcoq5;-y;-{pA^gdsX`I(<@6o6&g^C2%^v5OoJJWa1 zlkWgy#u7vFW05U2p-_GMrC!3MO@JPo5~y6Gb26D;kj#@vSJ$sZ|5#Y}E6{)-;+v%6 z;EW(knzEdgRGGtQ4?wuN?)PoUnW!`$F1gSEovhBwi%E+eLS=M*DL>FqN$m0HQo}SC zNmz5ClTD?>&mLPFn4>LH?vg2#PWk5ITNlav@^!3aEqP!PFQEo)J)SELSEkjhl&ppG z5D8L)vFcl5?oRs*afmSMfh+gth?#zkAXO?-w_oV+PVagxKAfXb%OiMyP*;JyD3*rd zsBbF%Tv|^@qk|7GS&PZsMb8b43-pa$Si%rKbF>Oe4N4D4-lJCAFvuG=o=43VYuRUn zA!dB?%FY?5Dd`H?gr`dEvxb+dXx~gJQxjM5`zWe&6H3lc#(nH{(YXQx2&}w~keLx| z;rnFLJ%U~Xo4PDm^v4e+$Y|I?hrCeEF-cms!^IKjlv#|r3JtsYA@BWOZ`)U}Kw?sB zIHt`fs+%ahwTVb?c~RfwI~58gaa+SD$Mo|Gi)KS1uBahxWajI=*fPRdOBIuo zzad+0m=GkVZ1Xuwk}cEv;{qdOgnyged0ojJd$lrFV!E|QwN68k>EPM~`;*l|6W(I^ zbU0_Udtvq2tG9w#QbK7`irpd3TfxA%x#h-UR1p3khuNL>sy=Novll<1*{+=5b&Qp> zIDNz=`=x7xF2&^xb;i*-a?RLc`@o4|NRU7tiW-#`=b}uAqoR~D zECC;Gf~2SBK)DEC=oO@XU!L`KH0OIO?&or*fS-L0{-713C{+!MVI!u@&M4_?Q$<*a zbcV5NFz&!$94yk(B5C@aj&9?7+;)N^qIgU__c)7=-R}81aMC(I#`hz6WlN()eI8rY z?65zO)Phn$(1C)do!2Q##mM{e>n$uZI-eRR>TG-xmyEcv#gEZ0;>F7J-=S!C*=8f1 z)7N?COlx~tj5|amS1=f^lqGUn=fO`A8Bg?&4-bitz=fTN00CHF%xz3CmL}%r-sV^w s#sX(::make(0.0f, 0.0f), - .scale = paradiso::Vector2::make(1.01f, 1.0f)}; + .pivot = {paradiso::Vector2::make(0.0f, 0.16f)}, + .scale = {paradiso::Vector2::make(1.01f, 1.3f)}}; backgroundRight = paradiso::Sprite{ .bitmap = backgroundImage, - .pivot = paradiso::Vector2::make(2.0f, 0.0f), - .scale = paradiso::Vector2::make(1.01f, 1.0f)}; + .pivot = {paradiso::Vector2::make(2.018f, 0.16f)}, + .scale = {paradiso::Vector2::make(1.01f, 1.3f)}}; auto grassImage = paradiso::BitmapIO::get().load("base.png"); grassLeft = paradiso::Sprite{ .bitmap = grassImage, - .pivot = paradiso::Vector2::make(0.0f, -1.0f), - .scale = paradiso::Vector2::make(1.0f, 0.33333f)}; + .pivot = {paradiso::Vector2::make(0.0f, -1.0f)}, + .scale = {paradiso::Vector2::make(1.0f, 0.33333f)}}; grassRight = paradiso::Sprite{ .bitmap = grassImage, - .pivot = paradiso::Vector2::make(2.0f, -1.0f), - .scale = paradiso::Vector2::make(1.0f, 0.33333f)}; + .pivot = {paradiso::Vector2::make(2.0f, -1.0f)}, + .scale = {paradiso::Vector2::make(1.0f, 0.33333f)}}; } void draw(const paradiso::Shader& shader) { @@ -61,7 +61,7 @@ struct Background { if (sprite->pivot.x() <= -2.0f) { sprite->pivot.x() += 4.0f; } - sprite->pivot.x() -= 0.001f; + sprite->pivot.x() -= 0.002f; shader.set_uniform("pivot", sprite->pivot); shader.set_uniform("scale", sprite->scale); shader.set_uniform("rotation", sprite->rotation); @@ -79,23 +79,23 @@ struct Grass { paradiso::Sprite* scrolling[2] = {&grassLeft, &grassRight}; Grass() { - auto grassImage = paradiso::BitmapIO::get().load(std::string("base.png")); + auto grassImage = paradiso::BitmapIO::get().load("base.png"); grassLeft = paradiso::Sprite{ .bitmap = grassImage, - .pivot = paradiso::Vector2::make(0.0f, -0.9f), - .scale = paradiso::Vector2::make(1.0f, 0.33333f)}; + .pivot = {paradiso::Vector2::make(1.0f, -0.9f)}, + .scale = {paradiso::Vector2::make(2.0f, 0.33333f)}}; grassRight = paradiso::Sprite{ .bitmap = grassImage, - .pivot = paradiso::Vector2::make(2.0f, -0.9f), - .scale = paradiso::Vector2::make(1.0f, 0.33333f)}; + .pivot = {paradiso::Vector2::make(1.0f, -0.9f)}, + .scale = {paradiso::Vector2::make(2.6f, 0.33333f)}}; } void draw(const paradiso::Shader& shader) { for (auto sprite : scrolling) { - if (sprite->pivot.x() <= -2.0f) { - sprite->pivot.x() += 4.0f; + if (sprite->pivot.x() <= -1.0f) { + sprite->pivot.x() += 2.0f; } - sprite->pivot.x() -= 0.035f; + sprite->pivot.x() -= 0.03f; shader.set_uniform("pivot", sprite->pivot); shader.set_uniform("scale", sprite->scale); shader.set_uniform("rotation", sprite->rotation); @@ -106,6 +106,7 @@ struct Grass { paradiso::Renderer renderer{}; }; + struct QuickWings { paradiso::Renderer renderer1{}; @@ -118,10 +119,10 @@ struct QuickWings { unsigned int flapCounter = 0; // How many ticks since last flap float velocity = 0.0f; - const float max_velocity = 0.05f; + const float max_velocity = 0.04f; const float gravity = -0.004f; - const float move_up_velocity = 0.0055f; + const float move_up_velocity = 0.04f; bool move_up = false; bool paused = true; @@ -129,30 +130,30 @@ struct QuickWings { const float max_pos = 0.95f; const float min_pos = -0.5f; - float pos = 0.0f; + float pos = 0.34f; float rotation = 0.0f; QuickWings() { - float scaleh = 0.07f; - float scalew = scaleh * 1.416666666666667f; + float scaleh = 0.08f; + float scalew = 0.158f; birds = { paradiso::Sprite{ .bitmap = paradiso::BitmapIO::get().load("yellowbird-downflap.png"), - .pivot = paradiso::Vector2::make(0.0f, 0.0f), - .scale = paradiso::Vector2::make(scalew, scaleh)}, + .pivot = {paradiso::Vector2::make(0.0f, 0.0f)}, + .scale = {paradiso::Vector2::make(scalew, scaleh)}}, paradiso::Sprite{ .bitmap = paradiso::BitmapIO::get().load("yellowbird-midflap.png"), - .pivot = paradiso::Vector2::make(0.0f, 0.0f), - .scale = paradiso::Vector2::make(scalew, scaleh)}, + .pivot = {paradiso::Vector2::make(0.0f, 0.0f)}, + .scale = {paradiso::Vector2::make(scalew, scaleh)}}, paradiso::Sprite{ .bitmap = paradiso::BitmapIO::get().load("yellowbird-upflap.png"), - .pivot = paradiso::Vector2::make(0.0f, 0.0f), - .scale = paradiso::Vector2::make(scalew, scaleh)}}; + .pivot = {paradiso::Vector2::make(0.0f, 0.0f)}, + .scale = {paradiso::Vector2::make(scalew, scaleh)}}}; } void draw(const paradiso::Shader& shader) { @@ -185,6 +186,7 @@ struct QuickWings { } void update() { + // Stop game if (paused) return; @@ -213,7 +215,7 @@ struct QuickWings { } // Update rotation - rotation = velocity * 15.0f; + rotation = velocity * 10.0f; } // keyboard handler @@ -231,6 +233,30 @@ struct QuickWings { } }; +/* +TODO: finish this + +struct Message { + paradiso::Sprite messageSprite; + paradiso::Renderer renderer{}; + + Message() { + auto messageImage = paradiso::BitmapIO::get().load("message.png"); + messageSprite = paradiso::Sprite{ + .bitmap = messageImage, + .pivot = {paradiso::Vector2::make(0.0f, 0.0f)}, + .scale = {paradiso::Vector2::make(0.8f, 0.8f)} + }; + }; + + void draw(const paradiso::Shader& shader) { + shader.set_uniform("pivot", messageSprite.pivot); + shader.set_uniform("scale", messageSprite.scale); + renderer.draw(messageSprite, shader); + } +}; +*/ + auto main() -> int { // Ausgabefenster ... sieht aus als wäre es auf dem Stack @@ -274,9 +300,9 @@ auto main() -> int { paradiso::BitmapIO::get().set_path("assets"); // Load + //* auto message = Message{}; auto background = Background{}; auto grass = Grass{}; - auto quickwingsapp = QuickWings{}; // timer @@ -298,6 +324,7 @@ auto main() -> int { // Draw background.draw(shader); grass.draw(shader); + //* message.draw(shader); quickwingsapp.draw(shader); // wait for frame rate From 500464fa73b1463d7353b407eb290c918d35aa72 Mon Sep 17 00:00:00 2001 From: _brxxh <11dac2t@huhn-online.de> Date: Thu, 23 Nov 2023 18:19:24 +0100 Subject: [PATCH 07/28] Added welcome-message --- examples/quickwings/quickwings.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/examples/quickwings/quickwings.cpp b/examples/quickwings/quickwings.cpp index 6146f12..ac626a0 100644 --- a/examples/quickwings/quickwings.cpp +++ b/examples/quickwings/quickwings.cpp @@ -233,12 +233,13 @@ struct QuickWings { } }; -/* -TODO: finish this +// TODO: finish this struct Message { paradiso::Sprite messageSprite; paradiso::Renderer renderer{}; + bool start = false; + float pos = 100.0f; Message() { auto messageImage = paradiso::BitmapIO::get().load("message.png"); @@ -254,8 +255,20 @@ struct Message { shader.set_uniform("scale", messageSprite.scale); renderer.draw(messageSprite, shader); } + + void update() { + if (start == true) { + messageSprite.pivot.y() = pos; + } + } + + void on_keyboard(const paradiso::Window::KeyboardInputStack& input) { + if (input.size()) { + start = true; + } + } }; -*/ + auto main() -> int { @@ -300,7 +313,7 @@ auto main() -> int { paradiso::BitmapIO::get().set_path("assets"); // Load - //* auto message = Message{}; + auto message = Message{}; auto background = Background{}; auto grass = Grass{}; auto quickwingsapp = QuickWings{}; @@ -321,10 +334,13 @@ auto main() -> int { quickwingsapp.on_keyboard(w.keyboard_input()); quickwingsapp.update(); + message.on_keyboard(w.keyboard_input()); + message.update(); + // Draw background.draw(shader); grass.draw(shader); - //* message.draw(shader); + message.draw(shader); quickwingsapp.draw(shader); // wait for frame rate From 7a3afe12819754d597cf30099423fabe381348cb Mon Sep 17 00:00:00 2001 From: _brxxh <11dac2t@huhn-online.de> Date: Thu, 23 Nov 2023 18:59:30 +0100 Subject: [PATCH 08/28] Addded game over to quickwings --- examples/quickwings/quickwings.cpp | 92 +++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 26 deletions(-) diff --git a/examples/quickwings/quickwings.cpp b/examples/quickwings/quickwings.cpp index ac626a0..2a91d22 100644 --- a/examples/quickwings/quickwings.cpp +++ b/examples/quickwings/quickwings.cpp @@ -5,6 +5,7 @@ * */ +#include #include #include #include @@ -24,6 +25,7 @@ // #include "lib/image_loader.hpp" const int frame_rate = 60; +bool game_over = false; struct Background { paradiso::Sprite backgroundLeft; @@ -187,47 +189,60 @@ struct QuickWings { void update() { + if (game_over == true) { + paused = true; + } + // Stop game if (paused) return; + else { + // Apply gravity + velocity += gravity; - // Apply gravity - velocity += gravity; + if (move_up) + velocity += move_up_velocity - gravity; - if (move_up) - velocity += move_up_velocity - gravity; + // Cap velocity + if (velocity > max_velocity) + velocity = max_velocity; + if (velocity < -max_velocity) + velocity = -max_velocity; - // Cap velocity - if (velocity > max_velocity) - velocity = max_velocity; - if (velocity < -max_velocity) - velocity = -max_velocity; + // Cap position + pos += velocity; + if (pos < min_pos) { + pos = min_pos; + velocity = 0.0f; + game_over = true; + } + if (pos > max_pos) { + pos = max_pos; + velocity = 0.0f; + game_over = true; + } - // Cap position - pos += velocity; - if (pos < min_pos) { - pos = min_pos; - velocity = 0.0f; + // Update rotation + rotation = velocity * 10.0f; } - if (pos > max_pos) { - pos = max_pos; - velocity = 0.0f; - } - - // Update rotation - rotation = velocity * 10.0f; } // keyboard handler void on_keyboard(const paradiso::Window::KeyboardInputStack& input) { if (input.size()) { paused = false; - bool pressed_up = input.top().key == ' ' || input.top().key == 'W'; - if (input.top().action == 1 && pressed_up) { - move_up = true; - } else if (input.top().action == 0 && pressed_up) { - move_up = false; + if (paused == false) { + bool pressed_up = input.top().key == ' ' || input.top().key == 'W'; + + if (input.top().action == 1 && pressed_up) { + move_up = true; + } else if (input.top().action == 0 && pressed_up) { + move_up = false; + } + } + else { + return; } } } @@ -269,6 +284,25 @@ struct Message { } }; +struct GameOverMessage { + paradiso::Sprite messageSprite; + paradiso::Renderer renderer{}; + + GameOverMessage() { + auto messageImage = paradiso::BitmapIO::get().load("gameover.png"); + messageSprite = paradiso::Sprite{ + .bitmap = messageImage, + .pivot = {paradiso::Vector2::make(0.0f, 0.4f)}, + .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 192.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 42.0f)) / 700.0f) * 2.25f)} + }; + }; + + void draw(const paradiso::Shader& shader) { + shader.set_uniform("pivot", messageSprite.pivot); + shader.set_uniform("scale", messageSprite.scale); + renderer.draw(messageSprite, shader); + } +}; auto main() -> int { @@ -317,6 +351,7 @@ auto main() -> int { auto background = Background{}; auto grass = Grass{}; auto quickwingsapp = QuickWings{}; + auto gameover = GameOverMessage{}; // timer @@ -341,6 +376,11 @@ auto main() -> int { background.draw(shader); grass.draw(shader); message.draw(shader); + + if (game_over == true) { + gameover.draw(shader); + } + quickwingsapp.draw(shader); // wait for frame rate From 6ae437ef75b5ea9634d628cb1bf7407481f7c2a0 Mon Sep 17 00:00:00 2001 From: _brxxh <11dac2t@huhn-online.de> Date: Thu, 23 Nov 2023 19:17:57 +0100 Subject: [PATCH 09/28] Setted window "spawn point" to middle of screen --- examples/quickwings/quickwings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/quickwings/quickwings.cpp b/examples/quickwings/quickwings.cpp index 2a91d22..9ba279e 100644 --- a/examples/quickwings/quickwings.cpp +++ b/examples/quickwings/quickwings.cpp @@ -319,7 +319,7 @@ auto main() -> int { */ window .set_size(size) // ... Grösse - .set_position(paradiso::Point{.x = 100, .y = 100}) // ... Position + .set_position(paradiso::Point{.x = 1920 / 2 - 500 / 2, .y = 1080 / 2 - 700 / 2}) // ... Position .set_title("PardiSO.FlappyBird") // ... Titel .set_visible(true); // ... und jetzt anzeigen! From 68915cb24b864fde5c8a69451ae70664e819c84a Mon Sep 17 00:00:00 2001 From: brxxh <11dac2t@huhn-online.de> Date: Thu, 23 Nov 2023 20:10:35 +0100 Subject: [PATCH 10/28] Added test pipe sprite to quickwings (random pos) --- examples/quickwings/quickwings.cpp | 52 ++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/examples/quickwings/quickwings.cpp b/examples/quickwings/quickwings.cpp index 9ba279e..45d1446 100644 --- a/examples/quickwings/quickwings.cpp +++ b/examples/quickwings/quickwings.cpp @@ -5,6 +5,7 @@ * */ +#include #include #include #include @@ -21,6 +22,8 @@ #include #include #include +#include +#include // #include "lib/image_loader.hpp" @@ -74,12 +77,49 @@ struct Background { paradiso::Renderer renderer{}; }; +struct Pipe { + paradiso::Sprite pipe_top; + paradiso::Sprite pipe_bottom; + + paradiso::Renderer renderer1{}; + paradiso::Renderer renderer2{}; + + int pipe_spawn_rand_int = rand() % 80 + 25; + float pipe_spawn_rand = float(pipe_spawn_rand_int) / 100; + + Pipe() { + auto pipe_image = paradiso::BitmapIO::get().load("pipe-green.png"); + + pipe_top = paradiso::Sprite{ + .bitmap = pipe_image, + .pivot = {paradiso::Vector2::make(0.0f, pipe_spawn_rand + 1.0f)}, + .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 320.0f)) / 700.0f) * 2.25f)}, + .rotation = 3.1415926f}; + pipe_bottom = paradiso::Sprite{ + .bitmap = pipe_image, + .pivot = {paradiso::Vector2::make(0.0f, pipe_spawn_rand - 1.6f)}, + .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 320.0f)) / 700.0f) * 2.25f)}}; + } + + void draw(const paradiso::Shader& shader) { + shader.set_uniform("pivot", pipe_bottom.pivot); + shader.set_uniform("scale", pipe_bottom.scale); + renderer1.draw(pipe_bottom, shader); + + shader.set_uniform("pivot", pipe_top.pivot); + shader.set_uniform("scale", pipe_top.scale); + shader.set_uniform("rotation", pipe_top.rotation); + renderer1.draw(pipe_top, shader); + } +}; + struct Grass { paradiso::Sprite grassLeft; paradiso::Sprite grassRight; - paradiso::Sprite* scrolling[2] = {&grassLeft, &grassRight}; + paradiso::Renderer renderer{}; + Grass() { auto grassImage = paradiso::BitmapIO::get().load("base.png"); grassLeft = paradiso::Sprite{ @@ -104,13 +144,10 @@ struct Grass { renderer.draw(*sprite, shader); } } - - paradiso::Renderer renderer{}; }; struct QuickWings { - paradiso::Renderer renderer1{}; paradiso::Renderer renderer2{}; paradiso::Renderer renderer3{}; @@ -248,8 +285,6 @@ struct QuickWings { } }; - -// TODO: finish this struct Message { paradiso::Sprite messageSprite; paradiso::Renderer renderer{}; @@ -305,6 +340,7 @@ struct GameOverMessage { }; auto main() -> int { + std::srand(std::time(nullptr)); // Ausgabefenster ... sieht aus als wäre es auf dem Stack auto window = paradiso::Window(); @@ -347,10 +383,11 @@ auto main() -> int { paradiso::BitmapIO::get().set_path("assets"); // Load - auto message = Message{}; auto background = Background{}; auto grass = Grass{}; auto quickwingsapp = QuickWings{}; + auto pipe = Pipe{}; + auto message = Message{}; auto gameover = GameOverMessage{}; // timer @@ -374,6 +411,7 @@ auto main() -> int { // Draw background.draw(shader); + pipe.draw(shader); grass.draw(shader); message.draw(shader); From ba56c0d91172a5a7357ad9200bfa955bf35d0f7c Mon Sep 17 00:00:00 2001 From: brxxh <11dac2t@huhn-online.de> Date: Thu, 23 Nov 2023 21:40:00 +0100 Subject: [PATCH 11/28] Started working on pipes collision (WIP) --- examples/quickwings/assets/blank.png | Bin 466 -> 0 bytes examples/quickwings/quickwings.cpp | 75 ++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 8 deletions(-) delete mode 100644 examples/quickwings/assets/blank.png diff --git a/examples/quickwings/assets/blank.png b/examples/quickwings/assets/blank.png deleted file mode 100644 index 5c1b88f4045da9b1d191fb5b907e85fca4542ce3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 466 zcmV;@0WJQCP)q)jWdF(fHcTm=^g!9jHK zYw#cFD!3{Lf+C2xx%;(9iRZS37SS7S&cl1}dpLOmp+wHidrcFNw|zGmk7)~wOIph- zZG?%?&ZusB&g9HYf`8Z7Jq@bfMOCl=@BO*jQ)$nHhF0M*({X)anTEu=?Py0Ddwy1G zkL+GNlEjIjVNhU|96nL0wq*9VZ@BE6W=%Y%yd8?T;>eH{?~tek>6(^miJq1xM^WYe zJ5SFV9jSB=$DsK+2;TdlWfw|2LGXPX1f>&be1c26=3kSX#y>^hscC(O5ZQ$DtD0u) z!NnGIKRUXrm!(G8A +#include #include #include #include @@ -29,6 +31,12 @@ const int frame_rate = 60; bool game_over = false; +float risky_pos_x; +float risky_pos_max_x; +float risky_pos_bottom_y; +float risky_pos_top_y; +float risky_pos_bottom_max_y; +float risky_pos_top_max_y; struct Background { paradiso::Sprite backgroundLeft; @@ -84,9 +92,11 @@ struct Pipe { paradiso::Renderer renderer1{}; paradiso::Renderer renderer2{}; - int pipe_spawn_rand_int = rand() % 80 + 25; + int pipe_spawn_rand_int = rand() % 90 + 25; float pipe_spawn_rand = float(pipe_spawn_rand_int) / 100; + bool pos_reset = false; + Pipe() { auto pipe_image = paradiso::BitmapIO::get().load("pipe-green.png"); @@ -97,10 +107,43 @@ struct Pipe { .rotation = 3.1415926f}; pipe_bottom = paradiso::Sprite{ .bitmap = pipe_image, - .pivot = {paradiso::Vector2::make(0.0f, pipe_spawn_rand - 1.6f)}, + .pivot = {paradiso::Vector2::make(0.0f, pipe_spawn_rand - 1.5f)}, .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 320.0f)) / 700.0f) * 2.25f)}}; } + void update() { + pipe_spawn_rand_int = rand() % 90 + 20; + pipe_spawn_rand = float(pipe_spawn_rand_int) / 100; + + pipe_top.pivot.x() -= 0.02f; + pipe_bottom.pivot.x() -= 0.02f; + + risky_pos_x = pipe_top.pivot.x(); + risky_pos_max_x = + pipe_top.pivot.x() + ((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f; + + risky_pos_top_y = pipe_top.pivot.y(); + risky_pos_top_max_y = pipe_top.pivot.y() + 10.0f; + + // std::cout << risky_pos_top_x << std::endl; + // std::cout << risky_pos_top_max_x << std::endl; + + if (pipe_top.pivot.x() <= -1.4f || pipe_bottom.pivot.x() <= -1.4f) { + pos_reset = true; + + if (pos_reset == true) { + pipe_top.pivot.y() = pipe_spawn_rand + 1.0f; + pipe_bottom.pivot.y() = pipe_spawn_rand - 1.5; + + pos_reset = false; + } + + pipe_top.pivot.x() = 1.4f; + pipe_bottom.pivot.x() = 1.4f; + } + + } + void draw(const paradiso::Shader& shader) { shader.set_uniform("pivot", pipe_bottom.pivot); shader.set_uniform("scale", pipe_bottom.scale); @@ -137,7 +180,7 @@ struct Grass { if (sprite->pivot.x() <= -1.0f) { sprite->pivot.x() += 2.0f; } - sprite->pivot.x() -= 0.03f; + sprite->pivot.x() -= 0.02f; shader.set_uniform("pivot", sprite->pivot); shader.set_uniform("scale", sprite->scale); shader.set_uniform("rotation", sprite->rotation); @@ -158,10 +201,10 @@ struct QuickWings { unsigned int flapCounter = 0; // How many ticks since last flap float velocity = 0.0f; - const float max_velocity = 0.04f; + const float max_velocity = 0.02f; - const float gravity = -0.004f; - const float move_up_velocity = 0.04f; + const float gravity = -0.002f; + const float move_up_velocity = 0.02f; bool move_up = false; bool paused = true; @@ -231,8 +274,9 @@ struct QuickWings { } // Stop game - if (paused) + if (paused) { return; + } else { // Apply gravity velocity += gravity; @@ -262,6 +306,19 @@ struct QuickWings { // Update rotation rotation = velocity * 10.0f; } + + std::cout << risky_pos_top_y << std::endl; + std::cout << risky_pos_top_max_y << std::endl; + + std::cout << pos << std::endl; + std::cout << "\n\n" << std::endl; + + if (risky_pos_x <= 0.0f && risky_pos_max_x >= 0.0f) { + if (pos >= risky_pos_top_y && pos <= risky_pos_top_max_y) { + game_over = true; + std::cout << "collision!" << std::endl; + } + } } // keyboard handler @@ -402,7 +459,9 @@ auto main() -> int { ctx.clear(); auto t1 = std::chrono::high_resolution_clock::now(); - // Keyboard and state change + // Keyboard and state change + update + pipe.update(); + quickwingsapp.on_keyboard(w.keyboard_input()); quickwingsapp.update(); From 5a9eb10507613a28b3d59d751e1be4c42bfcf1e3 Mon Sep 17 00:00:00 2001 From: brxxh <11dac2t@huhn-online.de> Date: Fri, 24 Nov 2023 17:43:17 +0100 Subject: [PATCH 12/28] finally added pipes + collision --- examples/quickwings/quickwings.cpp | 128 ++++++++++++++++++----------- 1 file changed, 81 insertions(+), 47 deletions(-) diff --git a/examples/quickwings/quickwings.cpp b/examples/quickwings/quickwings.cpp index 875f838..f8a4995 100644 --- a/examples/quickwings/quickwings.cpp +++ b/examples/quickwings/quickwings.cpp @@ -46,6 +46,8 @@ struct Background { paradiso::Sprite* scrolling[2] = {&backgroundLeft, &backgroundRight}; + paradiso::Renderer renderer{}; + Background() { auto backgroundImage = paradiso::BitmapIO::get().load("background-day.png"); @@ -71,18 +73,18 @@ struct Background { void draw(const paradiso::Shader& shader) { for (auto sprite : scrolling) { - if (sprite->pivot.x() <= -2.0f) { - sprite->pivot.x() += 4.0f; + if (game_over == false) { + if (sprite->pivot.x() <= -2.0f) { + sprite->pivot.x() += 4.0f; + } + sprite->pivot.x() -= 0.002f; } - sprite->pivot.x() -= 0.002f; shader.set_uniform("pivot", sprite->pivot); shader.set_uniform("scale", sprite->scale); shader.set_uniform("rotation", sprite->rotation); renderer.draw(*sprite, shader); } } - - paradiso::Renderer renderer{}; }; struct Pipe { @@ -92,7 +94,9 @@ struct Pipe { paradiso::Renderer renderer1{}; paradiso::Renderer renderer2{}; - int pipe_spawn_rand_int = rand() % 90 + 25; + bool paused = false; + + int pipe_spawn_rand_int = rand() % 80 + 15; float pipe_spawn_rand = float(pipe_spawn_rand_int) / 100; bool pos_reset = false; @@ -102,46 +106,57 @@ struct Pipe { pipe_top = paradiso::Sprite{ .bitmap = pipe_image, - .pivot = {paradiso::Vector2::make(0.0f, pipe_spawn_rand + 1.0f)}, + .pivot = {paradiso::Vector2::make(1.4f, pipe_spawn_rand + 1.0f)}, .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 320.0f)) / 700.0f) * 2.25f)}, .rotation = 3.1415926f}; pipe_bottom = paradiso::Sprite{ .bitmap = pipe_image, - .pivot = {paradiso::Vector2::make(0.0f, pipe_spawn_rand - 1.5f)}, + .pivot = {paradiso::Vector2::make(1.4f, pipe_spawn_rand - 1.5f)}, .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 320.0f)) / 700.0f) * 2.25f)}}; + + paused = true; + } void update() { - pipe_spawn_rand_int = rand() % 90 + 20; - pipe_spawn_rand = float(pipe_spawn_rand_int) / 100; - pipe_top.pivot.x() -= 0.02f; - pipe_bottom.pivot.x() -= 0.02f; - - risky_pos_x = pipe_top.pivot.x(); - risky_pos_max_x = - pipe_top.pivot.x() + ((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f; - - risky_pos_top_y = pipe_top.pivot.y(); - risky_pos_top_max_y = pipe_top.pivot.y() + 10.0f; - - // std::cout << risky_pos_top_x << std::endl; - // std::cout << risky_pos_top_max_x << std::endl; - - if (pipe_top.pivot.x() <= -1.4f || pipe_bottom.pivot.x() <= -1.4f) { - pos_reset = true; - - if (pos_reset == true) { - pipe_top.pivot.y() = pipe_spawn_rand + 1.0f; - pipe_bottom.pivot.y() = pipe_spawn_rand - 1.5; - - pos_reset = false; - } - - pipe_top.pivot.x() = 1.4f; - pipe_bottom.pivot.x() = 1.4f; + if (game_over == true) { + paused = true; } + if (paused == true) { + return; + } + else { + pipe_spawn_rand_int = rand() % 80 + 15; + pipe_spawn_rand = float(pipe_spawn_rand_int) / 100; + + pipe_top.pivot.x() -= 0.02f; + pipe_bottom.pivot.x() -= 0.02f; + + risky_pos_x = pipe_top.pivot.x(); + risky_pos_max_x = pipe_top.pivot.x() + ((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f; + + risky_pos_top_y = pipe_top.pivot.y(); + risky_pos_top_max_y = pipe_top.pivot.y() + 10.0f; + + risky_pos_bottom_y = pipe_bottom.pivot.y(); + risky_pos_bottom_max_y = pipe_bottom.pivot.y() - 10.0f; + + if (pipe_top.pivot.x() <= -1.4f || pipe_bottom.pivot.x() <= -1.4f) { + pos_reset = true; + + if (pos_reset == true) { + pipe_top.pivot.y() = pipe_spawn_rand + 1.0f; + pipe_bottom.pivot.y() = pipe_spawn_rand - 1.5; + + pos_reset = false; + } + + pipe_top.pivot.x() = 1.4f; + pipe_bottom.pivot.x() = 1.4f; + } + } } void draw(const paradiso::Shader& shader) { @@ -177,10 +192,12 @@ struct Grass { void draw(const paradiso::Shader& shader) { for (auto sprite : scrolling) { - if (sprite->pivot.x() <= -1.0f) { - sprite->pivot.x() += 2.0f; + if (game_over == false) { + if (sprite->pivot.x() <= -1.0f) { + sprite->pivot.x() += 2.0f; + } + sprite->pivot.x() -= 0.02f; } - sprite->pivot.x() -= 0.02f; shader.set_uniform("pivot", sprite->pivot); shader.set_uniform("scale", sprite->scale); shader.set_uniform("rotation", sprite->rotation); @@ -216,6 +233,8 @@ struct QuickWings { float rotation = 0.0f; + int collision_counter = 0; + QuickWings() { float scaleh = 0.08f; float scalew = 0.158f; @@ -307,16 +326,26 @@ struct QuickWings { rotation = velocity * 10.0f; } - std::cout << risky_pos_top_y << std::endl; - std::cout << risky_pos_top_max_y << std::endl; + float final_risky_pos_top_y = risky_pos_top_y - 1.06f; + float final_risky_pos_bottom_y = risky_pos_bottom_y + 1.06f; - std::cout << pos << std::endl; - std::cout << "\n\n" << std::endl; - - if (risky_pos_x <= 0.0f && risky_pos_max_x >= 0.0f) { - if (pos >= risky_pos_top_y && pos <= risky_pos_top_max_y) { + if (risky_pos_x - 0.3f <= 0.0f && risky_pos_max_x >= 0.0f) { + if (pos >= final_risky_pos_top_y && pos <= risky_pos_top_max_y) { game_over = true; - std::cout << "collision!" << std::endl; + } + if (pos <= final_risky_pos_bottom_y && pos >= risky_pos_bottom_max_y) { + if (collision_counter == 0) { + collision_counter++; + std::cout << "incremented!" << std::endl; + } + else { + collision_counter = 2; + } + + + if (collision_counter == 2) { + game_over = true; + } } } } @@ -447,6 +476,7 @@ auto main() -> int { auto message = Message{}; auto gameover = GameOverMessage{}; + // timer // das update führt den hier mitgegebnen Ausdruck innerhalb der internen @@ -460,6 +490,10 @@ auto main() -> int { auto t1 = std::chrono::high_resolution_clock::now(); // Keyboard and state change + update + if (quickwingsapp.paused == false) { + pipe.paused = false; + } + pipe.update(); quickwingsapp.on_keyboard(w.keyboard_input()); @@ -490,7 +524,7 @@ auto main() -> int { // Quit return !(w.keyboard_input().size() && w.keyboard_input().top().key == 'Q'); - })) { + })) { }; return 0; From e37a74137dfc48931a898c2377050fbea28256b7 Mon Sep 17 00:00:00 2001 From: brxxh <11dac2t@huhn-online.de> Date: Fri, 24 Nov 2023 18:13:58 +0100 Subject: [PATCH 13/28] fixed grass again, didn't help lol --- examples/quickwings/assets/base.png | Bin 2300 -> 1963 bytes examples/quickwings/quickwings.cpp | 41 ++++++++++++++++++---------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/examples/quickwings/assets/base.png b/examples/quickwings/assets/base.png index 2ba45d32091724ae7160522722bb3cfa63d3a345..26fa39129aa33fe2b906d9b77751651fee1a2272 100644 GIT binary patch literal 1963 zcmeAS@N?(olHy`uVBq!ia0y~yVEh4O7jUov$xnNd>VN`yna<7unaRlv3>p(lC)#=+ z4iIUZALhETtBKE5#wesPBT(c>;OhrLORjL$>E`A{E$mdxocKs;J$1i)nn?v$}b`YemTRxlJ2O0S* zx2*m*aWO(Zg09NG6GcCXba-r4*}T8j*?wPU*wMwOZ!c?6?$fdS*ygJ1b-gFV`Ad&Y zrI*(C`<1(nohVpZ9W63T&i4IQ{#n}}u6|QFzkS~KQWjqRg1oDLR!_QoWA}@vv&3$- z_wicnU6J`x*5Y={gS~T$g6xBubM_}5IL*1`yz_O_EqY;_R?RD}VLw^=(=~jyk%O;PHSfSq=|b^!PEybFoTr4H+OtG!Y2&-LKR@Rz`846h&v&_g^Mtp* zkK6li=f`daMkW>x0S`_aucd-*5Y7+X4S)YVo-Dm5Rl%VFC}hZJ{^N$jQAIFkJJW6c z__#Tx&Gp~D{ERFzzrSzZ*Wb1OtinJKhO9c6SiA??9b1IHFq97|K(FrE zDEFVwZ12-{*(KZ6xHY!_O0)YnGyD9vV&C-54-cn{toZw9*TMeFUwuFhWKm*L&;PLR z<~siw{PP1Bd^=lzX4{vX|I$jW#+KXA%oPU1d@ekSg$rBHM{|>aG{>2+vNRV>8dG~tu;U$kht9L#Pw>zzOS#!Q; z($A^qH=Qmyl|Ct=?&;FyCqj5=tbWPD3CqYnvZRLI=x4)+NE!!tyP_#A90m|hq zVFJl9G@f-kc$*0v4FVzo9}X_;f&_!e9$AnyBa6ZoJ&!ug)=2L@6IasHQwyG?$l97%Z~1N_Wz9G zPrWoV4zrSpJzp+3mU+m7UKn)RFbxXnPX_t$m{u=kX zWTZCC$lLYp#+8t!`s>Ga6+`oXg{=So{_jqu?rGUhD;z6sY?1YkSf;q~(akRN*4t<2 z?9-@Gxbyl%!=dS3=1g@#b9jIFZk+7Z=N$3%$|n08KMtmy)8zQh;m-YYQshkcTF=R$ zb7oGvrMa7Xx{C0Tiv}7SUF7=hR=S>ilOJDy)BNP73ZKf`YaVqdd;9I#yJ*^y)vBh- zyHx$>g--qb-sbL^3ketYYVwu#@B1&+{44jztxtc?JKz6r)ijIULO<;9=}DJQ?0yj) zs=JF{_jN&4;ME>ki`xx-)zRf&Hial#&pCPEG^fe(g>R*#o;R=2dMMgV7lM`SSr1K$x4W}K?cC(XdXZsO_U7*Y}U_O4@AaG=QX zhb~O-4tI7a@ZD|X;44+lJFru_P<)+JSMhd5QLQTrRNk}X)t`OvdP{%#q3gx(|K6YM z_+9?qp1pT}DmpYUFfy@l2q*|}+H}6saE5Um9{45v|9o9sIN&T?$pp?B4QW@n1Qnnn zcYGb}YpY8yvV1xEdAj(?yMKPvUHp8neqJ~K{A9-0uWRf-JS^5p_`jw8mi_aIZx(*{ z7ryZG{-Mbr+rTDpv+!Lm-(k562>rrO=Y79m?*88Vrt!_$>)oGE|9twVX}tc`pGizs z|7TZBg1XWnq4B^omMdp30%764ORHu-{vsT?|JwSm*0H+#cHWq@Y5&h>sZY)I)fPl+ zpL@>Qe|!Gh^R=O$zJLGr{Pmsrz7EfA z-*|$91L(j;R;K^H4tLjp;B)QMXMb7cUt4ZB_3zn#Y4w};-<1EyVe{>0Dw9=w_dFF? z7)2-)*fW|+8UW#p^(&6=v;6nlb8Y%X?v`F>lMyeYkY-d}bfU^vWsifj-2WMLqj z{L{E=;XV=Lcw=8zSGN0sZJZ-Kt`bxdn5>dM z2|!}fq2Yj5*tQ2tg3Nxa?K}(@w*_|$U0^?Xv1vA1yK~%sYIPWOjdX@lNm=OvSxHuMQ zZcl>yjA?}&ER70yu(Dj35^V^JR7S=S{!#BSjmF++;^Yt*QF-r!^v4(B@hP)|n1Gck NgQu&X%Q~loCIAIj%eDXj diff --git a/examples/quickwings/quickwings.cpp b/examples/quickwings/quickwings.cpp index f8a4995..a49f5c6 100644 --- a/examples/quickwings/quickwings.cpp +++ b/examples/quickwings/quickwings.cpp @@ -176,33 +176,44 @@ struct Grass { paradiso::Sprite grassRight; paradiso::Sprite* scrolling[2] = {&grassLeft, &grassRight}; - paradiso::Renderer renderer{}; + paradiso::Renderer renderer1{}; + paradiso::Renderer renderer2{}; Grass() { auto grassImage = paradiso::BitmapIO::get().load("base.png"); grassLeft = paradiso::Sprite{ .bitmap = grassImage, - .pivot = {paradiso::Vector2::make(1.0f, -0.9f)}, - .scale = {paradiso::Vector2::make(2.0f, 0.33333f)}}; + .pivot = {paradiso::Vector2::make(0.0f, -0.9f)}, + .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 504.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 112.0f)) / 700.0f) * 2.25f)}}; grassRight = paradiso::Sprite{ .bitmap = grassImage, - .pivot = {paradiso::Vector2::make(1.0f, -0.9f)}, - .scale = {paradiso::Vector2::make(2.6f, 0.33333f)}}; + .pivot = {paradiso::Vector2::make(1.002f, -0.9f)}, + .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 504.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 112.0f)) / 700.0f) * 2.25f)}}; } void draw(const paradiso::Shader& shader) { - for (auto sprite : scrolling) { - if (game_over == false) { - if (sprite->pivot.x() <= -1.0f) { - sprite->pivot.x() += 2.0f; - } - sprite->pivot.x() -= 0.02f; + if (game_over == false) { + grassLeft.pivot.x() -= 0.02f; + grassRight.pivot.x() -= 0.02f; + + if (grassRight.pivot.x() <= 0.0f) { + grassLeft.pivot.x() = 1.002f; + } + if (grassRight.pivot.x() <= -1.002f) { + grassRight.pivot.x() = 1.002f; } - shader.set_uniform("pivot", sprite->pivot); - shader.set_uniform("scale", sprite->scale); - shader.set_uniform("rotation", sprite->rotation); - renderer.draw(*sprite, shader); } + + shader.set_uniform("pivot", grassLeft.pivot); + shader.set_uniform("scale", grassLeft.scale); + shader.set_uniform("rotation", grassLeft.rotation); + + shader.set_uniform("pivot", grassRight.pivot); + shader.set_uniform("scale", grassRight.scale); + shader.set_uniform("rotation", grassRight.rotation); + + renderer1.draw(grassLeft, shader); + renderer2.draw(grassRight, shader); } }; From b124afdedfa1004faf5bd7bd12337228513a1fb5 Mon Sep 17 00:00:00 2001 From: brxxh <11dac2t@huhn-online.de> Date: Fri, 24 Nov 2023 18:45:37 +0100 Subject: [PATCH 14/28] final quickwings commit --- examples/quickwings/quickwings.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/quickwings/quickwings.cpp b/examples/quickwings/quickwings.cpp index a49f5c6..2d8bd96 100644 --- a/examples/quickwings/quickwings.cpp +++ b/examples/quickwings/quickwings.cpp @@ -347,13 +347,11 @@ struct QuickWings { if (pos <= final_risky_pos_bottom_y && pos >= risky_pos_bottom_max_y) { if (collision_counter == 0) { collision_counter++; - std::cout << "incremented!" << std::endl; } else { collision_counter = 2; } - if (collision_counter == 2) { game_over = true; } From e92dadaf4d9b7b02abd15af651fd3426f7bdf732 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Tue, 28 May 2024 23:06:08 +0200 Subject: [PATCH 15/28] properly use std::clamp --- examples/pong/pong.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/examples/pong/pong.cpp b/examples/pong/pong.cpp index 11f89f0..2b979f7 100644 --- a/examples/pong/pong.cpp +++ b/examples/pong/pong.cpp @@ -1,7 +1,7 @@ /** * paradiso - Paradigmen der Softwareentwicklung * - * (c) Copyright 2023 Hartmut Seichter + * (c) Copyright 2023-2024 Hartmut Seichter * */ @@ -16,7 +16,6 @@ #include -#include #include struct PongStage { @@ -86,7 +85,7 @@ struct PongPaddle { velocity_horizontal *= whoopiness; sprite.pivot.x() += velocity_horizontal; - std::clamp(sprite.pivot.x(), -0.5f, 0.5f); + sprite.pivot.x() = std::clamp(sprite.pivot.x(), -0.5f, 0.5f); // update shader uniforms shader.set_uniform("pivot", sprite.pivot); @@ -151,7 +150,7 @@ struct PongBall { void draw(const paradiso::Shader& shader) { - std::clamp(sprite.pivot.x(), -0.5f, 0.5f); + sprite.pivot.x() = std::clamp(sprite.pivot.x(), -0.5f, 0.5f); // update shader uniforms shader.set_uniform("pivot", sprite.pivot); @@ -166,6 +165,9 @@ struct PongBall { paradiso::Renderer renderer{}; constexpr void push(const auto& impulse) noexcept { velocity += impulse; } + + constexpr void whoop(const auto& whoopiness) noexcept { velocity *= whoopiness; } + }; auto main() -> int { @@ -234,6 +236,19 @@ auto main() -> int { ball.sprite.pivot.x() = 0.0f; ball.sprite.pivot.y() = 0.9f; } + // speed adjust + if (w.keyboard_input().top().key == 'N') { + + std::cout << "Speed Up!\n"; + + ball.push(paradiso::Vector2::make(0.f,0.01f)); + + } else if (w.keyboard_input().top().key == 'M') { + + ball.push(paradiso::Vector2::make(0.f,-0.01f)); + + std::cout << "Speed Lower!\n"; + } } ball.interact(stage); @@ -251,4 +266,4 @@ auto main() -> int { }; return 0; -} \ No newline at end of file +} From 945adb53c90b0b8a22d4a23762bf52aea08ee7f2 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Tue, 28 May 2024 23:16:19 +0200 Subject: [PATCH 16/28] updated copyright --- src/lib/include/paradiso/aabb.hpp | 4 ++-- src/lib/include/paradiso/bitmap.hpp | 4 ++-- src/lib/include/paradiso/bitmap_io.hpp | 4 ++-- src/lib/include/paradiso/context.hpp | 2 +- src/lib/include/paradiso/geometry.hpp | 4 ++-- src/lib/include/paradiso/globals.hpp | 4 ++-- src/lib/include/paradiso/matrix.hpp | 4 ++-- src/lib/include/paradiso/matrixbase.hpp | 4 ++-- src/lib/include/paradiso/renderer.hpp | 2 +- src/lib/include/paradiso/rgba.hpp | 4 ++-- src/lib/include/paradiso/shader.hpp | 4 ++-- src/lib/include/paradiso/sprite.hpp | 4 ++-- src/lib/include/paradiso/vector.hpp | 4 ++-- src/lib/include/paradiso/window.hpp | 4 ++-- src/lib/src/bitmap_io.cpp | 4 ++-- src/lib/src/context.cpp | 4 ++-- src/lib/src/renderer.cpp | 4 ++-- src/lib/src/shader.cpp | 2 +- src/lib/src/shader_sprite.hpp | 6 +++--- src/lib/src/window.cpp | 2 +- 20 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/lib/include/paradiso/aabb.hpp b/src/lib/include/paradiso/aabb.hpp index 62267bf..cad123f 100644 --- a/src/lib/include/paradiso/aabb.hpp +++ b/src/lib/include/paradiso/aabb.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -59,4 +59,4 @@ struct AABB final { } // namespace paradiso -#endif \ No newline at end of file +#endif diff --git a/src/lib/include/paradiso/bitmap.hpp b/src/lib/include/paradiso/bitmap.hpp index d75d352..d6971f5 100644 --- a/src/lib/include/paradiso/bitmap.hpp +++ b/src/lib/include/paradiso/bitmap.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -106,4 +106,4 @@ struct Bitmap final { }; } // namespace paradiso -#endif \ No newline at end of file +#endif diff --git a/src/lib/include/paradiso/bitmap_io.hpp b/src/lib/include/paradiso/bitmap_io.hpp index 0ed2cff..af0c529 100644 --- a/src/lib/include/paradiso/bitmap_io.hpp +++ b/src/lib/include/paradiso/bitmap_io.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -53,4 +53,4 @@ struct BitmapIO { } // namespace paradiso -#endif \ No newline at end of file +#endif diff --git a/src/lib/include/paradiso/context.hpp b/src/lib/include/paradiso/context.hpp index f53495a..31a9ac1 100644 --- a/src/lib/include/paradiso/context.hpp +++ b/src/lib/include/paradiso/context.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib/include/paradiso/geometry.hpp b/src/lib/include/paradiso/geometry.hpp index e3a8393..acd018a 100644 --- a/src/lib/include/paradiso/geometry.hpp +++ b/src/lib/include/paradiso/geometry.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -71,4 +71,4 @@ struct Rectangle final { }; } // namespace paradiso -#endif \ No newline at end of file +#endif diff --git a/src/lib/include/paradiso/globals.hpp b/src/lib/include/paradiso/globals.hpp index 3c126ed..440bc7d 100644 --- a/src/lib/include/paradiso/globals.hpp +++ b/src/lib/include/paradiso/globals.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -41,4 +41,4 @@ -#endif \ No newline at end of file +#endif diff --git a/src/lib/include/paradiso/matrix.hpp b/src/lib/include/paradiso/matrix.hpp index f5c87e0..c359a87 100644 --- a/src/lib/include/paradiso/matrix.hpp +++ b/src/lib/include/paradiso/matrix.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,7 +32,7 @@ namespace paradiso { template struct Matrix : MatrixBase> { - Scalar data[R * C]{}; + Scalar data[R * C]{}; static constexpr std::size_t rows{R}; static constexpr std::size_t cols{C}; diff --git a/src/lib/include/paradiso/matrixbase.hpp b/src/lib/include/paradiso/matrixbase.hpp index 491102b..b20a8d4 100644 --- a/src/lib/include/paradiso/matrixbase.hpp +++ b/src/lib/include/paradiso/matrixbase.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -144,4 +144,4 @@ template struct MatrixBase { }; } // namespace paradiso -#endif \ No newline at end of file +#endif diff --git a/src/lib/include/paradiso/renderer.hpp b/src/lib/include/paradiso/renderer.hpp index 2f349de..b52a908 100644 --- a/src/lib/include/paradiso/renderer.hpp +++ b/src/lib/include/paradiso/renderer.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib/include/paradiso/rgba.hpp b/src/lib/include/paradiso/rgba.hpp index 0ab6ec4..d7745e2 100644 --- a/src/lib/include/paradiso/rgba.hpp +++ b/src/lib/include/paradiso/rgba.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -90,4 +90,4 @@ struct RGBA final { }; } // namespace paradiso -#endif \ No newline at end of file +#endif diff --git a/src/lib/include/paradiso/shader.hpp b/src/lib/include/paradiso/shader.hpp index 549fe7d..d51f6cf 100644 --- a/src/lib/include/paradiso/shader.hpp +++ b/src/lib/include/paradiso/shader.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -58,7 +58,7 @@ struct Shader final { const Shader& set_uniform_at_location(int location, float v) const; //!< sets a float in a shader - + const Shader& set_uniform_at_location( int location, uint32_t v) const; //!< sets a 32bit unsigned in a shader diff --git a/src/lib/include/paradiso/sprite.hpp b/src/lib/include/paradiso/sprite.hpp index 34a024b..a518e51 100644 --- a/src/lib/include/paradiso/sprite.hpp +++ b/src/lib/include/paradiso/sprite.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -72,4 +72,4 @@ struct Sprite final { }; } // namespace paradiso -#endif \ No newline at end of file +#endif diff --git a/src/lib/include/paradiso/vector.hpp b/src/lib/include/paradiso/vector.hpp index 647f8cf..2012ef5 100644 --- a/src/lib/include/paradiso/vector.hpp +++ b/src/lib/include/paradiso/vector.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -82,4 +82,4 @@ template struct Vector3 : Matrix<3, 1, T> { }; // namespace paradiso -#endif \ No newline at end of file +#endif diff --git a/src/lib/include/paradiso/window.hpp b/src/lib/include/paradiso/window.hpp index 6613b99..91337ac 100644 --- a/src/lib/include/paradiso/window.hpp +++ b/src/lib/include/paradiso/window.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -89,4 +89,4 @@ struct Window final { } // namespace paradiso -#endif \ No newline at end of file +#endif diff --git a/src/lib/src/bitmap_io.cpp b/src/lib/src/bitmap_io.cpp index fabfda3..3490669 100644 --- a/src/lib/src/bitmap_io.cpp +++ b/src/lib/src/bitmap_io.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -138,4 +138,4 @@ std::string BitmapIO::path() const } -} // namespace paradiso \ No newline at end of file +} // namespace paradiso diff --git a/src/lib/src/context.cpp b/src/lib/src/context.cpp index 031ca07..6ef465c 100644 --- a/src/lib/src/context.cpp +++ b/src/lib/src/context.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -71,7 +71,7 @@ struct Context::impl { Context::Context() : impl_(std::make_unique()) {} -Context::~Context() {} +Context::~Context() = default; Context& Context::set_blend() { return *this; } diff --git a/src/lib/src/renderer.cpp b/src/lib/src/renderer.cpp index 3c5853d..ab03c23 100644 --- a/src/lib/src/renderer.cpp +++ b/src/lib/src/renderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,7 +34,7 @@ #include #include -#if defined(_WIN32) +#if defined(_WIN32) #undef max #endif diff --git a/src/lib/src/shader.cpp b/src/lib/src/shader.cpp index 7a6b04e..e3d6b73 100644 --- a/src/lib/src/shader.cpp +++ b/src/lib/src/shader.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib/src/shader_sprite.hpp b/src/lib/src/shader_sprite.hpp index fc4c15d..1f546c9 100644 --- a/src/lib/src/shader_sprite.hpp +++ b/src/lib/src/shader_sprite.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,7 +34,7 @@ layout (location = 2) in vec2 texture_coords; // pivot der sprite uniform vec2 pivot = vec2( 0.0, 0.0 ); -// scale +// scale uniform vec2 scale = vec2( 1.0, 1.0 ); // rotation uniform float rotation = 0.0; @@ -80,4 +80,4 @@ void main() { })"; } // namespace paradiso -#endif \ No newline at end of file +#endif diff --git a/src/lib/src/window.cpp b/src/lib/src/window.cpp index 4962439..a264dcf 100644 --- a/src/lib/src/window.cpp +++ b/src/lib/src/window.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Hartmut Seichter + * Copyright 2023-2024 Hartmut Seichter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal From a61d10bb563a6dcf34e868eb7b86d27809e11eac Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Tue, 28 May 2024 23:33:10 +0200 Subject: [PATCH 17/28] removed cruft from quickwings --- examples/quickwings/quickwings.cpp | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/examples/quickwings/quickwings.cpp b/examples/quickwings/quickwings.cpp index 2d8bd96..9df112b 100644 --- a/examples/quickwings/quickwings.cpp +++ b/examples/quickwings/quickwings.cpp @@ -1,14 +1,10 @@ /** * paradiso - Paradigmen der Softwareentwicklung * - * (c) Copyright 2023 Hartmut Seichter, Robin Rottstädt, brxxh (Hannes Brothuhn) + * (c) Copyright 2023-2024 Hartmut Seichter, Robin Rottstädt, brxxh (Hannes Brothuhn) * */ -#include -#include -#include -#include #include #include #include @@ -20,14 +16,7 @@ #include #include -#include -#include #include -#include -#include -#include - -// #include "lib/image_loader.hpp" const int frame_rate = 60; bool game_over = false; @@ -115,7 +104,7 @@ struct Pipe { .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 320.0f)) / 700.0f) * 2.25f)}}; paused = true; - + } void update() { @@ -163,7 +152,7 @@ struct Pipe { shader.set_uniform("pivot", pipe_bottom.pivot); shader.set_uniform("scale", pipe_bottom.scale); renderer1.draw(pipe_bottom, shader); - + shader.set_uniform("pivot", pipe_top.pivot); shader.set_uniform("scale", pipe_top.scale); shader.set_uniform("rotation", pipe_top.rotation); @@ -302,12 +291,12 @@ struct QuickWings { if (game_over == true) { paused = true; } - + // Stop game if (paused) { return; } - else { + else { // Apply gravity velocity += gravity; @@ -406,7 +395,7 @@ struct Message { messageSprite.pivot.y() = pos; } } - + void on_keyboard(const paradiso::Window::KeyboardInputStack& input) { if (input.size()) { start = true; @@ -517,7 +506,7 @@ auto main() -> int { grass.draw(shader); message.draw(shader); - if (game_over == true) { + if (game_over == true) { gameover.draw(shader); } From 8375917b357a647a0063bd2ca4b3c36b00edc9f5 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Thu, 30 May 2024 08:10:06 +0200 Subject: [PATCH 18/28] add some 'inspiration' for work in the course ParadiSE --- docs/README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..623fb6d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,17 @@ + +# Todo + +Here some ideas for improving this tiny engine: + +## Rendering +- [ ] replace the OpenGL renderer with a Vulkan backend +- [ ] add animatable sprites (access to UV mapping and tiling) + +## Game Support +- [ ] audio! +- [ ] some minimal animation system with tweening with different f-curves + +## System Level + +- [ ] add a `Asset` handler to load cache and manage assets +- [ ] introspection of file system if we load assset From d1f0ad538e7d673eb109195bddc6663bd5287092 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Thu, 30 May 2024 08:13:44 +0200 Subject: [PATCH 19/28] some additional ideas --- docs/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/README.md b/docs/README.md index 623fb6d..93b4603 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,12 +6,22 @@ Here some ideas for improving this tiny engine: ## Rendering - [ ] replace the OpenGL renderer with a Vulkan backend - [ ] add animatable sprites (access to UV mapping and tiling) +- [ ] add a SDF based renderer (parametric tiles and font rendering) ## Game Support - [ ] audio! - [ ] some minimal animation system with tweening with different f-curves + ## System Level - [ ] add a `Asset` handler to load cache and manage assets - [ ] introspection of file system if we load assset + +## Design + +- [ ] replace some of the 'unkown source' assets + +## Build / Dev Support +- [ ] add a test rig either with Snitch or Catch2 +- [ ] write some reasonable testcases From b9faf6c22cce6ca83d1b84cb4ca7d341ff63e3c8 Mon Sep 17 00:00:00 2001 From: Hartmut Date: Thu, 30 May 2024 09:07:24 +0200 Subject: [PATCH 20/28] add a excerpt for perf run showing performance issues --- docs/README.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 93b4603..92a878e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,3 @@ - # Todo Here some ideas for improving this tiny engine: @@ -25,3 +24,27 @@ Here some ideas for improving this tiny engine: ## Build / Dev Support - [ ] add a test rig either with Snitch or Catch2 - [ ] write some reasonable testcases + + +# Issues + + + +```sh + Performance counter stats for 'bin/paradiso_pong': + + 555,35 msec task-clock:u # 0,042 CPUs utilized + 0 context-switches:u # 0,000 /sec + 0 cpu-migrations:u # 0,000 /sec + 4.072 page-faults:u # 7,332 K/sec + 319.484.735 cycles:u # 0,575 GHz + 358.165.995 instructions:u # 1,12 insn per cycle + 86.037.942 branches:u # 154,926 M/sec + 2.469.068 branch-misses:u # 2,87% of all branches + + 13,092775373 seconds time elapsed + + 0,311565000 seconds user + 0,247491000 seconds sys +``` +above run with `perf stat bin/paradiso_pong` shows some really bad performance issues. \ No newline at end of file From cdf2cbd6c015b3dca75c99e5525181e66226a486 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Tue, 4 Jun 2024 21:35:12 +0200 Subject: [PATCH 21/28] add more info about performance issues --- docs/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/README.md b/docs/README.md index 92a878e..64ecc08 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,27 +24,27 @@ Here some ideas for improving this tiny engine: ## Build / Dev Support - [ ] add a test rig either with Snitch or Catch2 - [ ] write some reasonable testcases +- [ ] add CPU and GPU benchmarks to address various issues # Issues - ```sh Performance counter stats for 'bin/paradiso_pong': - 555,35 msec task-clock:u # 0,042 CPUs utilized - 0 context-switches:u # 0,000 /sec - 0 cpu-migrations:u # 0,000 /sec - 4.072 page-faults:u # 7,332 K/sec - 319.484.735 cycles:u # 0,575 GHz - 358.165.995 instructions:u # 1,12 insn per cycle - 86.037.942 branches:u # 154,926 M/sec - 2.469.068 branch-misses:u # 2,87% of all branches + 555,35 msec task-clock:u # 0,042 CPUs utilized + 0 context-switches:u # 0,000 /sec + 0 cpu-migrations:u # 0,000 /sec + 4.072 page-faults:u # 7,332 K/sec + 319.484.735 cycles:u # 0,575 GHz + 358.165.995 instructions:u # 1,12 insn per cycle + 86.037.942 branches:u # 154,926 M/sec + 2.469.068 branch-misses:u # 2,87% of all branches 13,092775373 seconds time elapsed 0,311565000 seconds user 0,247491000 seconds sys ``` -above run with `perf stat bin/paradiso_pong` shows some really bad performance issues. \ No newline at end of file +above run with `perf stat bin/paradiso_pong` shows some really bad performance issues. From 1779f750ff960d9b1cb383708633e1de64cef118 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Tue, 4 Jun 2024 22:00:57 +0200 Subject: [PATCH 22/28] added CC0 assets from kenney.nl to replace the existing ones --- .../tappybird/Font/kenvector_future.ttf | Bin 0 -> 34136 bytes .../tappybird/Font/kenvector_future_thin.ttf | Bin 0 -> 34100 bytes .../assets/tappybird/PNG/Letters/letterA.png | Bin 0 -> 1611 bytes .../assets/tappybird/PNG/Letters/letterB.png | Bin 0 -> 1459 bytes .../assets/tappybird/PNG/Letters/letterC.png | Bin 0 -> 1911 bytes .../assets/tappybird/PNG/Letters/letterD.png | Bin 0 -> 1615 bytes .../assets/tappybird/PNG/Letters/letterE.png | Bin 0 -> 747 bytes .../assets/tappybird/PNG/Letters/letterF.png | Bin 0 -> 771 bytes .../assets/tappybird/PNG/Letters/letterG.png | Bin 0 -> 1832 bytes .../assets/tappybird/PNG/Letters/letterH.png | Bin 0 -> 795 bytes .../assets/tappybird/PNG/Letters/letterI.png | Bin 0 -> 448 bytes .../assets/tappybird/PNG/Letters/letterJ.png | Bin 0 -> 1106 bytes .../assets/tappybird/PNG/Letters/letterK.png | Bin 0 -> 1475 bytes .../assets/tappybird/PNG/Letters/letterL.png | Bin 0 -> 580 bytes .../assets/tappybird/PNG/Letters/letterM.png | Bin 0 -> 1934 bytes .../assets/tappybird/PNG/Letters/letterN.png | Bin 0 -> 1225 bytes .../assets/tappybird/PNG/Letters/letterO.png | Bin 0 -> 2085 bytes .../assets/tappybird/PNG/Letters/letterP.png | Bin 0 -> 1282 bytes .../assets/tappybird/PNG/Letters/letterQ.png | Bin 0 -> 2361 bytes .../assets/tappybird/PNG/Letters/letterR.png | Bin 0 -> 1539 bytes .../assets/tappybird/PNG/Letters/letterS.png | Bin 0 -> 1933 bytes .../assets/tappybird/PNG/Letters/letterT.png | Bin 0 -> 696 bytes .../assets/tappybird/PNG/Letters/letterU.png | Bin 0 -> 1306 bytes .../assets/tappybird/PNG/Letters/letterV.png | Bin 0 -> 1821 bytes .../assets/tappybird/PNG/Letters/letterW.png | Bin 0 -> 2358 bytes .../assets/tappybird/PNG/Letters/letterX.png | Bin 0 -> 1862 bytes .../assets/tappybird/PNG/Letters/letterY.png | Bin 0 -> 1458 bytes .../assets/tappybird/PNG/Letters/letterZ.png | Bin 0 -> 1257 bytes .../assets/tappybird/PNG/Numbers/number0.png | Bin 0 -> 2130 bytes .../assets/tappybird/PNG/Numbers/number1.png | Bin 0 -> 948 bytes .../assets/tappybird/PNG/Numbers/number2.png | Bin 0 -> 1726 bytes .../assets/tappybird/PNG/Numbers/number3.png | Bin 0 -> 2097 bytes .../assets/tappybird/PNG/Numbers/number4.png | Bin 0 -> 1275 bytes .../assets/tappybird/PNG/Numbers/number5.png | Bin 0 -> 1766 bytes .../assets/tappybird/PNG/Numbers/number6.png | Bin 0 -> 2172 bytes .../assets/tappybird/PNG/Numbers/number7.png | Bin 0 -> 1355 bytes .../assets/tappybird/PNG/Numbers/number8.png | Bin 0 -> 2373 bytes .../assets/tappybird/PNG/Numbers/number9.png | Bin 0 -> 2266 bytes .../tappybird/PNG/Planes/planeBlue1.png | Bin 0 -> 3370 bytes .../tappybird/PNG/Planes/planeBlue2.png | Bin 0 -> 3337 bytes .../tappybird/PNG/Planes/planeBlue3.png | Bin 0 -> 3307 bytes .../tappybird/PNG/Planes/planeGreen1.png | Bin 0 -> 3447 bytes .../tappybird/PNG/Planes/planeGreen2.png | Bin 0 -> 3414 bytes .../tappybird/PNG/Planes/planeGreen3.png | Bin 0 -> 3384 bytes .../assets/tappybird/PNG/Planes/planeRed1.png | Bin 0 -> 3400 bytes .../assets/tappybird/PNG/Planes/planeRed2.png | Bin 0 -> 3365 bytes .../assets/tappybird/PNG/Planes/planeRed3.png | Bin 0 -> 3329 bytes .../tappybird/PNG/Planes/planeYellow1.png | Bin 0 -> 3502 bytes .../tappybird/PNG/Planes/planeYellow2.png | Bin 0 -> 3468 bytes .../tappybird/PNG/Planes/planeYellow3.png | Bin 0 -> 3436 bytes .../assets/tappybird/PNG/UI/UIbg.png | Bin 0 -> 1351 bytes .../assets/tappybird/PNG/UI/buttonLarge.png | Bin 0 -> 826 bytes .../assets/tappybird/PNG/UI/buttonSmall.png | Bin 0 -> 832 bytes .../assets/tappybird/PNG/UI/medalBronze.png | Bin 0 -> 9309 bytes .../assets/tappybird/PNG/UI/medalGold.png | Bin 0 -> 8803 bytes .../assets/tappybird/PNG/UI/medalSilver.png | Bin 0 -> 7585 bytes .../assets/tappybird/PNG/UI/tap.png | Bin 0 -> 1581 bytes .../assets/tappybird/PNG/UI/tapLeft.png | Bin 0 -> 1201 bytes .../assets/tappybird/PNG/UI/tapRight.png | Bin 0 -> 1174 bytes .../assets/tappybird/PNG/UI/tapTick.png | Bin 0 -> 2507 bytes .../assets/tappybird/PNG/UI/textGameOver.png | Bin 0 -> 20351 bytes .../assets/tappybird/PNG/UI/textGetReady.png | Bin 0 -> 17057 bytes .../assets/tappybird/PNG/background.png | Bin 0 -> 13024 bytes .../assets/tappybird/PNG/groundDirt.png | Bin 0 -> 6278 bytes .../assets/tappybird/PNG/groundGrass.png | Bin 0 -> 6351 bytes .../assets/tappybird/PNG/groundIce.png | Bin 0 -> 6037 bytes .../assets/tappybird/PNG/groundRock.png | Bin 0 -> 6283 bytes .../assets/tappybird/PNG/groundSnow.png | Bin 0 -> 6589 bytes .../assets/tappybird/PNG/puffLarge.png | Bin 0 -> 448 bytes .../assets/tappybird/PNG/puffSmall.png | Bin 0 -> 291 bytes .../quickwings/assets/tappybird/PNG/rock.png | Bin 0 -> 4296 bytes .../assets/tappybird/PNG/rockDown.png | Bin 0 -> 4337 bytes .../assets/tappybird/PNG/rockGrass.png | Bin 0 -> 4965 bytes .../assets/tappybird/PNG/rockGrassDown.png | Bin 0 -> 5004 bytes .../assets/tappybird/PNG/rockIce.png | Bin 0 -> 4850 bytes .../assets/tappybird/PNG/rockIceDown.png | Bin 0 -> 4905 bytes .../assets/tappybird/PNG/rockSnow.png | Bin 0 -> 4737 bytes .../assets/tappybird/PNG/rockSnowDown.png | Bin 0 -> 4860 bytes .../assets/tappybird/PNG/starBronze.png | Bin 0 -> 1476 bytes .../assets/tappybird/PNG/starGold.png | Bin 0 -> 1458 bytes .../assets/tappybird/PNG/starSilver.png | Bin 0 -> 1353 bytes .../assets/tappybird/Spritesheet/planes.png | Bin 0 -> 35745 bytes .../assets/tappybird/Spritesheet/planes.xml | 14 + .../assets/tappybird/Spritesheet/sheet.png | Bin 0 -> 252033 bytes .../assets/tappybird/Spritesheet/sheet.xml | 81 +++ .../assets/tappybird/Vector/vector.svg | 510 ++++++++++++++++++ .../assets/tappybird/Vector/vector.swf | Bin 0 -> 48186 bytes .../quickwings/assets/tappybird/license.txt | 14 + .../quickwings/assets/tappybird/preview.png | Bin 0 -> 162877 bytes .../quickwings/assets/tappybird/sample.png | Bin 0 -> 81791 bytes 90 files changed, 619 insertions(+) create mode 100644 examples/quickwings/assets/tappybird/Font/kenvector_future.ttf create mode 100644 examples/quickwings/assets/tappybird/Font/kenvector_future_thin.ttf create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterA.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterB.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterC.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterD.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterE.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterF.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterG.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterH.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterI.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterJ.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterK.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterL.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterM.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterN.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterO.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterP.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterQ.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterR.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterS.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterT.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterU.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterV.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterW.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterX.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterY.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Letters/letterZ.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Numbers/number0.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Numbers/number1.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Numbers/number2.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Numbers/number3.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Numbers/number4.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Numbers/number5.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Numbers/number6.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Numbers/number7.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Numbers/number8.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Numbers/number9.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Planes/planeBlue1.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Planes/planeBlue2.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Planes/planeBlue3.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Planes/planeGreen1.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Planes/planeGreen2.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Planes/planeGreen3.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Planes/planeRed1.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Planes/planeRed2.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Planes/planeRed3.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Planes/planeYellow1.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Planes/planeYellow2.png create mode 100644 examples/quickwings/assets/tappybird/PNG/Planes/planeYellow3.png create mode 100644 examples/quickwings/assets/tappybird/PNG/UI/UIbg.png create mode 100644 examples/quickwings/assets/tappybird/PNG/UI/buttonLarge.png create mode 100644 examples/quickwings/assets/tappybird/PNG/UI/buttonSmall.png create mode 100644 examples/quickwings/assets/tappybird/PNG/UI/medalBronze.png create mode 100644 examples/quickwings/assets/tappybird/PNG/UI/medalGold.png create mode 100644 examples/quickwings/assets/tappybird/PNG/UI/medalSilver.png create mode 100644 examples/quickwings/assets/tappybird/PNG/UI/tap.png create mode 100644 examples/quickwings/assets/tappybird/PNG/UI/tapLeft.png create mode 100644 examples/quickwings/assets/tappybird/PNG/UI/tapRight.png create mode 100644 examples/quickwings/assets/tappybird/PNG/UI/tapTick.png create mode 100644 examples/quickwings/assets/tappybird/PNG/UI/textGameOver.png create mode 100644 examples/quickwings/assets/tappybird/PNG/UI/textGetReady.png create mode 100644 examples/quickwings/assets/tappybird/PNG/background.png create mode 100644 examples/quickwings/assets/tappybird/PNG/groundDirt.png create mode 100644 examples/quickwings/assets/tappybird/PNG/groundGrass.png create mode 100644 examples/quickwings/assets/tappybird/PNG/groundIce.png create mode 100644 examples/quickwings/assets/tappybird/PNG/groundRock.png create mode 100644 examples/quickwings/assets/tappybird/PNG/groundSnow.png create mode 100644 examples/quickwings/assets/tappybird/PNG/puffLarge.png create mode 100644 examples/quickwings/assets/tappybird/PNG/puffSmall.png create mode 100644 examples/quickwings/assets/tappybird/PNG/rock.png create mode 100644 examples/quickwings/assets/tappybird/PNG/rockDown.png create mode 100644 examples/quickwings/assets/tappybird/PNG/rockGrass.png create mode 100644 examples/quickwings/assets/tappybird/PNG/rockGrassDown.png create mode 100644 examples/quickwings/assets/tappybird/PNG/rockIce.png create mode 100644 examples/quickwings/assets/tappybird/PNG/rockIceDown.png create mode 100644 examples/quickwings/assets/tappybird/PNG/rockSnow.png create mode 100644 examples/quickwings/assets/tappybird/PNG/rockSnowDown.png create mode 100644 examples/quickwings/assets/tappybird/PNG/starBronze.png create mode 100644 examples/quickwings/assets/tappybird/PNG/starGold.png create mode 100644 examples/quickwings/assets/tappybird/PNG/starSilver.png create mode 100644 examples/quickwings/assets/tappybird/Spritesheet/planes.png create mode 100644 examples/quickwings/assets/tappybird/Spritesheet/planes.xml create mode 100644 examples/quickwings/assets/tappybird/Spritesheet/sheet.png create mode 100644 examples/quickwings/assets/tappybird/Spritesheet/sheet.xml create mode 100644 examples/quickwings/assets/tappybird/Vector/vector.svg create mode 100644 examples/quickwings/assets/tappybird/Vector/vector.swf create mode 100644 examples/quickwings/assets/tappybird/license.txt create mode 100644 examples/quickwings/assets/tappybird/preview.png create mode 100644 examples/quickwings/assets/tappybird/sample.png diff --git a/examples/quickwings/assets/tappybird/Font/kenvector_future.ttf b/examples/quickwings/assets/tappybird/Font/kenvector_future.ttf new file mode 100644 index 0000000000000000000000000000000000000000..39ebdfaa904e4b08df8791f4c99fa1e379c408da GIT binary patch literal 34136 zcmeHQTZ~@Sbzc9>_yRV@iOt2Bz_G!Eq~I|a5}>phV(LK1t=OeBr3o|k*fV%8W@a4Q zNgJI=eaJ)9@PMMIP1CgEAyP>dwJ7DG4^-kIEvQOcs^)?emo`xzk|=7aN(1rV?^|o_ z%enmX|AXBmisp>>fA-mX?X|vj*=z4}{)?p}A{R<2!&1Ee!062*pIQ5DkgT_*Pn@e;zziinjJrNy!%c0Q;`eSgT9y>pPfAL z@xS{ZuCEtax9Rx&;*tz?e*$@*Wk1Rg$}q}SyaLzIgEBI7H?DW0cLcp32hwh5zH{oT z&lg*ZtBRu7SzK4#Q9QY0=c^;HuI+X~TR`GpbmpAqa;LdnX@oT0fA9Wn_nGef-FLsV z>&%zWeCf=SXa4-m7teg=%&u>LdCfns`6o(VJ$`{Kuo^?ZK+gObsluFq^7f4z{_4XQ z-}&FjmkQ(`p1ky9tnl0|yE0r3m$+PyTxD4Vufu2u{lRW2FJP3lqs5PJbY4L1pmnfw z=wJs0MWt3ZF!&8(I3Y4Ix8=X4Sd467k%E&u>lj?M^N(qUiCU%(4|eE zUOd=-zT`vaG3Dj>Q@vXT`D_byp4;riHkOJ$FPM!uUfX#_Q6Aox+c1|A>!6EuAIs|~ zN9)9z@Yd;MxdE6;iTLb*x)(d!%JvQEe$8)Z*to3~#i*LUvq`X<@kdDQD$ z+qdkzd$w)AMyHyGBLd1^$oIn_ywOULgR9X$d-iwbD> zq4`-;;HC0&QIf-dsr=*O^kG-bSX6v#9KC(dEqmX7>%N6aApFQ=v2T8M7JbECOG^vW6DNqeI50K7Fj?F+Gkt8*`5tm| zNFw#_`GupSGt-AA=N2ayM<-6-xHvw#clVyr{p2_?eYAM=#Q33O({o3Qk4_$+I=!%1 zJTebmW=})0Q^myO;e98Mz4!3Uty8j3=Hz zz25o&S`UG09wQ3bFDFnxf%>G}k8%|C85zg*eo)Mz?*PgIS~(_g?#;s__wFxhQb@TV zi@;841#s>L+9sD9D@fb1O@mJX?1ds8m&4#atGXOR+q@jX>wf5SubzW;Q|LL4mU~rO zqM5^(B}X(4YZS;xvoay~sCAb>eTR(V?}%GyF|*Ka*l8ZrnFoq14&lEZjd+1rQlLMu-sY0m`L{zLH``ix8i&xyZ)o@zu<=dCA3^ehUopE_n&N> zC($dQ{KIUh22H$2 z@H56m-LKB%Rkcr7rC}hBfF+!RjBpO^ftF`T)saAebG@{U2%~MB`7-+Ini^v8@8F-C zEnZQ{z$ctl|FZk{-EVcjg>D|ZssK-%3 z5=Q7~+_NQV8k2}~^Ydl79s$3fUBX!iGU==sR_b8VT>`J23VM{pdKPRFCe>OJ4n{)F zru8UL7<|!+y^=EqDmSlFS}q9`KfvF2N^V|tS^^ySq7v)irp`g(d`MCYm&)a#SHZl9;!A9HX zQJFLl<|Ocqvm^3`9F<3LX5SnOdaK?~_91S?uDU5Unp9 zON*_eJ>yKvbWj)hTG|Jl=?^(AvAit0lISqA@#2m06m+1T4rOg zS&BQw=4)%V2c=z%qn*PQ$Voh2|qM2ROUHuTe^2~u6Ujn2|nY_+>VGb7_7xmo^{QXcnS~BL1GpyNq0s> zQN_^DEE1Hrut`%h96# zV8rC{I_wA3u{s694CrZ`Wo816gG1wkmeK&GwIYsaDW$_pmebi($)LHVqQ*LbEf=_@qwPRb zS_#xW@>#ayC1B1YMu5*JTv=QI9qUOa&Y!4CZH+0>hvLX;n$Y~rhZ(Q@*av1%@f>!R@wu4u?0&(eY694yCLn=B0<*rhI0ef}o!Q3K^h@&<*W zTm?_xx5)OCQdNG5K9*%tGL%bC8kI-zo}Cj%OY8KfQ}ASQX*iq;Z`F-lA3p8ossm|^lY0iXKwHLI2a0}4hvjDtttdZBzdDnHeAg{K1#H6-Ea3C8H(Fi0bNyHEN7BA*`8<~G)i`PCN!_90>^s1c zF|c|+5&{>c~34aqLLTh&xxdurw<9E>&`As?Ne`;js30}##3 z1}f4{VNEg}dvu^@}L?x3%4WI5h%RsE?-p3s4pcTb4#ZKx&VsjC8} zs@DK2tPx;shVuKdxPx+2BuWtGAae-lvO6uRs=0lT_Y7@a0XZ;WoZ4MuprMCaG^j@E z###gfXb)QXZZhGu-um4jIkDJ#308N`#KS&aBjaZPqi4k`y34KaL7`iZ{Qxi4L zbQF$KOK<=#Dge-{phzWa`Qqy|-$}h%u8}v>%h{1YrJ8qhG{uF0A`pe!X2BLuhkK(i z-na#Y!@Gxw1jz6RXyK9~1$;o6#+yAMab`spHnkuo{--o`9-$reg^< zEUrPalZIY>2B<|T5e0bpDMaM7&9Vb{>wk>~8EYir_}tCX)ll|^h^OfW1)x^baxK+S zm%bF~eb@_S6TY{bu!ord^jS2i?VIq&AgZ*72{1_`$souYZc($=6(}(^luruSwy{;0 z!u~)=`w#m&JUL?2)k}PB0z)eVKxD7Eh?&fI1b3V)9@Pf=Vm7K>x81Ru1o9!)CXT$H z^=3}+Skt)c(@%wg7kaIMG(D(-?&(VQsRY!J)sp`$OOigRmNd(1;4qdJV)D{#*P>OM z>i`ZTAlp8X`poNaI9T|6t36+Ymf)?SgKCV4W!^_yE;hic8MJD1eXVY?lT|T*ho&zV5S8*&U6Msb zS+qn|;*>EsNnZRstqX!|70y$*V=HH{gkJVIio zrIThQyOcmbA8wyTG>a3b4F!=_l-Nab9Hq3bZkR8L=Vn}(z0s(wamj(vV&J6c)WPgQ zaSj1>M9j@GG|)*38TiNfo5eR-v(?$4+O_Mb8)4{QpussaiAAPzz+j6Zd{P*n7Y?5o zMl)oV(7rCW)Daj3{)9;y>fiWlt_;z?VPON4de*m85a0Kt9UuXx_VwS4P1y#3xJtK6 zdzdZTkFgjXOH1&@KGHS&5s|ct+GGd53AYd5<$AEiIt_CT&_G>RZe=V%(VFenJ|7fk z$2?~HdYuMp$C2UuDNrDKO9l$Vxj&u}QboV+lD7@y(>9NF`dg^4$9}rjUWujjJKE7s zA^xZF{pm*JHiNkl-OYwpi`H2;hV|cMpN~1vpT`RP);9+FOJm6PkL>?{ij~CA`9RDy z0~r`O_!51Z!|>3MVDRwJ2A<271sY>{htGvtbA8D1xU_4W8%uWBg;`1oT)8^>TI74{ zVXmiJu+i~dLMt@l=Qi5*2yx#K_Xli`{c(}wa?LUAZ(eZ2&rFA(IjN|HCbrOCeXyC) z2F0dXHJC}a5(8qZXj#W*&o_bxgB#tUyc`ssnl^06T;vK27(qfQd&V(RvEdGUPj6gx|J^X}ma>@b;a)<&tTG z?pgvQntG|P7K7k2pAU+Qu1~Jx#eldfe#vohm1wh9Y#S7snyg`@l>-dU$H+AQw}@rP zh$?fe;ZLu=UZjSBHRziV`e#UbWI&gkdxlg$c0~6g_+1LOi7HMQrNt-C(fdpzKPg+| zw8n>Auvg%LF^u&*?joPanG}jg%Hc71ZlmLgZUBSGskZz?ZuJEkLx#!Nv26te(=u{( zXE%Kw#Eo^o%LgdD#9os5VLM*&%nwTa5Ix_)Q{{fQ{LI>Bw)5aKH5B*T>*DtmQZQ35 z)rF?i^hum7K)^y1qA!{qt+uBsb=7bxK4(?m;o5v?RN3SIG`BWj-*4~msdNPsakNwb zB1b?}af2OJmAWI#x{Zm-k*jsXRY<^RIr(!f>wANyC&JDu&l~(M$W>X)sBN>Cs<8ng zF=?5`Imm2Qsp$v*C{}&;tpu-mCYY;*Vl@;NQj!;fnUZ#C_EMwmoJ}ZUH zIB4Y2a{wM(CnIF+_ivX$!rnp9M>S&Q_3MMcS;_1;H=PHcHC4M@kKc?+nKqj+(EzN3 zzgP(kE4I#9JwMcKG{DNca!WOHNPm0PDVWGgJi`+?m(O%DC`-QB!~RTrwCbj>%;U!I zD%pp^k;wRQ6*C^Ghu|3VSabM!4qss`^|iT{m@2>9 zft(;u&66@Kq?p%Imp8}cTV+&wZ!W~`dl zLuyL~W*q8HT~vIS`uPSe>J!0$nxJ(PTN&}%E07?%k}5UD>+17hjV;(U*qK?) zA}rr9o1dz7TYVl}dH{!ny@GuhCV-A^58-wvKw5pb(9B`shGPVN4ExgXv_t2f&VNq= z%mcN*+T{wK>Ys;fy#lK=HScemIz=^}uSMVwVj*1;gX=@?%F-w23bWMe^Wa-G#xRb%_B>lorFoe{6N4w*XN_w{~GZ8N>H-)z}a23+<12ZRlVE3Vf> z8}>yd_C>4DgVT+|dB~7-|9~zz_YA3itUbr|6@xHJU;eT<#`bUZdGOEnc`!YLdr#h# z*;81*2k|98to)uAu-xm49~L#ZH0&VAC`^7!Lb|DrPWN6=WdRVAQ)%JBbYNU6RA`NI zNWtPML`O95;nP~Z`h2;Mvtlj|&R}-W%)jynTXc`Rgtg?0e$T@#%2tZE5;Q>0yT#S# z%e3|C^W~78Mi_|kx%=w#W&L$=n56brXycC2=PnlN&G;qmUEG}4{^C7Q-qHVqvuB^7 zKQK}I?s9;#56gTkKI^14xqp4H`84v;QFP+2oN(yuApE%6^jRH1(1#+eA3y)^Tfi*1 z8|NEG@Tx{L)T4vZQM#2#Q|kA^){=%kbZh!;n0CjTEezJ-K4u-q*eLBO`D*V5`M1LJ z!~w?e4F8rHXP+Fxn_uDEZFPAH5i)bmkPAfV&e4()eC5BFw^sDqc425!N!lZhZ>k*c zST)HdzU#vGmYuWB0dgw&;+9~w3)ypuRM9CWYFhcjKpa(wr5QqZZ++*Gx}gD9--8EZEWza8 zXSSOHhFgEZnh^7YJaANDvZYK=+kwzB{QQbrNYUtT0>26W!8JSSQy!gz`Ab(jG`g0>AWi)_3B1sEBx9c!EXy_x88~Jb&*S^L@pgc!S$t|MERb`We*8|rc5qhLc#Sm$lHecHt2c9 zMij`s;vmXbMYhj~T)7@)3gtz7ED?QgdS2uzFt`dlulik-mqo6=1?6#+Ga?0Oi|>i- zz%OZE6?~a#6e)$!VU%3(m^uPN1BJTjMcf2Svwj^>F+TVF6 z3fkZKyvRP-Z{LqZ?uP7NJ1DY$1m!7_cR}VopA@`vdDXuMBY0i z@;=bM598i{Eehy9@Q}!_qwW6nA_s0j0gi)@i~Pnxl<$i?fbqYH_6OgCg7yc2>9_Xq zf9FK`y2x)oCGyZ=k>A;h@->kU0sq6m_b~8{e?eqoGfFA=Pft<6`|x8TlaMzF43p2| z{{Th*(LE^OI|Z7lTTo_Do&` PiOjzua{P-TkKXowY>-!K literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/Font/kenvector_future_thin.ttf b/examples/quickwings/assets/tappybird/Font/kenvector_future_thin.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9f4b4fa59ac2211aabf9cb60c6f7caf441d087ef GIT binary patch literal 34100 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 KTY$`k7yb_mr&(bD literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterA.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterA.png new file mode 100644 index 0000000000000000000000000000000000000000..eb9a6abad8c5ce0f50f73e09c6f5b37e04140dbe GIT binary patch literal 1611 zcmV-R2DJH!P)We3l+AOPQBldQd18d$LJ$7vHH z;Kc`eKViUY4qqzoxNy7NcX!Ckj^B9_{XPS4`>y}^ga{ht35VBpUn&3ec({D$pMTYM z=*ImxaBO1kvrK1?+oEh_WMCgwfMUo*>e9)WbWssrfxocn<`)!Hf>b4^Fm+L z){>@xz-fbq;fP>8sI}aP6=-ZaLz)85h6q^F7Ys)y7t)ks1bj-G3YBG7tmGowQjC0a z`M1b1@N39`-E7xgno62tV{!S95pPP;a5%*Zr75f~(iHu!D@J@J=lRF4RBBC%mAXk& zNmCRf*Z%SsBcL=q1IcL@D;Y~u_RLa@oO$RcMo`ukYQv_wVg)0q%m9pE3Pjb?lMXKC*6ux5Zp0OMH%3j3Z#nH}n9VuO|eq(ZAHpve}JI$Hx^Jcj@< z_xc7u({g<#3N1;2Y50}gysdxWy@Q>lmrHhc@5jIKGs_^60|wwi@NtrCAvq4xWJS)g zW9JU`{<>^WPgk1iku4{1CMck>g_PV3k)YMgNu^DbIHBpaSwRvUgS4D!T1Y7-;24fa zlF7Aw8yATcvWmbm!2rzCLdp{KHBE`jjx89V$!k|jCMY|#=1YaHv<(7i1TgEF%fe(6 zl6rm`Ca=%P-o+M>phcOOX{B74)T9XqM>)Q?F z>~Tw6%1)NHwyfMQg7cN7XIspjsAzh4Hv#cn&Mk2{60*upqBc>pt+VfuHRz@LPxiT5 z!CK<-#oBQ@D$PvW1rPFLnoNJXY3JuIb!zcNayDgYT;fu8at5uHoummlj$QcW-qqHi zVHgw3TM#Xi$Ub}2%XgHWvb43YIJ$xW4p)|*Y8==!AZP-b993zB3S}vi5f2ww+8pE~ z00ix8@`}YN?dBBYxtXXGx2MNdRhmW4Qi{Ts?moJmi%-YmxL-;u9igbI0nZ3KCka!`21Dw<%Gk)9~pS)=&uZnOQ5}rUYKJxe)HtSWDlU z0xdc#V3uP*3+UTqck!v!|FACFRHd5GpGg6d^05r~KZTe)d_H!CJpcdzEp$a#bW?9; zba!ELWdLG%E@EtNZ)9Y7E@N_eaCC1jX>DO=WiC)oM=~@;Zewp`Wpbznf9?PP002ov JPDHLkV1hPB{?h;e literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterB.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterB.png new file mode 100644 index 0000000000000000000000000000000000000000..75a62763d821fa4679455b97c9146202cdb97f92 GIT binary patch literal 1459 zcmV;k1x)&hP)o;{M4cOB$0+B?r zd2Qm_sFT9lf%c&WAwyoIuz=a(+q>_laP00gHU8j*+VgBgy*~U^ee&&(G;Y5gRnI(n zomzKu*G)@pNtqyN0t;i4d<3-%d>HJxD>*oc3}k}oGZ@L)KdHI}u>ueY#fC zGJn2AunCf!5iki#pakR$nU8ew<)|*()(dz3MKEL5&zA^a?C`E~q>pn0|`e3w{t3;wPWo&hO z_pL~*=ZzH^I4#w5z9j+@+Ojof07?7?!r&bU=UXCcj(0y^v~Axqj^&5C+CY%@A%F2T zk!(Qtq&b1fJV zw9Lrvb~{g=t4LP(o})ypdUPXX+h&C5wDLp??IIEeqiBR2X3f=-Jsr)O=v9Fr0u$sT zBa)HjsY+iHfeBLCPM}Cdl|yZ0(>zV|Qr~L?WxH{rf|(mdEF|6eyAMwfjE@+H5Ikx{ zjzo0%Q;6z}6Ji?EajlhW$$dX^kYJ=BY zwD!{0(+dlh*`W!UnvPDectV`BqG_h5M3Bjmne!=1jmHaO5K->g6a|UQ$x@!~v55Ir zd7#R8(grsx(Z7cRLxhIdJnXWZRU8N+yinw=u9!B41JNOJ639Ii;*ns5Hm3WY2sbD6 zG34NgRI}^q<_aREz9nLuX+aZ20&M^)Xh9F7}+x0`39ec$N=wVss<31D7=yu8d^{7 zU_L=8FDO=WiC)oM=~@;Zewp`Wpbznf9?PP N002ovPDHLkV1mYXnlS(X literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterC.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterC.png new file mode 100644 index 0000000000000000000000000000000000000000..8ae3c7fe0169f71a13802d82686ccc5b6337535e GIT binary patch literal 1911 zcmV--2Z;EIP)z z1XC|*nq6B1wOXnrSga4FHTI&$TN6#IkK=rs`8NNaJ!fXl+1Z`if&U?4=gj|||2zNn zG&R-f*)e)-AOG|Lj0qm&FD*geNKtK_EP*vjWuQ$C@Kd*SjD}Q+( z{jlUsUc4SlK3P~Qy>s%X6(dM6Kmv0D1+OI!J1lZ`ai!uz0C4Q`viISo>#+gE5v+-| z&;9<-+J^bxh7Q!nihhz}*qQggy<7nVyO}fyo!}dD*Z!^mhBLc*rV7u*whY0*V@Y~} zR-j0|f#_(d0z$a30)rPN#bA|21CbP@9@u1hy+{YZGlQ2T7%Z3;7zjKhy&um|WNd;7 zd1h`UFgQolg+aJ~box7APYKQ?zd8ea4E*mB4eFSK3FtP^dxqam0 z8DH(3FYQ%eaIlCPsRmP)T4D@9@DRrl#2CaHU3PK&>KfgcDLnY{+mHLIXCtjss}lf_ zu>35JAkHB?5F9oa|Ho#RV$XPSIk3)p?b)Gqcy^$W3mCbRTJNm=}U#Q23w!^ldpP@A?~aOQPdzjJGNl3 z0sJsZ37HXt9uL1cInuZP@X+QLUfZUVt*^iP5`HIvVGY(-kaA`)K653oPDY#JZ~>Yd zw6P6%Od7F<1OrbLxYk@8L0s8+VER;;1%udw-?!+T!9M0|++mv<1_IAil`#6d9eAOf zi)$ zZ9#sf1C!M{gH=GqLDeC+R*wvLf^HiUXfibi;4*=9gx5Vmx`PPq5`Sd%NbiPNV+?rp zeptx4raRJI^ZX!4YO~+}IiRN72GB#VjBL5B0Bsw3Z*zKpg0v?|K--5uy+1WTbla|g zWQNUz6rI-80PP$-x`(}LmcX@kF(aFP^?dsFA9|{mzzSj6PzH3cFqIl0cqCScuBi`m zIaHXOw50~ zrYN9tJV%(hxYAAq#iohwoOBeEAc&XGO8C~w+>CLbGnwT@5#id`UD3rb+Ku-hg9 z05~SoH36_jO|xKG9iUE0J9;~p?x~u%N^98)-j&UI*|6vI&O|%Z={b5k=^T<6bio5c zG3;^}04R%)fv&A7xYJ5<;H9G-Iw(0b230Fzml|;g!6g~yNYX^RZfPZOlw5WRwDlCy z4reZsb~sC%0LTp7ws~JqA?;*iQ%AdIwqoh=q#Jk1@ftz9a!fMNF2n95sVC1^fQrpfIe`fr9r->sAT8t_-r}L^vd0?3T@O zNk8?T91>EOS!`0*%VazXyYJJg&T1qm97OdxCO8dGm^2j`lyz4GaDJEq?amkGqO$mQ z-Rx7nXR1pc<@L#Q=M-VSD=@0|ywm9`xt8P??!7X-19l-+}b`X?w0f=`{axgPzoT;c*{qHJ3ayEdB zpdgqu;C!j~3sjI%qElQId?#e8p0zFSTUGC;J7bvM$@t|eSc4Ze03yachm7lZuruzI z8rB0yC>2L|qr~QtMpC2CwkT^gK(YalmLywX9l`yAMgr*$zS~^S-d>Bv{Q?*13P7|p zrSLQdK{*pB(qpN3S8$=P-Ng$30Sc{ZfG#50qW}N^Ep$a#bW?9;ba!ELWdLG%E@EtN xZ)9Y7E@N_eaCC1jX>DO=WiC)oM=~@;Zewp`Wpbznf9?PP002ovPDHLkV1iG4cufER literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterD.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterD.png new file mode 100644 index 0000000000000000000000000000000000000000..99dffaadf41836e23a3f699de2cd27d32f7ef4cb GIT binary patch literal 1615 zcmV-V2C(^wP)THe}sxl}idhWw>?yHq)cmL(Ci|19Qo_ca%S!!$*!pix>=pzBuu@Ke5fCTMc zvj)U|;y}l)-L0DNi`l;nD&|fu+FQum1W^xE}0#Y7eG~P?R|^%8Bpi+zUT0RPDc)Ccg|dwl{9NH8jbZ0NyGXT=QZn6TUJt7{seq;pi=^Owv1rv>i+bip4?Owy};T z$pBuXwWz?P&F?;b$@g3om<&$|DkS>bz#$!DeADi=IKUbSGKja&e_M6*K`LbfN3F@d z7Ax51H$QlJ%R7f(r)+)i_~C&uXI?$?A<^ZW&h2}~U^p$PbB94Y4lr-nqE6P8o`2-Y zcPB<9Ak7nB-*nHx{d3LCB||6DPB6;a{{Dxy9hkg8)1+C#p_poo841l1wVA}gApN_B zHt_fGY@FLvYjpiEYcYRpV13QNVgGTzQETvat$If=#RaCeWuD|c=}}FReGm>S0jeIOTBn;LGt*J51G|gg3k9lJnz|ht#Rj~Y01?ya@V7Vm;hANZl6-_h! zRDvN(XtkK6#<5g@;h2FwSQO_sEe5Gz+xDH<+AnL!@}SHD2x1zX!Q84Ej!gQ5P; zKFH274o<};VAzkWSaGb!UmMw!7#J!_yh)X2XnG#gl?NVuVd&vRz~BjSna^G*e|B_eD+1j598q&)HX0*L*>e#d@F*DF6)e@Cucdg zJUwq39v$?i?1}~K{(~3FeXl14dy3A&#$l*+MR}czQ@MX?XlKC`r)2eIf^8*OdPBN- z)GvdRd341bK4s8}?$Harb}JVYEW5Ef1*Z{cYfU1T67XU+RbSnl_*g8I3T@>h0mCBs z(50TB_6O%+>hMkLyN#GJxvM+*K{0_`n4w$hcJ+o4PG( zmHAA80ZP8XVx1m>Dp!rRvH&KZLa0zdFs8OvWCjclM?PMWP{IpB3YmBg0naB*4>6K^ zN&{8&Q>Zk90f@&C3NjV>3KbWJ3RHJ$AFv<;kq^S?&gG*p$i`RpJ*z+!f=iCZVDe@$ zsy7)rtstml4w#$VLo_?Nmv|JxHLn8I7Y1Wp+c-S_AP10_-Kxk;0_LJVr)?yBGRxpv zlV*7z6mzQ@LX1*8Uvp4F>*9SduT7D(@>Cm#5Cqx23bP1M(@;Jb@~rI#C%>t8+~7kL znXQ`$pQB?8>D^R;$!YeHl-}TWw5is`Yg2d}^*u(M0ubbR(2iygsj|ARqi6)Cdy|25 z1z!-80~#hP&9+&AX`vs+z*viDMQ3`;ZU3jBm_q6Ei!z2l9 zTr+pV`QVH71oeYL3?PMIj?P>PT1Vh$x`IWS$cms}N4pmLAFFk%@0|)=-T(jqEp$a# zbW?9;ba!ELWdLG%E@EtNZ)9Y7E@N_eaCC1jX>DO=WiC)oM=~@;Zewp`Wpbznf9?PP N002ovPDHLkV1kc01VI1* literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterE.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterE.png new file mode 100644 index 0000000000000000000000000000000000000000..d9d0ecfc5a69c1272b7dcd2c2e2ffb4383814eda GIT binary patch literal 747 zcmV>#CJA@C{DjUnConACuk8eDkfzq(1EKKvR`_VFgk% zwxnPP_1K(&T$AwuU@Xw@VjY>!(!lwHQ_0ot#RwdzA751*%ZG~pG>jr(p=dCI_0uSC zUPYAShZj^?4&9T%1fR{lP^+SYZSX>~cT0QY>h(Vqp`KRXEG*B22G&B~i{oYB; zSSXlPFsT{Mv>t;!29}LWmNE1dNkh>hP|{6mLor<-bP}y^69j>$#uBG5%;RH86Jdm3 z0cu_?uV4KHZ2$lOEp$a#bW?9;ba!ELWdLG%E@EtNZ)9Y7E@N_eaCC1jX>DO=WiC)o dM=~@;Zewp`Wpbznf9?PP002ovPDHLkV1o2qOF#es literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterF.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterF.png new file mode 100644 index 0000000000000000000000000000000000000000..d118f256991ecef40c870c18604f506ccb3b15cf GIT binary patch literal 771 zcmV+e1N{7nP)LoWoA)G=XrK#<$d6}=)nAZcbs|t`;MX*g&~QHM*Y2 zdJlYDSD(aIbXRj|Dv5>FF9m@O%zRPT_WnAmmv)lYRc;)N)rcRAt?lXueMYEns{MH~H_#*Pv)!}z*lW-9W_*Vb;sHb=IDMi->2HUT= zT-P*g1snKAXP4JF0d-$++$Di)^>#3_*zo*q^t!LLIt`rf=xZ2w6Si2-bCh6;9EUuK zEO-CaoNn^=g#-GfAj+xtVG%yjdibOQPkc|3<~Za@7?3ZIZfly63{2f3e8M8Z5-h$EF1F%40 zt`b6QnUaCZBSM#FVs*_`Yy(?zY-l8|e-7en)t*9H2mk;8Ep$a#bW?9;ba!ELWdLG% zE@EtNZ)9Y7E@N_eaCC1jX>DO=WiC)oM=~@;Zewp`Wpbznf9?PP002ovPDHLkV1fo2 BW2^uG literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterG.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterG.png new file mode 100644 index 0000000000000000000000000000000000000000..6285343505ec28c5cc3b8f9cf61fbb5ce8dcda00 GIT binary patch literal 1832 zcmV+@2iN$CP)Pp0oJC_=yR)j)p)oM~(QCzqXD!5Q680@mtN)^$Tm~>RA zm0;^fjLq0usMVsDU};?xYwVZCuO>CEE}!o=+%ufqyf<_2oq3tmfwLHR@4oxL=bZof zy185izqNy-H}?&V-`!s-5A?r1zHfc$z!yHUaj3kS_j9fMv4Qow%foDF!#f9~W(n(Y zFe`SxfBk|0;Y0nU@lB7FKA*NX^UTPX(U$RvXy>uh&cgHQ;L4Nnp}m3yWMWom#0IeA z$Pdwb-=B?+Pt8WB{`xmq4o&_U?f&jewDr)5=&3!2=YhkNn_`w|#0J6#Io-6)o%rLQ z=$ol4sZtLdhckA1s&ZHynhh-2961qfS}eZr)P+O<$9}yM9Xx+I`gn3W8u{^(vwZsV zOjJI1IXZH2HWe)2)WBj>obU#P?P`r+R{A3ozh4ak;3A)$or#YAGFv$){Y}iV3M$^8 zyVJ*Nl@~XUemloMj{kPG^1)_ndTmYNqNh*swmK!x#QuFd$k!ICH6D z5$plqmHh>SVX-Vs%T+%7X}Y=>_9f&{6AZCMz+kJg0FKHDwF(S^WypSn9QsNJ9xNoJb?|iUVV=K6#u3Y1=9QEYC<1`_Stny9}U?RP9I>5Nc}BDv`aBXo%;X>ABy-MsE9y@2W zbKN{Zl5|SejM{y*qfG)JI*R)W;4!Nta1wh~Z-4hi1E_rt7)oASJ0WR}WXG`MoNPFD z+;zJ?8e6q>Xw!W!y!>FAz*dhAjvh_Z8ln@@JNlo#Gv0o8DjDb?iXZqUjq)xV5Fj|M z`Eb!y07q=8rNOnY?%igdUpgO<38X>>AsInZ^fnG#43%4YdvC+6&>Dv$egk0jTw5x; zeRY01h^n=A#MD&u&Qg}m&)edpPW(qUB{bz zD})=Ak_rgw4XI6_YRlYuTq@#5z|86X#P!>pfGXV^(u&}G&Bxr+IDT6X97s-kI+S_YI%>u zRsd07wH%P9&PG!o*GWJofGCvg{EjzUj~p@qL}4Z6tt6t@?q=#OMWxnbQC=Vc7P)QST-)_)i0Mur>oJC1k5r#|h zBE{Ub1gJ_5n#OhUCz@I;=H~*aswJfFt>9Gc&^fZlBM&?M8A~hPTLg-)TjV^#XwCN#?7WF_Eve5VD07jo1aLx8H0I)9p zYiA$qK~k!9gP%NEt6b@{2TTNBshuQN**6MqQ2lCO z^S$EC=2-)FtyO}s2Q@^_yEZvHl0XSCG{$tg*6k2iaT#s_g62-b9M>68&Wsid^~Uh1 zK1p+-LM()30bq^ulcY1``gT4|TS?l3NJynzh39=QY8WXra={*L-LL@n5L~5u-UW=n zUuO$}EjLs4&Rhn+Hbe1UQdeaJpxc;yCLro*E^o9~2=Ikv=KZ`08||(i{tw6eO9Q0J zZ;${004;PySaefwW^{L9a%BKwc`jmXZ*OE|c`jped2n=ZE@^FHXJsx>PDe5{MQ&qn WWMy)w27m4V000010%}|__f>dmi*2%#^=-?4Y?f5L@B8l{{Nha=f{V&e5@@pN@fTVpG$;!3*U_zxzYZC2c+Dhqb7hu@{tD<=*m zFY3Jc{9_3S92H%8@oiIl`1O}8_))u4-jzphzk13GU6@<^-yQW`MOSdKu)Zzw-+yaM z1-+PDc46$89*iA>J&I8=D0xvQd{lS9QG!96aq;EaA2Ii7LtCm4d{w-_z)!`X==e& z7$zh7?>@dNi*2nX*zqPH!!QiPFbu;m48t%?b(l9lw#Ab#TiP-SL&=LecZI?6KtG!i zUXL}x&rjZpV~vq}soQvSZaQDFxj+#%Ce#>w`cAS>2L^V251itlYw5tLcmKVxNM5lhEYE7_mUU&x;HSSVA^%YT!LCO zVOk951&7saFyJAnfF?}9wKtW!Sp{x01QI0vNh4?osLf>HgHlbFx7FnO`@Vty02)Ok zbmftbNdN!DO=WiC)oM=~@; ZZewp`Wpbznf9?PP002ovPDHLkV1nHpXp#T` literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterI.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterI.png new file mode 100644 index 0000000000000000000000000000000000000000..9c5e73740768895b3a289a99503b0d77e0bcdf12 GIT binary patch literal 448 zcmeAS@N?(olHy`uVBq!ia0vp^VnFP`!3HGdlG`sbFfjUgx;TbZ+)7SpX!@|z`paUm zw^8zY3!eX*(OP})xZb_r^CftKxGynZk~T?SZNqHDAnCQn@khazLwCQ&rmcI_F3qz^ zP%U!r*DwFShR^?VzwR|_pu`ffCG3em&i$2G_x4u#%l}um-#>XsThFdVnvZYNiOSt? z5}A(6?Pu4v`t|1Xe`bF>!B)qt#J0m{7-x1S8TcIB#xDPF{m##Q8azSPSszv$T+G%l zWrK&2!h7%c59J7ELy0BR7932EuTiV^;aDP`=J(-CZyOKa*RM(^nteAEDh3&N@O$W= z=vndew!EQ%!G=b*O*fj<*1lPIY=<<*?(i>chk4nOH2?2YEfwK?cJ}^X#;g@0T?Z9- zCNb=sC)1OnaVJ4cg)u8J?S{q@4N+cEH#u|Gol!krZAL~57~NK|>}=ywl4fIg{mNeG zcq5q*Ur97gZLNP6CX1j&i=d!IL6B6?LaZo=bnxp@P{vSJ zOgc_}fLYQ9l4J`>CO<0sR8wm?z5knc9%rs^#(6Woso-AtZ^nD>`Q3BR{TRz_*P%^ zbnr#WLVpH3WLspheB|g#|J&%R>G|l$_unZC{Tl{H4Op+zb<7q}pAzbYgQI~bmHB+ZK_#dJm7o$-f=W;cDnTWv z1eKr?RD%Ampjz2Q2_5vchFj1H|C6t5>MZ`JKv6D1CBnR%66!@+W;sym-!VF^Iqd&1 zzw)4nA~`zOHKcV$Nky#xBm&0g)bHu!jOMU!>Zc{p;jh0mJNU;q`|9ssNLU|2MS@o- zZoeLno@jq&TC~E9No0@7k?q6Cj3rRAqW~=dMLmZKSX3Jt`mz`YjO7#~EDB|tp2#=D z-U{TS_p^pCDva$q?=KTJL98T5(Ih7@ro7?0H!`KA23PCLvA6`M}3{4V(*(!V_}| zZIcN$HIiiJH5zQc74ZR7Ng36abB)uDwtgwJd%5^1^hZBwAujOTvollswwz}-_uBF zJ`iS(Ji<+t&TRu5*wcpL?*{(R5g=o`oi)$Kl9Ejbx348UOGX#~_cmRpVx$ojyfXox zNXU2bQ3K(@!j~F;*>aQI;uF&NBN7;Am-rf@cPYJy(h9gB3^dA9zL=v!5xDyJE!%cQd*42D^ITRJ8(`Bj+q`z3V@ z1Rwz*?Q&0000jbVXQnQ*UN;cVTj60AhJAVr*}3WMp|RV{&KQKGBibQ YV{c?-a;OG>?f?J)07*qoM6N<$g7`WDCjbBd literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterK.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterK.png new file mode 100644 index 0000000000000000000000000000000000000000..5362d899787fe35587118174a8ef12e3f6ac09f8 GIT binary patch literal 1475 zcmV;!1w8tRP)k9XC`q^%elesrqjJE%0gWDeM>r%vewAT>htK%+Pc$&Z3T;O zI@4dTvZx4f&8aI(WPkt@X7h?k0T^iUkDXn&bEoc4k z?ECS?{+j>5NC6Znx$$Z?*Y*6Hlwfh(19J$1;(D;N*kJ;?`r@0kK9XDS<_fF?&MG!2 zm^e8F4uqY)_HrgPQ0C2d_gQhK-7{rbLM%`m2#0!j@{6nI`eb+@+(Y+cEpimiXL_Gn z>J}M?f_tYJ5Cs2^0)%r%KzSa|0&3iyT4SkP zZb^+%D2ja$*gdTc&#D3hhvEf-tlfKLqXPs<8iPUr)&&G1AnxfP>)X$^F(62VF(^@R zRdwCi2oX@ziOYvQKnY>|&36HwT7MA?E*ED8qF355rU8eBP0KrDjPxt`7> z6c^QOK?Ed-MZrKOprWQfULZj%N)-L9)(N#BfOJCP`^GR(m2^c%2UOI24x$Z62b4-2 z@&Xk}fBapyDJY#lg7hamP~1?l0L2aEmvL(aiW7scB19UUlc z^Yg|fd~>;AhdOs@0V;*}1DKz)aO-ye8&r@NM12r-!v7K~D5KB<78OdRY+S7L6{gQ+ zEcd(rVP2`QLYpG2x~4N(WiVY?x@rkbR8IcanRHq+rGlbTm`Z}{{qp72Be#)ODk!QT zslG8@qu^PG1$L}7=Etf?QB2Vfc^4)h-C{_ww`Q&P~Jtg|Ao?^jkXm-gw(P zstq`vaqz$_j9;dp2uw7#gE$oBeDRE4Xoe=CAgDjk-;dvV=ITIWEy|}#VB%{CD#5`} z0uy<}s1q;T4D(6>1}9#sI2cM{^nY?3s^^QldCVvln4#g>q$EMXBa-9bZB*5agWPMiW~3)P(AA*dA@$K=hIs2_hW6VMLBTTtOh)MY zr^pav1qTzEA)0owI!Sod7oOGigdB>0=!F%Danppz40X)W7L1%Wrcz6zD&Qq#XPD6M zN{Y;oyLlDKt3o->qLM2>q(<})BV^BPJRs<*C2vTHuc}@WK0vbWU}u931tlAfUf3UL z(B4{*%{v5L72FJY{E8yjAZLK2#)X35q43sJq`qZG0}Hmrt|Sl4co`l2A@+v; z0VZ+8`}jkg3IG5AEp$a#bW?9;ba!ELWdLG%E@EtNZ)9Y7E@N_eaCC1jX>DO=WiC)o dM=~@;Zewp`Wpbznf9?PP002ovPDHLkV1nUSyA}Wd literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterL.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterL.png new file mode 100644 index 0000000000000000000000000000000000000000..e747d8acfc9c9ba421b151f4ad4a319e04ed43fd GIT binary patch literal 580 zcmeAS@N?(olHy`uVBq!ia0vp^Iza5e!3HD~H%(PwU|_uD>EaktaqI1^z1~fZGVBG- z98!xGPRe-cpOLdhkwb|iXTp|(OdhGICWVCy9ak+>Z84h9bxL5%!B-c3+V8z+)hL)4 z7kFst8XhVAdj5GYuQc1K_kXedp~rvk?(zG@1?tNWPRM>X^)KJ)s0-;+pPblGGC?kq z-`I4c*FyJK&b7X$8_S$kr4p|){Xg{GV!L!}^GYX^hcmu+Se}1$M%;VT-U_eKZF%#i z+AW@aQ6{P{WX-O=!_i{ZfAuu4Oz&4N$>iDD6kD@svP;y=KR;9tFFNTTYUy9AS^Hw` zhr*0AT@966%jVyk`Td=5D2H!tMkND}!2t$lT!eVT+IJULxpLh+&3p63B@c^;*8z;H zxYp()~8f#YZTybqpoXd`Mt%8NJ5h)C85(y3e zwJqlS5ZES}v8ym5}@nd#iJ+=RsBs3(=%=1l1AaZT`g|KyKCXte*!@*T%^_BUs9 z%e}Du`e%BOw`fB2=9Lcz24ilmzFe zm6RtIr7|Q{>Lumm=clAp>LnLd7L?@cW#%TPr|JQdiIItGUUGg)YS9X|`gcH$44$rj JF6*2UngIQy{`LR> literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterM.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterM.png new file mode 100644 index 0000000000000000000000000000000000000000..e197a99b34f6320d1e74032215ba7d490ab18f10 GIT binary patch literal 1934 zcmV;92XXj`P) zm{xgBld(V0R*OG8EY?M_#{Q^L+a|SEm(TeobEYTv-Fb7)y>|i*90FnP&wS_aJLle4 zspLExcGvG4sm*R4sYPR>wV4xA!TS)5uaxu*Ps~1=?CrzZDbc?6M3dOlaBb%KwL3q) zN4(Ic@uO=-Yth`Zdyh3;B_7{UEh>EQQ9k9di-xcY_&QlAt?}*ew?%tu{BgTQLB&ACK7<$w~{emTv^B#MUV<*4P>SGIO(2_UAdWkOSY$YP7(6(Ke7f55Ql$SXt4?e z-q6+%UA`&a(~+MSvvCwFo|}l)7c3ez@FIeY3lNY~zl5_2n>D~CT$Mw?yfAjrqVOjS zgsE$R_~hb^=D9!r31StL#!`eNWK*Sm7T@et+=dL9KPhR~?y(k3ZTCAeTFO3K0 zYg&Vgg+eG`!qS%%Gjl>@hJ+vjjmyHYiq=@sW^rL`IC^Q(X+M%`h|lI0oEPUo>aE#^$|{IOx@L+zR~2yyB2yd)*M&_@@C_7M z1qwFP8W4Pa_MrlTv_Kpp1Q0xjgQQ8U!e$MwL7N2Dl%(GITg3{Y;N-(0Y=XRx`JmmR zP4J?R*E$Hkp%fwjVku`+Q4d{dLJrAsn{jw^<`)ypI}7|p0Riz#D_q&Qv_u%E4#Fj zDJc+mPa4ojD`q>-l}>BG5|Jt&AW#TNQyfpFM6gH@L@7Q=J`iz7<37$nXcj;ql#(7w zrJP`KMk}3*K$Y$j3M*unNM$}iXo4%f&j}U;K~ysj0UDHDn)KQQ2&rH5UIj&Pt^kQO z@Q*4L2u)v*Ygih*%v7pv4bpfG5L^KipIS(jPr*f{wgy0+N_lZ5>3{GK()LUW*`*H< z{9s43F>{>MwYUXp`A#7aX6dV`_{zHNLSfOuy~8Z@PAQOYEW>;nX`+R}i)98>4725YgkJHMn1rvbw3sxLc=3=ITa zL>n}vDHFX4+N%o?Z3{0dxOgu>`T@44D6b+zHFwNIWmnE40>Y)>vhjD`d<|h0{7i!1 zh5BCr5$dRp=YHM+_XUEN;w>jj+_!y!;6c;p@YYP3zCchC3L& zuA-F5=MSa0AVBZ}h$ddQWn#10Y;j4Ywq`Ft*zo>=cS5={1H%2@lR0x zj6!>2Wo!QfgwQ}_7t2bB!UHy|(B8hWrOf*W2On6!ZQq+d*B5e2aWlAS%s3AS2>CKK zWi>(5c8tGi$Dsq5_leiHZY&iD7w(<|L=U$LZJXY9`3tgU0tHv)nJ5LK>I;Om6z4#=+^sZ$NHteUtzuyCm9e!Z&{D}R zhsIWwg0LDB4{e`%tW+R;Cba;OSq1(_Rsk*J-6G+18d)L*qANtTTq+RM=rDk|i${4E zNnH&f^vBYHNjL5|{E&Hiw;ANc%U zD(5okDo-G)ML@X7GS}dN$LGgv)HxdYpuXJ#L`SMs7ZAE_^HEU;QbYk$D@J;*RG;4U z=`{Ztp;mZ+d-%oI9&B^F`0f-CiS(vf$NKQ14%V#QGrz5qlC{bzP+<;+YnlUjviNgZ z&j6L<&Og$P6^A)e%e&*h_z!$4G5n-8>u+~q8cc@k@T(*5d8u7+!rdn zap_tiAbJAsxtj;E5EJ%PR_^Hxq`-cItRwJN&=SnF-0SHQNoM*F;Ou%#IJyxy z0000jbVXQnQ*UN;cVTj60AhJAVr*}3WMp|RV{&KQKGBibQV{c?- Ua;OG>?f?J)07*qoM6N<$f;jDV00000 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterN.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterN.png new file mode 100644 index 0000000000000000000000000000000000000000..60884b312e30cbcbb8f9905159f8acecc6d9d581 GIT binary patch literal 1225 zcmV;)1UCDLP)XrcJJ6_jzwC~iI` zA7GYLB1yK8#C%lt@{wB0+x?IC8^7jG*EwefJ!jy<`=-Iq zdJfr*;&I{xoE-hIu&J3d%kE%_q?LgZ^$&acamkJ$5GWYkDH!@T1FO{*$_ZB8H@4Au zr2D+KP!A^;;v-+z?8ZrnVCP!QGA*G9Z1mfjowOwNP&P}AbcBLEnOcmGegAE>(Kq!Y ze&ODLCq+~m3f48f^dG5D4vIQL!Eik}svCU2sc>ik1snddYCEfpy-u57+CXtdW zU)n&W6%I$mp%qj*;o$kD9h6fzsN&%Hr6m*>4&>Ly+{c_kerXHED-Prr`3&9e>ChI6 zgo6TTdo!6b9oG^H);qhLGJYusg}V=v%`cL9rJ&F#as@dflV9+uBowZ}-IvWTnlUQ} z1;Y$jHoqYANy%rS? zz9OX*6s?8RdkBGy%qs`Q+kuJX7j;7=p-?5DT9C;vbXz5%VAp#_rSc0mK&0DlDHIHq zxNLqY2X(UXaVK>{45~8YmvT@?uHHC)x+yk<*N}P2FRU(U4Yj|d_N&oO-u zx*Kj8l+~zVXyrHG9N@Y+-fKs`24ycTT6#}X_bnzg4&%2@Dm8WS?i014 zjA(2(6plS48dO5@O;(~yY^p%nYFKvj?lrz0PIl~40m|Tmaz%6OopbCGt>jgKvIk`@ z8hoZKvLLDwRHn1wl@$$@pzLnQ=Usf=&}$5yp`b!I*^BW-enBXE?BWG4uQae^ChgyC zA}4Ao+daJ<*=_|dRT{qhlM3$ICzG;&Cx8#))R@N|}CIie8+{K;iriOm~7f}}gsf^KL zizJjS8l;Fp_%CE11YwyH|45J%wEtZJHkj|@Up@+g^pD4%7eIprl20i`G=lW+=ZWPd zZ;sz1Lo$wk{Qm_=Vum5!Y=e>j001p?MObuGZ)S9NVRB^vVtFoNY;SL5WO*)Qa(Qrc nZ!T$VVP|D7P)Z)9b1s0M%T00000NkvXXu0mjfzbQKG literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterO.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterO.png new file mode 100644 index 0000000000000000000000000000000000000000..390b566125c687e6f1ef9515b1c7fbaea44234fd GIT binary patch literal 2085 zcmV+=2-^3FP)wg9 zN}9*mT5PLDEx}@46l?lY?m6eqWOCsL>)glr&j0%U|34`d zT5xUJ`_XN~M&smNx{uR9ko1kmG?HY%Fnt&cWdnGu% zv}y!!=FfkFZfX62yK`a3Lr-=Ukg54Tn?sw zx|&H2Uswrhm#zgTe_f3>Nxl!8x$Eee7;vnoWm-iP<%i&By4gZY$FBSnEjlZ}H2L`a z)o8=8aq>G~U0#khT522X%h!ZOK!SNm(>?wBjYunbfK1ao+&}_Hpt}jWwvbyYlm7a~ z@gHM;2@SLos0q0Acf<_|+FR2}V4+nT-^^2B>QdXefgY~TZ8w3%$MDg$04oLYf@?ww ztAh@eWn$l2`3lIx}MR0Ik$n3?H z2F8>mxDWTcehXZH?_vQ0Qj$r#hn2>7XgRQ%1F8G?L!Cd92&YS{7fZHw!V2_w=7WjE?c+4y7?^2Nl?xhVAi-yMKDWO zQ$pFug#$!0pi*E3e3s=WOxrey(XAxUt`iYSBN;es%~_@dSVAjOL=7f^hrH6 z+E!&WYq$onJw9IBQtx6gI`adzMLd~~+|kXu#&;xu8VIFd$bkGE<`18jTDG;gglN4d zMkT>Rd6R8q=5y>lVZoZ;_Jz`&!g+29Wsvv7?{#0cjVU_6u9Fb_hb#eY(~;aw^4N#o zn%bupKiCAQyf#qVh~B!@*#JY|*kZ?ZR^eEX^7z z&xLi#^ca0Xr<1lXW`K~``9GRH8qyQH^ zx=Urf0fF@7tB8nK=M5NXMMYnqs|OqB6HMC;xW^N4H}mm&0bKNL53e7O-+~6sg(zL#_x$dA z^hj;%FY*IU;||eGWcNj;Bis5srJ#wfeiq!WC87)xa@=7vzEm@<1%1rp(#T7Q&=r2G z#DZG}3EN$T-*d_k8()SXnvFd0JHg7z&81aqYDnn(z6Y&R-}+PUZAs8_c8d-RML!KB z!MY9txCWUfmH+nDi8|EH>O{_iT^ix^AD*|82T;-k_tA`9H$15kzj5TLyJ5-Fs$zX% ze%SS+Qq%IF8BgX(fuHF|pIircrh(eS`#zmf{u^sG^`YrzI^y7>We8?N`jMk7gEXHB zBDE{K9HQM6FSwJm>=GsQAc8cPblML8AHVy~h)p9F6|5@Ke`WKm0$XQ_lD_P->+O)F z4574JQGK$8t54Um9CxhMF(sRcB_cC908*_2TTX1Nuo2E_o}3l0r$a5;AfS}S0is6u z(6c)?$#fx4^0)@ER%kY9JS$9jP&N2dM;?)uF&i?S)#?QE)(7v>ZxzX?WYKP&Tk`>w zRHm7&?_n1o(GSY#vuFXf+)TT?ib;cN)Xb6%A!W5o+i)eMucY(S8rX`m*34H)J}hTF z2xOA)l99E_w_(1pCaG00GkJEzFnD(w^Tg)12xR2j`T-Pq@Dz*l)jBp0oZNIW9>J+z zeumN5FozzMsTTZECl=;L`C|zk6;t=J_IFczR)U6*lZ)9b1s0M%T P00000NkvXXu0mjfJ>l_& literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterP.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterP.png new file mode 100644 index 0000000000000000000000000000000000000000..70883d02eb6d09ac5c50a88d8291cd19cadd579d GIT binary patch literal 1282 zcmV+d1^xPoP)A#H4j3Fg`knCJqS8<2nxCcK~fNe^dKQjQP-`Yj3u?$ zd~80zEa}0LWCzJiv$B_~sdb#@yUuU>&7axF%+Aiv#twWhy7S-P=l}oB?=|aiXk4Yu z_cqqF5A1|$y@7hD&f7l>9lSLt84>QSy*bc@wQ9WmhbvqCn;m9e>qZ8GMh!Fu6_}~( z2zZhP5)D6kXGA*Ve-T#m_>@Xrlk-yV)PgSEeLWkwA8SSf!U^Hjb?-baaDE^t4bA+J zCV&1(xn3=-NF6Vy!{3Pw6WuLg5F8_JY8aY`{e@rGq~{B((&(oZX=MJFAz_VZFgRK9 zbl_TX0qDb60E@v$d|6;_S$gzgN$PnYl6>zLP1F79#qhe=2rZzeA44h-`5C#I5CD7? z3&40Y4UQ*l5WaKb`)?HpJc7FvBBLz<_{j`@TvmbL8DSACXlnq{!f&fxDR&H znkfOOY4g9?-|8PD)p-I-^gsA7mFozPMxFyzI7P{AHo&gam#gG`DdH+QSzih;v1~^W zNNTgJ0)Tcmw4b0;pnGtC#sJ{&^qGtVsBG-KME$m{0V*4PrLw^;Qu&3}^6IAUPWnH8 z28<@Nlmf&Ob{|m$pGRCzHjGv^^=!8U00|D=73BeBRXq_1Lh{qd11{45#QBj{22Q4& zpn3~yhif5E@0_Usapyp?0hn~4#y8UV(>j4|du&HWG&B@_cwelzPl4?L;Cj>tU~(uV%T2Zh;0--|pE@yA zxJq_++ZF&jPsa1egVG$8tpbo^I{<`BalFW9q)Ox|iuk{s0K@?=+=d&EVvrSwZd(8# z5u!xk?m{m<$mcbTFO=m>3jll@E+QJuXQ140_9pRt5H;o4X^daE(Ig}(CCiFUQDG$Vqyj*!M!E1XB8!SI z^CE92<;oIG4-1ir8E@rWNED_Nd$0RiG<-a9Zc&egr!Rsig|=q*!rl#Av>PKVi-=}}1U zuT8Q5S%54+7U2H?K#fi>-x6t3_zP}6^0OR(-XijMS9--qeq{|ETP+2kS3mTt#aNAr zme5)8Zc53xmR?01!l+=pQs-L_0HHI|YD5x|F!o3ffQhmkAkReO3ms{=TqXjz9cj8; z%I+m&e6GU=m&>4>=`#2)czZ^NF(b_&0000jbVXQnQ*UN;cVTj60AhJAVr*}3WMp|R sV{&KQKGBibQV{c?-a;OG>?f?J)07*qoM6N<$f}0LUSpWb4 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterQ.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterQ.png new file mode 100644 index 0000000000000000000000000000000000000000..c8ee72611a19c07338053a90ba91932b22449234 GIT binary patch literal 2361 zcmV-93C8w`P)X=#pS6g~717z7yzNktEdSqA+m#o`7-m~{U=g#%O0?~8NKHpwzul22; zV-#h4EnL5Q`l1b^w=LdOdTsIWo-ZJeytlWUMtFbaw;PviD9y#QqE@{Y4exn$@o;G@ zEx7cXP#VLtTLR>)wOg+n93EY21NzjqFUxBV{7_zd_(b`G?@pC>oj6xlwjVzm-wSzW z#~~~5!Qs*htT`!Q0rcVF&&M@LfII&8f0+n2Vfn~6HNdfEQ-R}LRd)NRe2EuFkH#;T z^x|KiyIel-%cb)Ev;V}h_sqrWpCR}++>`YCePe%>SMEDjeq!_f8ja_E##$)iu{`|K_l?6XKdA{jjDOg)-TWZ=nW`ix+z`~nO zCRi!(?wNp|H#Bks$poB3t7z6HQqy!~h$O&}-boq$3vWyZg>chqU@1J)aAb_tz>o?o zNIOkq)3+z9yVnd)9OA(lw!rk9Oq-^R@I$a50wE3t-dwXQDW%gFgFQZ;&-W!A1(t?P zin~Jw1t;bE5&(gtkd`}REojSkJj!{nv|3*&O4 zIpeJPEF?n%7lO=tW6P=}pi*v}IrHX)Z|~T`-?5N@XS$j;Hy&85W^FTPS8qwigGEsJ z!1Ep&8abE-tQ7o)q=%c2XS;5`4pB9U1(SMY9%NOnj*8j^S&7fh#?po9gHPV-3K+k^ zZ}oY0)iT2&v#BccvYlU7X942C7o&D9XLg_>y%m{Sk!~fu^44h@mO!0HH}6&LOJrtI4~aVSPuKE}%!g$+&qvG1Xmoz=Q}v+LF+VrOh$&d3oB5~oh^`CBiU+mq zbC$^qWW@tbGgk#@zXFVv#}{JWdd~~*JVvdsm*kpo%bJ!nBNx+_jd$k3KH6nLLYA9= zk$?**py_^+Pl=QyM8-arR}hZ`}rv(?@C(2*ur%BabVo-$BiyIr!hHd9P5+RPiy zLDE2k1jN%khS%^+4HV&0(p9{h0^9FXc&K*rY@kU_$jGFr1ANG!89;*J=@~DbkRXzX z#$D0Jlqd9fYy&6^S^TgAPD2ij>tQq330yfPOQ2Xoe)A9)7%Hp~#|?f4BqNsBw=N8+ zr&&S6d{`w(`>}^hUMq_UEb>FMw$FQ#B=lRSDM^zzFe%o=^q?8E!n5ugzhTx%U%JTe zoZz@{o+&c-4%Kw0KGS*_1zMN$Rv~?730%h9MgsG{I$WA^gt*StuDy5CpqY%{tWSlq zG=N9e1&0RDP5)r~z^m@qq3>8iqd_w|H>u@3KMaw@yQ~3I+dU@cSwTxa9#VyLEdZ!# zgv_rtJbuE^cd{ znVh%~HSwBeqor_Sl9Iv{;dw*MoP3)fd5CGi_GSWZm$93}W~8K=mBFErhr5E;1w1ni z*cVO0)vZ0ZZ)9b1s0M%T00000NkvXXu0mjf15$Qf literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterR.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterR.png new file mode 100644 index 0000000000000000000000000000000000000000..fcae55c7466f914616f7228d2af3e4d7f107e68c GIT binary patch literal 1539 zcmV+e2K@PnP)3>E=N7JO&o519^O@Gp{NC2=rE9I(eE-^`SDc`-CVP3P@P22$1M6X3=t$Ul zmL2Yy4TUC~H5D8V0JdZ=t&a>`I-A>q)6*&3dghk%W6xdZ;O!>`>3uR7Sh^p*D!jYv z>Vv{sUe-$=$#t)4yErcdkbH&vAe`lyxsiw~ZEgJ2Ea+BaVg6)d;8>$fqW;C_L?@I_bz z3uD9F*o8lbowLt|oUT9KM<%DAzAvncLs7xO8?X-v3Z4@f3|tEf0!WmbuOv7u=u|=B zTa|7%t^hI7V5G%hEeU8xuK#P~bE95tz)&teA9f!6{b>{wzGVSuZ>+%3_2l;?0U_bW z3Jl#&0%A}=^o<=D0_uNP1cd!n4B52|hTjma!vyPTomvM2LGHuekb}5iZP^nB%=v+# zf+FeL_*oUKi4!(Wz|uM!kN0^e(=cF=$%EEps4PqXFY49{bx?H0gOGE6~A^J zianU-A2N%U?m6}o-3-xQA?=_)3gd;$%J(a6@cru?)K{^tem;=W+ZU3WV6OK*h;TF zbgnm2Ff26v1OQCyF*W-gjSU#dp-Fb8WECXjWX*%YH^Sb9AzuP1eJcPnxu(G&%S!@K0%>XM zc__-HrkW)*(BqR*(zzCZ2#Y`(YZeUh6)l41OHKih92FoXXzbjrPPIDH(6s=v z$2a-@RQk%Zcc}sU9#DX9sQ6ErR9S1sO*92wjuOmXSkSyl^-BrZ(cP4dgEmT_0W zceZJR1K^sVQcc@r8QtWt$#?o}gPlR5Qwa>y=tg&wrA-+vYZHuQFr~Y}bxga=G1fVf z>#iCYBsgSl)!h&bf+kZh>u7_4O%jllEZmKEaZG{%I0Vfou-`hE)omAclxnCHIznCU zF$o6a8q`J}&5F@xipnv|++z|9#x(BfN&8Y021Vtz#KXqSP6tzT5Wma_T~eHSK$Rty2Xs^|TJg98rX7 zTBq!igL+!<T_nF;{&0l~>&|OOK6WI-x#tcc1nl{Nq$^&F)8dRsMcTG0eMhm;O05Y>I4@4l9xvkDO=WiC)oM=~@;Zewp`Wpbznf9?PP002ovPDHLkV1mD$!v6pO literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterS.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterS.png new file mode 100644 index 0000000000000000000000000000000000000000..c5b671f6f11a59bcae882db7727b2dd33caac836 GIT binary patch literal 1933 zcmV;82Xgp{P) ziMhohBTw)D(xZjxS+tM~bin<~_GMcqzAo%Lbs-kaS9AZA=-4ldWq*gF&LM=+Z_X6& zaLp*SA7E?Nj(OSS>AA9tPX6(45!jIne-}RaX`%4JkMo7`A1tEA>d=n8*WTpU%7HfoU`nG=%Nz{zuT42(>k3t;vH zw4%HQ3DT;7%eM1K8x?a7$4VlSkIxMGcWGQ@z=l`$ybuC!_L>QqN{6!Aw!JVd;rJvS zn{kO?O8*k(nt{h|3t)Cu+IN^G6}M0Pb~(2*aUsqfN2GHf6ZSn|DQ3&v6W@i>u5?Us zhE3&(+maGyrkI;VXxGPpNZInP!Qm|-@TN%M3WL~S7T`+Hl2R7JjuDuA3nD-$c3;=q zdt(4`l{fL!3OMDi-gW=3iDO1uWdxY}hCZCM44^5rVC!<@l&xOiO7nSv+w?4Hl`6Wx zM%Tae_Oqdbl`+7-kywzdtBHGej1Pss>yEAlL+2E55VTWG7-3RSxjotR)psGS$L_(=1ZIeNd|LX5AeWpZOU-#S_4;#?kvC`(j#`FTk zRxYhoLqK-)^_3(mv}_q58r}NHQ#U1o4xergXg;DBH>$5hShlw$%B3AkbfP95)cAo5 z>Q#>;6xWnsz{YV#BT2vsIX#lP?SSgtwo#wB4A=~uG?r*nLQpcWm0}}$PB$8%b%jx? z*C^mk@@BG}Z=Qm4Wf}P7^#K)Zwvk9Oo0S4ja?k-{uT>-Iz21GOS~u5hq6R|EVeG5` zkJ;GaCMqRP*OLJ&c{waY&?u>|u$hax!B%f>`Kj4qJ*Hc>{-K5{Nj)Y^c3SY%6SjII z;IM56&Br9AV2II z`gq69o1eHPMaSax1)IpI5cBl3HY`>S_JeQ}H%{munt11qt=sQO!+_h(%XG4~hKa!K zs2O`wtoHSdI3~6YFzOrPy^k;-IdR^eHW9d1gSIks`^LD%Y7!~hWSt@;0@r*+Dpg9? z*w@`hYD4Tcz`m`sT{ULytW>wyfl~=ILERlSs}3g$z_qV?&q`T`O}-IdI0!9|B(~@D z#ax&mo1yM3jBt709@br};8zvfHknD5jRed9DvGLUKOWPZ*tJSHuInsYfy+#?rsR6JZgNU9 z=x;AgYHdfq6iZoOQRQ~}X13T;F=AHnzZ8IpAa>4c3t&?FqQ47f7rUpF{2U`AO_6hyxJ?+QgcHLE zHkgMQfJUuVv~6>jTct=6H@$LuNNg;wWYvB$iG1G`+NOm1BLc909Uh8*by5pPH-jdU z7)eXmFJL_;;hINV+!&(CPHWSWS~Kk@lZfA@ToLw!lZBSFA9gn9VW7s;UGYIphNn6F zjHs)@pgSr)rm5m-4PV$Z)9b1 Ts0M%T00000NkvXXu0mjfqS2@f literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterT.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterT.png new file mode 100644 index 0000000000000000000000000000000000000000..5e4a3e7afb0a489800509f816bb5afed085914a7 GIT binary patch literal 696 zcmeAS@N?(olHy`uVBq!ia0vp^CP3`K!3HElPlwnrFfh4!x;TbZ+rb}Xq3^t$)$*;To)Ag_tH3o9qE^LM!~U1Ossq92u;tT8=Ir1&P!(@7pmHXb{d zY3Afr+I*W`+;?*6a+g8{lg)+>fB51b!BJu9kbg1*t}j@ zsLQf2Jnw>a;KLcllU_WEx%Vu>;g1Ms>b73>X0dxYpL0HL>s7A%rg5M~jZaT`ui4IU zWrZ7S{dXJhsy-%vXWx;K1<(0+AK6(WR>2tbanaM$?9VorebxA?-Lz`Xy&6uI?XxQy zfB)$Fd1g+VK#Ky4B8MYK7w?6%2c1^I>W(*kf1Z24^7_qvb^oM7^5(B=7w1(z{pZoi z-bb57Yl?~-3t9p{>x5^>o=~$)EuDGw@4g8gO~N|9QyQ-6H-%(>TO;E&!)tfCZq2o8 zha0Uoo_Lib7PuvlscAm5*R^NA($D+qifv}$IzA!Q=xNv&-@e9>yj3#uYPUM>kCYF( zV|$11FLx#T#U%^2t`5l+$ko5N;72{vsg8fqicjSmgcdtm&5G_96nNvq^mEyxmfrzk zUR8IW*)zPXm;B1LZ{~l7C9xpCI0-btyoJGJbNtu+o5RcR$VwMA$J>qWuOgWxI#QWZ zHbn#-bz9S2ePsdP`*XKdIu394H_@y0d>^qqYV-9E9l^x`7Hl&_1DF~Y@-rqUFuAm_ zpV$y>Vp!B$`Q)$ShGnj{j~!CZNM(d(YBf!YU^u9^bag}HLw?!BB_%CIQm$|3Rt*I9rl;xwlctf0 aYhH4GN@~#xw)%HKjSQZyelF{r5}E)`i7F8A#CtAuU$9IR zCI9EK#;5bAn_oJjlTFX91=}pyfRN?%Tg zUwLPp9T4oHbD^A@GeKlbBPxK1(AB>hb}h7Ta%QQOZ1RNm-+n#n`dsKtaux|~8JaXU zbWQx4Z+!RD5k2}a6%*_h4Dmyj({rICc%ZWeqrqq}8jJ>`!DuiVj0U5@XfPU#2BX1f zFdB>oqrqq}8jJ>`!DuiV%>M-D;Yef&n1i+90{bh#_Hyh!a;t0gfB}&*xXyEWuUT3j zz9e4(s+?&GCNCJ=AYaGze40@b-1lY9;H&5y5ciAW5&K)_@Cf!^?tW|V4t)EqbY}18 zS%VKc$G}8a3jI;pJ7jElF*&OwxclRb!PhzReIai`ZDm$K3agtp%FzJjRL+Es;DgRa zG}N_>8DNTQn&03DSQZ=lzs@NMzW+XAdh09~0^BeoSLl`*H^syk9-DR*+7u1@s+)TZ zFh$pz8sdpxZmDPE5hJPX9wJ~5JW0m8JM7MQl&5>HHdYy63NGF}6Hl3xs~P~2#mqn; zG_Z&Ew~nfv)iFN3q=Ev2;r`r`qub;d27{`15GwqR9Y|!AM6fb=?H(gQA$U_&KEjb?Kv$OhSp+5vF&9r0GYdQP0y9F)yOm4*1usG< zH<9yE44DKbgNGXR8}tvihbDvI6@;eTU!Z#wLmGieMW~^?(SsoJj+@*`7NMDwUi7L- zl;i*k8G-TPhaIOb?3Nz|!4hs_JJEz(Bp}o%L3zi6`2x(Mm5m?wRy}B;jc)ruq6x;N z@ZwX3$dv$3{zaj-DKBqxXIqbQNGyWiZ|-`SDM}0s5V(B zk5EF%r9qW@167L;tz!NPFk0*6Ve5L%gpy6;4tWWsn}d>PE-1GgE%(+_27$Aog9IeQ z=__5YaAAxYm4k;JjXsEFbYm-EP6+u3kMq2sL`PV$sui#*#dd2A&mSU;4!jp}f-+DF zUNf7RIl=n)kdxmA3O}6ooBBfT24L-Ew3j*E6ptIR)G9`B2MJ;iSLG$0+EqO zZ!A|FGLz&fznHa>4#LV?=~jipA!UnD@_AO-N)eV#x1ki_;e@TfvA|vMTo_6g0000j zbVXQnQ*UN;cVTj60AhJAVr*}3WMp|RV{&KQKGBibQV{c?-a;OG> Q?f?J)07*qoM6N<$f~MD0_y7O^ literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterV.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterV.png new file mode 100644 index 0000000000000000000000000000000000000000..ad94fc718928071014a4f913d1f933ac6b14f081 GIT binary patch literal 1821 zcmV+&2jcjNP)y&<7TTfI}RM% z(lF^n<@l42RX$tQPH0?Yw)%!ogMIA{j)@J&KjaV3&V5mP^Yo9kg$paH{=xT`YP(OK zix=?a@#Nn2p1q*j*WvS5!+kw{@KkL0*1aFz6_hL0DVg}oE338hfBk3Ov9W0KB_Bou zH9qzRr^q}L(~I|G;u-vSasHe5p;K4?R`st}{%M+g`~La6osF)026Mq%n1AWoE!Dox z{I(w36dPSXF7exZ{>WGH1II3{)#iS>(RTmzm$h)*cPs1OAP$cty?o-zP1U|m|GM6^ zFOZ^fa=anUOFhUdpJ zF3XDpG%+WjY6EScSLPajZfYx>j5S8^!xiEmUAz$+E#V7d$Hr)kOOh)*X9I17xo|Ia zG}ostiO~i8@Ck9mM|p{1TvRkXFJomdF3^@R3N*9PIsDlE)}dE@LR=QpLLAR0QD+P7 zlgoc5p*_ZHjczGFbDvL$L)qCtT%hgp@-v`4%xeweKPL{%|A2?^uq+5eY#`2Wxm}2x zpshV-ctIJ^-o)#H#!K5?fBz-XxiS!t?H0sM(AJ_&RG5Lai>5V4?inAyS003?Fc_Y5 zg*ei?Za^Dri%2p+d(gDz0RH&szM~7QcU>UPZ@ZOHVQ7mW(L&pVvK{XnITRV4OIv&F zq21HF@Gu01OrX`ge6BExMwSZ1Wg{pGWI>zBQ-ds)ozUwE0vl+@=n&$Pd2!6vDkD=8 z-&B<(Xxnm#=_oz$!fOww#pbj&%9$66Y&J2QJrEZc64g=>Bree+BQ_6djBb#nE-^cK z){+nxLBeZjDkP@ZoF+S4wH(V*mpT;+bZHO=nGs zp9#Gjm7i_3K1*JiyOr#0)$%M$d1Km`jTgn<0C91N7h=NZ_(*JK0s}fDqx)=(?qgZX z5Y)y{*&IWh3;DLmjl4`DFpAA1E|pj$-6fHwLN?l%ZGs_R*Vu$aQ%Q(qXWqr=ewL-I zn6!DeiEv!RkHluK$D#V;0__G_%B3VBG%d@TO2oFs0?wNSIppPGANOdXEZw<({)`Ku z@kS*J;u0^ehFl1Yl8b&HMu#z*lMs=Mwxt}&cV!-JMkRtLuFTXqCo;Ggcx z&uK!8T=WSn`IgjX4ml>IzzRN%&Zj9fEuo2*gb=l|Q_#YM7!lZ*4+3i{C9y&i*3~LB zPWH92nM0qXkjM{w5?HboIDEMf8XN7Az&3Tl=#bDj<+LRqA!(tiVQfxM<050q zrCg_4p09Sf%%dSCn?eK^@hOGu?}pKR$?zq$YONmE%2)nCFCwsF(8V^C7QTFY+gNV8 zO<;rFG}>GEviU5^X9}sVp>f63<$EtprPFr`=`DQu^0s&xWhz+%*(lOC7) zIK+y0TPsa7Ki{Z}p-vPEY+HECiCe;?SkX$;v@Z%Mn`-NVy<2TFhcA~;viRE7kWCE- zJ=F5a@WtN78EvOCW3%KWF_H^}_pNk(`@@9&ClAxA}8RP3Nm0@^XJK8r>Hq z^bOZQ@HoUpyIu0-gqKHy9&Tay0@Dhq*>;3LV(fe`8=Z?bS&~~3#8+*P%0Q)F5+iMS z+hfmf1fz3uwmtL>;pK+3(?cH!Hdq^wi$9A#(y1E@wEqFwowZ{*3maZ)9b1s0M%T00000 LNkvXXu0mjf?Nnp~ literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterW.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterW.png new file mode 100644 index 0000000000000000000000000000000000000000..0b3e63e18675d54fda99d315aba6e2e04a1dfeef GIT binary patch literal 2358 zcmV-63CZ?}P)k7 zZI#$GV{4&Si&~1Mby2M8pBn#~YO5~eoag<9lauq_yXW4QG!O2g$$R(b-1B|sJLlfC zRC3Q_`oqH2-o;;t-?W_5l(N2(T)TSK=@4^p`&i$Ue zL@!%9|K#HJp0PoaS;Q}+^3(f1Pdp*7Nhy;hVaTZT9+5ZTXj#*#UzXC0Lrt0b9>5RY z|MpUl`yTvZVL9=4A(6KjG88t+xA7e(FHIW*?||?-mu;xQcoZqApNDr(pCDUN-$V2d z`XT)iFMfF8TF?NmAO9{hQX+a$qs7NWV}hOP!CkJAG(#u|K@4qb0>?M@z5;^{KKSOo zT~b=iT)J*D7;%J8qy%@-L@<``?jsr#60(Ae79nFf`QGPW-PG;6KY`?ZFTM4I+z~70 zeIq4#p7dtx7|XO#N`xeD522WoKi^!omODm9?(7Y)e)OrkB}}YQ#Wzw)zO)1w@_HB< znT5ucQ1}?bx)yjcMc8Ch_DrAccDs&`(HxyPbeVohkP2~QEm9IR(zqp-jIkKWV-z{% z=3CH0+>J3_o;{uPLzLC+y2i(;J+$kiL-b2}DMY~XfqJAo+1b8i=ez%w{ACR;fD1)e z4f-14TlkoJF*g4GZQ~S;t9+d5#@F6`Q7*UP`G z0$4j%z-qgLyiemVi#F0!I2J|asiIOMxfw)NlJN1Y1CJpbTisd1Kj4C$=THeT7PaF) zrppV|_CWabu5Z7@*)j?fRgt*Y3^qh+Rti1~VP>UB*m*=@>&~Y|WGoEjaTt({X^p~K zg<|B{ts9{5I*0786h<=jlZZym?l`gc+4VTWr>%|i9FB2x4schZVu8q3yo;}7Lv*qfGcr}7x;W1Pn<#Xfk-%-M^*ye<#coWw1#;$CT;tHxh0;jUQ>R;8pfhR66s zs1cD{l3&ZhIV`P&ukn{lxGNTe^=Wyfg~zz7`+5uH2#DKKZGiT(D*O!oDqAnW^mr^J zHA;Nhq4~|+bJ!DLZvc3r5W1_0!^2cT=;;9p+Wwq3D!0Yp_cFjP- z(l;6R-bGRMc;C7fhov<&3p_(@TlJS(=cn3GOqygpm?av(T@Onh z8dI%x=a21D0Z&uAKW4oX;iK*m+9^6i(pX_>l^{3|aB`wigu!b3{+MrG7z#%mZE;Cc zG%Pd9IfF$QtfE~bu$Ha!A{B?DgGO7z(i)+C&or5w=r8K;1lmZGikv*p1Vp8Cn8pMZ z@CY62*_woLa$>m1Kdfj#UW8UJvV^0Aqf^>-4$IIh@jmx5+;LjHNP`X19nYBRg%OTr zPyt|xT79f%%bP!JlPX0TtdGl!(95=IJ1r95CYLnGG>U+wcFI(woLH77X}1(ZL%nu| z+}%{>k*dKXbSx~nx)+<&SP6sGG)@VDC5NM^L&?OqS|lvBj6&I@!kz&>`Orh&wEOlh zIySXTLyMNy+t*q~;ZC=ssuOunOH=(;SV9LW#H$^guH&AKdlOb2sAUxHu%lU8!KbcG z-U3UWmMC!4gyW#*+1B(-gQHXTwUsp35>DZlhv^*9r{SPOf#Yyigw{NpswO^T@=a3U z*k4-Vr#E?iW@&BWT6a5#cpJRT6!SOSfa6N2`_##ESn?w=-$oG@6L+`#@`yL_Y}_g$ zFGCT)(s=pXojul9!(de|Vx#_#i!Rx_u%1V}NwnmbmSY+dtCiI-SQ+J)7^9J~+%C60 zbr6ZmHgeh+W4TRgl~(a-paesNO|Y^w7tY(P_4#@>HCnKBOloX{+AF2*b0=RwvrN2I z;JDS*G+4R7i4PdY9V%$dR><9n*r$le*8?`HS-`lJ(k*%_feUCwB)ny(&O_lJB~KQK cGBibQV{c?-a;OG>?f?J)07*qoM6N<$f(sRlvj6}9 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterX.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterX.png new file mode 100644 index 0000000000000000000000000000000000000000..f65c348bb53f365d127c116c63bfd4bc97a9e312 GIT binary patch literal 1862 zcmV-M2f6r(P)i7;*7#VC^WDyW^W8J&-pu*WxjFD}X70WJ`Oo?O_g^T` zs@CRr@2Jh4*iox5Jo5IjhATDSTg3a-T77Rpxi*izf6HiXZddiK`Ds`FJ8PdVNBo=b zZaX-0tCazS)CiX@^xO$-+C@lgPJ76rDc_i%ji53fByU@Lz}jvx1*`Yw9#-0%N3PG0@Xna=$3cPuP6Y&})WVnpFaw0jW# zAo(7?-6kk*LLNMN>3U=8`)f}0!NqIQ2F+82amf-C`h@46KJrD(9~*b&fA-gZ;)Avd z%7zG7mlMUtU76v4WV3r_zKX43nqh*4HhE*iu6%JY!uR?4g_y6&ueUledl`R1kws4d z1y_ckFPCmY=<_Sfs}P>7zmjEuL~THy{OE?J4}Vy;>gQd1_TOjn9K8FPm+qGbn5hQB zU@Q=Z&RJnZD#J$b)K4qwgJs+Bz-vveEkG z8*1b*k9(eb^RbqYpl%klB!7g2Fmz4c7vCC%X-$0<9?)a_5BT{&R#5ZMfsbZM$coJX z_R9kyA$?Rz7@JCLgKqxpP2^PtuMdx zEZt^rmhX-sJo41u&7mL+-7|fwAO(8t`aO<-1hNkwoHTZ3ZA5V7GdH$ui`NPcVQq9Z`Sr#4HW9(mZI%jw zR&WTr>NKZ(l$m%#HWR||TOlBOYpuq^pqg>dh0v94d1C$H+{23hT5gc|n*1Z3LKqpIkL7QD@hJ z%Hg^S$yGeIxUN;aPJ;!myr=d(^H{d-o3K#KiM6blRtZ8d+1YOcAf!X)zm1qlV>~gHF`yhHrtwrfbYapwMnz+Ki5Vm#bycXKy zAs{Oo)>voGW^#kDOp0*HQv+G4;%Vbyb~)6cTMPu*Fdb<&D%x+PLD<_01G2V)7|g!5 zS0bUJHYR2W2MZ(wvLQRtu$q$6X%3B5ATc`7!SstgmaWb0GILFhmF2>-7!lTWO%lKm z=2&>G>6gsFfIHG!D{B^>P3x_xN^syWzBOz5#SYoY`h=N&p`q(zB{{b={joOdkyu#e zThpevTsM+cc$TUJC+iyB=dl|xOdXHqi2>p;Pt*Lh%^FD+kLM&Lm({fQxsc{GmS>wF z(-;fZAFkqYvo=(%iA$s0WlK%c*#L1L)TcGbx^wTo@!eG5ipr(7p$$zY#Fkwmrc}dZ zOQtmr-8M*NG;8~%Hq13A-wL9rN@m1lGeFwR#5Nj7oi8ao_sIa46v6pcH8z2ZYCO}F zh?peL7zCJxBOmMS!NJH`s zqbXEgBN!{0wb3E6Y^n z91gr~KCp+UPLxy$Fket=-9m_)jD`Fk?QHN-?G7QX0000jbVXQnQ*UN;cVTj60AhJA zVr*}3WMp|RV{&KQKGBibQV{c?-a;OG>?f?J)07*qoM6N<$f&%D; ANB{r; literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterY.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterY.png new file mode 100644 index 0000000000000000000000000000000000000000..ba733c286e816dc039c383e929d9d77a03dc82ef GIT binary patch literal 1458 zcmV;j1x@;iP)`lrc9-m^HHdhuypv%h%GC7b*ub)`JSkZqSNQj&oS`0$R* z>mTlTD=s#xx;4=ZAm2%@Sp=@?E3zKQs`tjpW;5L+U9@5Gh81HTlE~?(}91u zVl!;pG-5N1MU!`ec|41_H5Pk`Nm#c_Hk%cI*;tgm53EzH)Qm6|d+AJuvT2jqC~Uf5 z5uYU%(dp27OY`r);sacyC)Q*0oqgYp+GaNjn=V+SCIrtDi>p5$IUL4f4V%b0hBH=>nym z7rE5s%b2*PXH1>vr0o4ByEo*x>$#fnWw z)JuWK=JM@>nRS@SKU@6e!6H`VkVylM;e@=3LZKup2OL~KF`nGI)@k$6i zqhcd1X1slCApC98i+WCP5D=hggMh^F+j|Vc-(@mWYNHHMyT^qa1x31TDM*vupl^A^ zvue-qzGlK7)fVZJ0x7VS6zRE+AQ@Sk5ojxAic1PFLeg!E!XZsgm}H=+>vlV(vF_8h2V#E7WCK=tzp>o#W5PC zZi$MGcFSl}j_n2Ngh)GiCnT+wvpIH$-uI%|*h)rZNqOUwFE;8;wuyE&^Gkm|uIp@2 z{9H&zBuQy>xi-$Hg8>~H}EFf$!{ure#$x<_yRS@ zmeE^2J`<8^Cr#dY1Fl`8vTB~JPCNNb$mA^2HA>UOIVm=?YA3PD8w3-OR8ch++toZ< zHfE4rDglOV)EyJZo;W)j@wSZ#WT#4!trTxnuYy}#0DgOD3O9pL8c&6 zkSWL%WC}6`nSx9~&J{?EC!;zIlb;Kad}?Rn^y7&{f_!_=$SVHT0ZrAVKadY5=3f>+ zQwg*T&0uXEL#&rydvkFjL1Jo0KUp*W4=V%3EB=%&mq?H_UBf^a;}EIiYlr!omPfTt zHbQjaT}cGl>QC2PfoxX^wGKx>vnt`Xz#r?Ifa_5)d^Pt!x~iLkD&qle0000jbVXQn zQ*UN;cVTj60AhJAVr*}3WMp|RV{&KQKGBibQV{c?-a;OG>?f?J) M07*qoM6N<$f|^UbqW}N^ literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Letters/letterZ.png b/examples/quickwings/assets/tappybird/PNG/Letters/letterZ.png new file mode 100644 index 0000000000000000000000000000000000000000..d5e88ad8ef767db79737ea7ec9f6b18207973264 GIT binary patch literal 1257 zcmV=P)ikx6a~x@ZM}^`@ZMA@ALkCE*D!>&39M% z+hUje;oisoa4f#>W?#~7g0uN31H=L10Li=DoBR)e0K~}W zU((qSv?;RJ1-p-D1tLm@J}#O9F*3I(<$_Ws9E#0vIeBgq&l%nL5MQ>voD>EEhryw& z00G(A7(|}6G7U)e#apN80jLc&XjaZfN2Seih_SD~llR{xbZY||%mQLv1`vE$bGiMz zmGuHj0n*09_w$B9K#-Nw|JGjZYEOYs2LkaP3seD+5vgm545^g^eKQNXLBysP~!Dd9kh6<_L>4PNg?;u%bUOv(tkp*;eDVoI(ETO+Tr58Jm)tF9)V9vH|q;^Pb)xpmZeAy2((gR1O#^!#Ea1{`aKjx%gw^%*`5_zAZQh(kmd{m z8<0tHUi3`qC-?BDB~^0oICJfw0z|PZ$K}pde4(B(Y<8sMiOh?^5Bhn*%UEcYK){J8 zUY^@!^+FGfHsrj}Yf=y5iL}N7{U>;*0I|Yy5c`9%YT6Jj8VY(il-|fquPzt;K|^gD;?MMq#vfelo^u(FOYvJ!3#KXqX@WLrbiE~Gqq1=eENOX!=E?xGW%2_{D+LM9VGD*!e)SPy}b@<2d=U07_7! zmj&`IIID85X!^2%4Mc7yc?uYWM|oMGyZ}Lzt2OtEQgewy0a3==tbYNVkyQURX(@F8 z001p?MObuGZ)S9NVRB^vVtFoNY;SL5WO*)Qa(QrcZ!T$VVP|D7P)Z)9b1 Ts0M%T00000NkvXXu0mjf6@Nqh literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Numbers/number0.png b/examples/quickwings/assets/tappybird/PNG/Numbers/number0.png new file mode 100644 index 0000000000000000000000000000000000000000..a6ad98c107a4474712cd5e73b0780344c8619e78 GIT binary patch literal 2130 zcmV-Y2(9;tP)F*LB3QaoN(l&pi(Jb18>_RZDR)g-jzdAx`B`vS`dGfOTUXna*1b00D^zkJR8xpq6asmEK1sGFljP-WzW;rB_xA#TkfH*&wY0P}-cvxBK&u*d_{|@~dkcGUElK{} zOib-{d-uJ~6Q$tp-Me?KS8R5ffFAw$P4epZcYHAaZ6}r6tFT*?e*k98nocA z@y?uEzl}R!Df3Q7gIZZxS;rtxe)?(;5cK{a8-R(#o5q4SZ2u@md?@s{GfONle=g!Y~4o2@b zFjQL59>s*EehVU`IGtY#okXOhRpRQ^tDlwuqQsV$mtWvnXI~MUNUbP5qEPh^fp;dr znJ2UfIpC0pF(8F*fY@)`xN*&s7RCu}SfA32LKS34gmB+P5X#$g*OVQNrhOnY)seI} zDJ@FY*;XhM=2dXBl=U1Vg{of0(}NrY&?x~>)<*Cgp7%C0G!(=7gqXN7-tiy$NH#L7 zfiMwOZ*FexTLE=+AMXLcV|d>4i=ffLq4Hx!P{-(qou*j)RbEqe8~#)0k5>op5aoh<`lhvkWL+orkvB+1X1m zpzvPw8pNe=4b?$q226MSVx*)l)(vXX6FrXE#sL`~O-)UG5CaPDc_v^v@?gEn`FDI( z&PP=<(q?2ft{F{MV%O><+&7>G--0?|P=jwl?X`iv1vNiE|6y$2zHdQQxnX|`YCllR z%gbNmKX6`V=PPknRZxs-qCgcn-R? z{OoY(ri%LW)?Tt%yP+BrA5p$4qtn*PFFaqDk4nR|@7=)D)6<_t`w3wmCSRo2^nqzZbKW0q+P6azsRnztM za!5xXVl82-vngApgU9+rN@GEHumHs% z*Q<24l(5y+R1G0Z3(&DXky23p9tL+>*A97X2wOQQV9GYhc8bDVvd$x+apo|Kq8JlG zkE4nXYmgA;r5(wciA7u1N`OvnQRihw@EF)d@nEkQ@(3jbiS6{)0}?s3RPB?w9o1!Q z8kjpK&~er!HH;(9HT%^-22iWQ4a=Syf@xUs#rV+CJ(vlLiDgH;r#@Q2xQy#~tjJV( z4p;q#<+$D<<}(;|c;Sw&IY&kaYE;(oJDyXY7LgG2S8vJ}u^+GNYok+oV9+W37{TSj zA46w2rNLl)Mcb9^C>R(iUxQ-;1*!vkfRUGV{Ep{%{?cF+W%m>i{nuz&EiCk&F{8EP zJ-lB6hGnZq8a-^yZpFShlfe$KNF*1_I)2A;+v|XhQ_W;~j z9h6-cxKYN85&g8h-xpxY&SXtlKQKGBibQV{c?-a;OG>?f?J)07*qo IM6N<$g0CU|=Kufz literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Numbers/number1.png b/examples/quickwings/assets/tappybird/PNG/Numbers/number1.png new file mode 100644 index 0000000000000000000000000000000000000000..99b38b8651ba729aa60bef04dc7f22796c7a2e52 GIT binary patch literal 948 zcmV;l155mgP)ScbB0009*Nkl-(HQ9r(J`vbuDZ)2l&*%VuF5Pb-9{H#%qnCT%E+RU5DEECl~9J3Aq-^} zL#l)>hA>)&E*`^BW|11o(8cZjC-)}ry~+E`y>C(Xa2844yZPmu|2gO7-4_Z;wnn3| z)oQi2ogBx7g0ObG-RpL{#EVOVDHe-s9B9AymK^S99UaHvcp9~oET9p-;NZg>a{Vnr z$Vtf2PYz#9py;`K!u7Kd=yZ#av+c!>&tySCtaQOK7C!p8I|up^C*<##SlY#&cqo>x zDi`Xo|7xBVEkztnG!#wO4qZgUV!iiOq8-QQK)j|rp-C(dA?o%4+Mboqf|6*bV$qrpMS*qKr4*BTLGR#2!WCSXk;8Ne8HgAV*> zM1 z_xLds0V3?BGA*DYiA3TNeeoM2pJ~cVmEl;VTt9A>gj%6~zf!4u!kZBLWMMQ$Cqv^z z&tfq6L7snMo*Huh-A0}LX|FZ$skp>6@HTrR)kW5qD}kqV^A21W)HES5|rAM>tmxW?A~>i`UT z8izoEluD&CoebY)Kt&KOzPSG44gCx40F8~-)1JC7hudP6sZ&Hua!Tv=S6zrY@gaL-7 zeKtR3L9IH#Y_Os*-(iso6=qQ|M`fL**Xp*9R45J>Wq!xyy(sBWer}K{C=0rghKHx z-(|f}C_ESW^ji!&71+%5>uj4PDiq4)PKA^I|41j04;PySaefwW^{L9a%BKwc`jmXZ*OE|c`jped2n=ZE@^FHXJsx>PDe5{MQ&qn WWMy)w27m4V0000b-O$B&HMY_ zoAJ<4%CWb%cjw^XV0M3hzj%0fSPi5WQ!0U!@GibFl-Ixlun;Wj`1n}$LV|DA@m=2_ z8gdcU-zw_ygC%wL_^x{P$5-lg?bBF-=WCA^TJPc;0#p-P%S>B4J3G@yM@J_-;iLOM zwifg5bX=*kp`Hjf!UC$awzhV&Cm^sp62yb*&#Lj)baXNGn@YW$Rq9nysn;c?-qkMT z-?~!&H821DrgHH+p2PDNQ20KyB|!!2m`e--yFotDWK)7B-v2#%Iq{3>i-lpqX~z48 zQq2>k8VeVjLf?leV)Gaj0!$*4l78{z;rCGxX#unw&?2<=?2exA^yHof6!`3di-Rw) zHsBX;pMG))0ux{deGGttDbm~s6i$E;L8LZ9{_wV{av9h>0}wVF*3$_{m3`yolP|(1 zgnxo zx%un*`uZjdYd#V=UCbHdpSjk1%-?KL?K%U(#7rtRje&ZFU*PXZtP;T1*4FRy^Yfqc zcWeUfGbjMk-*=%$2qwWhFkLdWk}c)j=1GGH_gpf8=Gkb7)v_jFmH>}Mb^>7n;_qWY z&e{PR5g{6^-UenkkV#C49cKTLlwWcrEU23%+DW-w4(B$PR6vXXZqShpaAcDcvVF@M z1OCuu!Q+A42xLsiZK)mpmX2;2fEl7iv?hfg7%b)NjbgF*rIURVkdKp^m92h4 zQr7+wH)*2zK^%|+5=Bn`gStM=Q2vs1soNkv$o_(8o7Uvh0I7$PB^)2S?N~l@3yRXj zn0GMTXMnA1PKLF$NEKxMgGiIFsOb)1Y@=?DAhIZKy*HV!@JZj!s(glq8<{dA}1hR z5w+8(S04#!#I?;tv;}^~8?(H;{GH&1IXJtkX^Co5MlYj=D&zwsVLJ)JeFhP|rl=n3 zocY74}LYq?= z$ZX_P4aW+uQHy|JGjahU8xSGVm;wm5h`a(Jno?x66A0xD&tz61m^ndDk8-(k*L=%CgL26s?GJggsY1I9frl}dN>V7oo~pM>Y- za`{_Hn#Xa|4^`oy3EfZ}x8BVhPziw<`;fpC1{lbs?f7GaKnKQKGBibQV{c?- Ua;OG>?f?J)07*qoM6N<$f{?KlEC2ui literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Numbers/number3.png b/examples/quickwings/assets/tappybird/PNG/Numbers/number3.png new file mode 100644 index 0000000000000000000000000000000000000000..1942bc4f6434bf609f48b70d401bd73baaf723e0 GIT binary patch literal 2097 zcmV-12+sG3P)w3@*08*!V~ODFs0x z&_KW?v^0l;AYkYr;1XI0^dJZX3OPsw3V|NB`&sWz-pAG@zxj<0suN1HuNvFm-=D@ubO2Zo7S{fCI(YNj zcn~}t@e;g`xinxGg@OtvTaYHy{BAdBJzNN0w(cY^?)h90yjTi?m-U{!YQFtDq`lC4 z=Hhzn-Ph;U%gw=e1gK^%^CL~PctV)Nv!6eX@BW|Dy@kJS1zzKyiyl~j(}3Z73 z`skF8PwYxRh-m=;uz)x1pwRJer#CO=r*FM_^1d=Z91_+Vf;OZ%J%9YsTL3T#m7zwRj?;zI#JI}OWwGcz+Egxcv2m3DZLh7few+)}}WGP$+2we6)H zoNjR3G|6)U;$1Q~TkX`OcA(Z&?O=g00dbtB%Co87sfZ)kXW-p%9t3V1->FFL;3cDW zuuC+t6qsh3#Nw5!KO!`c?{FANJK0Lm&iwrREI*7CLum(^(4sZs5lm91AW6dMkeU;l z5(#F*AtU00y!KV z1iNWq615}K3khIxaq$yuK$gHCd6Ob1Ch|Mm(K%C@Hi2nng`5egoyR|Xsho}`=x%Rs zf4j1>@|g_?U7#t}kkYuVb~L}qI-)T~@lmNAmc6~bU$DbIAf$$PK4oq$nKx|!&ta2$ z-oS^~*4CET?kzNNE0k)2+%{u#%I#BbCY&B&nSgQ^-oxgx;NQo1@J8j&~%zUaryALu={cm+ydQb+g=9%G)UKK zyblczlyhUICz8xMX3q#0m}7Ny^@~9ghb>NRG85SZ6GP_A@s3Qt7(NZ$R*EbL*0U{h zGzA1ZZ96D0K&VTR5?lTDLbmHc+`4&@Au=^x|U1RZZ z*4PyQ_aIv!l#fYYA+1c(0hJ$2Dzlj+0O6AM<5{AeaE!CBkX9yhhlv;%m<#OLBuvZt zaBeUy0>W_xf)q={ypdwT_|mg!+7OpOXoUS_eSQ6F5x~pC4@QuG>?0yTGLULfL9c&c zL@eRkB>M>kNX`vMhaZe!G5Hc^(9T$q=}3Rg41jQz7Bw8{H%N#6KVT#%N-TAHHjBs@ zJ}~lhBh!?g~C1^E&O&q4s@$^by(!5@5rr~wcPP|hVnt@QC@T5iTA za?Z&hipA6^T30fis3wRgK=~gC^?LoTZv#V&qV*}8K(ktklcyqG1@{H&$s~vcx=4DK zB~mv9?doD~bZj%{+-NkGyutVqfQaIfqJ^ob`;Ci+NIT30*wD1D6qL0f^W{2_SJ}}} z-tYx8nimWNgnO>CBbgdkBl5JTlqdx^NyQ+yO@NTnN3?^Z+cCT5Q!T4j(~mKxn<<-# z@*P`Kqf|%KYU+cc&&Da0S0uV~dPHDE1$tm$xWZj~SHN7B9Z`LISHP5FK4Y8W3>z43 zaZx2f7v7oLQ1~Wl1VglH3;)^ACQw-oP^pbeTB9A!8yg#+>OkfU-K~W;fl7)uQmA#w zqUjyJtSv7ue`qW>Ky{KxkS)6iPFPHi`%v9TqPu7%UUlwLaE|w!@duEqBbnpu)Bvt2 zo34|DnzLK-eQZ{w8sO60Ktwtxn#4Vi$@<9@@0RJ7$ekIco@5un#-J%7S04@CIN4u_ zQ!7V`LA+zCtrrYD)K5JtQn0Jo83veD5x}!b6S8g6lPJXIii~+uH?hmkS$y>JV^F1T zr}#HR>#mbvS22%o{~3LsyGD>f#EMRA)7C{(Zi-_DCaDs@P213N-WFo=6{!_!wwQ>3 ziTTU04Fj2h_7^g-u~>YG_{*>Xq05-KDtD=mr)E6+mA?#2qp8-kEeSwTbc&WYP!W#! z3+#IshTxhd5Uo~I)-}_K_{*UCnV}6)+K{yx^tx&7FY(rS(EA5k5ujQzBPTXtc5nKP!4>SHa`?DIfS@0~!q?D9NcH<%_ic&dCB{7qoot?b{xxm%VjdYB zGbu$0HVf7O$2Rzc-hF7*T2i7!&6-+;4I}NwBCwdG=4@Sf;b1at`=Kc)I+e;xg#2a^ zJaR!&Soh&L(WtcnfVfcZ)9b1s0M%T00000NkvXXu0mjf(B9pQ literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Numbers/number4.png b/examples/quickwings/assets/tappybird/PNG/Numbers/number4.png new file mode 100644 index 0000000000000000000000000000000000000000..b72f2e3a9256a7bd6caebe7bd95050c358659a6b GIT binary patch literal 1275 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 IM6N<$f}5Q@rT_o{ literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Numbers/number6.png b/examples/quickwings/assets/tappybird/PNG/Numbers/number6.png new file mode 100644 index 0000000000000000000000000000000000000000..f488ffb0e9b02a068fe98682e938a005bd32202a GIT binary patch literal 2172 zcmV-?2!r>DP)ns8s1HS`|vjqS9rei!8bdvkTQ{n36Cu@;|9El+Y4F zsAf^7O6VelXb4>lA(Sj8LJ3{m-p`wJem(cTd*Az=-@A9-{5Xtc?!CY7@0{~Je|~2s zCicL(aN)wC8#itoL#|)He(vVYo84SChe&r~FRd$At}I=G#yOqN4@(h|C3lO7`Z3VFL{dy0; z!+T%!Hu?JDe3m_$h!&n53#j~qXUbY(Giac8!%r5o?Afs$dC}dGzt^+u_2!N|T`GX$ zz;*?UIC{{^osDmM8hQEq+x;Ne|b3$O-M>tul`$hau)|UjzP6dQk2*AdS z6a)w6$k*KKvapZWa#rF7|FAY-=Jv= z=JMsszo3ysAS&~&@> zEjb`Gtbp*Bix)4hMfeD(zdx7BCM(s&z7z<*h+V`S(GZ8CfX<#h`)Li3!?_&HWxCZq zg8EWVOHgnu+u?I1le>EL>hq&VkG@v{<}J}k`>iU~Qt+i%a=<(>)BG7_I5boN2opQ7 zYkdVxR+F?OOhXqCHrAJjT|(XJM=3&mL|M~V zL&XwANLXVTPqd`Pn-xG3yz8VcJ>q~z2B%3Y4j%Hm*d@NCo5ZI87^>k2;dikRI!{*H zWHrg)P<_GlJlTV6tg;QJfg3@i`ZF@1+^7M!==G;w1`#&q$?SH_vNpp+y7Eh6|E}sP0e* zxSq6VHx^bPW{G=50n@rE6XzhaVheh!8BnF0y%Zr^2n2=J zJ=zk|(4;spVUwU}Fw!BasdR%-U#+dJeMb>lsNcLfrLJ1EtfnxebE2zc@7!iB-OK_Qr;-blLlAR(kMFw!Kbm6esxq(d~U$vBnE ztTbUd^vw%l#S<$_d*~IE3JMkqV*yS|*Nf$Z36y=(yzD4xgjPZ4kE!Y+ksL2x@;*py*xl!byE$NLym-DWTNL zRK?$Od{w9vV%u|de$8z}a^)+DrMaqE^a9czNgyjvQe9%d)z#GxdN1X^D4EtJRUsot z^(*a>kPwF<6KBs+<5d2-nchoJpFaJ5A6dkvD*f4VbtM|n?hYA6tocj3TQdr7SOO?w z1^-ZZF?m(uX?e8O7yLa3D(tJdA6Kpx)QqMo!2~>IfH08l^uz>WnL^txuwFunq*=P$ zREEpD{hC-7oHh2uDk{-o!C0@23J2+7Jqahao|4Y8qrZ}h~<{O0z1y2}3oAR9cv6$ZBGN@UK zw!S+mZ)20+H%)$=7|mHJfZ=yNq*QThX|7>s`%)EK+Z3i;Qu=^I`qB+X-;i+1II1yo zy$vy=43!t-3n12%C8;4&RdVZ$xeD4$IVheH##6tQ*felX36AeDD^wT`Ng3g3V~N?> z&|#|WnL1FDT4MJ#M8*wF0NJ4vT*YWZujfm+2+o2N<-SjzTVoL0V zGO*AT8P&(UfMm|e0%A{Q9`HzPN_Nn;uoM`k7<>%&@=|ePXdt{;K&3e+*G$vA1*X{s zFE7Ly*r+LR1XbQ;rklwaG!3c%G&_;d=~<`(rukZ7PD1~tBlcFl3`ESVE+fH*O6~0V z)GB+@0z)*F(moyFD*vd<{w-9UR1Apde63BX2r(5yTO-W_PL+Y7HENgg^$Y=#O?f9> zc!t9%kMwZiP&0)#)x_x1l(0;pT?_-++Y8T35>hpsrQ@hI)6R_n8VF2<$c|}h(2f-y z+veFJz4&?8%&c?G#NKAG$w3l1d)|={)B2i{anVl8GS{Yd2C?I8nMg*I!!nLKIk5-U zw3z0+6NHX!&$K%6+@Oh050O^1@gL3gsLVd%bWi{Q04;PySaefwW^{L9a%BKwc`jmX yZ*OE|c`jped2n=ZE@^FHXJsx>PDe5{MQ&qnWMy)w27m4V0000Um3IJ2Y zhm+zR+di+H_ZP2!lh8usw&VPcrDB4Z2U}pAbb$1` zVCYYO6x(T}_F=%@yB8H8hXeXvQSzj?J>~*gUS2*P8XCGAIhd)bspnPUWx||L%FZ)K zdk;MCPE1TZQobV&Fp291f?v-enjiHDuRxygcOEFB1k+!VAyi zJqTCj{XJGx3%xmq#l?QA0tUadVR)%Dtb|t|IU}0Ib!>m19S3->hsrJ!(1?P%2cab#A!+?UxV{~-%zNA<3RlU7ozruaJGN9-bO?>Sfp%oCNmwFNmvg*Bj#W$0K9F>i#V%VMYbs){d4$5kO_ zB46l8f@_OX@ozK+i|O_)At6S!MJDmpLg}%XE+rF-sly5}9j3O%z7YFaGGZ|fv4w?& z_f+x4yppfE38O+82(hFjn37M6=}uqZz3>o=i&L_3pHHoE!-NCKDJ3xO#9zl-wo>rsx|d>0aUq)E7F=>$N0Tl^!$fD*0@ZRB}QxU%a8X zS6>Y0$UNkuMl2=DO=WiC)oM=~@;Zewp`Wpbznf9?PP N002ovPDHLkV1hukYMcN7 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Numbers/number8.png b/examples/quickwings/assets/tappybird/PNG/Numbers/number8.png new file mode 100644 index 0000000000000000000000000000000000000000..71ba693a6d9d3bed1974894e0f261c95fe85fe4d GIT binary patch literal 2373 zcmV-L3A*-)P)7c0z41SX2l;;!mQb5GV*O z2!c@RqVS*~bRncj3qltU1VL~S5eh;VxA%LV@AS;fz3G>L1ah=o zv`Y|=?!E7Bq=;|9H zUIO6|l>-5h<)A?W)e8?RYk@jb2dLWm6@P*Sb5s`Z3T;!}YQfO6t9s$(l<~CvN|G_& zKSy=(yhw*OT`3)ScuGY-m~wiMhVc*mVls#3aR8}OFW>9jKCTf$l~h*nM?9onJ;Oi| z;!vmiO@LBWMg$N$p!P0RcdNi`J5(HND=#_<#74rUFSvi{(xtUCXU=@SyuAD=C;ra@ zQVFG~oV>$zoZJX>%s=Sju_20hYDh#*>iPNe=f5eJU8lIj74xW#%lOfemFH;%AY_d%~czy71}Kr{BqTnnKT*s1d{hV#JXg)QXd)y@1{wF!%=$CX1W{YAMc> z>IOiLGjoCTiidbs4==`Hij5+W<>8+=apEJPd>#Afz?Ab-!hcB7M9q{CGeTBXB#Ygq z=Lc~_`xkse(hEuj@t^pt2@7Tl2)Tjm#LNJK`q=0h#!iEGfWYQrR9e=itzg1Wm3v?G zB|i>?K*r-&iG$AYpIN~o3|RxA*)OB(}C6*KwLWJ*B0z~qU!x>HR_Ef3`s z%?-sPlO-jWQN`WV=F|A<>grcK5%oK%C8(wYWFhtgt)Ra`6cG)`wlf^x5GxT-GER0F zwuLn$G6x{jP3y$u7%K##5p8T=2I}Fp^LkM(fHi4{m~}lsTYY=_1Oh!x>H>Hlgy9Cw zTl_tz5MQyrDF7broB3%P8yjqz5BULRP+O+7ayoF3uGmoDP5{-*$uVMV!~n4oE%GDg zNThazB#yLVT*%R?Uu!|mW1Y>E^8o&$|WLPTQmndDyW=3Y1pUfSgEv~ zd>m?!P&9}CF|_$yvOlMKdF9w(95D zX9|@|Ex@S?fenHxNo=0sB}`r*xF|CK1QkSR668)Psd`w|Y^#cC%`A37X_&H|jTp{s zxMc#tX^C(HPz2<30%D~js>Y&y&u-YqRB^|8c`-t^vW-+)HG$v+V?H}c4jO615|2dJ zw3{A9)3>O-#P&#p?`inP=%*rz=Bj>7)zu}W6d=9I=2+nIa~FEGx!Kr2ww!YW6ciwv zf>E8#2h)m8n9P_P37F)CJZeOVH}mq;{N95R0$^&Jdl!tZL2U-MnAlHMFmzyQGqD69 zJa29qZRcD+BmpU##kNyCYVNrPa=k7VOU>dmEu-NQQ7j;-J8xy*)sa#Z53^U{WGhac zW=dKtjuSy z{i(G#djmH$K@+#YAXB<$y$a_HRSi>8SGc2(sCNKKu4O!RNV%kCZ{=M zAXdHPdP~qfo2W{d9Ah1IeYu~yiVa%&_bwexRCdm6 z*EwqukgcQyKWIRdFsj?<>;RaClPxTIKw4E&(fa^4rM34d;po&`TS?*cngWBgp-!gt zPN!(23aFL=5|s?jSwJWq+0qcGI{-yT%O3#2fAphf{$>W7ukcA&pS1;6M^U2k>IZYN zDeVEjG=zc$shjx+xL!k`1``rM)DCs_!=MUjEXn?&v)b{hN(w<)N!cIGVKe;w*`UeI zTQxF4>T{@g1&CxIf&ZzRP(J{(%-3Y{9`u0Qw{y8b^j=L}Wzv?5pwrk4!V7F{(1iN% z5_gRRmb~id^w^NbxCC;ol&ii&nvJC~2-M<;0klNLM*^Zw{bqdTYcP2adf#6E#CcM5 zdRD@Vg@`$4E^!Y<0{;O4*>;LlxZeW+001p?MObuGZ)S9NVRB^vVtFoNY;SL5WO*)Q ra(QrcZ!T$VVP|D7P)Z)9b1s0M%T00000NkvXXu0mjfdkJS_ literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Numbers/number9.png b/examples/quickwings/assets/tappybird/PNG/Numbers/number9.png new file mode 100644 index 0000000000000000000000000000000000000000..18c1d4251fc265cdd81f6720967e994c6acc79a3 GIT binary patch literal 2266 zcmV<02qpK4P)Fpb+Rn2#5uti+~^$TttL|(8cTfCg;1Jd*{8(J@37l=!E`|&U=m+Q{(Y^5j7@TIO2Lv;;U1z6u#?O!;RKsv(;NZe8B4rEok;$oq{_7xN&);} z^TFiXU9?z8{2dY}6sURNyxeC2wlmp7@p+)Oy;!o4gSZ4gf|*)=>-zQUvokX@U!|{a zb52c7on2mD{*7J%HgmvYT~S$!8`#5yq;c$?^Y_>fAoGjM5zx(>Hy1RJtO>w9?hXqW zHxiyD)>_X@w$AnNKBF&~7^t2x!&V_}AAMgyGHCs!V5bmDof|Nw~LHFgLSBq|@ zb3C16LHO3w`7VFAxVZR>mqsjJBDs)W0*`ZF;V!#)GO`dAw2Gxhgm@Vzad`0z7mOXU zsVZl!d-=)9BE*Psr6`XwCUaNP{|S@dSGhHekBN>GGGIjrsZc&kL`im)5(AeT*-38Z4GlRng`Js(l=(9268a{@@g|MXE?#Df4d^ z=z-U(234o9#6OtTvb+>lW~}lY$(ks05W_vkK-Qkc zKA;*@%U&fKtHH85N~#aucd~6(JPxfFI(PyW4Z=QmIk zDd~N!NvK6@c~!8r_jf?;Xo5l__tdiP8+dLAU}Y>e$Pwtz5LBIg12j*_N)8wT818b| zMsNAkQ+1=S(7tft!pEd|?|iB#c?|N-Ez)*;%HLB;`Bto0V^{ z$dJOrnRnDvpg?3jhpz8_8gmpBuYn=X*dWnOeo!eSj_U*&CP)ZwjZHH5{W6-F)6>(R z^(_aakkX#!*8lgL8O@KrhgBaXzqTi0+(%SCQiKR6rNtdOL#M8L7iUQIa)3K=K7EN&OEBUEa#XYPMNp#~D3u?D>jE7`y zJVn&3C&x$4+JMHGlrfF0IX5>qO$&LKw=9~n_q_L&Y}j~hm;>Dt_Q z_-J%!V8Y9f-odq1KZ=6TRzhkSr0aQiGI)g{^YUYnyH3J*`b1u6ylp%_iU)xse`$w# z7lxr8JcSSDvKE{fO;dFg+cLS1EY$Vt5EtrR`EH&<01&U`Me7u;#iXyOZ;+|`8I5RA zJlyVgYXxov5Nvz(2v^WGz!dFs2-|75Q{>Q+)Dq`TT(lOV*nQqB_ij38l^|G5+45fi zX*m?!(}<^W_O`tnFj*5;03%^S5fr)ZmKQ?`kh;}EwriV@Vi8Y0y={H3JiK>aZQTBUsgLzz>o~66vB&-RRH3}#;0BpSER28 zy@puHIMzX;*7s~d21?7dgBYq;rRV&^?fnudk8GeE&}Yc_??deTK)dNq5-bB(3t~rK zuN$dSr23$cJD6xW`}FnjEI{a3QCAb5_POxbs9bsXoY?niN&*1t9K=V~f60SIcv)DQ zBza&?6iTcyV{vhDUW?YOnPq{{8rYm5&*aV4z)SK@r*kg08HvTi3WyC}+wNnH&@zom zV`rby#13PDdDF1)b`Gl@tqpk`tEzFSEW*peqqPGXjS7HF$mY~*hh&Ty7vGeP;I-}1 z+94fvSzz8glnehK$e$u8X_YG50000jbVXQnQ*UN;cVTj60AhJAVr*}3WMp|RV{&KQKGBibQV{c?-a;OG>?f?J)07*qoM6N<$f=+xn*8l(j literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Planes/planeBlue1.png b/examples/quickwings/assets/tappybird/PNG/Planes/planeBlue1.png new file mode 100644 index 0000000000000000000000000000000000000000..ea52a1dc23a183e2c78e152de63f3332a433da9d GIT binary patch literal 3370 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 A0ssI2 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Planes/planeBlue2.png b/examples/quickwings/assets/tappybird/PNG/Planes/planeBlue2.png new file mode 100644 index 0000000000000000000000000000000000000000..566b1f47432f91676d8d1ec891abd7eb76968660 GIT binary patch literal 3337 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 Ts0M%T00000NkvXXu0mjf)Hq%K literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Planes/planeBlue3.png b/examples/quickwings/assets/tappybird/PNG/Planes/planeBlue3.png new file mode 100644 index 0000000000000000000000000000000000000000..7264222c5d88bce24394af95a849fb11a0b992dd GIT binary patch literal 3307 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 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Planes/planeGreen1.png b/examples/quickwings/assets/tappybird/PNG/Planes/planeGreen1.png new file mode 100644 index 0000000000000000000000000000000000000000..ba2949b472cc638076f81d7bdd25f7eff027bf6f GIT binary patch literal 3447 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 ZZewp`Wpbznf9?PP002ovPDHLkV1l?smFfTh literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Planes/planeGreen2.png b/examples/quickwings/assets/tappybird/PNG/Planes/planeGreen2.png new file mode 100644 index 0000000000000000000000000000000000000000..2ae3006374ddef37ad22166bd1dd5cd1145de43c GIT binary patch literal 3414 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 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Planes/planeGreen3.png b/examples/quickwings/assets/tappybird/PNG/Planes/planeGreen3.png new file mode 100644 index 0000000000000000000000000000000000000000..4b22f2982b77e94ae29022179b21304b873fe315 GIT binary patch literal 3384 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 O00007 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Planes/planeRed1.png b/examples/quickwings/assets/tappybird/PNG/Planes/planeRed1.png new file mode 100644 index 0000000000000000000000000000000000000000..c0d1ddb622258ea34c0d9f1cc636faa91a6f1c1a GIT binary patch literal 3400 zcmV-O4Y%@%P)t?O3RIR`G``!D!&gr?`(=*fE(*wgUQ}r#!>7J(h zbI(2ZoOAD;F=N8~Ivo`?wm3REsd&yDCsY&@^R#5n92RLRj){3m_joZnI_=z>Z%!E# z>93-hGiOICP(#4EVMH`wSOaeM^4z(s{=N5D)53+Ub@5`>_Wt`3r<-wc;{F==eU`uT zjsh7*5}DRJXHF_^vXl!qABj){NrB9bBr>g+w?1wV7BSM`l0}z#+{J~r-b#!pxP>t> zak#N-^X836xTLxT3k2Yz*w})I1YG;>yCWJfd~!s(2?BiO?YBn(hua6^CPyk@L_T!o}x!SZ%AhHTBGnv|Uii0&Vrs30}AxRqlaU4!DY%BrsZ z%9^e;e=4u)bmF|W&PU33o1OPn*TvtVWBB`lQf1rVih_&;;1W-5uk$Y5#k;gt9X!=- z;PGLF)XE+|m1VRm;XLto7A;mD7J}6h2td_Bs;qJaeBg>|SDe4b(e?@mf8VOnm>ZDz zC`n<}E#5`?Km3s0Te2jmdU%(rnLl53b4GLb;@H@Je5bpvU3p-DAsBuA&wRj_m$wJK zwiYC=qt`1suiSWT82mnlBxZ%x8U?ErEE|m@S#y#Bca){|!(?r>^?k}`@TbCht2>_> zc^+~TvLD9vw63G+FUORg7v6BnW4*9kD{x6@9Jm$5nuDa5N;3$yjsfKRU||J}OR_ZjYL86^Z(tye2F6hTJgA>!~SI#2eCur^oEW99$X8}0}= z6;)jUdj;GFd@ve9>ke=|xmVoo`B53jLSdJgnVp#F$f?Y9*b&0_}Tm`qQM}%r|UDk`pK=L^aeojq5^vQFfyL1*Tw#sK=f zt@8mJeEci>>E~ZryX&EHzE8~n;nr{ghVI_F>jPrL#x1(wj4Cm4jn6gv`v1~6Ko<94J5Z?O$#wZ#tH(?5J{v{O%SI=Nba7isU)eYCy zIbawtsqAW_kAF1`ST4#SLsK4@!|waw1J=vc!{y>hg<0J;(O~W`|D*!ZQqjaR_%#yE zS}oUp9+#is-*xi8uWh)dmOcRu{=K-QR`_Wnkl{K2?yw^#$uwZ3g=EFZ&fNUQI&7#& zb#a-pVhM!%XtwhCb>6^5TmY^oz`V+jJ9Qe=ebAv!$2qL470oOsuSDql_Z6nB7-5-d zz_Kq!jiJ+~dTP5_z&Bi8z}%v389=3;(R=%efCbAXz>rZ_K?C33y_sW814eo)0NXfG z*grvV0aLhU39y`e=q)(~vGOh3>;gaNsY;#NV_isautdN>>9ljrdhd7nd-}Zoho0G{@(!8 zAV)JF_HRJ+EVw3D(J_JnBeF0Hn5E_?J9-R z-|US~P?8EL5L^HZlx#GA{^je9GOK?(e1PQ@L)zF_Pmkl{1zgk`P#ChisNb8EtN_Ad z6PmI=lYK$>R8p`kPRwd#oK(t{!w1-td}w21Jv~^qOexd=bU3D^I`-_7W{2w(z`3VO zLn^orIbiLE8f+~Q8UrLYrlV{V}>fWJFgFg$=M_BCp~B=}!|CVz}5f})B0AppfnORT(1Uc6Xn z%i53GrcGPfj?ezc4riRO1Q!dkwJUpu3^1*2GYeSuyK*#P)hBmzu%C0F!PXJ4S-YN{ z%fD<2Ft!?K*QN~_V8p%qX3k`ZQ>U_I4%umOo(_JQCN`~nKiL3W($b~NSeb#imz0xx z(Pwq#kPdQ_CQV`xJ;0v0I5wD?8W0FFy+C1{8DV9+*)0aJWFwGe_i*S?_LPVK47uHI z_UhFu_M)na4Wy@wmFOf)G0_%W+9w@~&$YUb1Af_zdyrSS4=Lb@6DRfqaBOU>a`QWP z?qrRPjY4=&pU<5;SGW`LvjNgiC|Cu($Ab0B3S`BwUfO8{_b{A*(*QUsDk|s$P33TL z?vkje0!poA(DaiEuyP||U!cu0@!YSYao4V0>-QXgkpWaxD)IZ9;@BTp!ee)uxzZqK#f^%HIYAXfC?7{p%?i(Z|_%Wx+^IO zE~eq-EwaOwDswANBwq|mj*gBN?f}Ajd`8FLc;k(vKv4-oKRwuT5oz!2*+Txn<>lom zfL$(^-}APo>}1FOn#WG%6e`hzyq{UScX`+V<28Q#_&Bm;KYEFCj9w4h%<%JudcgGt zR;>loKnvLZ&YLk~hPckgP1_Vmuv$$0=*><5I?gGtZ1w&`0)I~p683WCgb5R-z$bGn zb;`nLIA%xOjqH&IR`ifi207|ko42MEV8KYRDId%jQ$ysU?8!y{w|zEwIA6TcvH)h* ztXY=f&gZ_JdV+RL2>g2y-h{)uY5Y{`nE$2MxN+lV1I*;flXVAGBcef<_Xg8H0t!pV z&mBNvo#-59D|S-kViqn2Ub0>^)|k ePDe5{MQ&qnWMy)w27m4V0000r)h08piz({AQ`Kw2HDUqoxEj(HNB^N|g1&u9vL0NTj67nCy~Lx6GPEN>^@P7Gojc z1&M&5C?GeH>&Rt>OAs7gFCj+Ob+gu1s+KQ)KYO0zyoa8qd#1am2Zjn$^%TQQPt)`3 z_dMr4?>UDF6N3CW7Zx_LFg!f2aKQoxR1gs{P_$qH3pEu+L=4h3UI`CRy7=asGbV)k zqhRjb`JoEb5O5wCAq^POfQ!Aha3QOG?>*MAbSZ0IzMQqb|9;5nPE?e*zB+!LrSH5W zAtOjaGkO;+NW?`JbK&Ac5vngq$UI0wGkW>m#|0uH#u{9T=wgpuTz>1V*pPyo9}y9S z3%j{!(U^ows#&r`04|7(%nM1t)$hJLrUAo~L((P)@b$Of9tRw355`4~Rlvx6@Exv1 zMwW*hU?l65MU2&sPG%CJnh#SROn$6R*V?!5WX|262{j)0men0P=B2KJa@JGUAk>(A zdf5B*`@UvPpTrN7ozaVyh|#G1BQV}`($G;YL??XK(7E_|^hQffr?T0-2fqm2X?x5n zs=K5rYr5roz3vxY@A*^r-2wU8y7MKhCcB8;K5|Ojl$IkWnCnmb#Z7J7uxS|B#%0T7 z@xbf6_&f9-{=ToFvTblhK}G@KDj(Y3;!V1PH)*xn`B1lx z=Z9sAyX^6)45Lj6$BDnQY`Ofh5Tceq0IC{Nd4BJUXLRgd7#Z1z&ve$b$uA5r1f!?#`7rRMrEPxC ztpdvpcvcu4D z6<(}{+1&DQSgR=g!=~5Q8SH8q4G648uUfcK1Q|CE8Hb+eIHfNl+FV^vt9#*I+h0nVpv6?eOSlpR^nb5;71cEHtwY((%wWwaqJ(@W2gNx%k_;!p?G z$K~eT^h)z^Ug`CXJ?!|29HF%I>;WzZl$xHEk)EEN1RYH~Gv8Lgc117=*+wHz){V$@ zIN8f4==rtlb!=Ds9+sS%$u8uU`OSYbvx>yA+qQkmmhqc>y|h8|yjM%=Bw&96_>`2a zDC-vC>CFT6;6UWwxy#EYNZ%e#5ulU;JT0k@gYbE+^OoIgW>>G(N);4VvP*fTQWq|k zu#D5W-k{U6t(7dv3z2S(7GUUJ%e`SBwrt&@3C^fuV>b*tXHVZhS!H#rA(dA+*!TJ6 z?BuEQ0x~Sb(y%yKHem{I?o}@kuCD%o;F6l|c;C2I=R?DQNhLSxWh7hjW*Ws|geJc* zhu!nR2dtZ`i_66a6=rqU#0_(Q`4=w`O=S%%m7gQlY}9fc=6U&P{#ghA`|2Cl(9|QK z!QTsus)bJ*feh;a;FR<%^OZFW3n_{*I&14U0?Z@YmJU?WGP>_R6R;4u1Q;@E71Z$^JeW2SR*`xjG{*&mfEfMs`6qfoR2ZoCkR|gy)pn z=|-?!6P1A57k~#Nnr#8BXcbBiwxTP=)e;~@Ype4S>wo$y`|0OjS)1#zjAGr|fR%+J zZJti8)6*%Ub99@`NYtH?un8X30ojAPRand-lv3NlgGVpf!1MnJ;khngWi|oGl{_!T zge8eG0|5MitCs_`Gp*Cgg9G*9VXeYs9;~Izv-#EmqYzHjHMLMF3))C-^B*-wT!H$q z+J8wkwJytmDP6M!SULF6T5<}=!5ECV|C%%eKxq{L`mnN9+&xz~lw&*kECa^SI$*$> zQ%ati1=2XXA>S*i^s)u7bj_jt)gwq4p~v_b^j|Mz!#5Yuu~~#>; zjO)ePwL2!4spJR`wj-|!%C|GYyfU<87jip)^%D2 z-2BO>ta)WLE8VfnUchR|n8)ifIGFgy%9S$05%C20N%ATArJrP97B}Gerp-feIFuKv z8}v+ZgS1)@r1W3dMephucC)fozUJWPwFhCo_w#oQPU2TKKyvgHUSM_ zU#?&81(%?sm7ujizr+pIm)+ez$zw2T8(N3))H2}uLq~!Om>^Sj5lAgrZ(!l&!$;GF zufuWx)lB|-zo<$^b@8tj%0oNT#*9DyUO{xHlX(wBjSjm;_ic+VRsPx&XD1AC( zeka$aIk(4ol{(e$bzp#lB?1OYr_K$Vhd#@n)9bY#Z)L5!66AZ1o$;^zl&fj?9ub*< zS9PP#C*WJ$%Jcv?#H@K;oIjp5h@y~f>nb43!)d{FjMIqN0OPd_`@iu_ zGiBPd^?)|KpwmO7D&Zn($Kuje$L1}T0T(5FVV_N?7qC<;S|s73UNM$exWg{|0UlON z3Kn3IS$O;yQ}JUtdP(qRD}c!&EKM&N_2V8-#qGBSm^wL{`LKTjqG!Q1Sw;I828_(Y zEMSUWOH=%2^W)~FOT{2$tU|t>_MP86SPeL+(W|#47PA{JKhsNiA35$rKJ0}$Ei4rn zsVqV{lG6h`VjEzTg?hm5RY;vLKVP#(40Z9-u2Lxd&F*Jf(wAY1{;l^fBAZ& z%=+Jt9$@8)A$4x7rKhV`3%IB?pfF^2QNKGbUIM~m6PmI=pLtn$D#_m{PRwego{{Cs z(F5!me5i9{Ej@~kmW3LC4#u=p`+-A>+2I-qIQv|2Kn3>^2dv&ugRKRqQ|MLPsE7l& zsCWfy-mmrRqY}`~$~&U6mYY|~im%n0f?HbFIJ$tTjESf*S*aDbV_l!7T#*f*yZ9CbX&;HC(Qcqigiv`*0 zl|3T{nAWzL1+4U4Wj0~elRG)s&pA+k>xegO+{`ZKUNZ$4TMb@U$+G%J95C|ULv!b{ z*qJj~JcsPCI8O&(rio1}pN}^Hm$Y(aG%GQX_mZ-*uXqaSXA`kI3C~N*n}_z^@#nO2 zDJY%Xv}w~AL|@=QR21t^O!Nr^BRyYfoEc$dyV)%Uh-4#>mG*G#Smq4Wdg=FU+6N^oL*nJaG|gh@oxhZ|3bkk=mQp_S1DgnjOeAE zMrwelnqk`j6x0fu2XGPqhlPdt{X#Q2TpYV1EG&s*C;y(q&SvGyY(cr7IV9lHWAfz5 zQ54BK8pJVXwwdAI8)^a9>R8ngOdTy?>m4^|&Kz-`t=o1O z%%jwy6kfx7cI4d{JyOSt77|D&M=fjn&V)QH7zs(Jqw(N3EdyZY&6{T#?qcrk)DqNv z!f*aDY0{+m05g61bj?oHh^W)$ts!rmsCE=PD049j7acD}FK*U2O&!0dP8IpJ(MYC_ z&7;I|l76g$H}L^V50#@yKe;&4#f))+1_wHnRS;-&eoD=rJzMy-kz9QIp+A~T^pl4J ztYh4BZ5UM|?^X)%?a0H8KK>8MePXLPo>3|Q001p?MObuGZ)S9NVRB^vVtFoNY;SL5 vWO*)Qa(QrcZ!T$VVP|D7P)Z)9b1s0M%T00000NkvXXu0mjfL*9w( literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Planes/planeRed3.png b/examples/quickwings/assets/tappybird/PNG/Planes/planeRed3.png new file mode 100644 index 0000000000000000000000000000000000000000..5ca6c703847c2df4b9380cee009f57e858204e81 GIT binary patch literal 3329 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 LNkvXXu0mjfS}TO; literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Planes/planeYellow1.png b/examples/quickwings/assets/tappybird/PNG/Planes/planeYellow1.png new file mode 100644 index 0000000000000000000000000000000000000000..906947da12d94d434136bf2ff44bd9a62c06596a GIT binary patch literal 3502 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 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/Planes/planeYellow2.png b/examples/quickwings/assets/tappybird/PNG/Planes/planeYellow2.png new file mode 100644 index 0000000000000000000000000000000000000000..aedbe37544df97d9ff6b52512495343bd1ac8137 GIT binary patch literal 3468 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 O0000Cn>t}^?2UW(D&)SWh`|2(mfJgzf6 zeRV9~p7P5tTT>*8K3;NLcA5L;o-*bAe?KK3d-Cqd+4^>G>F~)a>c{mr#hf|HXeV^~ zY2>u-O258%mCD;qiZ|!&`Tf9RUb@VA`#(+zPyfBW`#)NtE%8%7dqe+pC5EXEqi8e) zMnni)jc<&YGxuL*qEYlsiG)&MKJvV`Ey0IR-BV8W+gq`@7z*n3e1K%IdSn%!xCK2P4E6w_v6dgn>)-SZ&`f6=d38B3WPuUgcWPI-QQUdqlH={|hd#6Pn;PkLj&r~Y%z3>&FQYeV~4!m@#u zKmNIP?(NYkg5tG|Cd_Nb)VN3Q4O!&U4|^7m%Q^qp)5l_2Nd-aYR5iGAzkwKb^* SY?{CVlEKr}&t;ucLK6TexdQ|M literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/UI/buttonLarge.png b/examples/quickwings/assets/tappybird/PNG/UI/buttonLarge.png new file mode 100644 index 0000000000000000000000000000000000000000..edda3bc3bdad52cf677c7b8466cac0e3ff5f569b GIT binary patch literal 826 zcmeAS@N?(olHy`uVBq!ia0vp^M}XLkgAGVdzGuCIfq|LP)5S5QV$R!}=d)!}WsZOR zZft#1ZT6Cz0p0cnB_Ag=N9++f>U_{%(fwo6!uGh||0_Dh1^s^tcZmlskr2$(UMiSt zz<$!K)3dBBU5?-LOt`?F89o{J)}KCfPR6eNx$T)voey50pKgD0gVU+Mi}NqFd+5*o z^WcRtukf1M4<9F=_gkmZkiRdYZu_}4jLl}xJauosPzk&D|Ha9wU++$D7jv6@&dqD( z{kMLfUuAoLsrt-tCO$T&a`~74x9{F$OQ^4(zV?3o(p7vXE&10^`MN;n`qRHtUX<^? zyyx$^>M2h{P8ToTT>5Fj{QbL5Yz>clzFdAkQ0?!>yY|GV?O@(el00+MoJBL=7~9=x ziMj0a?baRLxt)vVG+#-~`o(){)A38asq_B*VU~P1Mdp8AM9dyOhp*3ri-NaWgj+?c z^Z#09mr(Wa+5L2R36YP-?)daLPCvGP?$>&jiCv%W9P^$RaCmiQ%T9MIb5~3DIrIL`$>y3R$gtb`HbY4@bI`@y^o1pUK^IfA(l{+_f14#9_y1(Jd9|2tjW z>!$Ub$9cNbIn&Bb?!kWzSL^jNb=eC^cR>i{`UTi3OEvL`b zaJxKmey+rXNK>9zG0C=+uykp*?e917eGs3#^s(wU*}L(;Ji*}U>gTe~DWM4fu9SbQ literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/UI/buttonSmall.png b/examples/quickwings/assets/tappybird/PNG/UI/buttonSmall.png new file mode 100644 index 0000000000000000000000000000000000000000..ff1fbaee692a5e7079786f5105e94dee69a49afc GIT binary patch literal 832 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 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/UI/medalGold.png b/examples/quickwings/assets/tappybird/PNG/UI/medalGold.png new file mode 100644 index 0000000000000000000000000000000000000000..9a4159374f45daf654c0e1cdd6b4c93d49a2ab66 GIT binary patch literal 8803 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 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/UI/tapLeft.png b/examples/quickwings/assets/tappybird/PNG/UI/tapLeft.png new file mode 100644 index 0000000000000000000000000000000000000000..336fd1d2e04b042f1fd7c289a07e78370cc0787f GIT binary patch literal 1201 zcmV;i1Wx;jP)2*+=(o@N0$6mU5haCok zVnUm?e*zZ|-etiDD-|tCQ z01ucR8@o;*Fa=!mV!V@zuIoSRwOTgN?LgC)E`15ic0Z-lfv)R?uB4iUUORV=WHjo< zyiP1XJbw;Au+ss2q4tPQPO=lawzb8krg=8Glfp<-K)H@oU+CeulIja}hGVI|Q0F+3 z>I-$pp;CRJ?m1AZS?DKc&iFzdVk^}w^rL|RJ{=kYe4$QgyH9Nv`dKUncq25Xs`M#} zo`IbQFNW@o@mkg@W<&2RDi!{mn&QpUlIyv(!?OI3 zTBsMqRn<|S8-y%#F`G3ax?2pXCqbyBD8$q0mi~A;jpQPwv_r@;?@ms3HHI-39Iw#d zu3ojYFJ`k0rcy@x>FwLLOZlLPjH{|8P1x~rW`Jkk979Rl|#>WLU4L) z>^eOjp|DqQluX8GYn2LGrDC+*rhuJdk(GSjv-z0`>hLx6wouqBI6{_$Bums?lzdC!))9Rk<{Wa!O^HE*K;mLEQBiLAJ) zx-M8pi2y1<2E5@?#t)=DSp{>#uDiRu+PhaM<&RUCHNLZpE43znqyd z+GU$1y<4sF_x<~p8zPNy%7ubu46ln)JK8;=GDKZ0z};l>+prKfq(Fer6@{22QPcIF z*cJ2&jsN`{PpE|29J5vLe+S^#Qt6kEhlXBAp^*C5#s=?2A`A#YL#QN;hO%k+3tj|8(Ru*4uE1DPO+84V|4XC~aow;PeDm4l3 P00000NkvXXu0mjfH&0es literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/UI/tapRight.png b/examples/quickwings/assets/tappybird/PNG/UI/tapRight.png new file mode 100644 index 0000000000000000000000000000000000000000..daec2ca96670f41793f36ea6a77c815fb616a999 GIT binary patch literal 1174 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 A@Bjb+ literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/UI/textGetReady.png b/examples/quickwings/assets/tappybird/PNG/UI/textGetReady.png new file mode 100644 index 0000000000000000000000000000000000000000..ed0d035cc62242c9b9cef9bc572a2d1d2ea18333 GIT binary patch literal 17057 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 LNkvXXu0mjf)3FcJ literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/background.png b/examples/quickwings/assets/tappybird/PNG/background.png new file mode 100644 index 0000000000000000000000000000000000000000..05c6a07e16df266979f70aaecebee0b5c9050fb3 GIT binary patch literal 13024 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 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/groundGrass.png b/examples/quickwings/assets/tappybird/PNG/groundGrass.png new file mode 100644 index 0000000000000000000000000000000000000000..fd3655e8a3790635e96b5856bec424c03eb6567d GIT binary patch literal 6351 zcmbVR^;?u(w4EVk7&@dohHpek=^j!E=`N)QhE9P&98x+YMN$xk?iK_-N_tuKDr zw5(Fj;ro8UuO@yiC(M)tP}^7gin9`&_cNF}>hFRyHi=bs6uA7>7!QswG)&VCyNI?n zV84_FAd_?bLXRfoxV$qm3rm6lu)j;)|7XW=6>5pM0F4SMEIqnGDqO@RB)6S1=+f!@ zm(RoR>63J(G&7P`Z6;TIP}oHanVOCDgT!H%@w3&Y$(A>yGJBovEZ4!KfrQ!@rT{=O z#zpSxj<-u~%dsvTi29qvwyneCoJ4*J7K5XdUmCgGRP6}9>^!<52wrJ^eRadIGfj#I zVf^f|#u|ELVz*8xsGM^Dke36XRQU+SuM}zZ0@QAS6k=PzX}HrC3%QUxPDqZ5DqTU3 zx*!y*MYjdBwkkRBmOnu^l@4&fKcwT?KWpJ&d2Oiti67ed2#)I?JU<|!Zmz%%qM&6{ zd|#}L1}F?q*W#2O+3iIqS%ksqKR1XXjBK&!Nnp{t6-H(Q+^-jL(v3XzWD8Okc8T;8 zf;t~#x?6l#ni{g6vb=6Q3=wp=g@7TcCQZv-o|ayliii6qMC9Sv7q(yqwG~kR_Ftgg zd(W@m>6|~Aez1>&(e3`-CMJ7rGSbV#Q6S;#va!>}SK5S>AmX)ScDz}BJS%#^xwqT+ z=JVSsFg}GI5^;zN^<4>`u0?f3k^oMp6MB$}R6Y);wq@a{T@dh#qPv2^`3fmfd+=fp z4s5QrzNE}JA+O$WQssv_@wqc&{Khg*;tj~z4D4{bd?9=Hx>Z#T26Ng%QEB3SYp>6^ z(}g|*-c^quTrq50jh1ff><@Oyq!-|}TjG0u_gl$hnX0jJYO`C2sFNhCngv5d1Q7`H zAZ3Nd6cA%XnRSNg%DxE+d5Z1Ao4|%RXN+Q9$fomXJOobf2(QC?7ZoM_w{IkM=X7;u zMM=biY@CFuvO9`jq+{F6*pDlM)vc zmwUfy2-y+$vvHb_gaMt$=1UD9O_k>!xZ<>s{VU118y&T!z3Hwy6K2J)SuEmAJJ{qL zrg?f7LM>l8=E=$zn&P4FE-q&+*14|QL9375=$_6v3@hZ#TF9gMtnKCpgaZx?=P%q||Cw}RC3=zG@{@88 zVr{qDr~Ir1$}8xHE?6si)yB@f+HgabXXwz$iaMlqg1aFsZv|mXxsFN}=~uV|8>?dp zdU;TX1vg^}MBm-=QGXzYrg#QpEN9_H-```wG{T+XS8z1b!TRT5p zKW2=Ly>fZ|(H74o%nc-#=(6;gbnrj|JY zjfHKvyPVEvlUG2k?aE%QZxR!OdHL8^mdV;bUV2wWe+uG%phIizn(n*&NtRW-+Lu2mHoZ8i{TF%(&omkt^}jWSDf7-;)YgP}9>6UhVIYfdOWTlAI%h4D z_^Dc339{9Gv12wGztw^@ob>t4{7>v&mJG8-C2v**8vm1dIUn11M0jt-veSzqVx|WY zrjb<{;aX+0F0aTzI?^pHL}%@b7qfsUO0V5p=+B7>-;VMpxZ3XO&`6Q!i`U=y$qRq| zF3)it2$^J9G)}0+X`C|-m3EVOIMZSCDc?xq0=zmK`|>9Eq28iAmBECET!AD_;aT-I zUZ>-Y1A#yhIVzS$OLj~lSm4X7?+(Z%tI74t;r#_>BzO1HEsiqjvLZ!L?46$XI{Gu- z-k|LB26#=4EYR)JXcx323D`Vg(CVxvUtAD%K(Gl$bcpA3 z7P6hx;{UPhIQ*@G4p+@<8$GN0{&%`XH)C0%Y1#5uu%^!ohW;12+d2Zy2RL?0a10fPTco{A11UI*;EbQIXu}03*608L@c{eo0Q^<9 ze(EH|QzWAP+O103X>E`-TX-^|XGKJ^F|1CjS@rsPasjTnbKF#wZqSShdcHs8hr6;0 z+eKPW`gUy}rNFGzp+(53M?E_KhxrEyglQauu02{S+mZUtUC3LQF(PG($R+FkiR{>MQ(Sx>tJbxBu0YNRJ|8C1hFhg8X4cq>-;5CV6KM#`D@G01u^!5E z$luQJDXRXF=0#u9^UJI62;It$|GHUVcI_)?319_|_wCw7jeX~X)eL7ORcHLCEcF8(47Z=Z^p zt`aJ(u>>yE378c(E!sLtypI%JOM(&c)qU5|IAw?UM_C&vpaHe(7Ml;KjN_SKeG8he z<=T_J_(bTlXEdL=uew&w*tbr`8)im%Qlx_G9jVX>@7poT?CTG_pW0HxmRoR4JW~|R zmx}*??2ZG7a&$S!YhHCr7L@kK8~h>a*!rfV+>MRzaWYQlZ8Tvo2FSjF3<3%sW1|D3bIPuWqf|Nb6q9_zn zx|>DN?(cE69et9q1_K(KKI$Id$bAi+CSZ!Thm8&HpQ_kPt=GD$`a4D9~ zZy;OqUc3a6y*A~L?o}_QRjnMvjFjV)WObJBTwez>1QTX$WHg%VbY5AsYNFsI=02m2 zgUE?NF`cwrN};A0_>K4B?d-*u@xowFd-s0z^&a02AgK}v5Y=O50--PRrkl^pv|se* zq|q2ARw`GEKodH5o@u2X5<@C2H9$Jf430r%s z(x5+basJ^fras0NbmT1aTUw}_KfrZH(s62uCLL%%^wP?14Z($C5dWK+vUtmrToo_P z`BIl>l;`-(&;#C;k=1u8H80ijxh`*niItguK7LjDJm#T-F1NF&da40+0+#YWNe+C5 z9S!xgPp7Ze3SelgA8PDJS&Ky*&=OFCysIb29|N$>rOuWE0q}A>av(j0cL5hNQ=mKE zu%;HQ>@@7s*g1~b`U(c|C3L}8F-8XVCizZEk*jNM%7eA%De*LxJONy@E^%BK6+~g$@G{jwFH@ipu7Wo*(cRZ zh2HZ};yP1HN1`@sNE>pV0%fuN?OQc}e8M^7&ELs*D(eU9`nY;w=J6zZk3eocUZM74^&mZ7aT(5M; z4`sW70P*}w9hvmH{f9F*M&Ej8X4q;8N_RW%^CHT0%%9fii0BxLkZQLQbp~iSpW{7P zc5c2OD_EV^m1``H z5ng2TtfqX^+W#Smz8Fve#yHO*%xSoEy-AG>DR<7{X5W(b1L z`l>e~G%+zW53%Zgf5-+`W6BGM%DCW|6IO4L>GxPJeR!9wXm`1*Suy zAWu?a`A5Ws>PZC~mEZi|C~7K42Bwb0a4;vN!dDk=zwxJK0qb4JD5yp;w z{VSoFu)^Rfh@Fipjs~U8OMNikV9VcoY}2b}Gk}JjF6~KVPeB-}AZ)!>;u;)eGpR-w6Bfe#~6C;a2~$r~b&mU-*76a1JMZ$Pd|=IyydgO~sjmpC**OLi#AlGHWf}9)k4n&W=tMHNR+#?_ReE|^a zbGJdm&FRX>k{}`GmylngJBj`A`yWkRelM{!e0fxgKt=tVz>bnu>WwZ&lEv(i<$t|; z*14le%nxlI^I%65kmrk3V4MpDODO%0-)Jbt{oWvhG!%-am2Rtk=vHX^#AKr4pmr?Q zXhjC%YH6S0Uyu~~6`T>tbM)_R#th}@i7haKDf4L2hueMJH$s^;^m=@r51W z!HGS3q6_Vwlh=z>guM_f8mThNo?X^|!w(P-b^{JWWuSLpUJ>Pz{KDqMSc88Kqdw}o zfFroaowY8z8Iq!!{~D2z(@;fPAIC;4oEF!vyI>PJ7bn z+5>utiZLFM7IF)S=XQkESdFm1gw&O4We^%wsZw}?^P&M=s8C`e2Nt>wb2z&%68}N~ zU{Xc5%5d!j9*)IyOd3|bLnT{YHo4`Yd%iZKTl$e|4I zOxWoy$%GSS10D&$6JO>|%dDea=R`Svc$knHxvoemAuPS^11D?5pSu&=E;=ucf9lD8EerVTzeN`w0=jhvzs_2M>2yZi75QxcqnZ4K zVOw#aE{hH_{0B=nTKn|gq?U>mlwu0zPTKS$00qWC{XBth540S{s?CL3V|G*83>@YQejpUQf$4=Afl--D}vRkHw|0*+3Tul*GQpv zsqk)UvFfwC%pU-~8L}V^It`9VQPldIHs0p_=5ijBHfMPlChGuvNe;I8ffBLwl{-?XX}#tu;(yv#tZOjd?<-Cyf*wd zdt3x%%6ZeaO-`Yi{n@2Ek~mQt!`}L8_C$kp7%EZEkM(@B2sO{0Y2HlpG5K<3 z5#)4KPqAYC1Hl~f;s>~(VwDaXg~@s~sep55KjSTBSSr`F;lbk+tIb8r;rHlnO~6P_ zL{*3JTUX+p>8FzWX9xAh=1-HJoQ=@lNMm6IG> z*f|(D&*uOvj93qFR)0nBu6P$T45c?i{VfAG0ksAVPzNpg;?ZW}7|H#4Ju{(Cx-SKV z=3DHC@Zztg;B4BtY(G!ae~I1AkKJ7yI7z~MmuM?R%A{(&K*}U>IZ5#idq@_}kF?ML zVS^IEQcry>x@G-XbPW)u)$<2w5?Tqo92&d^6JcaAiDVBsM)lQUhsa^e1j6Y5lLUe;DA!A1G8ALD9%Mdk)=snRz zPxLOilY9Szdp^9+`EcI-K5Or@*M8S}s|VGf05O9A004#NGYA|2AOz$08l=Sd=N`^s z4FF)Y)P$%Q`e*I`u<%_l^(9{ZyZkf>B{Xk@dD8bN=25uuQ@wAbErCQO@eeUH5QT6s zS4;qrM`9lOep4>(OmB*C+(Wm`^%Vd&>8e&Zk@BAMG->NS{ zUj+h=QH@J`7i@qwI@Oy6#eOL#<0TSh2!2i8DV+Q*u!xiG42<^tfbMFJq8~d4QsZA7 z+t$~zQmdk;Pd8~JAr}>+2l3i?ongDe-}h|{QLHUOu&H)K^igON8(Z9E!&ufcpf$8 zBPlgvX#Ay(QUl3W+`x}!g|{4>1;4)Hh-?UK&1zg!GT5vBa%mP)5BP+oB1m;A z_8Z)_0af3p8kKSklt6@_gcSJBZ$O)f|9|wrf}H{Q+(dpYpB6$%6wt&g_Q@D#2loT~ zLQ;pgd6whx0rJpSRDciw6STGs+~vhoflDk@wVVz`aRJ`Q``B%YOorm3I^2zya&-R% zXEmx7IArMkyy`PFLscrIj270`E@WA42*$0SI(#A$tM}F|tNF9u(ceO}R~5v{LPJAg z!wkg|D3Yv+)DM!xmXj?ASdM|YFkR8ltLnDf?;4Q4k@m8S*|#_rw6N*OA8J_2>ORc? zBH!`O3Er@=A`?srJoF!S$`JO{kZvWdW`sJpwVhJ#V(z7c;tLu&)!i!(cvVQicDrUN z-EFGsrEeEC}2U`4;Rae(oiGYA1AVj(lbo)hXx)XBNu|r-rGRUI*R`yP97= zf2|)08?r546Y|`cMFNLt<*?lMs2f#dLbms)SRWG8%Qfu{2*-r=|5EIq4|B#wG{{A_2_QDVzeJITFLq%IKG{>Jkg z@U@IhM62+itns_R4`${eYJb^uWz`kwkyoex4PEKuh&gbR=(qdb5=6Lc2I=9BClSH) z_{=aBPIeGn9HvqD6x-80Ei2YXs9=R>Bv;Jk%Il2AO#cF`2>SZ2*mw|3N}TE1$`=vT zt4i03qy^$G%uvAcCQ|ys9fbhZOlZMy?1j4Nvx=4zJ!RXDyFO}L9Pb7qy5%`~*s0!t zHTpwUN#19RT@SFI8%MSd630EX{!7yI(QG&d+cOfk@%f!Lpe#>9e0V;0q|CXzLq1hu zK3bLkRN>_LOG-c-sXyh2SG|Nu?r@UoBs|l7yur|Aul5$)5ipdnd&PlyJS-pOmI2H9 ze)$fFluP|C_JeR!x~F77v&_x!y+h84E{C^iO?j93jNIdd({mx9d=^&mhO#A#OojXn zMKe5|jGyn)@%Fy!jaMb#K|j3+e}xp6CO9FY`=Aj;U zDHpx}F$%@14(jD-72XO|A{uaJ!p`L(k+_SRnqaDdopoW9T`>YCdn?nYF`_iDUgz3m z%5pi(njwJ%x4qbOA{N6^V_wif8SEl8az7DV=}k+D0^Y3UEH?j3@7P9pGH)1{l5T^x z!BCI3Un_sbSH;#eQa}}|a6!=oR;rVnS39(W8tS`(a3)oa)CHWc@ljo5eg5om@J>JFhO4HTlx1 z+g;)bLic#)o6AJT`Ka0hjldi{J+?b`YX(mbq;+eS3SgfV9<0pCUne&pNG<1mcY`r? zHH-DegvIdl(G8mqHU*37aFN&1*et=6&Qz4Ai1Oc%i#e(QD!!6hvgav`>i(9**&)6} zp}Q#fqbT}SFJUoM$(1otLIw*2hD~7Q&<=caEGAe zdy~x-v02Abak_ht$d4Yd>?V6wT5wBK2A5|Vl_{#eM_)AURYFR&)mv9s0}G=$kl)N| zH~v1k3`lOfVd!Kj2^~?n1t1h7S#Y(r^WUF*ly-RY1I`U=xj!6lgW|WX~0+*g~EuNK=OfFp=Lqu0NHgidGe!ek1t<8LH z|2BUA3O#*U-}f9Rb^4DGo6UlOQ@fXJTzeXJ%K65%E7%v>U0yOJ>8cN0Dx zjLU*C2Cn5J(3fuTZy33=_++cXPx@Ds2ITyb!~@2wRmrbjp+ay_oJ)kpdp!cJ?S#h# z>-o{_kFw&`nfgf`-hxxAb?FR>+q|z@!zE6>%es008w``C4Z)AmoqQq3w?QzMA+hkK zgBkh9?8eMEt0)y?$?1*=N`Z)1F2cna2%9De-HR-kAI3F6$N)rA2bjxcpA%?vbcp0sdA~~J-ROl4sI9lD483em7 z0r87YTX;!eN3BsL)JhNe7hJVUPX#ovCxg+3yHoFiA~fj8`EK9Zza7c3xqM{M-&Jn= zM^nJ6{+n0w4q1aBCcdJbj1hlI_+m%Cu03$=Q3j+2<^Oy z8T*p%JJr90hlmrONhwi1K(Y5XYpoH^AOVWs2RbO#36mi%{j4ar~j4e)4u4*`%K&fKzxcDH(!$%17ZyXf$!`T+u&4nzv@c-?mk+c)F0 zilh^bsh+KI?UkZvOOwhp*IoOWM(mU_6~MHfmc8oxLk-_sR$5wl?0_~WnS86Dvzv;= zcAM+6|?U0I>TP{S}hQ>T?-C-tX-`2EX@+BEQg8XEG zolc@di)BLOU_-E3WiY_I;*IaLCgZ=F^l#qg&RfFxs?ARXMz^13?ux!_HR>1~J$(D~ z&=85%W=Rvr>LFW(9is4u#pXD)RL-+{;2uLaKr_0Vi-LLF(w|CZOn>iEl=Ed4xw!<( zE9UR0)WSWJFU@bWH=bvE*Wa<5C??X?5u!`|b@uL_HT7pnBB2SH%$z&pLTauz*(}r+ zfa@D`05%m zyD@BFQpTrzXxx2C)$F{L2^*5M%_MH*EixyVmD614bD9;tO1DZKmR-Y!ymMa0$n&=? zKf>za#SPy{ljjkAr2p#W>Nnn*rYO2u?N-cSZtThOi*Vou%v!<1l9%#Y3(yM zf3o9}e+F(H@w@Uu%qIEE3?%2UY>9bB40paY-N|n5TF+H)_q0-)`_U+?XmqwxPNpnG z_Q63M8R~3U^)s^OK~J5}IE3bjVByx`@?g)SejQT3t=8<#Dl@$j9pW?g zB6kKW5Z^IC*Ybg>p3Md1yrY)V>`KZ+zXKKM3{B4nhf7EV|Z00(`Jk zk7*KMaY>$3K@~fQnER|txE1aNI+W-{OSQ12tnbT#cZ}*6lhv@WKK^)zC$Cku2eX_> zEumS~Qlwfe`wNr?ZYP0p!@}=+qkG-$Wz+`UBog+wXNZ-oQ(Yg+=10}^aK={0uSO^o z&iOG`)p8{04)$B?u+9eV*{VQ_D+I8n1Zgni$5T`QHzqjLCexj^kCs+0rq0<=8j0^y z0c~}q07Vnakx)YrUb^fC_eoJ$wm?^!`D1wuhpjLikmrbBR#NkffBppBL7xz2{e5U{ z+S%K36~$4gY~&zcP08iFZA@oP&k?hsqBby{+q{l<~V_^m;&G zKq5A9f$h+v2J-zV(z=0QyzcT33#A`-0WlLCOu-krI3@9S^tWC&rLfxahGVVAhx0kA zg9pB!2ze7U(#q5B{W$M|uR7nC#3k115Y9}jvXZqrf`BvQ?SidR^L`9^wWny0qu;vc ziy|$g>#BpoC%%rI0T013c-?gWndC460F!s>LY_SXu0r*dK zDZDN{_9cHP`I;$gb55hRfjG6 zGDNvqyjS4-Aqb&70OeNbdze?iqpQ7T#t*Os-C_oReQ?E4g*&fqeJ(1kY2Sxhymkhg zJv{_xY}@l6zSdV#Xmt%-mMY`JqpTwXE-#c=FvBaerXIiLK&(g6Lt~E4Sbc*OvQKIW zP2ZP34Lr2VH*A1$vuIt(&DO>#8$1>HBGddZ8HWJbj&yvG`b<13$R$0xVZk#0s}3XG zpoiMLLld5{h7*`;E*M_!SCfjN8FMacQM|i_LB|3e)ecD86^?`n4QpE52>^IK*2l94 zvBLjh$89$LTDk{t;*rmzRBsrwzBxHQUSGDy-;Z&oy+2?Bfe!ncFvV=I7|NG3FoSUN9rr_jH zCT-Rt*8{ zdg+8GsGB@l-9&XDfxEjL^Ee{!SDRnwKe9bDF$$(vy{WHq*tLNB-ckbaQp{c^Ka31N zA}FGK--%}d2&urK*1v$&8L6n?S1eDfbQSx1^v2^EAqU~^yKhy^euHSnD*Kq>@P_<| zK}Ro@OV-dHZ@H_eWAmtnZR%s)vAp6{SqKeLiem1C{H`Bm{+V`N-E=Zq{!bE z`BS5NQFH}%%t6W}4j|wJwHPuK!DO*Sg&%c7C|REVjGw`=SU7&rLESV+ISVT90%o|t z8g5;WPfaREj@aZr-ZbZakjrwFIdoX|QmH5JzN@bURm_{zB#Z+B7bG9%MFWeL*qPM^ zimFvUg^WoWaTX|^PCdHcM?0tKc=@C7=DX|^J;9>|bBr!yO{BGcdKyca!0&vPFRx(v zC5kLi)w@rw7Ss~&Lu0PI&VYqbX4BAp#k5koH}^ziPrg}@^RQsy7bk7yx3WW$T8$5Q zId_IcIC$8_jv^9w7nd;q)X&-UURXJ*C_tG6gSQlHxA0+?D47P zC~}{SYwEiDO<(@daxxc?EzCEqz&7IxDHRTyg#U@drs|5p+UE`@E>XJi;`zi!XT5Z2Bem=3{K5cd2OhoE0V2h3CJs8+k4Q(7U3m@1Ri=+ z1Q1EQ7Po0aX;E&UNo=jd$I6bkO)qHymP0)l2a}YL`vgt1Zl&zpB`1TL=+MWOOfI7+=cxB*BZv-rd{(P4Zc4C7}@E zMS7IF8YxrMvjz_-+w=hW=ik&gIOTA4H-gzEioTGSR4Es+|rDQfT5R!U>wfb-nFZ?AXPz) z3PLsZc;fTDp63sE&JXYF{BX{7&Uw9F=RWs+zvCeWIt;Yjv;Y8rLH8jT3II@n$bB6e zYVvoZ)nN$$;DqXe)s2I)Hs@^pZ(xI|w^y^eDR1%XAw5K)E`t-WC&T}=H-J*dS5Yr1 z9~|kphZzMbu}c;jNGkdXJz42|!J{A^nu3$b&HE0d2_5Hh{v8)kF#S&Kn!r^F8vF(> zu{%oNj$`^VM>}QE%e&k+B0y*lzl!0U-PUqSmWy^Lz~70~SUh()!eQMasHb83gjQcb zyX_NeW7r%%t}oh^L6{x{ zCO2ebQ=r*!{IUeRMW`$%_WcM}X@-v8KA~Hn+DWVV9#v@)RwR{5DPj-1ay#&FbXE1( zn!8ugfD;l&ZlDUBXem)+p-}8{%nVfcZw>U%qxEuzfx3C6jr}TgOs$DxS`wPEs(hq{TgjEzYV0q$pYL>coo^D<;^X3Ge>Mi5D_=$hh9*sM zcYpjif)(@BYNd9Rl%mIV63n(qOXZMq?5Z__0T7|O?!YZnmdC6WN6Y+faEx}Bd2**2 zD#P?#MK!GQvKd;m-^Lf?@9l-Vy{JziG3EYSe`bmx(aXks4a0qj! ztMv>F%U+T{Si(jCq{2xcdXQ|bSNOqB=ImtR=5UgJZ$3(eyq&paUaZY@~SiO0lBkQ102GC33Kd`Js8Wc}C2zJ9!5g znWCjwaX6y7GsY8#**$!_+AF6=h{r%(l_jGd8&!I7)pUs4fx*9bYn28S z^SoTp6+xs~h{}CjopwWy8s$QVr{$cFHODpB9OwPC)Gm*QYj=C>j{6;qOHBZkq_thc zbFTxP`&Q&Ivj!5&a{R?-Od-4e{?3}wQJ$;sn6B~|4Uhksbdzfi+Tl44m9(^MhrtZN z;MQmIGnXcy?|l{@C!tv=Oyaxxyl z-Lb&HKt;=7wf*~^rO3kiqIY9L|KGazf6ehu*2x|@z_mg6A(sZ;}cGR@0QRxSQ z1qA*EAzV-lYT|5(TFt)8ZfjoDEb7a45vV#-C&TBXCxP?I-9Hlfgj#vw6mV)07-avx z_qlkNZbDS3fAp~*ZvXd+pAFgowqPwOhT@aFZ)RF}pAr6~hHV#RfjDg7k{Fz4#Yr*gLudnwifD3JI{ADr7{Zeq)(vp5KUWWq+?S}P6 zYJ6=XPc0jp1_(LFJ;B`2#a!3*Q5#>Q)Hz3vp)q5_mp$t`L+)dz@$8t62GT;Ww@8Ym z8SNlIid+a|#qh7TUzMaMJT!=6*BCm{q5Jbs+B2dua&uLa^wT*w4P>4^+k3Re(Cs|j z+Pmu<0aqI+D@_A_-4&vuEfxvdU#>}1?d(oW*A9P}AC+QXNZDJz|HM$webCaR!qWwP zJzSiQ5WBiHH|bxNmV|^d0lf3p$iue>O3Sl@Y(o==ZNvuGOAUk*0|EoLPXi5sA;(lk z8BtBVE33l}3nbBZMD)#@3u}E`Q~4|awfyJLB>q($_NVj?p|O?4Z!B_@C+=YqyH?q<#aq&sz6-j+Ox56h;ObY7Lddl$D8R_qtK3ACm9kadBDdfnNf z`w_%_J#Wd9#3xdWQa+BkQQ5=$Cgsr5Nr(h7uer(JkM4tAHk>p!cZNSR%-?<&m60_2 zV>$B|nnPNX)=`s-q!KMXy2A+o)Ia~z`)-vjGMclh2=YO_6|xp|*3C4$bGje#@x#Sx ziZxzU2Gh60WrU004Raion9blq<4;@CLFs`>xvU;^j@DvTKg8{F9_*_GUn#(bdanMh zaFGjm`0-2lEclcrCdFpRgVUfASmJVq^Ueu+?0yM1&^;!fyUGb!Gmcs)3ZJ^#)&G2C z)(xI2ND_HzAKuVB&Lh8^!oV^8;q{&Mm$G&GWyiP%4_puVffKNNkw{Zw;yln5ZVz(~p`oh&c`(Ica-v5rq0xs?^h6=CJy~OXV`X6d zg?`iS;(9R1oDxv%Lj}>daJLHHbsMG_h)t!Mig{*bJR0W1i}bCKeS80q69THhqf+R~ zn-d1pISiV&cuYrJCT_Q8d_t(w%j8N5mRuZ8G76#l0X^0_SAY$W;M;%QdmUKxNKak( zacmsELa<;Z^?mTUkPZ^FIc*Oczo%00!{6}y1Z_r8_;i7f$cIu{uWJN<>mnL=V%294 z!wN!Db;VFj2A*%LvIp-UZ~;@`{P3PvSUoFA%E&kiYQW_hQ2Wy?Jj*ATn1&_0m}mYp zy`aDUDyKouYo}$qWxtWxC~1ZXcb#{{Z1JHNvNW!i;=D~4m6jl0A5jAnTSU8i=LVft z1LevC_(SydA%#Z7qb|J}?66edm(CCtkA(LmUl6LTp)$l;6eSFI0(=lp#bA7j2>}xG z|AypsuV~UD^y=^wfV1FR@iWk?fMoAq8x$iJFKRZ!Q2x5CIS$%d{ON$zYS3X>_kzB4_{b<4T_&pQ=$K5rEqPaNY06l|kBbfr48-g%23yvB7wV|x zgXPVk#fAhO)be3lKby|yBOCK;dMvTORD27RPW^oTokV#t?(N@_dCBpKb*S7-SCL+( z8Kcr<({ymV`R{;x#rfNxe(x9`*s4`IC*((cF4w6Y56{%jRSdAu z^ShGmCLVRhUEv811j#y*zwIOo}w@LM4Kc7l|gdv8(?s}9sl?S6c{38Xt@xQw`0;5uN&MsnM z4kXFTmkS@RT5Sp|G5B5f+8$N;s28YAD!$lwr*4*V`dpCe7l%o?BxrKgZal%Hhrv0E zo>!B$m>-s_@PFx0(R9#tLCeLmuy5vCJIj8xX3rxMvS~WR?NbNT!9$-t)F;wP9iLd$ zr1pr=QPINxhM*nj0OX1(s;UubUIIf?qr-EoKBu`2ne}(_ZdGr;UDDD`5aPdD6E7T+jAkiRQv3o3ws_QGtNO^^l_mKeW=XIF+CsgTh; zy{=_tJYX-n>kqjKY5_CGdiPRCEp^SzwXZ>%`P}Lz$8q(I-^+w&d{%z}iE&??Kw+%4 z>G#kE8op^VOAq~kuY}T}+yTGbpD6zziDdc8gw1K_`EcL8L`ZshxDC`)k{!UHVyq5(<|G&6FMG6|{P_gHbC0hNeNUDNs#7^Rcw9eK$zCI-=T&`vUhR3q z-+4ISSTP!!NAk|#Fmy%d02a_OxQIT4v=2hPOV*B?LBjP3eaVs_8eNNz{(&DS?#nr6 zy~%M}mbz<6+mh0ktf3ybHFtiB>C`P8jU=m_mSJgc_-kASFs0M#djqT;ACL?xwzTXR zDKV7ov;AizGJsdy|ZJL^fXS5(?}&M(n(GH zvhBDd~P7^Yk z1HbjJ8Nm27K7S_1e7!zrXQl0?fY?MW);2~r&`F|2<9K8~+?b;KoWkoo>3m~mKj>_u zoNQGTJQwx25;+6?N?tUurqrgq>qAeZX20$!qwBv}%vPWhUtPNx$_pL`isOfewRFa} z&Bc)Tk+t}=ax!kU1h5{pYS>dBYUHmH@Arl14E|j=9TTbM3sT!jmpy%O)#e>`hsg)F zkHpI;YU<@-Zq~D~KTPO;S{n1)BZ{&#q~)!4;alyNw?^X9!)YtmB5v!TBfp8a&d-Yi zk9Ol+6s3!j`3wMdJL{G=@1M$VBvTI&6}bZD3XwhEJ%smOAh82ywl z#H$U(^A5CZfcvIBmSgnC%rr5quTbg`YQUWm`c1EzGsu=7bRq9+Ln7OnXUrd^{@%A&<1eV^gnq(au>Nrf;s5yp*URr_jey8HC*f{Ye649P zsi{jfCF=D*|ccr@${yMW+FWhnwXsjo?2|Ry??6Nw7?@@ zu%j+s^8*?n*YqMg6}M2+pOY!}bIP|0`bRe)a9H)nl|ItWm>SRQY z+JN3f3=2wH4NhP)00cx884-wz=3od~G5;o{N&x0kezt6Tt{fWr5=tX{y2kG4_Ub&} zp33R{`sZ=e2iO;*+fCjGdysDI1qnqdBf5Azz~B_OX3YWV8NXL@gI^FRk3ilUJNX8( zrm7DM&RmfflC&p2u|B=0hA*DkIb7v(p>(;J_=AHcH-`yxV3bR;4?5Z0_kvCJWzU-_M5q z{s)o2E=3+5?!tmj^?F0e(bV@-xN*0tIEQ$n*N4(kDG$)QIf+_f&zW*4-B-)d?SNcM z%9hN7fC9p7!INdoEF^Cw&4hBOLVF@#jzdI5IVp?go>u=+bEoL<8e>|J0 z1E!Ms#eaF*^lWhXX7j;9aOvn9GuwE%itk57;6ASVfgx zE`vC2=XEMQ?_Txd7Dgd2cU-`Wwq15j-5c-*PKHa(=0XeNvGH-*#kt92yi!&Uw_HNQ z1R}FuO3C0oV~1AhZdP5HO+vSP;RW1+#rk3S!q2MavyarYBNtwSjyWOF5t}|f(<@K* zosm8`qar~n4s%-#u({(Z9Z=%H8VkP^L&Fq;_w}O zxU%9vQiO_D@&m>#C6zYXr*7aoSUYpJ2NtrynTCsh^W+n5VDLA|hKl}Mp;rsWj zpL$m1lMpoT+cokOdMa9{I5PK54%#+vv02TQ6eysO`9$HsEw5Noo3M_ni!e`v@2*O| zS))1b^3gy(p2;wNc&WqQiH~H_+`iB#QNpNd6&Dwy{!MH1OG5N%y3LTbL)a=*nq0jc zW)M)y2@?VzK>0uZmb#*9&EbK21eOgu+mnp=GytMD*-Iqn7DrZ(RV9;MQ#Q{Gl7IpO zLRh&krc6d?#foPoMfu_FPOF5`TrPpAkWClnSS_$H`S6b%r1%B6Iex(-S^{2M{fOBz z(sya}V7ku2xOgYy>3@bfvP8R(5z{2VLWpdLmnk literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/groundSnow.png b/examples/quickwings/assets/tappybird/PNG/groundSnow.png new file mode 100644 index 0000000000000000000000000000000000000000..891e3e0763f939658070fcaa0e387c2db296b7ad GIT binary patch literal 6589 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 R)BaEZ^tDa2-fK8T{0~`-6bk?V literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/rockDown.png b/examples/quickwings/assets/tappybird/PNG/rockDown.png new file mode 100644 index 0000000000000000000000000000000000000000..90edad52f8f627671392d1d8e59a2e025728019a GIT binary patch literal 4337 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 U&4m!+?=yh5hQ4|g!Y1th06{@OrvLx| literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/rockGrassDown.png b/examples/quickwings/assets/tappybird/PNG/rockGrassDown.png new file mode 100644 index 0000000000000000000000000000000000000000..d6a18c67253fd7819febdc1fe4caf54231863f02 GIT binary patch literal 5004 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 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/rockIce.png b/examples/quickwings/assets/tappybird/PNG/rockIce.png new file mode 100644 index 0000000000000000000000000000000000000000..7dc1fca262969dcaa2d45a6b77a90e68dd4e1a11 GIT binary patch literal 4850 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 Kb;`7zp8XHPbquBe literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/rockIceDown.png b/examples/quickwings/assets/tappybird/PNG/rockIceDown.png new file mode 100644 index 0000000000000000000000000000000000000000..1ed48580e6aa6fb8c8f47709b9bca5589efaaff0 GIT binary patch literal 4905 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 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/starGold.png b/examples/quickwings/assets/tappybird/PNG/starGold.png new file mode 100644 index 0000000000000000000000000000000000000000..c8663829203656a8110b66d56fd20955a1419d69 GIT binary patch literal 1458 zcmV;j1x@;iP)dm0EuhOHU}Y25{VaXiTDp}-Dbk2yD-}54c=8_GVa_G z$Lh7lV4@esFPt&^a!I=-z)%{bERne}VCAEy?fZIhPR|asz}Q%g&sER+`Rn^U&-*;j zE7$_L5NUlI=mKg$Oeh#U86N)nN!Jxy0QNJ8t|BY%_`0yX}o7FybZ z0Jvt(Qug3m#Ns6YIy$@YdUpZ@b;|oo0;l7N0zt2LC;JZ`2B7Tz=ZNf-`FrjQ$RyEq z5AB`ZxZOHH$nxl?2X`UTdIm&~+pW{y*^RDy5Q~@4mM+_4gj&Kia~9+xwY7Ej9{|xm z5NUg3Gy6S~Lwxp0>vLsUPJ=iNaJcJre2qIv`2E^NZjHnN zWv%#SLO?Lz{zBj-_5}`sTr|Nfbrus@(N4~L9Dwh?`-(f$ zx1IQd3K3oJvMzud_^9Q$P@)G!kF&kO=f~gFVxAaKHggtjdE+ZATXPIm*@0oCNlqrX zH4@|g{kzT~v!J4qTy*uFXv10d6as4UZC>wA{7tR+pKnFiJ@zCm^&@5TUv3DNmrULJ z;P%etUj8LDgZ$Z z)F41|($smb<~T}Jlnf3md#pYRU}rSIpeD)n0bIX!5yMD>YX`FWNJ-(c-eZ87&6wAW znlMO5wNv4-ID)=R#^BO#KL8-BUPbDAO9GawJ_2qZsnooEYD!a~-f&`01F$mI*i za&p|9R08!n)tNsSQ2i(09sLCyfnSmhFX7NQ{qIqqf*FtdKQog(@ZF>0?6Y|O~n9GsRvsNwMrHi z%=OnQydSG>EtUNL;R+16*cev>Qs2Abow%7h(^af7BaN6&`NL|dh(jn*fhrFmJ&`;cxQR6`CB=`l0APLCDYO%?UjHQ}6M7-@9fL+05}3;L3i<4jNAW@<8Fdmcdj zu08mCe(HDcp|-XTH1HMK-y6(X+(sp!U9ks4m@jKt&))qAZVn_)&l&>|GU=&B8ZPgq@lHAavyjl)?-13T$A`cpT*rO&Sxt=F^`TS4iU#+KW2xv+aasU7T M07*qoM6N<$f)4Yzm;e9( literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/PNG/starSilver.png b/examples/quickwings/assets/tappybird/PNG/starSilver.png new file mode 100644 index 0000000000000000000000000000000000000000..3ad059c771be1efb418a2694e18beddcb0da991f GIT binary patch literal 1353 zcmV-P1-AN$P)IGTC#U;L6wJ)N{p`GX^Jbpl9%S408!6?c5Mo(M zc_f6W6$*tv?`l`v1K3}{=9FO}w%@&b_xoLJ-wDpP?Ki-VuIuD-IV{VfUawQH*8z}H zri;bm*M-B`w*4zm19<)VHHkzb=nDaM$K!GO{rmUL+q^@&%|n$+-7N0<#L#& z36PFNB0CF#i$o$-AZ?l^*=!boZ{NP*`#u0CCntEGhhZ4xayfKeM+lLhtj~vot5hm~ z2qCsq02qcruh+wIoM6m&Jf_`lGa8LpSy>4_0N9zV(`)Nm0rBC(2TKU?RtWJH;MJ>F zSeAw7c^n@fGaiqpp3!w(tvkMa`NIDGK0p`P_I6pzPw_Ust|A3uJi)9D0#Qp%bTqI%V4Jq2gm_HRdu92^{QczAeu=J$Xd-}h^!Qt3=g+*f0g zf}T8iLNb|TV`GDOJRUqX91iJryST2)j~_p-4W^{)I!jAS#N%-uJ$e+hH=9ik4i0Fw zS{EP-g+fNmND*LCUjdRMNkn<^HI1wRGqI1Y_QLj?{}%JgH-7d+W)7R$02jYhbx zi{m&927`M83d?ofV7fc`&G1avTT8aWG9Y z_yGtZ(wdaA1_VA|U0p@fZk2LxEnU|GD0QL%Y8tQ&u)Dj9=XpdTkznAWr1rvky{@*I zBj5L{TCrICDumefeV@;tKLfD5yi7D2T?m+Iniz(G<2d12%a=-}GYw#JV%=-CS~Q#I zN3TV=H|$O|F;dE%LZR?Cgc84$GOq?XjJQ+G#o|{f<<6qq zJI9@G!v}&3ew$DqbvhjyjRx>A?hU(hcXt=x_mNUg-PkU?bwZto^T<)|4X3gDkOFHq zn`#T|4u`}1<#AI}QYaMumQq%I-{CybmdR$~#qAY`MD~1_@Sii&%1apHi_O)|9`ma1ca{ZM5EE4 zj=f26J)YI*`~IG;>%nblRzPT)Ml2R18jTW-Mu|isL7(S&xUS1!Fqk?UDqHP#TQ%+7 z2(DBro!PcM)gFeq4D2`#{eC}4OX2>(U_ig$pLd9z8L4yO!cwJ$R4O&q*K9Uvx7)N@ ztqYO8wzh_4S*)$Cv9hufe9%pG72F<>-rwIRlgR+*v(sv|0-$;7bUMM3P&fZXB0(~l z#4rpz&kM4Hl=5b7ooE}Vg^PhRbR?zxB!u{+?wXZK<%JMp6W9VaRT@;O@RGVx%DEM& zD{Cc_!b_FVMSD_4_#~zLbe*cDZQH+0DhQi|${Ldo+qz5T^FP%;dj54?x_m|K00000 LNkvXXu0mjf#)^(@ literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/Spritesheet/planes.png b/examples/quickwings/assets/tappybird/Spritesheet/planes.png new file mode 100644 index 0000000000000000000000000000000000000000..cd944879a694b9e4c3d23e5e9ef04317f169c68a GIT binary patch literal 35745 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 + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/quickwings/assets/tappybird/Spritesheet/sheet.png b/examples/quickwings/assets/tappybird/Spritesheet/sheet.png new file mode 100644 index 0000000000000000000000000000000000000000..2584c66ac07aa49b6919740d804ebd9e991dfcda GIT binary patch literal 252033 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%0A*`> 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 z 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/quickwings/assets/tappybird/Vector/vector.svg b/examples/quickwings/assets/tappybird/Vector/vector.svg new file mode 100644 index 0000000..92800b3 --- /dev/null +++ b/examples/quickwings/assets/tappybird/Vector/vector.svg @@ -0,0 +1,510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/quickwings/assets/tappybird/Vector/vector.swf b/examples/quickwings/assets/tappybird/Vector/vector.swf new file mode 100644 index 0000000000000000000000000000000000000000..49565618dc1fa0ac1767d3210214c2630d10ae0c GIT binary patch literal 48186 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 CSF%U| literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/license.txt b/examples/quickwings/assets/tappybird/license.txt new file mode 100644 index 0000000..b1a5ebe --- /dev/null +++ b/examples/quickwings/assets/tappybird/license.txt @@ -0,0 +1,14 @@ + +############################################################################### + + Tappy Plane by Kenney Vleugels (www.kenney.nl) + + ------------------------------ + + License (CC0) + http://creativecommons.org/publicdomain/zero/1.0/ + + You may use these graphics in personal and commercial projects. + Credit (Kenney or www.kenney.nl) would be nice but is not mandatory. + +############################################################################### \ No newline at end of file diff --git a/examples/quickwings/assets/tappybird/preview.png b/examples/quickwings/assets/tappybird/preview.png new file mode 100644 index 0000000000000000000000000000000000000000..21772c0f99ca76294057af41a44e1ee6ddd63f5d GIT binary patch literal 162877 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
-p@d};146Vwmq=72J_ zu=9Jw_2F?f-O$oSj}xgVc#68~C?K65T>ZzJYcdthrz8b;mBty{5zf*^XA?Fb{B=p@rxgCm z*1wkCUj!1^{X-Qyd zf*5oWC67qDxE5PMV#fsL-8-9ae{hX%v<2xAF+_+WQxE^Z|2R>SbmNnoYc6tJA?`}! z7w=eZF_n1c%(TNDuM-j?*C5NG7He6NP4Eo15s-0q`|u~uccR7=emN)KEH^&9c86|v z8J2nCT64^?pA#4H0Yf({f=;G?^x@T?ezBJ4sp+Hu1UHT?A6@XD635J@#G=Uj)1B>) zKD$Y`+Q54rm!yPf6D-_$8IjR@4ZP`5V9 zb%kdoj)pO^xSRW!BJ8!gy+)g5(YCcU13r@xIF>;R0dtZPIarw8w(6<|bE2*gh5#x` zG4tBelo=wMB8$fft5Xo!U$5_Pt!$)VmUuC!HQu|k3F=4^HWsWST5GCqIE%&Hix(Fh zo_j(7IZ8YxA6O#}HGL(c(;jDPbetdm!^VHo)D!o>!}5x@3>MXT62c?r4v^CFeFs$) zW5YO^&eW5xxqR-@SRxfVuBEEwO69OxO%zJP{`!UTN;+3Eh8B1fSCvQ{^mzFxBYg)LJblF22dC8cyjn<*i3}Sr zb4({dI}v3+T~u`~F3Bd)G(h-jr9ue;%M2<{!27nk-FzZ-(Q21=Zl*-Z#Oc}t%e*MI zP16ek9tbz^?<27SnyPl%ZJ1lqb?J~$NNP+@oEe{ZYrJrF=SC_FG=lPcZxkCy;qbIx ztCa-(#t&gR8m-nS<^ZNKA3AOJWF z7(wD3r@pcC@l5H*&z?bvoa6xK%rK;eaim8v5-=Zj8&Pk3{_*vCyZ73K#k1piEUdA| zd9dGO6pHG7{hwBMSMRPz)tbl)tgJ*2neyO~hL6%dvOI&+%}|kYCe%O|jsl&GY_ ze&@!=*ZZ3J?TZTwg)9j?AqZQhgMIUZcgc&aOjGrq`qQ<&JF8nnwUH4en&ZNg6onv+ zG|v|q5+*WkBdu^0h!EcoDW2y%x3hcj@z%lj&(Fiz9q>Yw4o;P_DIqC`t=^HiTapff z-eL9cKf3YK*}0{$94D~>_RB~26Vx&Ik%aAeKl^;``rQq8?*PaU@*_MtAr027XFGXW zWH8;Lai*<_yR$qV8Bwb=N%7m=Pd~g?@2KCourOc9#MZ@dn1Y0u9~td6dmpdu?x5+a zNpgaGQlLJ`GJ;3;o9$b*&YNeZXHr6J$W8FvW~;ZlzLP>unNv4Y0hPxx>+OD}ujhCU zCx)RAE!+2Y8of|ADM2DRp3sby{pvIGQ#p=~E8&2Cd8iuYYD0J=SB+efoGxY+fro9( zDqLLKHNmsMwm<&j9D7p#Poef8(Z1@GZ zxJc7!wMUV|;w^%pN-51We3I4-gTa0=fFHn4nIg{>@<5QSp#>f#UUS@DyWKMkb8-@N zDg)O<^HBN|waAj!4>pK|baa8>D~9j8zR+FT5U{Gc!r7p zDOSi}W9WvFQIv34#x*XrhL1Bcw+})fv11-iE9fOB8ZeHldB`ycN1h~)S7HE#fEOGO zm0rQk=7UK^snlwl?e!h(3CdBqdVGE4#b5i)ZY@loE!~ zQ~UYX6TeZ|cCYu}-oLgmS;QJR?p+uWyN6ZT_edsoLPxx;cxwOZXEy-wB!-Ip)`l1C z?o}k$Asz~gh3&(LGU&;6r(3yp^S>R|^2O|QDZe;fO3I?|2e_nguv=*yHoFIvhF5El znl8#RCnZj3ghx_r5F8v-el7x#F#(n`!1gRZJlNW2Z5zq=FXh+gc{!D}`n~<@H!FMP z$%*2#=ND$PscD(t*WGxxlDL64Xs0bzPx9=G7tfFv&y?$3r_x{_3PA$(!c)~NE89)g z2!la!b&y5XcF$}yd5|fx!t4F(*Y0YDB@5iBPZ|gdn1M()jztw<1`yVpyPeM7=6-R! zurOZ8XOhKSY7oMN%!E|mFt_%rd(~EFzZ`Wsq9ik-^hmcn$THuL+U=iyd{g2Fa0sgq zkW{DM6debZpL;B|r9mfCl6JSVf9+-!$ZI+=JD#7&rGsIi`&y?DgXwkqZlgsR1`sAz zlumQ-QKdQ4`25B_wcF=NVqlx6$Z|)G>J5fsP$%+JRvL*SWE2I}=YwmCD8}t}082nz zws#K|pi{_ZK=1@v-q`&=U7u$MGzqm@cU*O^48#a!c|AOCiWb6fZ)5L2xo%bxhAGH+ zoINdQG$mZZ47>9zNrSL| z@C7V4nUHy}%lDc=u7o;KvV4~jfV*Zhxj4{z;6w|8VlJlu#Wc-Pp;B3v5BmM>M#J&_ zx~`Wvj==a0|72TMHk}zSuTr5ICZ~=LMr4?^di`9f1l+xk0qA}QK)DYe6K0vEGwY)za_B)04I#cWpKc|hN|7z@tJn>|%Bf zZvn@w-tVU+X>{U-8bdg!hk7LW8#Hc^ExO~F4D0X`Lo=pkD^l{fu1g>NVmt%zxYF3z zmG#wM3dP0?KafwEkMI<~|6h76L#Vy(-L)%gTlZxaNz#rZi!vcA1lIK^mK6lisnl<_ zd(r(4( zM6QN{?9gQFYj%obE-%bnUWjbh1314~uK&uk{8pEFU|WOew5{gtd)4*rQH?n`LU3qV zKP2S@oJ(Gi?8EZyRy$(oktGxzGtc8gf|TS3h%)L5W$58yx!Gt|S6I|km}QS)d=$`@ zP1`n2kX$0oB9;GfjVRzi`^{FP-GN_@6g~zD4|AvxGDkeVD>IyJQ3R>uXj-_n-D27L zI`5P8a5<69fOZ|y^-zVdM2hBxk)`1AMsFZ1AZhgV&FkBH(UDC^`96=jZKqCOCJe{u za-^oVZry9K%;4cTw1M(`DVd6Ub-?Od%}%w`#pZ#*LI5iSHIPoGPSk#KN6nk@NWV+z%?e?T3jWVYhmQAwkTNf|FJZ2T;Xq#}; zwsVQZq$2e!3;6W?%J2ZXf?&Gty=wKfxjF54wKc^5Me(rLQ*|xG{-#kWSJ+g5-wv+r z6Qdx!h#)KXY89>1La}2g%!QOi5eS3XY}8v#@4|(6QQ!qUmJbpct6~KBwz01bloEK8 zF(tvaDwJ!--Nez&8HO^|bZs}C$&xq#h{n0KW3qf`7+dZ3ayDD8)#CCgFfhk3CUUuE zrxV-uVQi8tHw{Cztm#a~9|jx{4mJ=eEvR?`RVsE48oC<`Me0lBGx6DWF=P-Z+g z?DrqwADkpp93Op2@E(ngN-}}(dbUmVx*kJ+u(tQ7&o7%kjmlXg3n1BZ{f_P9KKJBO znlCC6d7_^kae9H#9J1RzHjOmHCX)mXq5=NO`2h)2ef0bIGjuZj0Q6#6#!<<1=zG5F z(5@F**0C5jY$5>WN(&-`Dra*iHI8}Ec#b-P8yYIdeMIACIDrxP(_kd>j4(WvVn93u zz84raI|^)p+tb+FoIoxH&}Z;yqEl`{MwGZP1g1lh_n8yO6rlXSg;9x4Zo z@|g_$r{j5j!x+>Z!~R;*_lv1i@1c5XXb)4=YWZ-vG?rA9ql1C311fLpMpsVTmdPbk zBk|>X9)My%lGf0d44*V~^%FC=b@45jNKWrkfuHgno^YeUcNSjiEnH$p?Gr&Kl#{)1 zNM!v%4<6gH(qrQ@E4S5ym%N3GjD_@xfaRlut#eL)JiFX#weCm7Gt6@{(|0S?1!Rg4 zV{bPM#{`UT! zkzGJ7Re4Dd2PGY&A@IZN!$}cP%_XDP?^8ovq26dLj!*pI-qt%;|GE0sU%|dVso(k2 z>+8V3aR8B^Bp;AjaU|yh!h*$6ah#M4yj+jIeTWKU0mQN#(D4uz@rjN|00!TKilyG; z0T&bq^z;X#YN_8knis}~!c;f}evu@@CcbfNHJ4J}Iyc+0yoTYpxF;1Z_KG88X==UN z>Qo!~M$FL^n!Lmvs|p%ghxvt4Qd}V zR3JGkS5VV>IXrW|EB}Pn2zX(8+=rmU)*&@kX^~o7(H=&bzK_ zm}cC|1oVSeyLEPIrgiVG`T4JU-~MC9)QG1p@UJ6&6T^B552STJoP{+YF4V(+d5ZfF z1Sm~$kNLpkZ-eokKIyyB@AmFkgFvOHL$h3a=l!de<-B%wW=cV}TU>Q6@B%^+7|V6{ z4ytVUmhPpIPbbJ?}Z`WD=ABhCz)<^4UzqFzU(i zFkLX}D6DH#Llgldj+U@|Ka20?dY&N3Zv|m=cpaE-fa2g#1t(pQbd(3}by8#Xmw)Ib z^OWx}KzIvNyUDS3r82TL8z@q}-99@to$7Vhum7~q%OS&MZS~nwUgX7kvpG66 zVGu}yaHri?Cl5R@I45+sFXRsDXs7+~kp={f+wVqt8lh!QX&QXyH^we2{} zE#A)X0YQ=gK5gH}J=CK?ObLd-Q7y2zk7sN`M_-3S%5f(dt3pOjZ77%5)<5{x(%D#( zfd477ytBL0c;OXBl)Drc;RLfF_DSP5BN1*#7B}qx>`YSBnRFVNF<6EoNC($LMQx9; zmQX&}{^gZ_KKSAP0!#u`m?om$!sRPhfA%Lu)PNXS_^|~724AUGi~0N;nT&-4yg43K zVy{-KBsP!7;4RBC+JB!)oatm zv2wLCvZJV~I$kP$cPv}K@{7Z;Lap7@`)JXJ2^l?Yn=j_ww0nqum|=CrtzQt<~#1 z$Ho4FxF6_I+YjQ+IO7@kx5%=YY!>AUxK4bw!q|pPp_DUi=+6ek<*?m5jBN}@t>`47 z*jn%GiyzRXfJsN;KxTb81R=c?AOsu87m-r=UW`rUtNCJP#_=yNRDF9Iekvv0oh`7iz|VHR?^(IUc!nyuEv#O${=SNm6fslEE+2!HwM#(#?6U&|}5Hz$ZR z5-K+5I-zBn`?!A)oOY6+!%&iBQed9Cf}UPaFC?>k*BhJJT7Koq?RVd}^h_q1?Bb>x z)DZvfCtDwhW{8`7!0%}Rm3c88XEK}Rc<#NmwMKw~1SN{fu&DWs!q8_+V`v0hOAh*v+B$_T2yGq(15l^VJV-- zRYI{lie)Vq!Cf@$zZs+N$l!%aPQ-y}A&TSiZOav8j~D1+5g3l9YtOv?;jjNLD>tVm zCTop)TycFAcNWh;%hF_T6o4b6wa_9B)7gSC2v7G=} z6{1Lxq{y{b2*FPmv#pI#N*;9|zz5V`&%jTNbq$UcI8l*Oxe3&>j@;hgE^prKzwu|F zZCNgIy$8eEt1uFlrqY&9Ow6rV-~RZ^Z+Q zOZwi^ZT}R%zs3*_V9l@`!xEAb1Re`#dlWGX=Uot=a_^_t(`#^C!btQS?b5eD>(=CZ zcV4^vtRM)rX4CV1`k_#jFfRH_Q9RFQ5(z;Rcl!N?sxBuI30W>T>Ys9{+Oyw-^Tj!) zV5mMpPVC(&nMPJo>a7-oNzpbqMOI~Itu(A~6gJ zFQ`nBhWm#>|I%x>DjRd{)_9>%u2zvbkVDNGa;a3i(<~>(LP5%eUVyW`N0yA(a)1K* zg1|lAw+;Ryo5?V66Wa;^^(h*tImHOXu)qr_E+-$vZr@YlG%{|@oPx1Skf#PUMkZ|CSM!ZK)OA$T2o?b@|1RM#8B5N=G z;X7Zjy}Nf`oSL4SoYYMdSoH(3jerLN_FeDb9^slNfL?vu22f`N!38*v!ltHf?QA(OoP!g~`wT6J z!)yqIZh*}wuALVTUjEU4-S{E^1%P20&zau*{H!c4Oikxx8MwGY(*mw%;vxHd=y^V> z6NhuDkyYCBScWzu!sR9EXqkj4$bYB z8@0Oj`kSf!wM5_vg6MiUs1~S29B@DktNI*|D2Q{J`gbwo*^(eEW;5A| zaUM7{%XZq0bv9v7pGEZraih5i_0Q$K{6uZzW4Mnjim1yOHk;2R64!TjS=6B+QhCXt z8QTxbORuW)7g!H<_22~g2!3HBG!ZerXJy7Zuly0J+(J^U=R}1G@^E!uwFuQtIR+P@ z`YkL)DT2U|gv77_S2D|RJS)%w4^)(l4pr5de2zJun?pu~OcKV#;=S+xWo7N^xx?M_ zbXZIza*~)&DDg)rg4A87Y3hwyZNsour!V);y&NU8s7?JKWieui$U6V>7iue7xdAGL z6Gn#T>73YSgv#6t#^hqIb-31U^XaT2@*=~AI3VEvX74?N>^iPA!F1O?|ElV}vM2)& z&{GseQlu!gq*ixJEz@c<8#6n*JrTRVb~a*Wf9*zW#PoFR&i?I)?daLqn2!C?MruvV zwOS%2iV__}5}*Mu+Xm=DqKgfh~YQp-{ZZV&S=Z-!+-%JLlvvQoj&} zJqPjLcih>Cb^AeJ2%4PxdPXQFu4+~mr^j}evni7aEO|Zo%>3+vk(YUF!ZazA&OG_0 z@br=Xg{sh;T!F5oY>s_q2-V6T-fMO%OC}@X?_?w+89Rf*nXCn`5NG$pAC*U^uACpL z%;cLb9C)iGXk?jv)vTxUo~8{orp6Su;J7nwJ7g3wT5-Ml;m^r7U9u@|)L0Ki)ysSP zXY_1!;Ywfsu8Vg?1a_&$=uSh$G+?r%i_;v=kHX`P<2ehxK6_L90jsvh^zr6 zx0a<4UJ*0_0 z+4$WMp%h?FrcitI#UqWCbF=3MmZuAq1ud#<5TCvSQPs#*diPWw+e>=}2_`8NbxH1) z4L~duN4WU#3%|;hkZVyR?Wb}86RxPxNa>ta_CEPm;GeHAq%6nqD`|0@2$~Rx@5w@` zY8aXZkZh?J=VHp583@%J*Uk2bd(j@8I6ixB^1>zYo#HbAM1sXzM4x=*d7!5_r2@h! z?>cE@Pxx*pSV1T;2t#p@nqfkem@+pR@W1^J|6g(yl97yLJdpBB#&uIK2&CIpI-eO> z-_s-lKM2eR8#Mvy^aZfkZ^x0{-4t8Uw{8j9Q2!XO8EI`p%M=K#+_)@rxjGE3*b z^sm%R&iCA~vLG}AS^gChKb4Pl3q?^(Gu=@$WGz)M?ivu?9vE*!5F|)Eu`m<qJpB{i?Ek;xlbwjxWxnm!>(wap7gz z69q!AGz@x&)NbMNJE+swsf8CE24fU-iw4FqE}fPtQaRu;zf1m>RaNzyw2+a-cL59i zfXgmMoj+UkKoHq6Lhzu1Zmeg(Xn&e>*2#SDG;CyXvMlurqPDV14@d@SeP4g4K#rHsX zy~YPyMKhd(J1hBc?>x>MI~Z=%YG6$15a4z1^Yyw_GBp$aPDV14k&G>~=##NIor&LC zAxg%*7$~^}$w)>rl97yLB>bI>WF#XQ$w)>r68=s`GLn&uWF#XQ34bRe8OcaSGLn(- zcQTTZjASGu8OgX0W821`%kujH&>1KEHk1sG07Eb!z`J8y0T+IPaFdaYWPJPqIbUB* zj7Lw=x}fY0ALx7vx)27}=B#g_kcB?gDaQ=pZ53@VE})QX7=;>glezUE@;BrFn|u+4 zbx6HU&2X8;04XvV$pU1=iECbpCf}7)4WZ9Dtq4wGe6-qh|7#reTizxj5jF4$rGH=3) z3N2X?b$bX9S<96x9!t5Pr^WhIm>4Gy8h`sBooDBtGXH+8WcQ}LsI<~8<`x1xWT@_F zXP1YM+23+u5d;4Ya0~40Q>pKc_DS50%@A&ai|dXmaF5!5;K9Nj;b!vm^i!$tjFsF7 z_ts+-_ssH$INv+N-C;J+=A<)PXBbJfDYiVKvRWJ7;v8)hD*-~j6wb-m$>gm;RL8K^ zolf#MLQP>Scj*}d7-H1qUBVOdL?N!Kw^k<%<4D(AMDgQSqS~NTGn%WOHDO+ceq(vz z^X>L;iMIq}ZT*?L)ZCkX?{_DDRW2AgVFlprlJJfpa067g;nXtw>E*91xg!LH$;^CU z_?rTi(8eM27oUHqIyjKWB(>RjB}?b}V>4$~K6v94{T4zYyd7y9;nokCue^Bpc5%g8 z4n}9rEPwFE={v&3VfD$vD_?oIUg*gww~4!J=Je7BZ=R*!yj|P}T+Wh6IIh1`Y{OJo z|5m4>awLm!4I^7_Qb@BYz@#BNGDPl8OsW_;v7b}Ch)GQfRt{zJ3QjzCk82-f+>Gi- zG6=(@WW`RJP(m0|s_Xi(V&7}2l;3f8M2>}sis_sJAc|mS{$(|ny?^H68 zm02-TqP8NPnFujJfd<;*A3614PMDZk&X4$BIS3C+>-7#1seKr z8+Gc0CZ~OUWT04|Zyo#T>}XPDY@7495R<4QUd7Y`Naf8weWAD4R8+-s0!~{|>0K`9 z8Onu$W6{Ytq?|xVWHTT6=fu>t{u1fYS76(f%j%|l#-*2j4VM9|OWgT8#O)(J+6uJ1 z+s5Ts6S&4gZ%+y-s^j`RY(`xNu8SKzUBxxDfj&~)9PZBHZmvVvRF%m%P9mmTMXPp6 zniJAQ*a0y~qd-yWk%=SwSSU(JRM}Y}vWmE>(YP&>c&ex&Azf=6aZRIe)kO-B-JYo~ zA8pho?AE~`?1eBBwQ6z_i+o2+DU~tB(BCKx{9<67DOsKK$mXL^=+_X5m9By?YB3_7 zig|$wa_WV!qc^q@r_o~@0bf=T<(9A_#RCp)3>+lAJT&^eq;tp)+xRiBJmNdnD=SN7 z#(JZPv~})lF`pIWXsX5$cCAI1Qc439xP#*T=o*?I*9s1sJJ)m^aqpS}Llp#}(GtLd|am0$0B=uJp$HASDPJGmEdo z4M^X~+T+7#emy>HbG1LfhXcP20fA~SVhvU9kaci1R1va)Gb&&W0mZ|Gs@L*!H^tpy zDwO#evUe6h$;Q)XF%!-Wot+yA`LRXR6;NAE_gzU%=`~*f( zD2$2K^ozk=ua-wmqUh{020_HuE)q1%#RI|0PBb5U$ZaIlKS9ROLRXut9B#NpYlXn! z+Po91`M5y~p*m^~j#fSQ=Z(f6MH}H;7s3+tI3s?DDfOgOLdy2aMUt(~8KcZ+#$B4; z34h=HIV6^V0YZBh`^7+N1!2_-!m5+5;z#Oe|JmRx?bG_i%&~GYJM_^1RQGa>g?;^p zC#O!%F3$>$7(;S!B;B8H)+?K6J~0eWw4?`8JPO>lRZog@f6o%&J#$hp!` z59e#Ub{o`me$}&e@2-kb)P1S5ttszMWJ_WB0S`)%O(Urts|a}tN`anN%pB?+n6;W0 znzdYIdEBukLb`|2EJAL?;(SZwn+c$28oz?5%DHk2v486$5*J7f!b6mn;3qCzNN^Z3 zjF$&TemyXnLnfvt6!=c6V{Id_#vf>H{=_Z8J0I8(B*Ql)bcI^*cABSJnR0f}J>{Q& z&9=XUad@A6IonfXOQLbNH-8KBR}HTGR{u-C^@wX4veP`{wB25K@4|(5<_=BrFJ45y zcd`ELX!EsijGQOgZ-TI*!TRYdD{o$`ssssRJCiB*^gp@6D|uXM&7A(pu}`)2=b@4n zX0!?{*Gk>CKK>9wqd_s*YtcmD7t{>4k^s~79fj5S~X z#;yw_{dGvI8myk0sT{e~!OdnL>FxiNz%7tcbNVBJYw6E(B^TfxfqSC_Fv@j3nEdk4 z_n&=87|*73qcPfSFT8)@+&lA!C;4w(L|?nucV};Ta%d85ufu+fhetPs-$M_6T3O+901a~KiTF!`JyfQd`tY@Gnq>)n+u484m zQHt_wOd|16=s8wI$!_H86c6lZr&Exx9T`|IjLodrcMANjjb$*<6SBd84F%9Ja{WfO z&n*ofYu8Uzm;0KHQP+7mlzw##Wryf{C5s~s1`={Hoq4Ui>q4#&GKO!#8u696$!8D` zT`)g&a%Jh8laD5D~@p|jN_kwsI>tX@>03cf8xDY&edkaM+I)^thA~pi={s# zT=7G0rt}z>ui+99e6%ESKigP`i>|iOvWiTT-5kD~g==NG4%#upqip@RmzG42i; zLfz3d?als?*Lz3u013`vfJGF$x)VtwK8_h0$z4hLSbU}(T^k2MKl)g_4auSp^XRYS z-$oB$*DhaG2)h1rxwYBS;G6a>_i?)AxSgm~UuBG?@W5?D+hzOBLceq!>{64b=(py3XN%Pt;}3 z{%d7LQ1}Fd&X(^8Y`u>*#dwfO|76$hqs4LonuK16EN?Ll6n?M8pQP|Pm3=_*r$K2r zu-h*$F7$EM50Raip2>Is>~F}aj$DQ_)T5pk3d4m*wvwV3AAdZZFD})ZKPL#Xu#U3> z1lKuCz4gW`VXHo&>ySatz>!zpwyRHn{rA6BU1>GJ7Y~=j->)#rs!lNH5tHywPxRzc z=FtnY(+*kfJ`Z`QVV9%p;65R63ybwu7dJOdNP_`^`wQA?baDAxzj()~KKr$=eZ8{W zZh|kb$6W{rh2#bX5!JB+u}-~U1Flhg@`-ez7~x_>{i>4Nr>Kq}=r8~CcR8bbdiq$@ z@&1jUz3Hqx`^|5DdugHN!OuQk7AI2;DO<6_MISRvb}of;#!?uaE)V~rf3J!bO*V_A zk>o%SAP`D!ju;wm*hA#-YNsY&Z>D#NIVL|0Zn4uQh+OG7*kK!kNtNd*9SFc6h6Ob> z5T^T>-&$zae$cAt>(%|XwVSbF1`5KQ{rCaKj2S?h-5=z8epMb?&JCK#PxB)wI;E_+ zc5l4WZu-?xoZsWnc%-=NKnq{|o8`rCM7CgahuVTL+IG<(Z>LlLJhJ=4o^mf2miHWj z$4u#W(YETWF^6Y#ny1RaRR2iBbzW-J|0I&hJ6v;0#skma(gMQTY`bq^>C*77A?Pt0 z+OgM;hB9b)&qN7hxx0yAzeoKmta^DV_uaq$&lfISQ8gvr(af0s?p-DgzXFjmG&H0T z62&QTt5Ji~%T~ZACiadD_Me(wVr?HG6?Sm-xpv>;(&W(S5a{5_6&vI3-CbVAbwh6! zRHqiw-}$@$eDTt(s;=Sg8BNphO9(5&!$XRq#EB$Uy?Xpg<+6*yNL9dajY?wN*_Oba z8r*eV+N->NAa$GHiAD`T3|u=2tp5BL?qnku|S<2?6n6Zs(biJu+_<1)44t0YWdFOxy zY2zwF4#t)^3yd2OIRv*L@)gA+iqq5I$`|`&5Jek-cT6C(F@tR-Y05GJLj4kx`ACX> zkrzi&p8M9+#R1=Y9APgqMdDpQwqHn)7~Qx2Do>o)n`{rNImj&`q?KLV3E5}7@vfOPP*wS3RW~#MF>$!1)m{|Q-+=)bqE;0 zj<5)r>W22P#N``tQ%z6Bgs7?}lR~?=hNcZDwMX~w z?JMM7J@(O*!x_Y=gX>G&X0KEIRbl8_T%lL2oo~Q0nxQ=Ol=+#*qn+9guJ72nhNEE= zXsRX-w1bOKE|bbtoW+m}IZPnmDONaV%!IsF==sN?gKfQ0rf(Q>A6o0kS;n}bD~7Ie z*4ebSY|jtqs?xM2Vi-h58wVB!EdrMaIK{(q07n9)RLqyd?11gJ&eRqzHETJ?-pyqO z|0W%zGD%%kXG=qq#gam_K1vvyM(~|9s9~VrRazxcLezU^=ppSXFucD3z>gN^c@R7q z<&_27cvDuU(#axd%14^EjB%SNEx~_+wh0M|$`yr*g(Z{w6(D|#xgi!B1Q_A0ByR@@ z`jmG~-wN`M0}{lHB?MyxZ7*b2M{0yA_XBep702G4j=cy2&Hzu)j7f|uNL=6= zieflzS@cCuN3~oY_(d-3v;Z%g|MBpF`3&f#Z|Ty**)=+au_Y8YQ(Pe=6qdNoB_u*C z3h8~B%|MNeKN--D;G_m7HJYVx)CVO^D+c`sf*z;g){aRH3vT`jaG|Fesf^G9L(IS> z6})Xqi_N$PHnE^^3gAgSf*mpTccy6*W!8-*C)WS*ggW@W}Pr0Vck+Y z!c{uB?kcXCG6B|HABgYb*T;SM`?DE1SshQE{TG@uJUVt=T)|rigc0sLU0fkRkq36c zU|Ls|$T`tLV4P~2VL7{yYupcpZ6*LqaJ-iofjQx8NbB zGD1yEBoE32!Yhi5AuzXagCI_Q;GKa9(lo_!d?;4yM><#`ycmkfo+*X70mgmcwcWry z8~PtQHg>EYyPfykB4d4wmBO%0X(1wVdhhZTlacWEO@?$y*U>(z>&xDw@U`#$OE5V+ zzB}-7MAA&qF9NFNKb0oa7`ScvsRBL@fF9Z9eh9`K{!kXaRd*j(jZ)j5C&K=cZGR{t z#+M&{-RR5tbdYg$UEG?)HI^NL`<;IYCx^zai+dRZU*Hz;hX9ye+;LapzFBjhRE_cm zTr6;3GkXhOIB;EDD9?9)sGALEulm~Gefx#!p|LUF$9x@b+y8V%nS_GB>61lr9Pk*| z^T9rs@5#Yem-**aqtCJ$0#)EbP9avl`RFh6yZ*#io<4r*M+>&cu!?TMl)`GQLugBO zMn1;%xKk1)RiWB*L4~-Eu*_x=CS$w(LJ;hU0-El+5J!=s5Y>y7MJ6f6i>f-KYSW6b z(l=ZwC`JCO9H; z+KSao*;bm;eBk#7zOc>*V(FAnTEgF3J)c!s_|pp1^hy7#|Mx{+Ew-(B{H{*QlF48U}ZpSMdetnsb#f(kIVs-_E{FnBrnjHv(0RE(GN|< zi%VgzOQg9j?uF98u;Z=b8WHZ>7&tZd3?+)R^r)~%LZ6i(trW?7)uxfvN*F%M=i4_h)Wx-Yo}!_bfkz++>g;LCRl!E$ z6>+{HD`L8s!RIU1P);|vQ(41hpxo=E(#u!cEnV>;N1Nalmd(AJO202;7*VAjfEB1H z;&orqWwBbU`l`Xji%v6`Ia6I(`~$`&5VE6&iR@$Q`%wcD1<2ZAuDA=r8dB6Nx;~?u zb9%O!%7Yug^>_cb5@MjPbf zh-C&jhO4>Sn6H)eBHduT*aD8XbW`2704|gpw5uQ60<}YB@U$*Wef$jQ-z{$R&u1?~ z*LzXud664tTMWi@LXMY*e%L=QG&X}e9MFiETav0JVT-G6N1iMeCH;%@31H{S!{|4@ zKS%ESfl9DYkU_Nh71iGda#KFi(6~6%3I-JdXBDpUFiSx>fP;{vh>|sR!c#si`T+|o zp1a_*FSs_UtbD%Rdip-LB2C68lfT!70@|UHKjwZr`}TLf_SwZ;p~r4ls9)vG?}PtK z%oZi^Pp%V-Vjh)wywDGRD4y@rUJ^2AcOPOIoNmk?8>mk zmFqgwBizDK=i9lrzw>*~EoBQuXASq?$GCmq$4(bF%H+LJ20swb_pjmhOxs_Xa|LeD z@(av2@~M@BrRj5(VOvrZzaFj?Dy5^&x3X`4_p6^>%H##^iqNkGZVCRoF76MVweuAZ z&X>VIiYMdnr-%U7!Tp^%_eBK!rZ`_$7q|!dB(8G<+%A1eO6%S7AgR z92+o1GPT;t2ni_2BUKJZ4mJS)US;`PAsrRx$fOHIkIY2cX_^v+$jYWn(MD-R@br4P zD(9NOfUpVS9Ksb{pEpzUW_nIf`C1kmS*V06sHcIjMdmcHK%~icy;v>R4HYbfV9eqO zLN5r#55`E>lqeuj$V9~Xwu$Cbq73q@T;(x=hwD<+yRA)S6U%jOg&P)Wxkrw4q5quK z1tH>3^Zs#h8DCwvVmZ#2WVput=LsIA6dvy%{Nd06fWr(ussmwLy9ma`^=G$ZSK{iKP%~-=e}#a-OH4KY+y$ z6cEfIlF^6{(mA2mN-tBZA-kLBI^#TVk zEqPCcOc&zH@u-5`tiX^%q`_@2(hnL;6da!j^f0E}h@I|-plSzdlKQyI_1`?uYUDM_UmFDl9`#!E(O zIh|ceWtKD@D~6$EG{jA|g!xIrg|)q;NcW}^$z0{SLJ&~SY%j?k1}C`jsiS-Tr;RbDPV8lPgZ{@7(Ra z>5OF%oE{kZ;qU>bupE8Olrd=WY=Nsa0Jg6)S^BRyZ&{9*q^g2VLx!Wr;j0kJ(6%sS z9Y@G&EQR>DO2C35Unx@F8}Pg==nMM-pkNMneC_09Y*>{A!hK2g!dAjTn6X4J{fK2F1(=Z#^<%}q`R9bL$ z)66((N+F7lNlBQVtcv(~g)U;yjDBELefm}*!NTAUL)x-E6xl6|ii4sEAzfEsXLnyZ zCzD0~@fM`q3ui7upLY7jix7RdIJ*phv8n6^C?*MZoPD0NpYyCNE+oUOK4u)dxX~$y zE)NcUXXIc&!aRM=kVS3H2k%D5#ilTVN>r6Oel9dlLEe!_fmg3qu^5f$ve&WPPZ7&A zLqR?Sy@8CyL&@fM!r%9QFriIO2hYEBV!DuT4)hPZp3fOo^**7P`tH&?51I!$oj}R5 zH3aFhu6hKQ=iTQ$Rv<92T?9ky_~~UUM};|g3u9E`UJgF@((#!>uGxPz?(!;quE$-n zh7etfap&9@JeC)XE^#S|aI+LRw`wlI#NwUuUwHY%m13b)F0J8;H5>-@Yt}sXLZf08 z5MAh=?+ZT530%j68K{T6Sg~`_Uh6HbKn^BVXqzz5B7;BLjuk)YYeb>JU=#7zO!Y7Z z*&Hw_ROQ^^7??)LF^fXbLcqk2xGt95oTf5LM;vYFBj1xPJ%k0J>691*sv2Zzabfrh z3}+OuNTi3*jdm`Dj%D0lK`}2%qK_-l%C6lUIIahDO~J_Z#Jvc3Qcn8gS>bXo{DQ_P zgwNSMyVCidd1*a@bq@d467g}Qx40G2D>4j)!p8D+W9h9{{UOUb$XK7?9EiL--9(S- z0idaY!G9b%WRoyQUpL^adY4n-x0b@afO5-KFh+vO0dzdy55imIO{{Lj*a)^%Fh@XE ziGq5Q`I_+e{r4|Y3~Aj_t95^9L^dY@$kffUZ!cl32X3tOEGXIzdOw=`Da9YuOeS03un3j#WD5%?ePt<>JWo0Fo zO|9Yzt^LREKQlg5DD_?rLKkeZf=O%(ZASbF>)J)^Sf?E?7f(%TBE#+jU`8@Ut9#;YSSk3@3$5#}~fZThoh5(Br6Sn;T8opc5%3Uh6ITg<;oPInr1> zTCePDw+~P{##k}RNW86HrNSyr1F+Ip`u@nlmZD|oD~8Pe(jRyii|13Xvl0O3n@)O! zt3=Kd=1%x~dsyFsp=j$f*&lxXP<>!%GzbKFE4n!l`t>kqL4?=rV7YY!l{B;)gQ-k@ zNKFTU6H=M+Eq+|rqm*r4c6V{V|AoWN{=u;>Zhzp{XwZfTZNOEbl7j8VU^ZgHXxC&tuC76BLK60*GdWFD!@!Sm zh3@V;Ue$*SXQ$K)(@TMj>)Mou6M@@kI*Pk7(n55|^jQK{t5vcHO%S=D?I_V5(K#nI^J7hehfsD#a$onqo z)Z)&FucE}YB~CbDUV0zJHWfLewN$*W0Y+imdjxv1q@saAmC-$-SdR*&T+{w%SKmEETa2wut4;(l=F|mg0xlS1R zgdmv^zA0Ro@G%sA?_@>~0+rU>fk$MgNz-u~ynA8-DG;frln0 z_Qtp}eOnNCNasTXQkl(-@0~)v>M6ZCur4BUAn8FE~80yYK!GH|~lG=hV&|5Y~3sDg3k6MFy^#=3P!%z;Iq+ z=R?r18M_T*#Lt&!?DkZ3;k{;cn6V7lR5e-1C`qL*?K(6ol=bi}6Q0%N@gz4n83})H zqXWXA<)r_wzi$4kdh1)iGr|IAsnW0-lliPsC=U`$!Vpl(H5Ig4^e_Il{*zzZ7%r*! zgOkVK`NKc?)7=yMZQI5eyN=axg%ICtA#6fG)6V>-|I+%`jn+56vWt1P#BB;(vrro7 z;xbKzttS18ziIsQYnH?%?|*ds-9P%1KOLXgYuiqQYcJXC(&g!9tx|I-N95)Qpb*fo z)Bnf++xXY@<~M$OgnCx3(zKhCY18N}_hX0!C}rF*;PhPZAO5oT(FKpw1%tDL$nTo$agqKW*gZY1LGc94z%nzB#JmHf=1rso|GEV4n-g6pPGw<=)g8Dpx6b)2V1 zQt+HAk0gn?PDaAt+su{3LzFpohA#c}@`C^T%Hp|`ADo%klY8PYetP0eA)nHXl#xn- zocikbYcIWF_ZDzERd!u_Wo7xbS6><*+ndd1o7LroTH66iXJ2$PLPnNT%p5%(F8`O6 zdGCd#xw9V~KeKyp{>j7Wsfn|NoGEeB68Dww)qeJd-B(b|R7P0a%PUK-{p#h>@x2*= zTUlPNx0jgFxKdYP)shC`EzCe9Q-8DX3f#Z02;BKAr%#_ay?1|c-za@{@9E*ef}$Em z+5~Ck&G*{J&w0fxN~Oxa?=3Gcy#CtD;}SQwGB>kSZwE+4+l{y2Mu~h69FM~CZdsmT z2;Bt=#f~xN2T4)rd#t71!8A~L+(`>85VnXxT7wh1KJ4i^8il-dKgOaRbg=HJ2iM+h z19nCSg1m7;-pNP?z>j|Zo7?Ju#8Or@gAg=x`t3L0cu&&It z7Avk*U$}U>^1WBWN{wYQ#-IQBpEsM$>FH^~rWm5Mu1(D@o~~1j@S$D(g?#SxrO73m zB7D<=;GC@rjN8Fgr{)&VHduhwkRwlae%yo)SK^w&`ky}an>Sy7^VqRd%T6Bd{nNVg_}M9E zZm~VT1D7-~75#{}ma#NC67pVmQN^e${Y_Gan@+Nq>JMiJ3ug`t1(XGhh1*Q?=Ln12 zY@C@>&o%ZFlw^TEAoh1u#DI@J{yD`+x0YwIqL%kOlI!brJ$gm?+LBd4&89YOo&VtI z?3ptIgZ*I`e(!tVo0^(3OtaCb{QRvqmr=oinvXTi!;j9My)u1i*$yFA&@EtPo$B!? zUQ`9{${bd-{ymRo`g$CXwpVd4Tj$0jS{MET?1ueI9WSxEg-G%e#%Kc^6b^qZX z{^81%D~4fIRu*4=6P#w_X@{j%}EZc?|JE^m(rOGhP+X$mY@7uOUcu~yH%F?O>m#R1~;H26Oep}O>;Ekest2eTjB#h z``OR3xt#d3M!h=t)Hm8%kp=FZkvHO$@T6vPGVYh!)$QteJAyqK8!w^E9z%Cj-Y%+# zs1lhjLbsPsgEOL-Ay4YTK7jl!%X`s~$$}A(QrXXX^{!&z%ifmEEf1FH=e~XZjeisr zuBS4s%6!Xq2OfH%Ja!22kVGUZx6g)&t3xGVE*+wFh& z#nRY8feRqNN9Wr=+)rQlgUKU5QX4hZNHvyb+m1W*$QR0E2O$gYIAASAnu}6G!AVv^ zGLrFN4(Y%P!R;<#xwq$g%|?ssnL(hq+bWbF3L!|0%EGkor4z^6gT~*h$|2`BdPmr- zyB>bV%=b*a|0}_Mh_Q*s4~#$hybRV3*ViT{pph#nHphr z>cUx|@0Hcl`F8Sb$lx62wWdJuP*n3H@ew|7{Cz93bK8xcp*_W+J%M9kMI)-}+b!8g z^Ik?Tb#O=a6o>BvZr`qby(4=9*T$+wl)Hdy<17b-WEmtQ84vV8AiOR9mgS#i8^93Q zcCGQ@HasIC)C>ZWzAQVFzhnK;cVtC2M2N6YJ{X(tfvl8xf0CmN)cDByvW{B)>U6mMNK!D*h#CM z;5$v+*EMWiUy2%Z3Vp{CS7sO{n$wP-9+-zN5Bv?*vY=i{*EpMTNPWJ+oCO-%K!GZP zcr~n)OO-%FYvmwh+cB%%2!sth2;u!9PYeSF@av6#Lpj-o@h{?%5a{d3y2GI0guj!K zjO|Rr(kkNX`FCxdUmXd!?m46ZWL;Uz8Dt@h>?E0{Ks~tTQ{gCFO(>8(GO3oPS{BG= zXHl6Pp461saWhJAZhIviG)!Gz&m^jfFh=Y2I;4@*y3&puB20*~=7i=PD=I>Wcc&$k zpHNtLb}0%8f?#s;Qq`(}bkBX#3#EVGK+WXNC;WXc)GsmnbuLo?Z!3g>%BD!S*O%~< zjQfC!S|t6GZVRlFp@gmZ*)XTFeF~SkCs16|)weh&1S^WdnT+TFC(!JcEXHeLV;^6WNCBP(2!xK zW0f!dE&BnhA>1>+h3e0Crn~pTeF!IqF^FR+Q`xtf}|A{-k?V#ylNwJ_4!)!(asB+nJ(rF z?RL9XueH5)+a&=pv5`iI0HGgjeISys7X>s#cSnH`*HE6tC(@}P$s6(Nl|JZHA)MLs_io@i5ZxB8HZg!KnN#2fKkTe)H+TUDrYw$*#w}*3`;E*fWM?*PXROOiBV}u@s2?i>q;04>pYXo=L$v7u^aVT(`nZ0bsy`{EI^`cX*e;$GJLWz4}AA- zwfo9Bf{e~)9g zg%RIZ9`s!IN^_p)hhY?Bk#JHn9&G*=#ubE(Z1$C*@n*KzC+r)(>AwWPPggFu&KvFa zw;&8|%QRWV9iC`q3cUy^o5$tA&#qkXPQB5#?g$su3cbG^-D4Z+9zheggX;-g_taaK z^^M!beNaVhZFWG1gTrHy&yrrpie5h*_&SrQ`(pf8yklB{IFEpXIH3S`HYqzQ09f6# z6w=nma+{MV3Q@K4;7Cv4Iju(1cBmS|N`(kjx*eW{ z1Qt3gL6F4u6$C_4wRBe3^yPNj;2QI0CWo=^`EEdEopbRnrGdnacf_xctEY0BuCG{|!hNs@hnUsod!aitvQN+? z4Ogo&ty#&Dwaue0WF3Z<|3n-d{pPFA&1((!_`y}W!0J=M`jm!Y7(gEpEJ$1x|ECLm zsT}R|oMyXSYgR3rIV2q_22wO>kqaWci%wCQ*Mvjg!mX7Ya0drUnOsqNbtT>2%-q8W z-NGJ(kO;*@U6@>$cf>R@a^U`@CU4!qMBGwTnI1~v{^8x?{2j;kTnj`cm+!qU3d6v+ ztac`o8y*^VrY>7V$3|)^l_w6MPc_O3+mQ|3m1B8KE+&bKpkJ zej$gM==I)q>#^$M>)9ShAw600u#xOb?J?az(u`XTx_Vt>*F%2kS?wjDEfQbg8^os1R1W?MG#N zZbdh@W+UA&^Sxz3VwbPXv}k}beUOGb)}14})e+`m1R zlsc;NYAU^q2nl`W*f~lcVtjAA{gtWnia!5AUtW7*-~Zq`InKh-oA;3j}TT6 z85=T^CmfP%9gv%>SqqhAFMB$Bbg_27UIfK#^+0XC)-z($u~ePT zX9k+#hi5MTKLmo6g)!Ut47wTa4w$D3v+6l#d2D=KT!~hz5x0A}mSV57itly`S>N+ojcT*iuC-b&P`H_gT1sZA-LWl>2=gq|SSYK!e{>|B z&4)qIYBs{qzguoz$F>A@$+F!^Soz7deQGagS*t+lm6g$#$GKI z^t{Ok-f8|847n5Fx&<#UgP%_ScEumYJI+0MKlz(;jkCGo(SO?aNLACs5+lNlax8!P z!io7SkGswnZ2I+<_1RYA^~Xjo_8MRJX_dp~*(;SJ7b^-uI>CkXL%aJwMXM`4YX3(| z=T3fjNW;%VRN$;6j8Pd;8%;^HQG!Rfv%{l5*}D$cZu>I=clL=0_ZzL&XWNZ89v!~a zYkVzWRR$WTuT-{{wzdA&iW!F`1&G%F&*&BW4r%; z_u)WMb-9trsNFs{ec|}R?30f3c^ZDR+4?kd-foRv%;`^rpv8Fo++6)PmnteohJt&u z0}q!T=b&0P29M61I`P3{I{6HMJpl9}Xz$ecbB?gMJ!W%mbaa=hnayTRNWEx(q3cP3 z_v^$v(q6D>=m#=KSQgb)#VD2r3O%%BHJgn_-C1t6m#CiQS|)17a9eT`39B2{=d#S| zFXi(+WnuCQvato((BSUw(Fz6=7gN}RyGO?-r>9!tNxBz4FbQ%pgC9hBfZYgi9_RYY z6o1)jC;*+`Od%Kp)>kU_m51cENEkYfE&hQBZSCwqQOiN<*lkS6z~Hbud10}+1k$~- zA1GYyX@B?Q+9((77Cu@$`q{&nYXut3CBDNL9KtlC zR!%1K;l79G2gk+&FIsO1pq5&X1n$I>WPujKT@FLQATuqbg)OP zK*o5rUA6s{Y!Tb+)YQT$!e0!7#|f@+@d6NQk?Y(SB{tLCBoG$x3*Y6IWqEX1t@;V6q&|GDCTOty)v`%n@0y<2!Y#neW>8E!Cr!e62e!S z%Wja%6cvk|xI90J*>BTeH^vPnlm>Vs+y{IJ^7dW5d1Y*9&`4!l&AO0xtK=;VCQUar zU5{hXgv1k8R2cYME{LV174un4EkOpp=VD3Ynvu?lpWeW;Evr(mH=Ff<7;+nX(}Gfl zIRsA0R7&MB%}9w!BUsk4CE1|6dXAAT$b}UuAkvxK_^#2(>B|kqQMMGt)w69bsl_4& zR+X?o94!_+4VZX95R&^FgvdmH`LC&pmk@#Cxv+UvUEVUGyIa;4lD9Zer0NDC;!vPa z#V8d&)V5lgY<_TPB)ELpskIo^0;q&UgNiDS6ktUP3+ck)cjaCPd8i;;7v>8luC?fU zt(~a-%bhbt&nQ}tsf0UHI^I|RIS&c35z6|qULlprX!NqCXZJi}r1LZF=9E}yF0Cr5 zJXh)}%p7^^RnV&K(~T$;nIHY-&%^4cfA?!&Us-8q?caL5SLoo2l<}Gq%zMNn{L^EF zY|1=#ac;&XtKTo|C87x2%m!QtG$Xh7Q8SaDZnvg{DdmJ!lI{UYLj~z0M_z^P#y(A# zxQxI13xWHY-}&m-mX}*u`%7!McCZ)_hR6-5G&)~w_%6E&cb~+)Y_}$b0cQslm>D6u z!vo``pM8(=@IbM|qNRJ}<(~%CXTJLNZ!Io13*K{2mJo+40(aRCmwm!9hC6JM3i75@ zY0M7y6?28&Mx#dA8gB`{A&RQ&x-4`RT}vdzG6v!Okwg)TM;qjV6?_`_o+BH@X^Ntz zviVG|Ak1c~-M+0m6xI63WHLD(8EU@xPRAC?3c3em6FU=x^3et`lgW>d!l}zsje5xQ z187^PHbLpiYRvZlyI3p=J5p6tnJ1tS*r{6%Vb^(nm3ur20=I<5g|_euYXI4rB}dM)3B9>+c+farpYkfH&iMhZ)$RNd)Ki98j= z4>6^ljLJa@*qI@0G9X4S9BS@J-{gJdZ;r6qYLsg$r%S^N)UbtBXwwKM5?sWZdbcrdw*ud4*2dp zdxr=6&s_xMRh2xOM0+H|L9g`!|0zb7@XhySRo^-lYZM z7co|chew2B4`bX~_4sUc+C^dH*c4v_*X!L#Z#7Hxm9u?A5w1t$#TVlauET}lGV>Rj zOQ|3I;BP96O>tUssfxR0y1RDgJ>L=%V0dUmN~j38Rj5)RJr?*_MR|S{DHS(5hts6!Z*~eDJF~KB|oQOwMFqg$oygRNaN>5+;YWsTquNzRfFcQUy`>rGG<9i)oC3DGKyTy4Xo87zjz@>}l zsx>YsJZc!f{U}@z5hA>?*az&<(Fr09$|x0quXCeA2-jy3%DjG|U`5qe0y(yhyyNxM zDg6@VE@DiCh9_o-yzHLC!T`(CLrS68+gBQ(G!!bIcvswd%Wb;ir_FtUpki{>5Q;y* zs;mLb`Nzvw+}U-XcJkTXPyQBHHV6;TPoF6ERXJ2WJ6uiV5dvA$ajqvat+*P%Nr%ny zRP$^9E?k}}b1Dl98(CNy=h@;(JDjsysY34Sp1XXa&>P`8VOQEmxCYJ@V_Zex+Tj(RuKxbNr^}ON&XAA|W`vvTIbnzMc2loZ ztNB79lTJ(A{-L3^J#X776={$+nc@md39iR|c>eOqyujrVZZ{=aeC<`ZRyc!l>L35_ z+S0{7S*4qUR1Wrzg}sFtH>kE6ex+V5hm26-(FU@(DM*$F86V3YKl)Py|)7Lh2Z(p~&Rbs9`|7RuRUgp=U@P0>-a{8z9^p z;U2juF2w?uWlhsK_?)uu)6!+IhHD$BDNQP|{9so`NL*bXQ0kBD+tXLb{p!6_Q;s0t zPU{1qVI$OAuk}|K-_8_54{BTvcH>T2^ane$L{Y zn7K|W6bBzySis2bDSl|k!$ADtz#+_2sAniRl`_+XqNd6HKg+VNHIljoEU!L>!1pMl znr0YADsr8LQDpUf&W(w4&lrn>rCjjMr^!E?-m-Un9Svy$Q>LA7y=lh=LRMUB*r(BfLSl7Wl zB+ge@J6^-&$bwM56}TV(?cQL&21`b2E|<#*5fI~wgBOIAQc1IEVIje^G?PL1H!Z;| z1Aah%sa!JpSzP=k-oNc`;zmY7EcRHgr#z08$tzcE@mFS6AP5ry#OKw$!f@4t*Yzq~ z|Kf{lh%gr)4?X7Fz!#kD>yYYz8k%CJ(y3IxkZX|ymezA1E${1Z_j;}?O%y`9bytud zc*01*SnfJU8y4ci;msAn-6~uBYR=$Y&;NC<6{T0%@o-BI76CyJ?KTh;J}M~u^5k-5 zniq%Rwy4z20ajUaCFfVhN5=)RwVI8XvRAiG*6Vg~RfmFbJ4^$ik2!XWYKAyS&vAsN zrkg2(W$zsEuIt)j;>X&2U=@MLbjJUl3rOF>;!7SRfXz@xwx{LMf}Vbur^Hpv?h;0_&v zKv1mhwh`f~RKT5>Vui#vO%o%Hh1X5j5xDIjeE7=cbcB08lUpbc4f@x?J-~p^K-;8; znqWO{s561v5-U!VxbAvfu^2-ihK%y-;sz0JSk2~7Kl%JhX>jNoTr0x$IB*Smum#?N zAnwc|E7R$8yiG3?jR{Xp2qvg@Ka2BO3sVNSG;1&7u31m871 zZ0=bwa1F!^j7*gaOIbJ5W-22T9cgg{o^9KLxmT;9U03EtLXi5NOGqZ(qLAB}o+tiF ziNcp+1tqSzwv89yYU!A5d2n(s+-Y-=%4EhT_9#=A7OOL?xGQqiZhn?)*F!& zF7Wf>gc+^DQParD=J|MZLhKYQ;TX4i4u3Erx@`M&%* z=LXQonVA$tiIOad5=Ggvw4Sjn+cO?(?AdSEpZ{3zjK8tRGh?rJSC+$iX5{sLvzFJg zEhkyDC^3i{0Mu*q&#hdS~+Ee$we%+1O01+C%D>R$0U%$S;8>-IloKq(N zh4=a%LyYn!yEvpsN`(*l$}x)EWbmjh?Z!-tq=Ku^!6e!`OJ3FehZ9=Mj8(uQVJHB} zE{U4H_6@036T&W#tF@MYx-1$@g{t z(S+7|3GNQDHNk=ob{RKzjJu98eP(*?zSsZap{FL>y1FihdxQyLiazS7d*^V0&e!O| z>RIvSRPaedYcb6-PbxvYZ4@R_%laQ}SoPzrOK=a~Zz@YPRYa^~ceNFibp8=YW`atjt<=)bOdpi_WPsAeWoQx?%HptVY(M}%k>d7j4?0pR+V#Dh0*Er#>O z;urS4@iz}Xbs^o74_*F?2sab@Qc2v!KyUD#!cox=(7fS#rLfx#Dz0+6;+_>0!?mWQ z1}+tpv?-{wz=X0CV74T2=J~E20(-ND4TyMeV|*!7f{93O>m*K-{6%Du;$V@U&J1oMPdSt60@?(J_eYnK?)m-Qm>rvYqKELVz^3yx@b zQUc3b)Tr&oOVM%iwkj!SdPQ#!kax9Gy3GOPH=V*Ghm$~}0c*r|?1fQySNf}ZDc{Ij z7Q!NlCwA&mv0h)@!&X(nA-*3PIO}u z5J!Sfh`Tk1H1Itu^7(^gyshP|?`0z#0ja=h)QyCm$}qNwt!cegTfKRVFc&Jud)f;^ zr;%z4f^vCwraWD9iA!{>r4SG~z236$yy!^i)C_ZCMSriBNL9-v-*fL?@}Ad0U1veq z{B_LOddNz1hBoDKnv;&&^pPXxKb*7 z!j(=l6zKjI!V;K!ahdDevSwmLg)8$}gxggZeL8XU#dQw^R%8=K`@&1dJ;e|OT+DQ! zEkDLpuZe532se53rPW(}vka65M)*~5L!o{+D$Lxl$P=qNHg?EW`o9u`B?f zG~j{W%OhUt9^r6qDSB3|CMj~v){WQ#Iv0Hx1$xu^^q7mtBO;b0CD+oPZ*8xYOQmvY zwpOzRnHf1G>({X_jxh6W-JBTcYzJkxR;k2$-uK46z3l7eXpXyyzawXz69k*jotj8y zccxo%z8@D?iF@*3;bKOLNe&eAAab2X;oC8-0zr^aAa+5k12;NDieg;s z#MgUG+?y_T;!~!)ac4beoHgQpBmRy<;pRB?<_M{{0){9_QB@8Guk>V+H=y&~rWm{> z6dri+)zIM@ld|DKU-04ji@*=zk6g!*BnfQyWG3HIE7xk(nc76Hh8Pi-sAPt`*^x8Y z(VEG%R;p#!weJDTyE&TUp5kwi{)8~cdGgfZvzs3)4s#UzC=M>PH z6qdTJU>Zw~io4U!Gngg>6z{7NgE;|u1s3Y&0T+kWyS$1MY{?*bY52|XX-&R*Qb z3XT>^VY$Z&rXt*)wDU>Kj0jiYxL(4t)4pJnYhSNmT2Gxid~Wk&l{s8~z3?l`tzL@D zJR_{O+2JIXTow0b;Ch)Za0e&jnNzIAaRAr4BenYHDSZLC$0f0lAl!6;%QN74D333S zVze30V*Q}$HeWuLVxu^`>+<@qpl)fJ(V{1FIi6_X`95BhC~?JOf)r4-oRLUXsuiA0 zg`3Z}Ihy>v90$YLw=HB?`RAB0AneocbHDe^{lA8Xk%#$k|HPx z0f(JpDyJ$b&$GiYj2a0d*KxyuZ^&G?P_c`Ixw^B$ZWF&GX$Dmk{jO zPRS!bIx>vWd6VcoCG@^2rpN?lTeXJu)+F!cZ@z=pWt!Efu$U;!_XdoeHFVLVZTyJp zMfaM|w>g?)nesPJ-om5Z1BIb2-InRmkV!Hzy(w74`DA~^o(!lPSFr*H9Xmmfy%l16 z44Hq|)6>6t&HAVgNr(vn9`$(|#*%S)nbVQ(!HLydy3H6@0^CWU;zhVfPz+)0I6d}u zh%LbV+upu`)vMRX<&^=~b!?wEA;3|`&!yp#k?#J9l^c7i6$gZsEMmZgv&kp>%2pw& zC&i6_LWHvigL4Nds+~gCH+%aBSFc_dSBgZKc#duR;e?O?REd{XxxXqY-rP>u&2bw> zw3$ME&%N|vE`GA}T;5d9nxi?EHGg9wxR(CH*L-^-c=VZ0ms-_gwN@QVrF5-T6u}$~ zFry4C(efmH>1*EEcWEFTCDP$UBJmTS`_iT@4}c{~fWK|C?1a1`*b=RNNw90$3;)e? zCWA*lF^6l8rINaO5$*(i5pWOEP&h)QLy1K4bD#gx#*Nz@C&sl#Et(#_P%X_CosePi z>L)-%!8Wz$|BGu*0B)D-T9snOG-nLM$hTrq!n`^%Wr~i*PlnI`zE_%HUT}y=2b0MZ z;BMHk&2=4uv1wUlkIGoMuKp!_PrBLjpgHcS=5^iPmgcx*6*rZdCVwxJ(_5hCX=P<$*FR!NY#B8iZY(5QHhXi$R}P*nx#%22*VjC zV{Jb-dicP>V;vjw-7BSm)yMMf2~kqvdNo}s`jY0_e=mzcX{Z{>RgZk=?Azb@{ona&=!e8; z(Rx2WGHi^TeLbBW&g8vxzTjKz$eT$~6?8-W*T3}TmtJ~l_wL<=!swp2UmqG;Gd4MM zy2^Bsh*(e*Whup%Sr}-E6vy59ov;4R?*XouXw`eaFmhfSIkO|i&E&^DO8{J{j{C1) zeDTG-d-se3?ylEYuN)ekoIPDdlt>n1R>)h3T+^#d!$41_Rz3XG*TqtPVP<0D$C{bU;gr!|KT70;qc)@<6|RxckLJ)Sap74 zX4t{J{n?VOlbGpCp;V<})1qmP=D4dzz?u<#P5xdEBP!uEu>Hf5YE-92i6plVZOOE^ zdv+iQpP8AOo}R1{VxHZ?-mLLP18!HnHP8L7!M5xYc5eR3yvK> zK6c^UwB-v#!qz$x%e1$;9QWC=k!f_HibeCxzCAO? zPqntUxvu-d3opR+0`AOo;h%oEW8>oqpU44{$@RMyT^=piTm{Y19C!D?0=pp>di+Oh z?(5zgJOJ_@j*VH4`C~Nju_*OzdLj%w%u8)!-?1X~GGHtz2pNX7Twm+x;gfc?WTf+8 zd25=E5i1vGTDN|(sMrWbe4eXho1T3FB){&=_}M^AmA9giCP+tmg+>#*Ut_ zYh@#qYy;KC;^^TflzH?*S*v-xF=4g(aF%Vn85-4h3%eVFy^jl!)qKXU% zg)U;j9o)QTydxsm8#1H5Adq|Tv9M5-G@pw1>a<&y7lsh!B``x?Q7md<*?1ZVc~Lb8 zC)b%9dh#S% zI$DN4@Z5IP_K>~ zxIG&lRT7!=2VSe=Zdo_D^(o#gdjalEzg{?aFW~Cw;dfu-^U*zR}&*GnMZ0Rl(;A8^_z|M4SOs9Z(j% z;N8wqC{QnMO~iF^O+`sVA8L24$+sr8Jkzp>>y)=|En^f|G(GOE-PK3Vwq(7UU7RexQLHF4@}QOI$B9m+COM1W zZW9Vr4ibt6FL?C+J)e=A5r+<3$o)8{uoQshJ@V#2ZTITFtfFbI7sU58YHJ5(DzJGF z^Ecnj;%|Da-k0an2h;c;yPP%16#~=t2*$}&ddQx%#^0z8ehOom@6p^w3fFMuu=#QL z-k}T!?4FIF0X=KjS%2DoOhosfo{hfrTVHRg-_3FNh+2^fqI&-2HNx?geH{y3=oiV- z`r9aOP0lVAqiE4j^CJxFVmd0eEi}q;6M`jP6qlFub6l@fDiy6@Qs^uxJuEXw6I}ue zF?DaxJ|YuUAq=GHL(C}&NPNFyA1;*0EIUNiEP_k8ufi!1rdX23cJ6{TuA zrtPxJ&kmvC^m;${2owMjqjXY}2|9bBa722@?RkO(_U+w~;oWy#YJ^O@x1TUDw}Q=k zGC@uhnxi@H9#I=2Q67DJRd8%@pd(;7YBzpq|7muyHN+OZ8%7R{$chpgR#a?P#j;gc z(D8>B6iH>MH_WlUA#}Z{!JO4_*cVtyxhb+rA z%ds3!SbE{*8-qnCpsZ@T*_1KR)ml5d=hS32Y+c7G{Px{>9sr`^YE!N>`TLd(kj}A) zUGjvCN&$0UDQe>0d+Z$&1&_VcZ|z$(*nx;dgRsHTtZscr)qfZZV~6GN$*pIVbuuD3k2~@}}W6j*sy*+I|3?NCe4~6Ng7%oay>F zO?TtKx#y$vn5e?UP|yEhH9OMZ-yzB>nBAuB!K}Fr>k00;=hKR5XA=5Qcgh@lYgEfI zqvbYlgf~Z%zi*LqhY^|Zm9*q$oOSCdkI zr-rBC2se;1z;O+^b)YSI{kXH!v(x9NK%>7wTwQJ*Y)fX6x_X_sQ?t{ol8#c?#1Ih-RWc^;{{>0YP)`Lv&g1q zaq7zDTQ^JPLnALw0EgsPW8b`MZNaF-O5~oJD~^U@=0?7a0+$7q&Z`*)9=LE|*^8j2)WTZFhZ;r%p60GBw9t%HO;sI6>L2T;D)%Qcnlp3CYI~fEH?=0&9xL` z*KsA zlXh2IH_RnahD;moXNYg36Dvwzty?x?rujPiCRNlGRY znxU0=!Y{j~D|!(wi*fbK;_}GjtK%jTs-YoNx&d4)5k0LNng$maoV=Y%>*!1CTbY{3&6aCnI8WY`GEJ3KRf;(gZVV8c@84EI96v-} z@CD5AkorOBc)sXhU~yH|S`&$!?+#eCncAVk*n2gxMc^&rmq_7J!g^31)T^z1X-PG} zKy;m$yhD6bJ5B(GKzYB#1-NX7Tj7~hW&`{%_R2WSK;RM{7ac5PLmad=5y)GaK4{n@ z@EpXTiWyZ%C}JcdDicA%OqK*u4i%Bt>EV@CFqYIj=qmwbrgi(sJIZwwVA6^roE@@V z&v5{pRxKx!)cZQp{>1Au))7z4x^j!7Ux3YU_}yv$Q2{olc4RMXS=f( zJN~bs=TTWAs+I@Z0WlB9~uP_0afwnE91W9cRWBsd--n4B0{k! z751&N_jG1exVtJ$0t`eg32{z8nhPg~?+fldi}XJrZ|`<0e9^Kegh(Q<&Zfwc$8*h* z=Y=)X)-`o)weMRMnVLy!OgE)gOKP#j6qVD0oIq-lPqfenDfxbK9C#XJ0K!C& zai~inLQM<*+Wt0J15QBffOmaSM0UqLQ+JxbK?G}(Y{-hPfm%#M>X^1ua{@akjuk!6 zPv+Atsl+24ZBC^IeB0mNdVF~7!fY8PFjz6Gy4y3^^yo~{FmzKur%FYjx~b8L>U0I+ ztJAtggPc*7t@-M;7Cb%oG!bUK51V92ZTFPFAO@SHq2# zu9{LsRZ=u{?s_e!<_5N39GwNVL(eCBa+xPOI;P51f^bh;{@B@(v2r!W9qQ>!q!Z)C za>_6&2yt8txD(gFy{gxdZw+$4^L&Sfxw_xHLI{vetZje*y0HT9|<{OQ`-TBz`NCZ1aR_J-3m`_k!9)p>%+_sIv?R7c*|0#f`v*Z z-d$twT-B4~3LjmN!V$lUs5?@Vqfkc{C3-}8gTUOLAKX@NO;mb6cHr@#OoC-ubR1vc zwm4{>OyavRMAzkX(tro;`@Ut3Iriyljnz=5DkR~{l{12tr+N!j(y%HK4Q`;CFOYXu z3%7UHat28oGDyy5gPv<@Jn(=@mQ%69JtKO_6(xL!Z`qyXZys_b;r#lFr1vaq z|Gp!lOJQ+@ULcA%${vawR*R_(aB&@X5Ul40?uFse@d&p(UYaeGO0CIFt+})$2i$2Q zymw(@=b1Wg)-WPm)+R~Qmif-UBhnl$5wDnxODQEX>0dw4KhSqE?%7du#^ksYC9m7u z*4mnsBpP*JIX*VI3vh|3OC*;}cD3ZHl(lQhc)7H1&mlSB-AzOPYPeU{CYj*XP~dWz zO+DgO>*kDC0*MgqyjFDLgDv9)w3yvaQ+@bWL4z;}*wc>-&M{2@VP3J@SS)h$_BC zPC3$uv_oVeKhIs9Y5R7RmwX!(61dO6C9Gm)lG?idJU;*CdANj*hcWepW!1g~;Sei$ z>gYga$Ex0}AZlR{TzY>(UfdMEal#Ix0;hED`|a28&|IZ~ICu@dtBM3_M085X^>~OQ z;k}EASdXQ^iDWXJNp~>nd#>wDdhT#75X)t?JgZnj!dF{-wT)_dK~k3*(jJ~DBIK9Vy)!Qy(-wFG?>GLAW?H&617y~kZ3%*?JRw3!BbiC1 z!MZ(p^i*xOCNaTuy-CaJFj6u>Zpg4=^mcYggx9bxnjmNVOg>{HcBU{clr7itMMV@O zDU9q&nR$pYpU6>D3f54`IqqP8Yc{_KH_dTR&EeJn*W|b%;06Lw^g1r%xE|oOZqXE(0Q%i%wYpAE0B#LLwxsrU zc8XlUvzcnm3p_YUOJHY4$KX7GS&4Kt+^euAd^}ZrS1%nEWlbVX5<*pmxrtO9f_9-Q zGJ!jXsYnPg$C1h6i11NP;h__oh40g$%8hKE&`en1G2a#fS9K>;yP$iM8Oh12LNd+c zy0L6jEI%@m@I~{dULfrvt0Izxnj$4Mh3D3Vv}VDqVRu$I#jbU}dmYmG`mBpex6Vh( zH{K<4mrMob`&77%)$S2SE_b90nUub^uLTXic~(Gv=OY9teA(1{r&vKV$5)hoxV}ph zB+U;3fu~Y(1s&KB{)I6uGNG;+&ei0ZD{Ftp5;ox8f}IW8XXIR=b$=3xDFVS8K@bKZ z_YK%C=+Ow)pe%_Zk+h_e$dGIpw7YH?SiWDWc;nS79v8M3rA=5^YAaH>OPUn4r=?JC zDOq3uG?UJkDz`9^Ri&jjUk2O3r$j(^(geSg_BZ2Qdbq9$3(xoc#%hv8sjsJ3RaDcm zKx#W-h!hp6vMdO@cD;eCwRMUrL}6e1UVD)iANa(xpP!nVNKKD#&r5z*ge6Eh`h?*t@-YYLZ4~uz2t|cl8 z#&*B*opAQyXFl_ViNbicH2Gk=8b&6?tnEz&B1P9>gYzO40_)E!gV{ugB+eSReuofn zYNX~+rg0ON33{5W7c2hw%aiP5VX}vByom~EQqe_)^=K?!aV&245Jvt=c3E4ES0Et@ zS2o-lvnG*KGJ=_8FqQBo(<)6HN+J)pNCx#QWUB3jUe%%O^4qYnAOtkMJ5Av{E+83`_qr|}$y%jmbF!xM6#(Lb01NLQS{_ZP_~tcZRm;^BP`i1| zAWU6DSK^BOeE%Zyq{ksLQ7nbv2h?_aQN;X_d8Okq@3)fgA6 zde6Y1>$>pym4ho`_5=~GS(-U8QXF;h_12z11PptH3B2`T7&4!S^w9v+%19LQ)=AL- zJ2;a}u5YR0!b?`U57c~{N+H&`3s6n~AM=SU8$4nN409#TXE~Ocl#J5}=DKilPRI5P zHcw)EHpz-vR!Xtiq$V3#UDq@48IW5JSRNh)D>`CjG?ztl8TSE59T0RWiNxFnpLbk- z1*#;0niP{drOP_B7G3q#a$uTxFFeH^>7qRR&goThCm>r3~(VCwPC95;1yl}QGx z7W!v@xV}@xie9Q%Fk#}xH0YAei{1zEdy==KEDLqFwl(8{;$7N8oN-PnF8BX=eR?emNq*G ztV(%wY#h!%nM`urj_zL5o*1(=2`PwHnC!AS%dvjF*4StPPV(Bgpok<>KmDKnXlCSm zZDtZywVuwj4yee#?lLLd#d(C!48m0mgdiiG>TjoobUx^`%)P2Kup_`s6gNdmcR>ugMR7>GLScw zj8IIVC}c@GS>y}2wygx80W+m$y73+qm|yTC z2sK@m;;g*bW!;oG?`On&;qdTMhBh?Vg)baGcVY%h`jWaa@@IhEkpzRX)mrBz#TA=stRj>hq3Y5i!Rk!WBnwEJ|o0E zbuf}d6v&Ks+G+-%-Dl&D#-C$un3blB)mk-WB+vqrbYX33Ug!X3a}XFtV*L|Oa&MAt zBMhdaOe7qbj!-QVLKH=T?_sp%MTo4cYJ!xIa5?iU!Yxjhu7n#)|9RX*V*RQQ(u;9z zRILyZaAjb)7#9;+Q`AnWv~kVKmUQYz2i`kxgC*JsSOStkrKw`IubR@Yi5tT8u6^tY z8a@%@ijs^ZjH?!^lth9RRgI6paj}$58p#=FD~B3hEi7?!)^`KIgnQ3ImJ4lKDu z6arHMOu1?$bVX0)F+p?uinzlgO2dm@MD!m8Ds!_v3^8IrP3pVzrrEiL@*d^(bWe20ieUsI)rTJ@NA9c0n~# z#ft6ucO`i@DBSf!n6hzTBiuC0iSpU5s=PLo+bE&}))Dh@fSSFin*4p+)lceK?##@r z>$rxlr;;gNp#|}OK*sSDrU+@2s*GW9qqf1o~AWF`l~uFn7FRx&Q8y|iEHD+$;0*1#keiLuVA7X$yBNa@6TN? zRW!|zaM>}r8%{AOk8WP7Hog?`$8`lNR7|(Q=-f0XJXo3s%i{POZ>}kdYHUD9hea9> zB%*Ud2ZKO&gV1vv&*Q4c+$JTu;k`*7uw5@2kD`zz=6YboJ0cNXpXd1FCVRhcXD>WU zKL{!{J87tiO#Y%qFL9fgI6F3eQ4cLdg2;ryRM_hWGnFHS!r>WtplYn3scxjE(e<_) z=lT9RwTj(SuWoD$wPdU_9&#j8jGNJU33r0anv> z9ms|H{$;I$2-oGfU{$oFwmq~Zm(B#-)6OF^!#P|nA{cmAr?k2lSB-FqC@B}=8U}YS zyKZ>7omY-qbI%<;2dgyQn%)Yysq|%W<9dnOVq93Ta4XC(6lDdY`H(KkKyT0t6n>yT z+mcPbd2*uQ3F6I`YYT5=J%Ke8=39isq#gyq#pI2nigoep$h8mxpZY-<1T@;{n~TVL z9})--B#AhoMI~H#;4ZZ+uxEH}9#9gZ(`l~po2G4pU05|8MHcJDj-sHusIm~>dBOE! zUXAXnY_3)bmL;h@pXtc6a{2sp_2gKky`&9>*&(Lom!6Quh%DH%E#u$cnD>)F-ZjUK z_q^|gdn;Vsnb920u^jn3R^gqpO+#iE&36Rh;m5Y+(`n!LK^)86xIeTFm1Z{s{^JQ>-jw?jh z+rWkQ)sTU{GK+CqK)R}#7B|6JlnDk>vUA&(&4UAZ79KwTQo#;*lKZWGbeDAArrd!~ zg$3~)u}eIzvJ$7gB7|;Qo!6)Wh9rsn$ROcGF`2}s<#~S46oj{eX1plEzhNn|MKj@| zFq67k7y6;+g^r75csiL}HYapdily4F(XnGi(oT77#F8jH6vTuxyeU;mrgA{uw&UZb zcGetC{=VY_^Lz+i&~*C3)PCjA*6o{!Mm*WFYv;sbmGj!0epDN_RR@B5prA<3Y1@O z5R@cd8x`(?$S9n>9{@Rl(a&oi2a;H;RgtC#jx9EDDb?~VSU0>%QIQE|cP7JUz7^+u zowTSAcVvsE_@96?WI+Vc8z z&Ah^Xa2@w_;h3sz*sxAjluL2(5^(iuSv70i40LSj*eH?AwC42bVe<+BRB`=Oz*RJL zJ>bfUY1`f$E{&Y(9Jg4$1lJQJ8OaLM3=#x-t&S@=wr`t)kxaJ$?gevs1a95ZG@dBJ zoK;OnS7m`m^U)}Lmo~}!7Q4)Dg!toqaZt93m5^YhDrzESq!3%E69|h^;pcOl<_>}@ zHOF$BmUnYB$1>w@zCH<}J{>(hl1S)7L#u$yxK#=krclpMqzihDEOy@^8b{fPDlnbm zSU74Z6!?KBQ`ykPs~Tl>+*2b)LSMb=#&9)DK(cKiFw=Rx%+L!2z$I731qu)SaO5Q5 z8mk5eJ=YDRzEZT|j=lmei`$=I?5P?YT;aGBEEUfUJfcX3j_)TU6fU%8xpV4DGooiX zoA32?6GU2hBW4QT%o1;0FA%Dl#uvc}@9Y2>!^LAWe7}xPw zKwX!L?|4r&YS$enQP#PY@HQAhrBW$O)k4IplU+F^8*tsK1GqegJdwP9+{is2$7G43 zKt#V%u1rjsfGb^1+z^q(xT#bUaO?FR7gpxFDsFsoF;VmD#iCyZ+-d7txc3|}G==(I zX2c`R+srtge+~P7@q=wX=jLdR<;&lk(g>+eS5LindgIm&$wa~rf{@aLEE0^Xu7Ak_ z=E-2RT5-Vum1G$qya8eG$0p zHjHpt1D97W#tU$3fJ?4f7zwQK%48X?chj~Fi3Hz(4=GD1d_&jv!%K0wOW&-yY#x_y z0PyQ|d8{v^*3xh}Gz$syo6Dd%ma%uGc?+(t3B|TUvrbWyzn6~{POxp;mSyELSukg1 zEMyd^`}0F<(`{{-EOomKNZ#SNb}qtI zu#k>$6-3bGaVG&ckxnNJqmC;Gvj^X4S-mdZ(t?+^O~;e0;Cda~GOcVXgNdjTWXPoK z1}eGa0bxu6UzjSm)6)xZc>?<6{(XAaD9z?QP-T|pWDKzEVJ(b0B{xTNG{@cO$%q^0 zHg83fzn8(_TfVGgMd!-ZgPBy?4=FHbMwKitba{mKJbm+IEk#w5I+P=X+ro z#6=BU*X1o6mtLlpay_^6Pn?N zJhUgJieT}3{2Ugsu&ip5t^$9HskEl54O~J9uz%5^=Z~Bv=xi11pafj2ehXLF3(A@q zxo_Dt_-KyiXpS49a2FeRS+#a;j{B3psX#?V>RH)8xMCGp!jv*e#HP=KQdl z+o*{|;neYCJ733^iOpJ1@4(7c>!L!O6cggwb`XXLgh7^M^~bn9EBXieSJY}XP!41Xu9qT&TQpMQ zCD)=Q3T8JE&mY-;{?GwrRuSO#4X#|ZHtsLNYiqcU9k2pR0;m-A7F&YaE|?_4gnV-u zG)HsX)dLGblfRq%edh-eMc1tT(^vmv_0!Ki{PE{J->+3`w(lo3MNyJiWQ3PuW3r-F zrYB$gldqmRu$%AwN@6mZ`iYsBN1iClr>PB?`Dswfg*5f9u1~{`f;b z_UvNZ1QDaQ9)PQA<*A7mzs7MX;thb3$@EWt{!8mOYz50ZvV+Yri)Jnio8{S}9WqSN zHE<=nQu)XK^EaP#0mKm9#7%!SbG+JAluUsdQ<2Vxm;D1rebI6~eBrz+%7+kG;La z8$X+MO6SMM4jek#`QV3#wm#U^)3yLt+4sFS&c3_HNM{?kyLZ06cHQP=GFh6LoGRC5 zsk-k%Q9&~mDiLyxeQ2Hq4!Apa_!H*=_w0p{caI+He)yw3Yc}-ub!0OcjIa#aiYlJj zziWErJX~*UD&@FNsZ`ptd&hc?o0=IPnJAealAC_;Tjdst>h?76!~HN^FW}w17Ch}B zYAxOxuJ8QbfBwzT_pp|cS~n8u+~}Ee>6T17oyz2M?y=b;Z~RbHb=@$2 z>6d=_<(FUHy?gg~VRY}VH-=WN9-EjxRbhrmB#gj(rb}qo%G-n{GcoR0{`0>NeIM&t zxosm6&t5ov7H~7^RJtYS9GN-t)@zcg8;Qg(|MI{2-uJ$@ckkZu@sYi|cdTAHG&(VJ zriv($Ov=otK-D$f_kgRXva25cv2%OA`<4In?*re(dR}SUgmGqSWGvsF2cUF5;}oY) z?%OG;TE3;_7k}{=zxAze9X@<$d~9Ujo*e`ItIiju&)b;0@0-!O*BY@bo@?UE&89}3 zo9I_@4C4H+Vv!BP7=AP~Fqla59^Si_G^#mnK5evSjD_tBvPn%><@$7B3{?4iN^e-( zFl%&G$)ywFT&g-uqkJ~0%5t2%&Ld_du_cp2T%AX}Z$RMX4EdX{?EULk-ys+`Rm0}E zNBBEx4~z#Ncv@18>hvfU<<6n4na%;vG~Ft*idF%Si<)|7_p1{Je%RX483e&gFTFHA zKCWq6xis_Qk6s(|H3w@hQ7{XRoj5)|dT!eG1@Riiz~jD2D<1raq#3p8F^;=>Tc)Fb z5w5D9-u=qtyFUV4-}hg9@x>UoRGfb4N3V~2x{VbV0T5eyk}3njAj057ACt5M$CZ@M z)!VZjeQwQkDy%kZB8()!-SzU+;TnTGEqmDR=B(`Rggy5L1+jFU;rUcQ31@LrxF4>6Uhfj`7 zmA=3Gy$h4YNZ#^(aZRy%4>33I!cw*DC%3Nr{6`)z_zY=O@W+Ox$kM#&EG@yM=S7W( zP*g%Ot~+5-!7P>n*CL?)XLB_sJolk(XUAstzBdfVZ$5(NxF`4<=6&E3Q5x9tWDt0m z_nOAOWAP^1gtHwDsUN!Owv`v?Yj&+{q;hY+{WkA5hK17XOn%G9t8z==J0fD9K=zE) z7%d}7;}y`aMQt)(jj)Xt5&5DuCM7Rb)tW=zB-TF*L&VltTB6cI! z3%J{!x*RTLA#bGx*Ewf+-ACN^H z2zAdHjc6EtwD~%%moyAK>UeHEQPiXsf6g`S^Y6T3l_uL(ZSUQ(-M9INHC-s2IlK37 zzY@465f$IHLf?f&z3G$xV%<~EC=&VNCm$J^Doz$nuYd8~8AMlic$66HEIQGo?9VoPa; z&2a%Agw)I%F^dseJ`{JAr4 z{i9YX%Bo(T9;=yF$NCR+0xtFGeM8>x9BQ@;PxBX^`@n-6`n_;LS=j|P5krejq(z-i zdA97FlN_wBsQXp)bZb8UEg=HW7DQ1&y-1EX%y&7VZCKm8aZT@Rv9{~bsr@G|oE)oNW+>#VSv-xLG$gsjIpw-ESnqldt@sYPnx{dh5@8>M`KyN+3+1 zJqd;~BG|KPR&gTg4$P{P7b4R_G)q%%t;q9S8SUBh(-}#e#@0!jPD|^~9U;M-)U;WEh9nV)~ zsY&6@ao6*AT?BK%9A4>HVc_;|cuX}i=l1_F1gWcp{TtS<*#03doddTau*vlk>a}q< zKCUD(=l8!Bfj*FumRD(%~}mgB+*yk*g-P*|M&+U-q1he2?4#rm9xbXnqB7i@U|!mSgN}>U58syAgBY-30yFfY`0bdJ<_Sn z1RnfONO!Ji?db&h?t5T$C7yd~>$6X7J$!29;K`BwCr3|Qn34!FH2L;a=dPHxERyG* z+?Y-3*P2*MU@*oxZ1=I@!b}Bp5#hdJ5foKo2jlyvKK8&DKk@LaCtz7Pv-6c*fBD;- zzcJx0Q!trRrb)f|04DYL2|<`Vxvw;Kx_|qJPQCSQ_@tc3)@BPkzwtXi_A7q~`p~ZL zd~@X8A0=CR7lKNvVU?zKe&e@4{6GFa%cdXQIQZG8w*2+?_esqindZ3O3H+ts`ubgZ z>fGUJBpGF%T@@u&R8&xwd4tVcEI=dN6e!vYaI36g)7?^B9dJX>sfn@*U$+N$`3&BJ z((yj`^wyvL_`|cl0QOD2NGz&H24DS7z|^2&!?D4?W`<8yC(c)=$Fy{Q)nm^{vfx;B z|F{23Y2*ZDl;2*^*J|aEYi5Fx?Py)KwR_zoof|$NX<+^eA`)`Z2}~4gCx<8AI&|jf znX#xl76wTy5_~J>fFDpV2sW?m`iZBuY#Qphi3dMlDE`sk{NUX9tf49x-4`w$xRZ7DVeot3`2Nl#=hF%G_UPgPg$Eq|)He6STl53fQe!<@bdBeQnhPA{lgqq_%^Vo);`uIa8{73|e2%*n^5%R$CfTu3_K(wqfd4aLesT8g9 z6#sEz7~aqIu3i1XpHy_@SzJ;niZFKK_?ut<4YykK!MtW+W&G?zKlRHq=Z~Fu{qF+L zCcLM+$jvVzM($IgGI_oTX7)QjNVImh4Q=b+_R(xl|CFrAM95|nAIK&i*f2OfQ`vd= z^sXc43NzJm%@#$XDH1{GCU7C*c}-v`cDH6e_1O9kJ-AL }BMf9n;iI6-9fa{3A{ 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�(Kd6PwXRTIX|5y-O~ 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

xXM3N06&5rd; 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

TO5P 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%0A7mc|Wjjbrwq7XN3h?^C9 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%0DXZnvs$F6CXGNlR$F$grt-auHQetT`Qu-+ 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

xXM3N06&5rd; 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

TO5P zZPNA;vUI_(_LFseh%c#=k9G3-$zF#{r)YT*Cb}X|QIV$`ayyjG`F!NRR=N+dj`DP| zJY8PMhyT{uuUQ?6Ke%Nkyk+J>3Aj6FBRps0f+A>UNf;B3EoS%->*$1m+6k2e0exdY z-xxDwU_h~g1T;!ci;`0%&i!G$O^~BhEw9Uz#*ySW3_yv1+JP4&Itef74K(^r!>aXA9;jMdzgOV z%i>5MV%;`q${IAOD$EZv@IxiLdx#YXA+x)8?|9K&HYX7>-!EeKi>PO-b|290!$jH# zir#?C+tKdZQN2k@f;^=MEPmFFhlxyf)PPsB4p^{x-?t`AjHY8eMwNE6HS z=Z9{q&AkMvHi-?J#8hvRGG9>UI~tv2D*m3a?8EUExb||iu^eswW;5}+)U`3|@Hu%V z7d?}^Q6fk`*o!{cyP*Jk`8JJ531aBf0BVuq_-We^UoOQ1GgKPc{=nztJx@Ohq@oynCiz~=dNq4Z<73_88p&){A(^pl? zs=q;w-sq{lQOSHWQ*lwmyQrdGM)`m!QoZ~(a&N+tLPJP(K!6PhILig) zF5j-7BAQ9{=BIi)AhkVhC^+Na|2U9p8DCVUas{-@6YTOFz5?2_Cn>$h!3I)&%Eg{? z#bz7xN-ih0cHmT>yBa@t^+g+vWwF_qDm7bQLb$xpz+PxDj64@?Uh+DV@Q1iBXWy4w zQYN_5p51A0i6*%B)*0t_bKGGwuSD1@5&w3aXM@(6*jf0yjXt7AA2+lrkzJJ-lBepd zrz)i*-blb32?H5rr5(GqzqR^6s@V)Io55c`fAO0Awsyq*RfIwmp>RWCc+$$rFTU^f zhtMHDHpI96hrWON67k1s9NOpU(C4`rIZ=Q7U8DEw)){d0avA(wl~l9)6kwl%i>MyF zQdd~;c!n<_Tpp{@AFEN5R6kSGdZtE0^|c9()R__L+=h?4F7H!c^s3@Z>7_+;=0J{$ zSXdE@iBfFf&?-kx6}baMF4z`4Giw=y)(NpXp}c95nq^u*Jz*qBR+=X(CnNu}E%})% zC-46UPSRry?6HQ>>ts`KXpG74IP`}M{|)DS#218nBA5c@1- zFZ=rKzr4-OJ8)>DlGmuTLk`Uc_Dj|sxwRFJ(K9`@XL?kX?QHd-3C$<8{dVCmQyN z#`xzfcSiUY-!hzm1SvZ~I(&F8^PamqG`|!=3$(EU?NR^yJh}YsxlFl*x4E^Df!lP+ZIxUY_pHG^YcUD|zQ1+#UtYcqa7aQ%sfDOy_DJRF1dLGS zs|;tv*DDAw;`>&@`&KR#r=VziVYIyqatd0f-LCBs*8@3vU}W;Zi0V3a${(EaH%1%H zwSRy24?OVUer5AGXX5M@7-h0@gsF!J9s%=ib?}gCwdf0hAc7apD z%Du9$#KmO2F|XcuI9&&d4<;nz5e4mt!jv+4r-Q+1(p>v3+`Blt-`bDZ8(wm;mt0x( zPTX6l$-n}C@W$2bjq5}t)=zGrRn z2if+*Yx%|oJ##%ys|7^a_+ z^sozhvgd!LUwg6O+kg1GQKn{5rV}Zqx-+(BXKW{;xaS`0Ct=e!j`f543tjq@?oS!T zZfnqOEkP#V!)GGv4m=$XNAVLM`@|RS^}jKvY*z|le{1u^f5X8#Wy^1t>W5B%&~_o# zE)?>wkGiw%bRKaPovXxuUdSNTl)*lshh+suJ- zZx(6^LMmvIUBFov5pvx)Qhj9P_&wS%YxC=;}80+uq^w?7 z*{sreBHB(G&yU(OMvx1eX;8-+)EREx&A%VBxLb-tuglrjRW!8}1v^DyiG<4^G3myO zIX7W5nL1de4qdpmVqk^lT;l#dNy18!m?QP;%*cF`s<=wn@%>`XewE~J-+jP$9~L?s z*pBSKwJ5$0Lc8enE;?0T_+$+}SsS2_Zr($iQ87?5?{0FB%o+X8-nug)`73 zF>I1Z5CgkcjB^c{+zhE^>Z@hy8&Q_c%RumwtiDxpxobfNy&XbRwb`jErNDPdz%I#f zDewupo{A$0&*12tp<`$0Osxm^0~<$NU5qpE!iw|4%9^rAoU-SfvbRQi#N#sw_YQyi z20wx>8oi4~?dPBz49X2Cg6XI=IBIQx?hw{2Z5@2Ie-OTVnJK!=q#pK;+k@lw0@Mu7 z$US>-&t8B8am<9j-0vS7{xm#!_DztM$*SsxRG2N@TnfMdmTBs%?RFnFx zoiYZej1AG;EN2KGmgLDHG)9*mqe~r$S_!C?3M+Z*harcpYxMN}b7mDd;C1 z%BMaUabwvoPuR~CT`WbH>CKNH5t0#QhBM!0%xN97d@=`{>rAsdUy~>K6GH7CO?r<;-Dp}(L92?BS(^g1kxpjoOs4$1;PDK|(IAsQ zsFJ<9%K>yba8Vq~*YSJwGjGj-93|^v$$E^II9AM_h!r<+j*d#%M@fZ{6J{-p^Oy^v zZ7i&f#h%v}TEAMl{5uZ);>i2rXonILNPl`8cM2Cl=y48qoMViNx#G}k&a!LHK}gz| z51g8IOLGE^2AlS-o?M<+E6PHIwZTaS#vBjaJ8AQWdvd=2OQXy;XK zS>KKWZ^>KMB+W4w*J;N>sxO4X7b@2dH}?c*=^75wpXCN@Wj;}l7;kC*v}dkR>NXrU+9f1mcRXpzkA=2ci+(t zc~nhg4TzeKRYHzJ8G=w1Z-g=%P)2$q{QlRSjxk<$Av8qH3lURIOZ`5e--mOgBUJGxZu}>1 z4k!%(%49$cbg~;Q*^O$j+C2{JCJk1b$IaCV(*R=#=oca9i;#M~(xe1UN)|f9qKkF{ z`kEzt&7xkHg*br_^0w-JJ-_kEY6hg5VI;~hqKf7=KhWkUK;fWmE9W#Gn93SM2#6m{ z><5#lBk29|GUOYP>!aI2*iEUAx}!Pg#a77}LO`^#OE*YY}p@LMjb0VT2A2%~T39l}<=EK5?Zx!NheT zWT04`S*%Vy;-r~?G%|DNr6#?UkuO(3Xc$ir#-qB^G`WE$Hy(;$bnG~2JMd^79O%H8@IKV<@n+BIke2CW20?LtzHSS16Fv;jxzDZV`zvx*eaH2AerE zO6|-j5oPhGIjE;Oh$+c+P6vR~q_F^Hm?D~aWkY*qLtWy>g26E|g2?+HZ4c>&Yh#EF z{FE+sN|)2v>~t&s-bUhT@2e^QtEmHJ0}plJhdMZ*gA=kF5zW*IP3wf?DJ&){L9$YY zEJ<_fTlZzuyoTdDq(dK4i4MFY0e8p^T;yAR9jto;C-|^7c39i^;ld5RgM#T_agIu4 zvJzPk8eitl7fRutw-CCIhwbB;KHX;UV%^3ygqfz<&7#?DDw?&3dMmrbU%DZ54-ebJ z6R&skC}anE<7Rxv%@<`7+1+<6{>kfJ$ZMTQRHu>$`H~N~MCL(W{55}E@|`bm z^b+YJ90aC5vi>g#C%VC}%jI=Bt$|>2O(&-GTzR||sXtRC3Sek}^ z+#iBdeIVsMklLY;g}HtiS~}YT0s#I`lbS`7nk!nBUYX@iOHWS=AVg%PCcjdXno0b) zDL8J*rRdYqb|Bi0ixPVAuNAHuJTVjU+Q*mo@q-anyqSld;Gw4p+KY~uHBG<&a{m9i z#b8ybL_hAf1-oq-=tS%oeJ9&&(LxCA5(&FhoRJ>*fCpqE?^6HKp_Ut0LFh3(<}p30 zFgqp%$E3sgM^~(9cgRm&2L~&Mf#onngKLFe(vz}k>oaK{Uvjb8cWMhMD3y<GZ>aqHgDY#@RqR6gn1;|#2kn?9* z=AU@ztm#BRH^Xv!wCE^8Xit|(=S_v9gz^)C+762EdG99(C^Da=`2oCVIJDkNRPW`6Le>?*MVmr`)8UY`=t^2t zLVJ=;L9(fsvcx0oK!lwbC9!LIv5cM2dI|RPx=?&w#gAyG66{n8Q3!eBdA01Zf8@hv z&S(qIXj8SFOf!&a#;5p+R@i|GJ3dNUXZEAu_J(+-UrI_oz=a&6jm2n-N)G93-ap+!821mENe-DQDgE4Q zBiU=CM2RT9Z$wW!?J@wFA7a}KvFB1GMzS+VcD6#_3vz-dn6L1oRrpcE=iZG2@5T*> z&%M9d%(=BpGmzLdS~am&O??zegFh%YHY_LoVZ~EC4;tRphtNy`mMP#>IqO_tTH$U& z_+s=D-tlrl%cjiT;0LFU4xv#jEQ-ZPxesvYpo3`8!3~`dqppnd=@l^`v_y!N2(32Q zPIc5-9e)}A1R(GO9xhN zE%kxD$)#htbk6!oIqU47u33gRbJd!E)!G5wYRp}IBz4g*zL08~4lhlIdd6vyffh2F z?CXa9*7q}lAvBsHj8<_kuC)QRqc(Pl5ERQwjEBy>N#+(Kl0NK{f{Gd{eAJBdo^a4<1LKs55BTgOKw9i0k6+`KXelA{hjg(+x=an>g)>iol+@zQyp?d?lEGYVUs_VmrOt-X zEF&z-$W$?*dCngb;$m@Vho41<-&Az+H=^CNoo)Ji5FrpFbw!c7R0eWQL9VHQA`tTw zAWtDc0x`jbc4Fk?rLf~ox>%F0(Bt}$v{3xK0B@#5j{m$UUs9^VC{^KwEcVNJI%DJR z`~^Fn%#kK@sCLEzXHeiQL9>Q(i4jv#<3p?Qp{|8T?wEv#>)rLEFC1Up{H#R|Fn z6(2Ws^XjZcI7g>lMWeXiSYE#XM?Z%*; zv^D=a%TQzS+I&d0hlTa9Sm^E@r@GgPyVps9M!-aG;YYh4HzBlykCpI+C|(+e4td}| zFBBbp^|@O1^6YXrpLb}?J2dKGrI~>=712Ck3kGcID5}0DeC>ZOot2RJTs>B<9`*M6 zx)fZOGLUHQrC+N9FY6&R#8557(3qlhlm&sZATjd0LnSeZ>HElKeN-vDmgNSr+!!cf z=dt4&yGF)#L#oaCYR&p|3f00OP#82CQT;gko4|1C4+t&QW|eAFc^#C1LDJ!7^6ANA zFNj8tB?LqT6RTiy{?^)*?f7y7Vf{Yjz&}K$0s8N4t9SbW^|1u6Z@I#^D&BnYZXn)` zk5ZV@2Pejz{)G;qZ+L*8btNM;Ftt+-Q;Jg-DNs6qLsN4?{GQ^jgK<6aTsYb&GR^WjZOGWH} z1NJN=cHGx$Xy5I$h0WCPuo|9mlyzzIjIflqcr)kSW#`?482_J%wC%jBR{Loe$b6E9 zVUh;b*qvz%GD&0i!|WVe)^>MDwU&X^GMEmp7TfFViWlQl!)!TWw!=lVzinBN)l=vN zsn)Xu^(xnoj~&5dM;@~I{>D4@VDbFPV+rxvqJ_0+(S6P>cC$_Y?;8H#oSbz|Zcgz% zFSlitlc~P#JV);Q_YD3nK1Kzj)CxvX19(ojsh@D;Q}WCH2mn6rJz&FLAHp61BvneDStxfNg?;7km^qT#2Y;EW}}3ZoL}2xS0(%np*L8p8!9D{ zZaIQmWJx4bmt_AhI$PlAhf)o&8^H!=vvcGURTsj~`TKW`dJZyHiJm;?)uU?D-pF~Y42!md|= zV1j`zrnrkqji+mL0F4eplnQ*ihkU|0lM%thf_kROe5RrsUy*|=ayn(pJE{Oj6?C-a z?GI6Z8gNcCn2_;qN%K%NqZAq3e3% z9h-z!@8`mf7wXUpRm{Yvq~Mfv_@0-wc7Anc(eDuYkR^DiBB@?Ef>(|_luAA8(73># zK}#V6kGR+)E_d9;C7Jc_{JL=l8eIjAu1?4oTo$=xfmz882)!o6t_g)|ieif$o#Cr- z=#V%5^FlU|>bIpOzm7i)p-(v26OM$I0ix`5;v#YAS7(#2&H-pGoacUMWUfnwyykMG zxhhK4U1xBYRH_~=soT(!kpiK0bV;3x?_8rbXe52-D!%y5+HoWmPW^6OY_~3V@XYHa zCf=(F0esO^a8V`LGD9KAP&lEfH+p^X+J?_*u$fX8t5ikW)H;G%Qre)hD#TZqVo6J} zqy~(C8Vf#+9WK$0stpm)S}CnoO1>j%M zo^Z4K>}mGdb0Tt~?X+x|RKGPJF4J9F{9RhqgW+{ka9zbVa6*rk4&9KO5SnL%LK&h+PrFQswtqt6jYdU zD6;yN0^Cw?&?HGMa*NJ&HbRa*F|bbzBc~(sMuYlwFL90z+er`G`J-wQHv`XB3+KFq z95vF78YwpoKVGWnrHVLVIc@7Iu{aDBCK6_anDhkBof2__z6srpG9`=o6cd%@YeaOCJ@{K01v=4TUA zZ?cgrhA%w52f$+1h#S z)MK*@E~J{RBh1#JS}CICAX?5xp(lS#IsJTTCU+dMdwkPV`=%$L$m*}Q>R)YzNEgSM z-yZ<>2XK+BZdQMgU>BCJvA7c5haH`4v_|FTuhrTJ$J8Ed= z3ZWrJScnnll_cocb>6atIP{nw|CpZx3e>E(Qj{)A_J9nWv$9` zZ1#0dj(y!02z^S&p3;qxTP6QMKwk_2=V28lzjc(JZ{nIoet%Kt{J^;BJYs*2N7tOUf8cc!Ja zzrE6ypBP7I0g0Meq9%9Q=RNZMJL=-_2j9#D-^`pSzV5rM1iP%9kgvN&Rn02)uW68@ z0v1-lGMcw@dC0)KP~vK>$WdD4=#R>n9A4Kkj=eks4#_2<+36tbG;%>nmyF2@&~_k3HlI_U)j5ily~K9m-Rjf#-;8 z{4nY#O?m2N;ys1)2)*&d1Sc`EBqlFDcPh4)J(uvle{Uyzui{soZZAwHZ`7Vh2V6Iq z3Scwu4YBuzVz8F8>r&r)EBxJV3*&AJUzA#U`}^r{Zr0mDXs!s$74dhqUs=qV{fh#J z#`%cieB4lgde_QDIlCq}!G88>i~F>x%6Y34v`U3&E9eoA*KNw11gR$Su|z)Sjbq@= z3Duv76?V;oe~nBh@T#R_ss55F5PDq~yRK^>z_d&P>;5^6L!TQno*NHWd!4qX#%=b> zxsZWEF{@CecJ@VIaFMK?En4^EH-5uhIC`z>SgX2mox6?0!Qvb5ajLQAvRLyV%IA?} zB}=jjLZ64joEcZ9W&8@8xl0${RY~g6Vhvizq#j$-x83O1T?CmgVq-;Yv*rNbb#d`A zgh8Xl$+E?1I?@P_?jIOeRJ{U1A2P6q48hn|%b=xU@9z^F*@|OrJX(3tG{;~HX_u#=kCJi?k=drN6ow?3*FZLJD%9bBDExuDhIF6-9#0Hxi z{XPXY)24~FY4T1>11v8(tGk3w-KHv<4-4MH(9NoauGID#WAVkQ1yi8 z&fqy&9eGp(Q@E`t6LvgQh=mG8D5nM9Ot!Zq+gpi3;Y7Q5eZhHIkm@rA=NW@)+R3s7 zS+*=x{|qG`Bg8;Ci&d_oVBc{BcSr^M-D;n+*F&yD2Krc7A4`btJ#hx2o$#L*S~kp1 zN5i$V%OJFziIp?iZ}PYgzHdIh1BWI!@Dd#CP;B{=yYoHo_g28Qa8X_DqB@(hebq_T z>!ci{uH)~fjRk3BM#Gt1Y15p|t6@J&c;XV3yyHpkAjw^b{7r5E;{|0)n*KM?0^=$H zHIdCbFYwOG2&J853C84ie0liTKIOD`dL$bHp_hH%jZb&K<G1pZNiHDCg@>waop_aIv2CW_EyJB2?;lCqOXN8FtToqf)w;t9mwa9;zvufaO$99Qc-UqLwHhM950 z%oLPZi9Q9lPoY4i{)DUiItyZ?kfY;9g5yS1j>`N%nI8|8w@5YHqOtL%4Q%G7I(AcC z@?(+zqD@z~Z^oNRHaAH&51w3UXB=Sk;+QtO+s<|vxWlOkd zCA&y&32508GoCJBr3X*PZ)q0wL#f znI^eRs&w0D5BAv`Ba1TrZjC*tu{TD}{XUg;zYJ(Dh0Po{!j2p9(Hg*^WqzVEKQ}bv zajlcW@{g~B%@nHh3)QL0a)ddEFy~Tc{D2iWV8ulCB7VNx zs(-f?P^u|L2Y~1R4mwi#ZC_<*F=ZoUu|yr_mH zF%@qWw6_WyN;9d!AT?Nua#Ok7ZcE8M5DBTKim+4>uT(0GmPY|1>tm>oFx1Bd={D!@ zZZ$nCkA>@~fG02DQJuY_-9faw2@({?rtG+U_xE_%&xhJ(549&!7zi-~Au0*}dK92X zAxBIz+g3XstB;4xq-ZizRE(B~jlp5Er1Ta|qpXIQYY-aF<%DyoJ5RL>sCHqY%6TP^ zM^*JNxCQ$eF2KSCCTf3A-;$C3n)qIRc$)t39M1DZyM980o^cyOtJqi-TTuSaP@s{% ziSUGZ?j(Lr?)kEoezgO6t?+y4QOA1JdCu!I8;nm35I1p8ilY%;ezZK zBX8X3mhNbSV-%tx3(*LojL}IsI4PG>ZVJk*K$(>kmA5sx^W@r*>W`4c-7IW3i@(Au z$e8A~x*cz~*Fn@vdZuhETQSlP`wGXXlwnlLpxUdyE5LV!2J?(aSx!)kPg~e}S zQCD`4Bj|DDqOyxAK_hMi3cf>VoRA-CT1{L01RECQ6n_uw8bzmYPv)lMs8(-iW zQmlO8Fjs&-DDV^)kk#64O5bSPX^eo-Vj)&6G>P^q+?X9ycnF6^DorDmwf-$7Mv&@HF7}hlo;cSg_27arbew9L8?VgG z4kh0aY`nOsuE%&Hv1#1Uz;0-;=I>u}a(#FD4g5i?oZG4r7|>~D_po=8ZlFIwy`T2ya~Vlz-|#-!vB$+QHSmP}NX z`A?2$zPMTmd-FhmJrMBjm1cH4tiMC(f4jYfyS-hI?34^unQU4*{(oa65kfRoSHf4kPYvUjU6i9T-cW~X^!hz$o%G;=;+@b^QESaWoEe8=YN@gWRhAr7l05Z>@wfI7-{BZNQkOkar;6rM z87P%W(G}43S1|sT|#vfxD#tTMjKRas@*Ssm9T;I2vPr_UwVNU;n^xs^2B-@8r#)V?&XwnePLs zb}|K>OscM0>Hta|cxb&g2h0&HQ=b5#{VZ`mi)x%W-~Rc23OMM z%Flb%K?v=0GQl~S6SApq5w|wqa0-D8M9{?%DrSp1OHgMiL{;eDUh4U+Iywwe{i2P1 z(Kh@yvCiy|gA0iB!&ejLSJF~1W*vAPY!p3-*fs8IVRyA8L0>E6vt+l4*o>oQCP&Qz zC`;|2jmbfq0OV>Jcj{tY)Zk&r(V&nwD5NfmW+iA=a!@c;Jxd{ex#`j*V%K=2r}juC zUrvpKdX0mGQWQEZ0Hl%ma(HQ3C&OZjVQ*gYv6pczWz?+Re z$M}8HIaUw8Lk4a$vD-{`)xt2|^L2}8I0MNJykzo>j>2k*wO2=D)zPTp^{fdvYr;U; z5OXH|QIX#}ax(Gt_3L8&x(tgO1MA0HFD6XP87AxuGI65ut@|Bu?Bjfc@60>DmxLZ#!nhY1eNbo}Cm|O1y>V0@9lg`wNq78u?OePa^@p3pi^7&e||gCb5tG zAJUfHFo(TK5n?Gqk)GmKS!=p4QRcD5ThijKM3Zzz@6WJ?kq)po@%n1<`ZCJiP#FX& zgN)G;JFrn|bm4C| zw|3J1olJbnaZD_Z$sf2|Cv02&fp8M+vJ-XLxlzuLdG?|_dpC53toq)OJGNvaWd0Ff z@Q6>9#5tZIhxBc@^Vc)sZzs3HsXswCJwYE&8NH`g;Hj02;th4g9vrckp>{7Z?7Ndj z{0E!4sXgkZHr0jVn-TbCL_-~)Fk|`%*@qo)j5=9ZCySkLm*th*yPpV7`RT~}NqXiY z3kxwu2VH0fU8s&z&x679U>4G8g1cvBmDt5Xs&Nb~j=@K1w{fcVHlljc!LWYHiCZ48 zk3e2iwV0_Y@g%Qg;FXMyHqz8{)3*HxO@`1I4Q7l6)dbol0bP>e(34hragaUzIAkC~ z1B=iwTq0fg=Ly9f7S6zTBj$Ib;i5nup&@0P`%)k@oQZ`qSs^JomjW|;kK)kBcHGBy z3KYZ1JX3DA37mq^YXa<=fJ@ zp2VRp-UI)6p}U}OOHNL-k8Os_^biv}#N;(FoXaP%iV1J89y?)=%Ed>Ty)ccu_{h;Q zHr;UIEo>%24~x*_Z!A6YYI9;d;h|9}6IIIG(42VeQob(T(+i=IVk}ZjzZ{s8H%jSN zg+ssju)g`2qZ>Ty?QLVs@;<}qt7EY0RKmN$Z9zC0-o-FfKg?XOHia0HGi|5`+@K+9zcv1|O)!hULve!k*VKy9qr0{lURgkC|4jwavf0U^3L6z8>Ehgq&e zU6r3D;4`@@O9C?IbUyHaR38ekhXPLjp(CTepME=tQ{Cgu-$N#k3;%tV|Khd2Q;1#T zv4PrS1L_VJ=cyj&X+bHj-4qC#0*7nMVe5WR5R?T$j^a4-I1becljRJuoK4W^1^n>; z5S20;LL&^-A`GPzDRVCf+zT4cAjUm%wZDzG7(#clO?R@X0_ms|IO;T96o{rVl4aYr z1u`GY6vV11oUiS`YdaniRd~m9?Ln?R4~fVFn%YL+e;k0#WLnTNE$k^Ay%-B#j5S44 zrjdK|=ih0GQwT}irH*x}(~DPJmH#ohEen6}K+bxglK1GDJ?j~n_voyl=dJ&0FTrN6 z8cMIKc+-VhfG`Wm-_JX~Yw*sDUOq=Ot6Y2q&RV1<7O83AX5y87frQoDg4}HqhGu9XQzr6verZKQI26yxx$8o#wyPw0U?o>^`OL{^k23b#&qbjivK{j<}ii ztJ5P04bj6w^cd}r7Fsn%O(bqlj!W3b$+L!S_e_y%au1x7ySmt2UFrD2u{DbY(^lco zICFWNc`(KFdBjS7#3~q>KJANlN{X=eu$dGFmckIcuBQFqyoebh0`J17a)Yph#`Lx+r+L&n4M{adm{(#z=@Q;9jr9i^75 z5)Xbq2;2`Et{qwu5+6U|qz;4@8>kfrZdWqDPK>qh0WBP)9THsbpala1&_xL*9CYpf8V&;S{#aZ z>pUAf&o;KU%Se5DW$+jLLAjHx+-W!gNWrA_AAH^HAV=L=(rzv4sr{uXc&U=;-h#~&KNAN+JO`{^{C zJPCgg?PeD3Hk=?WRJlaGa7-X<=D8SqE@s^SzIuF$6uXQ=8-3Z0q^pR<%#M944~~W7 zTV`ZbrebEp3mAp@i%|WSuwN4YT|KY}Qa#MT4l`JOXVf&0NTr`~sx3C$78?axavO{T z&KZ1L459Dn*gLve^{-u5*Kh8)jYGd%TYk5mZZPla3dhJSL1OuT;GAqXWZ*K(zZ6q?&_Na|vZ3 zU$g=jtt9A!ouwBZAp7MUY$jG0i`5l+b}s(8L4JaeHaku5pBHjv@ZWmGesKFG2(1ue z6+-Dn<$tj;dK-Vkp>axioH7`tJlOJit2^)QCAb)q4B1JBRKr52Ip{QJQVJ&}c!2~j zCaPM|nQ~$F?1R~`nM^$_Q_moSd9?YukqaRg+9ZrN($;ct?dYE4%sjXlU#ep-)p?=0 z^K9!nX7O<7bGh)j+=b#S(`zs6wRb^bbEWjuweEL{U^59iSb`2`rcFS!zU>bM{%)_7 z-%D2P)c%zG=gOxyA#|@0+ba~uRR_k8nGyH_hhFwJzU=Lb4#4i^)Beo1s)rMNa78zdPIzCkILMx=&D8L#82AroGC%oX$+Hk5vUW_3x8KN4!q{;E*cN~gO z@MVtdGKVUu>YYKovlM9qD1kKrz2Ql_;Yl6&{Bak3_qf;3uwgknN(&;A!7Nh&(enHOf1OuhI%ue`|9>+^Xj_=6NDlN6_6FXA)f(~j@oKYAKLHHOEH zQE{Go>IR;Y&T~VT!~Gvy@gUWgLhPkbh?0WhREw4P&kLO{Z_e(#vo78UQtjfiyZF?> zs`doco=jvf@q5$$hW3wg8X@=E*;qSUcIVtx@8F}NF#N%wli8q(+>3NGizMY9XYwA! z_Fee9#Pk{BKkA*qkU1DKrp0Rd|zpL6WZ#QqE&O zoPOdlZwzeajh5t%iU&-h93;xc$mtX3`HUSnV<%ql`_uISZ{lxWSa7Cg<+}hlXqRZ% zB^u9zml{h;Y`Tg=Z%TzXr7kGU3R#DVsfZPcVpURv^eREGQh@Bmy4r@8>$d&{nSaPN zdB~*-(Rx=qgP7lE2Tf`_=4_JL9~|#AV&iX<^Y3wptx-Z zZrjmcy58MYnR2RVDCJ?VV*5b|y~AVQ;Zd2-b_dz+Obyn1-O9Fo+e&Hj7w;CtLk0@@ zSRtQ(V*l}+ov-I@B-WsZXwbtAIdpey(fj?Q_EAXnJWp_5B@%4N4Gg*QkPUX7acc2< z<^>2X)HNv7RdHOGf=a1An)>$HM{-@-GU4cjjaCaAP4%lOwoos&;GnepI7i+7pxd8; zw5`RTHiebm%7e@o@vtJED1S_MzwOdHPjG00yClI~i8u;Rd3{u)Z_Fr>z+)?0vj3qi2|{c>H}tiKs`LxPl!9}xPUDSWT8#G4&JvjZQ6^h8%x{M$QW z2uhpdbnH0YWM*O1-@)s*5-xJ>R;KMLCAX98O_Ruy+anL!nVav?olbn8gPQa~6_?~M zCg6*S0XpkUR~XGX_m>bte+qa%1yr+ix;IGo=AbPosUP3EhR3sKB_9zHE3L1`J8@q0Y{>SBd<|8 zZ@+Q|ugLSZuig4T)0>vV-Xt4h$%gD#-FtJit~=S|R9~3$UYOfabekkEUXqs`(rx~_ zrw1(0Z-yLo>tfxyjI()(W%SlXgu_<02|Js#WG|cW-8k?@2;}Iv7WcRob--`Sz-<{D z8E}5xYSTPoaVUhIr%TVPB;t**1`*a0lvTv&-n^}jQ8*NDuab*Zas?y*kiK$?JV|Ih zH(bRxTs`tee|-@AJY)YI?ypUXh-gUls8DiL#Y)@c4Vt{g%WF1e{o54Ks~4hFeE*OL zq4)IE?y1BObOeEppkcq?PQXv8_;?&b6WwTuZd9Ylu5n=3xZzvX`7_r|AY35v0gFbA^X=4r?j&O(cI_D?(?-od2-Twr%pM2 zwE(W@<4pc>m5h|1?7$~GE@h|7um>6TT(r|2N$~l{F|iVI)XT$qc}D5y&xXA(woJsE z`Q$GBmA&3B8g;Lyv~{L5s@jz_8I7SeJ$;flVl zhh5hbL?vx8x-Qy6*b1xU;wrfZWm6oo6%W~ZAP1&t>p{Zt)6ZZt1De=?rUA-CiNAZ+ zm~obLT1FS$ga|33af(z5HigPTsGNmXH2&@(8*s>mg|5C)GA=@>?RTN=ccE^m&w{}- zGGlj_gZI|6I&a~!iDU>ORq`=b+kk2^ALHqX#|xFydf-(2)Diwv36nW22ZzZp8KO6K z;H(`VX-sQk6E|yUeumAw5VKyWxL`N=f+o@hdq#L{rhzGA2EqJQEx}bS>XpGQDYzx& zp&fQy;{a=1v=M~%FoiuTd&C0=@POPSR(?8uV8Q}#2>mYNd>2uVoo{`>TQYOS{Zj7U z6dXzj;5bbzPE+vt<5NqWU5C%&58~zGc)15fGdyW0K56HH`iYXd5wn&^mnNzRmu4%_ zY$c&wV#L~mSbGUtzsLBaUN1X1Z3ZE2N;R=kO?pSl!)rz#d!_h;m&UA@#=|L)LsPzb z)m@(pSuEDVinZvcH=YxO{u4;t@$E8Y?NX^3c*>e}imVxk>MRm0W@+=XRN~A&nu3oi zab~+5z%B<4%HucZw+`F&AGggQ-o2tDxS~Uyn?gA#l=CQS|D*z(RPa!|MP$@n;hDDo zVE3wdST&EgV+oB89JgP@c|PqfJnimsK~R`DczDL^C4W8YZ2e^y>|Uw{ma4(`_SKks z_{p6<9Qsu*`YLy$;Ed*-G_2KARm(=RAFIz{?{FPINv;malU9Yj6e)l+&MK zT7T&;M<7S#LabaUUSBglv!i#T8{W)8rSU4sRkq0n^HX`6NRn{99g zKAPh{FUsb4*30OumlxU`Evg3my~pOkcdK-;Djkt=+sZvT8QDY;%rJ9F7+KE|f3V+5 zvfoOH%ozMD*Li(KH(|%WGqLYXexzF`?#OJr0*AhJ5WOW`<*w>>EWTn<1$%RgW^ju} z)pye*AdRe5-JW#spMY{4iW9lP$8PZ19b0~>TC@E_2mauj2k)DQ9a6Zj4E#BGOY#6x zJ!+tKRHf)s;L|9nKih*e5GF`NYLmtO-BX!~xxWXSSt0 z>u0pUAxWZPNi^R#9aAuJCPB55C#~dB%~HqR!Etv9(xM$BKIzE&1T%>t ziC|z648hUq6I}Ilj}orJw`|0>Y&=e_^7!NJ>5M85spaUezY1p(A8e$)TBJVpsx4os zp06|(YmQ!;W6IRU-#rxsP6Z9yIpx1)pExS8gdCO8jmqfMgLt(ysJ0fNG*+Rdz{D{k z5JEp{@;+)(RpTTXNFu{r&(OEzPxv?oLc5Zx;aQU7g4Ny*;XLiN`yX-4^wA& zTe@zUNo)XFhFF%N=iv5g>|O=u z|ERhSpeT|qJgrLxfn{@ESaQxF8AL=qPk%kbojKo~ST&>;oRkOFo0I;0N{>9f!&C8Xjf^XBo>5ZcM& zbh4<>PL=}}_h@zgpw6FzZmnE8s>2R~0ytfJnOHAV)IaI`<~#Gl6Yyr9 z*-D?;dZ3dWZRhH5{{Jh7RGXQSW+wHkW!r*mTM_a~_`x`v@o&gm2z{VMdmvYsKGPRu zl7;CH);(-!-_--5@03{Yl&D(tAt^XSW}3<1ZHPFhEnY~h!dkkpmQFRSdNNpQ|1O??e=FoQjv!Otd(Qpe_+W$x4*QYEO9U& zB6Fc0zB$P#Omq`M?=i4@435Ky{<2M-iG4 zJm>}n-SnRPVmPGYtJvE399t%iD~424L|BT5t2HBOk4DZTVpk6F6oh!%qupw-(sfN? z`ZEaa6Jvd1HcDuUL;JmW{a)7SSoZOA>&IWK-a-ZjBpw5jzbF@n#Xg{zj5>E#sO?yM z^b@37sfJamacu0z8p~EI6HZCtGJZI@fgj#5?4xv3Wf3u>FN?9uVkt7{;tvwMWC>or zNFsJ97InSYt+9ysd>3?t7j&o#^^F;LW5%Z_+GlLQ8PX&goH=F1&-a9|nG_+GA~al? z(DLh7WzK25nKpNmHurhRQS7SEUzeu-Aznnx+ZRmX3%L`U9ZrU7|DdltJ8$fzAM&>Pv6dOK)S8vQ1^~!dI%NjUm+{ReF&sbyu#Cf(p_BX0h$D z?sm2hgqCtdrE>epD+ln3+)wr=?CR=joDPTNk~ZyfJ0;5jbh30r&+b_E`JYfhtN$`jzn%hhDH3T(GxCJDipK z`g<#__d)1wCU%=Cw7OK~AZWKbi9>5_@Shtp7L;tfeJVTRKWL%|OB8Wkk16(so%KF} zLl1Zg4v_0)flJn;4b>Ifej;Y)8WT##D1B4P-KcDu^DU42nT64Nd7x4&EyxrmTZ zk5#b8D%^Z&rxsR40;j$@vYNHdEzxE}SJpY||k&)$=gc0mPD?huiNueI4t(52+@yu|&3Rb$G#_ zEBEFSyGDV%egS#G{y)JM*N0kF5L(K{O4*Y7k+xNJ6$*nm^p(BdD|;U_&?pfTu}-2* z)T2$PT1VRq&_?>JUoP8tMpWAbdHp05eUeKzS?&SK$#j$YCl4Av(CmZIM2R?2;zE%! z72cr2TZj_khCZ07Ke&Rom>B3_Wh_{kXY2p?#nmAX!V5mkSQuvPNYVF>nF)`XIU;?p z!MyOvHxJQbLhLl~u?9YC_5R~d<2_3W!F$D(d&SifMc2pgC>sl_z@d0QzvJ4S) z4LO&eTi7_WQ*zhwe9J6a7GAU4|_G37tTCReX ztI$`D*Pgj{cBV#3Q?mz5x;CmE=UJ_!Lgr?WS4QyZ6CjW&)+ubeN-IpLi zpLU^AxMIdN2(4sbl?>+RV(VkxPVYA0&>$;L5SjU|aqq)#f{I&^*SDIqw{mByJ|EEM zGjW8PK1#d%X656>#4hzsi}p>6D(Ej*DO|A9MfKtEW?oDKFQ!ertNw#@hJSPioY7xZ zv9GGasuE z%57b+KKf8m{~E{Sl%02pst?5!NLVV1HDm8m^k_i1+h}r}&Ad3-T;K zzAZ}4rECNaXSRkxwuYRapE0;$ETb&)Xmb#4E<@o?F4tH2(*!z8h}H0cE&afz9>s$k zK#+qN4TrmNTVm^0P*gKLK3YlbeA?|I!)eBIIoeb3w4dhdPi z8ZIH`(QQrIZ8?ASOlO5mXM?4-m+r5fx!eRN7B(G(O`mXJpZa9q;!4a6vRI@^E7Igp zSiI>6Zu&8i7+`*=?2I^Nxr7jeqjYSPE?WER#Usx<`v_(An5p!bsR!x}r=O>*{KGUz zHH;w)ll#CG7NCOs!1tufF5VrU1)-1lMvwSEP#B1D1u?D$$g@+;;NQT;n+qWHE|Ys# z&MW=6EjVt=Mp+BOU7M>PjV^_}p5S9A_#A7aysiHnZy?6Ez=dBx279kP$vRS2vj$Sl z6$o<$)Op+N2AbXY$d4%Lx5<%tvFjl;Muit6XB<7L4^EPXjB?hBg%6ZA!*9~S7B#S` zcbT8N*Jf zStG`3#2ks_T|wTOTg1)b9WVYJFIyxTgJNIj&ANCTQvD>*{Un!R;e_(F~7&ymSP@Ba^okt*&_4E^XvU*cV4^-dlRgL1uN;G+HUx}NxG~g(#9Qqa_05H z6E`6=Rf45T_?P?jyfRfP_&BuATU1BJRL;`zoPB100ql6DlX|8T)xU7q9}N3X_!oXl zS+`Sg6o=wO-Y~E?3?aC*<6@Vzb~*ka-3tG?p~M`!WrG&8_3I$jAt8H6NIl>;d4MJl zCi3%pshCpvU<8NaM81fyFCs?e)*G`n_9k7yAGCS0+dNH?4C~x#sa5*8141JNScE_t z{j%>_OFf@pAka+~=;n*G^aD5kRmv#pgAA1ENXq1tjVg0cMH=A5A!iR>d^!f9r2;{z zfNFGp;|AWi@z4}MdCD;%WXE^Nz!@%fhAS?(pjDN<<0vt%-Hy85j$UZ)owmEE#Ga?} zGa)lu=)4v>)vQ-$0?J4ahD!5_^J~NoKNBPHnU8(u>s`6>byN`el<@dzbTw#n^+#1t zO4mDmU9s00Li2c79#53DP_(M{!)xN8bablpDCyhq@8nOZY6-I;G+GghR^(UfjsMF? zc}ScJvh+n+`p%!fX}o>yCUeOR5?}b>H3vc?7+3^Duq|WY=)sdcgj!H(A+98iqSCO~ zl}g9v!fqvSbQ3sKFQIG)knJErTfwh;TST*-#6qeie5`~o^L|yfRd>suu{hNOu7(F( zXCa%mtZ1li&7bEX)prtucM|I6l<5O9ePk#R8|R?^(-ldVern2|!wK22nFK9bf)+Kw)Mq<| z&vwFP#vzBV=z0+feW@=fC6m>?X=<^u+ED~MUZaE6=!j5yBOLn7T>8x11Lc@lka);F zGxZ*XW;3vCh7`pe;LvbOS-7Pya_mlDa{O8+vkY?7rzYrAqfXQ7#^Aa!kFtRuHwVYf zd1wRovj1T_E4&&uQ=owrXwXIZC#Jc&uutL5L`aztq~4bvW7wO0uNIC`pokqPSNr?5 z2YBtlL^hB9RK22ukD4Jz=QM=pG^l&SGb8ZKh)?0D%@nkm^3l0L|6i}Vh5UBd%v&YK zTe-570s0_7pN{l|gBnsDS?{^2uO&uhDIr`Ah_C}9!J=#LybiXc6PMGi9^zIH7o<9UIq3M? zKeLz+nk2!JB!bTiUyd3poL9!7mEPh?Zx>{G=yDpf3nlv&T%FoqbpIGm^_#oiH+P?j{F6n${+bhS1*xXHs;9eB&*(Wb zLC(yHC{K?Mvo{D`Y?cyhEJ=}-q)0s&J~IH%3>Xymhxaz%y$u6-(7#Rnm{zyn1~&6a zo%u9EU1fj{i$9R=);0vBae z!24OFFR0PCM_xkzd+?xp$aW^AdWR#tBbSrlnFDx6*5cV+V%5w0Z8fC&RR{a3!+WDR z&$=i!kvIotSO_yL9D^@D+*luRBX#`!F79B_8aO10Q)r1(sQE5KJrqJc^pKw@{_Y7s zaDq&L`O}cA)ySO9kfYm*?AwY|1-nEKl;|;$r_W^T#XFQW10l4GZ&W6Ch758AL9PZ! z59_?&8EVT3hRjzeV-?Cw{gtf5?NePfaR$<5oOH4#_2NCp!`8kEUP{zSdO}lsLZe#D z+h|H{G`2X<>#}{>Mh^b&K?S9Q3hcUpfSfReRqyc!DKls(10S4pKR9`z)3m+i*wx%WE1s0w?h1m_ZkjKur@7N?vCW1slq)|!OBH-vz1iOuEXDroCYGNP2BoP)z932 zf20pKGp2@(scEgw_Mp^$qBc(aPt#l; z?;C|fGNeHp(x6_X$NPbJzlng<4{l+*=QNH(=tVK-qMTTd@d7bq(z-7%ToOO#O>~%O#MGaRM<;9F!9o#rYD@ab@jsW$HA&F9r9>Y3i%Jz0&%iGNgK&ZE%}SJ>oRm zgJ%1QINND|tQ~EiOkYOq08dn~Cn~(vVWG4*!DJ%XvQ{Rnl{q5acz6G`ekCUsq?)P3 z$dpr~Q=}k8I#Jy{By@hk+h6(12%WJ^1uIkG^-mGL`t62=D*oV+f$))B2-7ng;WILX zY5wG~cR6_i*i3*rKR}(jaL!A?c_|l#sxD~IxQ3_PgU|+vutCnyndk!&efa1o_wC35 zySpoJD9%744@=|;imb=H-WI12D|gUYJm~C#%;80Dd-dbuOd-`2F(XCJ-y_xw#FG9V zHr`J8HM!FvG(m%%AQz)?R1X~0VcZQ7zrpU#aC1C)l`5~3XhT{S45u=!+z$lu^hI{A|*qWyU%$5 z@8@HC!^ifs(3$zO=X&!g@llYYQ%c-ZN>pF$^ZMYtJ{x`dxc6Uw4s~dPREJpD5KC0w z>T-9ki7|1L7Hcn!CH440j_h;4;S)%;QJL2$m%He=3>=qnkdAt=Gpsk@$S|auuY=|5 zaG%fa7+v}E!b+TKk-4DA+#WeDZDM`P#r#Jhv_b`|P+_jp;z;7}e})MTWSnO*bHwXm z>7g}2D<>@{)=7d2GeL!_^1smsZ^*n2zletqt-MQv&@n~bF-59@p+yE-WD-R6i|16{ zVQnP{t>Xym=q5q-s8F}P^NL$^A=O9| z^+*%y2)vpBUd<4ot*7s@yPu-73_=sNXo*@>p%OA3giN0}i0TRctUnp!2%&vUS)W{r z$`)JDVylbXgXrxCf3x6uEhi>$DxH@qXOHSN2EE1{%K0eS4J5m9(D`UvyZ(mEZ}XQE zqNACOHM52H+irjDirTpgf6#A_|0Z(h;tz(M@ShvnUUs}cYpd2KkTtSqpc!oia zP2P}2L|W*slriHi@Y5I3u_C%IDvpEm8f&5-YvPA)VDWqmQva@95PCroyP&AE?~BT# z^5C2Q;?P`uR<6D=(g?Fu4oxbq{tGg2jK@1Bm*w`gGkERHK{@ur%O17Nn;QbDK9OKg zB%(*EjhUKTa*yCtlYOMgJ|0LSN*``W{^Mo@gysma90Bvp`xCBu8?uSif{kvRMlyNt zDywS+{aa%o1H(ezuw0_2W)ILzCVKj3k|GCnssZZR7y)zKL zlau`YHo|^V@=wd?kX%+h4V%g3NOC#UgG;>wsCN({*(H{>D<+#JLg*Q`22caWeY=kQo zs0(boF4nr^&|+uZVrMUuZE-v`C*@H>DTIbguyBd)lH#Nv=bIkAfkUr&>tFHqLt&=K za80b-Hw@7m234G=TY+>d0WxLhEq0#5_`UbPFRj5kCRZ0OO$O4)^id(S=k^Vchaj{< z%&ibprFX6u$o0Zq-BxFc9}4%?)O`s!kUR`|jZ(#;R5_Op?P>e|*W^7ouV3`|U&x@~ ztfpXf=S`z<mT5S)i$uw*DyWLui{km>|}X%z9?jU|4(y$q;nl1^r#AURE2r!;?j!YxxW!H^Vjt_ z*U5sXVB@Oxqsu%XG)|1giFqBH9Jj1E`O97$8tf$u_Hsm{r;>T({40mqD+pfSv+*Bw zRvvT!2gzBP5?39Qmbnm8eZ;~ZvDm(D^vgny2H~9CY{zT1vqpIse{MY~JaB(Gqs86+PxxR6KFH-y=&%GGWc~zHID}w6NWu-0 zP-n>*Z*az&jY^65nUvi>yE|kBA$V(4uo@Nduk{a)|8@1TE&kxVk?wgTFUl$8vxV+w z3ompEi9OKK|MmMJ*qcF~cu>yT6yX9QT!bk7PiV>R8L!`m{r5fjSO#C%mT|FsFW607 zBfoROe{RUxU~S+2k5}d$g;Z}dgtz7HE)y(4f+fG-H2&N0@dKyV?J&r+jLCvjFNm-U zBHmr=^lvlm*Ad5{gPy{JWGZ0$HZg0K=Uqtkp^o&STs@}8=HM||k7=|2kG3WJ3P|;# z5PK*TwuHE|qTXc@BJzX>{&Pct2cnC=X4+1whtNQEEKpthW!(H5UKfAahC>Ubj6(9z z@zd@*^B&2yIZp8kEFKYZ}X=azcq| zQ>w39s_%uGk<|`YW`vqU=m9QvfGY{}3vKl>{u+%#OC0q|9DR@*@zU4ty*wD!D~XkK zo{61j3f8A(yO{6P>cAg-vlf4|rdrI)Y{X@x#k@^(nQ~9J4IHBYh9E%B?Y_tY6p?QC z>Ha^J-PE>&99>n$t}1IceUFTO|Gt-KH&TxgsW(wsWB1yu!-3OqDE^V6MWSfA==OdO z&`(CU@4c*P`ty!8kojH(tXF}1Wx?yY)26&Pz^T?62x<-NDYmm#8$qj$J+hrOZ=bYo z)t>*}O;yBF6*>L&wx5j~bO8QtpaDP7z!nWB{@}YA|GSwj`f5#4^qJ~6c0(4EIkIHA z`VPeopqQ-hfD&{Ny}2)x-4{{=@S{CIw1+NQmMu4RkB!wuK&o#P=x-FLHjhVA@Q5_g zJt^#cz2@nE&~hC~xt!VbkvYIi+oIFRO4 z6X6FU$QY0vL78@o*!LkvqYP}6!Pt7|TG#Ti-Gt5Kkv02~wJADtH1AfazP6wmLWh{x z5R*6dzdC8%^r$o(`oUKC!PXH~h7XF%ZVr)j!O?5sn6}6zN*r_mgQUCS`sjI|R!Djv z^B2?^7v#Lb8w@~$0i7~!+H63Z4INFJRp%=2ry72R9Oa3yJQ2S!`trrF%^pQKM+u&y z1hPiW{rWq1&KO~_`i2A0gwb>;u^!{_JM32k7+LVv`<58aGT7A{gqb7erP z9a^*wEvg;0X*y_{K2eVMx5uB12Y=^6s)+(DQ9y6_ap4<@c7gz>TI|Lwb~8kG{f%PR zzm;k&Ak|udVXc7bo;2hJhTQa#pSaD(ITSI6SU05Y|HF4DhTs7fa{=2E4cTjy;I z&fEA?t`6&M4C-zC(beIsKNT#L|6T{1DHRDy&aLD2J_qU^{#1nl11nrRiX4I&4g8 z@7~4t(Z=7+H0NcSTccHfsmU)yxnURNC{jl+QZ8n+zzh_aNm0e%lVeK!H2**UqpE_X zsc@do(H?01yOdCcgZ25rWCmb*MR0}Y(fyEWpHR{#q^g%y9-zuYgc7^dTZUw3I|r^J zq-j6RxSuwmIK-qmDOY+0!uGP2uxusnIOEpJp_VM-*f*{x7}v8$`HoOIIAU4Uxv1B< zP|a(pGePRi3A;2(BS1jMOw`9rs4J*<2I!qJk#z@Mbp7 zV##YHeKS_UuN758+CXE7i#*SNo9&gkjU{UQWU(S^9qi&Be00Tx7w;sm3@7Vw~)ez4lD;i2AjY|3MEZVh0r2hu5y1 z_u6H30}c(-=Y{E8BjeKH?|hxqYdr7ukYnQRVrXVd$edh za=s#ko(hGYLZn0C&7}E(G%`!U^2f6o_Ld!x`R8KnxtMh!<|&(>Knup9552e#y)2R9 zIkb#R?)kyLN$!H8G<&sGskO7@R~ex#I5O#QT;<YqKb>z(ET(b3qxqpv>8&zbAHg3cn7A9@gg{CfAtJ;kWzQI2@N(MPN}YOmE-?Tl213dnm|_W1EQKiQx^-;$a+26^HL)rlOGJ+))OOGKfHOV&D0Eybu1Hs84xwt8Pbhr5B|7L`V2UE~cm59JHJBk)KIL z2sp;GoUxkN0bZ$Nuhcn9FC2ch6x*ALKZr5p#~9k8ATj(wl@-6r%GO*~wr~8O1s`rM zIC=Vx(R|3!0SR_M!W#|w+qI}CHyMXUc?+Yw9XH4Bm6g1B-;!`+t*Cs{dI(LCU?~!D zwC>U1h(7{|d+f*Fx{tlRkUb&Qs&B4t_$J8wC64TpoSs?g07^+cGwxb@ zbbI9W)4h=Scs3T#7A3{Mw%_U1LD;sl?4?9{)HTUQKNs6%g9?K1x2Jf zi*39-654SXQVkYi!6H`FrrzNnQ;Uf!(zhPmw;qqqW=YR9@O(6v`>N6r$8OOW*KNEy|Y(8 zN!+k#(^WWnWvcu#RqCE}(-7R0bEV3)1i7Ru)rH+&Dp~)e!G7lOu^hg{HDkTjHc@&% z-p`LNdLLbUkUaqvsV3IgOC8Zm9qJnUXbwJ_3(&m1>hgN)3){PpqZgXA7n;=l?178I z0~dWvrl9J#q=GP8lurlc)1_!7@#Z{rINwqRIl8Bg-BZVJ9F=-}@_rZL&^SGI99ig# zwS~rc^r``l{3EXD5tqtQi4!Ps5}?F2HJgrZu8kjnRG;WzPjm!m8RAsi&Bg8JE{OTJ z3uZek-!llQrs#-M31z#rtf z>gT!op_=Bl@7LI9s)^SSqgTaXRmlY)gjj(PG5}$l#Aio@hY5rprqd47sT=Ce>EI^m z^{(4oSGCvLd<`KWl9*T$Q*hm6e1&7^DJT5FkhOS7?yP*@Mtq+ z^qCA+<1nF378vsjjBU~F+r7Q3RPOJc1EHmStduXDbNAhoDO(E&x7R>d{O5+e9U8`N zbX)zt1oksa5zA7P%-htZe8(k&*sYok^_t}>EIzT+dqP%NY~D4h_x|ou*i0c0E941w zU%0t{%bIk;3KTO{95Z#|?()%+H}oknt0D9Z4?DvXAxAJA+UqRsb@o7RU%ySKmzSrl zhePtlRsD@Cb#Ew`2@1$kG;G7^d)%&VgH)S%SQF3iaSeBa^2txc>9S<1Ny*fCjZ@!d z%{r{#?HJcFZ*I|UNVS;3EoM*!#IPk8wqzp@i3M+zqx~NRL8^6%Se@b&-~I1v+ugPu z#;Jx#wL_$0ba{F!aSkowmnaBrOpvB zWq(yHguZ5CubF&QWrX0>R#al^jB1Mbl$}ahwlV?o8c3%F(y5wg*>q4wUViC+)Xe+| zoPf|sZCa!@wPgCYY2e#5J+%CVk0<>-CG8}Ho>FC=l1sZCuLt7E^U>nGyFUm2a|QBR zriPWNY5%nO$j8+FF=A4@kuu(pM#GU`eo^H8l>?!pI@qX=U=NKQGhNH*FbBY4l7xQDtOA!;6d@oqistSr$DL~1dIy;s+76s2JX4h(fK;=hnNQ{?Kl)C(yEHJs%rU< z`J6iR5ymK7)YG}BH&JjQXn*x2T}Q!MV)Qb!Xc<~u%1JoaO(B=`(8r1OPY3>u3jPmzPQ*VaqHdSpJ-~MlF524LXE!XntZ4~5{y-gjpsv&P zQ&;G>y0y1)j@tBDZR9QEBNwUD(IgMZ{ADHVvJ&r~mhX3tE59f1$sQUCAIfE!sInAR zk@euDU*e_-%kX#cK?~NR1#3~AV=mY!T(FZZTz_x1~FtS8Y1)locZDV67j4O2p#5P!(8sq zL)YR=-i{Khu)tYR;B1eIrAlPS-|MfdhR{MWRw!nog3CBG&5M)fWsZ)2e{9rJ|9bfa zghmUnXo2CK_{uxldOA%w^st-BVYhk6*}%YsKUOGHUPr9$OdW2f4prdinS(rYHZq_T zgs<1w-O5-;tipO#tX@^S$Nk~jQ+;v!30`#>1!PvWPpXS7xW97N5i6-%5$jgumo}Ea z>rzxE{6fnOMCAs~l%v$Rm1x|`86|IfxTk5?#$Y4JQ3sRXA(x7-&KA_!a*?BgX7r2y z&B!-_9F6j^QNI41ksWEKRjq_mYmci@kLwS}vN5>)M2n58IfO>4VUcRg9~ai9A3wP7 zG7cTqjg0Y_q(fekYl54QHGzB=td1nWPvWU+(qZyoss|I*#DBj*ICEmpnYPnKFO)IjaH!1iV<}x z>hJd1)p5w$fYw&;&J`x{}Lh9yUNVFa*^T{x}bveBG%fw z@|(^-I232CmW9=_c$Wr;CM{Wn#o-U0*$JQ7IigGB_EmNJZZxI9;f$xVkoekk?k037ZKLVnITS7cM4E+ehLw@MhB8t<&9CpdsmPSD1I#}d7NCR-k~RPKbZw{G7uew^0_=%^dA!iP?a!S*D&kaw+&Mw+=4cpW zrvL2aOaJ=ch^u2k>YTskZ2F+mp-2SlkLdA7NVkjA$49T|a=$_7M-lc>B(OVDonf?U zg)a_m@)S3bvDKnWVcHQ(#^D?|p}{?&L6x@+MxeonO%X0Frl7@?jfBg|9dBO@RfF}! zRC~z89x^#e>n#2$?^At)KR9j6KW%G^!glpsM-+AUE3PL5@Jlu9rJ69e{Xx*{713e% zgCPU_=SDHyRGLXD&D>CGzoCbL@v)2O>xp&pN|W|VlX~Y>I2{yDw?rD#w_hJ5{V$CH zIeIL{9*a2^rcc%!zfUW~n<@6<7n4!5iaR#6|8FG|QXLR+2IOv!UwML8o-AbHwd+)E zm@VW$=<})S&!3ltxAlZruhFK}Xj6|1U0w=ZUJ{L(nQZn*WDyCW*LcBqUx1f58&xeDlX(>ok zBR*e}oqCcT)$HHk4;sjevl2(^RlEP%0vU)BVNoL1Ud`Rh9qZ!>+4b3j`kZMW$xRWgdSwY#In7a|?F5-fMVs?hs`Dfg1aP8kM6iebA-P zMBB&@1$!Pgtq+GBJrZD#1mYmhT_yg!dH7X_q~A@q-^~kEuW!t4@q49z1X8UuR^Bb4z zQOk?Osn)pjYus(U%hRSNy>U?YiFu+|@b^tfHAjb=Bd3tvHV3y!g{-Lk*z4u$w;(ix z%?*)DVwPkNlE@@xzdM`fw}sY2=oPNu3YWT*k2r!6M;?ksUVq)}uWi+Bkk=L#*1{5Q z{N7>aGH|XL=e5@k|GA-X)@ZEk*=GL^I4NQ^X|bBraeZm4@Y2>4U7+Ld-tYxCd?)Px z%e(%%bt9z*N~lp)Y*f`SFLgDe`N`6$IJCpaq{C<)MG$^AHTi5h4++Be{w@Ee%~04t ze9tGUI!{!oJNb|d43XKyy-uw9td%`w10gf7vazdd!M??^JuCh^Ogt#J7nhS2wX2q! z+_|z!1gXY}Byl3@Ro+(*@YO?v&SiatInrYVVhFv<;N4|VceoKtFk;C;W|Dup7Qa~4 zXbz!=RG5e4{FyK6f{Uao5&F|%ql(S05L%_ctWuy}%?|2sc~cjSDp&l`jD##ANwk{P&UHlZZ%nv=Q1rfmysCQFB# zB{#+M%|Sjn#XHvCnCE(68~l8+idd{7D`Wq=_Y6xl6a4da>vOyHEs^L*6~7a0<8Oyl zU#oCmt5BEY1AXv-%uSAN*opab*+l)a3Dq3*W(IgOgO9E|Zzl`l_cb4aRExRdVlMSk zD9s6^ISFGI_1#L@J2Nyx)}>`N8VjM>Ja)ER(S-1+Abctl#VDAKckZ-$lK{K*m4$s} z303Sb2I!r=GZXLDaeMqX;U&%IwqHIy=M<#csZHzD79q64@li-5c&kLUuKYuqKfxEQH6lOJ63#ALM&V^F2L~Q^n1B zT45_D8$bqn|l%n+2x-Sm`Of^zbv=fwQe*V|pZA@lE)uy;yKlrR)${*aV&NIG!> zKNpv_;`F6y5L&{(N*Ln5@BKR28~ZjJhmKn6j#_#l@tU;Z$m_^ueh^x#jMXaB2UZpp zZJ6?=9*368nB_9V!&vJ)aIA;1=Gp>Y&52(i^DQdO7CA}WVE{S|bSOrNuQuSTjSlj0 zGC#fZ?EMWJ;TYws=;W(V$LOsTyd^^uBLCgF(R|tt2o2Mug~{DLUGW81$ZAVv1Hbhc z+zEutpH;`ss*80K$D3byhQ;H|7wYR4lKzX6J}8w|4@N?&<2?R2k2>4i(GV3 z5GgUCzUuJ5%9SX{umBkrTohKC_T^~y&uLd614(==i7z>@a6>WQa-Rjxz(W_khb}(o zo($#YB|iNPy7&g2DhP*+!H}_#;$(W&4P12-A}3SP*w;SGuG{|&i8d`vo0=gbZ8}Js zK2eH6D}v|I8Fd$Obee~q=1GFOyJwf=`w&+JpPltSJNuv;kQqC?N^5>Dh0s(HmMY@q zFSSvA_*j#;A`SHvhLTRhb0!@=xorJ&2z^S&p3<42ra%0+G)6)sGAK3Sl$w|$-}X&w z@_L@yw{Ii_#8(CEs{(h^+xbhq)y9nR2Lt+o0W#DVf6!|t=ryxP`lZ3=*)Ar9pW(ah zs#v?Kq2R7?Vek8mgbntffyqIGd1$x79~>|@Ibc2yy^B&n5npYTE*_N|-(#lWn5hsQ zF=9&py8G{IrC$j#a9s(zuEcV>p8v|?StfC6Z`J3vlAGe}(Qj{G2pJGMB*uos204p$ z&wN>IMZ9~!+xUR@kGav`hyE%(y2as%`d+mT=C1?;q1v=iIf)VK2SQ1Sfzp^mUYUYX zxs1`BwxH9NhqRAx+CL@zl4t`NNEKkI0@meh>_qXtbI)-G%H6o-ZkEUxE7`g#sK0zF zgpP}_aS`k5ouA)-o}8$FLqB9g{gwDgDNHPdDOBuPyWokZwHSXe zW{v;c(3J@Opuz_KO=O^a|8P_FCEh03%wtvTu__(k2(B@+hrZy@Pcr5wvby@f{NmS! z>N_B`nS(WROqS+urUy!P7~s%;2lIY1tE}2qi^UarJK^Z1s*6(9sRy*Ddf=&^0J(6z ze!QV~O8IpNy&w@?knDkl24_8^JL1?|0TQ3*&Q{n|m$f%#oyQPEAXKO;} zFxzaH{S!sYigN&Q4kk#;nx6L0@$?ybzY%LXLxN>UgqIqeUn`BABEmaAc;i2}{2)i4m9WoBg0p`<`&uxn8iO~}sW0x-cR@1KY|G|+^{KNU)eebe zhvXN^kmUG)93OM!WR-d_?wa=LdA|`0r)UbTXbN?|PB2kOFp;4QAb2xPKA_2GLccxr zX=u`O(Ms6NVHW?e+}Y}zE%;_Takg4igeS`A$DufpTy-p0ooBVCPfiTQDp4%_?}walvRyG!*$u=x~6C;zg8W}>X^L^GM}uWm8?NkJcD&X zu+;L8V+&L9>mZnT#qxVvkrJ^?K^{dQ`hx#SBnEI*cYZmP~a?-3R;G!pBDqtxNdi$m}uWzfYLa+~moF&L3ka;~|7YowBs z_~Y|GgA)>9Gq*Xi+j5?1%?_ZM^i1PiI91dbei1T%j)k3L@h&%1`Hw%}*MT#C#7=m` zZo-HEW|~2HvUMhej?l3Yx{z1OIDMpEmDqx!O!1!^QVW`l+gg~Od60n!ZCZpj)gz>L zI_RA~;VtMnI$rwI*L#p^5DN=p@we{`w!IW|_L=z6G_Z)TaIeMW`9-rpm9ZC^zAxDAA(m=WDlR*X`$UuyQ3;u3^IS4QpBZbV} z&G+bO(+|E{)kV~dMSx#FV5nrM3J0Wc@39w57 zCUX75A5^$;D#(yuhnCLBFi70IqqM1bnY+k-Fqt7Jr(xy^PUUNT0JA~vvZAj zxklEMB^~O*3w5zZ=g<{wJGHBvO_0TFV$L-=YvO4yaGK1H5HK|Dp6={F;ddQjU?U6$ zN)m@RQ)SJrBJZSIZ~Z0A%ng7XeNw?bsW4?tf1E1Kipz=1?ch1R& zL(`&wwJ4Y)r2}s!+{h~2Xc=W_Vy&%Wt(PGcLnZ$TFaOppI5ZD*um?I~l!pv|x5iwz z#@q|}f$aP?OZEA}LfFhPCU%U;S67_OvU;&^E)M-*E&3oA)tY4^$|9p$&rObeqcN=r zHq*ew8knN=<;QZVD{ofz zltO5elX{aA^(tu0AB_1=Tm?<`Xgga%uZ9eqP{K|qv0v_(+q+jGiO8!yV89zNutpc7 zDKqXJwbibL&~IwkH#MDmhWo6myW0ulNSGcgOmCu4oX@*OnaiFxL+EoB_MF8>=Oi53 zXD8~jb4I5ku{bw8puY`5DSW)H^5d`Eb1BAr2`vkduKJ+Wb5 z-n!KWzB{168&II$#AFzN3MO+;RoCTbv0gY*iPu%9ZsiH3X${8ME(O zg8O8~Y;ZwHlKwS{1tAS2q zvAVlHJu8WZ9DR^rA0+0FBDPrR?=Hb`s@XnP**?qADP?Qdpu&9qB}jE_3TVlEI5%q34kb!JAmd%zmrFUSjA?C<>PuDZrK(QLk=~uZ z(2~F5R8L4*C&-MSdf_8EVHIs~E)*$YMM^qtr=A>{EjUDI(ccYN-wlk>WW*mNnzItg z5}Hm&UJFj#cnzDWVqsM*7Un+iZ`ItuV>q!Dvw2%Bq-$JBC(3=y^r@dAT&6*}5QGR|_r2vN@&!wXxe^Kd-4{*VJ`%a_T0> zKYN#jb96|Tb%^v%|0_87=@j;M2(1-hwE_baD3ZencVNeXlGMcMA@}e)h7l zUbe9Ji(k{4B#%QlG|~b8O4bDyBz3k1+(t z>K=Qcd{tIp01Lw9lN_SCan5%(pI#*+T390a~;GE$TOU<)QG3^k2f6Pw@jOemvyJ z*%xs`DR6Hpe78iKRw8#p`_NS3p{a1!C!NJ97OpM$yHV3X)U=5!TceoVaU zs;)CCill3Iy$(4EOwPlQbHhtuiTcK}N-8gU8lOj02SDDyVrZl#EFUT+mo{m#3wKpua z_eZBY(50z-YWO;&TBOP-l8fQGAORO7qd6`j8@u*rxZZ$^<1z!g%;4`WJr`Nl@hAqT zdeByMP%b_GZClZ8GJr8_Z_F8sBUO;23JzAm;io_L8){PeNCa;bj}sM-b4KBx_J8y) zd)ibDIr^%m`&ErMe-Xj4$WIs_3O9C3i;07_M_oOE_;E4?zWtdStwdt8l;ww0x z@0D2Zm8h43mxkaao&!p&dPfboy9wv$oh^80%Ru|~++e4?-*>))9JRBV?QH7Gj&=gk zPV`k#mOA;Lf~U6r7+O@M`w=#irOe5a^9?#{1kM_i9!lVP6cv z7d#qe{*N6F%(}KQ-|eH%|FVKq8&t6dRq;PoZ`|HhEUm|>Ht9>7^u3UO50dHx)npI# zWDn|ZSr-86$lr3R^H#iG>O@GjSr=>86&KWP&Eo_Ve#EJESV%i8ypW{2T2Q^j!(lRn z9?`{)=(6fI=?)#+vsN327MgPl&22uXq;`a>+^YI#4c}qmz%x1`X zc=n%bs%w;2&x6omb;ht*^OKGwo#e{6iDGiEr1 zF!vsI;~jRhLjpL%kwMO#wyqXRAU>5zH-E$ z(PNOF|J`XnB5y+IX*KM$ns)ZG(2^2Yg=if5LXZA}3ha8jHV_)F zMGKd6P>b^eaekww17sB>sD?86p>jIdeml@l>R@B?Bbd4I_K?>Y6)Z+Y_szLYmgddwQ~ZiNn!1l4da^>8n$F6(;$_#VJT?zfJ!zMX2i=nJV<^07+3aPzr}n7s~j zZ{t+ET_xSF?kFC>Z6e!x#)cUXdY+A)XG>A85FA?WXjty(j~pgYG7*A-nhEMP6R7K_ zHvsgK(i^3LB%s0SI>GAH40L4@P)4Tgm>#(DgTk*}8;KwFlM41pMd$tfCH;ZxomB7_ zLxzkYLnE});4e;FFiu+-p+#XcqR7a9xDPVl$i^DkrYLzE4*lk6@s0E}ddq29pwkcr zr|*ul`W}zRZAXql=w}VuXALn$cn*7kVXx7&VDx`BN4ZZv3z-jB z#=@1^-sX$vpS;#j1kxNg<{dY-qez(&GhT_A-OOFTJ(Z|$Q?FeW8)vxrJZz?b$1C7b zg;|d?=yB#)zIbq$<*UCnt9q&GpPMsbKZ_YyF@raI;87&Mc;OzrnHpPR4QVRaf5gOJ zY2ww5#0Jx<&T3VsO4CL|&?t8d>97SI;b-X!w4i9G5_>6SCN<;)%}C|j`o;I`jB!e$<5 z(H>|~OTV7ARyb>I;gCHk^qT#S>v%KG-k{lgv=(f?79z&eRpq@((*@8p1 zLW&yxfh~AoD@1DeJiT{+MPUQ~Ep;w-p37_7rLk;4C1D2M%!o`lB9kFc^C!`(f2%C{ z2741E(hd?))k2>Q~(RPe`4$*B;=t2OWio`3$7jXhj-8s@Fu=HIYv8vHhoJx9=jZe;J;P3{NA} zt@_F1Ef`hSkZPMItxc|UO0+kK_8v|7r#mk-ZcLC3gg)XMKH~dR{+B^lFzBj}ls-Bx z3%5H=bb!zT5xYRnxS8e&(n#ZG%JvNY{w=H za-n_fBP~wXB-qTLNPke|L*Zz|6O4H3p&Me?q_*RiD`!Ax#aLQ}oCp7LUvS)a)WgZ& z>v_4F`kepzX{!Fnlqy0#Oavb$jt1C?PC2(Zn&MD=T#M*f5#2)8+tv5<$~HoM5M^Z@ zWwo$2&L=DQQ{BOhKTgDKz z9DQAMmbxfD<2}1@1ME#E2g~G0&X*hL@-{lX#5o#r(jRj2L9Rfij&+BR`|bRXs;a18 zm8!2v)(6S@0z_4(a(nBHIlDFyffi<7vBsx-$;L4{KbGdXTaPF z*=$=vg`2f?_rPYpas*%H>WN*Gfon1zN&t{py<-6{Fa$#D6?N+ssdvaU2}mRFkVBwm z!Qeo|e?J`?OJz$@epZ};n~sJz$-Qvb%*Q!97RE#9X+CzEPd6%z<=jpCMI7czTv;V} z4!6O)tez`lUI`{zF58xz2%!yPtU)Zq8uF(<3d5~fxIV#4l1^r)7Z0?rxxO|HuKDLI z;d42iK%WEXldIbLc^vpmR&AxF@pJMgT!GDuaIg^$W0Ccl>ywA?6HyN3GIqJl0;O?Z zTUI+UWKk)Ez87Qf#fBR~UVXmbo}i0EuXveU@tTS(A*-_PH-|89z|lLR$T}id1*u*i z)ax_QN%)jvgZ+u2~XST++Ztl)z*w3F#>?f1g*caGRxoCMS z4vljV#yQB)*~aAZf@7z8zd>k|0BaKP|G0g!E1RoG7_u(mYIApIavMGc*ca=C(AB%p;nRj!jpSw+Xl zHWR|-yb5++MN*ZmdFIrLIYfx{Lu37i#y*rudTOTs)XWD>l6Uokkdk5_$k7!#c7@Iz zSf#4KyS5AV^{UU6?h;iao`$mRECSeB{@L&&kjAj=J zi;7}=9GnB0|DntOp-Ub4B1=$2>ejb?8uORn^B)j;oIUP1dp%|3a~wgAqa#|ke+0eo zeEW72gjOqZsuiib$15p#C1s6zl1k_Jb*Amytc1^J6HTp&%mje*+Cfw9py^QRiFMLU zJ8AZm7awTqA81UHxek1aAzvNQB@FeX<3gY`I85R_wNUi#<0QPUi=8?1Q>aV`@z8siC0>IP`}hZO zA;E%?Kwc6$`yKyRB}s&HRLsMQd915Rw1BfpVd?m{gU;MRXB%X>to(fV+k_Pva5P7> zX(MvM9K+sV*n8CDsAgb$@VaFM5L%?fEK;JLy80xbPeMobv-}g10~$}OA#^}hcR()g zc0>=1kZ$_#zF7TbXi*2ps9%HDFSo)EyC@uX(Yqi??9V&R|AsUF#1}mA6{3IcN>z2&?^k5r-xiNfM0Q zDQBxgHj+a&?#Qarvw>Zx8r=t*xy8b6vBaJnhZUw@>wEBTn;oRh4qj++_7&`SUQ?>L zg%Dw%bn%CJSP!xUL6$gQ z?^$die(hXEELV|pq~(8{~NC!qu$>XO&tvOI(KQW=??3 zoa0H($yK$v>kRHXi_k^!`LF^zX4lj$g!qfs)sNSuo*^5}L8G}IC81cfEr=#PfM(rO zvRxB6e+wbgx)@j&L!jg1xN`c~iG*GKnH~PPqGUXYRn|Tu7E2*V#Vo^OIWL|U4&Vjp z#bY3SuM)F&Eu@;n#*)}ZstFC=ZzVy8ajIpGre%)P(a2v-xESQ~eG`PXD`V}-y1mnn zJTz(i6^KIv4VZxjqcN9FL4$Wx{@Mnind(@kI@jUx%eiAit(DPH)b^M?ex3$1_=!t7e4utlpar)$rd9U9=Xs-zC6>%AvFWp3qlZkVEx2K@n(+O?8 z9ka7K#@F@1ex|D!rmIlzc;QAM+(@4yG19F;y0t#aES9nSonhGOA^2^*Caqphtx)Zv zQ0-#ceALAB!7M*QVgJS#yzw1XD|quBycL!VLl!?VuulyBW)-%3Ox-_(8uz80=%t-A z`jduNp7qu@9J7^>3n>gNg~7l5Fur9oc#J_!+gI(q@CoXyadVH6{P5edpI8OLDE2J{) z+M;!!{H_*+o)cl`M7(p|!7g_tc7$px!c!RGDMQ!oB{8+@Di+Zp0~I_@g`5pH#07-7 zu+SzoXKH|9yA~f(&Ea4<9O;(XPT^Zuedgd)L&q70j`LUOs6aSWz1M>M#%Qgl9?&IVxbU@3vUy4HyxEdXB zorIE~A*~cKSRb9$KRR1djwe|GAS*zMPVZMUF3t)3p8@RF5T83FmsBp@4WyI#{d#V! z_uI46VJjhT2Uwy3xgt!Fjv&%efYvR+kqjJ=36MLZ1FQYDq|6ac{TU_fjFJ#l7sa7x zjU{L0+{t?^B|Vnzs8Y;n*ONxmlwBcURMBa*}Fj92g=cRd48#J)ZshVKY~hw67>p zuXgcL5HB4KinMI-*Lda@2BEohUM`)g)eN%&VOAV;c-~V#_jQa*H0)<47t7@GCoFvS zc?V<;vY>^NrR%fx3da)CAb$0rL zPXE!>X>J#9mmHK1sXoxAJD_>V-!caCN>_7rvDXR6S`3P8#wl zN|_WJkYd9}N|}U=_Ckg4nXsRIJgkprkh;7)_vg>9-|>FFa4~-2G8u(mnC|?WeQ)3b zTw!s#Se&k8Yq;r?*y#6FIP|5t{!4Qo%AwgSMXJT`>un1Y4x?)eEROEur~))SqD|AO5&>~;Hn9Oayv?J1_{oLuZCk!;n# zU)C>@^4tb%#`Q1Qt1hxfHS2;|6-%%oeSaIV^r3zU_k1epS7r0g&o3 zRqUARSntRGcrs?U5F1>ho^GSwXy(;LZ=E7-o=k>RBQ$9dnp8_|p&uyp8@1F<9j^Vb zedAO}HB1=`Q`S*bpD@^$(L|WUnYQmjwT|-VfB1HL_XR%KuY3vJ8HE zQAc!9F7R*A1Psar{$;s>EHdz~*KdP$mC`7W8g` z(9hQDpRK7f<*Glp>OWe&qpxpXp5Cp0V8^p~SQbx@7HD*LeM}4kXTH_hpw-zA35s(j zPR&|Z4ne9VT!RuW)f9hXJUB64id5{Ump6P4cRK~4X*{zu-b~8WKXV4poJ~-Lk=gZo zFXjDAfDF_rV08*w$mt7bph2S3Ad#R2b+r23(WD92AoLj>dq!ufweMUPUZX)M55lcE z;nr5j@O{!F(0k$2GRQ!!K)+V5_*0TQNOIRhj-68-OFf^P)<9^VuB1<{(%WfEaN1IY zjPxjkg7{A!h(!;?)G3Ja0#RN9WOU5QcCdPA^%U~jBEniky3;?-H!#ldHp6+X_GDIj znxLahl9I9B+m&6AfjCWCoF;X%i1r21SW>rH%hXxoUvI;E&{O3q>Sk{-B3I?S$^ zQPX(Cmbr}(DuY~XkSk{G`FqTxe~w+oUmSCm9&`3W#{xX}hR5=-N zj^S+`>iyxgDL73=mj6{*?`WFs1fdTF{D*R?fOvNhPpSgORDIV{NO0Xo*iMSn*+uHq zu&Ihgi`BHr1idk?JI|W#$KyX8+%VLwpNC*zSpUIpbl0V^Ri zLl?`?l|K41&VMA|r5T4FurNGe;g9MR_<2Npo?h}FG);h|2@Jcx8~>3Z^C0qFwYizJ zxlKherWwQa3;A0^Ak`5CY(#-Rc2dYPjUR;vaA={FRVXz>xA>%`TlR7m?}y{t$Te)_ zQm3MJJg6P7&$Lhs+?Zb6Uh}Iu2HO=5q1oEBY;Eeb=)NDg?>A~3Lt7v5dvv*}cezo` zNe=_S!+_E9%UIR)Re!BJ0eP*VV>NU}^Q@JZ-j#fshx2;SntjmP0?9oTqD)W?;@}Te zK-_TxcbtUi0)xu!5YTsg-a9^ZlQ`i9PPlQ<*+Or!QrUr-1(1OsO4tu2oiQhDOiV)5 zX5tKd(`S4mbD0!(9SgTpEQiqhOzb|BW%i2utZ}Cf4TnCp=RPHin|_@2)K3U%AoQ9N zc1?+WG;+>fZeDK+4lOg`m60VBCcU)$cmBcuphq~^5sviGCTaL7rJx5mwARV6*2y1* z14Nn3zn6Rd5&Y@W)Uh;mMswuSYYt0|rsB{FV|InH1ts!1-IASdY0;}X=}YFPzQl#A zCT@=7JcAq^R>uyjb50#tA3L==))fDCP|6=9otUjsYfZ5>$mx>sdu!#P1o8^OkabD)gYJB_P!^$@5w+L%*EM{N2agQg;dY7 zu(K>Z>#Tvqu7CB~ajGQ_1|<%DNM;_hwg*=N1d!@Oq2QsMWhB=Fm3(UeXcG|0GB3+(K*Q2P-4J4ZUGr+Q^493__I6N?_DcC5Gv3o`l2WL&d4a{ zvv|qO#hSJddQyO$6o}3W6Hd^zHFR)jm789bnA!eI_XqKBkb#prW+!#1hm2+u z&}?E7k*2>P!AU>r+_A*Gz>eP`w2a3ulRN7Fa0Wk|xky`p+y;noP31CExzsz(4;lC& zqoY&KJy8}Xa>ml_gnWO+!d|fqP>3P^V%WiW*kLjnSNz2>nej2%WOM`fdNO0Gu5dZz zs9S8+Eth1Z$O{yaNk%Z)kvAse)2nYR zb*x37l2vjcv`@t7lQX@4_5`0jb(03MXRb3W!^SK>rL%U{WeDxmq;+ai9bm%zK$zdC zzl*`&>Em4;uR>ni#aO%8LT9XbciMsBD>$#0ysR&gp>S``KU4pa`4B>L*jNtkM4U5E zuW9rBcpQ4)(fq#SY&3oAm-#Mpi+%y2nW|W(Drf%s__U=9JPFf#g8{#R%+_TT!ey@f z@gMZA0(MtH=UL0D{5ckm0EcGkF*3<2Vt=(QyZuLW3#9r=jJ*;Y9gGfHRdDtS#dkm?Ci zNx|TBeC^K{kJ}-%i6Ll`bHypL14X1O&SBNe)H$~Q+d)XCFhwj(k+*TjoqhfiAHqJE zYaq-ukfH1esBAdFYosbCQk80A`yvHjNNunI7MPrPL3s!92c@fE=_&?DZ;HPNH!==4 znk=U!HBPsljI^ZB#_rmrk)jScDptpe)tMHn&zr>6UL-=SEA%-P`c^2)eume-D~^$`gAC1yP)dFwR6qxxSw@7oIhjA>-z6?88TVVpy=5nVDO{8po_jwf;@ab#L^`%0Ul2r=c3L;vVY9i>@35ILF%~9fety^SvvlP) z!nAgF0_W@mD^z=2u~A?;GV1wfq#k+yD(Kb!Dj);#Tr8f;w+-rk zwIuw{5uAY@nW#tRj3Srjcx9<5GArRgXDD+r%X@8R-#mTCM3>gSwVnIx9eGhY{>(}W-0OKb+!6(w* z+WhaY;bjeNkm{SUv^QhLlp|B0ALt{)q*37?g4Y^VdX1_91zM{IYV}6Ta^@b1+H+Z} z12S-lk6q$(t>)TQzFy+#fHP3*DyVgJLOw{vazKrHK#jU6Dvdy;Tv5M!R^Xl$8zs;C88F-XYop3eVhV~iuwo5%oyF$k z@%hRU{6&-jFN(DKtvxJKZr-J}lj!GbZQ5&X>Oj|cgBtHq!?xbsva%hAd64Qo5q3|+ z4x=?WJbV0o5l*$xlUGRU!|i;JhdbTmL+BAcc7$&zSg=FU^i#(z92(?m6687+SuxDF zOpf0bs1F&))28KVQzOT#yg-%Ls6Tg|{xOEJxf!H7z{UpHJmf}$Q_XP_<~YgFiMQ~( z$Ii%Ej*w~(N7y4*+wP1EoRRTQPw@%xo%PNOTE%s zEgShm=-8$tx&G?~n~7AWN6I-zUegEH^mWi?(YelP!{YcqAoQe&cTz;X7wz{1`#m{m zMSuMf_C)FO5(quR93|6Z|Cm9~`Tlhc9Fp70*llHoeu9!~Env*YhonQF z-Jx%R{=VU*UQ2fr?b%86^M-=n4F&3X@3aXxEtm5;*&HO3Ij>Xxww+fuKNvQ1P#rs{ z&Y2MSY|EUCOT5wzz4I@3_|%Y7GL#HJq?@rs73oIr(5p!0o^{My5*=#P7h~U zrbFiMs9|^11mAz2a^LZ5KA{*7*2f=L#dhxUe3B1XcvBh3){Sc~>p&Vc{c3%n(h z1RkD2W49~zKUdo7?$68f>><@Uu|b{Kk1|OqULeIwijDD-c0p4P(4myIrG?#lf|bDvzv5RvM()w<6EVMRjF||bzJ%5%Y6ZH zU3g+7cp_IM?WvXEDOn`#!}rFYeGaQ(Z%Q~=3CH-|*r)e~8rRq0-zJVTOB^@Tq$51` zh2qLT4BV7I8tmEyd(%ZX?4nZ@Q^nSx*jhg~>B+v?tK%k^yuR|$W#0ivHJpQmbHpga z0#5a*lk};R7gC_SdlA3J0UUu;JLrNAxiUBT)*#=S_tkmBG0TM9ge$mB_d z+Y;86Lg)hy_JAW8?$DlnX3BZOBjm<7{BcE5w10a_GQ78y!>NBUmiA&S)f`rArci7q zLNO^sGv443X&=-45S6*7y#BuxrpT$2^DlfW1#ijAk5a({cd>6PZ04(yTZRj|-+HUSG!UUXVY>;N`N4b!mvo<(q?T6x% zme=W>y?E*j9L|u5>LC+Zlr>*I5tL60>FY(846f3!BDFrV)a z^8H7(`|nEHmAlU6{YO=q{zUF*8m|Z9$qNipToY8wjMdAGsg}a$6Tx#bVxX=!<#Flm z7jQA2*WsO)D<$>W1bjB(P}~82xq)A99FziPTXxT$^S>JZTQ*#*fy-atCiX45>!^&6 z-lOrNN8_E5!K3o>|1uQ!yob$P)23aMOX%>`Q{k(p;M;<658b1=!~yh{AGqZ=n$RI< z+|4)_uU^>kb|$x7?lv9h00PO|^mx~ceh!`^|E+l@mce9}eKcNB;=BG0PBp=vlVEQp z`Qs(v{#G!%+sxl2c&E~CVvOD~Iq#TM?NhJ=2qvo)Rka;x%&=76O~{2_Rg+%Tsgy}d zHU!CrMwFy(<>sK=+z7?<6&Ks_s}3sfCVtohT2c#5^6?kXWuoUY=hLhI zJeuops&2C7P>h3<2IS}=NBB_gigRlmxJ8!lW{iF0w<=Z(Qavcd4hmUTHFam>_>-e> zsvYj!4tEi^l|1zNmDz0nPy zJSa46n+vJNXkalKbiU1B4_95wAUxB~Nm=K}>gzT&o!|Zqn+Ku&BCKD;V%(f?%J*?1 zVSD=K$^GVOgO)hDt`KYQj+*d}nvAlbg7rbL{%Cf7WJ4gJ{WA4_8I{+F01!b2Cs(xy zKe)T^fD8n)v0yf9>5o(Dn`|B$;|wG^auXeG(9J?S#QoK>O<@rFlz}~ENEYqWIs3$U z!(AMjW2c{E=YxEbh1k#Bu6u_e^adTfK^IQaUgVR#_>UqS`rS(M-O3#q6&0DiYLzWG z6z4T}yn609oxSZO zghq<7NU?Zdz-O-yN7D&!)7%Nt+zDRDDy6*s<%Z-lry#UV2W!(2sIB@4#t8ZezxceF5qOHhTR(Eiw61B(@v@zNOcn+Tj^Grb76~SB7}x;#UWg3w`yddMkcKP zq_$vq-CWJ7r-HZY&PayP0Ug1B4)wTo$P64Z&%G%STCKpSmaEzIT@QRG zlWRDy_20ygPKD5xMu+WW{q6$*3kDQK~lwpe>1)7H7cdZtPID+rAjVeulm*|)Ido}^&H2!6+16xlIQ`WB6DM-(c636xXRoXAl>&Bd*3rTqh${S)QZl z#f4|WJ;Y#L;t4MCs1y6v8N7AoA*U*zJ5ygAkGF!*EM0b%F7^0v$pT!mV4}=VR=>h~ zEivCc#JTGk3wy>AR5BOOxv#XIP$7MCz@O378TgByariTu0IvI_SLMCC{;-)aRh=+Z zs`hYD3pN&@C6;DD`n!bvu^jJR_-A-`y*p%N5)c%12xJN z8f5}x&cOQ_>kDGZYC*3nbWSgy9|VUaL>CLum6%vY9>_m`mvF<3Gt-YV^Fcoxq-fBSXO>Lnn&bw8>V` zWb1^~rcW5hT*Qm=U^5|OX(4096amrb4H~^ibvt_}()W)!UINFclZ|zzV}>@p zjm4Wua1tgs$-sHdf4utWW5WL!+c`1gCWL-vV_(_g-7CKKWt>?_oN{uVq`6LBNIl#w zP+8M@>K+`UbPamC-1RHa2n5OnwI^ACBr>S|c**uzE~<@?`6P}}l3YQC&raYoS&+f? zSpmQ5QxoKY9%}kxw{ec5t)NA+kDju?}6qgA+TvmItL0R^xsP{BcDGqDiLVrV|(I?IjjtkRl^Uk-Bjo*8|7N zT_aBVEaZg00fYuJn1Kwc+rwiU@Ysfq5_c_pbwt7VPeTZ;qBE=Ha_;Z92K&h}ct@n( z_F>+}dx@X!_E_5Ou~c8#VsnLJb15nci8CMT4PwbG32Wc$)St%2!*8<`rCEwpjnQi( z@Y+a1DN6Ll3cRtBAiIi5Sb4;Xd6VE6tdE-D$YcvuoxTjI z4Te&;WGZs>7)O*!%pG1S^Lvt#GQ> zrM&A>J9Lmg%1D_|;T#X4SJ~KAwto1EXZA@yo2TQ@$Bssi9VekhPG2%*PB z*f9|+bxeW&y{O6wIP|9n_ov6GUXk`A^y=@X=k^ktVm}M(X9@SUSuXjU!G|G3j*sfH_J;fi$kKlbklU1bo1Q++34y_1Yq(YbfH z?GI7I2S~MFlh!X6=r!yMhRL|Dw2j9%{{5^QQhlh1Jyc}>o>uiz*4z67r`jszwUSv; z_sewd%uxFTp(ix36B@eTYMP(zwy!3x@1YWAD5(@}-*&0+0@=+sj zR4z&_)f%LdQED|So}IG%OLZSH@^va$or=+!Y5T4|S{6+xmqLwALyf0Xj0oLUrrlQ4 z^_yoFdo2k5ZRZWephvfGb;Jt+q$*^yAg{MVG?0Tao28dI5bgAEQ-lJ>Dsc@<$uyw z__x9Kf?(3gq4nir^QT8A?;AtIqfuzeoiqlDP{;cls=)}=pw2*|1SFE_AEWV9051+q zh0XLZupS0$YQo!!Y3bWj@n-7mxOH|mDEcs_x$^$%d(+{(UK9u~%B3XkbpyR_e54f) zqARRf%iaQ^#cWBjT;;PDj^G8EKwo^MU3bsk|DdHhj8YvcuMwso!c_Nw>(1#n8}$}# zs7~?A>iiG-MuqoAg=*(bmVjgl2YKtD5K3aXeqsnd$@xjWv;!~gc&J;P>q8I!{WlPf zzzY@Zg$nD|_j6;iM zdc`tNq*{sCWwc@QKhbam`jzSZayr63eb7giXy|pTT7LTTNeF$as`FItq+hBBN=di- z&V0^`pF0yFw4A{%XHf4RF?Jxvjv2YpJ0>{&N&d9cf4mM@e+jPJenoD-B30XT%NX2} zt0$Ce26D~V=pM+f@t(%jy$rv7uOND_K)pQYn1CD;0maVo!xa2573@1&GjoqZRm=61 z6^B=qT!CZsN(FnRqJ8sfF-LIdDRDu}m(cUcDhL0JgdFnV=fh^=HEHph)NDg9Y!zPE znxSJY{%xWUNF=L-M=j`0ZS%MaN8;L8+BLbHw)MWC-gne<-F8IpkBuL$!)8V_Xd@cb zW=h-@O5Dwm;RA0b)eofljTR$+Z1T^w>EJo+O}a9cuB_YgLV81C)~Zs1BPlbHEcLN! zaA6VncR4sZhr>6$f`mL->8s%N}H&v`#TQ&5 z6He`1vh0z{MUy~c1L#)9x|Ow`xG+4;niXhy1YN;(=#wEp0$cR6tmu$i>6w6w8Q z2cIY#g(w>fRI>*E_P7r??lbD~!C^6``eZW5>n?Vk9$-HhxzF$S#PC%+7TC@?lIFbl&5aB)g^QFBh_g*zN7E-;#!0s^E zGwN2X*%ET*Cr&lmju%a;Yj)6Bp*~;EL8?D>1wVDEI+$WhP;ALdUhBNPD<$XNq&PFh zS3NlpdQ_8kRIZ9+sUIjMqc#qwt^4w$ABW=Y9ag~(tBBpsoqI|v{z$}|Hc6#TQZMA9 z^81mY|25TLfmEv$BvlGj^KOF_G)P4VI_1{8ddABf%~p*oBX5nZZLx z9^E-w4xyR4f=sz?#ae(^3*P(nt5&akK5Tz*x#`<`y7wTjkNMbRzOMhg5W2~~2eNQp zhh3S&t|n-ZGg}UAyy&eKi}uHWz&}Y0vvkYLxk5VMZpBcO;slI!doEp z0}K1Wk`B!)Zi+0LPNek=b2JPiHM}S>2k~39E7RNM_QF5|5NI%31Cv;utjVQ0E2I~i zFTs&W=hD-;)Fn481H&>MWURT?)mU`PHXn{ey^^?IF7Wi6Avk9!MA{L&ncL>zwz&|Q zN=1X2fejYrkfU%R7B19d>?<{wjR0BDxX7H*R)H8Xi z9Z0p~yj%IvH=ubz>?$YqF)L=igj6qZu?t-Oy!D;h#&b7!<5WY&i$cg`2*(T(rcZ5c zhE)5U)%%>OI@#<1kR33plTC`SX&QRa0!KbX1q)H(yDn@`uv@>HaC*-%7UjrgtSGk; zmD@NYtLhX#_U};@ZIGjbZ0sQ0*emVhG(p}i*5Srtw$lwz+E@t zT{oGA#&7=PXp2GuP8*)g9q58oFN*0G#ne^OIsvp!&_M-Z_6%&2=FjbhR14WyAzS2q zxl^2}nm{-nKXuf5>NpylYuCO&+%5eCsb1%EugfJmX>kQDu56^CGoCTywMNVcgnn0H zeOIAQUx5@9kjCOIYubI&E`VTSu#TxPj;T|`oIb%_J+5**jruk z&)Mm##uu#7#b11~kbWZbx}si{3=rw5_Wm9gi_oNsLXPyI&q zM6}2Wef|lu6zv|~Tje&kC4_d0u}-lis!@$YuX@>B^;(SF7ClP6kM|5&Luj8E>l0i5 zX7ro??>!5M14@~fU76RP2)c6GNLv}pF_;hxi3}`}!OiNMJ}srFkl^);jo^!o6H1kV zzsRu_e*O5+mzSG z4-^S}r{Yux94!XOoYNP#&OGWDw?3GVw-w5I70Oi4=QAeYjGX6lsyRp{J)fuVyHw_} zayxA1wHo$Xjh^E#`rq+1#2eK$8U%X`dvv zfAXDWk#LOKRj_syZI$JP*1>DKh#Om`AwAR3fFk$qTGQ`Z8!Rq&|MPf?vDI;a;AR2-nuda_VXIk@EVh< z-Me8AZrJOicp0R5Aby-d4*pOTa>X)GEE6JKMEOCHPLWnI9FlAXmd)U4y)|FtSQ2c9 zGZ1Vm47Qa~mQAUxu#`-;tuQ?4g{iO%PVhT5$vZXbnYh9bR2YgVcgRdDkZC1CTm0K~ zlN9}%9>R`)5o2G(?)Fi;3%vUO<>Bq#@|tkVD+r*aZFM~C&C}+3*zGwXZ2O<$)4Cwt6_f6U4Oxre9yezLGUqzzI{VDb~> zJm!zsgCq7_RG+PB!u_@x-`~SQ`k;b+P~rZ?+kf!<$`yovNvWZrRLBXcxZpR16(I5{Sso*1`&@hc+xIS#_b%>he03@-FRc6%sU(SMJ7TGR#FDCv zi1r83{-YU|2Mz~o9Np6YA60d1P+ceAR^mVG|C~6poslrkkjYRCzg{X{r9A+lp>!;i z&fic~nsNC|?+P4x+fsDf(ivTyDqXVT1a{xykbLEHzsia6WH*pZ=BqlaF!+74zETJw zaF21ZV_ara>#k`J76cgLFIr@r7MT^g5iZgc_nEh_LI}xJqJovE=zZJf%iWkfW*PqC zm65?KBR`7i=e3o=Yb!rw`az}oh#@JrS1-4xx<9=12QNwYhn2jcg%(q-AV(+J*h#kW z|2~VS=2J_qbmO!Td)i z^COdLg*)f~4m!|LGu4K-497M2LyppQv2}M&nVqr*GB6~>hJ=jZ z_mfo53=V$48F=Txe&=C+xv%9GRJa=mCl}O6(f3U;wL9QI=Z>Z2%4v#zSSb9k(AWOGXtn*3Tt42+ zWp8lVdo=sPX9ZVJx@;HZsEdnrarqM0$960E6Vq^L?|4z~cxR+#vYEZa=JSRN;!H(7*Rw{+Be6({U4r;&U?03WuHa?Jve2b*-`_rvAPUxKGJVd8Aa7>x zklfT2-PEO?bnjY#yA}duSGhj^`21DV%OG^W7Hz*4H3`&JKX8>y0(H$PgR}kY4G8_k zviQZCOPRiSM-cC5hWh!sm|ZbgQ3d=EULO_IQCFGCB@h*zWsG;S+4;hc5O*mxodv z0#n48R-G?6`iyeNN1=K`1jb6|qc3?wPvy+x$Ue z4o>y8q2RULj?-%^=q24e9{nc0JT3GWn-bbu5pR?;9wNPSTxxmIQu+5e?e%sVF zep)sD;+~`BJu-i1jP-qwl0qHGQ39Wyz^7hiN?k#zs}8z!NH|!b+J-i-sKO1xqn4p^TnaJErho%WawAEq$}z=Q!ooo{Tl_w8#&L$3?q6v3$`)Y*RMKFN#6Qu*|PtdQNl`<7`K}ek0tU3h#PmFK08m}0u@hq za42ry^u>E%KV!6MG1}CVQld9V^d7a+up^gR-8i@pQvJcielR5k&)mMuI|82JRAU|V zV;x5K`uquf=ZkaqL*}y>yev6=MUX8Bvc=;sGt=6_<1XRf=GuZ>TMoKH{T}#N==Yxe zkfTDTq>xEH3tzVf*X>2<;DwZlRLQHj`zPpT#6aec z>tM%q#80Ov7TuV|BxKlg6X|mkuUX}1+&iXOPp|L3d;ECODM&R%g_RXi#-#Zheok!1XV zD#$=NM_4ZBs$Vn?6p^m_|5K41`Z%WsLi?5Y{YunOrRyf(x(OFuF*@yiZ~S)u3xvk< zII(iMYKxsgu`>(lYu_c5KIOOJP@J_V4D1O*GSMx}IrpU&7k_cVPX7Ywz@5gwe6LkB z45`-ZuEl zzaRsZbgYuj*iaSP89OZ@5oaLCnjJ*uno5a&$>PP)_7kF`NyKWBOEgmD3986MBOl)% zJw9BdwV&wL4>tCL&3&;eA@1JfM&f>(?GJHXX z?`XVmUiP}9OOtf>6M{Ed4U1NzkE={MqW|on6n{}*%qlQ8qd0MdIkUo?%}|yUixau? z-k6FYM=1gef2Rddw<$wAq#)_h^nhPQ2k{j3vVbt2Yu_x6<#Gk(UHv5m2fbrxePN=T(e zT9g)vk`|&;Nkl}8C`rmzQA(7`_P_Vc|8(zto}S0^ygv7w@7ccRd%kNF2aDoZZJANo zE0FQJacHiiZLZ@gbWl51@cT}Gj)KrDI@lE*J>;W-LnBSuk)~$IBjZweZb8wFqmcM` zZH0JkYIsw-k7B!zKGHPe-*)+fF8_(z;>F3W)xr(2u$yQu7R}}LJc>CVTNF+Ban&&mbAns^wD_p1E`ewi?Xj1k?O3?%RO- zHZ0_8*I7UGDrFK1NdblrgjREe=FvA`+u$j2F@ z=Z$d!^1a3R-fqb4{_(1$Uv^~F!{r-L)*GOCgMXESuX1Vus#FV*O8V;VE!??(wf7VF zZPFBlq$$*;PjFUDaMnjr&v?Ht{lH7ViKUmduXN}S7=7D+NlM@!&PlSBj zGGyN}G())^&=w$A)?FvYT_>s={F?yqCV+)J8x0>evc!vcp~QLy39ul6VD;$S){$8m z%kdvRxQjoyyCD_5{yLSP$My;!G*b!7RAOaTd3|2M?0bMi2V~pu9)$A?ENYa{ZNAVZdFbhQuG%zz%EZH7J;Ud~G{MD2!vI>=;sSs%Ld| znf+>ONPK~^tU%eH@|5Z}2HnQgTC8u)z+1D4TCAUhPK#v?cJSMe4BkhYvwNK!)X|c6 zJhBCk$mAVks&j=ACjOAbcO2{;hr3feZTXKWX)K(?vrdAuP7dhycyYX97x=IOLMv3U z3RS(?e{D=rN!BCW=>`nh1BPa3j-HR7d-u9w4V=zuWvyyus-W^l3f@RH&>;|deVS)b z_bVhmT~i^QR@<%LT(RHW02SK8yE!!toFZ+dYR3|lN_Osm-BgHK6|`En=e)r=ves>P z)|zi#mU}{p`|KeDd&rOuvXi!Yx^xmsrsHziak)Pw8Rsb**(n=;l#COVHy~F0o37v+ zty)gGB`7DWVyhZKEfNx!nFTJ}T-km#U~nD>gP?ngBl@erEG79_H%LQb&* zD0bi>Xw8|YD{HJz!a2%Q(alq#zWl$)!56tUu1^&dHX5-g-%LsYLpl`+zdK|0NK^_?Yn zXDL8#p#BRz#daB=;UZ-y3o>Xz>q|L!Nh>KdWDADKl0uqZdKuC`6%G(22I-1}XzH0` zX5g5a5Cy^9G+WeRZ>n;D;GIVp*bxRN%7j_n9MGqR|Ij1j_sHy!Bkru(1|HQ7Qy}!P z9(Gud|Ju&;?<}=9gb}LNQdCPSLvA^$4w1H_^Gs)l`46J&gsQtmaspCBMXE>4iUQ4U>} zjX2B34IR3Mrw5*{TImG4sb)*6Y44S%4&W*IUWr>WRGRhYOb9*e%sA^z^*0+00HXmC zbn`5k?rbL2m;6bkb<@=)IHb zVCH_<%_SlKl8`F+e)0sL$nbVEBcXS&N*IJ*S7KdPqAJ-(rC?M#QHd(PZNOvWnFt6S z;OGxLk=6)&IPhOkNFCF_0SKWc#M5tpC>IQ*n0}3|>h6!hi zSH|*J#sTPwjQ`MYCdXs|_iy27iUe4ZfUh3W^Mf~YR2hff_YmDDBX~Af zbalVqrVvJOo1-l3D2s<3e9*VWVT2G-1MP)@q;I>{H?t*bjp|{k?xQ(N=FW9RwqQ){(U1hCb3bu3<;n>5F9``-(j3H^ADp`gal0ZElh4&2l_$riy@ zZ-|9A#8g+q3*O*@Hy_E!AO0Axl9*b$5gI}Z~7P>4Mg>TTLR zxoZ4S`%|2NvtI18US_D~Bg*UtFAEkwh?W^`&<+gRagnK1k$rj9=;L2ttKB@TnYF)gD)IkE`2?1l?i#$rFZ_ohN2emk z-_S%qbx-e(tc-$dGOjEfSEjD?dl`5yW7JyHl2I#Gz$A+%g|46q&B?{C2s5Rw^X^xtR5wCNnm9gCx6e93qn{YCgHHXkPRmG+7Tz)?<19m36^<(a(K2^ob?+iKUh2 zi1(*GljfA2ezI@QqrfYWfHqzIHd=hnOAGLljL(td&NCa1T!+w7HCCw_m79hcfG~pz zZhC%M#=$tH8aR6$s{9UG#Ko`?7&hWkRK3A=AlQzJ;?8@YG)jEV-G}3>;xoW&K+ZYX`zriFjz?uvN`p|Pr1tSUEs!{j5Ef)PkC;?wRx5Ng9mcVKMWr+U}ZV_}4h zab68Oug1Qz-ZZgb%QC{->b()~y^#%N;DL6$Ksy^W@QQu*>#WsP4-&icIS+fzGhf!# zm!BG0qk#X=;cC_4y4?PaTJvlnXKh`n_Y=X7ngKdGr{v(2T$|#oa?KiC zv(`q=DybUou|4Nx2Z@>3&lc`yQ-^ob0i1N;qeJj~;iF*QMn?#JBjCOfP&2H=dxCgR zHnIa0R465u&31v%MvkzNR#&0l5%iOF74F%WetpyFcaWH)93?DAN&K^g&hfMRU$x>t zJT#U*H1?)k7EjEiPt3g0Wswp3YTnJh>2Qv^RIn};-n^yLqK^bECT@T*Ltz+s_ZpTq z{uMsQA402HST&1v_!VzO-I2FOIP|VP_pZGa@*ucacS&;S@q9>8rZSeP%st8+|E4On zCmsd&br-{X`@}y01LlHvn1G z{Qm83cDObw!&c*zu{dSD;CQn_t=CUaw%V$Lwd$~tY8h{}+LT*uYK0WZ zPjx1l^HROGd;HQo20LTIH5R;j}7 zk*8FZ?MhO|p`kKfC|Q5xn|L7F_HGY^zGP!B*<2&v<1a4Fok|!)gB%4xjt*!?=iajv z9?g6QX}!;t-se(f)LYKrma{%$E-fc+HW?mx524TXt)A2Jwx9O}=gGY7uf6Qsevyqr z=rJG0F&`>(>6r<7W=F&_K z#KQKwGWuPqYX6j(Acb^h9k*idn)4U;5Wx>BwG}F9$(f4H6^qSv<6s!CPJWlKP|WTJxE-;Z{`u3Bsfq4)Xh`+O=zS?(aq zooO~;t}b@UdNDep^hdb26@-?v*ySuL^rk(yY0pHb@B0t`d$0Av20}yBbwkvt8~BqH zd?Hn^J5s*-$M}1~*}EvjE()b8%}>+&ytaMDhc)IY8}sx>E^%QanT?LW&VGr&&`GlWjj;A1pbjUyc!12eB zExQj9EV+?^H8KP#?@qZK+qc6K|KYu{_`R_kg(Z)hiO0>{5KFeTurqpX_c#2uRT*nl z79$sO{M(aq=}Eaa^)51(UNiSb4&x}_H?jAUd>BbSR1d1&nV@&3E_xrKg02KKjbog~ zp*rW3JA!h@iF&44oazUvzXn5!jw@rwm09yTTa$+hor%0A7mc|Wjjbrwq7XN3h?^C9 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ξ|Ix5>M}?4o3@D>3w%Z%u-7z zxE?wY(i?r`-U}c5MdS)Te$d8z>~w1otYQQ4tf}OzY4^-;M#Gj*+INnC;2FB@@1jOr zgfkI{oM6wYe(AZ*$3d`|)i8LgTJTo1nMK2MX-HGqcm9MFztg}gWe?BWNX^>_c_mV} z==h3l^tiSxHUl@72hAHSiROoSz1GMW0$@POU1rRynZ$*Rl46K&k4969j z#jdfH)Yx{P%x-^_!{;r>1J9ZH+7?sw7E=s=oE0!4Z5h7k?DEqSp-k`JDejl;l2Sh}Ucv$vn#|_sNK>S3X-pxuvafOB)kk zsp1j3f{1`D5AQ7CePq+`>qyzJBXNcDS-cnftA$IiKkOevQ=({7+EqxqusMs!H6?k# zy8*vk&I7>~HvOuWsaGw-=hre4&wQ?mOka3t^h*$|pd+kn7wHmSu0rGlPsyi$8nWdj z2tHv$woX>AP8O~E6M~0BfBV^e@8*P0Aec%=;`>$P{VJF&h@2p)_!=-xl<*YcYx4 zG9Z<@zLMho$FhGO2)q#1*Y*cg>gKCPa2UE9Ajm9W6+;-Krn^%&nMXBhTmGsOOd)yokpaC|Ha{<^MMKGj{ZRg zV}_(;M)#;GVh~xI&jwrYZ13-q$ry!!LA16e*A*;l^@A zu7)b+{mWci)`4IP3*0kxCuQocrmW`vxclhSqqev6#!Vpji9VSiSrQ}*{vMGNESI## zR~v2z!5G%$qp~tbWih&nkxHTsR{Ljt*}Po>?*eN{z}|5Idok|3pnw+>8Tl8;r`2wU zf}c}o<*!Nnh2wjOT*0TGrv5oOaxW0C(1;|{iey>=5s@P{?Y3IcDSHrzZ>ae^2PY5U z2hZ>Oe;oPYi>O=H4-P^#@3K6`F|)D9%;rL?7KO z-e+)n-iuvMfq}q_W@&=sYxItm~325xELp zkJWwhJ58vpHdZTMV zS#Dwb=B0AhXX_ zNb*ph@3Moq2rp$Ias`jt7Fc;uzb_CIXq1}2nB*^pMFt{Ae70cBN6VlAP;wD#a+2-X zBwHM?MUp$T$+O-4_tgES1%jWc`@5z}uBpNRL*xYSJU+g*tG5mada$QgVXRnTj7fBl zfq29t=XCfj<;tIdcar&*T2=L0Rdkali9HQ_%R76gXf}_Bf{R87PdRuS3El?Viiljn z2haUANPFP~5X@$Movk9DE%tSe*w>eo0wkR#zk^^r?ZbRclCKGUh{y@vTt4uE#eG8{ zexwegOqY}i=LZov;+*zbkIWPoK*`^9e+-*PqxBw*#z`7AIGbA8@aD9r@mo!S7tNL! z2@50%3%V~cWP88&wmfDE1t-!qtlJFYCR`GX$Q69j+aSxscsUS*smIS4MKVT#BS++j zt7Rt*yg)3VPp4 zw7dANjnNILVl#Dq4|K@`U48gy8AYy&18&5~-?(`bhvgazs6w(@R6Arb1hMnfr@d zq8_&dXN#`_9s%n$_06f&5xF2(L%Z8Ui+E_kh(P27&(BKp_+|JLAYPz0(O;hU%foX) z$_+_=uY0h@7BO;OmaK{4Nl@%TCf3 zEz&DmgmbWd@JZ?@_5T_XtwaV}zz50Mvf#oprH_bKITMbz4tP0p2mT5W1zLeoF}lgsXHi z^(>ZFmanyK|FM8|ER9|gq)CGC77QZafye(GG%#^G5U=$U>}=6eQY5^Ng~$=J{|=K* zn7j~5j%Bu_)Jne83a4MJ81)+4OP^7fTLglYG{AD#BJNt?o)J00;ZL-u?mA@(f*7`Z^rJBSQo@Q#ovff>A6cO# zM@N&Rqv4d1lss^SM{J=JS|BowtTWxcng$hw1YWt%XKhBkWoZH>GEWCPR?y<6~Kucz2 zH$prMKaAm%r84QzF=^l9Uhr1}lzx^ryLkm^7GBdv8AAJQjyS&Lj2zDR(`5r02X zt{8Nw9EdNdxr`E;)8=!t3|22;ltvV?>PQ7R%wd{oz2W~T80+TzLv zS+S*7u_fk*T>IggZllff?Pck8AlNlb7-Y>0N%KOm+=!guq~2vUPJ7xxFqZYV%K+etr0 ztREqMM2D)qCHQUn45QKZPyDt+!5`>a(o>dr3YXp?as}^maw;Aoy90#tgkDQ>%y4^M2-C6SC7dR zzkd3SyrEvw^Uax>ExqDE@Dm-3;bTbn7>INbIYH@JcWj1M+y=o6=C0lwslOLr)5{!& z8-o|OX~pG7+y%i@+T&MNkt;%vBXWYj8|JTX@ACkN$Lab#VGl_VPOczwMEi)EqUKev zpyV9p$eXmZnzV4D=8D&*eSGytV%5X9Aecf+J~xA$6FxbB$O&#O%bBQ>^a+R;X(z@j zl6c`A8$^znmyny1<<$Zur?MIC1TR6r4~Ipn6mG)~_}3vf>+eoro@JiRMMlO&29q0S zhg_j+oY80HR_guT%L-nC`0d9`_`FHu^Crwy#)}919m4NCUtLdtSHR|eyp>A473R-6 z2HR6x^0xP;_jSeER`6;fT^B^pCDC)C6A`(lG#*l%`p+DFAbQelzzr>OL-5gv98uwE z+s;DE#X!7EQ&EbKzXZQa!cH3fK;8n6bMAc@Cxs<$I3U93;a_#L=Go*h|=N%CAXI8OON}*EPl?Kdmcxkpm?^ zVmYLEX}Nf5^gxgLX3{z@h5-3r^l4KQ2dqowVmg@fUm=W( zZ{tAl1kD)KDU&*7=s`qIaNcBFxywbffOwaVn&7!4crFkTIby=~oHhUaIv0o~)Un)} zO>WJG>4eA;cWzPqb!CGwR56&D22T}5Pw~3rl)=a7xHj98liPpu65yR?eUmSzkT0J2 zI6WYlK9eE)`#e5YyA^opECpY-U$JaI_I3JjTql(bydksayan*WS-ccDdUW9ExwLi> z{o-i3JNoawGU?q;;FYqm;Iml8N4!O)M4awg0rs~Bp4bmOmKVJ+OLAeB3YGgl+lQ}= zQ+Vj<2>lXABg7nQk|TT<9Fgmn$Wd7pI~Tfw-o4R3?80FqwZr1>>b;@w>EJKYpJwgj z>j^v`)(-!bQ4L~7LhCXv)bK5tG_k@v4(n`5ET-l0$vA^BcAq8*Gnn+1||EjxF$_Y zJxx3}??VpLQJrBpa=zn}A=@EPqM>99#A)z@-ueC?Cz|jQsv;y z8bpqmT|c8w<59KkkmY6e@R^zFGx2h>axokr?>7G_b94gmo-tQeyi-!Vv-=WlhmF%O zQGUMw?*yAGo=em{#bnP3aR=D%nupA#;7L%y8?=Jugp>>KgdlPi{LQ2}=tbNNAO_K~ z)3SrK?0~U@$PxdZMaD0%S^z``>U;`TlY-UY%@8@_EB}R;rbR4=DrPaCa#@;O7T+Mu z>Whb6<{#epq0hIyAb6F|(=%G+jFylor^pFT=;|wdE&C7!EC#~ zrJBDbPSlP*=$B)1)=JE*qe1Wz?ZY>V$eTqFQz3GKPHv+N`prrJ!OP5>Woas9iQeq8 z=*@g8X7rgc@D}hE|7b}5Y)SrXG_c<-UEhQ0&Y{CffY!tY!+8tU^A_ktn-uV%i_P_2 zN9_!2ffv%_hu*9Cl2`M)fAt}_&xOsifBgu&H!Rl7Sfrh?2z}XW`EqKoud2T@_xY&- z+8a#`(>Zf;&K%l{$h9}$ceCMxBlYv#EH19!j&$?0qk zFed@#kc39$s(8oLFul@86C`t)c_`njSiTqgI+x(FX8nfqxkEj*K=3?m^QHad(ta4N zh@4>2+&{-kKN=5$3x4!<{A@}5?Cy6sj9d~P*vozb&~7tt7Gymp$a)?XyE6j!u}4f< zx$DezK2Zx(Z;i5FsWYn__IRjV z%^cu4vvRK;)Vp>NlcA2{q2`)7uf483SOC1o>;#beCW-r|?%T*JL6cwqrneaS#h(WC z!Nw%m7_v}^T)%8@5C7+D;tCMF$e!^DHI)vj4+#3R!SzT<>yZ+!8Uv*C1;(LeP8Vi$g1J8@aU@z9HzgUYgn4cJft$i*vU>bZ?9=2auEb`Gx^3h73w&J_{ znHT;?u0y@R^I!=ce??V)@n$n0@f&!-fg7dg9UEf}NiFIg-3}7BgAi9CavgI~Iv)vwn%g@i?u8hR--(zdt~*h4ysgDAG6zrZgfaI6WuJA^E005Nm0! z>aa06Yz#vYkt3Fr&ojBUaSjmMXchhU5&wPQE)Y4QvyYE-ZOdY);!)P-2qX0fF{$M` z4Bzjv``pW1>C1B9U1m-3SpB!hY8$E+H#~v5(&hHgroDZ;19&b>@3^AMaYbB@x`}#w zbXBY)ws`{Y1>==#s+VixvwJlRZOP5Qt!*aB`$9u9X;2leMZ$%k3Xy9__1E8eK2kdc z#0xYCx?)ML2%mCAnJWnLQV zAZF3n`P52sO871rB1f#hzWZtJt-dyJ4Go*1FXn2$n2Yg}y?CXR#r{DTlRpjuUMy>} zmz}zo9X`AZeee^glTS~YayE0U4culxhijRJT$u(m1(7S*T5U?_^M(I{pf`)Fk}PzR zEHI7kDSof_X=fkew|5@!9x-R{Jx9-b4m$fsBOIvDHOcHZam(SQP_X|XVbyiZl-v?- zhezZJKJ{q4e%IKwAn3)G!mcaFxQbhvUj05$)1{^Het_S>tsr=kI^8>~$(_}(j6>uE z6GG$c^;>rUv4)P<5*1P+9JNQ}h%fA0(gv8@0WqJ>d3OckE*wKc0gJfzzbdSgpy^p7vq@Oqld2wSS#n*+B zuM0ayI2*3r4-U2p0^Vts=e9)y+ZN%aS8?L8h6~@TzP44z0q-#@YsymQ+0)0 zY8vp|*l(^LNn)NaA@m@|5YCl<8v8 zoRehIb{OmMTF-rD3-FG!J|DPV61X0H$ge&>LHSO#TE-7Be1*E}yYtB1c`zm;a)y5_ zJ32u}uZv@^PH$;r2)88R!ip&(N1W!7`}YzDDaSsYKC)@R8KQWGU}N|wJ^`O#5lb9r z_XNQ*8nZlFLLLdH8xc9dy3NuaIk%*Ncx-@B+HZD|H@l#;5jmo5NWq$$*0NwZokf3- z*Q!4j&)lVp(cj$ZQ}kX*tAL;%4Xe_Zkn|-G{ULIK^9C-zxy?`wh<9mZ<7-cR?S+r) z6glF_c!SPU-e>~x4o%{@4dmPg_=tO9?-&8R5Y}QZTkBr7#t1rC{AfNx;Z>Dp<{x1A9(6Zu2Bb~cJ%z{_K0G>9e@2hd zAXup19&%Q#)2dpBjx$&M{`lMJ9re-GlR(f72Qx#GVhGioLXi{frP%e4w^B=ic#8Ic z8`H=Qp${N(#Jf6YG~~V40x_O0*9JI|0O43HB1e?!d)Rc8{yIpaA8WF&)=FNj#VPKu zCVR6o<4e8&X5d|5WmCCWr&8?Asbcip;O4V?{HOiE^I%;iS4kmP3H3ZBm*@m{V9De@ zg=5@-SIvUH&(k$OPsg>1AH8rfwt&;nWd z4r=Qh)W+a7qt7ua7a9BNl2r3)NZ(W17EY}vr-bVc5V`aj?O0Fpni7C`gSJ*5bK+wT zK_4PVEDQajw6dfCEaxzPePEr|0kP3!cQ2-6RB=JPimcOP;C*2!OfgYSF~J!{K<^Oh zhbI+m`RDkxBH+cc8qQiT$y(oWx9j|u|Bn23U_B%-j^-qAGYQ-bgD4`Gz{Rx#!_6SS@#=|AMrR1o~kil%zEqUv51_YrIe1p zqVrrJ7SnJb(t<<^m+K>P#OZ(Q?R%8C5G;pwZEuFz&XR2Bj>{|x@jZU)?qd%;Z&ucU zrn-URW@<0-z*B?Sy1{q#Hv#V?3(?9gb;~W$b;U?U(MI#(!~Anv*SA0d&r#?4ZjH*j zH85jE`?OY;Ft*DePkaYiq;G%TC;$v zeUg4b`@3cFp5$}iBf)Sqb^q@2#9er&8<8{Yd+)XH@qaG^v5*#F>`W3nQ`q-Hkt2qV zbD6OCaVA(!W;5#KtwzaPF>W|3UZyeqk1OM!7~Kcn57wW)PSyW96@$$m-SJ}af_yUQ zaQs6d$7}*{(6zHJ{IC%3%Hr3=#P|_|@&`SJB;KO!>-cVRd^ZGrh+GnncQ??gURDQ^ zk64HnzFZQ%yrXmN{!?RG)60**d(V7VwX9yXEcU1{ahI)U;pa{ZMtuR^1Lj;?EL2-8 zu**LcuX@v6;3M&>_yN3!Y}~oA$nb{v6w1S1p)_7G^|Vka>D~qzIYPsWkLu*3aM%fv z%ZTN=wT7kxx^9KbdsukkMTnQUpQW7OV%5@F_n&7CmEQ_806LI)tR^0-Vd{a%38pO? zI?ka^8HlOfgz(~|6**}I-zO0{;y=}?JGPdq0Wpv&!sO=tI!GcSM|90Sd*%E_4M^fy z)>Dq!Y9AF}jYyKYLfv7s)TQbFZPW+B1R99vFCh5~z%n8yIOl`YgxY_H0x^s>L?2_~ zBkZ+9jh}41!&?v&eP&2*;6aW_`DiF1$ZUQzm{4`N-ec%>V6H~nNyPw zMJ=5J87ZLqP7ZD(2e*M^N8~cnut%y#_LOBnY@?32(3}*SLx_gR5zWT=eVmyg5TDWb zHQkYO9R1$k%V9suzcHC=5;stuuV5IN%F<&!pr zD;5IrE)6#ys*s1mz9B@8I4GvTs9)SmD4iga_Tem2MI%yNN(&R;Rvu85_N@NuE8rc} zYUh>P8J62krfLVe;R%W%e|z;bdeLngoM57hBC$J3>`s`OA##RS75_2#hOG29Xg6$) zI&`;csCd^-xIDfGlw|qv=gd_yAec*g{pCgEvhb)oA}4rY@bJ#(r>KHpG+PrX+@W2# z0~aHYD?OkMQBCS{YxE{H;8p0h=cLHlpvW0N9KY&`M_CQ@G>4%&GHBz7k z@hc){c%qH%Y@5DAfq0(Ahx;ALen;?2h#YaU&C++Z8Wv!=oVD2Wi9^yS;)q+`>l$_L z#|}iDbE#Pfyi(?FGS+Hkti^!1RDvV;J_AS3VIORP7t309_zIQq6&Ml6%Hf^sdFp2r z{b$)h0t@NK_qN5PZ81c;h+G2ydo*jhjG6-oUS|VoD;)KMpB?307q{Vd`pf5~;h$@O zS;3OnILn}M78YW;A4)RiWj_!8?(-CwH`=vU0DZHzR$eHey_@=Vn-xma{Sgn*g z8`#aBDjQN|Gaf#cQ{;$i?M>~+1V060 z3>^u|G)bB8svjap)ZeEhzpPatKB5KwNr8M4Zed2`h$|}WZ&(GF0r4ko-cKQ&@PnnY zUw?7rZZkeUkVz?n%tx|;^4My%W2ara^YBD!=TSfi0xU_Y>-%r{ebvwC4MjYFpbC&+xC2wGqfKE#4mJ8a9}4nuoGM(B1g3K zn_Me1c@hxIXqyZ*B%y{7+#zzrAW41BUymn4F?z7TgBBHLJmojh!Ltct>G&St&V5?a)y7tsoY!n+f5+e zq@Dlsa`JgOj6{eWaqfR-dUlh~1!SnjE&rd|do~{C3UAbvB2rfOm#17vI^Xd1n_k z*E0j~MCq4S_eb4RY=Kw6mZP4}*L*JCKv2*hABbOg!AtQg&ejx-m3r zM9y%?SL^w!!*fBfj0qmM`RBOJTFNTzg>UXgsLMtE=~D_kHcn)lNwUp4PB*=0btSL5 zy$4!7%g0wurLUUUv_2?A(}EuN*QGx38@~u*4|5XuI(`(%Y=&+XdjgsGEL35JcciOJy8`HpWG&LL~OM--Bh=`owspglqMy|dB#Jx0bf961*IY19Z z2+N=57WXZS59eaG=+Mv_BbBci$z#``e74--)at`UYm-^uD7w?SK zFf9jO5^D@?#`xENd12m77xv4QbPxvwF8Ep(hcyNH|>-upo0(&u1%?v(C|8W6m| zhWKI_;^Eiv`-Z`^K-aO2?}3@chKV0rwSR2I%F9w}rDd4+`@F!ZnIC|c&UjJVbfdOm zdrem=rgieCw_?s;GEKm1Vo}Wt$AK>#@w@uRp7=E)#@K%Ct=`{&_mSyE?9hr3-*oz@ z^nvPm5Ji_;_nINgC3J;6b**Zuu%iW$%d%JRPtT`k_ud8JHJd{|StEI}2A$@wb-x71 zBjbj&$pNp8HGfwnC0Fr%qwoD&sp0aL9X8Vx&4Jgz^uF$teBG%@t^U$mU|(m_dAi#! z*g;L5tCu?Q60V6tryaC(At@CuheqUxCY{gKX`ea-M0Yw)#LOZw zvtS;D$Pt~IjAc889|2-KZLa=?#NQC+D2N;}$wzNkRY45o0_AebX1boo_xL{S(aN^+=r>DR> z&N_;Vsiuo51|fI)_|Vq6HU9nXxVGnzk*~DJH?JhkD^`T-ETnfC#&V7 zdn8BqbUa0t_~*6oQU5gnuZTs$o>m&3;{2pY8h7{oJvzy3#Q2|JxSE!r?*ihx0Ops7 zoZ)xIlMP*Wba#RwiU}UHQa>o(jr&X*!=$?v9?xUp^)uL3sMGFhVzdXvXj@XXnjW{% z$E6Qbx$D`(2~N0D!^z7@vM`T9p4LTkoCur+Dwkcd*8w4M+h52KK8t|=*vK~q`Qzs{PZrfsSH)9Zd zO4l2j6-cwNdVU|y2A1UXUtsws^C8!iRj(;y zm)|QMH=8)*?A8qpe+!mrY~5@@nk}GG5IMpAVO{ogx-bI-RoaUt%1jbvhOO{dm)CoA z=aNyyJka}2-EgrIDHh%WLge&@+<*IZm-~DmR?>YX$M%q8d!P&vIb!qoh_Tz-7J%Uz z)*2dBbQ)DKsCVg)H@@91Q>z_2cDrDi=A_b^R9b@|A}82?-`Gm~jqX77p@=l|2rhGpi*RK@OZ*gZR{Zj5(z9>qA@!xeJH^JRjP;U?|J$k(b>Qfj+d<2K_k_)6 zvX)D-mUkS>s%{QA?66=jWViu+!(@^-S?~=MxeON%Rqkc$a2y2PS%zQgX}r`!&+a3G zmkEwpUK6t5Vl?o+GTy<}ng_*;Z@dWcPOo$N<3~bkIw(BT2%d2_h$W(5m0tNwL>}*hGCu zr5&lXgC2#*5#OoyTvZ;C2bRlOD@@f@N)->>l#2&$0y4JE86|lRyjQG_{g(XhCtmya zO8z+=mPZ#}RJq&u0t_Ff-6U-$Nt+3V5jn%#M_<3TukjrSrm-^2wb08I-|oFEZfS8f zp7dwKf1iLC$Hu(89ol)~m$+D^`*d|*tJ>}#?Q!3Mcb`ql?k*a5SKQxP(5sr(N!;LG z2g{Y@_P}a0o#karB^gtpJ0WrjG&eeEG|5J54_tM_a-5)`oS=ZtYo9#s1P|9P+!r`m z7kHU$btP_&O57a$aF(fz=WiER`bZfp(Gz&Aqz}wgIUwHeeMJG+lYF!%40oSk06fd~ zG5N+6$&LRzdA0h@fa1fQ{svkJE5AqjhL7}d&iGt>!_&|`$8YI;bI9*WI(A2HB#|4T z$slt14gK@beb0#&An48J2_bgBhuF=eEYJR*X$_~Hj#-nidmiwbS?_G!Eot4|vDfKG zqJacDav7N=-PGgt>@Xnyp#CjUnItNMOGo60zH%r2z4^}}AQn@_78}xH z16w-~IpS^o89wV)L;=xVS{Qbcc9A4uB9F)sySBPrSZH(%h~KHNPPHbf)-dcKa>Px4 zJy1XM`~(n>(h=|VEb@951Otd1ap&ir_j31Ngwknb3oKtWl)h+Sh}O_;A8pqAOpBAX zH7U+Cc@^&*e*IzN;$qfM;))&45K@Zw) z+*OFXaN`OhC%FHw0ok*9H3IQ29h2Q;iJP$4fXESFZ8(!&y|@J|SFos|Sl6Uj+&=Bq z$D2kW_m>t%3|t{`h6Cd?<~wIV&Kba`L_|(-M^?A!z`ebkVKs{lc;Qp^!o`CNm&DIE zUyCjsKC!7U@KV?~@nEUs!BXtWzp{LD-ak=?>y*K8D)p|lnxs|}TmvF!SpNzcF-l?p zf=Mi%YBbPkG{ERJsV^=`51F8t*7fq=z+2tkm7B~ZP39fFdX4jupyDHAfp&>4UVMYa z3;1>XR91b!`>#=7|AiEmQ}60wNIVQ7g@{}V)%spZ+UYa_h(~Bxb7elcB77S`!f+3~3w^!!P z1i`|=?U}A})TwgBvMH3spkc49)T-5FGw@^Gas-9)TCc zf`&X(SU6SuTq+K-?hsHGMq%c$YEu2SQ#>m$Yt1Qo3B;U8c!fbQZG`pj1(<{C>)U^ z`t8(Tw`of-SWadRF-cu1Ngca#iueFs!5Mws9%p;Q`M_01wbX2^KEgL*z2N<>x-HaVn`G_<}_>?=22P>%HOXgWsM3?+{x; z_+V=CLEPGRNY0J6nSdFmH#P;m0K+e6Y>{F_QjEa;BXWjqe$)&yB8@-{rVClFy2Mo% z24zH!Sg$tx#Amr?AYP)xk4wqNr9edFh(iNsc#m&Va_Q6Q1LxybNgk}~_=#eNt^I?Z zNrrGTD~B#GW-F;?3sZSSPH?Sf~S7o|tyu7poi0|k)QKn4FlwnZ#ZmpK!b_X`8PLh7r1=MrCG3W~_-ZSSh!Hu3W@(DOEF7mS;x z9VfmN=PSMxXC7|ct@3>$@LE_u`MF#2Q@oJx*LdfBa?R(~Pl;eSk_I6^l*tceh}97} z!wY>{etS`T9t4kSw;TSZtp80Jef6>K(KIxicKvm6-}P63=g-#e3fAfrtVQ4NFYd*5 zZSi@K?VAI&n1jt@= z_I7m#xw-=aPDGBF{^G9T{DWmcOr%{P!kR=_LokQP5gTUuA5%p z)G0L52xx5de5-pgzrkJJX*7&%T}E1$L7zh81h+2_D;a!JZ!awDu!`|eR`XECE^xp5 zQ(7@QlAZt4$u|T+7g-@XOqM6fLUf4832uCJJgIv>V-VcS#)vurDfBgO&YYJJ0o($^D2(o-wc;P3U4tNdwrSY`m&DU+#J)vE+u;% zLGT^5{8*1X)`Qp!krSNgvh+m!o=_lGP>&d4NFs!tREQi=+jUj{*Of%OSKb9lOc)utYby3P>NcC)t4`Kj|Nqj>z=1wADRlhSFEE(Y3oI4<3iud z9(lCgsDC@{Qu2Ea82*T*y`Aje4j)|hQ{)UM>18{NGQSUkd)Z3g`MH|s=VJ7=w`Upc z(aT5n?y_|DGZ2iX^>uArt0@{+;Ei^3JU zg)1-)$`H@IjB_m=)c^h~;6YaCKR7~WD*0*J(Y==*>^0Nz-5anQg`IgbX%!x4ZKcTB zopM+&^lVcd=y|hBdF0Yr34U08zT)i=yPGy@r_Or^l1VfxF1AW8w$P~%ImuzK7HPcG zZUo8OBihq=XQRd)@fGFUij}lI7|fbg)hFa9@M?#)^FozXL&X)mI{7oSJ#1d}%JgJH zXIB^^S@4`ItDGy&7P2K(w3^eOogUR#tKbU9HE1AoZYnt^-2R5hC9v@7sLJ18CWf3(K#F9C7XY`vqRZw1D`LcIQK?4WiXKQDA|2qX9B-TFdr8G;>gQp z{H(}S_yfpy=_V~NOX6h-4girO8a!F`lOP@D%?u|M6Z_Eda~^nmynsqCnppEr=z zAb5}pzO*GTg{z|wIl&~y*}i7sYe6uG)%ROtgSX<=p&-R8G*F%CoSZps*)|aLqn;;I zfn*AgmmqS2uckS5{pYbS2xhVY=BtI;R|_0qGP{>jLCv8{RQ~zP9|X_S@!+yHxvUKy z3Xv0BEAzgyb4>^kU(bSvRKH=8`gMh7MRp5zvL#6t?#n{t3`_kme`=(b34#So&{Id>QwPJR zmfk2>y~e!T)DfmR>ou zX7-KuRT%WH1Vlg4uIM#`c+G(RfXE4+To`&OXI}*fKK{Mk2NciODi(K%J?@X2=3o4K zyJA-J8xVX$Q(3P~>V@ka5IMo_PtDIM)zkv9mG& z_du3BkcAJWh#XPxOLF@1{!KuPrfX7J(@2)^0xTj&%pG+mTye^Rvwy@ zhvrZ#h@9QXfRH=K^p=3&12&6D-y%u>zq|a({?hwtd14g^*3#hQ-A?juCj{w;oM1rV zEHXH26A%y4q6xDhVK&h95qaXu8F80Xwt?jjtRIlDtFZHIhZw;S}_n1iU>J+N-~ zY|7dziKli0qTkIlG}{k?>9p0{-%alChNU4yPVl$mO^G$v_6r$di)&%4HN(X3L=nAj z&^}sz^4z-8!|os$M91^*YsmLCP%?;|pkj|{|85FB0L0@8La=kqid+*OPetU2&1(y< z5C0en#M`vj`z#_p!n?eP9C5_`F^+5giUeXLZH5=8k&D7r0*D-O*vV6NPgWj>ym+wa z*UL`gW!JH^H~3tfzS1!Pct;1d*UDuJ-OCmjJw?f+(XMy(?|=o%XJ!KL6Kh_jyCtRn zcj)@^$XLZ~N3(!e#mexh^{}Vbi)rer#Vwju>E!0On|C22pJ`K(ZQ1>!IL`fPwuq%m1&_=Bj|b4f{B?%VuXT0<xeJsYQtLe?zq9#AMam66x3S0|Z@WgGcw5(H zMHku>iH#fz;DZrM+(YsgWv*Aecx6uWlz-w?pwDa)MEIEyT1{ z9f(J0cRrv;4hYjLM2?v3u;@`(FC(z*$-48S-O7)4iWrbVwdx2NYDzAEhe)R&3nO=!!+{b-2*7s;S0KAgH?Fp<`R;w3RK%R?l%Pv>i z|F2AJ2qdtUwwhBD$*GADP9ky%EPi(@ARsLQ1fQ~){ELk07a81R^++BEpJ)BAq?JV+ z0^VE3+rLa>zql8-M*b}IbB32!I`?0A1PoVn6HKzB4;@Cua#{}+p>TdMko2NWXUU8_<(`P5eH68)BM}xE?912Wu51slPB(^`y`8( zjQ-YB)2n{&ec;uy&@|sfE8hh7dARkir^{S#hnr?u-2M!_2DZ=}utqW2M+P`*sN z$?M1~k5wu@Ljrwi0&mVGH-)`jh+G0ss-)zVtN#GOs3Gl*;k%jYcQdTJC^`Isv7_i> zkEg2z-YGT)+?u9+OI%2e6R-S>&V9T6)aW)aoJxmVmzl&xI6jWZ89ovGOhGxk>wY*Z z!Wu*5Zq-Qf{P7w2Hk#x5H@*Qs(xmsp+YdC-ZL}kecHp}ZIl->mPIh^4q(2B&v(fhL zO3B-m9izT;@oRkTj>~{x5mvGx$u@+ETsB2c@b|#8^IsaN1Mw0K`%)cAsv|@Wh#b*m zrn;n;q5%-=Fmjkhd}axe14WKF>qNfg+?!({iI3RSFlV7o&O#h{9(IqX9pKAnH;+Ur$QqpPOoRPBRwDXrz4KJwSf{1*W)!Kl6RE-7nXQbx~^(ASmfxi#+DG<4ls z;H9$>>aC&XTSMffOSw?qs?Q2te{9_d8Tmv50^i-lSBTOOxr}7i{&B`$^t}y4Y{9%yvVlC{lg7Rf?H;R`$?qZ$t zaG>kAp)tU#V8g91QS=pW0IMLlYsIX-OCRGkF<>~FX1dXuGz#7Ukuz*()o;$}OQ%8b zGYc@1=BOpj!4-hdN_cNdk&%k}xSc5=cmqciOVVNqUol!Ja)N#LYA)R5a1I0yu({dm zRl2WNVSsqCcOH!}o;(U3(DLOx@QPTDn`P9RWzg_rc|7@Oars16eC1s*96{r%J5J<| z6Es*v&hT@)!%G}bJOIJ-!`f>lNmnUJ7bB7L;#Q|U=eD>xj4uV=3D);omq=QdbgVnw z7d9i_P5uUk&(Mj_B{kJcYA~}#$b_RV`# zfEe0M7%Prwkt13#9Yy4b_hZw>Opa7@hb_n~$ZlS2(kxzJSRlU1c4A}jpe)@i5*q@i1O<&*`cM4b8ytH5vguvQvFz2eVN` z&hV@7t6MuaEe2vMCB~|gSanDtB1e4LlK7#vU@2IRWbP(iQ7&B(htWuBPujdx$F|PY z&R+?ZVB%z18rEPHpT0E1x;iPgyd?g}Yx`lf7H>Z~V96Qhn(sz;i zh9GScqzwxMh+O*iW_j%CTkj2mfo$wanWmK@UcDMD9+Bxbp=P~mkT38&*dY4U%HXM$ z8C5&m2am`s_J8y2)`>9Sy<>W37HOSXgoABkze1YdTc^uyZVf&Lye8KA<8>9|b#eaI zq~Jr{@Q<4QmPe+=0ne3x8o7qSprt^;$@x4+}O= zsVSWjzk2zKM?%YsHvH&s*8seW%yoGh>UbLBkXPROD4olg%^9OU?8JBAm9aXh(b1|A zueq%huet3zR`!I}j;lhGAkQhHAHa*Zv^h8y+pfbT!FtUa}er|@1k zB9{?!3+>U_1^s|{k@~{IX{1n?v?6lEygwxIawY^UA7?2%v{CbrI75l)S4A!VcOY-v zpYxP}cY=*%Z($^ZpDNY+HImic30AtWMGZ`Q)4~qbCZXC;eTbatf^v^?JDZUpS-^VK z$;J97#rXA+G+vo9&-71Ytv=I0@F1<`>o(-N4TPnLoM7KR2lf_4S%Tnx=C8lmO1{~4 z{18*P#ca};&NjgNzE` z@wNXs-m?e61~%DBn`@9Z7rSVK_*A&pi(P?!LwAGVD>}%3)FvN=6;nh`@Y$!4JsV@( zKrouEbwq5@jM##qO?0ov@wrqL;B+!+HN@rE!VLC`4BA38^=KJjXv|a+iJQjOJ zC@V)OT!4BBA767p4;DI;=%%bW&(8x7Fq@ z^65PgAJVQ8w~@pN`(hC};<~GqZ$546>IqvlX<&14KDj7tr9XuhRLn_GXP5cU!uL3JBh%Lq&=jNfF`(L{4y?N3QfS1vL=7!8&P?lXj64 zZj-nvPE(q;w_MjW8VrKrw86H>krp|)R1c98{P5ZA>5}NNAQ;cWhO^c>XT_(%&dAi! z9x%EpCV2kmalmuaYIoV8lXOETpw-&g82zjAn?OpvIr?t-4Ad1;H8?*{AGQN!g8^zDB&; z*CEq%rq{6;5IjK3#&&056{nqX9}P0ZN#{dy<#51DsuO!YicPE#RGHwd`Y{ z>0^LyE=hd-=WXdj&3_XgLjr%&%6sZSo(k{3A#w>^J7-72)}W_Atf5{cPJ_g0K#xM? zh;w{eysMT~f#nJ|$NZ_Q{Zkh!rBb}5IJl(s!QZjXAecbQ(9M9j8Nl2TkrTYSZ}{@T zy?T1V9wAzW39CrLstIsHpCU)hPaj{ZV%^sZLI>uu6SWl+wK4p<*t3m3?R&J(sNkAJ zUEpOh4_jlUU1NnQ%oK0^dpYNstJ0c3fLFolD)f%-niYApWG2neQs( zy9zWfM2@JF{&1)7G&3MR#rgL_;w!vd>r0U%UdX?s>HT~b5TDbn9??1^S_f(mks~VE z92qf2c^ME3>GbFVEQiAny!)@eIPyg2Hw7<8Z-9&kF(2k5E9WDN14d#uTnmag`fqt# z=tdB&qsa_XAVI>^2ayvr@UXu-ckXT=Mp0s`8EG|x{2+3~@&QfbN56{!ViO%%4lN>w zghT6y9MP}O{!tFfagfA3)+Qco(|E8Aea=1cU7@-C7Khnvc?NU6oc zFvqQ1Me0^T=^%2ZTLvj?owifayHBS%?PE~J6iLSaJ$Jdsa_NYF>hytjp3O)<$SQo0 z#o7A#{&-u;u4mh7ug@I_yid#@pI)bWdL6C}e(K>tBi?Ucx^4FzKL~gQEGMlCR9hDy zuRsnLIcGF2`Xv2o2=EeF<<%-G)`|~6B=*Fi$}y_VEXZsOF8OPDPZ{ki+8i^Bw2PHr><24rKi1>wh}B4 z5K8*&26A=-bQVNTFhw@UscVA+5VNV}yDH?aaK9rWN4)#GrhgaviJJ@u6)d8G+S zMC6EDjyr5@^jQzYd(=rJZzjo`K@pK7hClhkdjI-uKzvW#POTBCH3Aop$PtJBK1{!M z*e)Qxq~BbRXp4L&#)jTf0}l_xbB@G-p@JZ_V06K z-W>e}T3SjB9k=JI0R0*g-WTa)M2Nd4EnHpbvs6Y@jUPrCPoV`+bT6 zULiWCZLn{f$s`a=rSaNZ1M=1Y<_(CP;2N1u&*saU12KuVo3NFtVJqPn6Cy{fX&E14 zH%cHrpkDjMcJe~_@`=b16LhXmi;rCeNxa3Thu7`(uiN97pPXKJbfq+0Kg4g{8W6lC zBUInT$>ic>IM;^A30g~zj9$NRJqVU|X|I*|t&;ey9X*NBoV_D-9&ZKSUe*wkRW*~v zr#@Z9H6h>dof;WxJAs$W)<*(#v;%Z7c=;rrAK#~bQPwo^An=NZx7&4ri%-Nw>SBV6 z*=n;}oR?<>0`C%QHT!2v_RsFP65Bhmv+oc|5b#`B-8I@8G}_`Q<)Uz$P8+t}hb$wMG!)0tBKR+2Bw zln^C~Y4!DEwL>Rg*p5Wq;cW|Y+XDP6B4^m=MRq~&KL)^;xQDFnJ}8h63i_1wkl>mA z?Y-;u$4xW=!5eg}IJS)(+XhYvkrRBO{b@+`kcl7|zvhIbVP>?o7C&IM`re z=V`$Ez#`+EDVjM`aMtivTzlB1SEIK$cQzPKr*T?}EJ=}tB1Gg2pIe$bt=G^MKz!X* z=qB%_6y8gz|3Z#9dg=Fs8_TwX<^S4SYxQJF_2iBRUO)XKpP#6-6KDnOgT=EwYR~rI zVtax7W7-POz*O;$W49+8>Ot@rj0nfF;fXuUvuLW!3l zbcY`}rC)z>ien3u4nPxQ-89fqJ%WZQpc07vltz&pw6<@{Ft^IOqjpBC4ZrPrp+ zH}_Zo2|PjTr9_dGD8i_R$R#l0%h!R)o0bDHn~wCiWXUa|Z6k8TuGKcFqkFFb%TZig zR8V>*-Y;}aK8H@l|GTp?r%Klm1ozRRdEr1_2vclCPViynt7lUs+dwdcxmb5&4R>Rl ztAs0*(8m34ert0|A2$#@uOM`)L|u}o3r!4>6MT}Nqrb9dKM3An(b6$lg=1peo-6Kk zpEou6{rI~fAb6Grrv*-=K={0e$O&$V3>sssbP|Xuv|E)Ml5#_cIT1PHdiAn9GO`ze z7(lyKvI$8xfsg=^Bf`6rOTUz+0nwlO#5yNZ=LAGVj%ZTvaO>YmML>K>qn2iC(rgWz zp%6J@+LRFshA9+7rrlVzxNcN&-H0nBZu0M`*S=h6{C6jh_rPOilWQi){lEJLFK_f{ za0~hbb~9*m$eTy6yMMlL_bce#W0T=DImI+NY_Rvb-J_$x=|cB4S<@s3 zVTTiKhzT|%!3HKPh@4>W2)XBBTU3DffX1-b7Lsei-Cl?s@w>lS$fZVAAg0k;xnMvp z7(lHca>PIWtew}hLhT@&sUFeZnX|TQW^G6Jo~Vf1T80i%j4)Y22L*0KWMbe0O52&a}lKSU?5OZzktALn$J1g4yH8FLF6-3xbbW zJ+~?;wTc(46!*Y6WYUeGE2IpB>XTOhFO$lC07X(>Ot}M{GvH<5?8Ql}9Tl)9m-v{?q zB>?XsE5Vz3nm6^Zbv+bI&~#q9=J}<`!27~Hd!Dvdo;F5^u98&RLEB{0ZJVE;2i_Al zlX|71@k)H@;F&m+x+i&ZPI}!X;O%84cm-aQfghIjUiob5iOaeUwmbdo4rKWbomaGN zRBhV`Ln$Jc(9VMcmU z@gLWX>p`%dHizq*$n{Oop%6L2%EilvJ@NYtf{r?Gl;lqAc%bgXz>#~M9`yBt z(`tj;dCl6|&DuDvcrA;!GAr&oCEM$|ydMM^G|E0@Ku#HqgFSu}IlJAasRda!6A&z9 z<9zZq-DL4@$Hz*QwAI||+VE25xfTd|P%jtnNaBS}Q;3{kQU8)}O`79?=uRu|wG4SJ z18-L$a>Ue6FGgKWodm>qS~QQW$s=o6FGl2uH?79H&yATQ5b3a&tU{87>o*WN;(W7d zpNB%GIjya zhsEPT^EHFSc-%+%AYI0YZOxc6;+QiSPNtsyg&}!i2!;_k!z*NFD96lq1;G;5r*06r z8$^?`O2pR~9$X)uwqZpE2!5yIvd2>5u~ayqN0Ae>HEoPtsdEPeU$QBPA0d9?1qm++ zPSuxIepoob;~DV0*nIiYM3YMsF~?rw6B$;zZpW@3s0E%Y%klM9+SgZM`*Kwdrd_mR zp|8r=WGR36>^iW$1l^QX-NaLJrw8EFXQq)~xy^b-;2r4N&Wm)GL^^kzFt`pl_F_e$ zrawGDPs4_$6{Kkeba_NB!{&qf5Bc_44+JCGJiTI_q+%To-@p8N&wVLQmC55lFq)QN z>1I;88R7v%PSAPK3ddV=rXU#2dephqYUji!7>>z)r}4nZuJ=0|^fm`x0rS^aKXj{&0}x;0 zC_jV5%z(0qp~w;Esz_a1?X?4lK{O=3yN%r428xIr(ernslMlb_ge1OV&7ozAM#~fo ziC+!4PCLr?|JM94Epq{0I2)DAW=P6rbll6i`*hR9VZ*$Em&axcSJgDHijR!kmK?#3 z_x4?no zrh-}tEt*g(5^4oSgUAWi#3pCQ&B_G9FeX@_pj;qsLJSi(AsVk+EVZZ0RS>MB3s9x{ zq*OR9g~$m$czyOw-{xx|c$o7^i?wep#-4Xby!O7zt!Knxxf>wpLj|k!NR=Km8$?bp zVo%(O zXdM)H1~v3frgdE1d0$ZB^B(Ym(M&yWr^Ci!vZN@?p zLs?N5+p84YRE=ARi^(sfaD-BoES>e&Nmno&NmIB_p6ru{eKLrg;XxL~ z^BpXLKyV*h?t9|Wc_92S>~j^*_mw%^YYSg}8knhU@OcQANx`q9zZtM9wzOs2IiVb> zqsy90vgSgr5jo>K=fwa0DeERk=CX?M-=goo1(z{$#XjIUD$2U^>)XJ4$4aMeu6CXH z5YM}AxpcJXq&r$$>25yo;+S59qGE*j=`5} z1(`ihZ#nxD1g|s0hvmp&Ib4&x-VHZB>%LM-v^d)t&ZI}sX~jbW@=#d2N8|+UU6jul z4Cx0g`yO*6rL!favpWvBpN3A3TB4%~yj128pX#VS)xmmBm48Yjhi?HB|6CF_4h*+a z|K+ViymerK2az+p-1d(2mMt?uaNm%2KXP7G!KCo0y&2s~d_%i+$F zaOaMp^Zmi`P4_hCfZ;Y8!3Itwfx@vDM9y${@2OLq7CL}n5(|l+Y}0)rhQx_tNZcc+ zF1q-mI|!yx!TnBTzZ1B2L{9Kw?vh!{hxvkFJqx}nR_Rx)!bbD4S2fMaP;cD_B^yG4 z7sp0DzZKek;x)U85_}78)+w`Yk3K|z;mZ=i-!!R_CSlhUB4>E?s(yDg7aaxS3+iub zcad7*$!bK7cuV!~?_NQPV7Zb-RZUwZP5<}x!+cELn6HINz`M=*-uH!S-xuP#?oIK) z&Bxk#)wX-D2svSmCS{f+Wfo3ue~kg!GN~;wKMEm%N9k9CbKA)|;d>7vm%!WCtx8Ak zs{rB++CfvyNQxN{5jkS8zwfl+Qk6iAp`m!0B`LFno{Y#5e`;EuE3T`DBu2C0=eW7? zadUA7*BkFezkc()!kW}~z_V&^h4oV;^;6Ij|H{em{ip5UOz#^6r%b8)x;Rhu;yehI z5IMUWyTtDc>!K0_ev=j9Sy_d%;$okl=)BfHvCi)Assp?i%ritQD@H40zbh9#&Fh3d z88gj>gW+2=-fYw%jXJQ(h{zdE?Rv=NKj*(du!ajT^bK!`w`9H*H_B)FOZDv1_#f~# zwr99!E&cK#_Q*2eePdIjDm(ouJM1J)J+rCD^bO9Bx;McGc<vZzCaXkpWX8ri!Jjua%9j6}Q zk*i1avVIS|63zBT6TMJ1S{&p{r0_LdZ!?e5@rGZ3cb@V5?e+b|&$j2pN15a8-7+#p zO9jJP78^`j327ClwO8bEnImdj$(JkNCBXa08dso}cA&Vk@Q8RnMQGTgc`~mJgW+jW zT6t|Uq)i5P10ix5e)LA-&>A-ch@a@B?8G8+Vi9y>M2>jt;iyrKV}}8;fV$S)sU&wQ zC?ayi{aJe^e0wrVFirdCZ9{U~5QvBz@&47HTi+T@hP=FI!;b$BEr0PJp}JxtwyTVU;str1V5TISr5848;IF-J{TuU;$-#Uvk*m&IM^WB-*UwQ zAcoVJZ@)3wZw%uJB1g1RS$#abWDyYG(+1mYOPXz=!6I@*oy`}wcl&o45EJR_`{icx zax=JVM2?uzb6(MZVcURMLrn+HB!R-QLPU-@BC=m+!y;!WoqE=tZ*A7SCEnX!+dqzm zn4!$9yE^gTG#A=T%ml*}*W1obWqarN7f1cKLDC(TxqWUF=Tr1M{P=`wB7MG(A9 z$GqI_BzHTMHX!018oKdiaVwJ#L3K*F4e#H>(dB!8>t^DH6f)Y z(3ufAyZV>H6mOku1Hmd*CzTtND>vZhhbn?!nI@h}7`=X{R0teCVa@uz^`Q6GmQ?L{ z|I2ig8aLfBWp6wI-VZj~2JDdp?CE&0W31Kw-EPZuf!D?c`FMHdczLwjCX-G_NB^%o z7Od_uFa$C}*E#Z*kh~=j86t8SF_c_BwAt)GAikq<%^gDS5NI@r95H*>m4{QGO#)&L z{l-+UPwItlOo$wD>zs6*oWACe#7LGzH+@Yvef<7#L?(cCJh$hDPp)jV2i|GMdtssf z!U6+=IGG^Is|yG$P1v&pc$L4k*YV?(lE*7M7R_I~heW)&yA*gS>^nueiblHlo#H}2 z{Hk_PYLLq&xfQ@G)o#~|HP($a#;+7*-H%bbedDw;@ zF7uciIVN0Ui^vI{9PlzIrsWV2&(bP>zk|Hr0W&B>j#v~mr1|0Evp_7Q(YpIW;x6oW zM&yZqckVm!)&(HmqRsHzLh?;`@*9yOu38utXQX}^@^X|#&DRv=u8Bt(k4k&dHJcfE z4}x8d1YQY?<{~Y1A}#SFSe@cyZ2zPne#?-XVE6_dcOooEgatTZM9%P@E64mZYaW1L z8xzd7)XuiVWw{^X{S{haRh1F?FF??TP6nT^CC}Hw_Yp)+@N>aUHUI7vKn$hM^{N)R zDjZ-#u`1d$`geQo}2!MskPaKMyJlv5XKrY^(|^-K;= zi=XrP_u=n-Is@+p3zmZQG=s$te|5d_7^TMj#7>)*b{BYh?G3hBL$z50+szFLK2K+{ zb4^r_NLk>uFsB};t{kV1zNS^Y`g>cM#nDy9ilN{c=qQnCO)`a>;1RiuJW8`)oViUG zh-K8*_^eg+Sqs|)5jkStszsxF4mAT}8XZEtHHfzcG#f;Yc*L}^zW2$=ki;{r**s8G zd>}5boRRjU&Edk}wINRC(?ReS6?C^G?!wtCL{3n@e(Rk-F6;&3H(DvT9LX(5*xrE1 z5!05gRk>by5Qqgd0{Wpweh5(-B1haIz14c;<1k2~CrhI5c2!^T!ADQ&G}^Kwyr#>g zzdr(k7icLS)+dLB#{dyI!Qb~tp7=Hi#Lv`nq#B77MsGxp=n&OuLVe9?u>6Dt_g-@( zUUNFG?BqoLVfH;B5qLh#F}Wei=_kt7;9AG9F{ZKi+HK;$yg zdN9(hmrgARhOr{_-eTyz1w*+oX>@e`EGd_GKk!P~ zl(5F=&l;oURIRKR_PpI+Ju_dMs{yZ)^{9(mbuVtkp{GKe^Ph=3<=$}37#tMh(kNk6m^uGXY)}E0}%LboWg|y)5Y{+Wfz~l)rH1`7p@v3EE^zHj@(J zV;Lfs;kkQ0hRdb@1;iNIL-UkLo-!=bB67qFO;dvO9-9I&g!cD{B>)4pr9T+8KN+r8J#PWEI8NhD;;8j2_s715$n zv}i%8q_k-h?RL?sB2tlr%I`h%9%lOWJm2TjAD`!aXXebj+nJf8UML>yyDlE=dp*Fa zW$_>*5a>-;Xz5~7x)^3PA}6r(N0oVM$5w(scNS6kt{&mL8Y8N61Mvf@a^}O-)c)QK z0z;|6{m0lSKrYqVRgXeZVsillLYX4{<4vGN)00Yzy#848w@g5|K{ z5xEA+Z;QP&$BO{*l9Z4QMp}|cOYl619MM8%_x`&*n#X$w*!cJ%MoYc#(zXkU{X`-N0rW+ATW)!Fic)8OdiKDUEFnes=M^;-WT;j;CXaB zYlye7l)Wi(0z9q6p_I|y`UOZlvV@>%hVr>+AqqdxJ(x!{KR1Q6&-lc+Qqk|rE8 zL*xYN88{m4%AN|u68cnv^hl5%OdCXwIQQc}Y27+42h9=8u)nnJqy|6iOoS9ZXsOIT zDal@Ifq4QFNBRd#{*dI`|9$gu@u5e#*Pd(vUIR-$9$RTVw!%2FVKDY(agcLZ(G+Xo zoo0*q?&_g;SL50{EmJ@(@qGJax4!QV0I!L~RQILi?n~kJu_p06Xm-}8!p8n~z$;)r z`RyXf+ePSWe=Y#4P|Xe1&c|SA+^LH?rb&)z!b3sihUQae|1C+2PJzHQW|i`dH1mzn zD%~c{)Y%>_)D7(9bOm@H$Nd@@ugxl6n^Eycd33obhN4Viis8rV+f^<8~(SICqRxdwXbhHanxJ`#u-)Xe2CCi#oO%pr2bFgsKG z*5xsvIh8Gd^ZHun^)Vl;?Q@H2PD-~Lwb1Y`2+X1LwSE<;Uj;kx5IKQmRR>*c4rc@L zBlS_irX<)Dnuy2|^))>VKj_y0F^+n@5GBPBB}iuwIpWsiDOsWFT|MDkBqf%Zk`hzM zDiAs1o+;W=LxX#I!iA#Dr#LTBa~6xvd9wH!a^Fi?3cWJqK;T=LuJAG9ZUdfollh69 zK+hEQHlJ`+AO;T-h{0wg*bJ5mB1hDdx^UyG>rl{qomE&at7=?U#fg1GE}sT-op%lB zIee2A@K*hr4o$NpO|vkz|2YpUKcwXpUK$Cs2xeeUuU9+0UR-z5m+ACcRNJy+<+!oX zz8IRcp0gq6Y{0-Ga_xIo|Eiw!m;eH8*+MC{(kT|d|J>FK&#XP_^4N5>?_>~ok{aTB zL&!bhRXQRk&@^>O?cm!}fOv;yx31E}RT@GTM2S+HKyh61l~7h z4+CXMpe(*t{x%q6j7zItZthyL7kHOg^mS+Th&y8R8F(HNs$ znY0VXa}l`?|EV!4(ksRh1U_dWaiB5@R7Sf%Vj4$Lq+&3t!$siMuz14p-?#z1g0=ESG7c=N~}{QOB`tcyEE{;=aRdlK;T}vbTLRA=Ctj&uC{_EJ=$c)Y1?+ zqV6_}KioAp0x_?zu=tuyNwX=0ONbnCSIN>kN#JH^;#s!p@9XN`*TvezS@8(HbJ2?O zeWy-Uq{^F6}vxcK_ zxk6uP6Qfm0v?`1@A}8=!bljpd&CfvKGZv7)F;IFVehKTTOfXH8ZVw)4?Y_Jb1g6lz zah^k*=YT*&PT;WWq)jddnt*6aZBxVo60rc*0U}2vhV|o{PRDK>>BpRay6 zXr;!l0MJKD)<+6?w|d6Xacq$OyvX6L94LQ6&4l}M;x3p8L{9M!oq?r2l;nZfLdWrg z9{HdLQv#7AdiGhMWi(eAh_2LzUY$m+PJ?I&kt0ri8tkQ~qzO&@#9|!pm73mSAl5Vh z52)-aNZjV(!L*0cb6q%Asivd3SS)&j4RIn;AHO6PQNw^XHcEai^=~9ij_yA*Gi(-c8tm=g&d!+Gsy-7R?{Ho zsy4Z*4IfECj~xhXVQwgE*Ql&rD=4c)`~u_zon2dpN;`nSZ}dG)$~2NP z4IDHgCop%O?OpS@(?E2j(;;=$GngA-|J@S|??=Y=;?L7*#*auW1Nf>3-w!%`lF4mcCCX(8H69COk9v7X;?g zHS=Hzd9VZyWg~I|k0lSD-}qr65KCx(zHC+evK1mIM2@Ju(E9Ql-z7kNMGbhd1}WBn zoEMQJHf^-bUTJOu#B%D3VwFj(GOT|@j@bJ9#^+fsmEmuY$x?8O?`F|c+qTSxyUNH$fB{0?sbtm ztm@3JUe{&9pn>7kl-*b*cViW-EJUt>GY35>Pp-NNM0Xl;#O)(-`=BR?9I<*!oZ{^E z3?QDSQ!!OdE>#V7(;;%i7y1d>i;}Z}=uB0|*pL_-aDj*%F`<0pU_;v+=*tCGv`f@f zNz}wF|AP3v@PWabeVQK?2u-AOHbIRf2zO~9aspGg{O7n;suqY}X%jOyk<3j%MC6F} zeo;53U26o*N0y8`i6Kl6@IXk%p zc<*$6g%RzBn(c^mWw7Y?qPpawddJOE(ow2cZnr{ zc0-2P4Z#$`yB}V`UF;LBrnpVP2dawH9o*SN?(6|~fXHn-y&E_tXj$Az<@NTeY@=06slQur%8~yOb*N@lz`^{Lr6L>i+dU;axFTk)0C)hnmti!@vDLyP9) zMoU-RJ^;LLY@i?SRCp|Y=DlTL0+n}>K(Uv4yNTCtA0bKO=raAc`XMy;X8qG2VQYIW+MdXOO^G`QMjdusl?^#Te zqotE0Zq2R}w`R|}a{1bge|&&f$Fik@?J5Q0Hw;T<%jhGHl{hrco*x9f+arIix^r;U z8h-dpZc8Q5Ni)(iaCWHc4M8H)>}aCzXo8dGy{I{?uAuJ5oOI}l3++niJQ6D0ri{pS zC0HeLzvsaW5O|Wg+iEk-YSG=EkVeJxs=oAHHzgAU+S8XncH4>Fb_hohIf3^V+m0Lc z^aT(jXxvf^;RF0Y_s{=0viA#>vZ>M^L3;-4PLhdck_mP@eXtu1?#vvrmd>2;4S1Ps zt%U8=3EPP~0q%(xFZUf=Q?n*Y+862uG_~@YO}u79P=LrO{+^;a@7izz#C$qFPZh{h z;V>s6N1VSbiWqB+_JxWQdxT+2)WXEd{}b_U2dPQ=|K{6_27&Q(l7-2UFgY+_h@3#_ zFUMENt@#6pMbt38+eqFCpAkjmh|~X_RIcOuFKDi1S&PFyH3xBjajm$&`0l!^HxGo* z7rH_tO5e4_SGXn&krNnKyYN3J%OxPNfqC#8Yn2>pT&MLz8t814sit~L84{O(kR0|sCV(&&ymnXJDNSz9wfB~ArC_2nwVGM zy5K=wDiDv*!MVGN+!ewRM2>hzN&T|>h(^%t&tignO|^VYtorziF~Q6GKbF2c^%(>< z(g?a#Nv>20CJrJe(C_cT8s`<8fmlIfzYmJ!gYexWM2;A7ck{&0TAlr1QL#Y3)MRL> z30Ao8igz7oZr2|iv$8vcoUXK{|8@;|y9V|~A#wtn8f@#6Jo*R%*&v=bRXlHsK}NdF z6*`DfA#aP3>x~0RlakmprFL&MDyw z6t7ydcWg3Qwg-YFJJevu+yq)_oG@z&XSx!YYX1&sn;Gn)RM7MU|YyH1~_lYffUqw}4@rJ%8@zYFeUubncdVV7C zPOyQgU#(le8cV$=df~3IH*F0LwlZ6QSIzoSElsM$6P4B7@vCj!jc4UAsNMksm_P%+ z%R|ZKq3}i$ksHA95{C~~8%_i9{SYC3a5pFJ=HM$3IpUSW|m$4Hv5JZkx{MD@U zIK@2Z^aJf*5yS;0xeH2|oz;n_wr1{deqC_oF$jD?GtFzdQ91AVnLX(}*1L%XvM$tb$@7X48qCzgr`J_Y9~YQRIlK>#sEo=-vWNtYMxsRYfUP z{Gdy*`1v%GQZ3c3cY9sx``Zr|b{1PoiY?JN{4A@FZ5Z%Y{lfs@m9yu32I_8aH?Q9R$9hGoorQsS?hPAaVljgJ=D@t93LG zkI>azWkafLU@{_d#0=A$-OcAs0nI_og1uK$ey@i0wQ%uXww|kc^%$u=7kKB{=;UiF z=W8R+z55;N?7JKs7c-)hF)02_C&W8L^3D*v3L>Xian|2YXStXHv5~g$^fYo>hzbxn zV%e09&YMo#faX{1_2tJUl8;L|rVVG7e@!{%as&ik?k+5=_Wh(?SOkciz`tCjGR7@; z0Adl1)jrN6AB9*Jkt2p3QkiVw;SR*6Zgin)5_jPOH+PC0vFq!tz1O}EgeG2QmFO@9 zY|g$mmAp3X z_@->;C65Fj{Y2nh9sX;X`kSfvn_&nRB3{FC{`J=GxxW{H;>YxLRmxh$6k*09a*8i@ zxs;c%_LVR;{e>=HSw*g_0t11_5gVoA|NN^{H4u-`sam}vuJ6=N}^(17P@sLlzb7Btig_7b6B@7Bq_dq|@zE>mn{IwR~U0{`m^IIk7 zx1wA5xtynX+}p6}>sM%C7F{Y&_L3*U(PBidfqOLVpFh?34#WuB<%_y<7joeQcFIbzWZy_GjZHT>a5 z4dzOtwX~wOu(tI;yoczkz1%F@%|k(;Hx<~hnKWz$-;Br!v{leis4pH50^6A{tuRok z5Z`{a$uv?Qnf_srLif`kPD^DM{XH4g7 zLQfd4aM!THUATSnr5LA4`c>`yQXUJu7M6pwYU{LWW0cX}KZM3wuEi0jzYM5wGq&{)hJ|W0PFqm9mw0+d^{NqT}156@PSH z@nAv$C@!a6N!2E)+F-H~ImPc%RA#?e@C=BbXlfC?UM_k)bOn(ke!DR0PM_vC!XWDW zGD~rmDsh%*mR$O{(-3j{N>|wx-u1xqANPwFxlA=uykE;-9>2+E^Ce9!|3(w=&N6vN zjkS)7UqHRn_XM5R=8ma7n%urX10(4)ERiE6a*!|}at%DEyk%>b-+BbVwkH-lII1W+ zihH`F#Y5jSCH=4e<MC1fo4PA0myT@PNpvppwqlX&)oli6#m z6rh1g)ahN2CKrU=ZHQb0+ch4=2S`+a_<}yWOM2vz@Hz{TBPRCm<`U>O6o{pC48N}> z-`7HU5RoH3?(($%>@ojB6KmNtOqG*QmBZD4{uPmbMNrlW+3mn>@HEM6Q81 zZ;g37^OZn+N{MMJNSbh!4I)Q;FYDK3RrLYT{GQdUTDK{*Zo>%iy>vZ|ZKS8Jc(r__ z5AYJ0P0CbI$rMizCW~hk-uX7DJ&}q7o&zg51}xMMSZGMKIt=_qdu%1u`M{x>NzlMx z>Z0QIk~qOdA#x3TvUGBKvR?@hZ_#OZQk|Sshi8Jw5oO+e=zgxY9Eh#7G7_~_Eov*Q zP(+S+^Pk*@cQUG=iTBz3idL457L%?AGH!IR%~a-1b4qOmULD(LA8Ifn)L;pfRxf^o zrBzPyc}?Dc%kYAMM(vGyq*1t00FhICWaPy~<H;+!Xa`*r{q&!<$eOOoKA_GOUO;(AQ~b^G~V&NpP~A4AU=ZP zJcI(>NJBR`+>gi+Tu`=IzEojIkO zNa-e+w1}KyCzqv%ElFg$t z5jlZ9pRXz?3upp?pILdtUs1(hyjH1M3U9)D?YN=vT3Ry*d`(-}YC>9tMS#c&yy17K z=6mc{5SY&b_mlEUC&kZ>7xZ{UTlm{FhenOMPFG+f6|Vg0q+&Yw(h7>4z#YT(wO6PO zx&oUm*^JHECCS;>*xXbG#rbq* z=NpiG1E}U9a*C5qN;@WOm;}TY+QOQ(q-HHV6hw|Vy5@dvlm0v)hR~SKLzZ~R!g5CB zh^J=x*iG$g3{9+NHKxMD>V=1~qEOKb_p6S2+U3P1c{AW0WqDkZlzfsD`aV1HG76`; z$tNEEz6}(6Q=@3Vp4hL4?GcEa;zvU~7Mph60mP5gj=bAT-U)>QM2=_(7tqWP+5?(h z*u>5>Qpz;KVA7>qDSdjmQinp{_t^&mD{y}8AWg!DmzpSY0+;WP)s+r(0%8+&K@R(g z!+vgmKbW|5LXnjv}3?!dEUleTG&W|LUN{LvjBOz+nV zBYejAfO2nI>ajgYY!5=W5jn*Z&viK#Q5FcqD!N=An~=xCZMKLUac@7{=Y!{lgXVvK z^}2kfqdQlDNInelrO&0!^G;^(n+d=({Ut7Swj_1- zNUHN^HtZ=Q`D;XE3ec{z(B+nb@-4AKadQB^-&nFQd(ifcslYqQ*3?}K-Mbc86g}Aw zufvYaRMB?yD1+{X)1~raD|xXMyagiH-L8rMk|(+iK>SFZ?rRhB+5`p=kt1f#)mxW1 zQzj6m16u<5^2+)0Xy_sa;oGE{_pcialhX<8{hJrnd{&8^Rf3H_h@8Oxv>w@=eKZP) zE_AJ=E0T2KQwN9~F<3+G?Ux*GoKSX60xQF$q*mkzZ*Fa%x^i@{zRD7_Su z^+GXOf4Qqkbz+4T@LHL}_0g91(MIFYCZ?_fL)3zF23SLfeW{%bolZihgZV<_I&84| zPe*Te2M`#{62l-fNsw8`E4~ga*!i+<%4y(TV(D4@GPU?+n1o!C&!<7+vc=zLSe+Ai zAxvI`nIyst4e`%O7`Zy*dB!tWXy64JSC#A{CA(maAaV_?ZeEwLX1xaxb7)Vz7Z7h@ z&n+TH{N1pBk@;^KK&+y~A_Gz+n07>tIAnL=(ti_+powqUdVjP@kOCf5omLv1=fhMC6DuPM@w?-gyti zqcp^@vm|zwLRwFeBdUG3mI^i13WBUb>(^2)R2yBWwu-VGdt)VI+V5V0e;W@Ag323R zQCaFFOC3T)L{4DUt5e@xW{v`Z1x#R&iC&P&T*`Xb`vMKWR(-m6&9d*GAn*h2v*SwQ zxDtE?A}6r$fX;E7>3@R2U^WqRXK3Wkz(EWXYsEcmS467oZ35m+onJlquBY-{yoT(B zm>Je>e!tz^=nyE5p_biVm)HyY{1G|DG5%d=`Smys0>fB#9koR%Y7084FfqGs+io(x zrO6$5Sxm9*UUl2O=x!_f;+=lZ!)H%jf9yQ)p0o7-x{B&`6*R8z#alv}o67YhcAmhy z%{uI;uI?z_wtidkgD!x7dYGxl7+ivm+@UrpP>KXf!6i9}Tt~)j+&FfBVgLxNW0~fU zZHhm(VUe>=8m|Rf72dYwg(^PGE^w+x}LgFc6r-l5jUeMK?nf z_+ETZv-@)F;jQa#0I!1C^~#OvmEzTs72*Xh4i#qllMAG`zJ=3i^%^&H9TIUR2; zZ5!ZNY$($?7{YK`j`=!^e4Pc06On7*PK^g%HlZp&JW4b0Is;N?0I3WjM@)M*<eq!OZ$NUi<^RYV7*b8@dsb3E|c5So~2yCMQ?d6EQa6vO7C(y6U z(rAwhD?#AtPQRW??0iY=d~~%xJ(;5Z?pMR(b_4G=)Ndtt2d zzPn}8=fyny#bs(2MGx;K zkLQpB$}%)%Ekb~IhfV654Qe&w_Lu}YJR95QPI%&giI(;6tJum=ojPjf+b37j&T`2W--!;j1O^E#wxku-iTRW&*a6X8< z!J1gVPpf_(zDv0-9&FB(p1otkg~z~iXD0Z#ruuR5yT|U*cu(<>3wlxgYfFLmj`7aP z$e)wJsqju355&({Xa4x>U*Cb(%BD=Ju_V(_`*vkI0E_z^h?p(6lxBY2r60 zs>OFbY6ITYJz3r_1QIgF^PQ&YE0#;o3~r!-zslObHdtL46#~&7eV3TLj3h6EMS{o; z%vX!%`Ztb~ff(Ceh*Uo6kdHbr`4Kr{a4%b+uNXLt4W-suh5Rt&tCtbHk3Iw|62*jM6~)V_K@ zMr^i!2|QbtwnYw+j~s#v)K&^l5Y6uAbUkuPI}G48>hJQ6Nxm@z;E3D+I^-*#7~~~< zfW)7g8V4ofpaeNBB1arGw(W7IY0s;WFtVWLxT5lLMI0F)v078o;Aptcx-SU)K(iCS zImA!6WDb!Ns5j&E8T}3Yf!Ihl8l)?cbR{ryh#c`)ztavYf0qKH9}U(06^OsE%@mO% zzUyNpb?RVs392xN9Fg?xd^di#Ec7Lw%~vOB87J`#Z+!Q+G)YKaG34_L zHznXTvZoTNt{ke4ef~HY3oBpNxH(%c&<4f6^wdPLDk)Zl79w(rJ!WWDNlFYrpe?hn zPtDYynqi#uLkbVuZ4Q|+YR_LYLEsY_$=MGj_Cp~+L*xWjT$fzvk-i!Peq=tcag(HR zQ%B#O>-xmgZ1Ec4#jtskXEi?03e)pQsTgWt8~Um#8p~P$&l4)_^bfA0g9Ewn>v*Em zaB0B}x1;-kd6k7BHL?mdvRKKw+6!Gp#GEf~9vAF^m&L~L_!iycTX5xN4Q`~G@9j>X zmv-y~@NTmrR>f|$irr|4vq&k8F6`B>xp{qd0p3mKMV}b!JTb<1)loh0@`lTITHZ|F z?*_b&Y`&hErg=tmDUE~9P`wITaPDBbNoI$<`%kE z{1*^^A>~Kp9`j+BDPu=Je+k4eYB+rl65oRm=OS{%%jFZ3=FE8wL|Ym;$4ilT;RBI~ z95G&X;w<<1T|(jdV@ixRB+-VjRuDPj+&!x6t;gf)f9PwV<%Ij0+ z$cMsyAXWjozgXe^Vw?~G{q5-ke6*oswe>bsht}H!Q+#(jC#HivjUlF+K8$tgspNcmnY3+02RB zr4qFZ(=z)WnRL}pNo!ha8!{Uj_?$YQ2rUw!1&a@nYhZEc;j=csF9Cs0Y*FP8kh~XFVG_edSHwZIf1T2OA6AH1!5vKU~wBs+(vk{hR6|fXH`z= z7GVv$~91m?13TDo7pbUzxLTvAI1af|FYZR)_DVQ~2|TP$&lRpJ)oLpd#0IVKw4vc2)O5AZHC%XwnD`U&ye z%VlX?_Cud`F>1Q254<9l%eyR5cM-2HtrRb=JDmGi{!-=mFxa6&OV^)t$tPWist~yj zJ2javJkf6&2ux$EK6SrZs(ANP=75*9!&1Hf_%Y063-H3&Y<06yb`uY|hKYw*#-o@XCw2?u9GVK#EMPNNNU1lMeZ5BddNfM~;n7^Jsy9-1|8cC+kC8={E*hS=s)=O0FRvBc0=18{m9vW*uG{(f|hWNqB zKBErExw<|9fyLC$6(1nQ2Vh3nrpChp2WMC6DQWeRGRHVH&G zTBRypN{W}l#75+Z^`}0kZl7KP#3S^%gej3QArM03h!eZ@9oKWl2k6UJ)|VH0YA?iH zDqnkipi8Q<&%&ifP4ytKh`x=wr9y5A9|uR|1X_<=Fs83nFR%?Q?5)Q;>(TG5S5a1r zc!lU(jXy6`PLTy(J)7EDD#}^n{+$Y0tW1*(ziwH&D!{8{p09AIN}*VOdN(MYPMb^G zR^$Kpsu~Voi|a2$LF5{!^jmMk?ng9%*hmdxlo^RK1B;Ew5w|M1yg9T% z4>W&fah0v6oUJBWo6p@b&3w13apkGxslan#YwFrO^=tDm4003ql%(0&Yqih#4-{Xa zzNbu`l&OO^L*x`+AC-A`|GH@)@FWX^BGyVG{x9_pxBVK>%Vq`$OrX`Bi$>(4@WB#9 zPT+AeE;G$`J_xK~@%_g`8XphgQgIQBs?vLx)HqJE0)bW35T7ID9D$4mkrSwuX>xDs znFByPO#|}hO60k4of;xXJiNZo;7(%>g62S$ft<2XJ!OH5{)%`fo%yU!4?S-j0f8BP zgr{dKPi*C3Y!Eqt^>RlaC^jAiV&Xu7_;wq4yA38bB1as$|M*y+zQ;gw9CP4hM7B)4 z*fp*{z6NVsSfpAs%>{T4tcCSPs`WO6<(=!}N$2Z$mDsmBgHoU)E_8*K>&lhuLf(qVbtLoA zP79kAIY7*$V;!@S#0cNBK;(#>uUx6yb^a+3?P=T|phE(5U}7V3L}UNDd8-rN3r%EQ zxu>UlPY;9GpuV}ZiK`9{QVb1j1KuOHl%3R6oYc^pJsX0z{8paNG8;LmcLc~|L2=SS z<)nj{ShNoIp+mF3n^oxVpYLHdf&oEB=F+fMZBr0M`PmuiIyxIJ>~)!EsrV2C`cWrpzn|FehcQIt1g6Bq%PO9D2m%wC z18|on?qVS*Q7iRW_OmxB_Ea~AI4(}cfp2{FFg2qZI z8YD&drW_(CaEJCdHRV(l5NOA2gXcUI&v|H+Y{ggja4h)MdlNMf=tf%@uS(*DDh47a zuw?m)HQX9PzT_uutQHCIhhn-K`9{DC`%%NRcDnUt#VsIejq@ z8)>~G-HfE0!Qdcr#Qrl~k8IaB1!4wO{lS8KumFpV$Pu$XhwoH(*$$m{V8ze~J+%li zO0$J>yz zae6>rp!`2afC$AmaJOGJk}n%!#v*dWr`rvK6~~_d;$=GARr^TQKIk(dM>PAG``CZ} zDIn(3KIiQrdBSiba>U+0R?g1p>I!{%!Ho7<3&~lFj>XW~+UZlP3(fV>A!nfDSd~u%yrnC&oU{$^?H8m(cPZy7fvnq8HXr`ZZ=f3XLop~tyaqY3ZH#D)Kr?5mXsgq0Uux%8PYodw8JE;Y)e1Z6p+OHD_$%%sy zv?FrFS?5NM>OLa~G#_CJP1Jt%sQsAG92R>>=>-*h+TXAaUH#u?X8v-dqoec@Df1Hf_Q+RKqnebS{x=$6Z$zw}+Y; zmH@Af@e(xT62w=sZF0Dh1G*0nt$$Yuyw7Z;BMnAGiaXyw^*TdGQ0nOr8Rz4*z`Mj! z(VKf!Z|+6Ce&SJ*o3}dkm;S2`c+o6WiZ)Vu#62%qJ<>UqT^AL3AU}r{|ps)wJZ=x*`t`U2hDnI_e=C$ z*cMm&c|+npgW{`nw${jy8sS=YL{9M_%^caZft_za7DdCz;Kd|(G1x9dj_BFvZvNgo zoo~Q-3Fdf?%uzlv2aRUDxWUa;=3{n`V?BXa&LZ)WZE_{sFjp=o7<={l?(?YI&r<8!G?X+Ah3F8G zBaWLot54eeIY7KdyOL`|a)tY_5jkS-ml-!JZ!d=?erLtwHIaf$2SA;5EHo;KD- zE7k_hx^sWL`Od6xf#b8kLV@>=H85;}VwiY6X01#EZQ$5PGA(tc*PwxAG){V`P96#c z5k#(md8h8|S+nmJ2)xHqg*z*C?yN*pc&|r3H4M3B%ilU)jR%2&bXwoqPHt@%ic}Oi zfel5bkFQsyfWUAzYZ~`xHSWQlJnMrOeu&GXW>leFy+)F5(-s}tva-8}3y5F@Dzt}ynrMNFH;aXqVF=pExEhffEY{Tsc?0y1a^!eH~62cnBYuY@#X)}5WPw`SKGlPEX-p}t3ycD+LJ!j~7&cG-nNxX$SamyC# zMXv_|FM`e1iUW!j2hbQsh+gO6EdLq9%vFI`$gFkAGPM$MV@%;d{3@*fVw=J#VUr?Z z7SayKE+?_VheHs#4$q%2ZR>Q?L?HGPMkZ#rV$5#XxsS*ZjmPWG%eu7&h>eu^gpel$ z9tk2xO#d&?^R%lKH1R77S6*$>ezge~-dD*}x=`-*I@9`hslaPz`vRJcCC$biErUZh zZ{I&x?+2bQt7WAuQ%e!M>?@C5HYhc^7jWz-@b0m|@TjToQBy1c-5Z3Pu4E2cb;-AO z2A&-kxms#DTH+(N?fHhHg~LWdt?WU-u_SPt&w1VygHyY_W=(^>BZ0=<}< z$ktTL7H`1u5^um65MsMC)zt%dkt|j((@`nYK@%6*Es-wxLI1A4JlV_-6rUI*Jd$=< z(k=@o4v|x=zfNBuyRcpD!gh4= zX9m2Wle$61d)wqc%YYZlp4>Tgopb7FkzyrxX#=B*wy$6JtsHpKY_dMys`Gd&@}k8Z z!7>4{PgfUz23`((a`sD=?8T(xfxJD{JHkJ7`0N2aqx$~l!y<;lb&|q$9SZ}I9?$Fp z2MfGxCeLoEvfWbj+xNt}>vzkhq2^u!FNH0VfFZI0Lv-lqr3^%qo;ug}f!jkB;6<>R za8X|AqIg2+nwS(V+;qarKv_QuEHJGgS8I}LVXqe=_dry;zv*_e({Lc#gE@j@=DSGb zF0h!09I-t(K>g$BaX@sUX;!rYsaAkj9*7*#z24xTt8RZn6I)moQ#)9;b})9OrC$~u z!uDIAyH42fF9?jJ2GeIg@tF@v2O=jhJ#_ZWZZoF=@eB>D1C&UBP~=ABh_;7K+D9B& z2%43DS=JlVB{!ybJiw8>L+i)tfr|vi-GwfD&m-RRKrtdGZ*q0l$bl`3f#^;{kS{~Y zm!V*h5IN$v{$@d|O;!Ohmzu8d-6UN2z7!%yl=m!N8n}4_5bt7zY96T+!mdh+9C794 z6E9Z&why{e#pXkUrgDQO&YQ}CSPehZ&F)aE?;#L)hk9E7#l&9-AQ3r%<=)Ru&rxs$ zf!Qn;h}4ve6knob%Y33Hq~H1XIT{jg5ST~(UD8UDB;1yZ$O-%{A^qQ>y}d!;j$eaa zHCIwK7X!_om9ZD!Zw|jCbroo@nb*lOmCZ86*-+l!mM(aix=-Ua^a=x>AM0?cu70X6 z=E#2H*Dj6+^mhx{k_helO3R-wH<6c{z;PpT?fd%TPII^BEFhkw&*ZHsd20$W2qH)9 zU%mX%qmzX|Y^JX~^4F65wUA9Ca>V6N-PAnZK7u9&u{G~!Ch;@tm?eBMT3^(v{up?6 zEG;^xp?*#S)3zgGT2$^mHfg*3TTuL-&cm9eq-H4$H6o{Y&*GWa+s`)wv7Hj*;Mf-Y zpw~bDT;}wW=1Y?1>r>XxCv8~v%0kvb9R#-Y6_(ZMUF7sG@BxUN!2UQo}4xo?P*@n={1TaUhye#rm?KB9{teI-d> z31taHPN2v011rW(odE(LFgNu~LFJivj6Ht+)n18b0X%-4 z1vt`oT>1v!*)w<1Zlu;OX14b7_+i~Z{Vy{HtlS2?@2n%Yj3u{>J5I&UlA#;bChUNY zxX}p6dp+@94|5xl>xj<82Uh1h9|Gb{I)tyMk=N7Ul08I@So>)3KwoVaAZAg=Qofs% z?*^NQ$Po|wYaEv{JO@o|XY;Urs7k%~zWB$WB$^N!B>LQZzAF@XADCxOG15p8U*TL3 z_dM>;s=4&tHVSxwZ1uUDN!-mk#$J<7>%JIu_&)Hm886pdl54I>Tle!BubDS0M>RVS zc=oJ))i(0gHaH89h&vDGg!kz5saW7SGsAg%hU)DZm^C`f;3r{~UM0z|9QG0hCZA6K zLL*XW1W_p>H!#C?ML(PBRslq~ghOyYGZnmNg0n#6h=XH_x?Ffs4Vr7&dlXk0Ial#o z=UQoWq&@WlGz^bz&bmr$1N z04M6E0^^!96vh|;?+RO>jutA878np;md9r@K6Bje<-^v3;;X25Cpohd#_$Y9PI3Qj zLr$-=Jq*NZTCZ>0OWO9rdP3xg`)bn{FKTcCVhT-dZI=*R;W`6Ej;Nq6oguZ_8JZZ* zn)pGAd=M`SydmFCJ^ces=jG~s&Vs-=s@Zi9aoqy}9U>>tcl^nZYYaR=U=3SQO%{?S z3tTBbSJaS){ZmmK92S7YS9iQuJIoH+j`AkHPnE!3h!9}`{p@|J_srbmq`G`xUK{^t{cKz|w>@uGL z?H2K7kscFWLix9D_O(3a3>cl;&rs@QaG zGa1!pvVykmb#JU+{Ft6r)vdJ(cqPn;glNi!XrkjOk#VB!+cjcB6Y1Ox9Zsi9FL);j z7N!j%*Wqg~Cr!%e*$e`UM*dp#xu#0Frs(AhrEm}Nim8jvclG=V0-w{;PR;?6BYamB zkrNn^-g`=?8$Uo`_K05sPi)aUu?4gKZ1EHEk6X9Q_EQ&58GdHYJNlq}wCKD)6WnY3 zU_x=;vyYu(;B6kAu1$+c(_)yeh@9dvng^HSdATd7Hd zW?z<9e3u^bT^j599%5dR`D(w?sa7=*7%n5&*Ymr{`Q0E8krSwyW;VY{gDZH)b@EpShL4O*7$ZIqa@LfZEh3|GEaw3;K??1R=nI#ZE&}Hwlf%t5I zkOh$=T0b+JT<%~4y6xCYg$pJ+7ffbSR#;y=p<3Y{?)jtE7I=QFKz3)F-kojuSniA7 zafHm4Ntb50gW}`Vz*Y_>m4o5MG9st=#MC>>((L>|U?nTzWm#!tiC^O^74L>S{?7-O zajtp5`@tfXmqxlTjj%NFL$;E-Z^tgxh0BH&f#M6a$H_({*$Au%BB%Jg|JbJ?GoFIL zX!iJOwbg31#iD&b%xH#9l{TDVUIILO_5$bWA<5H2DpcA}YZG4|qExX(;Kj2gA0;Ip zC52WgUK&589iWwcsNS{~c;##Zi7d#|nO77IJT*-}2LCVx~7^?s81OwDW1T)Fi|ll#U(P)gmc&qm_25mp`| zH!#m!El-U9S00EV)EZ_OlMG`>R1i7h#O){3B8C)OIKI9)H^ccv)({ zOii#f2^P0=WOcty^)@dosfoY36?ieM*5SKV$#*N-xagjEYUZ-KfnNAnE8rEeC;VPV z^}X1SqHe8pT>K4^E1vvi4Fl~*y@}UW;ejUW(_6Bwae=KJ3dUm%uJq9Y-Wg2O}Ph}QXjo%ePN z0nOnou1{SkNnMDK_~+z*e0bc>?K`7^calBgRCVv4!u_=G)UE~kOwDw;xN zY$F-lz=0xiii7)Uw46MV4FWH*Rrdl;Xuz*yd|hz&TG`XWJYcr4!HM0W8oL8$P4mEu z)G*v1xlP01!6V>#u!t&f=7_+V7*TnM<>nxd$-5_4zJn$nqZN!MBhq9fyyv0FHF2fQ zvA;~8^tc6^G-xjK!&LEyDa3M!9P!zn;;~`#6>mYp$}CONI_;!&SYveQ_mHmS=R2PD zvgxV|0`F4aXb)c-f*%;KpZ{?}&#By*K6UyC5L(QFARh~f&;RX$_*(zl_Kj741J92w z($<}7tvhk<_zuGDv|4lh(=t}i1l~pF0D|VI2F<}?OzG=Dhw;uvU9U(hW8g)wMRiPD z>6kVyf^hlobaF>{c3ySV$Q(NJp1LRp6XIY3`^*rzj)eAKZ?&x71|XJGfBRaOyw(*m zJ&GK0(dpy@rLsey`72xYAN909>WM{h@pH$mN&Ti2_Pq$aG&UFOw3O?#uvC>U-uIr~ zefInA9@ju|H1!n4(@60&$a@eu#nyHGuZ4}i2}C~{1SQLoWLdb63y~wvP1@dBZBiU) zPG$?gZI)8oEF7C;aVN>eum=A=Pm@5PKNXl@LlSIY`5|%wqrW+%Z{C*-0*lz(e!NWe zv1q}H2IAIui$UI}_jY*-0-NbzJ6jTGOPI5WoIs^hPxL1K{S1gX)Ga?cNFE)8cn*;x zZk%TFe#hxjAU+x*1TA^yB+neeB}9%mA>oI5qVj8KVigNoTGcgL)iGpwBZYfGrC*19 z-S_5X-PKx?K*r;w|Y=q-9u2EvxVerfhB;*DgK(Dt5~w70R#rK zfZ*+7wYOpkBS`$tvaGJ%&Z0vNATWc5Uk$3HLAd-3krOEOQtFt^%x@s@3Uj0tD>N!r zU{5Z~e-}vHUwXYoWPxSIhStDl8%F&k@TJ3t7YVsaEup` zBPQ(7HkEZ45eNHenSnTAD0jjTYnKnj6AJ@MQ_Z{POa`7C3o$;LX?_$xz~L%hG11jW zg|z%O1r)!e)8YFn@_iMoJw#4%ox6+ekGa!8pfd}yYgTF0timok4L(g5y;b#>`+xSF z2?Bkoz*}?3Eur#-$O$w*J#*DRb_;;`h}uMFB}Hc?DB>Y<#OUTH)7}=Z0AdPt1jlBR zW3wRvN92gpcDlVNZCeGzHagn(!6?EH48+g>IP!t5UVh0R)3@3C*kEkNjN>Um40NvW{S4UrS5zRCN*wgZ+R@F}x7Z8D@yMvJnZk{i_8xoLDR zzYx0vcyY{K{eTap!mr~C81?*V8k@`agX)iTeuu4>3tJBzN90t`9OtUKZNeEK`q1q4 zq$)Y73JU>|BN}PvuD9ED8+3nSE9;c8?nh@WYbu!yRkx|4nQ9_la>a2#lr1 z4sdt}B#XSD@2))*mm? zI(mOj;UB&&zYQYS(f*I&eE5)U{EO+m$CfBc^_!f08Z#I!Po1pf9$SKx)q4}fJ zu}-&Pj|JP@5x7qh_(A`OKQv$}z0r?>{ z^B>lc59=W1MC6Fw)|p*O9U~9gv)FdW9@fJQVipUXfUYPS< z>F}S>#D^?Fbdgtek;lN~QI9}sqb6>S%K9^MGVm%{KvZlYDYodi3<8IbE*mlDZ%|xI z*M9OIlDr2LBXWvA9v`*Or)nV(o9G~BOOb5h+oFgZarQtHgRs>rKyxE&;oJF|Z|DC* zSq(iRX#UXcnD=}4z%9V@V{@lnTBcn*kL}eDH>3upwJ)(8x)XSJ*n;+4B=KC-al@eU zSxMxX4ZER%Vf3NA+ehB*0}Fx3HBjS;wRieWXAt;`)kW`UE8Nk>GpnzLl+z*X)Z?Pb zo{2X=pfeqslC^RrYhl_Tast=R^6m8LvOs)7iz%T?NT^WzL*$5FT^4>Dy&?vPmDJ|s zDU&>97(+yk*k`~$movkXpoyPY?iVyeCuj!dbQk+z{h?rMu|b#oR1kQM_PI!v6sba_ zgUAV-AQ$M`=fWcpcvSOOQWq(&8Yxa2`=8%N`El@W;$KgJ7q9<|S3FOxcpfh3I|DGp z+DHP5J2h5-;u4xN9V6rzfr17ir&wmfXY+5CwII-o#U&AYRU^brgP!86m7P0`ENq9o z170)BIz!|YLc|Z-v~>5Su0>t`{Efu-jlx({PkG6TT(W`{g~%zkuDLv5@#!x>bfyob zYBi}^4PS;uKagjl&(^+*y~O zKiO}$H1K@cf~sApTe}czJw83IQoYw__g@qiK;j{qr8XoPgAaO{=zNx-|xp4|^+r60-|z=z4=T{zeJ8!npgX$tV} zvK1P+ND{fI<1Kq3aitg3v;Ps~F}*pmvN^JtK40yBl0M@~O?P!}k`b8%%ax2E-CNY4T>1yxCwH5IN%a zD{t0oOx^;Tqga4*bEwKq@vYcR@uZYhQp9_cw%x$H&C9S;N>zCch+3-tT}G}${F&QP8mtX(p_7fuED@K z&?(chpS0`;>yO9{%=l}!%Z9&*0)YW6AAX~%_(oL}*!LtA_#|`YvYAujf#=3LT)$PR zUMvc^i5p;=|5W{cd{Qzf{zPM-duzzOH4s80a*EG24%U~JP6dJ4Y;NT)lH@Kz#Xl3J zb!!GyHg~%V0?$)V>ts!wtRcup+8V*Vt4t6Ybn)Ew$JxBi~@cdbi7kbY9%5^EXH*4PKer--mV0SKhmMeo<*`}!E{CB6zeNbJJk4}E)e7Cg3pjA8S>zf z5jkSLrQM6)C+hz0c3P%=-@Di4Ue|TG_Og^E zvbM;+L}cIFwP=wd$x^l?ElOHYqJ$PHrR-ZNMWv!B{mwh*Wu{-x^L;-3@p;afnfJ_D zX6Bu@e$NaLc$7YsJ38c!aDWt%6IeT^*0ZH(83-(8NokXYVv{(CPsAIZbpLHg%8p+P zJa@MAa9vL6x*Yl>cNr|sh6L3fY&Q1=#o=@i-M13=t?={^ImN#PM37qBU?7&$K|H>m z9A6La6_F#}SIY8?n|}y2zhmV`{6^LIjTk2?27IRedcYh1L3XQ-0&>H=>Izw zaX)e6zY&*@f#O4SXtH%kwlFk^oZ<#K+X)X-E($}#3if0@y=3tYkuz^dai_DVD9dGvaDr$Dex+pyfQt5GVwyDccQ!{4JX21*u8@WUd3W` zGVz%VR^vmFYvABMDYJ*VeFK5cOyDP7jZeB5X>)SG$u`PiT7Oz5g%0&VpTCZVukQoA681=n=4%#-M_fw= z;B|K?_H8q-d=hxoY=%BrsQN^_XTGv;GM#y$${XUpA6A40Hql(TO`Ei7L%xT|H8A5? z_Z@dm8-u_+7D2ODsbsH0e|?kS$ z!{vWLu{*Wa`njZDIE97CDK`6iX~F6SQxNFE{IH*ij-LsZ9UeW>X-`xe9%ud5bq?@u zvLvK^nnwFHd?YvfRnz(Tyi_ZryX8vY&;R=T{q%Vd7{)5MTT3Ok zmUccoWaYO!Vsq^U;3cpaU#P88sEs3?AcrHkU;9M-`F`=BIJ=jiIDHyPp9bz9kyG5| zkXKbe^d%tPro}{y9%<2o)d56~SYm&2qr&0CrT5)0nvjN6Qz?$>14=j5ILf{|CAj%r#pb? zDkD6VD{|zD92|Z}^?>frd?iCuEkhH7@?r6vzTb_?mLAOR2E0J# z8NTgS`zBsR6DWg6lrJZRZ11q_ejP4Upnq!g-e?E{(vy8Ue787Ik^|Epu9a}Jwc9V7$1MCKZDmTToK$Agy%Vsf3e zUM(lHP#$>oIzQ#bFVc?}-?RBBzSE>tb$e*VYHi>}vaI3LD!osu@YsE1uS;~sKOcJR zpHXp!(2)+BYr3u^uEGZy5xI^`Tj6|lK!p(yGbpiXFKOBfQxuUSZrFayX^MskXbxjN zd84lRMjflN8R(Nxdz+U*;}`-g$BN)&#rA7Y1;;m1d(gtZJ0(L;8MdSqT{3Y|Mytfk&57U*y#OWkaI2nz|5kL2Q zo*=XM1Zcj-HrQfxRbq6}D_t8HMK$;JF_*2FkPHIP(y>0^NDer{j6&oD&I)OsTze)H zh^f@sggB58VOtoHBfcphjd>65gXWv8L^-UcaaerC?Ny%ys#!04%it+DpMbzZx}*72 zg*+9$28_rF^wDeI<#w(|I;=5LqK`iD(HEjTMUL1|^0t5SfB`_fGDw)qY33wN*bhMD zh;Q~SkH6ueoDP=Fj*A3nY6fVEb|YRF-tcm4dN)H&5ZFkgZL2nE)rNEckrP<_ZR&g5 zF4{n>q>FOz7La$shkg(_Vv>5W^Ma(`fOwn|Gj&O(E<8U(j=0Kdse|7iL!gP(Y!tuE z(EK(7o9H5bg=PJSr{_11odE*H>0W>qWR6a>kJ_%PjepIXuQ@4g3zqJ`?Us!^X zw^TcCDP};e{R-&7thu)P;o^_mKyN#Z6qg*yB}bT}h@9SEO;c66J9vP=Gi=$UW2b7z zPE5m3OX0!ooF}ruLvMHkuZ=a(XOo)GCX6U&d*f$~J|15;&hn-|@NyaNh_%)cYxLLo z;!8PwhV-Z(+&e(vvEY4NUG=#5dD?u14m#5Btlpe>Gdvi0*~}9B6o{XAc}un&UW9yW z<{YDozlRC(81KcF!7sMVp}oB;cb>}Iy3w)z&ZkHim{jUQ8VG41aPv7LH!$j&vIF#b zCV;>rtdu|PAUW;Oxs>l-n|h+iD-{I#Q1_ayMbfn($wlM@`cAp9VC;W4fq0*~P1kM2 zRq(@z98umqSx;9c3yAxuXSi%mE(@Lkks}@(b?bqgR5lRvXhjjWn1n3`r-aB64`g)N zYyVp=^d*F4ERSbO9?!(g=7)8?C;cayx<3G3AIkhrTc~$bcmq`t;r|CU1q$DIszK-NM61PQLpG5JPDbkIW}WgnNk) zIbumr)LEZ(V?cA&-#>F8_Z^z<;!TQGig>PMQXls}?k^b&0*}iIqkVB2xhQ;q6_FEo zEUqYWnA3O=c#a9I-l1JB)>~)A&vgw|h$u31m;k&IHt8=K8eKHR6~>ZY@idCs^|-WB zbDIe$Zlqo*XBo*^25BTBr?_ZRS>C(NW+3nbdwP*;B#~=6r|dIIdY=lnnF+k(Oz}-E zwVUF#yT?VvaC|_jpmG5yPNNz2S4;9$IJt_*DJ~pxV3%c%EeNb<0mXN(wy$`bTfO-8 zwmm-G53WeG170H=nPWS&j){l08WmfqAATGpcfieSHSj!`zs^@w%2&i0<=t#McDoJR;Y?Yg##3-o_3f@H{)e5VlG=Y!ybb^Rjq-S3lz&KL1_V z0Rju@jCweaJQQACK;#5gShTraU+W3P&va<=)JdLj`5+=kyuEtt(xa6JK=UhBvwB)6 zds?98m-2zM%i-pO#)Pa61%U<9f_3dvBKwqJj~tN`_@!Inx@Y??0P!~6-@T+rE-8W; zB637)$AQH!cHabIHq9eTcazfH;5iXF;`q0>TSpJMlhL=!*Wq8(L3eex9@X9Y{J<_S zw8EdNX`hNTiwfvTBD0z@2ZJ*4#nD9Zg!g2-cd!4g>3#!Fc(bgbc&SS9QcO#q%Uq*9 zZoF~w#ib8@fEUO@#iwIT#()EPcEB+m_DIw5l7GTZn`qvF)jK+K{Zq)>$v3fU_n zN8EX2;ftc2NkH5uCp^1Yc@ir)IYf^5Y2G0RodSXQmD=l_ZRCz{(-0y@Trp5%=gqfM zpf90pZ}6nD+DT>18;W5Bx51p`He$z9IcBOB3{RPjp6F^`{Kf!Xmw-E0wFp7wrz^Plz3WhAY3d9;Z>w|Pj zkZ=bGB1f#4@96zW>KbT%#p>Yi8x6m2#2w5x(nsj*BMQmd0q5=jFN2Lu>Qn<$%1W;urcN7hG(tt0)r`)1hfyOIn3bTqAOd|8p|Dn^{r`0)tr@ z?5v{ZEMA;{cp#2-WK(ps*S-(Hi()GYDXK~-su)x*h@U6Vv;BR9^~jIFJJ0-F%PO6g zRk*r&Ufk>H5w>>W8qYf5wKKnzyFilrf2W`N`=0XN`K3F2%r%E@;WTQKMr}yv5V?*F zu=RLtdO;D0rPMn(FDA~5;g}5~M|4P8;{Wl9ZYEsc#g@8@l+=rqaE>;M*XA$tGu`~F znH~sCqUM^UrI@4z?go()crPWRF=U}Y^q~{rg%NpS1W6SlM{GM$6lh+k2b%p@pA%+E z5@vQjOL;{j;&%A3@gQ&?&Dx_iNVITj2aywa(P8u2KFU);VA*dNW?&ZFGf=%}fQ3}~ zfC9Q46Zm*_+`q}wffven>4tjghB%?Z2VAB;WJp<`Ba8RU1;z1np0t{hR#T|b5jn*v z`O{Ut8!P~Uwagk$5QP)sWvsOXYumi=pe6sQ<~p7ru$=j%3?h?3)F`XG zC%$&lTQ1JN>y!h)i(oZox}$o!BU)F4!W%l&T|$n&8nikF6#LLJrD`{++6|rokyGq& z^6;-?dM1OwaF!4x8!IInLhV>>inGmqm+1!@n@4k zu`6Bbjxr)qMxYpxQ*7aw?EN{k2n3#C8A0GON#HWfM1B-z7rzWIkd=A@ymM^E$Lnjw z>tkVdw$~ZjK6tWwR-6fh6w#E>Us3aR2x!>$kvj`Z-4~&X8REzjw7O_8#AP^kgNB ziytjeYL=0jWsnUca^s?6yTsGiY>L{-UxXeP}fZ{7y}) zM4gnVga1I}1fB|cJ#5psY7p4KY&F7KC&C(C=BNHw=>WcI`?trNq&nagF%t|>Q4CPQ zjh;gBn-+Th4=PRmsRv#qo9#uLREsvDS9m)hfXZ9kpQwjq3%naFh*hg9SF2)jeM1al z(LML<+Pb&}Iub+uTeSkI7Cx~D(=IpRl_q8hX%>2E7U*We#E*%2uGqia zsze5OUM#DRv(kyP!VbI1V*}qQWzOq)S{8VjOkV0Vh16+S)!r6&+q=Yl?q2RnZuaVO zmwK598xmmy4j7SZ;I@PV_rpH@0Rmwukp4BQ$C*gtOgj7Dm~$b8P6@~EW!1bS&=d;cr6~0BlhWcMB?24KTzzf`BQW9HtpnXxP;~` z^?*K-x}p8{)x?hmUI=?6?Mrmqmtf8nBA(Hxy4!oh)=!gwcbmD(Lo>7v&A>TVFTT$A z@!((UcI}xC4GgD7{dq3=JQo}~BG>1JC%pfjsu zUf4@s*lSSMkJ+B~abDZ?fW5%G!Fn8IY!GCOtFG0(@lD!=|GX%t!xSTYVyqU|Zs-$Pc5=122wEx(^D99~4ktTu)r9 z{HHXrF0@+yn~EtE6DSv zPbAQk1e$_>L*(RHPZ+T?70V4=T3oF!StpmDy4`kHU2-o%6j9#Ew{zfpu;b~aW$%^nvhfz zI3kM3by#VGd-gw8b3ouewnUV;Lo-oajq^~%EXAcu>!C;;Ti`{pfw`=#ep$S4B&I)} zx;Pp&x+!+>Qs9*_4}5sb?}xX{rdrE-CDB;7FI=m1+~m#Bz;oS&241!#mn~uM3z2JJ zrsQa@){d6{3~qcA}a0h0KC!c(f(SU z#p*jj@h6%_<=T*38z|usImP1^I;Mr6_6C8e%+Ew@ltgUAY4^j=eEt3F_#`tQ;5}p& zV9rAAoQ3GAi^XH>Uq1Xc-7h2p6le7odVJEJoV14+fygO7KdQ;KpH~$KbY;)jWs|nc zCKMPg+SZ$Qi)HG6Zv}zw)Pa0=BHx{02oX7f8paJa)!C-0PhHE;Tvn6H)8&gDK1*nW%Y2~GknxgdCjc>+x|(ELl57jE29YC{+ig^gcrhJ_rPQvk*pMs2 z3r~m~QLb?HpxDZV(8N5J+%_0U8Vpn@>&MeeKK^u}kIhoxrLl?Us;}uPz8wBR+*%Fq zh(2j{el_qCSeN%3816T~I{#H~ADUD07AdAi1)y?>u>P0z|oPtL3=adV_flv#&BTXWm!m! ztU`<|hKjpVc%{>?%PzLhIvNe?8)@jdt4{8!gKZ;nsy8_X>u>RdD<8Uaz+-_raXD#S z4nYr*BfcfSP0AmU2E>Q7iZ7T?3WV(hM2_e%VyM~+^;y((25_3p65jn+QCVEK>s$YV@7`E1M)mG=K zEv8Es2OXq4geoHjZW`oN3p_U#bL$sM>KAt2EPK$S_KQ{Y2T;798pgpr1SHAGJF zYRAONFPR@e-~;xkGh|7IcryKg6du&j{ZpY%yG#KNTqV#&4mV}urVN9K$O-(c|KG*n zfAxTvN0)PJ?MbaYOnyX;IPgDLbQTyzmiMQEf&YUgDoZWfte6n5r%a?nX0q+!hDqogLzAWvWT6Jq*xOaTQ za-l19N%c4($Ax!H5IMy`ngJfZTU>;(Vc|3u-i(JIW(INMx%lL$(DUbSx&iYDV}4ny z{zbIdBfaA2lx}rQjdFYK3A{R1N`;%NhnwSQe-!Tyw!2&tG56*fXyO~{l2i3as_@k~ zM6QV@C-ZiAl*a(kmp8{{pDEFFn9~$_cT5OvYX|sYHACYTdP(+}O|9?dw@FvT(-R*vNx5GT_hIp6mJe%oW zziuoBUL_mrMlFp-EetSkW$+_ON8)~6ALH=^6qi!PEz?QMba={$oMNc~J*Tu+KLvqj z*=!DS?y3bpad~IpK5B`IFJI=LAMgs8fy@%!jMUwX&=P~?pHo+N|8V+>gA3|_ca5ER zJY}hTO8gMxHKkWno~+D-1qDRqLqlBzYx%n?TMnH6s3qCh)GY7*K1iRVyA6xhfvdmka z{*h_OU(sz!F_;9jSmqmomP>+`cRrBm75!hg$gR_E!;34_&4nqDFroTETWW3^WSuaQ;Y6}D;>wrGQ&BzStv)@k6$qLB{3 zd(Co}yL0vL&c!2r`}^SG8Pm&Yr%&E+1Rl#Ck|#@&CwJ~|OrhuYYg%s5kI244s885U z5_ZEb9U|8ci`wmutz(wUZjv5jo+&4a+nA#$n}KJ|On&^sFh z?qk*(C$AVMkIMx6u=u6-=v*qTrIhtv6u)|H_Z3-E;i|VVNzXDzjD}PSyl$_ex z*&~hZL8f1rUIQJzOdZ36>EwZMd=ioC@XoB5fj!H6=fI9T9hrPBk}ur9kH`@}&$f8H z-nwrNq~xq8NA)$1>SK?u^}x;8>u&xLZ?9ui2LX&LBnp+up4qEM2_fr>uV3wqZ&YLqv>vuIw=xX zS`ay6<*l%*4xezJ)=*ap&UM2@(8%CX(6%V&V* zx2$Sz)KPELK_C2Dydu5l`hBJfb{4=p##)#*T`Nue!r_Vjcs*!KQPRynlh%S_54yg2 zeVy|4bzlvMoMPGElbXj~TMq(1vbf`~ui~$ddj%h4@Jgv;uV3t$^w(bCG2c}(Nm4SY z^8)PmnUzXAgZ)8o2Hm50s74+NZdgM8OP>71Y!=ICvI+C3H-pp{`ik0XTP{VJtm+A`V-2ce9Than58(7q4FucF4n_OiOZ zcc9Xwiyp^TkYg)g(F2id;N^c`w=B4<3IZ*Dj(6NtN!(N|O8ODLw^p@ZKHt+A8?zl)$kga`JZezPs3X;cq~ELM`IPW^!XQ++u>r5o@crp1NA{8z|0Tb1F|+Jx^Rx zyCp8EC7C8%?mK1#@IJE$5VcD&Y8OU|&wcT5>DRdf)ox3Z#&lC6ZbAzYImL40 z63$dsi~*t_tv))|l8&|Tpb1L9`sD5a#YxoR#H*2b;Y*f?oMO}U zbM2%DxPm|^m+2oo5fh1@?;!1Qjta?90oRVm$qU`JGjsZXr$OEc z){$#kD%Z5oah~Y)iY6?r;|_hV@Q4H6J(i|jUafU`HD=-WWZ%=QIeWd@r^bLhP#i>K zS(Oo~GJ>O}h@9ekd+t=P+*1g|J2a-GP9dpNVCfB!BTAj^p4XyL4w^$)QdOj{StKs0 zg-W$k7rV^eGNDd1J!w@-vDzZu6vt4V1uCRolc9Bl)BCOtW#cjvE z8pHnGG^|!=A)TUiD@ff6h~J2uz(=z`-6}K}h%aeZ+--@waAg@HN0gr3Ubx-%GZ3%S z9QK`z$~zg5h{zE~eS7FMp-LboQ`IS&Bt;WaQ$&uquW--Aqi4PVF`iC=79G-}1H+BT z5xf2Bd+d5?m%EU|(n%UcNR+TdfXERiJ-B|ocJzq5Q24Wg%S}byO$9^v(Sdjqc+9vt zstY4V0xy6ioaypP>GHUq9UzA%FxsCqk2^4XH1OP+BmQWj`q2b8gWbqkYG9eg6O?-B zO#$9J79m?^Xts#2Q*`vg_vX_F#_70hw1AHI(6AD)hXe>89Yf?ga#_}JQ*78Q5SY)V z-la|Imo{NX^7~;&p6SJ%9NBv@@E$YE{yI_Z>qM+)9*Y}xb}rv^HwD^*;$t*Sr7k0> z%fQ`TCvLo+CP}AKZ=d1Kt-l(zQnVwco}u<% zZ9}Ss^bnB~STgDB6{$aCfcTxJbJcMFKl~uS`SBk|PD-nu^I88gXn(|_K(M`Puss@1 z=>UA;*3B>fU|E-2!0TZCA=Ra;KK!uK{4RyNVyCW3JAd7O2h@jA_5PZ~UlW`nBB%Px z*)>BB{Z$IYS~~rlRf)6kp$ffw$*9zII@!qu~c=;9HvFzqcaqtzg*=k!#?96E!dL#|p&#bZ@0}2PqZq z1VZG9n+EyqS+3Run!mF&qjml8*7eIN>wUlDw1xi1#*YlkZUTX+G+}a|Ox!2KbV1|< zJ{~-?s%FPGAl{(X^W2;~7uK>7Ib!Hv|HxHpdRz8ND}IK^XJ(RTW}O#Tzoq}%K4_)^4ipY z3XEE=9<>}DNn1D6`yyl5Y>Er7@g^mf$p50!QSfkCV*NlOfqmSDORC?3jeHXFO=cD@hr zs+jqEtyT9DSDoJ};j6hl4;3_7Rr!MA=XgL-n?!4a;%JJT;!LGExi?&o0`U}`^6%Fw zzh4X6Scn`^_Qv>7(+4L&^GjAhM(kCM*ozbDm3Zv^UY3J<-;cLJ;0xO2bbXSp4~LBr zIf1Kdoep^<7J$HmYz%96tJLmBYdA0v7i4y-g*;t#x*P;X(X{1>A$cOa1%${6yleYD zb@PswAh40ev!ZE(i>A$?tfqcn=tIfa{mWYC>-}@#OFFd6t_u`g7eGpY$O-JTs6_Jb z_<=yYN+;eyJ#tWZiye_8MxCn8?ouTS#1cAFqSlir;nUxU9I?B9mHCGanm}~M$6`RD z4WJT;rpOVemVSB@YM}+hm(*lWD3B8hV2OwvanpG$gdEvOj%)X3=zArlyHM2={#XFg@&N9$a; zTZvhOr(4(I@IzO3N9GRAd8_RY|4}=^7DRf{@rg7hk;Y&Xh@8kcsE`gAb$SK~gJoCs0vwa{ik?l-1&yqCH`kk_Vl&?o# zrRfqgFW{B4C{V7gQU2rm1N|{I7^uH{pxL4jP#i!5!}@mzyCG%SRFL*6%F9|P9)z6vL!^WfrZ_S zzPumW3IaV@Zj&Idlpt0Do^t54ulpT5@ypY1An+OWbfvPSRJc49krQ|(k}GpR}V>BuA(GAMNvWy#gC4pt-X2`PN>^t-YPM zwr`&{xsavTGY@wDsXIKPM~(>Y5Rq%%w@qUo?CPNc0-vxs@_vrw{T%e{Kjw&ITj-7v z`&B_;EcJ$G4aix+8zOQ7byl8KaW>Hdfi7$oKUie&K)jdUMIn|x;ZGVf+g1!33<8Vk z0A|UOEMWiytRuxa`S$?znJ z|NpIqx~yogF)$trv{bfY|EYc2#%BwG=t{S8K4>U>5U#RC_GD+W`gt+%0fGDb3Rz#yYLc@WmZ}grfn@p_ zKbv+}5LnOrhnuOkn<>VUx`9`zz$5)tHTyQW1MeMETrI0mEgsH!CxutzPK?sJtasW2 zc;So}ETb4KgX@Qu?%s@u72oj>74{D83sftSFh)6-d! zr~mh<0FSfDw`@SSngvo;$fSp>w)V%EMh@m63rK0nUYsR<$=fv+`5180h_ifAaK>s`B`Bm zsW4Neq#urE<>)N4kJhO`d(ZqwmbzM&I<81}A=OX~UWIgxu#;J6UE_Ng2(>z2IfPM%bkuP~iN2U6W#y1ILRjLM>0MK94{%Ehfjo#Ty`zM+MnHc(oyXm1e2sUJVO7Wt)`CHlg#c z9)R_E)awC`TmQ0xj$~4^K5IzM8iL0}kb1V0M z-S%xIXg2xTk@_i;`YE0FdZax%Dz4pH4f4)VdBH{`Sa{|;?_!XYb7ih_whUk^kK22O+mFy0fUp5__F4rv|ghf z%A-JFFYIYTE+ZBkdjJ}66TuKa&a_x&q_(Z zH)m)u2yGfDbmxr?c_S>rB60$4Oi%f`eSZo953$rRWr<;mxDpd2Zd_eH9QVcWO%?FG znTb`el~k|Qq0)YMhe>fK*Ct+V2A(IYCN6H)zPK5)3r}f0@UP-Byr+~8fp76%qsef! z9;wy?6GP-0xc70ZL1Cg!0la6!Ol+T-{ywqXxiQdgBs0%#rUw%%$ql+a+ z7prw@;J{HSeyhg~0mX%ohCrRzoxJa^^#eJ@>IQ+8*Z=$%1O~D&)jCO|brNpn2a2yg zwJhq}U-q9dAn*`fUn!FzWipUoAaVjHrVUgcI@%nFKD5ip8YEdmNckvo#GQ$!|C`}E z3p9u8|LjV}2IGtkSTg2{Z_Zn|S|t71eHjRRK`kdjNhLzKWCD>BD0j{A{`UB_ATW_x zO|iCev6v1gis^7=|KdAepR5C32vh96Y_Rt-TvECrt}w1Mo~gPdb_4LDnY@#GR8Q`~ zX&)_Ccna%IMBduE5gJ%Y9i68+@f2<`MC2McA-&%TFAstEmZr_kHl*1`*n*(Q5t}`i zP3iw&6KKvD{&Q#wRFn!-FjizL;it2nG@kS-f9?SSZ_yxCZcWOq!E+*V0>Qr+DX>j>sFOi6F3!Z8IH}S2`-DuXVCmB~Pt6^!j~#9tiv91 zQ}!PxR62i%mfe5(Ahe1J-7l}WUp)0yC5yTEddvE$S@uOB)Qg6`{8c1h_%N844C2~WBf8E7-sqot3#Ld4rgYx&|Ig;_u|LL>%PCi<~1Uw550+X{*g(EQ%lhWHBk zJtC)Aaq%A!+Do?sv51afsvSwS10o_vJh-Gl!}^XtXs%_CBzS>-@B(}!AH*YjZWoPp z`}R8m0S9{e_ZVW#41|t#qS~U zdtiwLkt0qU{nh@KMlT>fqpGX6lPcl!6o?#gLr2bHa6`Y zy}DirE|Y>fo&Le+UQ8qzCY{e)T3mhb`?wHokoT4}50NA0PYQ|GOq>YB3fjWBjU;X(M0!My7(6D?;MUCf&_dgvEo_-8X_?yD zg=CH$s=M6W2IM`Z34XCGDVBw|nh-g8tClMoN~bIZVmnQXOB6|oA|yA695F0x=HPJ^ zYe4Zu=51tx-9+L@M+@I*CD`r#;VNP8OpUYu-a?xl}&l&N6Js#TzndM+kcAl zoi6d6-q~v=L@mBoIQ%ToeAq;Ju}|ZrbdR`@Ty$X{if;V)PTS+*1-K5+WR#yvp?Pwi^tKIQa8D)w1U7l^a-CZCMS%+ zTO)D;e>EBUGBQ==0o*y&UC3-2cag?jVAO~lae>RW>#;kv9>4_`EOvW$*YNI+FMziV z|EAOx-e#;%x?}6*`v>q&v5oX$wcT8}1J8`4AC1 zXAB7RqSGm2I*AZYvmw^mK>w)f&>AU>d(^Ai*DMEJ%UB1crt`s|n-I1e;evhwJW zuKFYKyDRSoW>CjIa*+1KKO7baV`%u({?BNto)MRkOT{(&)a^4rbunKAylc#C{8mW( zR&-vaZL#=AcJgEi|%^8@8{|ID{8c)xR=(Q7g$Jn!rg72@wuXEy@gD0`~#0l@%WqTZ}5U;6!PaE2R_OF@Dzfm9aiB zgno3a1C&XC@X0nrZV2x-g$y6JI6@%OHHVU&q+}4WGF>3%(E_eckJJe@ zD)vb>keR^^Y z0r!%6$AUm-nkrp|H3IlSg7M=&PUt3;$9C!IH$doJCiJ+f#&K12Va;OsX!q(j(tqhK z;JGuGU9?TRNW25YP4O*N{>R3+(%UAtfmhEwPPvjsx%dUFPd(yk1zwrZTWgood*GdB z)2~QJvq%S5mrfIBnjd~J{#DMf*Ei@)I4wRND3AxjW-80bGqc5 zE+|Ii6lZPAk-0Fm7YMw^M&`^moip3;MCd)mGTM{&x?{7tKIjbs>!>3sB&3jlKtxX9 z)?3+MmiWm4(Hk-cNI_|_Rt0gU~JC{-8-D~8W!vx+#7A`J2DqVC$2l1e1 z9krTg-JQNXTfG~2tt@BHpQ@8T703EZcf8B1YQL*E-ynBFGH+SD#RP+PkKjJ z+-#45fq70-uN%9_ja?8Q5xIe}SX0(O3Z97@A@<66?V z7G4WLOp6%{}Re8S1Mwi(z?!y0B*oDb&}NNz8Lh>yrA9-%hr^~>&SfOv$i zWklMMNIM`Ra>UdZBcIR7-U`I`Gy}X~K`vOpgGS_tGXIUKj~}=bnpns3q36b`&y8_e zrd|&7@~%Ex|9%(X0Rnw!u*zIbGFL;fiO318ygBjmFHOE6Fob#dswI-DC7rjiGF&Xx z&yM#4frZqp58a^1DW3ms&w}A5*Fazai{q^; zwOUtV%*a>7*9y0kJZ#xil?4Lb>Dt3JIdV<-qzob_Fy5kK=*YSGATWuUO_rm2mUx+B zlEQ0h4o!9$87up~1>PxE4M~AWY6QjSXisk2lG{R05IMzH z9*%CFzrX84xMr0_t9&c{d@EepdLn(F+Uu3Lwe2sy3cNZtgn|01f%<3+A7x@_$`o&V zaLx(sfxrvU{psim=js&B#i$!B!B5Sex@D!)B0c0Gm@A!mpVumXUJK@m$Te`(x`ggU zcZPt#n=Japo9f1!;+)SM6hsxTIls2HPs0e{E&r)E-%OJKe`mS=bS(bRrDz<`f>_R3 zI#;iBF0NMviDv}7mo2k+J#q=~PO}Hns;1g1erWToc;NBd@X5`Rpv};ai!@RsDv(5> z%0=Y*@zQYX@1;Ao0@0mDz59yfzOdkd$Pq)`E^XW&u>A#%hCL5GJ$ zhxtGgeOZEYOG)dN5*ndj_dse31AigS7kc^uub!pP?=~pC+kgpEJ;C!fy+>6$&P_Z9 zii@D4g2kflq^3K(V}QshRu~r2C}k53#0=_Q52%v^!mT-o9C7xN?!P?nPXJ;Xjb`l* zq+R$>3?fG~+pHI%ot_9yjAczsUZa(~2D=hVaC1+4q5R5c$FG3E_ta{&!7w%@HrYJ=*&wou57#vx};_JO#y`xbS8`iVa|> ziz#x7m**U|O|Y#7fvv13nWn~>rnt=WwcmLv@M3;!xaGZ%An*eXJl@8{+ZY5Qasnsn z9qlo7PXiG5Qy-TrM{n&HG3{FAT9LXz6?i^u2=B@%-4(yC=p%!l5FELsW`aWF5ZE?r!hokkF6h7% zy+Dy`;MqGy+mD|d2?Ad*ffWu~6%J^HFJy3y`q#5B%byN40fCj&xh8BR2^)nBh$1I& zNsG%bD+W#lVl#ax9onQr_-GI!M>HNAnfXzA8W0nx#5N1kW&tw_kt5Ez?&~;Z^Dby& z1S`Q$m>Hcg!?fW}Z@d#@$-A}JoP2yhU?>$Byodw~2Rsltfs5Pq?lm>~0`V>-daWT| zYrqd9a>T;mQJXr(2LiE*I=Tou5+URlh#XP6fBV7u!Vn-nqUk`TmP(}-^aYV4#+&v{ z)sH+aJZEN!_Y{@yDdGaFn|Nr%V($qewJ!>I=QMxL(GWxJ5JOxaJSTOH&b^7l)KmsM zivq=;sdGp*CaK2ooDn(2yUh{{qc27S@fuC$&g~}Wc7tgna>S|feOtAED+kT{+2l)H zWSqDN=ZcSbhT-$=EJ^_J&)WQnvNP!)!z9Dh~`wR{nX*uc@2uxuDk1CR*idZgO z>4lH)Oy-!j*|N33JHonrLR000Cf1OLrEbumH~E>-q!s(>fOnAj%}W+qmn_g?1I2|& zmArDD$z#4k1D{gYexrNe8{Op~v7yK{FuFGMFQ=(pOJPHwg~x-dbPkG_nkS0kv0YyG z_>&ENO5wF%nr%kgl4x7721HKaokz2~j+@vY1jewQlp5-n8e)ENQ3@{-N)Nf0K0s>_ z@Xj&APTlZ(>W0}=+Cy<|X|L4XBeQ&Df%leG|G7?DxlY*Qmp$>=&5M(}0!}oj1J7mn zPooJ~qaCmYjmBB&I8FJgHm3DRsvZKoXqNxDI{fbHfO@0FV(G_z8-;{e7uGIsJq$^Ixw8fmf+psIgY5u@>HIpvVa{c~R+*`pZTj zdiNL75N~DTEiA7ha>T9;Wc}^~+kkk3#@cp5+J%ozA#%h7-(4>|EOtW^n_1v-wwE~D zD^b>uCFNlWc`7B-oj_nNb#Z}aB+v|!21HKa^uw8dS)KC$ViR>BAu~wG46uGgj<`Kh z%FyuLe$d>+o=Tj7cANo@c9SATl;N@ki#n$JgTOTEKwQj;i*TL=krTKr__XEzJs}`4 ziJ3$B0{wDvBl@y*3mxqtuJbCUJr;QPS!MKk%i!1I2fOm+&QY@oj-HU5taKa{7t##P zUxoOqK!if%6fbeBcUqMr5Z_P_lF_|yMt51*rKHFaH(2$G4ZVK`i1%rp`+Xt#z7X6$ zB1hEK_HO>59|Oe0w9k+1$Rj&gSVH88>Z5FSEU$`%zO=DHOwm?K5sz`UiN`oq{w%(J z{+BoqSVI$$4~pc2q8^lu6gh!WN{ReI7o)5f~Uw=;K;Ej^tjmA{k4+BeocyIs8$ECo#!JJad9MzUN zSVU!rhl~zp-&u1mq6Qk6OWz)Fn@im0!WbfQ4fJsu)EwBm5d_9DXOrrnl`3W|akBUp zZ(#eV%8KD%fcKbr;R0Ft0$J?HW2x`7R2VfXU#i>kR#03|6$h;)L2F^|A##e#eSh6! zA13<TytOl9;8G=SJbtC@UQYlI)9B0v7)$Tbetz88lZJc3Gv z6owO3v$H*;w>U4u)!&IZ{LzXffz?uze=n~ zi4`~H3enUE(?O z`M_&rygVDNJn>c8PXm+bjE+?P^Y6QtR{*b>&HQ(Jwcm-~*lL!$OasBF5f9g1*H{T1 z38Rnt=6rHfxTqA7>&S+`8$DE)ZUN#;I$I9fk%M-ylz_+)Z}w6cmlC}NG`FxG*BR;6 z8DVMNLK>-Wl65$`;@RJOfcMzo=WHo6Rw*;aHMqDnc zAAq?-ujNf2o4R=c?<1S0{%h6!#g~IWC}C~(d2`%cl5hkR*HWMOy!*iC-BsYtI*Od) zRUOsFBb!cwzzb}Tv|^!lg?QESg}zVd^t*ZFe1h4db0F|NjcA@Lh^KH!8Icoc_r36V z%!Laeu!E&(b+QU|;wv;AJ@9_prTxq=CT~p!fv2gDePu;nSwWye0_`Ysbg>SSSclHMlx&Zy9UkSlI!J@UIP)nK?a#YlY>f=1Gq&*j`(-B z^EYk(H_*)6%)*N1XcviZwZ86?NG)u`rKSM4qjkW$!g80g=~`vt&Txu&)_bw@`jyv$ zT7Y+p`K1tb)e!M>n%N4WRGvh+;Y+3aSKzrZ!}&H(LP(HHk@4_mT3#)MIos(RkhIpv|*rDf?#)80mbT8+r5qT=S zgo?-s+%YD-s*m3!5E#IE;$djuVThYzNqvH8ZMJlMx2`W7769)p8<}HsRgcZZ$oEF6 zgDT!K_|53b?8U(IW$AsLs$QKc`Vjw~_=?56v2&GjdN@D>lc~Qx3?s)7NeyyRcnuJdBaYb@ux9C$2xw*) z>vo=nTAl?y!1O-e^Z_pUZQzj$?v=p1$I`W6L)~CQTsFEV-9`=Kt!2%rsQPx`U1Qze zKUrh{WHg+s;x~5!A6BK=YxXaPE4A4CtKK82-lIla_roBnCjFZvw^{~xZSgAKy z;Tva_{R8M@3DH_<5mPA#JZEOu&lVX!6AN5t@rBUg@}?GDHI#vOnDzIzh0bjYT-D9) z<3%6eknLl7z4=2Gc%h6}qN7}*gC+g-K3;TO{D!$tw0=Aocz!Hzxv8RgQw4*gzwA9K z?|hcdAf*k%fw!M|?8v41kxQ|9^cm1b<%NYW>+`T^B=8=wx;oj$I9Yrbx>PLGm73hw zZ<;#^c;{J&y1hW{_5yrv=Lv3U$VQcqR(moHc$v(SkZ+yb-w~qG$xr5ezjpn3L_(U!uN3=e@)N9%rKOlagImC(8fk=tVUTK0NNvFwpVv)UfqRe@wh*3GW1Ev z7?HI22^u7+7^O%WeSZig7xB3?J zYNm!}xW5089({6vSHogP>^w>Ayw2wli)UXOX!%!x&_bFT6IcX89xpqn7J3S;b{CJY+Lv{N}#3r*a|npiMH zQZNI9!4GqAGWpPB>8^U#N_29c{zkDM2@Jt{p8EdyNrNXNrP33 z7HQFf;YQ?$%l>d$(PisoAg0kJxQ906q3}TvM25jZ{e56M^|nTH233b7EC=3aR*-*~ulZpDMs>U@$a%u+LPF8dvE*om@|W;y{|t2H24RJ8<2IoZ?D{Wt$FoT>*hnY?3yw(raFY zjyp<>Lt+1<>v-?W2Hry!#~*BwJlN8C!C>ly*DA5Q^FVPK^$rKD$N?*G+K8Oul;VfW zUO7Gh;yYUCHtiryJK)6wM2^_Bf9x5vh9V%k(v7k5MWlQYRC9)C~I!1H1`Q`BaisLhybcuC_Tz=*+aU0lbF2i|QqhIN}Ib(=e% z7n^{|O=|wfH<05S!2A)pj$|*}Y?A9Z6$F;D9QCuk`e*Tb4kcpQXXNqO zc5L7x5ST(|s1Jm4_zAOK{EriQ=~QrYIaw;Sl9^()wMMlyW)j)rsp=svYI_y0ID=4s zn!*P;k|0MY#}PS!$tznd`!%=$F_Aiwz*Qu06$EEQj@az5OZGzbKF}P&yy7c3APc|F zPAu5-Y~h|^`$1$SebkQ^lE=c59U>?4@BE?W!cp09154-{v(_YP%yqeuP>|Qcb z(sS!y2fQn67Ti@+ysL)q-z3X7QF(9T63mOAcXX2L=@WzOo!0_oOHs?nufWWgX3}o5< zktN=;dv?GD+QL@_iWhB>9?S$CJpB`@kDPMxfjGEqia&?*W0oXl5uHzB&Ovq`80b_sFLhOs`nu zatK6L;XQ};?6n!bH0{knYuUw@f)6|*G$kg6L1v?GQ|6>l5;P9y$H35p$>$zzJ{|tnJh8m z5^=}0?s|W+FvkygVC(p>B}PvWqc`xodv~J;`Mfw405k`>JUbkcb2voIje`U^xRSQ( zI`T}o0p;_?9_kx8^hOR$B0;8nu?renC-2Gvfp=(lT5YCQ&F^mJj*h@Xd+4)M;du>Z zATSqO_zV-2VFCt`AR};Gp2=?-O(Lamh8MR?h#CsvjusGPh&BtihR$h6rLapz1N^2v z%1wKS%ap?BHSWCGHFBJ)Ch*?T0JU3Es#}tnk#~r=yta-`m8y=qp!h0|fI{?TL-e7_ z1R2HIZPWFCMb83(b~NKtuvEKXDcO$f9TAQvpUx|ZiE8uz1%bD4mD?mxn*?m05M%`E zdmXL0_IwctJVTe=d;0|U_6@vsF~;ey+>}AffcJnZZjo1LktYWBp&$vjb^PyLyBb$+ z1;tr-*1O6fS2<`xf{fz*!(F${I%om{^J&w3u#ow{A7jerk1@?#Bbhqf)Eszs=;C81 zDPbo`{E<6iv3QPdUEk7p$nZ2Mj>k(ygcXXg0t-u!QM_TS@2N2jwjj`j4nvRAavrD2 zFm&O+cp(um-m7}32MCPC1~JVPrJ2IoLy!>|k`iM+VZR3m{7BcHCOO$AITDpt%8*Mv zUuri88V&UV-gUZG1ny7|a{Z51xfWTU68H&}Fiq(lnP&dv4SEa~ei>@LrxrH+FbY3Ra;WM2{Uqzk z&$m{XjRhVJ?4K?YJpI29;BC-p&ON3&4rm{!32|Ae=(3Vz)>`?^3ww((YN9Ko%HU}i z+$SwksD(R|PLL^IkeA5n_(T;D*g_pdS7TLIW3olu%wK{T<)7l6|86qy-08CHu|?N| zPjR^quf_8zDEy0g{hWoM_zG^AU$W?zEVLj&MsezujP>?YRs!(@?z@|drEe~V94|qJ zSfZX4BR1F$G+(0OUY?Rt9)Gp|GQa=ouYJrrR@4P}wscwcIHKsmzk_{uR2uH%#@2hI zq=vZz?-6yCoYx4P|IbxAd~RyM&dZ*_^QZDc)fGee8)&aboyGF%OIrQ>#@+(nHR@k@ zZ`1YWlbF7uN!Y|`R(@+pwTlK`H%%wlFPF1lPUdmXuvjcFTi7B&<-jxG)ziTrU@izS zA2|5G)TI5mu_Y0BH8flG(@60rpJe?aLcShQdq1gF?dwZuXfHgbeXWtNHP{7$Ohenh zo4mZHG=~#N$KZD>`R`W5uc;9tyR=#o`YU>u<^k^$olF@=CS)90g{6HOmxU|RqB2e> z`_e~Hd=als`P)%Gx5G}5QCu|tm$mcJ3Lw^Cm%&XJx#_}CAjlBk=ndL%qofOnSI2V+ zaz_p1$Zh))WQa3MM)f}H>4qXY(>}hkQgCJEz>OkB)4;)I9fQlk#8HPTe7REia$*J@KM-GY^;-)qvYkVJP~9R59!Dm^Y>j*5a>&-f3LNCuQh2yUop~# z?^V}rYO|06fnTsY?6MEJ?1O1SkP(<(iuOd9Xn?>xYW=f!DQE8@D|bGhBQU;xd6HwKoMS{v7&Mw>26Mk&s9AB)40va0TbJ%s zDcwmtO?z>2S7ndxBIQvt_5;s@E>A8SlwJ7rj)x2hz%4yfRwyhu2)swMsa@>`tHKW{ z;UlqF?C;gqyjp1KU#PoPt@h_sWHti4h?18txMZapWKlCz=T|0`;{` zM9zdh2BHg|qLJHBBzIhrAVZv{YwDk^^c09!v2{(hLCH4YToYu7zwfZkTDG$Yi0L>2 zXxNP!cEeIjkRk3r{##)_^MnZ}dl!JSD^i)Zwa~);CtEc18X_unY zF0$}^kqE_;e(|(L)nQY<0k4T#!{>)(pC2a9#aGc#Jfo(X&eM(FDUI_o# zcyY$=_*JV{!&!p6*jcY%iRxEEClh2E=D!%9A?oMX0kHzNVDJePd;(ltf(+4EeX^+g zTvO2em9C5~x^gc3d4jLQ$p;<6yLvA;9zOsAoA7A3yAa)7I2WFN!N>?a^02P0RqZqg z^q_uM#&(qqJ`d_H*@Bz!=-4``r5Vm3FcRlYvb9mRHssO>G6IdVWuNTabO{7TP+$17 zn#O1T!MX@R5MH6SZW^{reRd=WEQOR!tKt)(QBQ=#`j8Q*7Ps<;R2E0f!8XKM203#N zG!bNoomU!TWAdUw^T$d3Q!hGdrq#Z17bEQ;R!h>?vj`jMuwR2wD?q!O+9Fip!V?2DWyB7$Ql(P zLoSlmjq6eVr1}+jLDZA0I<8oCoXpT5{#~z+r#7b^IQyHyPe;af{0bQ|C`lyLMYQmNQL8gG2`R>tCCZZLPS*4Cmu#tMO5lMGP^G{0z#~a*w zVIfxm2W4>6G|Hex8CaqSG6JpA6rSo9%7MT(>e-}h(@5Dy;`mPf(d{d<%PeONQ30MG zZJB2ql%DY)An}v&#uKGt?Xb&^f2aZP2DJ@wt5o9nW6A;iG3BM>D%Ov?Hx+nisOR;5 zli>X(C0x3`g~DHULrt3B@4&OAyzEVa?EmBa`CH7qF%EN}!cRtX^XZBbx}pR*Y=TUM zy|;<2kasiyVjQ+LFZIz&E}SOF5L^FoRF<1#2$~(~@NYV%+;ohrwT@Ec>qIICG#+RL zSpe@kb>%$er9I_In$MqqFsOFb&G0MdPJ-g=*spmkg&s@63Pq4nY#d&G_;ar#2y}u8 zivPh0CmX>xn}H6M&w=8eOY?(3;5FRG4XaVZYH&6QG6J*yzH*{|{R6Iqv`;eBlr#8C z_1F1J^=2yh2@8B50&jZ1UVD9k{r^1*RbrF(yYJ)((EAd{JIzN>^ATu4f{fmRuTf*| ze~SlsO*9iyrm0q@Nz(gYN07C zo+dqts7Dd9Qv?}e)T-p12;np!mSC5!Ru0w5LBLOtA#U(c`DMAb6pENkCurSamAb>k zQA!s7ikDie-woRxr!@jEjQZixQc}@UBv}*2e*pT%ijkv~cDI1yQ0!jYA3^p8@S14sd&5fp1|Lwgjv?2olv|glEMNQ!3fP9dnoM<+$pzB{nF2Nio>^+>I<^w> zT{uyiq==HZL@7ar`1AUb$OvHxASU6^gM3#ZCCn+LEOr<{Zz5x_sXxWWVt)pAYZy9V)J~m3VCdJa=k_yNw0i z#sh8Am`UExoKw#LuY~$jw#qWL%EZMjm2AU$$9-v=DpqhEctLcyx=2X6NRYrgXbd@b zxg=D7Uw%>oRJZ}VkUbWt#{woYL8ii0%D%lroL&O)>1fXWpI4DSuL3PYkRgU7*#CEN zW*!g=1RU`-Jc9y1uvGN@#*l61U;R%^=>rtAn|5Hdu6#6qFWPIA5ANuZDqmjT@cRHl zqjA5qXrLA@SSH8_{AX?KU=`1=AkdyV4n9lNefaHaJK-C6MAUu{R1CD~0)h3|#@^kA z?rsCuh9Dzwj+d8|Q_+}D@B{^&106<+9eie@R^&VxVm)2AX1<;ZJO^sPB5brGY>0Pg z&!0VhB+|Bj_&t5#{h|gj-)`^(_#r8WUU8DyZ`eKUeCQYbPw+quK04$pj(oXmBLtZu zN;wVfaT>XlQ%y}>%YRxe{}I&={D*o*w>=7*?Y|s&{rs<$6XSWR7m^Bd*P zZzSobDj{+S-6rh*0yOKy)O# zb;nTSF{nx-MuzyNIa7J+uL!Oxw21Y_+V#d{OQUH7c}wHtj34(kL}EaoEne?0n4=5a z)kcDhzlVRh2!*Lbe%nytHovRgz#m~y8}i6uTcRWg z48d+^suW7)Zmkn!1Wpe9?q6@E3<6(MPvh}st;d_mG<`k10N128s^*&JWli9v(&((i zQqW;J@H*So?PyoqCtXmSkH>4V1uEwD90@Xt*E<*1p0u3`0x#3q;wUceC{99wYy3ew zWB+pt|7n^AyzTw-{_#@5z@Wb^Oj>9{-)A?dGYGQscHm z`I7N!pJ$EotYHumWXiYp{+M-%w;X}kif3tnCJNv_&qa_S2CT_%QKMU zlQ3uqGDM*>xwWfiJp|%ioSyJdLLN#G(-UNf^KJ8w7=}EAx`fbte4>(Kq7sQS??{t) zw8j04ma2LL2z0WgNlUX8ar%54%@(CBFI$4 zT5NySExY5KVp@?PE#)9B-Y=G}!h=RHpnQeHFi#M8NsMd4QVCSbozf@B2pp?j-fLEP z5d=Qb>7Vn}NUECu;`WoVB!Z0S2+`=u^#Wcj<+UzWZ{;(bv19FUjX&K8R-Kd_1iZ(T z_X$aVLd5((9!stT)gFI2F+c1%6z~kTU8M@Bl>1gYL8gF9_0D&6L?nU0Ou9hbG?u+- zOa@Kr2=Z9A`uqUX>6Tf*tEGN%`9k?}{)@FW{3pS-^t4#63gCEd)X#ouEO=^65>S24 z&7qdAJ9_^V0Pi*(3ULPoaR&#c$TkXA2CPeO2i^+wSD3O4K3OLk2a z8T(r`tS5BPoLi}WZY9YqIq;J zBMH4ikRg82Ro`}~T?2^r*bwI)N4ebFi3Azq_TJL_CX!k}ti)w}rHEc}K`udtD6D2s zE4^16i13;Q)Vk3OHF8Js2r@+V5xHSc9_Rou6_1>^$5h`Q1Fw@HLp-lkebu6VDztY8 z?U`G0O1I=lPj`xuSC^|_j-HSw`#T7%#-{z%DfEi_z8^tG;NQ!tlBZso21Ey(hZ4%Y|b6Wls}$C2N0s0%@cIAr|WfQZHFDnDm?@OD<<{Z2Zyb?4qFW{>m#4@{?k`IPc-*1 z@Z9LUZ(5_##J{cTI+h&6=;^(hvj4ylQ2Yfi^;fOYRcqKBBFHE|dJdS&BmPu2JU&zAZ&buw~w{I@pF@V?Cj8;@zF0)J4Phvz`SUR1Cb z(lP`Y#WxBX=e!*L2#A$9SP6!6sPF@=-S-svqGKiMSP6axL58^c zpGrB&X$erwYP$BlJ|*}16bV?W#p|*C%#&ZNVSFJA1U|zZ{GU$U0%zc6kanMDP&L+JvKs<-%OXW^f$+q~Q>C1RacS+ori~ z+ksgR_%F*j>HOK=YbXr@{cxS_HIO}5XM&8tioz3fzj?}lz>n0$4}?up_#va>mgFM}#Bk&!NuAq#4@LlgDq;Rf5@><~8Quptnf#9LRz&z8T1yysjKJElwHBw;*@!I|2lmhUr%S;BcAVXRj#e~t;sr%AH8N;3amSGs5_UIbhV zk4ydesup;Obi@Q}>jZ0)jAP=69y}7N2AgO$<~IN@@6Y~r3071LRwT}DHGlCxCGSO+ z;+1c}J5MuZ9{;I({72gFyf8^<&-xtuMz3T@Ej)jRd(L(XvfTn_EC@0k;wpFJhy3y} zK>UtZ<_8EpKoAHMWQZf0lY|rJDbzx)liIEnIi(bSW%dyNijCoo@Yn0>kq!vFiUr22 zp?EczOavK$m*kf|>qUQpz&EtYnTM1z50Rz*jTHG{$-JUhr$$)L1zrpt{6AL-z!!M6?UtA7mIn`!Ak%g0gvjWcE7`VG{Y)kB&Qb@XL0zeVKg{Sb-V;|PBJz!%jl^f*z5l&`RQoMc^y9z3 zUL;Arzy3;p?Q68K1`6noYvQMe{PZ~A3nNoN&u`~GnJ6^^@jdoT!`Gp3?%UG@8RCo=P+D}WipC+czf!`rIcYdzZu0Mv= zLF|K<9{;mGXBZkGF$e^aCmOB0BcU$gwnY8 zhY2zQk)d$+n`I+__!-yv>^^jsJ5WiGAzsR{{MT}(C}@628}XK@;Fc-z()woAyN8X3 z%6!#h_>K}PYQ%QtOocm4qa zo#+Y_BPkstNt_@jiHF!}iFlhfX-D8J5SWK+QZ9$e<-mjyWCZ%3Hu*kSN*@H?rCyrf zsY!mP)?wCN8FB!4j$vwq!j&x`FcmqMmm;wYD;)&bCA2;3Sh|xHNe4vaTD02$|MuyllU-R)e zMQ0#3;2f~00rE6}i~>Q1Xz}kj-O&Y?q0)_XQLA4lU(YA4zDfq;Ry?Zr(qmeh7YNM5 z3qj|2)Hxo)OoEKS8BsFt&gfkMfzH&?NM5U$yq1har(xgmYMQw{wPJrW$LpdVSeD&j zUHBpKV<*1}IZ@u!Sg-pws1C=O^zhv%oI86-kWoE#xOuqm%4iUIi`wIkt&=vz^}6tcweZ6Xgnp`cxn>n zeL)%6Y!6fYWw-0XFHrnRoHNIlw9q9j=xBnBVzH6=8N16l;wx;o!z@r3_ozNWhA35* zzpVPm;ChJ9XbReWsh0avl7dbeM-sBBc^6&JEgAy6r*uMhBFRqv6Rb}qNFuoQOu1ID z#|Yp#(QbCtR(91Ufv_uoGGo%1{SO?oP(9QH7cl(@N$iCqHa-&;iYjG=F+WSN4uBX+tOep&x|)}+3=xiM?qi`Uc~Em zqdIOf6J!KVaeUCQdx1R=L$Imql|a1`aFmW9Lu@#mta0xAbuMi@&}ux!ytX4R&O#7m1X^G8o9#CDIS9N>&7HrxtiL)LI=98EvB0iGTi@7e z*&whR+u1TBRAvNg20=z(skXyT^DiHOScf&gS4Z!;LtX?KV%UTzr$_mpfS7;>&#hJH z7WaVwf($V&WSn)DdJ_~ei$>#iO2|%$Y(2f=@3ucy@gHh9vJC_#;??Tca`bCCXeP)A z%(U^3S+l(d1Xj^8(Y{5yeGBn>Kl7Q}ai)2eEwg(;;4M+k6bQUHM&IAE$?jHe@GQ@{7QraG^(*(_#)K@G%p;*kHyv~p!o3Ei&0;L}hXM?~v>L6bo*uf*n5SN6R-p_5E51J$Y>L1&#ri!knWQC5D3BuNC<@MlM zUf))LKwCUvK0){ZKQLkXeq)6Ci)brP?cm4-*oKzMqEaqgBghcvoeGZDU1tK?{b*F~ zW+3NgKy2Q1{wVD}o!H_%$!9=dBksaiOVFz&V0j2K0^O9KS;$Ow1ELe22t87$M+#b; zAVWMmE?;+v>?I&(Vbjy2fqJ+d2Z9W7e!a9>x$Y$>VhN4If(&$m42Y{*GM2nrCNw$3 zT0h4dc*T@=)kx*45jpx-JeI_Nvp!#+v*Xq^P@IPI`C;NHOdPUO1R2FQ#hhGhi>`yf zO6p4&?hzF38JNjj`+39jwncY<=S@Sfr>5#p`9t>C`4DW5<38;zS>eF*qcgfuPpwgp zjBY<+5~{@(T1HAOi38qq>YHC%u5oQSNg}-%UW!MAnr^A(kK6H3kr*5!dZ-`|6<9V1 zG8K_0RzCskhZ&lh`2lYRDKqvm%uhm-&>mM-NU5>g)gXGvp4iBr=0 zYSWKLD=N7@#x0n%7A38Pt|Q1OcBn8=JF%w&h{c$gDULF^4^|Rnh$f5N#I#+8e1$v& z_RUi^pcL-$8G;OPXWaPk6=OyNF&7h^4UseVcq>7MIPb>6qz@({Kn%nSR;(_H)rGKt zAVXAqm!5L2Q5J}Iu!rSqhJ3j%?hs^%%PtGv^z2al3M(5O4&{3U<$Fkk)92c?oRvMT zDys&(3OWwYt0|sWBNO`b*w@&H|Lx$EomaPNf#P)RQ(l%sm$}!02{MYUZ&z-%8LkaP zSKNy2VyImVj{Om2h#%bAw}&m92*i3k_j1%xjym)UL53(^ncdQBJ%=kIO@TaDk$SE| z(vL2qqww-K(mSxuYxPDDSc}a_yAf(P0)Ye>fvJPN_D#y)3`8%yPNqqsG%hhkkReXX zK9tCKaj36U0SnPeol;R5@ z@Fnf$h+Tq+T?5lO!XeW%#;))MUh&j^yZzou@x2x4=3?GI4lVJyS3LM3@L;LJ{~*3t zC~#dk@N~@}v&z}-2O@x0q0!H~w0+8@?PTZoBY!&m;feo-@0E{(dKBSN^Aw?{2plnj zOg+viojL!<>sLU`$7|$=CFsKvXhDJuQTgMNv{sQc&`j%*xLA<5cwh=#wfEPH@wYQU zo+A#b{7sNQ_f7>tMqb%Jnaa;n3P4^Y^)q}l6n%K#GirPyUc_}B&Sc$6{|o{>aRECQ zq0U9%xDaFnj?&*@`RZ^r5CgG8@^vfvx^*r*J&lne4n4HyRCs7DXwISTgO`PlmjziV za>fPVv2bVi<`pus4Zw?{L2=Cnoth1V7sX%cDV;tiLs7FA6lY=w=ei=g&V7o7AfxzQ znWIU;U7<#B>aY*yV}yLTc|wpOUQtYauO%t~q6hZ$ixdGHc6ifi&=*QrjK{Tcz+r zwo0FhlBcA0+vc}_Gf@NPW$M8@s3D|lM;U>rG#02V?A&;iw3HW^Hekkfo|Bt$W}txT!xY$Bk+mZ<9YeZ z_5ra3FQhq^D8~{)Q-Tcf$PD*To684)m_XdB6{wW^5Ns(%hIn%Oq1b;l4g#?gk8Kxq zD+4HMK+f;t#5f(+3)LG=E?za9WF5L>1! zHI&7rWeGCG@{Apm^Zt1V#QWHZJ%0?HKL!JWAVYlpX!hZIO^<+>LuQ{1DzbrzUxbk% zz8k9%{b@@YRJxqbs!Qt?F0CianJ0h7zxMCpI)T43Kwv(O2Ha(ky9{V1$Ov3xur)Av zV*wD~;JTC@LuJPxBTSGX&XfAnRJ*+hG^f%@5U@ofU<+{)-;5>4JuZrUb+n%Q1$cpU zKqN0yPhLhgb#IJ!$JTgV9jcj~!toO5I+`o5k}FTV=LG)VWcKe@9j;#g2D~D*{(%^e z#N!c}d_^OOUd!~*hTd~MP?2}I346w)p7CJ72r?Df_UGS6_g)ch8ae1P?&c!cN;ih6 zh9E=qyrTQ@)0~k_;AYbS_E|ykGoMuV;gjk^u1ZBOxFi9*chr4;vq|+0{~mY&|51Lv?)@r)4AIpo^7YQvrCihC!BDP< z%DMXo1R3J#b9dtlw=4r$*hq~0$m9NTBrOJ@>a{aIj zTxXZkWoB~bJ3wF)F5<MEB zULaK*Zl(}!MrK|h@Anls>|D0W{|xZLC@A|3=*sP`*Q(a}oLAt|*=!8P2@ z0aI6|xF;uY9fv)ZW_8reCAJ7M0+Vi8j41h@1jIya;wmc|1H7`yk02qkjvJwb*js@+ll^@|!5@i85*9mkbBj+1d+HHy5pW@=R0o_AIg1m47f zRMZ9(#YNTx8G$P^cDzum)B<9J0lnWH3g@NEb(!~&nYry2$GKyv`~`(l(7VwA|t zyCF^9k-n6scX`2DJ>bRA5@sJ!&ptv{p3+hN*w*X{Ug*?bu@)42W5rPmQPjePP(qB1 z;@EpianVnVfp`u#;e$0P$-9R^6;jmX7 z@VsbTU1}mIH5vG{-SVt&uSWNL1714i)$9_~>>7Anz~boiQxbaLp@5ZS(_}k}+79+6 z3L{g%1`XGh&0oHQz>WQe?(-7C=OqKK1=9qY;r4)njDc{`n-M0=y^G|FKh1 zvg6~oC;Vp-l)S`J7o|^WhTEF3RS70WXl$a8WFImW5wqCso1HWVhI& zLwt4M^u;rsOF{E9T4PT|c~AaJ9?$vbOWqnD70;Wr0eDfgiwjK!h5vU*VM_Rm1tPi| zLGf$60Nhnace#8PK}NAkn$|tp0t+A(VDI9IB6`9F>I500Nc`hl>qJff@f-H2sx448 zcSDXKL)0$0U;k%0N4$njNXbc5!kG|)46(!^cCd}OKh(vauA^^^Ro)mAkLo6${9Ueg z`g+3Qco0~J8!^uu<#G2V2{HozEv!0l<@HMtSV|i)Mo}q7k%Zsh_@j$cDxYm}oSF>0 zR=ViJns#HUD;ajB@S(&9yW&VY^wub~7nq zy~tC%0HjWwaevJ6-&!EgP7?&pR?^M<4be)W4(xh)uh}T!7An*NN0YFT%iM`FxpU?O z8O6)g$`g>&7!cS(n=o#jQrtSygw0aD*t(8il5#p^ofhz3P}AjnT-EtF$%wp=&c!oy zZ0fkRmvbip?Y`9Q^m>mV>t zoU2Kg845FlScV`Yuxi^Qp~~0*5ZF1n-@0b)RL$B+ny`bvQ!}kcZOgv;8^F6r`?zhT zLfc9*7B2EhAhRV2hP4Tyz-yubO80h^ZvJ(s#$oojWvmXaanlca0z7vrFLAd*;%*}E zf)I&2R9@_#@#^=NP?1P%Ldx_|nI6O)1euCVn=s~Yg_W5g@HuUn00|Vpx6E@<@(rCi z^M-BoDais}KJAk0YRcF7mtFFN%kY?SxOi^YKgqeE*bUG3#+9gXCD<;4jN;(jMcpOC z8$e(?ZNc=ND(U>)@iwu?Sm36v@GII?KY-^?Tc&K6Vj2HL+4W)MV)nK1-jasD_CI~8FkqXR)rtZc~RozNbV-@u`-tr2)DwH8Fsvy zx1nb4HX=br(Z@({SI5BrD2n@izlA(n% zv|yqTWCUJ3nISiMkQfN`p=)0BDwSydZ6j|!=9jK^7-bi#00Q&z0#JSem2=Nc5o83; z*|gc6aI`L=d-x?9BAVjlE)FE7E^o3-a8ssd=P>9_fHvPmqx}dsI@^vzhCF_yecg-tR;2 z_bq^f2^blo$IPxxe;?ZgL_3^A@HvKjj=_{C$Ph(#4*ljSzYj{7Ks&iWLApSJG~si} zZ`fS_)|8gGviKnI@@W(PIyv#z$u(G7zEB)CUc>Tz)*ku&5Ga0$o#qe;6e0opu>={# z!@utT6p(!s1iI0_t5#R4=5w3p$6vr^z4F%NO;eAY0fFD}+U<1`d2z`Lf{Z{TTQ~E6 zFS~=lhji+FIjHdEATc5_Vq`FgypIl)x#0)A2-?X-s|7`?2X^wTh+QHU@(+QRM1y(v z{TlB3Nsyj2#uv9t*tvsBQqwtJJe_%d>(%|%6PNj^cn3Ce^92W`mW+H3yjJQbb(#x0 z%?Cd1sD8I1_SD-XsPGvaG)BUQ^9*4+5o9XtoRaWENBcDpEAd2*F+?$j5aSVKhv zR)$$*f#zfVqp)qcpl$g;Up?1zL$Y}5XOMRXy8=Gi$VVH(T7rzcvGdoM$1ke~;xB9s z{g)vBB|s#|5YNt-Q?dG78z^q3-b$9TMwT*Z!f*WZ6NO7P_S@VT`W;Ro;+nMVLM^+X z$^;pKQZw3CsP_nf_#S(FA*WFY_s|bPhA1z6#-Zo*NciS#r(%DdU4#TKLehgq3>iGA zZ|0@dYDpa2KNPbj|R&z?M#BCoK_zBhGq^WKRd@GcI?uAf5JPtAqxD2$B2#_$P0_e}a7 zh@se(%hW-c+>I%M3~^#`gh1-l4A2}%LxrBrIz9X;;6VP_QrA{j`^q$Y~w|It1KOJ{qd>O}^)i3UfzTk?! z3NBn(Y!-nla21f(-F(+WSGi zZpT1#HPzgutk$JWg2pexskp+YpX$6=6z2jwM`|;}j8wyn$Z~Q>lx zfhL|Dcj`LsBnzk;e>iiMjLlv5+#ui;Qp-@eTTr=s;4&d`_|S|B!%*N=P#3)3NTc3} zbjW9sY+Sxo)7syj621?-6uQnvnaM`+FEKnp=XaF8=_$P#Wzt8!I*Qm*vk3 zh{bGAm=NLmrUV)=2zE+Bry)6*3pSMG`!L56tM)P4RE z)8E?Qt~ItGw=L0aOK@=sGQ{7`8@-m=Fun~Q@St&g!Fuh2_2iga4j;!)^wbZtJu3mc z_@VuSuuEFdB`t@g^$o(^X-Sp;yp{yTKk=X`S4ZXQFpUW^iWL;+y4D?31!4%UivLmM ze-wgHf(%jUO~=m-b0>i2Z?uH>bmi{xPpZ0%x{5nx%WC9j{O)hyInz$LXCi;kglwET zA@Z`bzh-MJF`snZFP`>xrd{oJyD(>VxL8g2O>0A9j zNo@pq$IpwEpZb1dls~VXWNoax8_0IpuzN2--rTVTf(+4k=RJYW+dZKD7xf12OUT~m z-%X9HrjG6ei)pd_( zAok)wIru$PSM#u&vI!~4ht8DhhiE1IvnW&`moo&b&ip~nBX zfDj`?^nLK?&rrSjK)ireN9{mSJD}188KT$pF<0(1FN8{idx8JKHo-zc(!zlU;Xdf6 zD$Y2%8RUJ!^0F7pWiJM&k02v&Q_bt_sWDrDcpkTQl{%{8_LvAV#K8~DH8%&D0`V;l z74kQreC`SlL56tk_U6>?mF7^wPjr0sO3U_26Vp^LoQ}ugw7_p)v~5oT?O_%V=U6OjbTqTJ`c7lrIhs?06XzF9YM1AXB~*YP;`QU&#exIjpxZV1&jb z2`Tp>L$rSdEhbq3#4KzND^8(`Q(&+OGQ^OXs5@#wBNQ=}hGl7M1Ziv3FsrZ1c|8@z zZ&QUjVAAXKH_e?b8h7}k61ijZaVJ0DGGkq^yD0Elsj*2%66uJzrC-O88!yIV_w|S@ zk^o-TZ~gLOj|yUs4h#pg^X@xO+N9J0;~&q^AR8291EZB7QxP|v^z`j>wLsu^y7J^6 zR?6i+o!%l!&aGW2b9?uBt2PKcPlEo%=+R;j_y{8-F#R`m?}~rt0nq^u!^o2;l8b-| zGQ>sp<4@08zW_8h(n$2Gr1VuuGL;+o?R%fyYBT-2R{}3%Vt_OjxIpZQ zHw(F+{+PN7cz0>jYP{33iu?8BWKx61*f=mIY2CLfJBpnBV zFQ~vkOF^LJz~Oqt`JuPi^%KCmPkG4}f@BLNEUj-WSRb8Ve?R9O@WQCQj@MC(=XZHL zc?Y&dW9>oR5*H|73m(>8+Net#>@`8AfG!KAgn#~Y0f7!G{Vfx0sTyoaJbQ=XwG}*ee5hfJ%FAbfcZp_Q5@*`UzG76 zUm(I+9GFjckE6TC!K@Qxh#nm!zVRy~KyxLvad*}!-QnH2JSjKacfPL9y=l*)LEv+| zPJFgPpRK?o5o82D2)z4nir)($reJTNb~CEo48xEhLk#J0v+$Uo!qu6MuE<47k&8&) z{3U;;XlU>e!&dKizzd+ZCVQ1aHvhrzq|uJpT5H<1%U1f90`Cr;CplZE=4>^>TJMN@ z;Ea;U@UBCChrR=^o+c5(_o#>OA*;N-fF$qkZu#x7{;p2o-KAFjy^_*<{(+BB{(+C_ zbJqW%x?)HtxJk5+19j8_`9V`W{2ne}Pp9vo({^Kl=S01WT0PxbJrcb|jPk|hvnMBphePV>D;E(xs90M65a%VT4}4%v1Tgp-qA6g zdS~QT(RlT; zlGbGiGvv!$fc58s8nGK4#)+W8n2rU)WVu)>W0P z$35f8tNenxtxKBBb_4G-HR+D)1&-?n24z+o8{)73It&$Y#B84iL>MLg<$ zj5rZv1;jd>t?4pCU0k+?AVYK*b+*Vy$`v%(9?`=8TB=Qw*rkg3O#;!x8=5hXypjAwDoaul;1oGyY4 z(Moyq%-rW6f!Kzfu3Q))6w*H#LEEU8oB}WzdENf)_Zmqnv}rWi?p=38`hd942T&uu%nL?dV; z2s}$oLza$O7H^S4`GYHOXC&8Wm~H}IJzaHDLRpLf<>X ze&Pn4x@lS02zxuIZzgtV(iKoT_vj-*roOFX%Hk#7o&%y6-Y|;NMNzttTOr60V-44a zyxHakntN!%>+3VlTnx~5`j(J&?)b4j4*fwtcmM>4iXU#Gc%PZRi2_Y&t=P`0USNCufN?0I>(V^&L8>LkD(Z2{J_G zaS8cO|8_tz%V>lWxknJWXQ0bBbMQ{#V2du`U8R0a=n2J8K5c$Q${knx&pm!WLu7sd zuZ~)FyREu*{ELOPd>-cZ<)206@E2V2* z(P^oo(<8`3q{z@}=TRPNy#f=q=k9)6KptR@M>R&2knokZ8T zpphU$Ox$q!?Ykl!(A>yOD={fwF{1g~uxPCLj844ME(?9&eV_y4t&Q4S8#3$9j{b~! zD-KJK^&Gz(cvq?8@KRmnr8+sg;>Ra1E?gTEiY~7L-n{|a-CYZhT7z0Cg)+9d|o|AX5*8Rom_i&0G!g!l@ljSuIFeJuq;auJ>EjC0!#B=#9-`$y!vh z77RNuBz-Q%;bOGH=Oz7ZhsEDk$zZBVWacwPh{<~b2!sn-IS?316@NS^_;_%jjmyilx_)e*GVuIp-#t8`_>f=4u1gVbAaL5Hj5$V= zfLBVBSdTU39&3`LVCDQR_*LO8j@Ft}fLBLT`p(;?I&UK}axH(4G}^H7n4|wXsK`Uy zf?qbFFPp&CB*;``|Neu<<_=qcn1)@i8%xoRrLbvAkRcwsnyI<-;ug^SnYv0z3Q|dY zuD(u^97yc?_2I7t2X}zLAHtkp^J@?K#a-o;nrH=)+DO+9-V=Q>oKK& zUt0O?2gU6;=h`KUy0{l;2r`O=^UH5G{BsxtzNRMW(owBTM~T4K0&?y{%iAE(lUhwz6M?IV5@z*T&F`y!8c)v+170h&Nr4Mh0v8fzrB#URHqN~BS^Vhs zccAzg?!0I#6m12gh9IN(KvVo*3r?2;F$#*SFfr(+;({{RV7Pf-GuXs`RUx)nH!O}>O5%_Zc zs_x!3!+%0b4i_;+7Nu~{co1ZWW6!wm(I^x930tB4ymX<$rd~A=_zcGhZ{hh8_yLR4_ZuVhrS`V+0xK;L`j!fHF_d>P zBojK9e2Uv8p}YaH+DwCtWlUXxYz_4f!62NJ&?b#1_b6(Yy9%4;N{VQxA1Ql zd>k{ZXd4J@z@bmJ70R}Pt|rI`^b?6a?saxM2<)K&c(s92wE;2;H!kr$AsE?w4d`l&lP6ksu>5 z%JjsJ(luv+*n}4hJ3VBl2SkDlv1HEXlQ!lTfas6CjOS|TIrm5}L56623bB3vb0d(Aaj{kR2D> z5@ZT^Gu2|lEDw%oi>FnIGAdDqq#Hqo`17a9+mWApfcOlLFIxzx;b%Eq{^WmS$Pb3D;`J}gZZLu$Fj0NKG35DmnkCDI{?iM2N$S8joKkY&zoQy3f}G5$I2v^G z>R*dNXd_;V5`;!22#trEXc!rR3vMd9y}G^x1SZoF{`0uX&*Q}2ejFW%O$zGNsLUR< z3wTAebIzIx&YBJMdJowd)GWMV2D}KGajDTzsL>$4Vx%jwwyvHY% zAM=?RFKLpc$kFUcQ_{Nw6$!^}e!)!o0{49gf=oqHKPz5{a7YK@XS@yFs4Um03~n?* zhS=0;@F@9iCTM>BNB{7NH!Z zs|Vf(x&+?dB!8Rtb3O=>8$eOEdN(#sZh!*b!)EcyR&-@6m_>q20XM9Pk?0L?1EK?- zfn5tx7xy7af(+65iJW0gZ95R1@p2F+iQ>5TT?jJ7%TWiD)0h8%A|_B*%*jgLiT@~O zg78@!=Z@YxIkMZA<9(tT(I#cNCS~Hze&!E$yt45WyBaR_3qIOOtNhMb`JFMzS;g`R zO!uA)*Wc?F0xtrFHU8JC`0&hN0sIU!@u3?nhU~bj56no~DW7*Mf8I?bM)2eCzRHtg zpPB1_!T7@VE=vYwaU0tNnJOpURdO}2+62UBxNY8Ap|{*q3IrMA@x;d)KFMwY%{g>N zIa|s)TapmFi_aBIJ@d6<`-L6AdqqpwzFVbzH<@`U{Kttb=a(w~u-yr~a+=Gs<&r>i0*(7BRw!5SkCVI*A+M@!lJ#5r z+%6e--)YOl>{X26U*vZi<&6#U?V4*HU2oEWmqgv;+eZ{{A0csR67L>=SnK)6#EeYf zdC`U7jik&QNs=n?l8D1CBeKqa@ZhQ};HA+Pyly*K1%60dr|}!$MQe*5c)3+Vl>=}m zSAs2uA3gZW1^*jUZJ+6i?}g`A0r@7LR<(+#mba1H1Wrm4yE8cOFi zh!=5hd_AtW;o&!5A~!Sx&zbr|b?cSt))Sty%o%Kp2OT!ub!1qLV9?PuDHCOHjTQ9J9JRmyFFl2gNiz=5$A9@TN%+U4 zzSVZnfs1=4-CDT}|D|D`aKpU5Es{au^|Ec|POEX%JM@$~^k($w*);TE()tYe3p8=o zpTb#xD)jxOTP;7vc-UI}m!K8GK`Z*UiU+B_-7#{z={hX!{UPP|hx!|3_=#^LCJ)(w z|DVVEg&)&WHznm>JGgH%{)?Tlu${4DpPuKB6O2Oz+wot{{wsX;-##-t=zPTbuEm`@ zv7WCIGG8V7Qapolg`I7C0(RlQeA1Hrq}4Zg2dNj$9Cgmi4F4r@>y*T;8~gMOHBO3o z7JeA(i5)2%JF>rjwy*iIvvh?e{!8Nm;l>61?N>hYGbVyFCjA3Y(#vY96FP?nV50$QH0W;w7=TUxqw3D%q4@s?fVUmm?n|y!>xjit z?mM@&Yj>?(_a3bKCX~|YK5~l^5fw@Z712S2D7vH~N+hDBsHph8XFp$lGy8b>=Q*$U zYiDQP=j@uH@lDb&DTZg656GLelf^g936qm~q4Q!w^J0q&v1K51L5y!fOd#v=N7TxV zr{q+fSBpG6mC6gv*(a2l^=F0X7IMe@uB1Rz~tt?*QUg95t+1HUiv%oLU-gBM_4HRU3tE{@)*~%FWxOPx)}ueIU;K5?GM9AXT#?3g-j zi3UqY_()WdqMX<*-j<3`bVcY=UAkH@QHGJO<85izM7L`$ov+TM07a?LCf>210Fztr zxA-;lvbK3f^5c~)yi#3!=q|pcQdfpAhLWrw^0s`{M1R#>+HWt?H0rr&7cbwd?Lx1% zFJ1*(CXzzcoM1lXl^Iq=534Q?HOoTy^nzc%dB!_nZ-Ry11TPK-&;jcW=Iaf{rh8jn zt`$8P6}|k2$g`)tyd-U#&~2NRI+K;Rj_cO@yyd;|PXU3S0!!66v@vXb@{M=@?W`pF zt0egO^?xsm)4^ZwH~hDy*9hHfwAB2wmOXjAT=)Yo+rojh3kMcwQ_DCSpN0F6P4ISh z%wK5Cf2lJ8JNwz6@3TJ+XPDkxO3oC#CHk^-=g@zl!?r@hwu{qR=yQFv<@;zWv3Nt6 ziPYEXQ{|Jq_q$Dzx(#l)`oEX?{*G(XC1)!_unfvPC~4#?k8_c%@%ac zmZkIwqpN%_Zu-UB#~}fsq5tnXz#9(>@C^%K8br?cKg+Dyl{DqrGN8T;1*I=vgDzhK zE_D3&>ixCqSZ>uS6f{zu<`+86ztk#0k~92#XZS@{ zyfPC8=m~?RYRnbcHXfk7j<;o&hMuJ@Rmkzm)E!CNH}JB}T1d=-3C{ms!*>}Ysm+^t zWg<4CBQ`I7!@lgt3zcuO-P?F&UP)kINi1FfUZyQ39P36B;cfXLi}@kD)a|5tVOFg= zv4fW_To)a#yHvejTOVqv4aM@dw27kIM3-u2$ogBmpT;fs4bnAciV3;ezp9!WylddjFV1SAhWtUC?}NBl zU(QEv+NGL{`Z-J=-PZ?rNuKOQKiRufK`7%VZ~mw{#7oj5EYu-1IB&HL=N*EJN3a)Y&1VtVdM7M^q7Knz5mzbsTx)bDjI@`lY-ib7b@! zd8snr;>%dY&uHLni7-G%7%a^rYUU5AG)_L?ZRtCN?mM*9!XGzpYZX4)%G;8@6`j6y zspd@B%zq0z*~U9xFKne=*e> z8vO4MZ_5|&wO_oKKKgnO*7+xI`IbXtPCreypSD!yO#j;T+N;+thYrf91$xwCX%DQQ zz4TGNzlFEut3LXx{?d7hOgbq4%x)Vm+k*Sr1^1;DRrh5P`cWUj|K4Zkj{coX6PohR zX!=_sb~!YtCW#6qi7s9dfO?W-QNCo+over+!;c?>f}_*+u24TD!F%IQVRWbPw#5&q zuPhKjn2_OZ3D-u4YcI9m(fWnFjQzWLTTUsXPbn`|(VO-Xc{BEkyj`k2u26fNzL;&F zz`S;}p(<}n`3|via3i(t^U5V7oTD;H(j!**!J}NbG_!>D9%H^82aoc=4L@t#i`LlGE*RBIc zr*75yx>ZY)UXZqH6}oHH2HWU4j`5c$1pwc-$$j6pXYpCOJW%<*O%n!xwo(6VV=UeZ z5k$;yv!37PaQe)1yKN(~nE)dAbtCuuWlMDy!L^Bcx! zZEa?(`*s`@iRLFo^IIU`cr1=(p3x&D%Bgy8sOE(+Bu%Cw(J&mGtCq0~q8d4)RmA*mT!?X`?&cRtI4h%fxAU--3PkhfhfZ~LCK6U#?2 zFU~uIh`jA;dE2!SV3fDr3^FXb0yEX!h zI=7o4z@l@z6%3wkS9-c#eSkF(p|k&!6vz=SAR8{QyKyl6W=xkCbWEcJ6r%*xcC2-0 zXca}K1IQP^=L;x~`#fPM?(l!Y1GRhsZ3O7&3z)#5P(Zm*Ktpe@Y3e!rm=7pYBe1(h zKt(Kt6ee|X;SLWpY6Ns)P$!^PC!qaC$MKXqTHg#rbP4S45>R=4&3ym1CQ&^eXmkna zBEXo#*B7ig^ zU;%?M0kts!?Igxvb92KDC6HrYKxSS*Vew%jJW!q&&_IChynrDB2=fAD7(@u}i4asJ z24!A1#M|!$IU)oNA_Prga9U8|w4kzYOF`Bu;~jD!;;f+RSwXE+sEL)a9-h!Ktq@eG z5L7;#&3yN~&8(3J>J@@IFsKq#trFA<<=e#KnkmMDh*m*`Rzcmt{bk%_e>H~s02+$u8G(iAyK#&T9 zK|$3)L9N9n1%ezu1@S)x6(u8mwpb;UMDRfMr=S)LW(AdJ1vR!;ALN{j#vcU{DMI)Z zA;rf|=-xoRS`{9srU+>vU~h_$5e(9Wl+%SYKBA&db@!p6s$DFEFBVda^-N7p`g`dH z4^)eVv=FejSjY$ggkm8w46X<%UlGz+xgzP@-5&7s6YwpSklH;V?eWKg4*8Vd>jB&s z(!DQaxOmq@03AZ69YW@^Yj5R*m>Kh0wh*OLh#s`1r~b|k1*qco2YhpjFWVAsU~m=m&?6S9&ZwOam3YYYUCAWTRQCYRx2 z)=DIq9{`XfOidDIh}>(FYS${c3?NGwoh7_s@m78S>V)Za!nULI3+1Qd!UlQZR442P zgFC{sJHpm4`lX7U^w~HNaYvYQN7w}h4Z`#WVcP>=HdS0zxn2t*8ictG!tMx&M}a%D zp%8Qi&^b6Y3DcT{t#5voIy5&fun**E5_W77c11ums!2Ejg`iV_vfAv7FfJegekA#&Le{{hE%SXaCFz6DN?-EvuNc1vXZ8!21M05#T zbO~F*U`$wROjz&gnqx;ooqyj45o5x}W5PrjOb9DX2rKt}`o{Ni-vl%OP6}&H3hUwS zAMiYVAbB?rj3zaiDzh5#Bx%o{~$1)r|S z9o@W>0$@%=drm}OVdn*@GppO41Bk^K#9~YfDBJYUc%NwCd`81%dLf1Pl1Rm3?&OgM*u4e!-c^m z%$`da)mSH)CTHI>+d+{M%$^dADz0^pimTB!XdZC~qkIRWvG||102(lg4H&hF_s6{z zRriSl=)>stVGI|a*vpSvt(@9=i|9AZ8j9HjOzBgI^fZFN{Ud1=>luVJdX^e_?EYVOR)o|Ap~E!2VyD zFc{2XNOKsA=bAG9xJR4|AjcfWb`HZrfcqTA2L}Hzq<Fy zN<)BElc+rmT11I0qSVD7tAQfDqK3VqgiHd{&~)ohcOIDciqa5Z)hlX`0CumaGYtAg ziT$F~#Rpk|9J8XPv!dpUzs&>?v%?@}hpE=8r(^c1Uu*%y?=XwsLGgRjZYCl$_69)N z4wbSUn)|*Le1DQDDZ>N3vK__vuXVJ~760dI}b66&G?>Aoy`C+w-Y_LbHn0e!U6o-N&UBzQRnV2dVetGG=L~9 zISOm}-Ha2ru}_#EKoS<6gxxT26Mu24#)&>SGSos#LQuXDr>Fq~1oCi5tu(~Z+ zLj(|7uw(>SwqR`#z-+-f!QdfQ;UQM}y7aZOQESv4kn|B&;SpAO@qg|BbYT^`u*x|r z7;`GDn{@!5VHKWXm0w)U3kdzZ;0d4`tI&;Ap0^yq9L`LEx}0t-qZ?}ngI8FES6Jo8 zYOWtBA*Z3W)GI9G71j<0y;y}_tn$rs6%nShLC|R4i)Hj;?O@Q4Rp`emj~;B=-Cfr3 z5k&N38U0v07`(@-yvJ%j7Gd5}+!+XUN<&zcA*`mGz^ab(F-H#q7{RKHU^TBDp7_C7 zcO9C<7m1k_iBaOj#*0gg{yYZIDn@7(BXj5bD_jI+M*zGQGkGmW`lc-YC1Hgev`~B} zruI%ud-16Y06vJReGt<=x%SE>Tjk}@#OkA%+D9?%rlZXLhSU3p0E~*Mjf!b6{@??^ zxR~0wnD$)qb&|NZBDAMp#nirvX&+zlrDR<;g$dw~81;`BLuv)4-v7r#Xe7HJZhAr7 zy!SM-uUjHU4M34Ny-3`)daVTRK*2Z-z*TXBtKz0L;)SgRYDV_~REQf?h?`D6Kt~?4 z*L%PNQiZq$464Kps>Ds(S4ZFceFY1h+bVHVmAC~07**nSFt{OZa6{a*`~2%~QMWpC zK#?2bq#NQE2w>b0w?hEyhBy}n&EjUw;*`aI-32*X#m!p9Dd}YkGLQVfLPJu!xLLb6 zC3S;kwx^aO)CWBlH+w8jaTWdN^{GN*J%CT*2A{-DGanqefBeI0ZvbD!(O<+jY<}xo zAKcG`PUSaog>T}@!g3KI&yRnD7BxS_6@G{-4^g@~S2pc|)?+`#6@H2)HVzQet|x$#AlsV9(1S@+S3OTM;=IoqZWVM z3#3irNE?vDH5ERz*koc^P&Dc;G|m-D$rnl~ z(ZfAHubMv$E#5Cl$zPIEs@Dq+Q5DGy22dg;Um~Tn^@Ym{+~nqd0Hsp$rBX^d2gZ$s ze<-~KP%foVE~Wg%{?BaHhUjDfl~M|oQp%Eve{P<9$h$y%T}t7)l=7t<@ZcZqUZ_8< zky5CUQjR(QdvE7$2k21ONvYIHY0jJw)i)rU1^~DtrE*6~v!J}qZd?dI3ZOwsr9nz_ z@h9W}nxxd4q_mq|Gb1t;lc7<)MM|wjO8d$6VC}*i=b&rK52e%|N@*)cT3CNOMuXsy zl-eUHZM}k3K_ol=w*b1N)Vid!7atP^;F*-#Gb!yhuhp$4_OoLEx~25HrA!Drf?}Vx z9nJ^vN(%i-YQwjg`S;rrbf6a1FLk_MDhegFEc`-#85$Z3#-ylYQVjEglIb_wnxO7- zLdtzY%E$OoP)ipdKQvfQN*PQ_nLdm~rHkw#x&SyO?Q}}o&HMnlOUdbWBY*;Fw*qPJ zubSlV`~6j4@F2KA`XCIhNi(iV+ZAuHG_fe1fKE)Cv~8O-tI^#^Ehj8+S+( zg;KFciDe7W$k!ol)gf&UgHCCaPHB?F4{8gQxG)GJI;Fikr2}B_RNDBdG;#6yks#uQ zw8;x;k~KjwyfjglLf70Inqyu0Ojx!F& z5kpyK&%$bbpeafe&Lj#)ipQ({oVOME1Rxe?9E&4%5SG~&yqz5YkbpBuz>%bSf2>Ts z(N6)8gfmIPkvet6HB&F>LqlOI&NLNg-njd7N>!R62|xzUI0HxA;Pi5>w$au{Jg~~Z z*&~3HfpbBCX9ms>0YMqKP#9$4OtNsK7dweK=aepJ*RycmS-1cgWaEspam3b(rlk*X zYoJj)7iW@-Bb`m4ZLj~D2Q4k~amM*LqCrjCZJSmFs6`dxObT(Nt8ce?2vxEV1Gt1U zxr8Gv-klFX3C^?xXP!Spn^DnefQIB!oOvmZ)>nzu7Zr&n11QItm*Z&q&C|Bwm&v67 zDskqOI9m6=YhM+89b5ri$C+Qp(H0-V4xk2SUW23Idhh3SFn;O)sKc4p;b`0&SsqYHSjzCHP30(Bq_I7$PKE+w$@)VhIP&{1!~QJQdcvE46fqo&(40kq&K zEjW6}kx!R3#&$y|>LHHu5Jz9UO8|gJILad&eev6O09`mr7mn_@QEW*dre#D z57t1PazBpJkE7!QIIE7YxCb@Dd7SAy&irlvnzPhK-ys0WGFHhl_RNCtyUy>_puR6n zMn6r)sjlr`n6D?%eC)i9Nx<~CjLG2Nt^cj zJ%AAz;)o1&?1Rzl`Drg_9@vb?FcIK3BIAvKkP(?fFc_0D9g{J)o>xqomnSBI95XV< zX26HS3Z#yb#8RMj=!{G(YDOjzPV+K>^D_I@1cyI}-&NlaV&Y_Pq2grkqCO^{)YAQB z1Re5|vgnht8+M0Jl_!tdKtocpEIL_sgZJT1`F$IQ@Bl8zk}k+vEWdQ=%l^}^$^aC} znit8^g8rTj(@NY4wd~8X=9gt@g{ew!=Q;*>qlc_PkF2SMz+Jgx7Lw4|@J817jV$q$ z$&`8-%G8PnmTzQj5a9Gi)(rsxZ)8JYFfVI0FKdr;b^odEYavsUSD;IQEE_998x_4Wb%R|+t zQ7*Jm?noZlbZ?WUB(ywfl#4<&%EhB#^h7QZ^+YZWbzsw&F!^x;bWWehWdb@2r{{8< z=W;IRS$l%YE*q`^G0)`=JeNBRgO_rSFXddn<8n@riEsEp#A`XuYdM!X6MZ4~nAGI} z`s6r$axRClXWn{Ud;_gX`s9xHfgOU$fSl)moZptlezn&eU8uzm$n77H3qwEzYCtX) zg`gBbr;wBjr~pZq0hJ@^CZKvGH34da)3BWDu$))vCig)5jh@i@?2}wL>XTdyYTt-i z`pXn&sF(R6=l(;^=S1gAOu>-mRRAe?lN3CuXU?u7pyeWTvQqH$6ud1A((xwgc+%oi zRzO5Lo}P}kMF2M)?+$}Zyh$dWv^r+t+jV&hP53zpz&90?1K-w<*9g5#UyU_eOw! z0X`T87xBc4c&gmPSz|ro4QP&j5pQ!5&qRRRMZ7lxLN4MDA>immd;|(6#du;do{Be( zx7*)toDH%T<86xZOa!M)&b%f|1)++`M@^48Q|C&rdEnK7_lLn#yxmhg`*YIP!Yrl} zG|lJ%RTs~ilm2|x104lT-M-@4U-8ZhvRmG*-id*h+f#VX6yD{p$l4ih*XD}=rtzF< zyi1W^eQJHhi&FsR@U%I+^{{0A`@L6npdA13ZvXJ!rw@kcnR`Fd0+1_jnk#P}k*{JA z^C4c32aH^KI|MlA%6lMSU#|QC805>-^5w1ds_H_bcg#KoIr8P%`SQ*P@XeRshk(QR z@+V+$NuGE~o|-mTIPSBe!XM-)k=HAcHy-mntvF%q_y|C$yg{kF=?Jmz+-SzFVF2aw z2IcamW2%0=sDtvW0948wRLYwMVh1|5@z?NHnDWk*@*Xg_E^l~Up0Ic`Fi@mMes_($ zieW)ubDzuRFFeqwk=KPmgFLfA-l^@;k-IV149Y>oV^hV)rfM&&?rgPI?Ro>?iK*ff zQ?(fPB*UZEv6lcmH&uLYs-{HS^xR`vOA&yVriw33)gne*_Ej~PiUD|Ss`T1a-B4-2 zUum}&GEjKw842W%DfnpG=iLnX1Q}PeA9?=RuY3v#HW&Q}w`cx4HM5ziI;bVyg7T zR6S(Zqnx9qVkH2+nJRxX)%bVLyt)c4@BzRNQ{^9~8tJ=ye<7O?f}Jmb z6aq1YK;2<(@X9>Rr2s%WftXI9_OS#5_;=1W0mvi}GYQmhbZb4l=3yHEX9&bI1nS}= zHUZ=ih&cr6zVeSfr1myw(w#>j<`Jl^BH3I1x!2-Rvx!fbr7Z0F@U|&Pv*d{0W>fgKx4OD#u?LLD313vNuUv>pF+zk-S z2MDyqXHW6Kae&|ogKvbuZ-o74R}ydP9F2MfB4!E4W(kofrPmv>osZex2lCO(^rM;i zhS|7e|Ht#tF&s5>8#VJ@{B<*caWl(tGn?3yKlr#nd8pxjH4FS|w%>$#G-AWI`<(zz z5{*w1i7r$51@E|@ZUe|7+GG)#K{t`vo+O@t z!FOW7cVb9XnY{GIP1#RC#CPJc@5D$HLW)q|iKR%o0jLg6Geo}`V$hEE4{5&1XQ57W zhInL#7>+_nA!>$LjHF6HH{n!5B9@S-;j!@_cE!p=7gkD0UL_=d7*vupDoMIEWzubz zl&XC|#C4M9b<*DLqaEW(xqG0-R70|;AzAfjyBd&$2^ZceF&h> zoX}@ZjuVeaR&8tj0^kanc7<$xWaGijhcoVN1kgpc=^`^9(j`sx((UU3JR|!&BL{X$ z-E+YfWDOKCLir4N1$NxiX8BY93t>yBYStl#Ty`GhO9J0 zR=;s`=d2fgiwJ<52i=!yVQ8a}8^GljTgS!Bn zq$r=HXp}WstXz@s<_>^ligGeVqi)-l16j-|sI8 z?EwJiDJthFngieBX|4x0Tmf)_qH=+v88v=#Dk5c$1E7dvQbZwPUd|op_O}fHaG7Fy znPUDc;uJMG{DvTas}$3#6!Y|9(HQYrdNhCv3Za5RHhO7QqPyW3bQ!UVLad@t@xQv{ zE#K>02XKQzyg{J~M%Ut``5!>*jamw^mO>32`PHF?CP96AJ%w0Lp-#OV-dww73lwpe zLb^+_c=84 zhJ5?E;W7Z)DWrCa#bMU3?;qWkB>{L$Aw8y8D7+MZ^6~UqXm$03LV7~67}!-3`@@S* z2f%X*={dz>O&m%OByzogKL_7i{eUG94T;5EhkHHCIs?BN^PEo;95=%bkT zQE2+wHO^P>o2~>fKrtVn(0cb+j*f@@X$SCw!umns%I8NZEPRfGM$(@YyPp(xAhA^n zr;-HqB|jf(EKuwhD4d~C-;chg_n~eehRTSc+Oe5c5w|*=C_G@rP`NP3q}pUs znX*5bL`%XYMG$d@%05GNF8#Px{BPxdlWi(Dhw4t#*)LrAnh5niIaKc)Y5)xKsN6iN z`|(%FC))%*Lyazv>YYaofI%_Up_u9@^V_~!x%03&h`33$yGdm)-c1+4J*xFRszc(g z{L0IlDxs?VldAobs=w>~{JqpedtU&UrK-+SwIoCLZv50NUI^eXRrN1b>p`8E#pzR3 z(5^2~RTrpQb&~ljZP(3=1BkTHjI`LhAz}Y;bM32P0Hqctr52>CU!H!cq&&z2P;Nmk zx3JXzy{7L%VUY)bCJU1$3(`8_mFi=w-1qZ<+GN3iL5l^s#llh?^>X>cwOHuP^;($p zT9ACb#{Tf15QEN3uLZT&f`I_rUJDis`Yp))7M3Aesins=1EA{g-NNL%1xY)dzeR%? z2MyrgEvVlu7znWaZoxu;({~Fu7|d9ZXDlq&{K@NHr6*7ca-`F!=`_ZqkxboIv4qb6 zGHJ9-nzeFcxcI$gla>H_XofvB!q5i8v3mbi&;fcwQ+h*FFYtTCy23ranFrc$X!_JQUN zgO4fM&y^lTb z&>4*P0K(~e!s)6P+QtqQ@12hZ5Jle;MOW><_4d_4ihv}5So)q=y6We^jSG~Q)?v?SGgPEX623592@ zwUM8$x4G`w&`dm^u9#0(Tf93bfI_-rAzdw8&VA-)YzNfyU!p5sqN|lDT#vuiJp?te zOLUt{bS4Z+=!zwDwWQ9Gq(Y-x(CAS@w<)1BVNgm}ETyZ}z0(=6X$gf|b}8Mal+J`f zIbE@wuBI?@&nNB3G&HQ0({0M>Oc+$s)hp>b=aOg5@3niALBw^s`gOXF?xxZ5w`Udj z0o2gdYv?*JE{py=eNF+I0^XrJ+@U)vPst7^?G7^n&_YMI&^Hi5G1vLK(%AqW(!)^? z=`pBxYS~9t`=~*q!y~%+BRcIvc;P!g<;zeV>Y|%>(P`e-!yFFOw?YGK7oFKfcY?uR zy53*9vAjXa{jaO3FG0j#y7OPU2MiYI8VhvY-^K1BqN#VFiB2TrP$c8nv`?C^$mV3| z^TseVV;Fmt3M0zi2wi~|3Gococ!t(4rl4nkUQIU-yy6-DFi2#mCo**8>DaaFgk@qt zL?Xj8k>Lk}s|>8CF*r_6Tsf%J4)$&{ak#4Eh{3O{95+fY{@sAm%+I3H6?lj)Kt;gEYjjKy5sC);(@! z48#mEjt(&*P%s%`P(~Q^V67+E(!PtwLC6ThVT9p`0Iv~-KLQSpFpk1tj6oS=(Di*@ zr|;gRat`DeV>pa491-9(#_)&11cNfcpq~xs{d3Cb;vgt8!El&hIKp6(VLr*Ay(SD@ zS^Z=64G@uGy*tBNr7-SuZpC$HX#iQ)yR)oS$Xtt`?=A*I>%?s9-PzVE5wj-E5|o3` z1R>knAlup$2D#R|bFEc^qpMZz1Y5WuBHwyikjF|h0{fD-FHCDy82r5+16Z&?lv0HxL{rPi94Tpy@EKDyNr zK)JP2xwX1n%Bxm`qV*~Oo><#Gv1Xr@yBef7QI!oK!^S+rhQ|Kz$xxqP3EGeAHl*t| z7D)|>IfLgdF9K+>F>A4*i2bDH5Db_f0Cd|}b=%lCUb@ApLVw;0V9@5opiMNYv=jW& zBlyZbAj3B3VVez#dLGSOrNedrqHL9-Y}GSb9{Lm)jzg2*C|m6)TYVVB+G@ty?mcW& z^(ZZ?SPMkt+A8JRs{eac6p>c!C%^;kTw8qv80Xp&VUTaDnQyyS+0%%a$Y-DkiZs|# z8f@uXeM;2U5lhn;nUokRSJk!SV_&u>CG?DSjgOfpS6J9^@1&^7)?c8o`Mb|#pPk2`Pw z3jxq=XWMPZ+9V%#a&Ku^1Asm|a-W?gcNb%$_~lIKC=c2>4%)e*59%HC=nuXO;H#bS zS3BaX&^2A<)?HAU~isa zPutSnO};%728H(Kh4!?m)a=gX*KfLk zA~p8LHTJ}SdxM{T1h0(e0j0*CjsTk)dnN)LYwTTNP-kymXHT06;s)w}Na_VSy6ug- z?TL%epW*?v+n#{{yKZ|n3|`rrzp|&@8tM&G-$RG0)R?{Tm_701n>w@4ednS1@`Anb zf<3WzosqxCREh?GNC$MJ!-j^V%l*RdZhpiAa-@SL3}PJ2V;pENN_Y2Shx8&q#BB$g z+YZc2G10V=68Gri$CT__joAKAxyLIRqfB^^B0S7Pb-LLHrKd*yUO9Kvm0}eqj7<6zQbnt4vv~SJZ>E=lg zG3eko=nw>h&kpR*4$i6+1Mc}!d8kx7T~S(=4*lyx0#hr2sfPgL1SSy% zNlf)5rp~VVXNQw4%o0G65~gAaQ%y7FgXr07AD~??VQQB!^$}oF!X&|U zl?iT6-~@`?Wg6dQ62A>=+%{^?GUS2hU8Wxb_T6P3KtMd|E;AVgqeiB2Ba^uP?DoDh z2SigqmPV#$BhwE7`x==C5Ri>(Wagn@)XXF_Gs(@b^}EB~^RDPMGp(AL_6TrkW_lvP zx0$&Q2CYm&E0g>+a_q6KI0u@ov@)$)nf3^9X=QpMAgGlYih#qd%o8wZXA;_(Wc_EH zy`uH2p_zF*)2f|mj{ui;rY8b|+L@sU2uHOuV^9c60F(l!DwbOn%loUpLGkVA+t5Vm z2Fv#bYhPAgO#t?R6VwIPvaD)Z_Lk?@wP@v?=->gjmgSCs7*s9mBnn3LEUS8!y+xVs zrb7>N^+BO}7Pp?|j({vwJu3$Vqq{8IyDXOc{CJ4sa5i-9?=H*rF3SrBjV#+n7E2gy zVHA8iISNEHvRoTkUI++oWF3S-Gs~`-#lBvvI!5Z}{VzZ>>qs*z9EFf*R5L39N#_6+ z!l{*I*UDm_{`8X>r``iy)M#ZLX$6T85{+sFi4arEOZA-N742-h)K# zEYEh99|A(#Sw|3XqMa3ug2`hR^D)awD9w3KL;MM7V0z5*e9ZDgK?{16a2%sPUA7}PL0PzcHdbQVc@fG)u4Gt2xli`IK5O*u&JOFMY4A1tRIEH}B> zSz3fuV#+XDfoQCHZxC>WKo?aJ8fKbG&a0_+;0&r`;BD`R`Z;2PWR8k?O|u={F7 z+sI)MagFVEjqQzqkZbHiFsNqRSF<@sY5v{6Z>FsTMXK3HtJx7Kgv6k#*(Z^d2j~Kv zZnEufvN^5YA>Kz>kD~7AQ3`hP&Yv$1eF7-hSM!J>lT|^Ve@Q(?z8P6NOX(s zb&KtffP=T#M-dQ?y2Xw`!RR)db(_r%y07{3-*}51$a0(Qb(`&vfP=T$M-dQHrx!s#B{<{q25@$|&wU2AizLE;B&?+5IFO$SsiJt#1}4xo+AZDYIZ8$8=3U+V#_ zNjliv4z@c{UVnAGlI{;49O+<(qhQj>w(ev*{MurA{Bg=MGZ50rcJ5?*AfO1<$u32~ z=qcOoDVu%CF??%o$_gP+=qcOnDcc(XAy3(d5DI($_I22PG8wJU)juSM>GAdC?1CD{WP01&33W< zAX_~u{|%Z;O|!3|rr9@8F#5&j{9?OU{|QTavG*o4HTuOaK>cDDpD3#-w%5lB>`O1jsXv8NFlgdd)rE*TAV3fge&fs`lQyj#&49i0!UIr&1 zgA;;)V;P)C6he|v86XvmvN+CJ9FHTVNALVt=M43pS)70@P6z^yWq~v>$>um`b3FLI z9e>yod2Bf-lg$ap=7hi?m*bSnar-uH)%$gwkP3*X;jn8s&TqKEB8BfP9sp?I5E?k- z#oM6(XyOo>IOMLU>GVfm?&kw&;SgFl;!yU?r%di%MmPp`te0cf%c1x-J9n(sGH(OW&oS%gP$o`J zzx+@etqtHk$Lu|avTsPrv--CcbU|Z?V>ZO0FmB!Juu*=|$pgP3P7n-6IA$XpN~zzQ z$Y4$!bRA`c<2S+yg25QaY>Y#xH@d0cpmZJ@)yFt~W1JuuOmNI5I26y;2ew-NjyMo8 z!SS2m1i@gEL!IO>?mY-pX3(0T>nPtj)bAX|3Hk*19P5>NVnV-{>E8k{&!Nq8tRG@ah0_?$&>$4yNQ-c^ zUM}!8aci~#)JsM?(xM%$Us-)`eoC2m2q4ap7UyVPes(!0%Fd$}K$@dpnq$y9SEl{F z7;j+!ryaddI|eM?!y3RjNB?tLa3tPvq^|rEeUm9ya2!CbBeB+z>io%{J}qqwHK2M&V!b0(s@nL6<0S7tFz-4N z?>bTs4p7ef;Dt|vh-Sxq&5j42*=g8Myt)VV5Y3KZ&5p+r5Q%Dbj6)$P5l|YOS{)Cz zIv%xNHra5o>Ibx>YX?Qz9g|RhY7SRFnA-yl0WTdxUOFDq&0G;v{=VoEfCWdl1xN2F z!;h;)KX*fu;CLsmcqjjS`rXeBy6-{&WIDy8GM$o9E}#7FoH%(By7YSn&>2AK-3%ec zhTtebIe>Bio$uLxG|bf(s8TTWq%k1POi+bQg}({Wm?@>WOPT&R<}?F1$hPKhWO-E%s0&*_+y;GJN4AtC^PJtht z_8<6kakF*GuQ~wJPWIDIoC0ls7WMO=9RTK>yyl$zleS+pYSGDoDo85VC6(*x6S-RD zMC1kNT{5^H8C>6e>OW$3x*mXbEQ?FX;*y0-8%M`RE1^|KHkXjiCEv-JtzI>r49!Jy zxrAIUIgxKWdEGgAs9EN73He;|2?~u~tYrsXyes6I6>=$0Gj&52jMAY~c8P0tiA(XY z>zoYU+y?Df3D>NIOVPrbeR#jh2dXWlT(eRxg_as!{crWXKmg@jYB`r7{bgeHq(jzG z0F_*7C703YI~t7R-=_!QI+uE#%h-27^RNJ6`Wt{6F0F=Zz4pOPxh>~DLtnkracOm2 zYY}I~!d!I>@F#t_mS`*jWf7@5o ziP0=5qJ>Lq0TJGxDN*@d&{zBYT=#yi5Ba6A$%I_m836CO9`Cun(^iciaO;D;0Ss|H zhPb}`x@%_k3Hd@fCb)qU-2F-meA{n4J^@|2o#c`yxt8tYP4^wiXGuJ;pX727;5o_l zLqO;x_XrHaoeAO2s2qL}TXHiF80v}(_%SOB>$in%UoPrnRwxt~mcz6Qv5 zQOtKy+cm$?xUH!33xGlwr9u~VyOw2Nn(L=_0=VR&bjd~i@9(>m+@$-m07_hxN?g?6 ze>|3U^h7(ObeP(q_| zH8d1Nd(fgitYHx6VHD?K)|7p@n*6F5>h$6~XmK9a2yl$^aD_pJhkk~KN#()3*n4m8 zL*G7Sc%-8;JWiuvl;vTRN|Tq_V#)hA;7%XgN6XxUJn)w8a8b5UxuorB&A%SNYfqKeo|?VO z8qYC(Y@y!uk0`w8->7k$*rc1zUyg31;D zHi3v~FRN)U`^c>YZ@s$3(*XSQvis-7-r92$pZ8)5G}`=V<+)h8KhH21uj_q?4lvL>G1Z2YtezyojR2i_hZr~W+^1JnX1x!=;IFs-UvHD-=v9NJC99#a;IFs+UvCZqj{fzI zK*40eTWi5vZ}F*gpv;1|%YwHj3?h99kv?Sm>c_QPy)8{ZM5K>Tq)#9WVtkBae25Lg zgOxZDt#u$G#>X?p#}5YaJ|^)#BtwbL^6T-Ank3-)r z5RvG^Nc6EoKxm@R5g4TSXr%b)zSsI&f!lm@2oy>2u}tx?LBReLpD-BI_z-G*$m8n+ z`5(IRUjaqxd8n>SSY6Otu^JkBqWzSk{WOGZ(Q_S?HP9u7Xg{53KLZ4qMEj9o z5a*{A=co6B8Z=V5Q$rCHIp?Q*&QIgq_-1|75#}Bq=$!L2K!C|PKN13{=lmEjIPa%* z-cRpKq{lnA2O9PuM~h!Fs>Lq@RW_4)gIQJzwdWSUJU|zabOlfal5PU3N74|WQ6&8U z^czVFfTEWp-Z61`i(eX?di+kJdi+vR-tLyC_?X&IFY?CkEb5J4K5Fm!=B~RsHa`Hp z_bWoZ_bWy1bFj-S%wRW`B&Y$%@;A!zHxra~tb5B;hiXMc04*ZG`gxb}tI-*qcL0(C?2-c5 zQH}j)c1H33zcVSoGbz9i0U=2NhY)ZgDIgk!kaAQ~KsA!?0%}51JD@Hky#&+?r>1}i zR8v4KitEcKS^0JvTD&y{qyox>Q%ittO8{%s?c{}ukd;y(rYpdzE5N>Rde=rFy`!1{ zx&u7B1N=<*dO}p)g())tFEsCeO?6y zuI?dMi;RAT=GVP}0lk4CE*|_=Q3AaGFaI7Gi~1gzh}0s?A1)5*G!;4 z0uIas9!5YUY9=rag`iYGnMgVZs1Qk4097EV2GDIdMeK8p*yk0IeVhJwPzkDe>HC=J z`QIBf;^T0|$9d#{ z;_3%4J~_g`?TU}55b(Oj0@;xgu8mW2Y!Qy7QO`z*k`QD=>S4 zbaJ1B@qT-N!u_qn{q0RAyX&s7JD~Z}ZGW@d{+0|0*;i3Y&QL+t`zMRk`=^OKSt(uh zzOmc`peO!Yp7`4;itW1|{R}+<1D_}U2N9s%-@4u3A$`GCt(B*j4grlWf2%Hk`|$yZ z%B$TBcnRxo*XO^r+l0yLk6%Xt8k7FIlm3SIwP#z)e{8n{VA|h!+MoaS)N;#!FCQZS zI1#YrM1ZZN%JJR1MINmNpdi4kAi#3$*Z0C*cc>Ns6b0~#0!$hgeH&QUEt?2HbwFr! zK%|HvH}R)s4g9Nsy8-*|2KXIb(d;JgvETRi2!rNNIR}k$4x0a1@;=P= z$`!~xygL{!^6ubqk#pzwwHP^cK^6EOp!Wa`j~GZ@HWh(J#KD962M_u`Sn&8eXKyUj z@IM~h|M8%|!o5#Rl|=tB2jKI;vm&1lri;W^iE)2m)*Ary1)whgxx{6EAYaeB0#Mu` ztGGkHdjc*TQPR__y0+4YCm2qh0K4S~Uy^T%K0FiyjCHv6M zlg=T=w%2#*0FZmgA@`6oj?zCd-Ovc-H}_DuNbaHIA_&wCP&Yu-vTX_J-zK0a)Ac}u z>w%_wYRi)~3=((%+zwQ_9jJQhL1udJxr315`oPWgfhxHQj6Ov(F0>YW7|3`S$a=pR z_s^E2<AlgJ(<6&D zpa=XFX!0x2LVR_r;jVM5pykF?;Et)lU7H);$JtfqSOX9lWEB}?pG56sy1!cq#d`CC z4Dy0Z!z$DNAtl&Cuk*`;^~!^do-8D#z1P#30H88huQJ$(W%km2dhw%uFfgkOwnTuc zV7;nfBjdHN-`5XSKvTM^V6&=VOCexe73_onHNko{!A9kNuKU8TifMx+HNj>z!Inb6 zwkFs~2)NV)??iyd!6uJ`E#|+}4{SUQHhCIsu^s1h{RYDbYJks!O`Zo^yrJAacd_C; z)SKFZP1=GjbW=+35j(d*gWlI*qp!i{xoZcKbN-x90pLfl&5vNm*QYRZF9$d51|a6J zYs_JHr^7dC;<@oT0K^>*h&voSYn=C4tk22_fYifa8^vMpIn!U(v%P9XSpemQXyk?H zgqT)5FDfp21we6#X>rJw`6Fims0y*F3b7yZIcW4VDh+agRUzA}LOc+lCd8^H#6F|w z`{fmH>Y&wSO^91fh^G*U5vd7@7ZF0K09`<$x)8;>5GIb8^ij^^8RP&PLKGW9n8rk{ z3rPt?s1W)?Sp6ZIs1se!s${F)0#F-jS{u4$ub9Zy+eF-=SI@v!Msdsj5)(yn58+>QM`aH5yW`BO*{IxOUX?+EKgmRQr)T zJ&~ILxOtR+^Qg7i%;eBJne}@B=s3#lILdoerRi7nt?DZbvPC+M=8GUu_ffs>qeeGv z&S%t7takvN?xS0}kJ<_W*Y2b4LSTRQQGX#2+I=)q1VN(1P|;y44|Cl`mhr&X`@ze> zFjQ>VN^e^gKY6lK5CBiZET4wi1&hrxxf$Q!u_w&od6+X@T>aK<6V^(g(HUmc8D{Pu zovr=3TMBYYJz*9-VK&1Jwr?mYJf0TsNP6@O$0J z)uUyazzOgm8**oaRQgC!XZb-?B5Fx?>m*$p?JdKp^{850WB1Ck+WpMPkOfsX?6*cjK#U3xv zgpbSkD31ClE;zI4`S^)3!&EI;Qn3|Pu~l%8#(-9l&LOToESZx*&B+K3z`=hB(wtJ} z!;&mDRF<0HbP?V3NDnE7B`oE) zn$%EDYJ#IlbR0JAi}M8%aKcJq@Up^S!4Wc#-fQI^&T)mUm8zpk)deT%ZK~1x=OJMy zd_u@YaGEE$kY|Kk0-q)Zm+aO-6N8*f;Uv#o-ObuR_rZn+G*JVZg40i4uV$Tpofq)0 z1ce$v364$Ly*zY|nsf-3Jm;gH|98Agy>hPCmChhI!zaD5C%pv+Dh;ev+NviX3`>e} zxMG~(jFb7-{?H*VY0l_0XYPEFfmV_3ESm1D5TK17%Po4N>J{`L<&|t0{A|ZU(Z@ms zr*#3+ira6DV zQ*Y$%EqezfASXALqi!r096~6vF0j$KEe@7+2B13sJG*86^CnR4J80+*8uBEkPMT;Z zjU?S{u&AkIihSdK!^&2#6!^wnG8?;O1m~bR4@3;AIj6$U)gX>;5Eq=w1D@-ixad7` zi7-{a(M#1kWljhD8hv{E9IRR-i7t{vp2}1#DOxNkWlB3mGjf$ZI{w}eM+r-ZRqx`^ zcX5I?0<1RRL>q82c#o3rt3@X>OAVcuyuoF_&zG!&O4bo%V7K%GwLdl4aHcc;v6=pY z8f_hL63^I_150W>m(_X-DuYK^@s{TVP2m3f1~w zgIw*`xWZQb1)PI?A8Njj;2b4?2XOd9P8*!&p#|!ph2TU*jg8i`Ut?aub(`jdPIE%m zZMu_ax|2*wW6y_z`(CxH>ppJyv!(+!Qm=-p|IhWMoFjF0=Jvoh{@_dh;A=kL6Kw9T zIM(&57f$nni+aH&%}dUahO)CPhG0pB3#!6JP$*Lm(>BdEe1WZX5|(um1cg%VU!ZmG zpI>mAE;m${o8U1_doQytC;o;dW!k7RZNZ6K`!0LU6+B%U<&xhHF>BlI{>xcZeWwoGnYML>I4J z2(`!=8hVB%IPVX1xxX~gzcl>AJ>GQ}tV|h~qvDp@qp+}%x1y-GqJpk4|HDO5mexY(eL+v+_Hd+pea&h6SxEic*$iqgq%s+4$JaM8}ms5FCB8A zq-X5)PFOM_iJp)Y97g!`z}3e4r*^}48eWbXUM?8HJ;Ki(y}bW0Ea~+`^?C}95S!oN z0TtY9SM+OFK{bG;^2Sy4jVt}|fQ0sr!4&FS8jV`=E(A7`q=rgT6CAQQ|6_E>$haAL z+zeTy6K0|lW-^2PkVWck@sT|4or<7~@o>RS`k*I$1ak>+zbPNlDW45@r=R+46BTne zPIZy!Q}peu+j2aMr%=Lw((cn{Q0v>LLYK zx1WL~<7m`4S}@-UQ}4LEq&X3m9t zdTU8Y2}sf=PHPiaYTzo9Jj|S*!$7S~TuTTTw27Mw0h>1QtqAa1T%VUHpfb+jn{1|JNdW=dR?C*LC=v;cBpD_Iv#oz3Yq6f zsO3m#2?4zv2@?d!mr%}^V2ie=+xRnlp|>A*BoyvQs2qINKIuRF0E(;Kkzn7E;37c1 zgi5`H#w}F6*j;)L8fdgjD6~tc*edRix%lY8au~4NCAdOBzg@x<0p3WcyphmYO9@$P z>Us`(xKRm(Q3;ju6*o@qS&!wzfITX~6$1LB5~f1HVpPHo0lrD7e3Q_iHyyBV=?v}w zHlidcQId*MzilrLjJ|G$0W(TcT?lZaBn^dtS(KzT0>nrv#z?B3uO7O2&`zELY{W?F z#z-0?K!)U|3`ypd6Ptdi!ptfd zux?0dBfu?5<}FF}*lHQOkHh1$K%+%+Q;Q_ixP--cPU2Bvz-p1y76N)Lk|qeyD#>h> zRR6KEnq{xR)Bs5aB{vO9GDAI7Jd+81P~dV!e8=^^e-z++m8B0^owQ z(FJLXeb2u~UovxmVw|PYI;G%1kgeL$b~!eQFfc2Xwnl&oX`>2hi@k53Dr2j@LGgkn zX`Lo%qt=(dBf@k3xWK@yN!nTn*f&YLAixu8qbJf9W$Pb=Ec)gi2a@zj>-0$*S#!P2 zS__gd!oaLg+FA(M_er}5fgOF)dk|ni+GqeAQ&P-AJ=TeI12)QK809jY^kZdyf$Kw| zHz0R1BQJ9cX@p-;dgkBH~#e64Z*b_2bA)r4YV~PNOWK{mh zXsGeC1K#i05e1S=Vzno+1{d#6uef%;6nd6vtid$a{FiskLUu&!9suHS+Hp7ovHoqE zOO*|w_XBY_lQ^6u0wmxJ5^&}sojE>6IaWPDBLkK z+YlfVXOM|AcWg6Y(vqT~@K^!PumH#3XA@j}DET!M{A$K&H{%Qzx)=YoI$s1ul$voS z%{WUTVB3t_CIq%O<8~oH3(lYgXFg;(bF9`orXJXMhc|qO=kMELutV$Y>p%cX`TC`N z(;|v={KSPOe*h}@rWJgv!~ZnYNXCZM0?@?QZ{nNwo=@8U+cFT!X%pX~iEoDhPxz)! z_~1hazn77IO4|aBKE8e*-*lhYTH^yHrG_xD=;PZ70jEB`8v+dQO$Yc^8`Hb(a=mv! zyZI*h`jdRqwCf8GTsz+V5C#^Ld^;iFG|6`p0v?lmZv>d;n@;nso_nGfFSD^;4{W5^ za8qmy5kK%Bve6x~F;4JWxY|)VkN`A>ZH$L)w#aO+KhnSMkOcq}Ho6lw#vjf-S5*CH zr6~-|Cv0pG;E#>*ADb=97rYRC_Q4S<e zZ)+THyM@^#9y>{y8v#jDY)w*ZEoI-lYzbD{1P#D9ZFO(j8q1M>dn9^?Low%@w&pi& zZG?csOkZqRWa4a}&Mn9y0x)84GGcEzcGcfBUE~)O{R?-{3wJPS`01*| zIeB{%4EW&=wg_;{!Q_~O<%6H5;VUGQ_5qDF2fZ}Fva-~Tnm0q$kmkTobFdWxj%g0t z5#WM@$pr_?=ijajpE&i&8zd=p&?|K?`I5WHovDLg4Fi6ugRKy7EOpo}1l&s<_98%q zgGq&hrN`E{<84ut@4&`02fb$wCWGirhELhmP)B~|VDZesP6%v$=CA_+UO1S%aIkE7 zbj)V^J}YUEB+*GR(Mk0wxxz=`Cwx3eqLX@}ldcdjOmyNSK$4Scl9Q(F=+)>lv4VBL z#x~-RQ#r51_RBXd-W0E_g?nzykQZicSs0i-3bICk$3aGqgDlh@zssyhJPDOYXOK>3kWoiB z&H8bII|c@3ok7+@z`irc1p#`3jCz7BhX3fKxM`T41W87MbVh=V+9lF#b}aJCfq~gb zkhKu79|>|10y{>6_8`F5AfvBA7Lr>QRCms@pn>miki*{~*Hu0er*?*i-2fmu*daRD zHKS!9;L;rjNFy=WAu-q$m-n(FsU{d2PSS!M(t=%o3@o;6pxuO~UqitrL&4x+6pMTr zRxC8>?E^7=aA~V3{w?y7?%bAku;9}@W)8gkDms8FIv|K9@V0Zp0!#muq^Y6O)C5bm zO^qx6SpF=9(Wu%wKDDkH3(UuYhEGxl{N`3AhOjq*cB`60vI z$NfZ)`^ok;>$9I!ver3T|1tADQ4JeuQ%AL_3&IMUtbA*HH{64bbl9Og>;&Oy@MN8K zqMdefi~M&?8e2WGWomDg+;Zs|Y~(Q)^_VMIjVn>A4umGP!^_um-q>^hMZf32NC~ae zbB)lsM#w|x^Nd9Ej3_Hs>s)Cps=FP-|MTZJw-Yv>poB_L5`=W(lP`^~^BICAdB&(b zV?k^&bi<;SjDsIxNvSrfR9mo|z3A+rc}9E$melV<)$bF;Kwi%!B!B$)1I}!g6go>v z5Y0GOx~_Z6ub;4_P)epyN^stKMbP)VpEajoYlA_k!5~5T&7Z*sJ>XSo^i`pg*o&k^ zi=;7&2KO&_8_ms9W7P20oSB1-OszystrRTf>F=f5yMxy*f|mc8PMAz5LEuYgVXEh( z(z->^dVLUs8pH_VggxC*pr1sc6)MXtZc?FU=~!UILa17&}ADEL<|mR>pkxjD${Lq7T;AF0~N7j5Lr2EVz9dcF5= z6zN69SDGOX&e|yz)F~A~1f=GI`u@mo1o&|h12BmJg2yo`4l&Vcr@(0{wNRB>g8Fje z^A)NqH^Y+RC8**hg4js=pN^tgH3n=g!(&s1hah6rzw}F5Zm$ZQra>9i@LvR^uOo2p%JJM*q)`S3m+vsa_LRuPKPXGiM6zjYoChG%?QdG0qnA=Bxc3zhIqt zu;iu;{-%r|E;;{kMySlY&CuOu$jDxgnP`t0DXN?L>W=S@6j{!yXAVyd;TxY&MV(L; zxC!msQ<0Jdwy^nDXF{v9AgYGV`0zz`rvsek85i}8D`@X)_KfYTO?QIRTy>>fbv2yN z?EGtRC`-d(=;1J=SNIer`YBAVHx%D;?NQl&Q``6Qbt>Eb%@P@Pf-DI1-3Z0(dF=PE zBwi5}uPA7{HD}U;&fao{(~PU5#{YYXC+|m@_I>3BOTrnbaE73PxV9`5(cioS&g`g{ z+^Cn%d}fP(Y+ex+>ho_7R8S{W1pe0aM(ZoZp+m5wKowQ+UvbT^2A~IQ;-i~{Le0&5 z(PlnAXWikOW@8Sv+2-vw4Vi(kkvB_FZkZJxIVT4okbGz*7$vU))2 zd%*qY^FJ7YRL9)WWA1{s1XO>!i~e>e7e7;wIg|4vc2&Ql!FBzUa87Qyp>DYeqMt9N z#(IvmC&D?&^;?$fC&>N$=MW(C<=fEZ+mN+iu}!pMn;e!nAeuwZa&Zc{=y05v3Y$+< zM}?`;SQ1?%Q|JdT?#o5>hX^_U<*<$T3CKvH#kxIdd}S=auWQ z%8H2HOBj!c|e>s)Avj z-!h=A&uxSy`BYRsRWN`#z8@{kOau}zfL-%qT=R0CFWG|Wo7mXof79Gtg}S*)aGyG@ z!+#RRn_z2gUH*!RFcriT4;868AL9J$XsN>$>TMA1O zR8a~4)sU)Byo$Eh3Ru#?MRjlmz2d58=)Uf-eh?FN=o?hQ zpb1=4B~`SNikEva8nARMfH8k&0Hk_N9(_$7*&R#dMN8zR2OB-^uV3IG-~7kR;IM@< ze7~$vR92|K2U9qK9V}7)VyNZyuP61d*PGAD9=i_3uFfs6q}*#+xtGAd`Ks+%*Yb}m zEa}{Z>)a*qZ!;a`^}V-t!1wtgi~1rfDD$`Fl6w=?++oR0Rn$#YL0PPNu{h-9Voz9d zCKPohRL~xxV|8l7lz;@}tv+028Mp-X9{(=*INI0?PL+T{CH%L^ob7bcb~M(3|n9BTf zskfYRTDPwWmXu53%ca=!5^RP-sZ1k~0Q2WVQRn|_>z{u_y@_T%gC)@`QPKY`ApX(I zT&=RE6_yMsqlT0Petv!Z-hEF>U&AFkunRq~3)vqBcZm+}!e4dt`DbUL@!X)3`;y|a zH?Wb;m8i~@f+n6iHE{GsN*8RT&<|bcCukSoiLd&JUiFjiGQ9fpyq|G@5icTIJ%(Cng(WBanK<`L<{;WD2rog(PL=IcLgj|?-ezpp6Hpe=48^p zH&#SFQ51A~@mJn>yCyO$nV_I1C<50){ z@B%M6|J`CJOHG#OCh!I6|NjG7YPJ+@wv^SXs$cl_;yL!>s)JQoA5~!U={l%%9f1RU zx_RJ8=v@t1Qo9^gyIkN5lntI7++e2-ORjA~UE3s>Q${D@RmMLX!ID@SDwZa2wKp0g zER!~1dRVRaGxl)6esw^v zHRsl&=GKcnsTdj0+HFS%AX1zjDXz4y_m<}OMfp$w^tw3xy0{W1cTYLvpEg$*s9hJ= z6au{K;-&~tF0NcI&e93rUiaw;{CVGAaeA+~(#2ZcMXX@q(cPYg+z(&#r&7=)_maqT0vnxVF4}c3B=odC9ohZ^=lz+&) z5rCWx^qdV!AG`WIS9xrKUXNVcAb)Lx^7L-L*~!;Uq5womSw>0O6RzhSFJai{15hNT zStO;mUQ=GTHG~0exxX)^a9@fUynRRO(h@54jv;NMX4*!*{J$N}(gDW~0dQfX?uCs; z8|wbF961sm2Ee6_>`NQ9#b+IIwm(5(Ie{F~2za1MbIyTxOK%ES;PKMLu zbl5ujZ#?u?w@!vzCu1N4_;oTi2+$y--XNoM!B3vFy)#-8B#FVWVlY}Ut=QPL=NA+L z5Qou;!x%bkNQmpZ)BFv91dL(=M#b}#v9nHuB~){#F&d{ay7pRq17axyP}b8ijC2g! zhxligrtu#r{+oeeW?(p*jxKu@KL(!>nt?ITz*r+dCPpI@qid1)z~xV8+Fp<(8>5qr zF??{<)OfM60rY|`7sJZMXsPu)Tj@~^hv5q_n+q_i@^WbwU*$ih0gb1atxqv-g9$Ip zR=-a$0^m7D?>WYpLc+^!JhKUUd)S6iY{RHzUX(2Q?52u_fp!~)hXAiJDz7o>&U&~- z_2M)r>#s4q*BDa-=)`R9#Hf-RU7GX~j}!xq9t^4nBev`YD)Mm2>mUGnF{oaQSkL1* zyPlK3p$5~B+1!s&4fJ%mf6v|y3bGGj6o)V>3$3G>n>SiOG4)}L;xI&{$-wi5isDE`H$-1gWf-SGYt^!_;<%M8bI3|DG=`{%Mo1pvpe z3dgX_pN7scV%;0o0}zd6L}S^UircSgH|$5IT^>A zF|pMj?_LVkODaw&6{q$qi@vDyQ6#h%CmpApj$`o_f5OXcxpESK44hI1PEBaDfpR8} zH6IWI8re8THjZss^Fl%A9Pv2-xj05Hjva#=$;;QBZULYG$0)$D5!(@paEu}x+xIOk z<<`=!dqATE$1K5d+;L3BBb!JY0Vu;U%Wxc}jK!Z5w<-S%jLL9)1h|1?-oSB8;!}ga zs>(r5=@w4;7LGNr!phEm>>Jd^s&PuyI5k2uwMhDv&kq1p!NBk(&Kv<=;TW%QY>(a#Lv_lZ z8h}OzPPGH4@m(4JC3YcA6M)~iO}}vr@dwNB#-jl)08HYvCvm*?Xq;Q^?9g%mrg7TS zIG)_Xjn(^pHN6L57RR2&X(!-U{n=oeumFGvJSPIr-T%Vz@1|>OlmUps>qOxVw=qR0 z-Wjvu(F3oOfH%y%;J21%zFY!mB;YL)@U{qW8qYnAH&`6;V%Son6nX)B8qYtCw?Tkp zyhbu!7o+o_M#S%vKF~eFIMmj2@hZ7^_3~x1Y()ifHJ&t8J^X=B&u?<5DWdd^aft}2A}@Zv#nc@jA75Lm^;Vi?^A(=+@VMLS?qd?4fW|Al(JMS3 z0Xp!^4m`(#ykEp>_z|Shfj8>F^AVsM&*;XpC$=Xg?6ss60*!Zg#ydP4v03Rop7|cn zc~^t~ob%5?5uh=MXAa^yPd*H=Z zc+H3Q>X$BzY=owgpYevD@#YBd1+Vr6uerKsZ?)fBC&(9m$7_Da>usP#_`f{*{T2Yf z@S4BydIM(d&V{QK-Cp_ualFwuo-YKf$MKE`FooBg z!t0I9L~M$;YWxh6OyP~D@O&X)J%x7^0xnZ{cLbQhThHJfeI!FJ4h%o*1~%sK)^m8r zc<;u2;7pIl07S}KN6I>y({-|?RlT6m^ti0`aaqSlfu2t{>3b3ZI4Ns)Qg)l@x24L& z)_agcIU{R*M%MAVHko~&-3tkHG_v6u21MMnTAlr=1rH6Qr8#Vw(H4-J4~S*>DO zeea!B-#S$Wb^}l;t5PYezV=aIua(_lUjV9Pb*f|yHKyCc^oGZq0H~2QsF5{Wlka_T zy#09w0ClpOb+UTDpFhN$UecEWzysO64`h8m>|ZKheDCmI03ONieI)C9_-2WhMS{N$ z0FPz&K9=>h&Tp%;T{Lyh1&-Q?q-arzHrV@Otc zNR~Co!F!UGs-Q{lu&lwbtXX2I`qsF_CTIX2k<}cL)#Ht0q;}fLLnZcAR^_X#deb28 zRN3(-vj9xXT20G3-0BISr$(Eo0Wd4enw8Z$Y^Z#q%#%z7Ad0|@B5?kg2dQ~Q?T3c> zC_+dSAyNcEVhE}+1dUhsHpFH+YuNym7{ZPi!fphJBdEm@G+*0kJ*dxomkl)H2!?S4 za|B2rpb`jTL$c>*|2c6F8a)#T>;!@~0-PprP7}Ct@^1rXa_@`+jnf2^(}XPukWA1> zCg^_5^O)0C2!ZBs$po`xf)xU!5>!(O8Y7R-N>v`j!~l&{fCyVE>5VY@l>Lm+QDG4}j+c zo#zBYe)E(1kn5e$+`5gR&_-aYv`bEY*-=soKo>!)i=dxgQIO%){-q8E{4Rox5ZKX0 z*o^>h3Cy_{3=quF1HaCh;AbHx^nsxC zfuOcz_1~oL&(FOA;1faN6M@-QAa+b&x&rEjp9t!o2s#KbN??u>I6b<}eO6N+BZ0;@ zg3337dTC9qi}ZGb2mpQ(m_G@e*q$RviOQi+nf@lI{3fVB8d=tTG==#FfJuVtBte4| zl-U<>gx&?fG(l~epqZk!B5Pr{ry&fsP7~Y^V3xp|C1}0K&09O!{}I{`89`)65VcK> zihZL*YE1x$BC?{0S_|%TR&BX?Wd?v4A}5B(ZB;w@_4!Xxs2XC34lzU*1c)Ol#t~H} z&+u3~&vBt;QUXyWfvEmvnZ3e>J!ohT&}pLTX`)7FZocb^@_uUol8LIxM2$30$8Xd` z3^Yb36ZMmcCJ2y9WTX<={M0t7`=dTkA4?^=rxLvoAf3oeCvrmi8CT2o^Pzs4PTZSL z^hJOSA|r#yK9yAXtB|oW1)JvPt?0lG^RaSy*F^> z7*vFfM2$wGE;Z@!sNOLMlRm#K+AzKXnvS;+HCl+e$~&WIef3-!09uK9 ztwdw#z~Z2%Uu4YzcuCZFNz}bAb8gvR8y2)qctzBEMKsO|9Zb@4&4%Jo9Yo6xqW$Hz zjL7D^MUdO>COUKzU9eUMuMA(Zg~oz+M9X(X`+d628&VP`j{)$W=HAu}0(Uqqc>M8nnb*|CQw7B>JePGpZ0wY8}( zYq53a`v90Ca;Jy}Kl-?Ji)gZt%b6jvXNcPA(mtiLsZw_Um?LuMhz2_*BmVJRYXZ58 zNIBg|IV0DqPXLk96tA3RmVW8F}r-=Y><+R_*@#GeS zXJ0BtL9v^+ay#D2?M8q;Ih{T^!*Tz9#gjX+&~Vx(=iVphg#ZI`oB=uR$qW=_v(d)Y zKx078c|dL_0(_9${z1;u$}9Ff4=WGFvOdW>WLp7=g| zCb}M~%HMK^zvawd|GIR|NB%wofJr&CNjafM(8dB)d4$ zHUvl@=_QbiFS-3egI^g$0gVKbWdg|_0Zx;2PLm8#V;Cjw2m$J1$t1mGlCjA_(`QPq zHFp8HNYcMZGWp=`HvL8g56uJ$NsK}gTj|R0tLC>i3J09+?A zuah`=E4S$Lua3S2pq#`gC$S$+=-P#y&ozdDeL2Y)0V+wVl_U+UG<~_{EY1;VRFVuU zN#+PpMM71P#8#N&jf|5&IRK3sl4=b}L+@O8)~NDp4ghr|lRDCtNLEUIOl|>G9t|X& z24DtvHr%mt6V%opkk}7M+R5X0%~oj4DFSM4#0@tDL$Ct|^= zZFBNK<0*;xl*Ez!W&Y6IXb$pY&q?5yOziIX@$JPtg)acKk(g~Hj*Y?Q@UDn}2moG_ z7_Uj}nizW5_XU|406Iy`P7>!W?YO(w=k5^zdPvM35~q~hSZB577#0RLJtQXt=q0K2 zlGJxK-|yFcB>5X?^pd=KNj?bBPh#|w*!@vU(=UkMI}J33NX#J;$LZsvR^>{UaR7!% zjA0V{+qt5&iJ0?t0F02BBP32l$L+!36}KJ&@Rh{)N@71cYj@<4zIlF9^0UF*Z5vNe-7Q1_T1 zc}U=Mr5~B&!DWQkr`=ZcH9H2# z)nDQ8`6V*r5}D1tdAi27aTDY}E|Zy;$(*8|b)M+bZHEEKAv1Hx99?qv=8h$+p}Nf> z+vJd)gn(-f*+U3;<&b@Zz`-2y5d_F5tK^f_Fa5Uo%}}q0)?WE!uY9r(0$e3?u9CUk zrC4ogsVGyRagEHmM&@eYAF~TDFue*uDH$|lZu{TsUpMb{+zCJhnNvaLzTe8p+S9ld zYU?-2oSS4WxvSy)V=MT(jibL;okFZ!PVs3&XG zlXc}JFv-i`5uuv9N7lGU*2O8b-8webd=`L*WQ~VpUH>B=3)DU-K$YD@)@UN@7H_ug ztshCq}#xt_6ix}>Q{5wf#M1DcmctO_vyHd6z!)yYY zOth0V+R3__>eY0QlLZ9;ydi76A?w;bW6RY)^Mib07g?i=tQ$~wZ;j=HrJ4Y|C2PDT z>(ci-FFv}k4(fz`WKJKM%NNrLyS`mw9RLGljRCT*w~tK9Q9_ky$bkYD-1q(9ZxEB`c4TS@)0Jd12mZ1g#^#k(IxZS(E9mQ|fh>UjXov z%=k%WFDHC{ly$MYAAsLv#&0saGk#&{-V5UJu9yykWf*foDWpe^W)hR2y)~#0s8naJRlulFB z3Vo@W7c2~+xpp!|Ihn%J@?WY>I9RO@Kq`fiN@3IYTl@CzOt1$aox)6~aQ<-<>*ls( z+X9e5(afOeiGOETbP!UZ4wOmJ%B1Mql!)0jEgx{qhEhM1Tq@ z=^}-cOcBk3=q*&u5NMKCOsNzprqqc1d|~o=pZH3sUzJmI$|;7=JlfM0b}xgbHsut{ za*90yR8km~6!y$%!<1X!WuWS+q;M-K1_*7}2f$=c?bK0u?LV%SbG7XsVbDLW9Li^Axlu+8$$i=SIb z+5nPtQDQ~9D2XBn^nt?qK+*ctuRE1Fw%ZNpe4?m)qNv-}nj-qNC(i$ILIuz{+G@__GqNuwOAcm?IL)9Egh+}I^=t9LDL){)j^+bR; zs#Y9TUm^U*wS-~YHlUF})k~ln?>YQb-bZWzy6tJI#%Zc<$QXV7g0zcAU|@EdY9$0b zPgA`SAem~POm!9|&P95jn)?irWKb0{s7%{SuX7f5SVQAX2Gu-+YApnUGN?y|K&(gx zHBm$ef$zXkFAJk$fXb05lgh}XvP<4&4*Xi*1%*d4sYaPpJ_2M@RkEq-|K#L+2}pfY z3^cN-LD|%!2#`xv&82Gi&ZGykPhy~!pG)1DOWlJ21yt1ns>bC+rJg^J-$9d)0_x5J z>K+6rqN)~AH5Q*5Hv8fu`vhndQB8`dTM(dxs#ZePWYYE3c1C8(0F4r=Sqaq&0m`UB zWgugP!K2wjMo^=;LAAU=wV&S|2tYLzRZSIBSgCk{LHd~v1GQ?ZrVuz(O$|YSS}M1e zYVg76nw7JBkQ_*IpQ>}8YFJ+69q)E|-EjaKsrrpnlZ#2lj}y0S-3!2L>gLx}RlYtp7u`ScGQ{Ko3=?hiaHVU1Oq>6$bf%9;$l})e8Z7sk*&Xqk|dA zT6C%01fbDN_2{MUMSy;)Vn0=76_0U6W>0`J(CDXH^-~=XV2G+XL{&+qIyPM|Xgvfp zhNxCUR0jkYrZR`A965*a^GDyVgO+>4RQqA7GXjiInIlw=hr$BKQ{OU8fyM~ceuV0b z0KcgQzo};4gk;6DDQsxMKS|Y^r0R2&O}`f&dkp#CNvg>tb&C*in54QOz%*5Rn#wyR zy0{_aMJo#=nWmafQ!Ryn<22P30cNS}S*kX9r^mSJURx4K5<%lc(6}tB67lNkcaWEl zpxH#woDd+2rV&Nc{o+09>uG;94`@Wu?4oGf5Fm!89z)Zq-Lra8pi%cE(1@d{#L?7C z{D!Bk3L6yxNT4Yv&{%68$<=>Isuc&|G)?6+O}+KqS-ggi3e-N5Y3yX0_A_Sn>_{Ik z76xX?G%Ey1rKzRTG~J^NN&+%IL#wKE8Yi8`eR0O&f%vb%UjSs#7#TEnpj=ev8{#yy z4$Y*oGHF_Vr{8dy7ZstW&8D%kX9Tb_q?}*e_x5dCsd$0Lo~rGMd(zErq^g z$vuz*yg}pMpc#x}8}_?PpM)On7ESvWjTePpZ}T+0R2v2nBDZKUA_!DX)2ycHxvcS2 zno+2RI%+MAQ%mD6-Mzeb?LYF+pioP5tEKHifV(v9yENWKQ=aBM7C{4O+@*QmrFkR3 zeVXQdnqK>m>KCHh6KI{;NYiSh>A#JQUG?g5?^XbsX`0P6y@s#T%USAiP>HnAbXsVJ zE~7`PujhU91fZ3s-%2w%xa!je)0Wsi0AA8KFKOJ&t%|7a4vze5Hzx@nwl8uu{vT+i++olwx}9Zl^WO>@oNw<;aZ8qjp? z9nIn$%@zUP)41({A&)vp(;1{0UR~vJz(H)+EdV~!Oh3{reLfhTd3DMS zn)Q69>3pUcroB>iIes884uCH-^)ED?54HR$?@fcyisw7c;5*H1!_BL$+bFKm0Q{oq z{-PO$J$`V4P zyaF}dGj!$|I;Z!Z^i~5aqn`krr8CdcIZKYu4c)oF2Wsu-=vwFK`ql1%Ol)Z)1Ay~% zt@Ct!>Dl;gsHd8v09>SNU8L);_t|y6^}ZGq5Xhplvglf~#P;g!Ww>kruFzRm=vuU< zDLpNt8_-yoM`z{HwdlMP_5sa$X#f<`nT2!?y{Z(in|rGPfMU8zF6C0-SP z>vZOIIwz*tL~g=W3R?e{(^bpq8eh+BJY_PWv>bp+x>_Y&v;4HWVqVWP1sH6tq`M(N z6F*vz#uxz4>Fnop?a%RRFQ+)cr-Zc8Ic;?A{N{0>(MES@ zqq`u$YdY&SUF#3&bGj$$7_=hpq;osz23C4UJWkfG3<98suHHk}NmZS7$pr5YZPuIz%92O1y057!q>BjwZ3j`RVbB5?# z5@zlRO-oD-*chT44bk~Rzce!MhX=4feeDPz zhpPK8o%5H@O%3$dGTHNl4FjXUbUp%v%WH(o>-uM2^QgUOVg@wAB(J-_>eN&JP&H_DNRl^9 zk~c?y6nRdHJa=I5<%EIR8)yoaBF{^aH${L8@+ueP)gvx3_{aNCXaS8&^4gc=d0J(+ z{i9^2o&#`Ie)Cm%)elCuGlr9@pjF~E`OVklRp)=F0zj$!=2Cgp1K4+u*R8(^O$96D zl`7=beu=%iBk?i@s+S7+9ToDs5#XV`#Y1`9p{V_fjuLn~fyR`+@{~TSz5GrHIU*h! zP~v$9;&}%LYy3alIO|;xKqAj6k+;2e(UT43(;syJNa3MUcw+f#lfimCd#Ej^@HiGZa+7!9Chs5u+~(=u z=9zrCd;0z{H}m^I<2KLpHqToK1mEU`A;1ieF~ei$eRd@I*cM?xk~to8j>kE|SoJ*X z|ERk2c&NVrao|n8lQ#8k)$(rN_rmOpZDyDmyBUgE%vdH2V=ObHWXmp5M5L5bq?9$4 zkX>mZB3ne1C~2eUd+z*x^|{mIasPRq*Ew^ybI$7?)14UP1^_`6R1k%b=O7bwS{$DQ z5JEwPPzdyjSKjMNvn&CGQ&8a)0#>W~?%``b(1a01K}Asr%l{cTC5o_e0T4q$$54p> z(X?OEV);;Z7)L?JQHbp}%iWf&8Gi^Mo`R025I>n&5_h6~p~Z8 zPEaxholGH$Z}hhq)+xSel1f3RQi#=tmNn|+fk6dd8l~8fR(cNVyfI!RShD7qWVM3`!ghfvDVMLB`!qMSy+sE0!8 zp^!66;@m^bZaxMveH5KO3UxdFk^7nH$MO_l(nn#!V1Pmzppbt)z)mi9S`MX)0~DhH ziUkbbQ?%bxC{L~vrz&!$Edde36un`JVaL&z>cdBW9|iD-;1; zKNd92j#J#nDc&#$r|O4OX|&z9{EGO)IUpj7ip`>G|9fpi#`cBYR{-3m>fEMM>&k69 zQNgcI0T`sx2C1f>l07O0C(a-gU_D6Xz+i-GGD2nQA37R1|5G`X%8gLjBUAwlzEbgD zsk#ol8TiB-bGabm2bKJTO5YU{_~i1VzF`1Asr!CXk=w%fk60`}=$UJZsyRi)8c&Z% zW;=EW0R$Q#0}b#;n?L!Dn0K@RIBuYE+yE1EP8XL_^`#C#m;oisfFTV~KVENn4Z24z z7%(mvn5&A~+%Bb_h0gmW1LI2umbGUdTLteo?E-Mcz~qVn^Uv!h08|^GstpKs=R7}& zH|_2QP-j4|GcYTz*WW$#)ye?CV*}mC1_qt!TSy+xvCx3<)ByX`K)cY9T6}pel*zs`(0ylM;OzIJZT3E!{Qy1~U_Ka- zIyR1@Wm{L%6+r!9U<8AY2AGcqB$BC1?7Z<6&;r^=1L{WuBN%)(zciB1cR>zn6Cz;|LS^UT~3^Zl8&zi)UO6cFi0`PrWk7P_R4S7JJk!_{^t#K z&KpwKU#ALPLe08`o5V|SqX#47D$ffsky(*{H z+yn5KhJH*V3Q6V%)-`U1ZoOYL?O!xX&-hf$W9`+u0sN+sf79sy9-LG5B7P8>@`LF3 zAiD0mIYsDwO}nW8Lg=&*x@rEm7RtMJn>zr)>GW{AncznuE#=8~Xk9#tPK%5N3WIq~({cRQXzEF&8>P}MVrr{=Mj5}&0i@B5(&!c< zk-MF92wRa>&`r|m%-w;zS=MLrph+QvZjwP~2H9K>_n;nH10aX4nM21i=HmAzC%n-G z@Pv+fLMPOkZ6p)ptf7af=k!C*>AZ$56?Vi%~d=T-Lj(khUj~M=-K0i7IO&f3Nyti~mC5S-0rJqD7(N#b<;B0|cAqHV^@nF)(EeQuWi6 z7d2W1Ks5tX%^(S4-?()00=5CDV_@nSBww5FpZo2nMFV)uz&vJ*%D}cVw9l-o zZQK6uoDl%+3~W0?`_F4k0CX|1T@3A4drb$2gTTMS4T`p+@^nH2Y1kro1&1sr@}rpXoPo=r?hJ!Jvu8pb5sOqUt;U#F9o3@!iDy zyNPwCPR6blT#aHsOwAHat?ncyZWWtPhX$2oQ);rQ(b}`P*T@|#XoV=*)F#=~4hFSm z#(S zOZ_5Cnp*o0UBkWN#{lkH;_h1NNVjiTNb%6y382JMqr?(ZxamezkK0ygU~03}Y_r4; zzHW1-eSQq(I~|r<9hNvWWk&z$T{aT{x-B)kEwOzI-G5jvvPuNdYpK<1iSztHpVPrA zf$qY7OU-^utkR1QwFWJ5uooW=S!xbhVuO5-IHbQ(frgzCORW)0+~k`ve8Yn_C|4P^ z)Eu?MPB>gNIuO@t0^p0K))!0MBV7BF*3XCn0N*V&zguFJ-j%2|VTpsiD{<0NbJ7w! z_o|#YcSJEa2Qak)m^k_SN=u7R(a<;)%+w5KV&i6)?wVCXeFPwssTIn^73>ow9HpC_ z0T98|j9_Aw-lnJ(&BVdprg)NxJjuj!Fh)j~G)JK;cZ!KT#l+k84(O1U?B@YUU?LNk zc-Z?ElbFaPCVtZKg8rs0GoaBwg^5aG5*kY{7KU6s0_BkBnW*zjLV#b;u6ptqG*F*s z($6!^U~rL%x(FhcH~%V*v^@+WE;F?*Gja2#sn(_W%zq2uDpT_+6MNBnUZK;D{m{sr z#nj4T;_PVW5o77MiUHhUYTf{c|0(PZfBncHfLlzhTTEPK_}WFq3+@I1$YW~dF>%qQ zQOP|Q6#o^pkf~Y7#45e_QLC7VgT43hJ`;H#9PPcGf+bgeZ3k_XGLfZB{5JjSqUv^{ zjRI(;Oj8&%N&JQ?w8D0;pvYYMFXE54P=mBvSlZ z&m$)B5mUb@(gN2?);$Lzo-k2Qn1s~ogYi#yy@9fW=S-5YQDOmtsFi|g< zgtE(b*tb>RLmlWPlkk$Mml5zQaqe6jI{;lw(=H|}J~rA|b7s#e06k2j9;QWB1Nefw zBvTCF4$I&U%edL)f@Fnz>wN{V?yziO@RX(cl%;lI#)-c9`lV2Bc*?>)Wog5pk%ew# z5x2W1^&KOtKoQL>Y%@!{AX}_|dTu8)qjs?lbg|Goo*7ORpDe{IfY`;-hd~c(Zx2gr z?tGKPCt5S1!|!3?dRRIz=ws>hv8Z=eH)pMR^I;l@=wli6u`HB;-NzCrfomU2q6G3j zmcJ52Ao^G*5ilBH=?t)_JtRCHzvVPApde5>@0`_~BKnYymvm{C& zf6ww)f(XQWu!Bl;7SIJ{$^ewDOof2%D^oR~$I8?Ms7;yP0D1?fVV2G?i|UecYN$&O zy96BBFw1C|WuXMN!z{iM93E!5D}j8NKTNCid#Mwy2C%Qj6Sg}l)&~A zi?0NSKe52?lftUVKe7CkAOi6ToGv9g1L&MGWdO>C(-=!AdV+{jD^#f!A$-Q$=hnL$p;`5z74o4K-f+%>9Bk~Y zO8}~@gjH5<@%jz*Enz193XoP=`N80c75a%45%=y%WH91B6GS|*;ytl)R08)WR^Bjp zZbf)*rMIT@!7AI`9Z=5w!iw<1N^ij~c_blAUJ9VyiqLMQ$J=DCw*Fc?G>NubMIzd* zVi8Jo7SIJaby?|lSsDC!MGdIdW2M_;WuPi0N*y~T*8u#s*7$9WDVnP*avY6;vbW#X z7Qd|z!XW4%F6f|6>Cx$~0VNBeq#)!VHsqjoQ`VkWYu^w90lYdye04}aKJ3afKdq>C z0G)?)IuB7-F2v1@%}Rihwd*#h>ox>x-Io``1C3Y!H*L^2ZHRY7c5l`{K5PKswhijG z4Piv2opJB@JvxAV8+5)6F(I|kZEYnt4nUEOW|0ln^upXKOsYS$=5^Ob^R5lnI2*q} zR+~ZsP-25Bu_5f58uHxNmjta7mf4`nYzQkg;PSis0G@+pGa=(EA~ z+2~xEom=I?m~ReXz=kzO$P)k^w&V_5y3SdOX;>{pj+~OB*Ya$JJxGU?X@++*>3Kx-l78~ zC;hg%{k8@=2hBsGyhYGD(x9#0psiuf#mrm#Q_H>s7_y}e*_tlfmiyhh*A;po7_p^} z*c#;=jd#u5=L=27qqfvhTcdU7wfe8p4`>4TVoUsDtIz7)o;$efQ#yd}w#4tY`j$WC z(M^N`R{#^X#0gt{(!+yUYd%Fl*JaXHXVRAHH{-hFbM)F}00P)L0c-y|M%OWk54Z?W-jtN%&PS$-Yb^*lB%kF7KBUYg3{8}$qTg=|tGo7~2eti0H5 z3_Vg7v+>1j-4D7I^Jn@7K&y!N*|_^`ovJv}^_~YY8URY!$Wk``sR4e&$!nPD03NcD z583!9&*ID;4VRw>P{l@8vGIBGP5+|i-CqNsmW`}sMm}QWUq*e{ zY`4xAdX{;@Mm}NV7f5aACZX-1oBuf*`J9b6jGa2Xa-!u8fER4!3pU<E`NY*Z(k@FDU`b8pdcsGGiKqh7NK z;y0U}a(`HG0K8$N-mnSgcOKL;4>UCZc*{n;WfQVo+kzzQu=N1mu~F~XguA*0q|*Ht zpaNm19DW5y2!m>lel>??IqhR<`t32OjcSgd znsXQibsTaXhyJtBH@9+PFEm=#aqR0j&M`&}a_IhjES;fO{~3<5^Y97;2XfsdaNa^v-t%b-#-$Dx_y0)ti# zwUuLZMiAlFIAgIPh-l?FwsKsRz^j$x3xjqJrJchVU2+$LMZ8S|Rk}FTE{@THE`j^t z%q7smOAm+C!y!NFTJxSnk{t!m$I30`HXJnY8JIpbdXDINhmb@KSfZZ_12?n1ydY?Fk)DJV}?{vKk{dMva zhyRHqguxg`cZ_3TOjSR0y6QEQV~ug_#yCze_{P!u#xY#v(B$=*Fa-@X-#Gkl93c$G zIplE;eb)#3YF&euCqTqF$9|mS41-@B@-Gg(FWl+*&5Cc(o%M@j|BK@cgWnv~Zw?_? zr+?P!_b;GCC5Vd);_6)9UtSpCqxdh{AzWezSHCvz!rE8gx&0s_oJ$Vp($AZfyf4Lf zdjg2!8b)zVO5P*0_^VGqM;pU6i{V=N1?9~(@@auORvcF^j%(QWJ?_}9+(*ztR6Lgy z&n5E*T<`lwMm8%z7SBBfgG4SVkxPzyVXnTfR00i&iCkGC_ZSS4xuj$+`9jOmqjG^u z1BgiG%96RqV35kyP30Omu9{%)HrWfck;*-eNaaQ%V3fu+PUBjR>Rvg!>tkRzh)L(- z(z!a#*XI71BD8M;kjcema&-p3TwHhY*my61Y%V^VtDE^E)V0)jP7Ht?E-r_wW65%PwQ$LQe!~w$v~Z1DxE3&IeLj{0~HY=i853M{7))}BlU#k;9zpv*M!zHL-%O{51GKjtCPzH-wob^hS($? zGKq)3pFEyBbLfORfD|4wg@=z)SxTRKZWolwp64OY^YH!*6SEAA6|{hGk%zj-BRq@8 zd;ZpqgGRE;Jk(_#!O^PWqhw(XbjGgoP*-^b%vx&i>zU3?0J3ih1OfcKa@F63CtcxX&Zq=aCCe-WuMsZCwz6QXZ+4N4~Me>rU-~ z&+7m@-zZD58o-ssa&*-!p>GKUoE!mWQt85x-&9{|qIR-c^8GEzb)E zk9f#OJbcX^lfdmo_n?QeCp_d69{yYPwApW8w?pUSIS=`qhcEa-JH4fek_g}hPv-@X z`g!A`nNLr@?gH?Vr}L6W-Lfg->+rT4Q0DrIr}K(ORevXZ`A|g%O1fY1OkVMrN?`wr z=L~~Ro?a)DC^xiPXbN#uX*OL zdDcqc|C$$qfXN%4{u>@`34ZohvAPR%(%$gQ-|(!J!2b=X1CzHr{kJ??hiqBA%wGd~ zP<_iYf6KF00>`&JR~WqGk>By?n>}_dF0fU(0IIy>S-j&NR082Uo*N84@bo|MX#0Pw zEX{xH4-JqXc;+8?)=FUaf#(E+k38H*o=)A+!*UM&ER=IMXt(MpaNr=D!dVkyA< zGtXKHc%ONWFc{|{$9Z_0)h-v4UfITjDv@^jk#@8M#>uz4cC3f`U8J3Pq@6Vk;_bBK z?I>-!bp^BzrqZzg8I-qG*pVyj=r8<#<*u{qhn^{`?P%3@rps1d z`!(&beky=EJDoZ^YSNseKKu{PUjQ`Pp&RXp^*u--0bRG~Sh-A=pRj`DKTiKW|i?UV!Pv2*LO^NO)q_|D*JnIC{YJGVYN zuVcGh&UVwcmjW2Da~rVpdJwrZ{GJm5N*CYT`M$RcK%66bP0Z0;IS0s3JJe4*Ldk-e zu~$xQxdb4H&j{k1&!RYA%J)3-2tWwmID~IGw`H4)-Z*yzKr~+?nvb#C<5VTxzQ#)d z7Sa5JFgVG_p5$w9dNxsiJ8U-(M4aT)PV!A*aEgyT#n&FMTwC*eWw$ekNZ@NH@F~uE zEups3252x#;%g`IDQ^++k7n*2fX+}7pPs}wgFy;kJB3eqHr(~ZAu^%^M5OTPDSR^} zV5RVFVQ`+WeV$L*H1)e|@s$QB89vXapXZw?0qZ>9RtfCR^POODk=a+zoBQyYQ+jc zjGzz^Be;*KDL#0;?Hq~(qT&Q+5pjYGh^5m{1{1_-R6y~9Dnz{C5#rE6L7cR0_GUnd z0#>5H_LG=kbFRPYG=O9QCRspQJ2h-}F&s5r0Vfg3f&>JNQU&^{0@{#l>Oi}tBLc*v z3hp6N1?31Br3o-;0#Xk@;)iyD8k88P3C<(Z1eXyoN*Cy-3ur65o-BBzy%G;%(gpR1 zbip$Oj4}kc41vzgb*cKyA~z`W%MjRP2<%{xDe%n{1R(O)a3pQkb`u~ZTY$+HkXF?m z@to-pD^-AhwjcxnlRSZDo&cMib4M$SqWcYm+!YY+3iMbev@LxLRzr7xi2zq3&|zm! zGGFb?$N*4muTgA|;RXKO;u+^s2Vl@1HE2&j9_q~9a5W040KGwbLnSa9w6}u6kUeq8 zUcdiXs&Ddzx8-FFn%+)0P)|4*DS^`o z2ayuUPBg0qMd4i^wGig!T8I}pes@9l?b_CE*BrZ{M)I8dg~*&^J4ljH$7??627 zpno^b_@8K-SOI`54tiG{46`y+p7m#M*Z|;~gT^%n%%As`1Gw&>dfh>7<5S8e*B;+H z0B$;9ZaR>HgOjp`HTLKzfOgZt6b82)Ft;5@FJ@j_SMc`XLJ*PfpqlTXHdMBb{>rTN zB7h_aXsk>A4t`=JWB@Uz#2l7N1vF!HPZe0Ln4%jkq zI1g^OoSD8e9YBQxzQRHG-+4~S_dlpF0#NOMtaiY+&iuG{F={1E0f(v`crd7QAk;bN zExWKd;q5=Mogkvs0om$+pP|3w`_9cLb|^r<)qw_s&kjbP9V|Yq(MS|>o7x?r5_+7rn=@IYJA-bH{_v9l0;R>Y^Cu8*2c(bY#7BwA~?% zwz=sV4zU6YFf5{cg!{zCL08*XMsZK=ewgroOtzDo5In4=^=0pmA zzH9&4?;rF5+;Gyr;Y8cB#=(vYK|v57+MqYv|iPnzaJ7duf%Nfa`az#>t2 z5C+LYY_d>$UCX1Yu#weJHjpf&BnufzV3905s06%Zp(6}Zg}YOQ8W~0_9ju7+3qc#H zLQJZV1cNl;-ZY_>$p!5ztpZzUYEKj5(u6uNNEd3Q3vsy{-U?4o`vT>{=|Y`!Ayo;C z(uEc<$Pgkkgm}MJtKI~BJTwbs2z4`r21;O@A+&@+rcgCgsMa)^#y9%(`w6I$DRjsb zy1*b?cpzJd_Vl)O>xnt{8ARj=kvT%V6KdWJ2a7hSzvK${<_fipFK=aMHld+es6e>4 zK&S=#NzXgNy?2CKaa+2cRhBCLJKa6u-g`nVzZlHZHGYY+K$Qo=y$^(1|IAMfx@nkc z0-#*DuUv@CTHfrxfY1Z|Ii*s#uTqHItiQNyQ`*>l05!sWHA3Xw=>gOs$3*BP*9diL zgj5*R3pMM7*aq4g(##v)Ss$E|4c}FCL|BfJ~k22 z^cecsCZTGRP_5Dt{f#Tf90JfHRBaKeE#Lj}qQe6(YXEIR)i$Bpf@6psWi!6c2GAi? z?GUQ@g=OA<$!0)Fdbd!uTc~!JTvuwAxfJR^y+T~CQ0JxBuZ;ucwoq^A7oz)xM8Q{C z=)>xK=wk2(t9d7}Q z3bCU??fJQ-m;$>bDE0dy#C{QK2Q5nL5WZL+3*fsD{ar|`y!7PCDxIL4049XQ38DU6 z+`VN))nhvWObUsULj6T81v^ul{)L9VfW!EJ!@9gh#IUaKBhbOcAJ&OKOvSpZ%zoOt z&p-j3_`~)vNIa~Qc$n(Ccv_qFGR1F=<~eKRIb*DRds9xUELje!6gnddo$*8S+?Uka zFUbT@?2IgS#uq+!9&8GCp#ym4jC|&d|2&hRvjpQC44}yw)#OYt+U$4kf#m+E0;o;S zMlfh`MzuH-PKRdr_-@r9f`~R}%{FJO)9M}1-)C)e2GHS*>u}Zyy|m!eHBm_}fNp1O zx3l)G`cozguGK@+YqvA4+u0Nbz0TNPXYJ$!ZBNa_8VeB7>rCr)HdO-KUT3}%L?L>e z;}A-87f_ipJqPqsncf5Xq)frndz~Yu!`kY1M)x}tzpmTDpLZk(0rsfhnbGfTt^~gQ z&H)IR3_6<(Iy0>sWVA1F<4`&?|u8Zbf7wm-v ziD%Ew{IyyE4tHH#V36;M&v(^b`KufGSsPm8*94 z*OU2&va_I>ugcY>%GE;&$`MtrH3%5Jcg4JSC6%vYJ}L`Jt_PKdUA2c@DWjv-xf{y8 zy%k_O?8<_{H&@g*SHh(Vo6SFF?SBCxLPUfRkzO}yys-LQAT%z8i-_SOeeK?_Yt^nQ zaeETgDIsvyuy0=9J@5YeRAFV$x0gx}+ zpD#j%sjmpAZW#9kP$b%4Btms3J@X`2)>;C%D^k5HQhPXWOaBNv9vZpsil}!*MldK7 zQOiU|RvR&-Lua$kf`~Fv7@|yc0s*56k$;6K1o7H@aL@3JBIu!`T7;?=5jM@|e%U`+ z3O#;Si~OoZ!3ZTeji?r#Ri=x8uEMEK=MLIBMoon{fW zXVZhXmgiPNw@SihuDR{I z=7ucVtlN=R;ti#X*W9$Pxlv${8rGOYC5PxC;O!v{iT~(q2}hd4JV&LGgXh9UXPpM zaYr`ifXQ5F=lk4{eQtR7(!7Id+YKB647lkHxEcQWK_LJmZn`6G2Dtuwxli{R9{{6n zm{B*<%FLXLp|NGg0KT~G|Kf%kKR2hOjoSMXz;`!|?{1io(#58uBj)D-Ot|fxaMQZt zdS=%5#{JNRm~`7W>4vo6&z$}|CKu|50q(m4+%=5fZJgC1P2C6Jv^(~+yY@%T*J;16 zUxdDpk?f97cGvBl{HJu&_kAt^Qr!uu?s~gVUR3|UiN6OR%^jcSuDfy7nOh|vMvDQY zyA#sg_3C%mUKFfFLN{@SJ1N7ReC}#r(aiBoDAmh!CuO>mGcUcXnl`xf5rCKOhhDn# zX0_0BR}Q`p0`SV6^UB?x@3_Pwc$wneiXYrfKDaY2ae31@?Lk%`;-fq1qdR%Q=`M4F z;vEhO5Po!bQ-UKO-2)LY`Rq>o?5_Vf?KB_Fwk-#BKD*n0c6U~SyNJ*3We6C3btimv z*Nbo{C?8RcuLG67x--7Io5SFTJMD+N>Bbt9{$CM#Iw0bQJL`wLtr9r@a2La1${ji7 zj^EVseA!y&%1}@xP)rOI>jx&?GyB!Eze)kLK(Q$dj*Cgh#pGT=Co^$Q0W|6y7t@c6 z&6L3YxY!v6VPfqtF{SF+e9sw2djmn0Ffk)cYz~7+u}-9zTGaBmxpQRxW)Kl6Hi{Hm zz#vY{h!dN8udd(qD^3Gi`iU1C#fvS<+tq5v*wqXGiDKhKu_fi=L(i!ooECs&u~D+v zLep;6%G%Q>rzyZDS!|~S4#{E{C2&s`dn?t(>Dzm zY6OreW@L)Ze>PoOy>e+1bS&9odbZeX$=nx@ow^mT0m~L2%ocN%K#(mytOTNLv8NJ9 zv&DWe$PqJg#OA$w78t)DmL)e(1W3&?2g#@7WpZ__JNoWgDSC8l~}|J#Yr{OE1>6=TCruV_|RC{`x)*Q4x1Ff zuN4bnP~xFc;(=LuxpJEfaS3`lD)Z1R^T0kkbaqXw9v@oOsPNFJ@W7ym7A7B8w%!6z z?V(xif&KG)+yLr4H0nGsYb|1ZZhukv3E;7Z=3@`+Wq(CDGr=z;CuA|s)jY;FK(_Rwnfz-=UTj>iS9SOlQeL#x#Tw|Q3ui&v8mUF>!b zt#%Jw8m)EJxx9#F0J=Q1x&SP1NjIY}83*vgL+^)&A=2{u*^ZkOF@T>QjGrFncCpj* zhn~3n1~BD;o$}D``e&bAW?Ov>fIta4P(sXjg1RqT^8@NpVG?whggBmb=*V{o33{N4 zlwcwyB%}MXM=g#~(BK~_F^`m3!yrLolpwJnf9zhc^73}*XcHv-1c?v^NfP5EiKWot z7C~c}42_^k5EwrkiDcP4PLH_yCM*!K9ec2Ku8%+}O}w=sPyZQ!T*=;C ziPnrOuiH8fkedM%NHhy1SXcEmHf!rh(DlC~IdDgUE+^l#?rp)D0=OsHdrzXZ`$wDo z5aBB{mOqf}eIU`I)$O)iJbV%AAP*!j5f3Dt2pE-1G|DBIyDwXjXTDq#jwqMJ zAe5*c&@(tyO7>MskiUzK-aW+Jga+D5iA|-%4hA)n-8B-8%8Itnua2if&-*nJ?HUOM z2K5rHdI@f|_3lmmQR|_OR4*~8ml!Jn3;fqW{8YJj{**90!#U6JDRT?DZ1_>Po z&m@}9Bv?DUp7Xv}QA=yy7P1q$-fa;8x+RQmiFqJWvgh-j2xw5~muU7&uxA9L@pHUq z@)cm-FR_NfpaeN6!N0~N?5Vk5uL&XsC65Az|8EK*W#)JX}e@ zH|76FBNF+D#6NsXlxUfu8#G^!NKz0Zl8Xo!eUTjaB0)DSIhOTdp8PV1`7Y7?F2P36 z9a)oovUClA35oZF|h=Mir~pp_?MM5AbWH0y z0KuN9U{6At@!Waqoj&&f2=&wq^~8pv=bs5ZZzp-;l00>8%q4BB%rQEy0D~k?V;H1(5>h<%3R^DxE7@v%7et)*)H?5p zo0t)i;83y%N*ykGqAz+9S+PrwHtZxrQ+A;zq0mzgAzj1ZcR$&x0GmQjI~Wvul8Qaa z8p}2`AK%Z0CgfsIcCn`b2KPM!5cfSp5f8)K64cAOp+0!u^AezIa4H2yR0@vh(frkS zda84w6H)4U8Bi9S9(u|jditw1F8%N5gPU{^^AKvq^CkjDRi4-?Pi;DW^w*oJ`_TAR z1x{v_X97Zr?gA=~|VttaJVSZ>$^VPg)cR_l2cQR{gFp+t>5UBRV6Z6EAH2Z6ct8-5&G)6t~H|eA|`M`I5IzoH5Er0}Xodj>{SkWa{ zogb@`09^D&UGyewj&fjcEBA*|<;&ja%ihG%Sv~&D^mOR?qR*Sy=dE8kt^O0%B?8*9 z0dL}fxBi}o?`H2;nGSW3_uiEE-i+uwYTBb~mQVl;dsBwJ8Jx&VZ@1=TKnrjueDqHE z7

$ujLgy2l&)K<)y)mLVVW*K#TBs09^k&SMRH7U>6zUWO~p|LU*?oGme_O6nH`x>|L&sR&8Pw|#8^o(I|0lFO<>_HVsZYbl6gQ@ABhSV5&NNkKqT zGj7q)Qs_m(_^>FA8EJ@?dSJh-W9Tvo15zh7iR>3*`Jnud?}J)-4Nk=KZ*+Sq{|SVk z@Hd+*1Rtl)^UQJJW3O(?(9K_rF!A%^m(ZFqDND?AeL7dh0skBsV_jd@8aoL8<8xpQO2DvLEW}z^c zj1X+|U73$B1w1`6zo8rkH{c_Dx(xE=2oVVZgtL*5=^;S^Eq%pF`^fuAH}U3MX_6rx zW>J7HMoh0Yc%MP@<{wS!%KiTcd4KT|#?0Bhr>AFdC-C9#^dcw6cpuQB{O7qoY|pPo zB~?8}0K8NNP!?lZ&djPMqiK+R;tr0P^g>_xc_|K5{Gwv~8SnRf>1@Ytfk62)bXA~* zfUf#3ez~}^hGW7wf{^%qgMF|;HkDz`x1yD78I0)OZ#SVvAIvEESg=Ga970m;zc8pa zVm3!TqE47yeWt?Xa7x5ySp7p%n=()-GwPeW@{=+BfPI3s<>Exo;6~&qn-6z!b8&IG zoU9v=rRnA2;jx%m5_A;Qed%viZ9YA=E_99V9@l)xS*HJ8z*IF2hl)y3Y4?Mn$kgV{ zMIUiVS|^M4am%c6^UXlfXlyOuUBB}V`39~f>0fBox5|rNlU$RSQcJl;y$lm)!N0NV zT@`*cbAnBz;E!U@ZSS^RFAm=+_*AD}XPTpE=ofza;ve}?Vv&4(eo^kZdM|6seQNb< z`GdtifZLSx8?Ugvm&2Y~4{=TW`5I8b+wM9#sAd&EF{(qwlO6RN5tYBr7wJEgyF~nZ z9T(f*t!169Cpg!#e`>fGNZ)=4a56;Tp6WEV)0ro&k9F_+D&m{E|2!!O)RaiQdd_$b4bStJJ-eCT(0%zw!XhL2^x=X1oJ?&WAGoBEb) ztR<|Q?fLSbrE2oS+fv?cQVvKdbLz2#zc@9G@T{Tu85*b=w?vIcF9kLN1S^sp)@wIg zr{m*Ap3cLBy1qWN?LEdikiE#ZmwnUV>3+S}UF3#x1m(Qmt7Jq&H_Z3AAlb^xB? zFb7>0X+d#O>+|;UhO}{up7mS79>2?&8tSC-Ji|c2C-mFW;_UO2sJT3%^~;}WlDCYo zXdCTZXx*BhJab>9a1p$|V&k|PdSZVSH#-&#jI?J(W@{|@^Sj!bG z!*Uib*T>LxbznFtVnok}twxUHepnbaVYsb|tq)R8<%*Cfm*k-OvIAzu>L5F*15wxrZDf5k^An6EBN=Rt>ybQ&By-Vnx(XBO_eLX?dkQ4kdFgPi2ns&OWr2>@h=Ayz zXV3s+A(2i4e>?U_iJdRkhFnv?A5e^lo{m8$#dwc=evi|c0twrb#N$3l#hf?!!r-bk zwibqiq$$yBeBhf_Pfqpox1DG0pSC=3jdYn{yc!ZzdiqX3Li;Lj8vH5Qt5ddW{!tGP3BfZ;-0c zhSr1^jd1PxRxXg^gKv93-W>2QbNeH!1t~1YSI!T=rYsw-6|PDH$xw zjGm^hU`Sv*1ERce=>af6NVKkVCr#gcjh9me4^WCwTG~ZY$i}UV%{w_sd*wZx{uwmO!_!Pvt(KP z)S}PQwk&_3#4K1Bpml$G^n-l!T?on>e2fZsZfuUq>=MWD^$jwEuaeNs2Whp7>?Jv& z*)7@PT3!{J6i%5uK_YzxfBjz{`wl5w ze0&R2hnjufU!Yox5JV zv$r&n=;AL8)9QsFbE$#U>y(HRjatD^M8_CK>6On+EAi`hS&K`O$ok?3!>``e3fS&z zwDwQW^iye9yDTUTSoY14Nhm!~P*uS>P(fhbn)?otgitUXxIt)y^vja&{=^$k3( zJ)Tw+>UVkaa2nuZxtsE%)JwkwXu9H7;2D|tqs2>K+hE;=5f|pr!x`~_;?65$a#K!Q z9aufs9fY}3R8kkBn(~=6>qHEF?bwfKI5CbNSR>`I= z`vxO_&dkphu}+pM=fk$PZ!$To`slXGtod>cy-_t`Y}f(6^58Z` zf_`g>=~%iep?6D#iz_!p}9t|BO@E3)I3cSyCVD| z{&M!E#_#m{kT$m?ei04PM_8szrl(6OQZz1(m+BNiIqLqvK1`BMq4ALxUSE)1GQvUqCwB0u;1s)^HGC)Lxyz0O;fhz9ua_rUk5v$6v z&_>r-7k`l-=~6-%p-f5yjydPFdZvhFEq-{VP%gjFO_a{2^^qLsNUC9w7QK5m+&Dk2 zqD*|L=KPEUfH%1AXO=>@ZEP}6oIgk49vV1TF{Teb0)2vBuZ19hc#a<)~XU_&EPbZ<*)1QTgH=Pza?u6 zap(xqUu14KOW^<{;!Ys0W)upfhO@W%-Fl((#rLAG-8onot-?YnDv6h(na%xrNq4Fa z6+Q+*Id(a;En}C(^crS^uhI>enXV2@De<}a>nUa9PB~j=%I3Q5;JlBj=ZS^tG1*yJ zr(?QnOq1qz`+2|fWhDbqCcJ#dsD}xWaQ|jyG4Lt`rq6HYj)#n3lE+NFZ7vXA!}+gX>XsJ5rmI~5`e^oTT`VdswMHb-=_R`WOomY zcoSJXKJ2Mm02W0=gY29a0$S=Qo=6j&!^J5+`?|I1w>rhIQ15h*3V6PE$AmIgrS5Y< z=VwP>U#B%IZ^MSv{TB3FsW~PbtUSh2X&9WcKhU5`6p{G}BACgI8LK^6*GqNtQ||N;FyL`htyJmWt^1=eLt*Yx?Y$2lDQyN`<@Ltew5z4>tqy1x8Z4`3e#6s5az zgOQ+~lTvx$(_SML zc;NtBaf47%2>x&8>~X|lWCM63K(_e$>FDR`P`^|F?_s5ew{d; zE9z3_%)2*5y+%hu{3&tRo}kuO${*~^WWJ=07u7DdicVJ1RyGs{NX&Zs-zB!Z63gL z56r63)lmxoUk~S^-0y%`3_A%fqMIxW?n=n9*+6mCNl+VlZm=bEa!m#i)wHWgyz7~R zAOG)JUY-omI^cQtdHM0Q-26y7Z2r}}+tphk)@fN&pw#8B=6KP7ep5rwZ_Efar8J@` zBtS18Xp?L))-Lw-(m^t&BAw1O zfo34ai`tl1#h)O42BQxQuP@4}srFoN3}b{qX6(C)^MF_Hl9!b!Sa8;xURQT6IFB4Y zm##R<7JRT}V1xD_bhhof))kNMBA?|hAZfciVxRc|#BEYPLAhRAy_FO`4shHPzVp6i zZ1^s@$Yh*G;cm4g3BMc7@3y_154G(>ffG(JCH2;b97@XSGb^#pnXxgFy{j^uKt4RX z@a7mD`LdlAL!GyDQEo=g*vBA@%;kW9sM7n&frrWNnC*}!W^j%7tupvlxywE+`*XX( zhALmF{uS}qF@m4?7J_)bND$c&wv>M6tkSjtbBwP~s@x!8*27@ES-|!Uov%HC)aSaf z-|7|fbCw}um%3pXtjiBhS=pDo=y@Cf9Y#%_#`?mVKh7MDUwVuWE;J54iKQHKRD~3t zoSa+*z=3dRlvE6fG02d%wmCnY%V<bWJ(6af7)B}4 zZNG4_B}yt&C#O+~b9>K37)>9ze$y3b<^W^@89&A}1wvj-2!eqW^SQ6>t_SZHG1Lll zSnUG?$#BU@NvSH3Hmr=%wuN|j@Fk3;Q;vKr=%7-Z2!Hsr<58~8cBBc2h_bS>d=E3N z#FI7=4%Zb9Chk=Jtc5&Hn$~Hb?EyUIZ*pu6bQdhR%RLElkTZMtR##W;xzQ-e5NgFD zy(l$`G?#XHOKhl@)dlwBg(qQHz{U4N$>mx%ZCDUA3AU`${&U~3{W~H3(2=(Ajrg{= zTo1BLRz$TJoj5xjvKc=+yQ-JE&+ont&GZXo@RSlageP(G~Eu^{s z20Ccl=VZ~FIvwAAnojN3oO=JJ{Q?LuT8?62ViJ0Hg)x$B+fK|cn=iNMw3C7Kzmwxw z@0$Ip4D`F~VkRTujeH>?B~>h)Z?rHm2?1NnkHyCmYtknwSn-I!W!MzgcJ*^G;(ugd zkiT20PSHHndSQ6-gK^r z1*C#*Vng@cSyZ=+%{_5u-p=!hh+x`b{OI?Q4&m9#n23X0L|FN~x9x6;o1oU!3f{Sb z41*0ybq#egdIO4UwZ~Z0{X3mB7UW`LVxlDxa9bD|%j#+WC&Df&f7-y|29%Ifb;mdR@yg>rH_6F@ ztjD;pFqSb2_fAJ@T5Ojb)~AkcE5XT(rRCN;jLK{Pa>1cX zM4Z>R%Z;5q_gfe`$UGZ=bY$G@iWvTSvb=8WL!Vk-bozX=aE!xdkN&!1^y&Z=S!BI4 z#om-z-##eR{v(!rqZfnpCbE^*Sauv4ukKHip&@wwEq37j)>t%=+RgvNp5Evcn zT{Yx+4qbBsLy+xML9W{*pHODkiJegTQdySGul&FQK|K&Zjq0;vRoM+t5K9bKEAElh zu|5RLJ96SdK8~Iysa#4*P=LStdb?^g#EZxeaQ}3mCjwX)!dCYVrA}17c$)M!q>Ieg zVf<)kkh<;*g}e%QT}(_(F*7lR0COMXdMs0?szzyV<|85I8$3$!qz~Po(;-K#4psK5 zDfY|QfrleQGG9|=K^EtLp=sD-Vv5~gMIhy~SYGlIWJJI=8~>x3rQA67p>(V2{wRUP z8yKe@px3MNQtdyvO(^Sr>c1r#SKh9p1vA&d`-YaDEb4TO?|wp0D`EekQj=h_9W)szOc3O4 zr!SH^Xj*4l?C@epu-TkFG#5GS^<#aBl#P6Z)Ve_Ajpbg+D6P~l)AzU8uy)$tkaVHX zUGY^i^#E(9-&!NFd#UzH@Q#f?M% E9|}>GUH||9 literal 0 HcmV?d00001 diff --git a/examples/quickwings/assets/tappybird/sample.png b/examples/quickwings/assets/tappybird/sample.png new file mode 100644 index 0000000000000000000000000000000000000000..efccaf41be84dda2d60704f099885b4532ec89b6 GIT binary patch literal 81791 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ÐIJ8NTZvWVqz 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 Date: Thu, 22 May 2025 22:23:35 +0200 Subject: [PATCH 23/28] update GLFW --- .../index/bitmap.hpp.62887C634633116B.idx | Bin 0 -> 1676 bytes .../index/bitmap.hpp.EEDEB52DF9368726.idx | Bin 0 -> 1676 bytes .../index/bitmap_io.cpp.181EA33891BBC2AF.idx | Bin 0 -> 2906 bytes .../index/bitmap_io.cpp.4AB5E576AFA93983.idx | Bin 0 -> 2906 bytes .../index/bitmap_io.hpp.C3324F345C5DD5D2.idx | Bin 0 -> 1110 bytes .../index/bitmap_io.hpp.E43B2188CF8AB392.idx | Bin 0 -> 1108 bytes .../index/context.c.91BC96CF7BD16B3C.idx | Bin 0 -> 13008 bytes .../index/context.c.ACB36D59D1DFD31C.idx | Bin 0 -> 13008 bytes .../index/context.cpp.4F65C2A62FFB483F.idx | Bin 0 -> 2924 bytes .../index/context.cpp.EECF18BC474ACA88.idx | Bin 0 -> 2924 bytes .../index/context.hpp.0247079C4DA06A0E.idx | Bin 0 -> 1544 bytes .../index/context.hpp.30BB9F8B4501681D.idx | Bin 0 -> 1544 bytes .../index/egl_context.c.225C06C339B7DDA1.idx | Bin 0 -> 18206 bytes .../index/egl_context.c.CD53B506C4A00245.idx | Bin 0 -> 18214 bytes .../index/egl_context.h.04386B6C0A7119A7.idx | Bin 0 -> 8170 bytes .../index/egl_context.h.B2730FCAFD4752C9.idx | Bin 0 -> 8170 bytes .../index/geometry.hpp.5CBEA5776F164981.idx | Bin 0 -> 1836 bytes .../index/geometry.hpp.D38DA0C44333DD06.idx | Bin 0 -> 1836 bytes .../clangd/index/glad.c.6ADEBFBBDDE6583D.idx | Bin 0 -> 528840 bytes .../clangd/index/glad.c.DC115C5ADDB0D90B.idx | Bin 0 -> 528840 bytes .../clangd/index/glad.h.75CCCDA1A3F702AC.idx | Bin 0 -> 1008432 bytes .../clangd/index/glad.h.76E6696D4B8D4E14.idx | Bin 0 -> 1008432 bytes .../clangd/index/glfw3.h.5A7452531BE9304F.idx | Bin 0 -> 52826 bytes .../clangd/index/glfw3.h.AAFA18C8892E0F92.idx | Bin 0 -> 52826 bytes .../index/globals.hpp.24BCAC15858D1B89.idx | Bin 0 -> 404 bytes .../index/globals.hpp.380C15F700EE3EE1.idx | Bin 0 -> 404 bytes .../index/glx_context.c.7EDF51863382D2CB.idx | Bin 0 -> 16858 bytes .../index/glx_context.c.B0ADB84DEBD4B2AA.idx | Bin 0 -> 16850 bytes .../index/glx_context.h.256A85A14326A9DC.idx | Bin 0 -> 7594 bytes .../index/glx_context.h.E85BD630F7223469.idx | Bin 0 -> 7594 bytes .../clangd/index/init.c.55CFCFFC01384B65.idx | Bin 0 -> 8760 bytes .../clangd/index/init.c.A2467C96C1716714.idx | Bin 0 -> 8878 bytes .../clangd/index/input.c.7252BD8769C990CB.idx | Bin 0 -> 35194 bytes .../clangd/index/input.c.DED1B4400041FF44.idx | Bin 0 -> 35194 bytes .../index/internal.h.445CD411983AEDF9.idx | Bin 0 -> 38154 bytes .../index/internal.h.DE6A02CC46470B84.idx | Bin 0 -> 38156 bytes .../index/khrplatform.h.29E603D3A52AEC6A.idx | Bin 0 -> 2172 bytes .../index/khrplatform.h.D6CEFEA22454BFC5.idx | Bin 0 -> 2172 bytes .../linux_joystick.c.0B324179DA9FB60F.idx | Bin 0 -> 7240 bytes .../linux_joystick.c.792A25E4FD082BE3.idx | Bin 0 -> 7238 bytes .../linux_joystick.h.6D80310652F4A3A1.idx | Bin 0 -> 1648 bytes .../linux_joystick.h.F9013A3DE8A76987.idx | Bin 0 -> 1658 bytes .../index/mappings.h.2B5E5627F59980DE.idx | Bin 0 -> 820 bytes .../index/mappings.h.DE572F1D18327736.idx | Bin 0 -> 820 bytes .../index/matrix.hpp.82213AF3AAC74723.idx | Bin 0 -> 4130 bytes .../index/matrix.hpp.B61CADF6F0D53E3B.idx | Bin 0 -> 4084 bytes .../index/matrixbase.hpp.60D06CA21577625A.idx | Bin 0 -> 3932 bytes .../index/matrixbase.hpp.F11E20E9DFADCEFF.idx | Bin 0 -> 4374 bytes .../index/monitor.c.8465A82AF6ED1794.idx | Bin 0 -> 12734 bytes .../index/monitor.c.AEB0C2DC26515679.idx | Bin 0 -> 12734 bytes .../osmesa_context.c.1EE9BEC9D6A3E34A.idx | Bin 0 -> 7978 bytes .../osmesa_context.c.9D0E9B593E3B91C8.idx | Bin 0 -> 7984 bytes .../osmesa_context.h.0C7F09075E273648.idx | Bin 0 -> 2996 bytes .../osmesa_context.h.141748BA6847E054.idx | Bin 0 -> 2996 bytes .../index/pong.cpp.0666B09B2C5A6C2D.idx | Bin 0 -> 7564 bytes .../index/pong.cpp.5E4CD60C67D0940C.idx | Bin 0 -> 7564 bytes .../index/posix_thread.c.3F3583255D9A0824.idx | Bin 0 -> 2120 bytes .../index/posix_thread.c.97BD9159EEF76B84.idx | Bin 0 -> 2120 bytes .../index/posix_thread.h.0D3851D1D9279E82.idx | Bin 0 -> 894 bytes .../index/posix_thread.h.2D23296B7CFBFCA2.idx | Bin 0 -> 894 bytes .../index/posix_time.c.4CBE14BF15C8C278.idx | Bin 0 -> 1472 bytes .../index/posix_time.c.EEC0949F9BB68444.idx | Bin 0 -> 1472 bytes .../index/posix_time.h.690873C37A0312EE.idx | Bin 0 -> 672 bytes .../index/posix_time.h.B922C8D5550AB845.idx | Bin 0 -> 668 bytes .../index/quickwings.cpp.85EA7B40D80DA419.idx | Bin 0 -> 14758 bytes .../index/quickwings.cpp.C395FD54968A1134.idx | Bin 0 -> 14758 bytes .../index/renderer.cpp.740BAA1FB38348C8.idx | Bin 0 -> 7980 bytes .../index/renderer.cpp.C9C31387983FB261.idx | Bin 0 -> 7980 bytes .../index/renderer.hpp.8430C86236A009AE.idx | Bin 0 -> 856 bytes .../index/renderer.hpp.926D47CDCF3C1D01.idx | Bin 0 -> 894 bytes .../index/rgba.hpp.BA781889E6CDBAD7.idx | Bin 0 -> 1844 bytes .../index/rgba.hpp.FC678113A439A522.idx | Bin 0 -> 1844 bytes .../index/shader.cpp.43E3518708249EAE.idx | Bin 0 -> 5988 bytes .../index/shader.cpp.7A00B3A7CCD89C12.idx | Bin 0 -> 5988 bytes .../index/shader.hpp.DF5CE306CA970394.idx | Bin 0 -> 3134 bytes .../index/shader.hpp.E7CD36D8F71952ED.idx | Bin 0 -> 3134 bytes .../shader_sprite.hpp.493F804E562576C3.idx | Bin 0 -> 328 bytes .../shader_sprite.hpp.8B17A178D93F0BE6.idx | Bin 0 -> 328 bytes .../index/simple.cpp.96D892360BBE0299.idx | Bin 0 -> 2236 bytes .../index/simple.cpp.C6B37DEAE25C79D2.idx | Bin 0 -> 2236 bytes .../index/sprite.hpp.A9098C65589F3A19.idx | Bin 0 -> 1536 bytes .../index/sprite.hpp.CC3066F6ABEF70A9.idx | Bin 0 -> 1536 bytes .../index/stb_image.h.66C3FB4B07894FDB.idx | Bin 0 -> 113950 bytes .../index/stb_image.h.A40CF375DB872323.idx | Bin 0 -> 113950 bytes .../index/vector.hpp.3A192E43B974E9B2.idx | Bin 0 -> 2008 bytes .../index/vector.hpp.E320F2C0D8CBC593.idx | Bin 0 -> 1896 bytes .../index/vulkan.c.F1AE9249ACD23954.idx | Bin 0 -> 6430 bytes .../index/vulkan.c.F75EB52C23E5F7F6.idx | Bin 0 -> 6432 bytes .../index/window.c.ACCD05B2BA43D003.idx | Bin 0 -> 38376 bytes .../index/window.c.CE66238555157A64.idx | Bin 0 -> 38376 bytes .../index/window.cpp.75FB94300CFB46BA.idx | Bin 0 -> 8644 bytes .../index/window.cpp.C49665C3E96358E9.idx | Bin 0 -> 8644 bytes .../index/window.hpp.B8A7D1770B434EEC.idx | Bin 0 -> 2666 bytes .../index/window.hpp.F8FA2942270CA4B4.idx | Bin 0 -> 2630 bytes .../index/x11_init.c.5062A2FC3E2A7E6D.idx | Bin 0 -> 40104 bytes .../index/x11_init.c.F00A5A0A2091891E.idx | Bin 0 -> 40006 bytes .../index/x11_monitor.c.271D126498E8CFAE.idx | Bin 0 -> 15882 bytes .../index/x11_monitor.c.EA1D4A157A0E438E.idx | Bin 0 -> 15876 bytes .../index/x11_platform.h.1DDD554B1F22A6A0.idx | Bin 0 -> 23928 bytes .../index/x11_platform.h.56FB194C0C211696.idx | Bin 0 -> 23898 bytes .../index/x11_window.c.241536F32C8627F0.idx | Bin 0 -> 65048 bytes .../index/x11_window.c.8BEA32FE82C65B89.idx | Bin 0 -> 65036 bytes .../index/xkb_unicode.c.31E6598E6573D51F.idx | Bin 0 -> 900 bytes .../index/xkb_unicode.c.757568D7EEC6A2FA.idx | Bin 0 -> 900 bytes .../index/xkb_unicode.h.53CF8CB5C8862029.idx | Bin 0 -> 322 bytes .../index/xkb_unicode.h.93B1782F55B08538.idx | Bin 0 -> 322 bytes src/lib/CMakeLists.txt | 4 +- .../CMake/modules/FindWaylandProtocols.cmake | 26 - .../CMake/modules/FindXKBCommon.cmake | 34 - src/lib/src/vendor/glfw-3.3.8/CMakeLists.txt | 385 -- src/lib/src/vendor/glfw-3.3.8/README.md | 211 - src/lib/src/vendor/glfw-3.3.8/deps/glad/gl.h | 3840 ----------- .../vendor/glfw-3.3.8/deps/glad/khrplatform.h | 282 - .../vendor/glfw-3.3.8/deps/glad/vk_platform.h | 84 - src/lib/src/vendor/glfw-3.3.8/deps/glad_gl.c | 1791 ----- .../src/vendor/glfw-3.3.8/deps/glad_vulkan.c | 733 -- .../vendor/glfw-3.3.8/deps/vs2008/stdint.h | 247 - .../src/vendor/glfw-3.3.8/docs/CMakeLists.txt | 34 - .../src/vendor/glfw-3.3.8/docs/Doxyfile.in | 1828 ----- src/lib/src/vendor/glfw-3.3.8/docs/extra.css | 1 - .../src/vendor/glfw-3.3.8/docs/extra.css.map | 1 - .../src/vendor/glfw-3.3.8/docs/html/bdwn.png | Bin 147 -> 0 bytes .../glfw-3.3.8/docs/html/build_guide.html | 192 - .../glfw-3.3.8/docs/html/compat_guide.html | 145 - .../glfw-3.3.8/docs/html/compile_guide.html | 216 - .../src/vendor/glfw-3.3.8/docs/html/doc.png | Bin 746 -> 0 bytes .../src/vendor/glfw-3.3.8/docs/html/extra.css | 1 - .../glfw-3.3.8/docs/html/folderclosed.png | Bin 616 -> 0 bytes .../glfw-3.3.8/docs/html/folderopen.png | Bin 597 -> 0 bytes .../vendor/glfw-3.3.8/docs/html/glfw3_8h.html | 1619 ----- .../glfw-3.3.8/docs/html/glfw3native_8h.html | 160 - .../glfw-3.3.8/docs/html/group__errors.html | 297 - .../glfw-3.3.8/docs/html/group__init.html | 545 -- .../glfw-3.3.8/docs/html/group__shapes.html | 191 - .../glfw-3.3.8/docs/html/internal_8dox.html | 74 - .../glfw-3.3.8/docs/html/internals_guide.html | 125 - .../glfw-3.3.8/docs/html/intro_guide.html | 329 - .../glfw-3.3.8/docs/html/monitor_8dox.html | 74 - .../src/vendor/glfw-3.3.8/docs/html/news.html | 614 -- .../glfw-3.3.8/docs/html/search/all_0.html | 37 - .../glfw-3.3.8/docs/html/search/all_0.js | 4 - .../glfw-3.3.8/docs/html/search/all_1.html | 37 - .../glfw-3.3.8/docs/html/search/all_1.js | 8 - .../glfw-3.3.8/docs/html/search/all_10.html | 37 - .../glfw-3.3.8/docs/html/search/all_10.js | 6 - .../glfw-3.3.8/docs/html/search/all_11.html | 37 - .../glfw-3.3.8/docs/html/search/all_11.js | 7 - .../glfw-3.3.8/docs/html/search/all_2.html | 37 - .../glfw-3.3.8/docs/html/search/all_2.js | 9 - .../glfw-3.3.8/docs/html/search/all_3.html | 37 - .../glfw-3.3.8/docs/html/search/all_4.html | 37 - .../glfw-3.3.8/docs/html/search/all_4.js | 4 - .../glfw-3.3.8/docs/html/search/all_5.html | 37 - .../glfw-3.3.8/docs/html/search/all_5.js | 477 -- .../glfw-3.3.8/docs/html/search/all_6.html | 37 - .../glfw-3.3.8/docs/html/search/all_6.js | 4 - .../glfw-3.3.8/docs/html/search/all_7.html | 37 - .../glfw-3.3.8/docs/html/search/all_7.js | 11 - .../glfw-3.3.8/docs/html/search/all_8.html | 37 - .../glfw-3.3.8/docs/html/search/all_9.html | 37 - .../glfw-3.3.8/docs/html/search/all_9.js | 4 - .../glfw-3.3.8/docs/html/search/all_a.html | 37 - .../glfw-3.3.8/docs/html/search/all_a.js | 11 - .../glfw-3.3.8/docs/html/search/all_b.html | 37 - .../glfw-3.3.8/docs/html/search/all_b.js | 6 - .../glfw-3.3.8/docs/html/search/all_c.html | 37 - .../glfw-3.3.8/docs/html/search/all_c.js | 4 - .../glfw-3.3.8/docs/html/search/all_d.html | 37 - .../glfw-3.3.8/docs/html/search/all_d.js | 4 - .../glfw-3.3.8/docs/html/search/all_e.html | 37 - .../glfw-3.3.8/docs/html/search/all_e.js | 7 - .../glfw-3.3.8/docs/html/search/all_f.html | 37 - .../glfw-3.3.8/docs/html/search/all_f.js | 6 - .../docs/html/search/classes_0.html | 37 - .../glfw-3.3.8/docs/html/search/classes_0.js | 7 - .../docs/html/search/defines_0.html | 37 - .../glfw-3.3.8/docs/html/search/defines_0.js | 32 - .../glfw-3.3.8/docs/html/search/files_0.html | 37 - .../glfw-3.3.8/docs/html/search/files_0.js | 4 - .../glfw-3.3.8/docs/html/search/files_1.html | 37 - .../glfw-3.3.8/docs/html/search/files_1.js | 6 - .../glfw-3.3.8/docs/html/search/files_2.html | 37 - .../glfw-3.3.8/docs/html/search/files_3.html | 37 - .../glfw-3.3.8/docs/html/search/files_3.js | 6 - .../glfw-3.3.8/docs/html/search/files_4.html | 37 - .../glfw-3.3.8/docs/html/search/files_4.js | 6 - .../glfw-3.3.8/docs/html/search/files_5.html | 37 - .../glfw-3.3.8/docs/html/search/files_5.js | 4 - .../glfw-3.3.8/docs/html/search/files_6.html | 37 - .../glfw-3.3.8/docs/html/search/files_6.js | 4 - .../glfw-3.3.8/docs/html/search/files_7.html | 37 - .../glfw-3.3.8/docs/html/search/files_7.js | 4 - .../glfw-3.3.8/docs/html/search/files_8.html | 37 - .../glfw-3.3.8/docs/html/search/files_8.js | 4 - .../docs/html/search/functions_0.html | 37 - .../glfw-3.3.8/docs/html/search/groups_0.html | 37 - .../glfw-3.3.8/docs/html/search/groups_0.js | 4 - .../glfw-3.3.8/docs/html/search/groups_1.html | 37 - .../glfw-3.3.8/docs/html/search/groups_1.js | 4 - .../glfw-3.3.8/docs/html/search/groups_2.html | 37 - .../glfw-3.3.8/docs/html/search/groups_3.html | 37 - .../glfw-3.3.8/docs/html/search/groups_3.js | 5 - .../glfw-3.3.8/docs/html/search/groups_4.html | 37 - .../glfw-3.3.8/docs/html/search/groups_4.js | 5 - .../glfw-3.3.8/docs/html/search/groups_5.html | 37 - .../glfw-3.3.8/docs/html/search/groups_5.js | 4 - .../glfw-3.3.8/docs/html/search/groups_6.html | 37 - .../glfw-3.3.8/docs/html/search/groups_7.html | 37 - .../glfw-3.3.8/docs/html/search/groups_8.html | 37 - .../glfw-3.3.8/docs/html/search/groups_8.js | 4 - .../glfw-3.3.8/docs/html/search/groups_9.html | 37 - .../glfw-3.3.8/docs/html/search/groups_9.js | 4 - .../glfw-3.3.8/docs/html/search/groups_a.html | 37 - .../glfw-3.3.8/docs/html/search/mag_sel.svg | 74 - .../docs/html/search/nomatches.html | 13 - .../glfw-3.3.8/docs/html/search/pages_0.html | 37 - .../glfw-3.3.8/docs/html/search/pages_1.html | 37 - .../glfw-3.3.8/docs/html/search/pages_1.js | 5 - .../glfw-3.3.8/docs/html/search/pages_2.html | 37 - .../glfw-3.3.8/docs/html/search/pages_2.js | 4 - .../glfw-3.3.8/docs/html/search/pages_3.html | 37 - .../glfw-3.3.8/docs/html/search/pages_3.js | 4 - .../glfw-3.3.8/docs/html/search/pages_4.html | 37 - .../glfw-3.3.8/docs/html/search/pages_5.html | 37 - .../glfw-3.3.8/docs/html/search/pages_6.html | 37 - .../glfw-3.3.8/docs/html/search/pages_6.js | 4 - .../glfw-3.3.8/docs/html/search/pages_7.html | 37 - .../glfw-3.3.8/docs/html/search/pages_7.js | 4 - .../glfw-3.3.8/docs/html/search/pages_8.html | 37 - .../glfw-3.3.8/docs/html/search/pages_8.js | 4 - .../glfw-3.3.8/docs/html/search/pages_9.html | 37 - .../glfw-3.3.8/docs/html/search/pages_9.js | 4 - .../glfw-3.3.8/docs/html/search/pages_a.html | 37 - .../glfw-3.3.8/docs/html/search/search_l.png | Bin 567 -> 0 bytes .../glfw-3.3.8/docs/html/search/search_m.png | Bin 158 -> 0 bytes .../glfw-3.3.8/docs/html/search/search_r.png | Bin 553 -> 0 bytes .../docs/html/search/typedefs_0.html | 37 - .../glfw-3.3.8/docs/html/search/typedefs_0.js | 32 - .../docs/html/search/variables_0.html | 37 - .../docs/html/search/variables_0.js | 4 - .../docs/html/search/variables_1.html | 37 - .../docs/html/search/variables_1.js | 6 - .../docs/html/search/variables_2.html | 37 - .../docs/html/search/variables_2.js | 5 - .../docs/html/search/variables_3.html | 37 - .../docs/html/search/variables_3.js | 4 - .../docs/html/search/variables_4.html | 37 - .../docs/html/search/variables_4.js | 4 - .../docs/html/search/variables_5.html | 37 - .../docs/html/search/variables_5.js | 6 - .../docs/html/search/variables_6.html | 37 - .../docs/html/search/variables_6.js | 4 - .../docs/html/search/variables_7.html | 37 - .../docs/html/search/variables_7.js | 4 - .../src/vendor/glfw-3.3.8/docs/html/tabs.css | 1 - .../glfw-3.3.8/docs/html/window_8dox.html | 74 - src/lib/src/vendor/glfw-3.3.8/docs/news.dox | 876 --- .../src/vendor/glfw-3.3.8/src/CMakeLists.txt | 195 - .../src/vendor/glfw-3.3.8/src/egl_context.h | 217 - .../glfw-3.3.8/src/glfw3Config.cmake.in | 1 - .../vendor/glfw-3.3.8/src/glfw_config.h.in | 58 - .../src/vendor/glfw-3.3.8/src/glx_context.h | 179 - .../src/vendor/glfw-3.3.8/src/nsgl_context.h | 66 - .../src/vendor/glfw-3.3.8/src/null_platform.h | 62 - .../src/vendor/glfw-3.3.8/src/null_window.c | 335 - .../vendor/glfw-3.3.8/src/osmesa_context.h | 92 - .../src/vendor/glfw-3.3.8/src/wgl_context.h | 158 - src/lib/src/vendor/glfw-3.3.8/src/wl_init.c | 595 -- .../src/vendor/glfw-3.3.8/src/wl_platform.h | 373 - .../src/vendor/glfw-3.3.8/src/x11_platform.h | 450 -- src/lib/src/vendor/glfw-3.3.8/tests/opacity.c | 108 - src/lib/src/vendor/glfw-3.3.8/tests/windows.c | 174 - .../CMake/GenerateMappings.cmake | 12 +- .../CMake/Info.plist.in} | 0 .../CMake}/cmake_uninstall.cmake.in | 6 +- .../src => glfw-3.4/CMake}/glfw3.pc.in | 6 +- .../glfw-3.4/CMake/glfw3Config.cmake.in | 3 + .../CMake/i686-w64-mingw32-clang.cmake | 0 .../CMake/i686-w64-mingw32.cmake | 0 .../CMake/modules/FindEpollShim.cmake | 0 .../CMake/modules/FindOSMesa.cmake | 0 .../CMake/x86_64-w64-mingw32-clang.cmake | 0 .../CMake/x86_64-w64-mingw32.cmake | 0 src/lib/src/vendor/glfw-3.4/CMakeLists.txt | 165 + .../{glfw-3.3.8 => glfw-3.4}/CONTRIBUTORS.md | 51 +- .../{glfw-3.3.8 => glfw-3.4}/LICENSE.md | 0 src/lib/src/vendor/glfw-3.4/README.md | 458 ++ .../{glfw-3.3.8 => glfw-3.4}/deps/getopt.c | 0 .../{glfw-3.3.8 => glfw-3.4}/deps/getopt.h | 0 src/lib/src/vendor/glfw-3.4/deps/glad/gl.h | 5996 +++++++++++++++++ src/lib/src/vendor/glfw-3.4/deps/glad/gles2.h | 1805 +++++ .../deps/glad/vulkan.h | 832 ++- .../{glfw-3.3.8 => glfw-3.4}/deps/linmath.h | 282 +- .../deps/mingw/_mingw_dxhelper.h | 0 .../deps/mingw/dinput.h | 0 .../deps/mingw/xinput.h | 0 .../{glfw-3.3.8 => glfw-3.4}/deps/nuklear.h | 623 +- .../deps/nuklear_glfw_gl2.h | 8 +- .../deps/stb_image_write.h | 0 .../deps/tinycthread.c | 0 .../deps/tinycthread.h | 0 .../deps/wayland/fractional-scale-v1.xml | 102 + .../deps/wayland/idle-inhibit-unstable-v1.xml | 83 + .../pointer-constraints-unstable-v1.xml | 339 + .../wayland/relative-pointer-unstable-v1.xml | 136 + .../glfw-3.4/deps/wayland/viewporter.xml | 180 + .../vendor/glfw-3.4/deps/wayland/wayland.xml | 3151 +++++++++ .../deps/wayland/xdg-activation-v1.xml | 200 + .../wayland/xdg-decoration-unstable-v1.xml | 156 + .../glfw-3.4/deps/wayland/xdg-shell.xml | 1370 ++++ .../src/vendor/glfw-3.4/docs/CMakeLists.txt | 57 + .../docs/CONTRIBUTING.md | 17 +- src/lib/src/vendor/glfw-3.4/docs/Doxyfile.in | 2737 ++++++++ .../docs/DoxygenLayout.xml | 2 +- .../{glfw-3.3.8 => glfw-3.4}/docs/SUPPORT.md | 3 +- .../docs/build.dox => glfw-3.4/docs/build.md} | 251 +- .../compat.dox => glfw-3.4/docs/compat.md} | 183 +- .../compile.dox => glfw-3.4/docs/compile.md} | 282 +- .../context.dox => glfw-3.4/docs/context.md} | 102 +- src/lib/src/vendor/glfw-3.4/docs/extra.css | 2 + .../src/vendor/glfw-3.4/docs/extra.css.map | 7 + .../{glfw-3.3.8 => glfw-3.4}/docs/extra.scss | 31 +- .../{glfw-3.3.8 => glfw-3.4}/docs/footer.html | 0 .../{glfw-3.3.8 => glfw-3.4}/docs/header.html | 0 .../docs/html/bc_s.png | Bin .../src/vendor/glfw-3.4/docs/html/bc_sd.png | Bin 0 -> 635 bytes .../docs/html/build_8md.html} | 25 +- .../glfw-3.4/docs/html/build_guide.html | 217 + .../docs/html/closed.png | Bin .../docs/html/compat_8md.html} | 25 +- .../glfw-3.4/docs/html/compat_guide.html | 156 + .../docs/html/compile_8md.html} | 25 +- .../glfw-3.4/docs/html/compile_guide.html | 219 + .../docs/html/context_8md.html} | 25 +- .../docs/html/context_guide.html | 115 +- .../docs/html/deprecated.html | 23 +- ...dir_13577e2d8b9423099662de029791bd7d.html} | 31 +- ...dir_7f92719a7fe62e5b064f87d7a3c220b1.html} | 27 +- ...dir_a788ef6c2b1e5b367804e0b6ccfd6f11.html} | 23 +- ...dir_b11153cd0f4fd04a7564cc166f482635.html} | 25 +- src/lib/src/vendor/glfw-3.4/docs/html/doc.svg | 12 + .../src/vendor/glfw-3.4/docs/html/docd.svg | 12 + .../docs/html/doxygen.css | 508 +- .../docs/html/doxygen.svg | 4 +- .../docs/html/dynsections.js | 71 + .../src/vendor/glfw-3.4/docs/html/extra.css | 2 + .../docs/html/files.html | 31 +- .../glfw-3.4/docs/html/folderclosed.svg | 11 + .../glfw-3.4/docs/html/folderclosedd.svg | 11 + .../vendor/glfw-3.4/docs/html/folderopen.svg | 17 + .../vendor/glfw-3.4/docs/html/folderopend.svg | 12 + .../vendor/glfw-3.4/docs/html/glfw3_8h.html | 1910 ++++++ .../docs/html/glfw3_8h_source.html | 1533 +++-- .../glfw-3.4/docs/html/glfw3native_8h.html | 170 + .../docs/html/glfw3native_8h_source.html | 289 +- .../docs/html/group__buttons.html | 71 +- .../docs/html/group__context.html | 97 +- .../glfw-3.4/docs/html/group__errors.html | 384 ++ .../docs/html/group__gamepad__axes.html | 51 +- .../docs/html/group__gamepad__buttons.html | 103 +- .../docs/html/group__hat__state.html | 59 +- .../glfw-3.4/docs/html/group__init.html | 1015 +++ .../docs/html/group__input.html | 661 +- .../docs/html/group__joysticks.html | 91 +- .../docs/html/group__keys.html | 533 +- .../docs/html/group__mods.html | 71 +- .../docs/html/group__monitor.html | 224 +- .../docs/html/group__native.html | 252 +- .../glfw-3.4/docs/html/group__shapes.html | 337 + .../docs/html/group__vulkan.html | 95 +- .../docs/html/group__window.html | 1223 ++-- .../docs/html/index.html | 51 +- .../docs/html/input_8md.html} | 25 +- .../docs/html/input_guide.html | 400 +- .../docs/html/internal_8md.html} | 25 +- .../glfw-3.4/docs/html/internals_guide.html | 135 + .../vendor/glfw-3.4/docs/html/intro_8md.html | 81 + .../glfw-3.4/docs/html/intro_guide.html | 429 ++ .../docs/html/jquery.js | 7 +- .../docs/html/main_8md.html} | 25 +- .../docs/html/menu.js | 33 +- .../docs/html/menudata.js | 2 +- .../src/vendor/glfw-3.4/docs/html/minus.svg | 8 + .../src/vendor/glfw-3.4/docs/html/minusd.svg | 8 + .../docs/html/monitor_8md.html} | 25 +- .../docs/html/monitor_guide.html | 126 +- .../docs/html/moving_8md.html} | 25 +- .../docs/html/moving_guide.html | 205 +- .../docs/html/nav_f.png | Bin .../src/vendor/glfw-3.4/docs/html/nav_fd.png | Bin 0 -> 169 bytes .../docs/html/nav_g.png | Bin .../docs/html/nav_h.png | Bin .../src/vendor/glfw-3.4/docs/html/nav_hd.png | Bin 0 -> 114 bytes .../src/vendor/glfw-3.4/docs/html/news.html | 336 + .../vendor/glfw-3.4/docs/html/news_8md.html | 81 + .../docs/html/open.png | Bin .../docs/html/pages.html | 37 +- .../src/vendor/glfw-3.4/docs/html/plus.svg | 9 + .../src/vendor/glfw-3.4/docs/html/plusd.svg | 9 + .../vendor/glfw-3.4/docs/html/quick_8md.html | 81 + .../docs/html/quick_guide.html | 215 +- .../vendor/glfw-3.4/docs/html/search/all_0.js | 4 + .../vendor/glfw-3.4/docs/html/search/all_1.js | 4 + .../glfw-3.4/docs/html/search/all_10.js | 13 + .../glfw-3.4/docs/html/search/all_11.js | 11 + .../glfw-3.4/docs/html/search/all_12.js | 26 + .../glfw-3.4/docs/html/search/all_13.js | 51 + .../glfw-3.4/docs/html/search/all_14.js | 22 + .../glfw-3.4/docs/html/search/all_15.js | 35 + .../glfw-3.4/docs/html/search/all_16.js | 29 + .../glfw-3.4/docs/html/search/all_17.js | 8 + .../glfw-3.4/docs/html/search/all_18.js | 44 + .../glfw-3.4/docs/html/search/all_19.js | 60 + .../glfw-3.4/docs/html/search/all_1a.js | 39 + .../glfw-3.4/docs/html/search/all_1b.js | 8 + .../glfw-3.4/docs/html/search/all_1c.js | 32 + .../glfw-3.4/docs/html/search/all_1d.js | 84 + .../glfw-3.4/docs/html/search/all_1e.js | 13 + .../glfw-3.4/docs/html/search/all_1f.js | 4 + .../vendor/glfw-3.4/docs/html/search/all_2.js | 5 + .../vendor/glfw-3.4/docs/html/search/all_3.js | 4 + .../vendor/glfw-3.4/docs/html/search/all_4.js | 4 + .../vendor/glfw-3.4/docs/html/search/all_5.js | 4 + .../vendor/glfw-3.4/docs/html/search/all_6.js | 4 + .../vendor/glfw-3.4/docs/html/search/all_7.js | 58 + .../vendor/glfw-3.4/docs/html/search/all_8.js | 21 + .../vendor/glfw-3.4/docs/html/search/all_9.js | 82 + .../vendor/glfw-3.4/docs/html/search/all_a.js | 20 + .../vendor/glfw-3.4/docs/html/search/all_b.js | 26 + .../vendor/glfw-3.4/docs/html/search/all_c.js | 35 + .../vendor/glfw-3.4/docs/html/search/all_d.js | 555 ++ .../vendor/glfw-3.4/docs/html/search/all_e.js | 23 + .../vendor/glfw-3.4/docs/html/search/all_f.js | 40 + .../glfw-3.4/docs/html/search/classes_0.js | 8 + .../docs/html/search/close.svg | 19 +- .../glfw-3.4/docs/html/search/defines_0.js | 43 + .../glfw-3.4/docs/html/search/files_0.js | 4 + .../glfw-3.4/docs/html/search/files_1.js | 6 + .../docs/html/search/files_2.js | 0 .../glfw-3.4/docs/html/search/files_3.js | 6 + .../glfw-3.4/docs/html/search/files_4.js | 6 + .../glfw-3.4/docs/html/search/files_5.js | 4 + .../glfw-3.4/docs/html/search/files_6.js | 4 + .../glfw-3.4/docs/html/search/files_7.js | 4 + .../glfw-3.4/docs/html/search/files_8.js | 4 + .../docs/html/search/functions_0.js | 270 +- .../glfw-3.4/docs/html/search/groups_0.js | 6 + .../glfw-3.4/docs/html/search/groups_1.js | 4 + .../docs/html/search/groups_10.js} | 0 .../glfw-3.4/docs/html/search/groups_2.js | 6 + .../glfw-3.4/docs/html/search/groups_3.js | 5 + .../glfw-3.4/docs/html/search/groups_4.js | 4 + .../docs/html/search/groups_5.js} | 0 .../glfw-3.4/docs/html/search/groups_6.js | 4 + .../glfw-3.4/docs/html/search/groups_7.js | 5 + .../docs/html/search/groups_8.js} | 0 .../glfw-3.4/docs/html/search/groups_9.js | 6 + .../docs/html/search/groups_a.js} | 0 .../docs/html/search/groups_b.js} | 0 .../glfw-3.4/docs/html/search/groups_c.js | 4 + .../glfw-3.4/docs/html/search/groups_d.js | 7 + .../glfw-3.4/docs/html/search/groups_e.js | 4 + .../glfw-3.4/docs/html/search/groups_f.js | 5 + .../vendor/glfw-3.4/docs/html/search/mag.svg | 24 + .../glfw-3.4/docs/html/search/mag_d.svg | 24 + .../glfw-3.4/docs/html/search/mag_sel.svg | 31 + .../glfw-3.4/docs/html/search/mag_seld.svg | 31 + .../glfw-3.4/docs/html/search/pages_0.js | 4 + .../glfw-3.4/docs/html/search/pages_1.js | 5 + .../glfw-3.4/docs/html/search/pages_10.js | 5 + .../docs/html/search/pages_11.js} | 0 .../glfw-3.4/docs/html/search/pages_2.js | 4 + .../glfw-3.4/docs/html/search/pages_3.js | 5 + .../docs/html/search/pages_4.js} | 0 .../glfw-3.4/docs/html/search/pages_5.js | 6 + .../docs/html/search/pages_6.js} | 0 .../glfw-3.4/docs/html/search/pages_7.js | 5 + .../glfw-3.4/docs/html/search/pages_8.js | 7 + .../docs/html/search/pages_9.js} | 3 +- .../glfw-3.4/docs/html/search/pages_a.js | 4 + .../docs/html/search/pages_b.js} | 0 .../glfw-3.4/docs/html/search/pages_c.js | 4 + .../glfw-3.4/docs/html/search/pages_d.js | 4 + .../glfw-3.4/docs/html/search/pages_e.js | 6 + .../glfw-3.4/docs/html/search/pages_f.js | 6 + .../docs/html/search/search.css | 92 +- .../docs/html/search/search.js | 146 +- .../docs/html/search/searchdata.js | 8 +- .../glfw-3.4/docs/html/search/typedefs_0.js | 36 + .../glfw-3.4/docs/html/search/variables_0.js | 5 + .../glfw-3.4/docs/html/search/variables_1.js | 6 + .../glfw-3.4/docs/html/search/variables_2.js | 4 + .../glfw-3.4/docs/html/search/variables_3.js | 5 + .../glfw-3.4/docs/html/search/variables_4.js | 4 + .../glfw-3.4/docs/html/search/variables_5.js | 4 + .../glfw-3.4/docs/html/search/variables_6.js | 7 + .../glfw-3.4/docs/html/search/variables_7.js | 4 + .../glfw-3.4/docs/html/search/variables_8.js | 4 + .../glfw-3.4/docs/html/search/variables_9.js | 4 + .../docs/html/spaces.svg | 0 .../docs/html/splitbar.png | Bin .../vendor/glfw-3.4/docs/html/splitbard.png | Bin 0 -> 282 bytes .../docs/html/struct_g_l_f_wallocator.html | 168 + .../html/struct_g_l_f_wgamepadstate.html} | 39 +- .../docs/html/struct_g_l_f_wgammaramp.html} | 51 +- .../docs/html/struct_g_l_f_wimage.html} | 45 +- .../docs/html/struct_g_l_f_wvidmode.html} | 63 +- .../docs/html/sync_off.png | Bin .../docs/html/sync_on.png | Bin .../docs/html/tab_a.png | Bin .../src/vendor/glfw-3.4/docs/html/tab_ad.png | Bin 0 -> 135 bytes .../docs/html/tab_b.png | Bin .../src/vendor/glfw-3.4/docs/html/tab_bd.png | Bin 0 -> 173 bytes .../docs/html/tab_h.png | Bin .../src/vendor/glfw-3.4/docs/html/tab_hd.png | Bin 0 -> 180 bytes .../docs/html/tab_s.png | Bin .../src/vendor/glfw-3.4/docs/html/tab_sd.png | Bin 0 -> 188 bytes .../src/vendor/glfw-3.4/docs/html/tabs.css | 1 + .../docs/html/topics.html} | 41 +- .../docs/html/vulkan_8md.html} | 25 +- .../docs/html/vulkan_guide.html | 115 +- .../docs/html/window_8md.html} | 25 +- .../docs/html/window_guide.html | 534 +- .../docs/input.dox => glfw-3.4/docs/input.md} | 355 +- .../docs/internal.md} | 43 +- .../docs/intro.dox => glfw-3.4/docs/intro.md} | 313 +- .../docs/main.dox => glfw-3.4/docs/main.md} | 12 +- .../monitor.dox => glfw-3.4/docs/monitor.md} | 103 +- .../moving.dox => glfw-3.4/docs/moving.md} | 296 +- src/lib/src/vendor/glfw-3.4/docs/news.md | 402 ++ .../docs/quick.dox => glfw-3.4/docs/quick.md} | 146 +- .../{glfw-3.3.8 => glfw-3.4}/docs/spaces.svg | 0 .../vulkan.dox => glfw-3.4/docs/vulkan.md} | 110 +- .../window.dox => glfw-3.4/docs/window.md} | 552 +- .../examples/CMakeLists.txt | 36 +- .../{glfw-3.3.8 => glfw-3.4}/examples/boing.c | 1 + .../{glfw-3.3.8 => glfw-3.4}/examples/gears.c | 1 + .../examples/glfw.icns | Bin .../examples/glfw.ico | Bin .../{glfw-3.3.8 => glfw-3.4}/examples/glfw.rc | 0 .../examples/heightmap.c | 1 + .../examples/offscreen.c | 14 +- .../examples/particles.c | 1 + .../examples/sharing.c | 2 +- .../examples/splitview.c | 1 + .../examples/triangle-opengl.c} | 75 +- .../glfw-3.4/examples/triangle-opengles.c | 170 + .../{glfw-3.3.8 => glfw-3.4}/examples/wave.c | 1 + .../src/vendor/glfw-3.4/examples/windows.c | 106 + .../include/GLFW/glfw3.h | 931 ++- .../include/GLFW/glfw3native.h | 111 +- .../src/vendor/glfw-3.4/src/CMakeLists.txt | 368 + .../{glfw-3.3.8 => glfw-3.4}/src/cocoa_init.m | 162 +- .../src/cocoa_joystick.h | 18 +- .../src/cocoa_joystick.m | 89 +- .../src/cocoa_monitor.m | 76 +- .../src/cocoa_platform.h | 148 +- .../{glfw-3.3.8 => glfw-3.4}/src/cocoa_time.c | 19 +- src/lib/src/vendor/glfw-3.4/src/cocoa_time.h | 35 + .../src/cocoa_window.m | 448 +- .../{glfw-3.3.8 => glfw-3.4}/src/context.c | 33 +- .../src/egl_context.c | 294 +- src/lib/src/vendor/glfw-3.4/src/glfw.rc.in | 30 + .../src/glx_context.c | 132 +- .../{glfw-3.3.8 => glfw-3.4}/src/init.c | 188 +- .../{glfw-3.3.8 => glfw-3.4}/src/input.c | 391 +- .../{glfw-3.3.8 => glfw-3.4}/src/internal.h | 587 +- .../src/linux_joystick.c | 177 +- .../src/linux_joystick.h | 15 +- .../{glfw-3.3.8 => glfw-3.4}/src/mappings.h | 14 +- .../src/mappings.h.in | 14 +- .../{glfw-3.3.8 => glfw-3.4}/src/monitor.c | 68 +- .../src/nsgl_context.m | 84 +- src/lib/src/vendor/glfw-3.4/src/null_init.c | 264 + .../src/null_joystick.c | 22 +- .../src/null_joystick.h | 11 +- .../src/vendor/glfw-3.4/src/null_monitor.c | 160 + .../src/vendor/glfw-3.4/src/null_platform.h | 271 + src/lib/src/vendor/glfw-3.4/src/null_window.c | 719 ++ .../src/osmesa_context.c | 57 +- src/lib/src/vendor/glfw-3.4/src/platform.c | 212 + src/lib/src/vendor/glfw-3.4/src/platform.h | 212 + .../src/posix_module.c} | 25 +- src/lib/src/vendor/glfw-3.4/src/posix_poll.c | 83 + src/lib/src/vendor/glfw-3.4/src/posix_poll.h | 30 + .../src/posix_thread.c | 8 +- .../src/posix_thread.h | 6 +- .../{glfw-3.3.8 => glfw-3.4}/src/posix_time.c | 64 +- .../{glfw-3.3.8 => glfw-3.4}/src/posix_time.h | 10 +- .../{glfw-3.3.8 => glfw-3.4}/src/vulkan.c | 100 +- .../src/wgl_context.c | 272 +- .../{glfw-3.3.8 => glfw-3.4}/src/win32_init.c | 267 +- .../src/win32_joystick.c | 108 +- .../src/win32_joystick.h | 12 +- .../src/win32_module.c} | 46 +- .../src/win32_monitor.c | 75 +- .../src/win32_platform.h | 279 +- .../src/win32_thread.c | 11 +- .../src/vendor/glfw-3.4/src/win32_thread.h | 53 + .../{glfw-3.3.8 => glfw-3.4}/src/win32_time.c | 24 +- src/lib/src/vendor/glfw-3.4/src/win32_time.h | 43 + .../src/win32_window.c | 895 ++- .../{glfw-3.3.8 => glfw-3.4}/src/window.c | 259 +- src/lib/src/vendor/glfw-3.4/src/wl_init.c | 1003 +++ .../{glfw-3.3.8 => glfw-3.4}/src/wl_monitor.c | 65 +- src/lib/src/vendor/glfw-3.4/src/wl_platform.h | 691 ++ .../{glfw-3.3.8 => glfw-3.4}/src/wl_window.c | 2068 +++--- .../{glfw-3.3.8 => glfw-3.4}/src/x11_init.c | 640 +- .../src/x11_monitor.c | 69 +- .../src/vendor/glfw-3.4/src/x11_platform.h | 1004 +++ .../{glfw-3.3.8 => glfw-3.4}/src/x11_window.c | 843 ++- .../src/xkb_unicode.c | 7 +- .../src/xkb_unicode.h | 2 +- .../tests/CMakeLists.txt | 39 +- src/lib/src/vendor/glfw-3.4/tests/allocator.c | 142 + .../tests/clipboard.c | 1 + .../{glfw-3.3.8 => glfw-3.4}/tests/cursor.c | 54 +- .../{glfw-3.3.8 => glfw-3.4}/tests/empty.c | 1 + .../{glfw-3.3.8 => glfw-3.4}/tests/events.c | 59 +- .../{glfw-3.3.8 => glfw-3.4}/tests/gamma.c | 2 + .../{glfw-3.3.8 => glfw-3.4}/tests/glfwinfo.c | 829 ++- .../{glfw-3.3.8 => glfw-3.4}/tests/icon.c | 1 + .../{glfw-3.3.8 => glfw-3.4}/tests/iconify.c | 1 + .../{glfw-3.3.8 => glfw-3.4}/tests/inputlag.c | 2 + .../tests/joysticks.c | 2 + .../{glfw-3.3.8 => glfw-3.4}/tests/monitors.c | 3 + .../{glfw-3.3.8 => glfw-3.4}/tests/msaa.c | 1 + .../{glfw-3.3.8 => glfw-3.4}/tests/reopen.c | 1 + .../{glfw-3.3.8 => glfw-3.4}/tests/tearing.c | 1 + .../{glfw-3.3.8 => glfw-3.4}/tests/threads.c | 9 +- .../{glfw-3.3.8 => glfw-3.4}/tests/timeout.c | 1 + .../{glfw-3.3.8 => glfw-3.4}/tests/title.c | 1 + .../tests/triangle-vulkan.c | 3 +- src/lib/src/vendor/glfw-3.4/tests/window.c | 457 ++ 634 files changed, 46322 insertions(+), 30901 deletions(-) create mode 100644 .cache/clangd/index/bitmap.hpp.62887C634633116B.idx create mode 100644 .cache/clangd/index/bitmap.hpp.EEDEB52DF9368726.idx create mode 100644 .cache/clangd/index/bitmap_io.cpp.181EA33891BBC2AF.idx create mode 100644 .cache/clangd/index/bitmap_io.cpp.4AB5E576AFA93983.idx create mode 100644 .cache/clangd/index/bitmap_io.hpp.C3324F345C5DD5D2.idx create mode 100644 .cache/clangd/index/bitmap_io.hpp.E43B2188CF8AB392.idx create mode 100644 .cache/clangd/index/context.c.91BC96CF7BD16B3C.idx create mode 100644 .cache/clangd/index/context.c.ACB36D59D1DFD31C.idx create mode 100644 .cache/clangd/index/context.cpp.4F65C2A62FFB483F.idx create mode 100644 .cache/clangd/index/context.cpp.EECF18BC474ACA88.idx create mode 100644 .cache/clangd/index/context.hpp.0247079C4DA06A0E.idx create mode 100644 .cache/clangd/index/context.hpp.30BB9F8B4501681D.idx create mode 100644 .cache/clangd/index/egl_context.c.225C06C339B7DDA1.idx create mode 100644 .cache/clangd/index/egl_context.c.CD53B506C4A00245.idx create mode 100644 .cache/clangd/index/egl_context.h.04386B6C0A7119A7.idx create mode 100644 .cache/clangd/index/egl_context.h.B2730FCAFD4752C9.idx create mode 100644 .cache/clangd/index/geometry.hpp.5CBEA5776F164981.idx create mode 100644 .cache/clangd/index/geometry.hpp.D38DA0C44333DD06.idx create mode 100644 .cache/clangd/index/glad.c.6ADEBFBBDDE6583D.idx create mode 100644 .cache/clangd/index/glad.c.DC115C5ADDB0D90B.idx create mode 100644 .cache/clangd/index/glad.h.75CCCDA1A3F702AC.idx create mode 100644 .cache/clangd/index/glad.h.76E6696D4B8D4E14.idx create mode 100644 .cache/clangd/index/glfw3.h.5A7452531BE9304F.idx create mode 100644 .cache/clangd/index/glfw3.h.AAFA18C8892E0F92.idx create mode 100644 .cache/clangd/index/globals.hpp.24BCAC15858D1B89.idx create mode 100644 .cache/clangd/index/globals.hpp.380C15F700EE3EE1.idx create mode 100644 .cache/clangd/index/glx_context.c.7EDF51863382D2CB.idx create mode 100644 .cache/clangd/index/glx_context.c.B0ADB84DEBD4B2AA.idx create mode 100644 .cache/clangd/index/glx_context.h.256A85A14326A9DC.idx create mode 100644 .cache/clangd/index/glx_context.h.E85BD630F7223469.idx create mode 100644 .cache/clangd/index/init.c.55CFCFFC01384B65.idx create mode 100644 .cache/clangd/index/init.c.A2467C96C1716714.idx create mode 100644 .cache/clangd/index/input.c.7252BD8769C990CB.idx create mode 100644 .cache/clangd/index/input.c.DED1B4400041FF44.idx create mode 100644 .cache/clangd/index/internal.h.445CD411983AEDF9.idx create mode 100644 .cache/clangd/index/internal.h.DE6A02CC46470B84.idx create mode 100644 .cache/clangd/index/khrplatform.h.29E603D3A52AEC6A.idx create mode 100644 .cache/clangd/index/khrplatform.h.D6CEFEA22454BFC5.idx create mode 100644 .cache/clangd/index/linux_joystick.c.0B324179DA9FB60F.idx create mode 100644 .cache/clangd/index/linux_joystick.c.792A25E4FD082BE3.idx create mode 100644 .cache/clangd/index/linux_joystick.h.6D80310652F4A3A1.idx create mode 100644 .cache/clangd/index/linux_joystick.h.F9013A3DE8A76987.idx create mode 100644 .cache/clangd/index/mappings.h.2B5E5627F59980DE.idx create mode 100644 .cache/clangd/index/mappings.h.DE572F1D18327736.idx create mode 100644 .cache/clangd/index/matrix.hpp.82213AF3AAC74723.idx create mode 100644 .cache/clangd/index/matrix.hpp.B61CADF6F0D53E3B.idx create mode 100644 .cache/clangd/index/matrixbase.hpp.60D06CA21577625A.idx create mode 100644 .cache/clangd/index/matrixbase.hpp.F11E20E9DFADCEFF.idx create mode 100644 .cache/clangd/index/monitor.c.8465A82AF6ED1794.idx create mode 100644 .cache/clangd/index/monitor.c.AEB0C2DC26515679.idx create mode 100644 .cache/clangd/index/osmesa_context.c.1EE9BEC9D6A3E34A.idx create mode 100644 .cache/clangd/index/osmesa_context.c.9D0E9B593E3B91C8.idx create mode 100644 .cache/clangd/index/osmesa_context.h.0C7F09075E273648.idx create mode 100644 .cache/clangd/index/osmesa_context.h.141748BA6847E054.idx create mode 100644 .cache/clangd/index/pong.cpp.0666B09B2C5A6C2D.idx create mode 100644 .cache/clangd/index/pong.cpp.5E4CD60C67D0940C.idx create mode 100644 .cache/clangd/index/posix_thread.c.3F3583255D9A0824.idx create mode 100644 .cache/clangd/index/posix_thread.c.97BD9159EEF76B84.idx create mode 100644 .cache/clangd/index/posix_thread.h.0D3851D1D9279E82.idx create mode 100644 .cache/clangd/index/posix_thread.h.2D23296B7CFBFCA2.idx create mode 100644 .cache/clangd/index/posix_time.c.4CBE14BF15C8C278.idx create mode 100644 .cache/clangd/index/posix_time.c.EEC0949F9BB68444.idx create mode 100644 .cache/clangd/index/posix_time.h.690873C37A0312EE.idx create mode 100644 .cache/clangd/index/posix_time.h.B922C8D5550AB845.idx create mode 100644 .cache/clangd/index/quickwings.cpp.85EA7B40D80DA419.idx create mode 100644 .cache/clangd/index/quickwings.cpp.C395FD54968A1134.idx create mode 100644 .cache/clangd/index/renderer.cpp.740BAA1FB38348C8.idx create mode 100644 .cache/clangd/index/renderer.cpp.C9C31387983FB261.idx create mode 100644 .cache/clangd/index/renderer.hpp.8430C86236A009AE.idx create mode 100644 .cache/clangd/index/renderer.hpp.926D47CDCF3C1D01.idx create mode 100644 .cache/clangd/index/rgba.hpp.BA781889E6CDBAD7.idx create mode 100644 .cache/clangd/index/rgba.hpp.FC678113A439A522.idx create mode 100644 .cache/clangd/index/shader.cpp.43E3518708249EAE.idx create mode 100644 .cache/clangd/index/shader.cpp.7A00B3A7CCD89C12.idx create mode 100644 .cache/clangd/index/shader.hpp.DF5CE306CA970394.idx create mode 100644 .cache/clangd/index/shader.hpp.E7CD36D8F71952ED.idx create mode 100644 .cache/clangd/index/shader_sprite.hpp.493F804E562576C3.idx create mode 100644 .cache/clangd/index/shader_sprite.hpp.8B17A178D93F0BE6.idx create mode 100644 .cache/clangd/index/simple.cpp.96D892360BBE0299.idx create mode 100644 .cache/clangd/index/simple.cpp.C6B37DEAE25C79D2.idx create mode 100644 .cache/clangd/index/sprite.hpp.A9098C65589F3A19.idx create mode 100644 .cache/clangd/index/sprite.hpp.CC3066F6ABEF70A9.idx create mode 100644 .cache/clangd/index/stb_image.h.66C3FB4B07894FDB.idx create mode 100644 .cache/clangd/index/stb_image.h.A40CF375DB872323.idx create mode 100644 .cache/clangd/index/vector.hpp.3A192E43B974E9B2.idx create mode 100644 .cache/clangd/index/vector.hpp.E320F2C0D8CBC593.idx create mode 100644 .cache/clangd/index/vulkan.c.F1AE9249ACD23954.idx create mode 100644 .cache/clangd/index/vulkan.c.F75EB52C23E5F7F6.idx create mode 100644 .cache/clangd/index/window.c.ACCD05B2BA43D003.idx create mode 100644 .cache/clangd/index/window.c.CE66238555157A64.idx create mode 100644 .cache/clangd/index/window.cpp.75FB94300CFB46BA.idx create mode 100644 .cache/clangd/index/window.cpp.C49665C3E96358E9.idx create mode 100644 .cache/clangd/index/window.hpp.B8A7D1770B434EEC.idx create mode 100644 .cache/clangd/index/window.hpp.F8FA2942270CA4B4.idx create mode 100644 .cache/clangd/index/x11_init.c.5062A2FC3E2A7E6D.idx create mode 100644 .cache/clangd/index/x11_init.c.F00A5A0A2091891E.idx create mode 100644 .cache/clangd/index/x11_monitor.c.271D126498E8CFAE.idx create mode 100644 .cache/clangd/index/x11_monitor.c.EA1D4A157A0E438E.idx create mode 100644 .cache/clangd/index/x11_platform.h.1DDD554B1F22A6A0.idx create mode 100644 .cache/clangd/index/x11_platform.h.56FB194C0C211696.idx create mode 100644 .cache/clangd/index/x11_window.c.241536F32C8627F0.idx create mode 100644 .cache/clangd/index/x11_window.c.8BEA32FE82C65B89.idx create mode 100644 .cache/clangd/index/xkb_unicode.c.31E6598E6573D51F.idx create mode 100644 .cache/clangd/index/xkb_unicode.c.757568D7EEC6A2FA.idx create mode 100644 .cache/clangd/index/xkb_unicode.h.53CF8CB5C8862029.idx create mode 100644 .cache/clangd/index/xkb_unicode.h.93B1782F55B08538.idx delete mode 100644 src/lib/src/vendor/glfw-3.3.8/CMake/modules/FindWaylandProtocols.cmake delete mode 100644 src/lib/src/vendor/glfw-3.3.8/CMake/modules/FindXKBCommon.cmake delete mode 100644 src/lib/src/vendor/glfw-3.3.8/CMakeLists.txt delete mode 100644 src/lib/src/vendor/glfw-3.3.8/README.md delete mode 100644 src/lib/src/vendor/glfw-3.3.8/deps/glad/gl.h delete mode 100644 src/lib/src/vendor/glfw-3.3.8/deps/glad/khrplatform.h delete mode 100644 src/lib/src/vendor/glfw-3.3.8/deps/glad/vk_platform.h delete mode 100644 src/lib/src/vendor/glfw-3.3.8/deps/glad_gl.c delete mode 100644 src/lib/src/vendor/glfw-3.3.8/deps/glad_vulkan.c delete mode 100644 src/lib/src/vendor/glfw-3.3.8/deps/vs2008/stdint.h delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/CMakeLists.txt delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/Doxyfile.in delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/extra.css delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/extra.css.map delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/bdwn.png delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/build_guide.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/compat_guide.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/compile_guide.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/doc.png delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/extra.css delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/folderclosed.png delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/folderopen.png delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/glfw3_8h.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/glfw3native_8h.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/group__errors.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/group__init.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/group__shapes.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/internal_8dox.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/internals_guide.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/intro_guide.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/monitor_8dox.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/news.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_0.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_0.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_1.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_1.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_10.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_10.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_11.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_11.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_2.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_2.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_3.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_4.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_4.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_5.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_5.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_6.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_6.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_7.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_7.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_8.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_9.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_9.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_a.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_a.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_b.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_b.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_c.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_c.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_d.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_d.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_e.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_e.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_f.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_f.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/classes_0.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/classes_0.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/defines_0.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/defines_0.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_0.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_0.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_1.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_1.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_2.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_3.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_3.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_4.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_4.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_5.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_5.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_6.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_6.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_7.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_7.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_8.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/files_8.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/functions_0.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_0.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_0.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_1.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_1.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_2.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_3.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_3.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_4.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_4.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_5.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_5.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_6.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_7.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_8.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_8.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_9.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_9.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/groups_a.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/mag_sel.svg delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/nomatches.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_0.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_1.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_1.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_2.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_2.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_3.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_3.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_4.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_5.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_6.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_6.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_7.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_7.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_8.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_8.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_9.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_9.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_a.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/search_l.png delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/search_m.png delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/search_r.png delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/typedefs_0.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/typedefs_0.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_0.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_0.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_1.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_1.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_2.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_2.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_3.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_3.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_4.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_4.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_5.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_5.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_6.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_6.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_7.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/search/variables_7.js delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/tabs.css delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/html/window_8dox.html delete mode 100644 src/lib/src/vendor/glfw-3.3.8/docs/news.dox delete mode 100644 src/lib/src/vendor/glfw-3.3.8/src/CMakeLists.txt delete mode 100644 src/lib/src/vendor/glfw-3.3.8/src/egl_context.h delete mode 100644 src/lib/src/vendor/glfw-3.3.8/src/glfw3Config.cmake.in delete mode 100644 src/lib/src/vendor/glfw-3.3.8/src/glfw_config.h.in delete mode 100644 src/lib/src/vendor/glfw-3.3.8/src/glx_context.h delete mode 100644 src/lib/src/vendor/glfw-3.3.8/src/nsgl_context.h delete mode 100644 src/lib/src/vendor/glfw-3.3.8/src/null_platform.h delete mode 100644 src/lib/src/vendor/glfw-3.3.8/src/null_window.c delete mode 100644 src/lib/src/vendor/glfw-3.3.8/src/osmesa_context.h delete mode 100644 src/lib/src/vendor/glfw-3.3.8/src/wgl_context.h delete mode 100644 src/lib/src/vendor/glfw-3.3.8/src/wl_init.c delete mode 100644 src/lib/src/vendor/glfw-3.3.8/src/wl_platform.h delete mode 100644 src/lib/src/vendor/glfw-3.3.8/src/x11_platform.h delete mode 100644 src/lib/src/vendor/glfw-3.3.8/tests/opacity.c delete mode 100644 src/lib/src/vendor/glfw-3.3.8/tests/windows.c rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/CMake/GenerateMappings.cmake (75%) rename src/lib/src/vendor/{glfw-3.3.8/CMake/MacOSXBundleInfo.plist.in => glfw-3.4/CMake/Info.plist.in} (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4/CMake}/cmake_uninstall.cmake.in (78%) rename src/lib/src/vendor/{glfw-3.3.8/src => glfw-3.4/CMake}/glfw3.pc.in (64%) create mode 100644 src/lib/src/vendor/glfw-3.4/CMake/glfw3Config.cmake.in rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/CMake/i686-w64-mingw32-clang.cmake (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/CMake/i686-w64-mingw32.cmake (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/CMake/modules/FindEpollShim.cmake (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/CMake/modules/FindOSMesa.cmake (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/CMake/x86_64-w64-mingw32-clang.cmake (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/CMake/x86_64-w64-mingw32.cmake (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/CMakeLists.txt rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/CONTRIBUTORS.md (85%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/LICENSE.md (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/README.md rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/deps/getopt.c (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/deps/getopt.h (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/deps/glad/gl.h create mode 100644 src/lib/src/vendor/glfw-3.4/deps/glad/gles2.h rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/deps/glad/vulkan.h (84%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/deps/linmath.h (59%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/deps/mingw/_mingw_dxhelper.h (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/deps/mingw/dinput.h (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/deps/mingw/xinput.h (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/deps/nuklear.h (98%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/deps/nuklear_glfw_gl2.h (98%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/deps/stb_image_write.h (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/deps/tinycthread.c (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/deps/tinycthread.h (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/deps/wayland/fractional-scale-v1.xml create mode 100644 src/lib/src/vendor/glfw-3.4/deps/wayland/idle-inhibit-unstable-v1.xml create mode 100644 src/lib/src/vendor/glfw-3.4/deps/wayland/pointer-constraints-unstable-v1.xml create mode 100644 src/lib/src/vendor/glfw-3.4/deps/wayland/relative-pointer-unstable-v1.xml create mode 100644 src/lib/src/vendor/glfw-3.4/deps/wayland/viewporter.xml create mode 100644 src/lib/src/vendor/glfw-3.4/deps/wayland/wayland.xml create mode 100644 src/lib/src/vendor/glfw-3.4/deps/wayland/xdg-activation-v1.xml create mode 100644 src/lib/src/vendor/glfw-3.4/deps/wayland/xdg-decoration-unstable-v1.xml create mode 100644 src/lib/src/vendor/glfw-3.4/deps/wayland/xdg-shell.xml create mode 100644 src/lib/src/vendor/glfw-3.4/docs/CMakeLists.txt rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/CONTRIBUTING.md (97%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/Doxyfile.in rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/DoxygenLayout.xml (96%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/SUPPORT.md (79%) rename src/lib/src/vendor/{glfw-3.3.8/docs/build.dox => glfw-3.4/docs/build.md} (61%) rename src/lib/src/vendor/{glfw-3.3.8/docs/compat.dox => glfw-3.4/docs/compat.md} (62%) rename src/lib/src/vendor/{glfw-3.3.8/docs/compile.dox => glfw-3.4/docs/compile.md} (54%) rename src/lib/src/vendor/{glfw-3.3.8/docs/context.dox => glfw-3.4/docs/context.md} (88%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/extra.css create mode 100644 src/lib/src/vendor/glfw-3.4/docs/extra.css.map rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/extra.scss (96%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/footer.html (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/header.html (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/bc_s.png (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/bc_sd.png rename src/lib/src/vendor/{glfw-3.3.8/docs/html/main_8dox.html => glfw-3.4/docs/html/build_8md.html} (80%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/build_guide.html rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/closed.png (100%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/input_8dox.html => glfw-3.4/docs/html/compat_8md.html} (80%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/compat_guide.html rename src/lib/src/vendor/{glfw-3.3.8/docs/html/moving_8dox.html => glfw-3.4/docs/html/compile_8md.html} (80%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/compile_guide.html rename src/lib/src/vendor/{glfw-3.3.8/docs/html/vulkan_8dox.html => glfw-3.4/docs/html/context_8md.html} (80%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/context_guide.html (55%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/deprecated.html (84%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/dir_4351554941a2744586042c1cf3cf139a.html => glfw-3.4/docs/html/dir_13577e2d8b9423099662de029791bd7d.html} (72%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/dir_1dfd43b3952c5bc1ba15d15b12afff7b.html => glfw-3.4/docs/html/dir_7f92719a7fe62e5b064f87d7a3c220b1.html} (73%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/dir_fda32cf7bec00275262cb8799a618f76.html => glfw-3.4/docs/html/dir_a788ef6c2b1e5b367804e0b6ccfd6f11.html} (78%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/dir_f6ba4c3dca55a8d4e7d63c8235e0ad43.html => glfw-3.4/docs/html/dir_b11153cd0f4fd04a7564cc166f482635.html} (76%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/doc.svg create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/docd.svg rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/doxygen.css (79%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/doxygen.svg (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/dynsections.js (58%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/extra.css rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/files.html (67%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/folderclosed.svg create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/folderclosedd.svg create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/folderopen.svg create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/folderopend.svg create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/glfw3_8h.html rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/glfw3_8h_source.html (66%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/glfw3native_8h.html rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/glfw3native_8h_source.html (70%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/group__buttons.html (62%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/group__context.html (63%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/group__errors.html rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/group__gamepad__axes.html (65%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/group__gamepad__buttons.html (59%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/group__hat__state.html (62%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/group__init.html rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/group__input.html (64%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/group__joysticks.html (61%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/group__keys.html (57%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/group__mods.html (64%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/group__monitor.html (69%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/group__native.html (67%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/group__shapes.html rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/group__vulkan.html (66%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/group__window.html (61%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/index.html (55%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/news_8dox.html => glfw-3.4/docs/html/input_8md.html} (80%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/input_guide.html (55%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/context_8dox.html => glfw-3.4/docs/html/internal_8md.html} (80%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/internals_guide.html create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/intro_8md.html create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/intro_guide.html rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/jquery.js (77%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/compile_8dox.html => glfw-3.4/docs/html/main_8md.html} (79%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/menu.js (86%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/menudata.js (97%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/minus.svg create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/minusd.svg rename src/lib/src/vendor/{glfw-3.3.8/docs/html/compat_8dox.html => glfw-3.4/docs/html/monitor_8md.html} (80%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/monitor_guide.html (54%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/build_8dox.html => glfw-3.4/docs/html/moving_8md.html} (80%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/moving_guide.html (51%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/nav_f.png (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/nav_fd.png rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/nav_g.png (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/nav_h.png (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/nav_hd.png create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/news.html create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/news_8md.html rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/open.png (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/pages.html (66%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/plus.svg create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/plusd.svg create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/quick_8md.html rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/quick_guide.html (62%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_0.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_1.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_10.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_11.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_12.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_13.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_14.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_15.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_16.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_17.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_18.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_19.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_1a.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_1b.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_1c.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_1d.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_1e.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_1f.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_2.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_3.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_4.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_5.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_6.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_7.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_8.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_9.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_a.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_b.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_c.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_d.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_e.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/all_f.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/classes_0.js rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/search/close.svg (62%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/defines_0.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/files_0.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/files_1.js rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/search/files_2.js (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/files_3.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/files_4.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/files_5.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/files_6.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/files_7.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/files_8.js rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/search/functions_0.js (50%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/groups_0.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/groups_1.js rename src/lib/src/vendor/{glfw-3.3.8/docs/html/search/groups_a.js => glfw-3.4/docs/html/search/groups_10.js} (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/groups_2.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/groups_3.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/groups_4.js rename src/lib/src/vendor/{glfw-3.3.8/docs/html/search/groups_2.js => glfw-3.4/docs/html/search/groups_5.js} (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/groups_6.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/groups_7.js rename src/lib/src/vendor/{glfw-3.3.8/docs/html/search/all_8.js => glfw-3.4/docs/html/search/groups_8.js} (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/groups_9.js rename src/lib/src/vendor/{glfw-3.3.8/docs/html/search/groups_6.js => glfw-3.4/docs/html/search/groups_a.js} (100%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/search/groups_7.js => glfw-3.4/docs/html/search/groups_b.js} (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/groups_c.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/groups_d.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/groups_e.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/groups_f.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/mag.svg create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/mag_d.svg create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/mag_sel.svg create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/mag_seld.svg create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/pages_0.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/pages_1.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/pages_10.js rename src/lib/src/vendor/{glfw-3.3.8/docs/html/search/pages_a.js => glfw-3.4/docs/html/search/pages_11.js} (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/pages_2.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/pages_3.js rename src/lib/src/vendor/{glfw-3.3.8/docs/html/search/pages_0.js => glfw-3.4/docs/html/search/pages_4.js} (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/pages_5.js rename src/lib/src/vendor/{glfw-3.3.8/docs/html/search/all_3.js => glfw-3.4/docs/html/search/pages_6.js} (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/pages_7.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/pages_8.js rename src/lib/src/vendor/{glfw-3.3.8/docs/html/search/pages_4.js => glfw-3.4/docs/html/search/pages_9.js} (62%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/pages_a.js rename src/lib/src/vendor/{glfw-3.3.8/docs/html/search/pages_5.js => glfw-3.4/docs/html/search/pages_b.js} (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/pages_c.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/pages_d.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/pages_e.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/pages_f.js rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/search/search.css (77%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/search/search.js (84%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/search/searchdata.js (79%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/typedefs_0.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/variables_0.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/variables_1.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/variables_2.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/variables_3.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/variables_4.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/variables_5.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/variables_6.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/variables_7.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/variables_8.js create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/search/variables_9.js rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/spaces.svg (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/splitbar.png (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/splitbard.png create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wallocator.html rename src/lib/src/vendor/{glfw-3.3.8/docs/html/structGLFWgamepadstate.html => glfw-3.4/docs/html/struct_g_l_f_wgamepadstate.html} (72%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/structGLFWgammaramp.html => glfw-3.4/docs/html/struct_g_l_f_wgammaramp.html} (69%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/structGLFWimage.html => glfw-3.4/docs/html/struct_g_l_f_wimage.html} (71%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/structGLFWvidmode.html => glfw-3.4/docs/html/struct_g_l_f_wvidmode.html} (67%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/sync_off.png (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/sync_on.png (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/tab_a.png (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/tab_ad.png rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/tab_b.png (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/tab_bd.png rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/tab_h.png (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/tab_hd.png rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/tab_s.png (100%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/tab_sd.png create mode 100644 src/lib/src/vendor/glfw-3.4/docs/html/tabs.css rename src/lib/src/vendor/{glfw-3.3.8/docs/html/modules.html => glfw-3.4/docs/html/topics.html} (61%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/intro_8dox.html => glfw-3.4/docs/html/vulkan_8md.html} (80%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/vulkan_guide.html (52%) rename src/lib/src/vendor/{glfw-3.3.8/docs/html/quick_8dox.html => glfw-3.4/docs/html/window_8md.html} (80%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/html/window_guide.html (50%) rename src/lib/src/vendor/{glfw-3.3.8/docs/input.dox => glfw-3.4/docs/input.md} (88%) rename src/lib/src/vendor/{glfw-3.3.8/docs/internal.dox => glfw-3.4/docs/internal.md} (75%) rename src/lib/src/vendor/{glfw-3.3.8/docs/intro.dox => glfw-3.4/docs/intro.md} (59%) rename src/lib/src/vendor/{glfw-3.3.8/docs/main.dox => glfw-3.4/docs/main.md} (87%) rename src/lib/src/vendor/{glfw-3.3.8/docs/monitor.dox => glfw-3.4/docs/monitor.md} (81%) rename src/lib/src/vendor/{glfw-3.3.8/docs/moving.dox => glfw-3.4/docs/moving.md} (76%) create mode 100644 src/lib/src/vendor/glfw-3.4/docs/news.md rename src/lib/src/vendor/{glfw-3.3.8/docs/quick.dox => glfw-3.4/docs/quick.md} (85%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/docs/spaces.svg (100%) rename src/lib/src/vendor/{glfw-3.3.8/docs/vulkan.dox => glfw-3.4/docs/vulkan.md} (79%) rename src/lib/src/vendor/{glfw-3.3.8/docs/window.dox => glfw-3.4/docs/window.md} (82%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/examples/CMakeLists.txt (75%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/examples/boing.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/examples/gears.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/examples/glfw.icns (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/examples/glfw.ico (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/examples/glfw.rc (100%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/examples/heightmap.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/examples/offscreen.c (94%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/examples/particles.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/examples/sharing.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/examples/splitview.c (99%) rename src/lib/src/vendor/{glfw-3.3.8/examples/simple.c => glfw-3.4/examples/triangle-opengl.c} (70%) create mode 100644 src/lib/src/vendor/glfw-3.4/examples/triangle-opengles.c rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/examples/wave.c (99%) create mode 100644 src/lib/src/vendor/glfw-3.4/examples/windows.c rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/include/GLFW/glfw3.h (86%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/include/GLFW/glfw3native.h (85%) create mode 100644 src/lib/src/vendor/glfw-3.4/src/CMakeLists.txt rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/cocoa_init.m (79%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/cocoa_joystick.h (79%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/cocoa_joystick.m (89%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/cocoa_monitor.m (89%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/cocoa_platform.h (52%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/cocoa_time.c (79%) create mode 100644 src/lib/src/vendor/glfw-3.4/src/cocoa_time.h rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/cocoa_window.m (79%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/context.c (98%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/egl_context.c (71%) create mode 100644 src/lib/src/vendor/glfw-3.4/src/glfw.rc.in rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/glx_context.c (83%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/init.c (69%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/input.c (78%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/internal.h (53%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/linux_joystick.c (94%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/linux_joystick.h (84%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/mappings.h (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/mappings.h.in (95%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/monitor.c (88%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/nsgl_context.m (84%) create mode 100644 src/lib/src/vendor/glfw-3.4/src/null_init.c rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/null_joystick.c (82%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/null_joystick.h (82%) create mode 100644 src/lib/src/vendor/glfw-3.4/src/null_monitor.c create mode 100644 src/lib/src/vendor/glfw-3.4/src/null_platform.h create mode 100644 src/lib/src/vendor/glfw-3.4/src/null_window.c rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/osmesa_context.c (86%) create mode 100644 src/lib/src/vendor/glfw-3.4/src/platform.c create mode 100644 src/lib/src/vendor/glfw-3.4/src/platform.h rename src/lib/src/vendor/{glfw-3.3.8/src/null_init.c => glfw-3.4/src/posix_module.c} (72%) create mode 100644 src/lib/src/vendor/glfw-3.4/src/posix_poll.c create mode 100644 src/lib/src/vendor/glfw-3.4/src/posix_poll.h rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/posix_thread.c (94%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/posix_thread.h (91%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/posix_time.c (59%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/posix_time.h (89%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/vulkan.c (80%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/wgl_context.c (75%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/win32_init.c (69%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/win32_joystick.c (95%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/win32_joystick.h (83%) rename src/lib/src/vendor/{glfw-3.3.8/src/null_monitor.c => glfw-3.4/src/win32_module.c} (53%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/win32_monitor.c (88%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/win32_platform.h (54%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/win32_thread.c (90%) create mode 100644 src/lib/src/vendor/glfw-3.4/src/win32_thread.h rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/win32_time.c (79%) create mode 100644 src/lib/src/vendor/glfw-3.4/src/win32_time.h rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/win32_window.c (72%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/window.c (81%) create mode 100644 src/lib/src/vendor/glfw-3.4/src/wl_init.c rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/wl_monitor.c (81%) create mode 100644 src/lib/src/vendor/glfw-3.4/src/wl_platform.h rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/wl_window.c (55%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/x11_init.c (59%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/x11_monitor.c (91%) create mode 100644 src/lib/src/vendor/glfw-3.4/src/x11_platform.h rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/x11_window.c (82%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/xkb_unicode.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/src/xkb_unicode.h (97%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/CMakeLists.txt (71%) create mode 100644 src/lib/src/vendor/glfw-3.4/tests/allocator.c rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/clipboard.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/cursor.c (93%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/empty.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/events.c (92%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/gamma.c (98%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/glfwinfo.c (50%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/icon.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/iconify.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/inputlag.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/joysticks.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/monitors.c (98%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/msaa.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/reopen.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/tearing.c (99%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/threads.c (96%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/timeout.c (98%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/title.c (98%) rename src/lib/src/vendor/{glfw-3.3.8 => glfw-3.4}/tests/triangle-vulkan.c (99%) create mode 100644 src/lib/src/vendor/glfw-3.4/tests/window.c diff --git a/.cache/clangd/index/bitmap.hpp.62887C634633116B.idx b/.cache/clangd/index/bitmap.hpp.62887C634633116B.idx new file mode 100644 index 0000000000000000000000000000000000000000..9eef6076523ecfc875569b95ed159532989d6447 GIT binary patch literal 1676 zcmYjReM}o=7{6ZIw;wy&(oaSUrNx#W8%ix@u^XjCgtjgO;pnnuvDB3obWEj;F|!c~ zGTnd;OoQmiT%7!|CEYSVHvGZ}j4ac{0B#x$%n@`DNv887m__uxBM;{#_uReD@A-ay zcQt{EidPUpJRS|SH#f9KLID;lHGUF$xR^awAV6JG7^ zl;0!v^_o}dJ-zQg`K5cc^rf92&X0@c zPcpY2oMpC-w4KiVVn!Ay)W3Lobi&+QbN_{t8suiS2L7=!kp2-P9iaWyBLRW3)-MOc?tH@0lj%uQ2P5^wVr)Yl2 zGghW1DGa+zE*mERj?BItNzRP~RHPEajF#EV34m+W$wggHbCrS=Vz^P=n9T`*FXp9= zb>uegQ;~8E`!#+8CjdUW_rO41-)z%*Zm-E}L#zPUIbdD!T~0l#AXV5qCX1zU0^lZz zPv7m$>02)?oEbJFRsbx{nm+F_9QsU6im|uDc)5DP@eXZPhp(M**(Z)sqMSV$py3+;q-6!I2(cYqOv z;UIyzFa;Fp0iddl(97!3|LL^`*j>J+F zDug1inx!VFi+-)XcFS_RT!1^b1s%{iB*NA#Q^6WYirWlG16r`AP@S|+3qBNz7DOL| zGUObMApm&bxGaZ34a>l4mbRdVmc)30>9mfYsxRHA10Ot@jF5>>9?6K9U@~%!<`C}Z z+vO*_Cw@AH=||gX8p44wPR_C(tnV)`6nK>y9wcLC@^}}<&6Mz`uq|A`2dKBzZ=9eUTr~SZ zLebtCPshKhl{Y# zrI1VKG6H>Y`#P@?+IM~+lUE$h{Dx&uS}+~v(EIM--1A44f53x|XU2`t^yszL;@!iJ xKUr%-&;-^k4f`W3-xDqS5|6Mi_{Ra41YQXE+pr4s-h~t8L-($92_;e)@gHE(5(WSO literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/bitmap.hpp.EEDEB52DF9368726.idx b/.cache/clangd/index/bitmap.hpp.EEDEB52DF9368726.idx new file mode 100644 index 0000000000000000000000000000000000000000..8c9f680f23a652ac2b0a44552e3d2f68756e4940 GIT binary patch literal 1676 zcmYjReM}o=7{6ZIw;wy&(oaSUrNu&z4FyYC?AD`11X>q@aIkDyEOn&?H>Og?ImX|lNl`99{|MZ`&-lZ>Q1B=tu^6}0@uhBKVqBEP_weGVCk9g#~_;OdL zY}df<(CKGl*9}vHqZN}E!c!;9et%>2-m{lp>^q%o&^<@*>3Qej&)usfPw#wheq1tt zioJ379J_V6{Y>^}GYWr!@u@ST6V{%ZJ5MfczkGMCX07p;^Q*Tc`5l`(#?-G?5V0dI zkL|)0|DAZb^P53Nt0E;T0!59{bY2j0+!4MOj@NeHo_ln=hTMeVur6%n1;8WSMe~E6 zu~IEbVc2DHId}nZX!i9`Vs6;4A=MaW_3UO|09>n0EE>97s#K&H!%fQdeo>1;EGl9_+8{oo!yv%~%)*;sn5j{q_~#rR3u(QiHuCibx7C0B)A~ zj9pAt?|Ny$^q>`S0$^#z^aYRU@F!YQioKl{r;Qf?AD#MPLO!r<8j)lQfow8c3NHu+ zLExE+kd$a`jKqwXBG=6E1w~vX6-kgU$Cn31vsK#MrT!gKF@@+YbRndp5L3+T03!-T z6;U;8DDT#A`)`vKDw0A)@*>sxeh7j>CGwJu6Bx^ITq~U|#PwNy*+SfaHeiJDQYerW zxJNkEtLt^JI0}W-Asx(0$x{P*zjz28TwUCsCZUki?#vNVxpG{2Kn&ba4ztlUg(8xO z95(ZTyE|FE<&jL05}D*CGc>eKk)b?1`mG0#raq(I{=ZT(LUt$xM^Z=h5D8d{BXJak z3ZV$B=BNqkqF<}8+_2p&6XDJs0Vi}0iLf=tRImn;;x_$qzaFe9R41>~gAawm`QZnk z3?)xv2ml^9F2`X|!!od%qb;bRB`IEDDs2#^>Pz(*zz0tzt==Le52b}HFc~FJa|rj- z&9YNn6F;87^rLfV8p44wPR_9&tnVx@6nt2f`Vqp(@288w8ZXhylnTi!Gb`=T6@^$8 zs})KK>Vs(z9rITc)dMB3|LhEYIo|#;9wcjJa|IXH&3c7X&=JfR0yH=pHcn6uE}Huw zp=f5t)A4UIF^Shnd+AcJA}Vh09s6VL8dgWl5gW`Eyd+Bgi{0~e{MezHa4zPs!D$9x z3b_m}GtdXOZ(z*Oe&M?cW%-fxuQ>Lk1X5uRJ#P-oJ#lpTJ3Q!UdejU}k6vjj-aX{} xle0DjEMVQ*cp${_J=VG}b|3eGe;jbh;Dvy{4W~f+zaM$K`K7>XVwqe){0CSD5u^YB literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/bitmap_io.cpp.181EA33891BBC2AF.idx b/.cache/clangd/index/bitmap_io.cpp.181EA33891BBC2AF.idx new file mode 100644 index 0000000000000000000000000000000000000000..d70caa99ab2d038a46dce49774b0acecb888a079 GIT binary patch literal 2906 zcmYjT3sh6*9ltl+@JKFsk=!p32m+FjB@il)1#~==K!KJ7aHyb*iphZ>lqNO})==@0 z()s8-R&6~LD^|Orvr@6O%qaz`)w4~J9;eh!2R>kSu5zkHLAx)wf0CT!CcoIMm&bEVPUzPMH(+@8;c8ZQ~3s^X8 zmVFqt9O)L-j-&}|%j3r{J!?PIQGHo3{NB3>w&{uKAJB4ITK>-;zBxXu+Pi2;;Od7x zYnPtN4yZcdNZZe3U0F6@ey6v>x&Ng`>8ZTBqSS5OA9SP)j$bc5(01+uCvBk3wBWO+ zt5UK?fBxlea2NIY`{d5v$YjG;ul-I`e)eJ)x4E}iy_cip_s(Bvf8RV*HF>z?TKM5- zd68<>%SZH8(sSnT`i$MFp^CZ80;}qyLtnUxZ#-BVaIfdYtoa`%5pNLmkRjna}Im7Tqe8xJ<@U>fWXerEj*sv-{5DPxqW3i;<-LlqT7_yZ`Fr3H`cD z<<^_YyXI#aPW{sNamsDpX=00e`F49#{mLa6VQI8=FFXGEF6R~2jy;h`UW)85|mh9>fTMe5TmJr)JI1Uk`rL;6ycfAy|W=IkGo`4mFt<79B zf93$|t>3J_cBJCOOh9^iKgKjnpyfBmnw?%sCR` z!?q1k4Qgf2o6xv9JY$Ul*Zwj@Nf>u%lt+a92c7>GLD zM+VfeXp|9`p@ir(vPIkCz}mI6VaIQ`4b@`kD&s4YK&kO+=k@k)cUp0*Mp0uJXuq&) zt}jA&GoTcZah@PQHYjF}Iy25CbiDE0r**btf@ya~s3#5xk8z;8_s zj4v$xc@qwhE=!LES2WT^>f(R`WgNgWsBm8jHHn)dVVLgR$lJcT|F)Y&p&UU@7}!$C zC@^{{du~OH{lDzr<1C8QMX8{4JDL4c5Fc&9Y@JZ&?cDMZ{a@U41{#URjU;L%qafV_|L8F&+FK8@@xZ65v!TOj zq>a@2wTW3`p5=4tlDQO+9F4b7R128^0W__L&fJ(D?ZnBNgeD0j3)8{o%&a?KvKHDR z@_DwzTf7rPqei;XPiEuWyi?v(^LoXZm8~amPwFysSrFw-vF7OcDfbtcy^+LUDP;BN z`r5mr_s^g7R3*%UAYj|IN$v%X?MvJkCbcOA+~8S6&CzhfiSd!-o)Y1oF+|z1*$Pm? zTTYSVU7WaS;)_&1nIYETr)g9ey_!#7-Z!@9O66JXE>o201&Bs@^1K+I1HD}DN9D`& z{ip(YftOl$_GW+Z?q3fE;sWNX3;YVm)e3#?Dx)gBGee`5{FQ!z&6Jq~h|tJIxB}to zFhF>pcwR*?U611a(`g`&U&UyqYtrXJl>MuVsiIQ%2u9zUZq2JiH} z(v$t|UA+5>#l_x)C{!V7Ad^yj{7On<=IW$rRDgEZ!K{$eak^EN{&LYW??vptQXE5MTBPYix@=;CPrZ6An z3Ucuw56?KVTgXsfzHX9slVZr%W?sF*^S_4OR&6i$JTRW)`9}s11QFqTlzJaY^w*rz uL6W>j>jN2yOd1|RgnMO##P?WTziPD*lc9V*iwX*42M5rcxDYPMBmM{3l#>ns literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/bitmap_io.cpp.4AB5E576AFA93983.idx b/.cache/clangd/index/bitmap_io.cpp.4AB5E576AFA93983.idx new file mode 100644 index 0000000000000000000000000000000000000000..a6d21675c2ec0a8a1c964c2190402835ef0ba093 GIT binary patch literal 2906 zcmYjT30RZo9sj-@9LYy6$oGaT$d!;K5LB84upCyRNR@~-t5A(XlP88l7HAsmf>I=) zBG1F)IUfr}XYoK=I%h4Lr31ujyLJ?7@v06Gv2Lx`)QN0+gZ(GTle~QY`~Uv_$45b~ zPFKJsh*#dsb(EW`*RlwL5aC}{wQXG?Nf6JN1mW0!s9;HHe=_x5`(?#Q;g!GY-rsZT z>g3wHrgZ;vhTyq!-l^fCjlEjcs*Zz?m}Sjfw>#x8GfO_-Yuk|5@||I*>s8U3FQ43c z`23-Ggrh79HuN?0a8FMPM>z7GkLfczEY)>Atsg9}mZh~7S$DqmdRT{R@57=+nj2*o zI-lR!z>DInxvNMH{EAUEUVb}n_Mz)k`pis&`)mD2(sDYtr)|-$ zD45i5(|o`C%To;NDVr7lnH9MnM z-@IP;W8MDWoN2nct~eddiTq}?@7%`SgYVrf+&OUU<-CZ09ya{2WMaDSQC;V}vjO+h zqYh{IA3x4-8CW@TqI+p;?5-!y>|C;0%+XD+)D-SB{cpAIVB?Cz?|*n?&B=(tuhII^ zZL5o!Q%A6ruU)k}9B2(jij&_~iLFgs z6MyCa>*g;uUG6fx{RbW+7>gBQiujoW#GL4aiBd^k7mpEw#fc$_VKWDahw@4oQ~P+s zB1Qy`?FexoIz}8Lf!N%mL)w@A;Ws8=#9(n9$*&_3Een(hL1EF<%@fZy<^BgJhZUSc zrwLE%d+E4l0wR8WfA~=A>1(< z=-{!j_A0?D1llW>isX~6^Vlp3WePJrYzk$Gv%*1%LixgcADLdP_sG7EeW&T&jOBbB z&YEGJ56D9K8JwBgmy30uXHA7pQ^>Bh&x7i8zcDiBKr>(DwiQ~%V0+>%zlx{hr4r08 z3M-OA7RO%K@P-e3E5kRiBwOZ!wpq0K^1uE6F2`&eZIc4~-LvaI)#sekV75Z0kV8oU z4xE>}=^#xCC9)EOp|Fz9ciMk@6)nKF6_FK6aGCPWho4=!cXlCW8&ixL$m`jb2Q5D( zUCC#%P_3X=1m$C)dNQz{?8#;vKohQs0ap~#MrdP!0%aV)J*aSB7ODxUiGX36xUrz6q5qbP!9rPrtYENZ zA-zEFp{lYC(N#aQx8f`oD;KAL(ye6nBY!^HhS^%7*3-Gm19Q%ln*=SG?IPJOk_*s> zt6m8h;FYvufmvl%!yON~{%elwD0j2x1k6bQ?;ytMyBCQUpIT8Z4b4D5Q+{;!dQdyI zO%;`d2a3hJD$Vf={;P*ZGvbLr}Y&`HO%1r2R z3aKO1K5b$Wn`U`kI>VhZNRGl=D6)=BfB>qd4|;DrA3KVZH42SlNEW7p&6!zu-ek>` zS>*L>jyHQIhC-E8rH{mxMi6lS<)_>W9NVY3F^o#%TyTSD5!FV)4IkVYP3~DL{4<6qGbU38 zN_fl3vOJ3uH%_hDpVC|5W?Nn(k4;`U7aSq zf1%WG?R|G$X`=+JabC1l0!HV0cig+Sr~3hZd)bja0yYVSYPq!nK)^jeEWC^167EP` zyo(_c=;6z`U$$^H_{*V?++Xf9*LK1l;Em+FvTznjc8yo&ARGaJKZP6|hsaCSaBG6S zl+)kIhdkWl$gU%Uy!pCF%0-4izBW_YTKE4NRko6<~rdLJd;$8gUh viDKItp7fC0;{9lGxFj@;5PM`qN%@;)LQDqn`3#o7A3K0aabg3xB#-z%u5X%$ literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/bitmap_io.hpp.C3324F345C5DD5D2.idx b/.cache/clangd/index/bitmap_io.hpp.C3324F345C5DD5D2.idx new file mode 100644 index 0000000000000000000000000000000000000000..9729ed5d74344e20d3769795f6ba3bd96286c81a GIT binary patch literal 1110 zcmWIYbaV4#VPJ4h@vO*AElC728H9njxTGj^K9F``WMHV6vv$HpuEPdAE?Me&HB*bt1nKrfBAKE zrs_wVl~Z4G3UhuCi)`esYWZ7xd)||KzL8z6K8w04 zS*&jR_}LhkxPi_F0u~)^9exH52*>-zdZkId*9`Yw=-0 z0!%zG-5LTKA~0!vzp0Bvviw`cm>6Nw`Yif9Fln>zfr;Vg^$&riSqxbWdB6lr`l5F- z)9+b)mxY+vVY-z>l_X%&-OrB+U1<=y2GMQAV#LD&B4EH$NW8wgMOjk-*9!$WbJ$^q}_p8D4rvMWtOt%WR3OrbHMcocK{FeO7 z#>B|Qz@osezz-%EIKiRD$im7{l$uuj4k>(@IKklx)5yc3E21j_a|A4u8JWPL3sVFO zT}Dn8P^iL$VWA2X28AX}_^AQw7j}N}ZbqQloVvm=vx7NZ_vWSw^Z|u6I5qfTW-h+I z%U^9?$5JL978Owy1(<(%Sk%PTlwe^8iy%fWaKylDsyX)HFvm3Wi$Eh)SX8)RdSUSe zbQdU|V5(v91T+K`KQLjK9YEEfc!3GSoDEbBiWHdelPeeYf84|S11K!cAub0=oD2*w ztAU1qq6elLMssk1qb2HkMQ!P&6m=dJC2l2Qm@|1$LXQWSv<-M+8X*Z0i6?9*4GRoN zGDFB2@fwN3{8*HllL&HKaZz%yK8V4R=gP_P*~8&1Gcy}20~<&P0+?Y81_o9H69Cx! BM|J=J literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/bitmap_io.hpp.E43B2188CF8AB392.idx b/.cache/clangd/index/bitmap_io.hpp.E43B2188CF8AB392.idx new file mode 100644 index 0000000000000000000000000000000000000000..a68ae99845d042c2a08bd86c75a7a0dc92ae0228 GIT binary patch literal 1108 zcmWIYbaV4zVPJ4h@vO*AElC728H9kixTGj^9*}lmWMHV6vv$HpuEPdAE? zA7-%~%ITKfp|<8|;sd$LqC`8nUsJFAnDf8EaLzuDV%^b@QEFk<%Y7oHQeJ&-ZI~_e63R7gy#cg#%qEA)hsi z)omX?8v_$J(9uA^qQkAj&%goUc;8sBH0isCpEwgAHv@|SivcT`fJs~ZnI3d4J}gLp zi3g@zLqJ0WCav!`b&*Jxf2$Z1BTQPKMV|*IZT3AdG5oy#A+R)yA&Vgon1D%N^iF2_ zJ&W(M5EDC0x00xm1Wda7`7xm@4MNu-x{X+jcvwILOqzSuMGMo1Y>x$)cwxHLIMoDU z(#Q8t{%~jd#!q}q96*ohO6kgj37E9U?+5FCHF*9MVB&=7R^e8G2TQJ~+X08)l7HEl z7`Yf&6xbE`!2|;*IMf(fSQ&~^(~93Ag)b8)I9y>Gd02EsbR}SpfQ2$66F78XieRD3 z$jJfBC4VQ^DhsJnz))0EbL$r#K;AX7?@2p#~vK!m}Y(vXru~@3KvW-EWUv5 z0>u+dH7uThhJfM+CJeI!s2UV6FkzUpfvQ1~0uz36<--1tdw72Ug~d6<Hu50D)&n A$^ZZW literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/context.c.91BC96CF7BD16B3C.idx b/.cache/clangd/index/context.c.91BC96CF7BD16B3C.idx new file mode 100644 index 0000000000000000000000000000000000000000..8429ab327c34bc62408e0d8a492069da29d42d94 GIT binary patch literal 13008 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 r4o7-^u~-Lj4pxZ literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/context.c.ACB36D59D1DFD31C.idx b/.cache/clangd/index/context.c.ACB36D59D1DFD31C.idx new file mode 100644 index 0000000000000000000000000000000000000000..9626157e66a6190e3010ea0626ba5a28b2f1d26c GIT binary patch literal 13008 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 X*MLS95h11IvQR|`qfDT~B;n+LJV>lX literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/context.hpp.0247079C4DA06A0E.idx b/.cache/clangd/index/context.hpp.0247079C4DA06A0E.idx new file mode 100644 index 0000000000000000000000000000000000000000..3fe8fed12d27b6f45bd6bff25a78fee5c90cefb3 GIT binary patch literal 1544 zcmY+EZ%kWN7{*Tzr={(^x4osQQilrLs+3{XfgIE>C^dd?+J!JG8ld!OgL z?|t9*{L&rU5(#1 zS~6nax$@b}p|f+72d>o5hmWPY-TP`1IH_&i=duF0%c6_w1>G6`o z@7%PUzy4e5sxLj?;$69Di9|D*+t1(jUDK^E0uS~re^cKzm}}Se7aTnJ!PRuGy}?BZ zd3v<`NqyX}s8o@8`TSx*CFmj6)t5a%?X}0s-gjE4Ng}MYu+(8J#AetgW`3gLhZ{#O zC@v2*$%F-1Kr$A@PuE?m{-~|LOr>t5kJuvl^sis;^6xCKy~9E6JUYHHUTQ3ee&na= zXBRt8Bve{}Xx*l}VbA}2^Uz4-ARJ-PvQ&tbi} z(^Jx^QYY+?63UnM?gNdvqX+KauTl!T%2wq-bmqg8`q)(Wz-r$WtU_X9fqmyEW0vsP z=y40NA-Yl$43o_u z0wmxr*$onQ{g{0*^Zo9SY>XbJ%**l1Yj0vS>)whgHei0TfyPKJQ}v(STZNV}e#B;jzVWA7a5S z|B_%9n=pJX3sxa7|N4vm>BFvbyeG}C1+hzJI@7I~+LdBU)z<#*FL{+w7PVnK;M`pZfjMeFL{<`R*8t$*2bd;sprYu^Ut5vcMd2sX)w!n#;swiJ^80Jp)ANB{r; literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/context.hpp.30BB9F8B4501681D.idx b/.cache/clangd/index/context.hpp.30BB9F8B4501681D.idx new file mode 100644 index 0000000000000000000000000000000000000000..e2927162c9be87c9896253220879535272bdb568 GIT binary patch literal 1544 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 Pv9VS*Z?96zZDs!h*v0rb literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/egl_context.c.CD53B506C4A00245.idx b/.cache/clangd/index/egl_context.c.CD53B506C4A00245.idx new file mode 100644 index 0000000000000000000000000000000000000000..3bada125527641f36f3b1b669b33aa03e34945c2 GIT binary patch literal 18214 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 WOoHLZGp1i*fBD6)KlORU*#7|}n+Vwe literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/egl_context.h.B2730FCAFD4752C9.idx b/.cache/clangd/index/egl_context.h.B2730FCAFD4752C9.idx new file mode 100644 index 0000000000000000000000000000000000000000..55853a93ca65b9c3ec49717cd1aed839a287a0da GIT binary patch literal 8170 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 UoZ-harXQi{n)l~>(-g-34?1TDUH||9 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/geometry.hpp.5CBEA5776F164981.idx b/.cache/clangd/index/geometry.hpp.5CBEA5776F164981.idx new file mode 100644 index 0000000000000000000000000000000000000000..490f4fc39ac48385f10bfb666fa90b50ed2a94c9 GIT binary patch literal 1836 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%0DXZnvs$F6CXGNlR$F$grt-auHQetT`Qu-+ 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

Buffer swapping

-

See Buffer swapping in the window guide.

+

See Buffer swapping in the window guide.

OpenGL and OpenGL ES extensions

-

One of the benefits of OpenGL and OpenGL ES is their extensibility. Hardware vendors may include extensions in their implementations that extend the API before that functionality is included in a new version of the OpenGL or OpenGL ES specification, and some extensions are never included and remain as extensions until they become obsolete.

-

An extension is defined by:

+

One of the benefits of OpenGL and OpenGL ES is their extensibility. Hardware vendors may include extensions in their implementations that extend the API before that functionality is included in a new version of the OpenGL or OpenGL ES specification, and some extensions are never included and remain as extensions until they become obsolete.

+

An extension is defined by:

  • An extension name (e.g. GL_ARB_gl_spirv)
  • New OpenGL tokens (e.g. GL_SPIR_V_BINARY_ARB)
  • New OpenGL functions (e.g. glSpecializeShaderARB)
-

Note the ARB affix, which stands for Architecture Review Board and is used for official extensions. The extension above was created by the ARB, but there are many different affixes, like NV for Nvidia and AMD for, well, AMD. Any group may also use the generic EXT affix. Lists of extensions, together with their specifications, can be found at the OpenGL Registry and OpenGL ES Registry.

+

Note the ARB affix, which stands for Architecture Review Board and is used for official extensions. The extension above was created by the ARB, but there are many different affixes, like NV for Nvidia and AMD for, well, AMD. Any group may also use the generic EXT affix. Lists of extensions, together with their specifications, can be found at the OpenGL Registry and OpenGL ES Registry.

Loading extension with a loader library

-

An extension loader library is the easiest and best way to access both OpenGL and OpenGL ES extensions and modern versions of the core OpenGL or OpenGL ES APIs. They will take care of all the details of declaring and loading everything you need. One such library is glad and there are several others.

-

The following example will use glad but all extension loader libraries work similarly.

-

First you need to generate the source files using the glad Python script. This example generates a loader for any version of OpenGL, which is the default for both GLFW and glad, but loaders for OpenGL ES, as well as loaders for specific API versions and extension sets can be generated. The generated files are written to the output directory.

+

An extension loader library is the easiest and best way to access both OpenGL and OpenGL ES extensions and modern versions of the core OpenGL or OpenGL ES APIs. They will take care of all the details of declaring and loading everything you need. One such library is glad and there are several others.

+

The following example will use glad but all extension loader libraries work similarly.

+

First you need to generate the source files using the glad Python script. This example generates a loader for any version of OpenGL, which is the default for both GLFW and glad, but loaders for OpenGL ES, as well as loaders for specific API versions and extension sets can be generated. The generated files are written to the output directory.

python main.py --generator c --no-loader --out-path output
-

The --no-loader option is added because GLFW already provides a function for loading OpenGL and OpenGL ES function pointers, one that automatically uses the selected context creation API, and glad can call this instead of having to implement its own. There are several other command-line options as well. See the glad documentation for details.

-

Add the generated output/src/glad.c, output/include/glad/glad.h and output/include/KHR/khrplatform.h files to your build. Then you need to include the glad header file, which will replace the OpenGL header of your development environment. By including the glad header before the GLFW header, it suppresses the development environment's OpenGL or OpenGL ES header.

+

The --no-loader option is added because GLFW already provides a function for loading OpenGL and OpenGL ES function pointers, one that automatically uses the selected context creation API, and glad can call this instead of having to implement its own. There are several other command-line options as well. See the glad documentation for details.

+

Add the generated output/src/glad.c, output/include/glad/glad.h and output/include/KHR/khrplatform.h files to your build. Then you need to include the glad header file, which will replace the OpenGL header of your development environment. By including the glad header before the GLFW header, it suppresses the development environment's OpenGL or OpenGL ES header.

#include <glad/glad.h>
#include <GLFW/glfw3.h>
The header of the GLFW 3 API.
-

Finally you need to initialize glad once you have a suitable current context.

+

Finally, you need to initialize glad once you have a suitable current context.

window = glfwCreateWindow(640, 480, "My Window", NULL, NULL);
if (!window)
{
@@ -175,44 +182,44 @@ Loading extension with a loader library
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
GLFWglproc glfwGetProcAddress(const char *procname)
Returns the address of the specified function for the current context.
-

Once glad has been loaded, you have access to all OpenGL core and extension functions supported by both the context you created and the glad loader you generated and you are ready to start rendering.

-

You can specify a minimum required OpenGL or OpenGL ES version with context hints. If your needs are more complex, you can check the actual OpenGL or OpenGL ES version with context attributes, or you can check whether a specific version is supported by the current context with the GLAD_GL_VERSION_x_x booleans.

+

Once glad has been loaded, you have access to all OpenGL core and extension functions supported by both the context you created and the glad loader you generated. After that, you are ready to start rendering.

+

You can specify a minimum required OpenGL or OpenGL ES version with context hints. If your needs are more complex, you can check the actual OpenGL or OpenGL ES version with context attributes, or you can check whether a specific version is supported by the current context with the GLAD_GL_VERSION_x_x booleans.

if (GLAD_GL_VERSION_3_2)
{
// Call OpenGL 3.2+ specific code
}
-

To check whether a specific extension is supported, use the GLAD_GL_xxx booleans.

+

To check whether a specific extension is supported, use the GLAD_GL_xxx booleans.

if (GLAD_GL_ARB_gl_spirv)
{
// Use GL_ARB_gl_spirv
}

Loading extensions manually

-

Do not use this technique unless it is absolutely necessary. An extension loader library will save you a ton of tedious, repetitive, error prone work.

-

To use a certain extension, you must first check whether the context supports that extension and then, if it introduces new functions, retrieve the pointers to those functions. GLFW provides glfwExtensionSupported and glfwGetProcAddress for manual loading of extensions and new API functions.

-

This section will demonstrate manual loading of OpenGL extensions. The loading of OpenGL ES extensions is identical except for the name of the extension header.

+

Do not use this technique unless it is absolutely necessary. An extension loader library will save you a ton of tedious, repetitive, error prone work.

+

To use a certain extension, you must first check whether the context supports that extension and then, if it introduces new functions, retrieve the pointers to those functions. GLFW provides glfwExtensionSupported and glfwGetProcAddress for manual loading of extensions and new API functions.

+

This section will demonstrate manual loading of OpenGL extensions. The loading of OpenGL ES extensions is identical except for the name of the extension header.

The glext.h header

-

The glext.h extension header is a continually updated file that defines the interfaces for all OpenGL extensions. The latest version of this can always be found at the OpenGL Registry. There are also extension headers for the various versions of OpenGL ES at the OpenGL ES Registry. It it strongly recommended that you use your own copy of the extension header, as the one included in your development environment may be several years out of date and may not include the extensions you wish to use.

-

The header defines function pointer types for all functions of all extensions it supports. These have names like PFNGLSPECIALIZESHADERARBPROC (for glSpecializeShaderARB), i.e. the name is made uppercase and PFN (pointer to function) and PROC (procedure) are added to the ends.

-

To include the extension header, define GLFW_INCLUDE_GLEXT before including the GLFW header.

+

The glext.h extension header is a continually updated file that defines the interfaces for all OpenGL extensions. The latest version of this can always be found at the OpenGL Registry. There are also extension headers for the various versions of OpenGL ES at the OpenGL ES Registry. It it strongly recommended that you use your own copy of the extension header, as the one included in your development environment may be several years out of date and may not include the extensions you wish to use.

+

The header defines function pointer types for all functions of all extensions it supports. These have names like PFNGLSPECIALIZESHADERARBPROC (for glSpecializeShaderARB), i.e. the name is made uppercase and PFN (pointer to function) and PROC (procedure) are added to the ends.

+

To include the extension header, define GLFW_INCLUDE_GLEXT before including the GLFW header.

#define GLFW_INCLUDE_GLEXT
#include <GLFW/glfw3.h>

Checking for extensions

-

A given machine may not actually support the extension (it may have older drivers or a graphics card that lacks the necessary hardware features), so it is necessary to check at run-time whether the context supports the extension. This is done with glfwExtensionSupported.

+

A given machine may not actually support the extension (it may have older drivers or a graphics card that lacks the necessary hardware features), so it is necessary to check at run-time whether the context supports the extension. This is done with glfwExtensionSupported.

if (glfwExtensionSupported("GL_ARB_gl_spirv"))
{
// The extension is supported by the current context
}
int glfwExtensionSupported(const char *extension)
Returns whether the specified extension is available.
-

The argument is a null terminated ASCII string with the extension name. If the extension is supported, glfwExtensionSupported returns GLFW_TRUE, otherwise it returns GLFW_FALSE.

+

The argument is a null terminated ASCII string with the extension name. If the extension is supported, glfwExtensionSupported returns GLFW_TRUE, otherwise it returns GLFW_FALSE.

Fetching function pointers

-

Many extensions, though not all, require the use of new OpenGL functions. These functions often do not have entry points in the client API libraries of your operating system, making it necessary to fetch them at run time. You can retrieve pointers to these functions with glfwGetProcAddress.

+

Many extensions, though not all, require the use of new OpenGL functions. These functions often do not have entry points in the client API libraries of your operating system, making it necessary to fetch them at run time. You can retrieve pointers to these functions with glfwGetProcAddress.

PFNGLSPECIALIZESHADERARBPROC pfnSpecializeShaderARB = glfwGetProcAddress("glSpecializeShaderARB");
-

In general, you should avoid giving the function pointer variables the (exact) same name as the function, as this may confuse your linker. Instead, you can use a different prefix, like above, or some other naming scheme.

-

Now that all the pieces have been introduced, here is what they might look like when used together.

+

In general, you should avoid giving the function pointer variables the (exact) same name as the function, as this may confuse your linker. Instead, you can use a different prefix, like above, or some other naming scheme.

+

Now that all the pieces have been introduced, here is what they might look like when used together.

#define GLFW_INCLUDE_GLEXT
#include <GLFW/glfw3.h>
@@ -244,7 +251,7 @@ Fetching function pointers
diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/deprecated.html b/src/lib/src/vendor/glfw-3.4/docs/html/deprecated.html similarity index 84% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/deprecated.html rename to src/lib/src/vendor/glfw-3.4/docs/html/deprecated.html index f516c9a..bc0603c 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/deprecated.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/deprecated.html @@ -4,7 +4,7 @@ - + GLFW: Deprecated List @@ -28,10 +28,10 @@ - + @@ -54,14 +54,21 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
-
Deprecated List
+
Deprecated List
@@ -74,7 +81,7 @@ $(function() {
diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/dir_4351554941a2744586042c1cf3cf139a.html b/src/lib/src/vendor/glfw-3.4/docs/html/dir_13577e2d8b9423099662de029791bd7d.html similarity index 72% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/dir_4351554941a2744586042c1cf3cf139a.html rename to src/lib/src/vendor/glfw-3.4/docs/html/dir_13577e2d8b9423099662de029791bd7d.html index bb36bd1..26931ee 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/dir_4351554941a2744586042c1cf3cf139a.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/dir_13577e2d8b9423099662de029791bd7d.html @@ -4,8 +4,8 @@ - -GLFW: glfw-3.3.8 Directory Reference + +GLFW: glfw-3.4 Directory Reference @@ -28,10 +28,10 @@
- + @@ -54,32 +54,39 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
-
glfw-3.3.8 Directory Reference
+
glfw-3.4 Directory Reference
- + - +

Directories

directory  docs
 docs
 
directory  include
 include
 
diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/dir_1dfd43b3952c5bc1ba15d15b12afff7b.html b/src/lib/src/vendor/glfw-3.4/docs/html/dir_7f92719a7fe62e5b064f87d7a3c220b1.html similarity index 73% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/dir_1dfd43b3952c5bc1ba15d15b12afff7b.html rename to src/lib/src/vendor/glfw-3.4/docs/html/dir_7f92719a7fe62e5b064f87d7a3c220b1.html index ec0844b..252c680 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/dir_1dfd43b3952c5bc1ba15d15b12afff7b.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/dir_7f92719a7fe62e5b064f87d7a3c220b1.html @@ -4,7 +4,7 @@ - + GLFW: GLFW Directory Reference @@ -28,10 +28,10 @@ - + @@ -54,14 +54,21 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -71,17 +78,17 @@ $(function() { - + - +

Files

file  glfw3.h [code]
 glfw3.h
 The header of the GLFW 3 API.
 
file  glfw3native.h [code]
 glfw3native.h
 The header of the native access functions.
 
diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/dir_fda32cf7bec00275262cb8799a618f76.html b/src/lib/src/vendor/glfw-3.4/docs/html/dir_a788ef6c2b1e5b367804e0b6ccfd6f11.html similarity index 78% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/dir_fda32cf7bec00275262cb8799a618f76.html rename to src/lib/src/vendor/glfw-3.4/docs/html/dir_a788ef6c2b1e5b367804e0b6ccfd6f11.html index 3464fd1..4e07125 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/dir_fda32cf7bec00275262cb8799a618f76.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/dir_a788ef6c2b1e5b367804e0b6ccfd6f11.html @@ -4,7 +4,7 @@ - + GLFW: docs Directory Reference @@ -28,10 +28,10 @@ - + @@ -54,14 +54,21 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -71,7 +78,7 @@ $(function() {
diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/dir_f6ba4c3dca55a8d4e7d63c8235e0ad43.html b/src/lib/src/vendor/glfw-3.4/docs/html/dir_b11153cd0f4fd04a7564cc166f482635.html similarity index 76% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/dir_f6ba4c3dca55a8d4e7d63c8235e0ad43.html rename to src/lib/src/vendor/glfw-3.4/docs/html/dir_b11153cd0f4fd04a7564cc166f482635.html index 4a9295a..583557a 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/dir_f6ba4c3dca55a8d4e7d63c8235e0ad43.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/dir_b11153cd0f4fd04a7564cc166f482635.html @@ -4,7 +4,7 @@ - + GLFW: include Directory Reference @@ -28,10 +28,10 @@ - + @@ -54,14 +54,21 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -71,13 +78,13 @@ $(function() { - +

Directories

directory  GLFW
 GLFW
 
diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/doc.svg b/src/lib/src/vendor/glfw-3.4/docs/html/doc.svg new file mode 100644 index 0000000..0b928a5 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/doc.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/docd.svg b/src/lib/src/vendor/glfw-3.4/docs/html/docd.svg new file mode 100644 index 0000000..ac18b27 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/docd.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/doxygen.css b/src/lib/src/vendor/glfw-3.4/docs/html/doxygen.css similarity index 79% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/doxygen.css rename to src/lib/src/vendor/glfw-3.4/docs/html/doxygen.css index 2010785..8cff99e 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/doxygen.css +++ b/src/lib/src/vendor/glfw-3.4/docs/html/doxygen.css @@ -1,26 +1,33 @@ -/* The standard CSS for doxygen 1.9.4 */ +/* The standard CSS for doxygen 1.9.8*/ -body, table, div, p, dl { - font: 400 14px/22px Roboto,sans-serif; +body { + background-color: white; + color: black; } -p.reference, p.definition { - font: 400 14px/22px Roboto,sans-serif; +body, table, div, p, dl { + font-weight: 400; + font-size: 14px; + font-family: Roboto,sans-serif; + line-height: 22px; } /* @group Heading Levels */ -h1.groupheader { - font-size: 150%; -} - .title { - font: 400 14px/28px Roboto,sans-serif; + font-weight: 400; + font-size: 14px; + font-family: Roboto,sans-serif; + line-height: 28px; font-size: 150%; font-weight: bold; margin: 10px 2px; } +h1.groupheader { + font-size: 150%; +} + h2.groupheader { border-bottom: 1px solid #879ECB; color: #354C7B; @@ -53,15 +60,6 @@ dt { font-weight: bold; } -ul.multicol { - -moz-column-gap: 1em; - -webkit-column-gap: 1em; - column-gap: 1em; - -moz-column-count: 3; - -webkit-column-count: 3; - column-count: 3; -} - p.startli, p.startdd { margin-top: 2px; } @@ -113,7 +111,6 @@ h3.version { } div.navtab { - border-right: 1px solid #A3B4D7; padding-right: 15px; text-align: right; line-height: 110%; @@ -127,6 +124,7 @@ td.navtab { padding-right: 6px; padding-left: 6px; } + td.navtabHL { background-image: url('tab_a.png'); background-repeat:repeat-x; @@ -135,7 +133,7 @@ td.navtabHL { } td.navtabHL a, td.navtabHL a:visited { - color: #fff; + color: white; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } @@ -151,6 +149,12 @@ div.qindex{ color: #A0A0A0; } +#main-menu a:focus { + outline: auto; + z-index: 10; + position: relative; +} + dt.alphachar{ font-size: 180%; font-weight: bold; @@ -176,6 +180,10 @@ dt.alphachar{ line-height: 1.15em; } +.classindex dl.even { + background-color: white; +} + .classindex dl.odd { background-color: #F8F9FC; } @@ -209,10 +217,6 @@ a:hover { text-decoration: underline; } -.contents a.qindexHL:visited { - color: #FFFFFF; -} - a.el { font-weight: bold; } @@ -221,11 +225,11 @@ a.elRef { } a.code, a.code:visited, a.line, a.line:visited { - color: #4665A2; + color: #4665A2; } a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { - color: #4665A2; + color: #4665A2; } a.code.hl_class { /* style for links to class names in code snippets */ } @@ -265,6 +269,16 @@ ul { overflow: visible; } +ul.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; + column-count: 3; + list-style-type: none; +} + #side-nav ul { overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ } @@ -283,28 +297,30 @@ ul { pre.fragment { border: 1px solid #C4CFE5; background-color: #FBFCFD; + color: black; padding: 4px 6px; margin: 4px 8px 4px 2px; overflow: auto; word-wrap: break-word; font-size: 9pt; line-height: 125%; - font-family: monospace, fixed; + font-family: 'JetBrains Mono',Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace,fixed; font-size: 105%; } div.fragment { - padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ - margin: 4px 8px 4px 2px; + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; + color: black; background-color: #FBFCFD; border: 1px solid #C4CFE5; } div.line { - font-family: monospace, fixed; + font-family: 'JetBrains Mono',Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace,fixed; font-size: 13px; min-height: 13px; - line-height: 1.0; + line-height: 1.2; text-wrap: unrestricted; white-space: -moz-pre-wrap; /* Moz */ white-space: -pre-wrap; /* Opera 4-6 */ @@ -337,20 +353,35 @@ div.line.glow { box-shadow: 0 0 10px cyan; } +span.fold { + margin-left: 5px; + margin-right: 1px; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; + display: inline-block; + width: 12px; + height: 12px; + background-repeat:no-repeat; + background-position:center; +} span.lineno { padding-right: 4px; margin-right: 9px; text-align: right; - border-right: 2px solid #0F0; + border-right: 2px solid #00FF00; + color: black; background-color: #E8E8E8; white-space: pre; } -span.lineno a { +span.lineno a, span.lineno a:visited { + color: #4665A2; background-color: #D8D8D8; } span.lineno a:hover { + color: #4665A2; background-color: #C8C8C8; } @@ -363,24 +394,6 @@ span.lineno a:hover { user-select: none; } -div.ah, span.ah { - background-color: black; - font-weight: bold; - color: #FFFFFF; - margin-bottom: 3px; - margin-top: 3px; - padding: 0.2em; - border: solid thin #333; - border-radius: 0.5em; - -webkit-border-radius: .5em; - -moz-border-radius: .5em; - box-shadow: 2px 2px 3px #999; - -webkit-box-shadow: 2px 2px 3px #999; - -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; - background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); - background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); -} - div.classindex ul { list-style: none; padding-left: 0; @@ -402,7 +415,6 @@ div.groupText { } body { - background-color: white; color: black; margin: 0; } @@ -413,31 +425,17 @@ div.contents { margin-right: 8px; } -td.indexkey { - background-color: #EBEFF6; - font-weight: bold; - border: 1px solid #C4CFE5; - margin: 2px 0px 2px 0; - padding: 2px 10px; - white-space: nowrap; - vertical-align: top; -} - -td.indexvalue { - background-color: #EBEFF6; - border: 1px solid #C4CFE5; - padding: 2px 10px; - margin: 2px 0px; -} - -tr.memlist { - background-color: #EEF1F7; -} - p.formulaDsp { text-align: center; } +img.dark-mode-visible { + display: none; +} +img.light-mode-visible { + display: none; +} + img.formulaDsp { } @@ -465,6 +463,7 @@ address.footer { img.footer { border: 0px; vertical-align: middle; + width: 104px; } .compoundTemplParams { @@ -476,47 +475,51 @@ img.footer { /* @group Code Colorization */ span.keyword { - color: #008000 + color: #008000; } span.keywordtype { - color: #604020 + color: #604020; } span.keywordflow { - color: #e08000 + color: #E08000; } span.comment { - color: #800000 + color: #800000; } span.preprocessor { - color: #806020 + color: #806020; } span.stringliteral { - color: #002080 + color: #002080; } span.charliteral { - color: #008080 + color: #008080; +} + +span.xmlcdata { + color: black; } span.vhdldigit { - color: #ff00ff + color: #FF00FF; } span.vhdlchar { - color: #000000 + color: #000000; } span.vhdlkeyword { - color: #700070 + color: #700070; } span.vhdllogic { - color: #ff0000 + color: #FF0000; } blockquote { @@ -526,34 +529,8 @@ blockquote { padding: 0 12px 0 16px; } -blockquote.DocNodeRTL { - border-left: 0; - border-right: 2px solid #9CAFD4; - margin: 0 4px 0 24px; - padding: 0 16px 0 12px; -} - /* @end */ -/* -.search { - color: #003399; - font-weight: bold; -} - -form.search { - margin-bottom: 0px; - margin-top: 0px; -} - -input.search { - font-size: 75%; - color: #000080; - font-weight: normal; - background-color: #e8eef2; -} -*/ - td.tiny { font-size: 75%; } @@ -561,11 +538,12 @@ td.tiny { .dirtab { padding: 4px; border-collapse: collapse; - border: 1px solid #A3B4D7; + border: 1px solid #2D4068; } th.dirtab { - background: #EBEFF6; + background-color: #374F7F; + color: #FFFFFF; font-weight: bold; } @@ -675,15 +653,6 @@ table.memberdecls { margin-left: 9px; } -.memnav { - background-color: #EBEFF6; - border: 1px solid #A3B4D7; - text-align: center; - margin: 2px; - margin-right: 15px; - padding: 2px; -} - .mempage { width: 100%; } @@ -723,33 +692,24 @@ table.memberdecls { font-weight: bold; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); background-color: #DFE5F1; - /* opera specific markup */ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); border-top-right-radius: 4px; - /* firefox specific markup */ - -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; - -moz-border-radius-topright: 4px; - /* webkit specific markup */ - -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); - -webkit-border-top-right-radius: 4px; - } .overload { - font-family: "courier new",courier,monospace; + font-family: 'JetBrains Mono',Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace,fixed; font-size: 65%; } .memdoc, dl.reflist dd { - border-bottom: 1px solid #A8B8D9; - border-left: 1px solid #A8B8D9; - border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; padding: 6px 10px 2px 10px; - background-color: #FBFCFD; border-top-width: 0; background-image:url('nav_g.png'); background-repeat:repeat-x; - background-color: #FFFFFF; + background-color: white; /* opera specific markup */ border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; @@ -795,20 +755,20 @@ dl.reflist dd { .params, .retval, .exception, .tparams { margin-left: 0px; padding-left: 0px; -} +} .params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { font-weight: bold; vertical-align: top; } - + .params .paramtype, .tparams .paramtype { font-style: italic; vertical-align: top; -} - +} + .params .paramdir, .tparams .paramdir { - font-family: "courier new",courier,monospace; + font-family: 'JetBrains Mono',Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace,fixed; vertical-align: top; } @@ -892,9 +852,14 @@ div.directory { border-left: 1px solid rgba(0,0,0,0.05); } +.directory tr.odd { + padding-left: 6px; + background-color: #F8F9FC; +} + .directory tr.even { padding-left: 6px; - background-color: #F7F8FB; + background-color: white; } .directory img { @@ -930,7 +895,8 @@ div.directory { } .icon { - font-family: Arial, Helvetica; + font-family: Arial,Helvetica; + line-height: normal; font-weight: bold; font-size: 12px; height: 14px; @@ -954,8 +920,7 @@ div.directory { width: 24px; height: 18px; margin-bottom: 4px; - background-image:url('folderopen.png'); - background-position: 0px -4px; + background-image:url('folderopen.svg'); background-repeat: repeat-y; vertical-align:top; display: inline-block; @@ -965,8 +930,7 @@ div.directory { width: 24px; height: 18px; margin-bottom: 4px; - background-image:url('folderclosed.png'); - background-position: 0px -4px; + background-image:url('folderclosed.svg'); background-repeat: repeat-y; vertical-align:top; display: inline-block; @@ -976,17 +940,13 @@ div.directory { width: 24px; height: 18px; margin-bottom: 4px; - background-image:url('doc.png'); + background-image:url('doc.svg'); background-position: 0px -4px; background-repeat: repeat-y; vertical-align:top; display: inline-block; } -table.directory { - font: 400 14px Roboto,sans-serif; -} - /* @end */ div.dynheader { @@ -1028,15 +988,10 @@ table.doxtable th { } table.fieldtable { - /*width: 100%;*/ margin-bottom: 10px; border: 1px solid #A8B8D9; border-spacing: 0px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; border-radius: 4px; - -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; - -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); } @@ -1057,13 +1012,12 @@ table.fieldtable { .fieldtable td.fielddoc { border-bottom: 1px solid #A8B8D9; - /*width: 100%;*/ } .fieldtable td.fielddoc p:first-child { margin-top: 0px; -} - +} + .fieldtable td.fielddoc p:last-child { margin-bottom: 2px; } @@ -1073,7 +1027,7 @@ table.fieldtable { } .fieldtable th { - background-image:url('nav_f.png'); + background-image: url('nav_f.png'); background-repeat:repeat-x; background-color: #E2E8F2; font-size: 90%; @@ -1082,10 +1036,6 @@ table.fieldtable { padding-top: 5px; text-align:left; font-weight: 400; - -moz-border-radius-topleft: 4px; - -moz-border-radius-topright: 4px; - -webkit-border-top-left-radius: 4px; - -webkit-border-top-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom: 1px solid #A8B8D9; @@ -1105,12 +1055,12 @@ table.fieldtable { .navpath ul { font-size: 11px; - background-image:url('tab_b.png'); + background-image: url('tab_b.png'); background-repeat:repeat-x; background-position: 0 -5px; height:30px; line-height:30px; - color:#8AA0CC; + color:#283A5D; border:solid 1px #C2CDE4; overflow:hidden; margin:0px; @@ -1126,7 +1076,7 @@ table.fieldtable { background-image:url('bc_s.png'); background-repeat:no-repeat; background-position:right; - color:#364D7C; + color: #364D7C; } .navpath li.navelem a @@ -1138,12 +1088,13 @@ table.fieldtable { color: #283A5D; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); - text-decoration: none; + text-decoration: none; } .navpath li.navelem a:hover { - color:#6884BD; + color: white; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } .navpath li.footer @@ -1155,7 +1106,7 @@ table.fieldtable { background-image:none; background-repeat:no-repeat; background-position:right; - color:#364D7C; + color: #2A3D61; font-size: 8pt; } @@ -1167,7 +1118,7 @@ div.summary padding-right: 5px; width: 50%; text-align: right; -} +} div.summary a { @@ -1182,7 +1133,7 @@ table.classindex margin-right: 3%; width: 94%; border: 0; - border-spacing: 0; + border-spacing: 0; padding: 0; } @@ -1200,7 +1151,7 @@ div.ingroups a div.header { - background-image:url('nav_h.png'); + background-image: url('nav_h.png'); background-repeat:repeat-x; background-color: #F9FAFC; margin: 0px; @@ -1227,11 +1178,6 @@ dl.section { padding-left: 0px; } -dl.section.DocNodeRTL { - margin-right: 0px; - padding-right: 0px; -} - dl.note { margin-left: -7px; padding-left: 3px; @@ -1239,16 +1185,6 @@ dl.note { border-color: #D0C000; } -dl.note.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #D0C000; -} - dl.warning, dl.attention { margin-left: -7px; padding-left: 3px; @@ -1256,16 +1192,6 @@ dl.warning, dl.attention { border-color: #FF0000; } -dl.warning.DocNodeRTL, dl.attention.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #FF0000; -} - dl.pre, dl.post, dl.invariant { margin-left: -7px; padding-left: 3px; @@ -1273,16 +1199,6 @@ dl.pre, dl.post, dl.invariant { border-color: #00D000; } -dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #00D000; -} - dl.deprecated { margin-left: -7px; padding-left: 3px; @@ -1290,16 +1206,6 @@ dl.deprecated { border-color: #505050; } -dl.deprecated.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #505050; -} - dl.todo { margin-left: -7px; padding-left: 3px; @@ -1307,16 +1213,6 @@ dl.todo { border-color: #00C0E0; } -dl.todo.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #00C0E0; -} - dl.test { margin-left: -7px; padding-left: 3px; @@ -1324,16 +1220,6 @@ dl.test { border-color: #3030E0; } -dl.test.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #3030E0; -} - dl.bug { margin-left: -7px; padding-left: 3px; @@ -1341,16 +1227,6 @@ dl.bug { border-color: #C08050; } -dl.bug.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #C08050; -} - dl.section dd { margin-bottom: 6px; } @@ -1381,21 +1257,24 @@ dl.section dd { #projectname { - font: 200% Tahoma, Arial,sans-serif; + font-size: 200%; + font-family: Tahoma,Arial,sans-serif; margin: 0px; padding: 2px 0px; } - + #projectbrief { - font: 90% Tahoma, Arial,sans-serif; + font-size: 90%; + font-family: Tahoma,Arial,sans-serif; margin: 0px; padding: 0px; } #projectnumber { - font: 50% Tahoma, Arial,sans-serif; + font-size: 50%; + font-family: 50% Tahoma,Arial,sans-serif; margin: 0px; padding: 0px; } @@ -1406,6 +1285,7 @@ dl.section dd { margin: 0px; width: 100%; border-bottom: 1px solid #5373B4; + background-color: white; } .image @@ -1438,11 +1318,6 @@ dl.section dd { font-weight: bold; } -div.zoom -{ - border: 1px solid #90A5CE; -} - dl.citelist { margin-bottom:50px; } @@ -1473,27 +1348,16 @@ div.toc { width: 200px; } -.PageDocRTL-title div.toc { - float: left !important; - text-align: right; -} - div.toc li { - background: url("bdwn.png") no-repeat scroll 0 5px transparent; - font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + background: url("data:image/svg+xml;utf8,&%238595;") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,'DejaVu Sans',Geneva,sans-serif; margin-top: 5px; padding-left: 10px; padding-top: 2px; } -.PageDocRTL-title div.toc li { - background-position-x: right !important; - padding-left: 0 !important; - padding-right: 10px; -} - div.toc h3 { - font: bold 12px/1.2 Arial,FreeSans,sans-serif; + font: bold 12px/1.2 Verdana,'DejaVu Sans',Geneva,sans-serif; color: #4665A2; border-bottom: 0 none; margin: 0; @@ -1503,7 +1367,7 @@ div.toc ul { list-style: none outside none; border: medium none; padding: 0px; -} +} div.toc li.level1 { margin-left: 0px; @@ -1514,11 +1378,11 @@ div.toc li.level2 { } div.toc li.level3 { - margin-left: 30px; + margin-left: 15px; } div.toc li.level4 { - margin-left: 45px; + margin-left: 15px; } span.emoji { @@ -1531,26 +1395,6 @@ span.obfuscator { display: none; } -.PageDocRTL-title div.toc li.level1 { - margin-left: 0 !important; - margin-right: 0; -} - -.PageDocRTL-title div.toc li.level2 { - margin-left: 0 !important; - margin-right: 15px; -} - -.PageDocRTL-title div.toc li.level3 { - margin-left: 0 !important; - margin-right: 30px; -} - -.PageDocRTL-title div.toc li.level4 { - margin-left: 0 !important; - margin-right: 45px; -} - .inherit_header { font-weight: bold; color: gray; @@ -1586,6 +1430,7 @@ tr.heading h2 { #powerTip { cursor: default; /*white-space: nowrap;*/ + color: black; background-color: white; border: 1px solid gray; border-radius: 4px 4px 4px 4px; @@ -1608,6 +1453,10 @@ tr.heading h2 { font-weight: bold; } +#powerTip a { + color: #4665A2; +} + #powerTip div.ttname { font-weight: bold; } @@ -1619,7 +1468,9 @@ tr.heading h2 { #powerTip div { margin: 0px; padding: 0px; - font: 12px/16px Roboto,sans-serif; + font-size: 12px; + font-family: Roboto,sans-serif; + line-height: 16px; } #powerTip:before, #powerTip:after { @@ -1664,12 +1515,12 @@ tr.heading h2 { } #powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { - border-top-color: #FFFFFF; + border-top-color: white; border-width: 10px; margin: 0px -10px; } -#powerTip.n:before { - border-top-color: #808080; +#powerTip.n:before, #powerTip.ne:before, #powerTip.nw:before { + border-top-color: gray; border-width: 11px; margin: 0px -11px; } @@ -1692,13 +1543,13 @@ tr.heading h2 { } #powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { - border-bottom-color: #FFFFFF; + border-bottom-color: white; border-width: 10px; margin: 0px -10px; } #powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { - border-bottom-color: #808080; + border-bottom-color: gray; border-width: 11px; margin: 0px -11px; } @@ -1719,13 +1570,13 @@ tr.heading h2 { left: 100%; } #powerTip.e:after { - border-left-color: #FFFFFF; + border-left-color: gray; border-width: 10px; top: 50%; margin-top: -10px; } #powerTip.e:before { - border-left-color: #808080; + border-left-color: gray; border-width: 11px; top: 50%; margin-top: -11px; @@ -1735,13 +1586,13 @@ tr.heading h2 { right: 100%; } #powerTip.w:after { - border-right-color: #FFFFFF; + border-right-color: gray; border-width: 10px; top: 50%; margin-top: -10px; } #powerTip.w:before { - border-right-color: #808080; + border-right-color: gray; border-width: 11px; top: 50%; margin-top: -11px; @@ -1802,36 +1653,9 @@ th.markdownTableHeadCenter, td.markdownTableBodyCenter { text-align: center } -.DocNodeRTL { - text-align: right; - direction: rtl; -} - -.DocNodeLTR { - text-align: left; - direction: ltr; -} - -table.DocNodeRTL { - width: auto; - margin-right: 0; - margin-left: auto; -} - -table.DocNodeLTR { - width: auto; - margin-right: auto; - margin-left: 0; -} - -code.JavaDocCode { - direction:ltr; -} - tt, code, kbd, samp { display: inline-block; - direction:ltr; } /* @end */ @@ -1839,3 +1663,23 @@ u { text-decoration: underline; } +details>summary { + list-style-type: none; +} + +details > summary::-webkit-details-marker { + display: none; +} + +details>summary::before { + content: "\25ba"; + padding-right:4px; + font-size: 80%; +} + +details[open]>summary::before { + content: "\25bc"; + padding-right:4px; + font-size: 80%; +} + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/doxygen.svg b/src/lib/src/vendor/glfw-3.4/docs/html/doxygen.svg similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/doxygen.svg rename to src/lib/src/vendor/glfw-3.4/docs/html/doxygen.svg index d42dad5..79a7635 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/doxygen.svg +++ b/src/lib/src/vendor/glfw-3.4/docs/html/doxygen.svg @@ -1,4 +1,6 @@ + @@ -17,7 +19,7 @@ - + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/dynsections.js b/src/lib/src/vendor/glfw-3.4/docs/html/dynsections.js similarity index 58% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/dynsections.js rename to src/lib/src/vendor/glfw-3.4/docs/html/dynsections.js index 3174bd7..ee3f142 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/dynsections.js +++ b/src/lib/src/vendor/glfw-3.4/docs/html/dynsections.js @@ -47,6 +47,8 @@ function updateStripes() { $('table.directory tr'). removeClass('even').filter(':visible:even').addClass('even'); + $('table.directory tr'). + removeClass('odd').filter(':visible:odd').addClass('odd'); } function toggleLevel(level) @@ -118,4 +120,73 @@ function toggleInherit(id) $(img).attr('src',src.substring(0,src.length-10)+'open.png'); } } + +var opened=true; +// in case HTML_COLORSTYLE is LIGHT or DARK the vars will be replaced, so we write them out explicitly and use double quotes +var plusImg = [ "url('plus.svg')", "url('../../plus.svg')" ]; +var minusImg = [ "url('minus.svg')", "url('../../minus.svg')" ]; + +// toggle all folding blocks +function codefold_toggle_all(relPath) { + if (opened) { + $('#fold_all').css('background-image',plusImg[relPath]); + $('div[id^=foldopen]').hide(); + $('div[id^=foldclosed]').show(); + } else { + $('#fold_all').css('background-image',minusImg[relPath]); + $('div[id^=foldopen]').show(); + $('div[id^=foldclosed]').hide(); + } + opened=!opened; +} + +// toggle single folding block +function codefold_toggle(id) { + $('#foldopen'+id).toggle(); + $('#foldclosed'+id).toggle(); +} +function init_codefold(relPath) { + $('span[class=lineno]').css( + {'padding-right':'4px', + 'margin-right':'2px', + 'display':'inline-block', + 'width':'54px', + 'background':'linear-gradient(#808080,#808080) no-repeat 46px/2px 100%' + }); + // add global toggle to first line + $('span[class=lineno]:first').append(''); + // add vertical lines to other rows + $('span[class=lineno]').not(':eq(0)').append(''); + // add toggle controls to lines with fold divs + $('div[class=foldopen]').each(function() { + // extract specific id to use + var id = $(this).attr('id').replace('foldopen',''); + // extract start and end foldable fragment attributes + var start = $(this).attr('data-start'); + var end = $(this).attr('data-end'); + // replace normal fold span with controls for the first line of a foldable fragment + $(this).find('span[class=fold]:first').replaceWith(''); + // append div for folded (closed) representation + $(this).after(''); + // extract the first line from the "open" section to represent closed content + var line = $(this).children().first().clone(); + // remove any glow that might still be active on the original line + $(line).removeClass('glow'); + if (start) { + // if line already ends with a start marker (e.g. trailing {), remove it + $(line).html($(line).html().replace(new RegExp('\\s*'+start+'\\s*$','g'),'')); + } + // replace minus with plus symbol + $(line).find('span[class=fold]').css('background-image',plusImg[relPath]); + // append ellipsis + $(line).append(' '+start+''+end); + // insert constructed line into closed div + $('#foldclosed'+id).html(line); + }); +} + /* @license-end */ diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/extra.css b/src/lib/src/vendor/glfw-3.4/docs/html/extra.css new file mode 100644 index 0000000..7eb7e9d --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/extra.css @@ -0,0 +1,2 @@ +.sm-dox,.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted,.sm-dox ul a:hover{background:none;text-shadow:none}.sm-dox a span.sub-arrow{border-color:#f2f2f2 transparent transparent transparent}.sm-dox a span.sub-arrow:active,.sm-dox a span.sub-arrow:focus,.sm-dox a span.sub-arrow:hover,.sm-dox a:hover span.sub-arrow{border-color:#f60 transparent transparent transparent}.sm-dox ul a span.sub-arrow:active,.sm-dox ul a span.sub-arrow:focus,.sm-dox ul a span.sub-arrow:hover,.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent #f60}.sm-dox ul a:hover{background:#666;text-shadow:none}.sm-dox ul.sm-nowrap a{color:#4d4d4d;text-shadow:none}#main-nav,#main-menu,#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code,.markdownTable code{background:none}#titlearea,.footer,.contents,div.header,.memdoc,table.doxtable td,table.doxtable th,table.markdownTable td,table.markdownTable th,hr,.memSeparator{border:none}#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li,.reflist dt a.el,.levels span,.directory .levels span{text-shadow:none}.memdoc,dl.reflist dd{box-shadow:none}div.headertitle,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,table.doxtable code,table.markdownTable code{padding:0}#nav-path,.directory .levels,span.lineno{display:none}html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),tr.markdownTableBody:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code,.markdownTableRowEven{background:#f2f2f2}body{color:#4d4d4d}div.title{font-size:170%;margin:1em 0 0.5em 0}h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em{color:#1a1a1a;border-bottom:none}h1{padding-top:0.5em;font-size:150%}h2{padding-top:0.5em;margin-bottom:0;font-size:130%}h3{padding-top:0.5em;margin-bottom:0;font-size:110%}.glfwheader{font-size:16px;min-height:64px;max-width:920px;padding:0 32px;margin:0 auto;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:flex-start;align-items:center;align-content:stretch}#glfwhome{line-height:64px;padding-right:48px;color:#666;font-size:2.5em;background:url("https://www.glfw.org/css/arrow.png") no-repeat right}.glfwnavbar{list-style-type:none;margin:0 0 0 auto;float:right}#glfwhome,.glfwnavbar li{float:left}.glfwnavbar a,.glfwnavbar a:visited{line-height:64px;margin-left:2em;display:block;color:#666}.glfwnavbar{padding-left:0}#glfwhome,.glfwnavbar a,.glfwnavbar a:visited{transition:.35s ease}#titlearea,.footer{color:#666}address.footer{text-align:center;padding:2em;margin-top:3em}#top{background:#666}#main-nav{max-width:960px;margin:0 auto;font-size:13px}#main-menu{max-width:920px;margin:0 auto;font-size:13px}.memtitle{display:none}.memproto,.memname{font-weight:bold;text-shadow:none}#main-menu{min-height:36px;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:flex-start;align-items:center;align-content:stretch}#main-menu a:focus{outline-style:none}#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li{color:#f2f2f2}#main-menu li ul.sm-nowrap li a{color:#4d4d4d}#main-menu li ul.sm-nowrap li a:hover{color:#f60}#main-menu>li:last-child{margin:0 0 0 auto}.contents{min-height:590px}div.contents,div.header{max-width:920px;margin:0 auto;padding:0 32px;background:#fff none}table.doxtable th,table.markdownTable th,dl.reflist dt{background:linear-gradient(to bottom, #ffa733 0%, #f60 100%);box-shadow:inset 0 0 32px #f60;text-shadow:0 -1px 1px #b34700;text-align:left;color:#fff}dl.reflist dt a.el{color:#f60;padding:.2em;border-radius:4px;background-color:#ffe0cc}div.toc{float:right;width:35%}@media screen and (max-width: 600px){div.toc{float:none;width:inherit;margin:0}}div.toc h3{font-size:1.17em}div.toc ul{padding-left:1.5em}div.toc li{font-size:1em;padding-left:0;list-style-type:disc}div.toc li.level2,div.toc li.level3{margin-left:0.5em}div.toc,.memproto,div.qindex,div.ah{background:linear-gradient(to bottom, #f2f2f2 0%, #e6e6e6 100%);box-shadow:inset 0 0 32px #e6e6e6;text-shadow:0 1px 1px #fff;color:#1a1a1a;border:2px solid #e6e6e6;border-radius:4px}.paramname{color:#803300}dl.reflist dt{border:2px solid #f60;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom:none}dl.reflist dd{border:2px solid #f60;border-bottom-right-radius:4px;border-bottom-left-radius:4px;border-top:none}table.doxtable,table.markdownTable{border-collapse:inherit;border-spacing:0;border:2px solid #f60;border-radius:4px}a,a:hover,a:visited,a:visited:hover,.contents a:visited,.el,a.el:visited,#glfwhome:hover,#main-menu a:hover,span.lineno a:hover{color:#f60;text-decoration:none}div.directory{border-collapse:inherit;border-spacing:0;border:2px solid #f60;border-radius:4px}hr,.memSeparator{height:2px;background:linear-gradient(to right, #f2f2f2 0%, #d9d9d9 50%, #f2f2f2 100%)}dl.note,dl.pre,dl.post,dl.invariant{background:linear-gradient(to bottom, #ddfad1 0%, #cbf7ba 100%);box-shadow:inset 0 0 32px #baf5a3;color:#1e5309;border:2px solid #afe699}dl.warning,dl.attention{background:linear-gradient(to bottom, #fae8d1 0%, #f7ddba 100%);box-shadow:inset 0 0 32px #f5d1a3;color:#533309;border:2px solid #e6c499}dl.deprecated,dl.bug{background:linear-gradient(to bottom, #fad1e3 0%, #f7bad6 100%);box-shadow:inset 0 0 32px #f5a3c8;color:#53092a;border:2px solid #e699bb}dl.todo,dl.test{background:linear-gradient(to bottom, #d1ecfa 0%, #bae3f7 100%);box-shadow:inset 0 0 32px #a3daf5;color:#093a53;border:2px solid #99cce6}dl.note,dl.pre,dl.post,dl.invariant,dl.warning,dl.attention,dl.deprecated,dl.bug,dl.todo,dl.test{border-radius:4px;padding:1em;text-shadow:0 1px 1px #fff;margin:1em 0}.note a,.pre a,.post a,.invariant a,.warning a,.attention a,.deprecated a,.bug a,.todo a,.test a,.note a:visited,.pre a:visited,.post a:visited,.invariant a:visited,.warning a:visited,.attention a:visited,.deprecated a:visited,.bug a:visited,.todo a:visited,.test a:visited{color:inherit}div.line{line-height:inherit}div.fragment,pre.fragment{background:#f2f2f2;border-radius:4px;border:none;padding:1em;overflow:auto;border-left:4px solid #ccc;margin:1em 0}.lineno a,.lineno a:visited,.line,pre.fragment{color:#4d4d4d}span.preprocessor,span.comment{color:#007899}a.code,a.code:visited{color:#e64500}span.keyword,span.keywordtype,span.keywordflow{color:#404040;font-weight:bold}span.stringliteral{color:#360099}code{padding:.1em;border-radius:4px} +/*# sourceMappingURL=extra.css.map */ diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/files.html b/src/lib/src/vendor/glfw-3.4/docs/html/files.html similarity index 67% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/files.html rename to src/lib/src/vendor/glfw-3.4/docs/html/files.html index 3c035b1..462fb37 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/files.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/files.html @@ -4,7 +4,7 @@ - + GLFW: Files @@ -28,10 +28,10 @@ - + @@ -55,9 +55,16 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -66,18 +73,18 @@ $(function() {
Here is a list of all files with brief descriptions:
[detail level 1234]
- - - - + + + + - +
  glfw-3.3.8
 docs
  include
  GLFW
  glfw-3.4
 docs
  include
  GLFW
 glfw3.hThe header of the GLFW 3 API
 glfw3native.hThe header of the native access functions
 glfw3native.hThe header of the native access functions
diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/folderclosed.svg b/src/lib/src/vendor/glfw-3.4/docs/html/folderclosed.svg new file mode 100644 index 0000000..b04bed2 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/folderclosed.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/folderclosedd.svg b/src/lib/src/vendor/glfw-3.4/docs/html/folderclosedd.svg new file mode 100644 index 0000000..52f0166 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/folderclosedd.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/folderopen.svg b/src/lib/src/vendor/glfw-3.4/docs/html/folderopen.svg new file mode 100644 index 0000000..f6896dd --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/folderopen.svg @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/folderopend.svg b/src/lib/src/vendor/glfw-3.4/docs/html/folderopend.svg new file mode 100644 index 0000000..2d1f06e --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/folderopend.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/glfw3_8h.html b/src/lib/src/vendor/glfw-3.4/docs/html/glfw3_8h.html new file mode 100644 index 0000000..bca1323 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/glfw3_8h.html @@ -0,0 +1,1910 @@ + + + + + + + +GLFW: glfw3.h File Reference + + + + + + + + + + +
+ + + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+ +
glfw3.h File Reference
+
+
+

Description

+

This is the header file of the GLFW 3 API. It defines all its types and declares all its functions.

+

For more information about how to use this file, see Including the GLFW header file.

+
+

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

#define GLFW_APIENTRY_DEFINED
 
#define GLFW_TRUE   1
 One.
 
#define GLFW_FALSE   0
 Zero.
 
#define GLFW_HAT_CENTERED   0
 
#define GLFW_HAT_UP   1
 
#define GLFW_HAT_RIGHT   2
 
#define GLFW_HAT_DOWN   4
 
#define GLFW_HAT_LEFT   8
 
#define GLFW_HAT_RIGHT_UP   (GLFW_HAT_RIGHT | GLFW_HAT_UP)
 
#define GLFW_HAT_RIGHT_DOWN   (GLFW_HAT_RIGHT | GLFW_HAT_DOWN)
 
#define GLFW_HAT_LEFT_UP   (GLFW_HAT_LEFT | GLFW_HAT_UP)
 
#define GLFW_HAT_LEFT_DOWN   (GLFW_HAT_LEFT | GLFW_HAT_DOWN)
 
#define GLFW_KEY_UNKNOWN   -1
 
#define GLFW_KEY_SPACE   32
 
#define GLFW_KEY_APOSTROPHE   39 /* ' */
 
#define GLFW_KEY_COMMA   44 /* , */
 
#define GLFW_KEY_MINUS   45 /* - */
 
#define GLFW_KEY_PERIOD   46 /* . */
 
#define GLFW_KEY_SLASH   47 /* / */
 
#define GLFW_KEY_0   48
 
#define GLFW_KEY_1   49
 
#define GLFW_KEY_2   50
 
#define GLFW_KEY_3   51
 
#define GLFW_KEY_4   52
 
#define GLFW_KEY_5   53
 
#define GLFW_KEY_6   54
 
#define GLFW_KEY_7   55
 
#define GLFW_KEY_8   56
 
#define GLFW_KEY_9   57
 
#define GLFW_KEY_SEMICOLON   59 /* ; */
 
#define GLFW_KEY_EQUAL   61 /* = */
 
#define GLFW_KEY_A   65
 
#define GLFW_KEY_B   66
 
#define GLFW_KEY_C   67
 
#define GLFW_KEY_D   68
 
#define GLFW_KEY_E   69
 
#define GLFW_KEY_F   70
 
#define GLFW_KEY_G   71
 
#define GLFW_KEY_H   72
 
#define GLFW_KEY_I   73
 
#define GLFW_KEY_J   74
 
#define GLFW_KEY_K   75
 
#define GLFW_KEY_L   76
 
#define GLFW_KEY_M   77
 
#define GLFW_KEY_N   78
 
#define GLFW_KEY_O   79
 
#define GLFW_KEY_P   80
 
#define GLFW_KEY_Q   81
 
#define GLFW_KEY_R   82
 
#define GLFW_KEY_S   83
 
#define GLFW_KEY_T   84
 
#define GLFW_KEY_U   85
 
#define GLFW_KEY_V   86
 
#define GLFW_KEY_W   87
 
#define GLFW_KEY_X   88
 
#define GLFW_KEY_Y   89
 
#define GLFW_KEY_Z   90
 
#define GLFW_KEY_LEFT_BRACKET   91 /* [ */
 
#define GLFW_KEY_BACKSLASH   92 /* \ */
 
#define GLFW_KEY_RIGHT_BRACKET   93 /* ] */
 
#define GLFW_KEY_GRAVE_ACCENT   96 /* ` */
 
#define GLFW_KEY_WORLD_1   161 /* non-US #1 */
 
#define GLFW_KEY_WORLD_2   162 /* non-US #2 */
 
#define GLFW_KEY_ESCAPE   256
 
#define GLFW_KEY_ENTER   257
 
#define GLFW_KEY_TAB   258
 
#define GLFW_KEY_BACKSPACE   259
 
#define GLFW_KEY_INSERT   260
 
#define GLFW_KEY_DELETE   261
 
#define GLFW_KEY_RIGHT   262
 
#define GLFW_KEY_LEFT   263
 
#define GLFW_KEY_DOWN   264
 
#define GLFW_KEY_UP   265
 
#define GLFW_KEY_PAGE_UP   266
 
#define GLFW_KEY_PAGE_DOWN   267
 
#define GLFW_KEY_HOME   268
 
#define GLFW_KEY_END   269
 
#define GLFW_KEY_CAPS_LOCK   280
 
#define GLFW_KEY_SCROLL_LOCK   281
 
#define GLFW_KEY_NUM_LOCK   282
 
#define GLFW_KEY_PRINT_SCREEN   283
 
#define GLFW_KEY_PAUSE   284
 
#define GLFW_KEY_F1   290
 
#define GLFW_KEY_F2   291
 
#define GLFW_KEY_F3   292
 
#define GLFW_KEY_F4   293
 
#define GLFW_KEY_F5   294
 
#define GLFW_KEY_F6   295
 
#define GLFW_KEY_F7   296
 
#define GLFW_KEY_F8   297
 
#define GLFW_KEY_F9   298
 
#define GLFW_KEY_F10   299
 
#define GLFW_KEY_F11   300
 
#define GLFW_KEY_F12   301
 
#define GLFW_KEY_F13   302
 
#define GLFW_KEY_F14   303
 
#define GLFW_KEY_F15   304
 
#define GLFW_KEY_F16   305
 
#define GLFW_KEY_F17   306
 
#define GLFW_KEY_F18   307
 
#define GLFW_KEY_F19   308
 
#define GLFW_KEY_F20   309
 
#define GLFW_KEY_F21   310
 
#define GLFW_KEY_F22   311
 
#define GLFW_KEY_F23   312
 
#define GLFW_KEY_F24   313
 
#define GLFW_KEY_F25   314
 
#define GLFW_KEY_KP_0   320
 
#define GLFW_KEY_KP_1   321
 
#define GLFW_KEY_KP_2   322
 
#define GLFW_KEY_KP_3   323
 
#define GLFW_KEY_KP_4   324
 
#define GLFW_KEY_KP_5   325
 
#define GLFW_KEY_KP_6   326
 
#define GLFW_KEY_KP_7   327
 
#define GLFW_KEY_KP_8   328
 
#define GLFW_KEY_KP_9   329
 
#define GLFW_KEY_KP_DECIMAL   330
 
#define GLFW_KEY_KP_DIVIDE   331
 
#define GLFW_KEY_KP_MULTIPLY   332
 
#define GLFW_KEY_KP_SUBTRACT   333
 
#define GLFW_KEY_KP_ADD   334
 
#define GLFW_KEY_KP_ENTER   335
 
#define GLFW_KEY_KP_EQUAL   336
 
#define GLFW_KEY_LEFT_SHIFT   340
 
#define GLFW_KEY_LEFT_CONTROL   341
 
#define GLFW_KEY_LEFT_ALT   342
 
#define GLFW_KEY_LEFT_SUPER   343
 
#define GLFW_KEY_RIGHT_SHIFT   344
 
#define GLFW_KEY_RIGHT_CONTROL   345
 
#define GLFW_KEY_RIGHT_ALT   346
 
#define GLFW_KEY_RIGHT_SUPER   347
 
#define GLFW_KEY_MENU   348
 
#define GLFW_KEY_LAST   GLFW_KEY_MENU
 
#define GLFW_MOD_SHIFT   0x0001
 If this bit is set one or more Shift keys were held down.
 
#define GLFW_MOD_CONTROL   0x0002
 If this bit is set one or more Control keys were held down.
 
#define GLFW_MOD_ALT   0x0004
 If this bit is set one or more Alt keys were held down.
 
#define GLFW_MOD_SUPER   0x0008
 If this bit is set one or more Super keys were held down.
 
#define GLFW_MOD_CAPS_LOCK   0x0010
 If this bit is set the Caps Lock key is enabled.
 
#define GLFW_MOD_NUM_LOCK   0x0020
 If this bit is set the Num Lock key is enabled.
 
#define GLFW_MOUSE_BUTTON_1   0
 
#define GLFW_MOUSE_BUTTON_2   1
 
#define GLFW_MOUSE_BUTTON_3   2
 
#define GLFW_MOUSE_BUTTON_4   3
 
#define GLFW_MOUSE_BUTTON_5   4
 
#define GLFW_MOUSE_BUTTON_6   5
 
#define GLFW_MOUSE_BUTTON_7   6
 
#define GLFW_MOUSE_BUTTON_8   7
 
#define GLFW_MOUSE_BUTTON_LAST   GLFW_MOUSE_BUTTON_8
 
#define GLFW_MOUSE_BUTTON_LEFT   GLFW_MOUSE_BUTTON_1
 
#define GLFW_MOUSE_BUTTON_RIGHT   GLFW_MOUSE_BUTTON_2
 
#define GLFW_MOUSE_BUTTON_MIDDLE   GLFW_MOUSE_BUTTON_3
 
#define GLFW_JOYSTICK_1   0
 
#define GLFW_JOYSTICK_2   1
 
#define GLFW_JOYSTICK_3   2
 
#define GLFW_JOYSTICK_4   3
 
#define GLFW_JOYSTICK_5   4
 
#define GLFW_JOYSTICK_6   5
 
#define GLFW_JOYSTICK_7   6
 
#define GLFW_JOYSTICK_8   7
 
#define GLFW_JOYSTICK_9   8
 
#define GLFW_JOYSTICK_10   9
 
#define GLFW_JOYSTICK_11   10
 
#define GLFW_JOYSTICK_12   11
 
#define GLFW_JOYSTICK_13   12
 
#define GLFW_JOYSTICK_14   13
 
#define GLFW_JOYSTICK_15   14
 
#define GLFW_JOYSTICK_16   15
 
#define GLFW_JOYSTICK_LAST   GLFW_JOYSTICK_16
 
#define GLFW_GAMEPAD_BUTTON_A   0
 
#define GLFW_GAMEPAD_BUTTON_B   1
 
#define GLFW_GAMEPAD_BUTTON_X   2
 
#define GLFW_GAMEPAD_BUTTON_Y   3
 
#define GLFW_GAMEPAD_BUTTON_LEFT_BUMPER   4
 
#define GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER   5
 
#define GLFW_GAMEPAD_BUTTON_BACK   6
 
#define GLFW_GAMEPAD_BUTTON_START   7
 
#define GLFW_GAMEPAD_BUTTON_GUIDE   8
 
#define GLFW_GAMEPAD_BUTTON_LEFT_THUMB   9
 
#define GLFW_GAMEPAD_BUTTON_RIGHT_THUMB   10
 
#define GLFW_GAMEPAD_BUTTON_DPAD_UP   11
 
#define GLFW_GAMEPAD_BUTTON_DPAD_RIGHT   12
 
#define GLFW_GAMEPAD_BUTTON_DPAD_DOWN   13
 
#define GLFW_GAMEPAD_BUTTON_DPAD_LEFT   14
 
#define GLFW_GAMEPAD_BUTTON_LAST   GLFW_GAMEPAD_BUTTON_DPAD_LEFT
 
#define GLFW_GAMEPAD_BUTTON_CROSS   GLFW_GAMEPAD_BUTTON_A
 
#define GLFW_GAMEPAD_BUTTON_CIRCLE   GLFW_GAMEPAD_BUTTON_B
 
#define GLFW_GAMEPAD_BUTTON_SQUARE   GLFW_GAMEPAD_BUTTON_X
 
#define GLFW_GAMEPAD_BUTTON_TRIANGLE   GLFW_GAMEPAD_BUTTON_Y
 
#define GLFW_GAMEPAD_AXIS_LEFT_X   0
 
#define GLFW_GAMEPAD_AXIS_LEFT_Y   1
 
#define GLFW_GAMEPAD_AXIS_RIGHT_X   2
 
#define GLFW_GAMEPAD_AXIS_RIGHT_Y   3
 
#define GLFW_GAMEPAD_AXIS_LEFT_TRIGGER   4
 
#define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER   5
 
#define GLFW_GAMEPAD_AXIS_LAST   GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
 
#define GLFW_NO_ERROR   0
 No error has occurred.
 
#define GLFW_NOT_INITIALIZED   0x00010001
 GLFW has not been initialized.
 
#define GLFW_NO_CURRENT_CONTEXT   0x00010002
 No context is current for this thread.
 
#define GLFW_INVALID_ENUM   0x00010003
 One of the arguments to the function was an invalid enum value.
 
#define GLFW_INVALID_VALUE   0x00010004
 One of the arguments to the function was an invalid value.
 
#define GLFW_OUT_OF_MEMORY   0x00010005
 A memory allocation failed.
 
#define GLFW_API_UNAVAILABLE   0x00010006
 GLFW could not find support for the requested API on the system.
 
#define GLFW_VERSION_UNAVAILABLE   0x00010007
 The requested OpenGL or OpenGL ES version is not available.
 
#define GLFW_PLATFORM_ERROR   0x00010008
 A platform-specific error occurred that does not match any of the more specific categories.
 
#define GLFW_FORMAT_UNAVAILABLE   0x00010009
 The requested format is not supported or available.
 
#define GLFW_NO_WINDOW_CONTEXT   0x0001000A
 The specified window does not have an OpenGL or OpenGL ES context.
 
#define GLFW_CURSOR_UNAVAILABLE   0x0001000B
 The specified cursor shape is not available.
 
#define GLFW_FEATURE_UNAVAILABLE   0x0001000C
 The requested feature is not provided by the platform.
 
#define GLFW_FEATURE_UNIMPLEMENTED   0x0001000D
 The requested feature is not implemented for the platform.
 
#define GLFW_PLATFORM_UNAVAILABLE   0x0001000E
 Platform unavailable or no matching platform was found.
 
#define GLFW_FOCUSED   0x00020001
 Input focus window hint and attribute.
 
#define GLFW_ICONIFIED   0x00020002
 Window iconification window attribute.
 
#define GLFW_RESIZABLE   0x00020003
 Window resize-ability window hint and attribute.
 
#define GLFW_VISIBLE   0x00020004
 Window visibility window hint and attribute.
 
#define GLFW_DECORATED   0x00020005
 Window decoration window hint and attribute.
 
#define GLFW_AUTO_ICONIFY   0x00020006
 Window auto-iconification window hint and attribute.
 
#define GLFW_FLOATING   0x00020007
 Window decoration window hint and attribute.
 
#define GLFW_MAXIMIZED   0x00020008
 Window maximization window hint and attribute.
 
#define GLFW_CENTER_CURSOR   0x00020009
 Cursor centering window hint.
 
#define GLFW_TRANSPARENT_FRAMEBUFFER   0x0002000A
 Window framebuffer transparency hint and attribute.
 
#define GLFW_HOVERED   0x0002000B
 Mouse cursor hover window attribute.
 
#define GLFW_FOCUS_ON_SHOW   0x0002000C
 Input focus on calling show window hint and attribute.
 
#define GLFW_MOUSE_PASSTHROUGH   0x0002000D
 Mouse input transparency window hint and attribute.
 
#define GLFW_POSITION_X   0x0002000E
 Initial position x-coordinate window hint.
 
#define GLFW_POSITION_Y   0x0002000F
 Initial position y-coordinate window hint.
 
#define GLFW_RED_BITS   0x00021001
 Framebuffer bit depth hint.
 
#define GLFW_GREEN_BITS   0x00021002
 Framebuffer bit depth hint.
 
#define GLFW_BLUE_BITS   0x00021003
 Framebuffer bit depth hint.
 
#define GLFW_ALPHA_BITS   0x00021004
 Framebuffer bit depth hint.
 
#define GLFW_DEPTH_BITS   0x00021005
 Framebuffer bit depth hint.
 
#define GLFW_STENCIL_BITS   0x00021006
 Framebuffer bit depth hint.
 
#define GLFW_ACCUM_RED_BITS   0x00021007
 Framebuffer bit depth hint.
 
#define GLFW_ACCUM_GREEN_BITS   0x00021008
 Framebuffer bit depth hint.
 
#define GLFW_ACCUM_BLUE_BITS   0x00021009
 Framebuffer bit depth hint.
 
#define GLFW_ACCUM_ALPHA_BITS   0x0002100A
 Framebuffer bit depth hint.
 
#define GLFW_AUX_BUFFERS   0x0002100B
 Framebuffer auxiliary buffer hint.
 
#define GLFW_STEREO   0x0002100C
 OpenGL stereoscopic rendering hint.
 
#define GLFW_SAMPLES   0x0002100D
 Framebuffer MSAA samples hint.
 
#define GLFW_SRGB_CAPABLE   0x0002100E
 Framebuffer sRGB hint.
 
#define GLFW_REFRESH_RATE   0x0002100F
 Monitor refresh rate hint.
 
#define GLFW_DOUBLEBUFFER   0x00021010
 Framebuffer double buffering hint and attribute.
 
#define GLFW_CLIENT_API   0x00022001
 Context client API hint and attribute.
 
#define GLFW_CONTEXT_VERSION_MAJOR   0x00022002
 Context client API major version hint and attribute.
 
#define GLFW_CONTEXT_VERSION_MINOR   0x00022003
 Context client API minor version hint and attribute.
 
#define GLFW_CONTEXT_REVISION   0x00022004
 Context client API revision number attribute.
 
#define GLFW_CONTEXT_ROBUSTNESS   0x00022005
 Context robustness hint and attribute.
 
#define GLFW_OPENGL_FORWARD_COMPAT   0x00022006
 OpenGL forward-compatibility hint and attribute.
 
#define GLFW_CONTEXT_DEBUG   0x00022007
 Debug mode context hint and attribute.
 
#define GLFW_OPENGL_DEBUG_CONTEXT   GLFW_CONTEXT_DEBUG
 Legacy name for compatibility.
 
#define GLFW_OPENGL_PROFILE   0x00022008
 OpenGL profile hint and attribute.
 
#define GLFW_CONTEXT_RELEASE_BEHAVIOR   0x00022009
 Context flush-on-release hint and attribute.
 
#define GLFW_CONTEXT_NO_ERROR   0x0002200A
 Context error suppression hint and attribute.
 
#define GLFW_CONTEXT_CREATION_API   0x0002200B
 Context creation API hint and attribute.
 
#define GLFW_SCALE_TO_MONITOR   0x0002200C
 Window content area scaling window window hint.
 
#define GLFW_SCALE_FRAMEBUFFER   0x0002200D
 Window framebuffer scaling window hint.
 
#define GLFW_COCOA_RETINA_FRAMEBUFFER   0x00023001
 Legacy name for compatibility.
 
#define GLFW_COCOA_FRAME_NAME   0x00023002
 macOS specific window hint.
 
#define GLFW_COCOA_GRAPHICS_SWITCHING   0x00023003
 macOS specific window hint.
 
#define GLFW_X11_CLASS_NAME   0x00024001
 X11 specific window hint.
 
#define GLFW_X11_INSTANCE_NAME   0x00024002
 X11 specific window hint.
 
#define GLFW_WIN32_KEYBOARD_MENU   0x00025001
 
#define GLFW_WIN32_SHOWDEFAULT   0x00025002
 Win32 specific window hint.
 
#define GLFW_WAYLAND_APP_ID   0x00026001
 Wayland specific window hint.
 
#define GLFW_NO_API   0
 
#define GLFW_OPENGL_API   0x00030001
 
#define GLFW_OPENGL_ES_API   0x00030002
 
#define GLFW_NO_ROBUSTNESS   0
 
#define GLFW_NO_RESET_NOTIFICATION   0x00031001
 
#define GLFW_LOSE_CONTEXT_ON_RESET   0x00031002
 
#define GLFW_OPENGL_ANY_PROFILE   0
 
#define GLFW_OPENGL_CORE_PROFILE   0x00032001
 
#define GLFW_OPENGL_COMPAT_PROFILE   0x00032002
 
#define GLFW_CURSOR   0x00033001
 
#define GLFW_STICKY_KEYS   0x00033002
 
#define GLFW_STICKY_MOUSE_BUTTONS   0x00033003
 
#define GLFW_LOCK_KEY_MODS   0x00033004
 
#define GLFW_RAW_MOUSE_MOTION   0x00033005
 
#define GLFW_CURSOR_NORMAL   0x00034001
 
#define GLFW_CURSOR_HIDDEN   0x00034002
 
#define GLFW_CURSOR_DISABLED   0x00034003
 
#define GLFW_CURSOR_CAPTURED   0x00034004
 
#define GLFW_ANY_RELEASE_BEHAVIOR   0
 
#define GLFW_RELEASE_BEHAVIOR_FLUSH   0x00035001
 
#define GLFW_RELEASE_BEHAVIOR_NONE   0x00035002
 
#define GLFW_NATIVE_CONTEXT_API   0x00036001
 
#define GLFW_EGL_CONTEXT_API   0x00036002
 
#define GLFW_OSMESA_CONTEXT_API   0x00036003
 
#define GLFW_ANGLE_PLATFORM_TYPE_NONE   0x00037001
 
#define GLFW_ANGLE_PLATFORM_TYPE_OPENGL   0x00037002
 
#define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES   0x00037003
 
#define GLFW_ANGLE_PLATFORM_TYPE_D3D9   0x00037004
 
#define GLFW_ANGLE_PLATFORM_TYPE_D3D11   0x00037005
 
#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN   0x00037007
 
#define GLFW_ANGLE_PLATFORM_TYPE_METAL   0x00037008
 
#define GLFW_WAYLAND_PREFER_LIBDECOR   0x00038001
 
#define GLFW_WAYLAND_DISABLE_LIBDECOR   0x00038002
 
#define GLFW_ANY_POSITION   0x80000000
 
#define GLFW_ARROW_CURSOR   0x00036001
 The regular arrow cursor shape.
 
#define GLFW_IBEAM_CURSOR   0x00036002
 The text input I-beam cursor shape.
 
#define GLFW_CROSSHAIR_CURSOR   0x00036003
 The crosshair cursor shape.
 
#define GLFW_POINTING_HAND_CURSOR   0x00036004
 The pointing hand cursor shape.
 
#define GLFW_RESIZE_EW_CURSOR   0x00036005
 The horizontal resize/move arrow shape.
 
#define GLFW_RESIZE_NS_CURSOR   0x00036006
 The vertical resize/move arrow shape.
 
#define GLFW_RESIZE_NWSE_CURSOR   0x00036007
 The top-left to bottom-right diagonal resize/move arrow shape.
 
#define GLFW_RESIZE_NESW_CURSOR   0x00036008
 The top-right to bottom-left diagonal resize/move arrow shape.
 
#define GLFW_RESIZE_ALL_CURSOR   0x00036009
 The omni-directional resize/move cursor shape.
 
#define GLFW_NOT_ALLOWED_CURSOR   0x0003600A
 The operation-not-allowed shape.
 
#define GLFW_HRESIZE_CURSOR   GLFW_RESIZE_EW_CURSOR
 Legacy name for compatibility.
 
#define GLFW_VRESIZE_CURSOR   GLFW_RESIZE_NS_CURSOR
 Legacy name for compatibility.
 
#define GLFW_HAND_CURSOR   GLFW_POINTING_HAND_CURSOR
 Legacy name for compatibility.
 
#define GLFW_CONNECTED   0x00040001
 
#define GLFW_DISCONNECTED   0x00040002
 
#define GLFW_JOYSTICK_HAT_BUTTONS   0x00050001
 Joystick hat buttons init hint.
 
#define GLFW_ANGLE_PLATFORM_TYPE   0x00050002
 ANGLE rendering backend init hint.
 
#define GLFW_PLATFORM   0x00050003
 Platform selection init hint.
 
#define GLFW_COCOA_CHDIR_RESOURCES   0x00051001
 macOS specific init hint.
 
#define GLFW_COCOA_MENUBAR   0x00051002
 macOS specific init hint.
 
#define GLFW_X11_XCB_VULKAN_SURFACE   0x00052001
 X11 specific init hint.
 
#define GLFW_WAYLAND_LIBDECOR   0x00053001
 Wayland specific init hint.
 
#define GLFW_ANY_PLATFORM   0x00060000
 Hint value that enables automatic platform selection.
 
#define GLFW_PLATFORM_WIN32   0x00060001
 
#define GLFW_PLATFORM_COCOA   0x00060002
 
#define GLFW_PLATFORM_WAYLAND   0x00060003
 
#define GLFW_PLATFORM_X11   0x00060004
 
#define GLFW_PLATFORM_NULL   0x00060005
 
#define GLFW_DONT_CARE   -1
 
#define GLAPIENTRY   APIENTRY
 
#define GLFW_GLAPIENTRY_DEFINED
 
GLFW version macros
#define GLFW_VERSION_MAJOR   3
 The major version number of the GLFW header.
 
#define GLFW_VERSION_MINOR   4
 The minor version number of the GLFW header.
 
#define GLFW_VERSION_REVISION   0
 The revision number of the GLFW header.
 
Key and button actions
#define GLFW_RELEASE   0
 The key or mouse button was released.
 
#define GLFW_PRESS   1
 The key or mouse button was pressed.
 
#define GLFW_REPEAT   2
 The key was held down until it repeated.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Typedefs

typedef void(* GLFWglproc) (void)
 Client API function pointer type.
 
typedef void(* GLFWvkproc) (void)
 Vulkan API function pointer type.
 
typedef struct GLFWmonitor GLFWmonitor
 Opaque monitor object.
 
typedef struct GLFWwindow GLFWwindow
 Opaque window object.
 
typedef struct GLFWcursor GLFWcursor
 Opaque cursor object.
 
typedef void *(* GLFWallocatefun) (size_t size, void *user)
 The function pointer type for memory allocation callbacks.
 
typedef void *(* GLFWreallocatefun) (void *block, size_t size, void *user)
 The function pointer type for memory reallocation callbacks.
 
typedef void(* GLFWdeallocatefun) (void *block, void *user)
 The function pointer type for memory deallocation callbacks.
 
typedef void(* GLFWerrorfun) (int error_code, const char *description)
 The function pointer type for error callbacks.
 
typedef void(* GLFWwindowposfun) (GLFWwindow *window, int xpos, int ypos)
 The function pointer type for window position callbacks.
 
typedef void(* GLFWwindowsizefun) (GLFWwindow *window, int width, int height)
 The function pointer type for window size callbacks.
 
typedef void(* GLFWwindowclosefun) (GLFWwindow *window)
 The function pointer type for window close callbacks.
 
typedef void(* GLFWwindowrefreshfun) (GLFWwindow *window)
 The function pointer type for window content refresh callbacks.
 
typedef void(* GLFWwindowfocusfun) (GLFWwindow *window, int focused)
 The function pointer type for window focus callbacks.
 
typedef void(* GLFWwindowiconifyfun) (GLFWwindow *window, int iconified)
 The function pointer type for window iconify callbacks.
 
typedef void(* GLFWwindowmaximizefun) (GLFWwindow *window, int maximized)
 The function pointer type for window maximize callbacks.
 
typedef void(* GLFWframebuffersizefun) (GLFWwindow *window, int width, int height)
 The function pointer type for framebuffer size callbacks.
 
typedef void(* GLFWwindowcontentscalefun) (GLFWwindow *window, float xscale, float yscale)
 The function pointer type for window content scale callbacks.
 
typedef void(* GLFWmousebuttonfun) (GLFWwindow *window, int button, int action, int mods)
 The function pointer type for mouse button callbacks.
 
typedef void(* GLFWcursorposfun) (GLFWwindow *window, double xpos, double ypos)
 The function pointer type for cursor position callbacks.
 
typedef void(* GLFWcursorenterfun) (GLFWwindow *window, int entered)
 The function pointer type for cursor enter/leave callbacks.
 
typedef void(* GLFWscrollfun) (GLFWwindow *window, double xoffset, double yoffset)
 The function pointer type for scroll callbacks.
 
typedef void(* GLFWkeyfun) (GLFWwindow *window, int key, int scancode, int action, int mods)
 The function pointer type for keyboard key callbacks.
 
typedef void(* GLFWcharfun) (GLFWwindow *window, unsigned int codepoint)
 The function pointer type for Unicode character callbacks.
 
typedef void(* GLFWcharmodsfun) (GLFWwindow *window, unsigned int codepoint, int mods)
 The function pointer type for Unicode character with modifiers callbacks.
 
typedef void(* GLFWdropfun) (GLFWwindow *window, int path_count, const char *paths[])
 The function pointer type for path drop callbacks.
 
typedef void(* GLFWmonitorfun) (GLFWmonitor *monitor, int event)
 The function pointer type for monitor configuration callbacks.
 
typedef void(* GLFWjoystickfun) (int jid, int event)
 The function pointer type for joystick configuration callbacks.
 
typedef struct GLFWvidmode GLFWvidmode
 Video mode type.
 
typedef struct GLFWgammaramp GLFWgammaramp
 Gamma ramp.
 
typedef struct GLFWimage GLFWimage
 Image data.
 
typedef struct GLFWgamepadstate GLFWgamepadstate
 Gamepad input state.
 
typedef struct GLFWallocator GLFWallocator
 Custom heap memory allocator.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

int glfwInit (void)
 Initializes the GLFW library.
 
void glfwTerminate (void)
 Terminates the GLFW library.
 
void glfwInitHint (int hint, int value)
 Sets the specified init hint to the desired value.
 
void glfwInitAllocator (const GLFWallocator *allocator)
 Sets the init allocator to the desired value.
 
void glfwInitVulkanLoader (PFN_vkGetInstanceProcAddr loader)
 Sets the desired Vulkan vkGetInstanceProcAddr function.
 
void glfwGetVersion (int *major, int *minor, int *rev)
 Retrieves the version of the GLFW library.
 
const char * glfwGetVersionString (void)
 Returns a string describing the compile-time configuration.
 
int glfwGetError (const char **description)
 Returns and clears the last error for the calling thread.
 
GLFWerrorfun glfwSetErrorCallback (GLFWerrorfun callback)
 Sets the error callback.
 
int glfwGetPlatform (void)
 Returns the currently selected platform.
 
int glfwPlatformSupported (int platform)
 Returns whether the library includes support for the specified platform.
 
GLFWmonitor ** glfwGetMonitors (int *count)
 Returns the currently connected monitors.
 
GLFWmonitorglfwGetPrimaryMonitor (void)
 Returns the primary monitor.
 
void glfwGetMonitorPos (GLFWmonitor *monitor, int *xpos, int *ypos)
 Returns the position of the monitor's viewport on the virtual screen.
 
void glfwGetMonitorWorkarea (GLFWmonitor *monitor, int *xpos, int *ypos, int *width, int *height)
 Retrieves the work area of the monitor.
 
void glfwGetMonitorPhysicalSize (GLFWmonitor *monitor, int *widthMM, int *heightMM)
 Returns the physical size of the monitor.
 
void glfwGetMonitorContentScale (GLFWmonitor *monitor, float *xscale, float *yscale)
 Retrieves the content scale for the specified monitor.
 
const char * glfwGetMonitorName (GLFWmonitor *monitor)
 Returns the name of the specified monitor.
 
void glfwSetMonitorUserPointer (GLFWmonitor *monitor, void *pointer)
 Sets the user pointer of the specified monitor.
 
void * glfwGetMonitorUserPointer (GLFWmonitor *monitor)
 Returns the user pointer of the specified monitor.
 
GLFWmonitorfun glfwSetMonitorCallback (GLFWmonitorfun callback)
 Sets the monitor configuration callback.
 
const GLFWvidmodeglfwGetVideoModes (GLFWmonitor *monitor, int *count)
 Returns the available video modes for the specified monitor.
 
const GLFWvidmodeglfwGetVideoMode (GLFWmonitor *monitor)
 Returns the current mode of the specified monitor.
 
void glfwSetGamma (GLFWmonitor *monitor, float gamma)
 Generates a gamma ramp and sets it for the specified monitor.
 
const GLFWgammarampglfwGetGammaRamp (GLFWmonitor *monitor)
 Returns the current gamma ramp for the specified monitor.
 
void glfwSetGammaRamp (GLFWmonitor *monitor, const GLFWgammaramp *ramp)
 Sets the current gamma ramp for the specified monitor.
 
void glfwDefaultWindowHints (void)
 Resets all window hints to their default values.
 
void glfwWindowHint (int hint, int value)
 Sets the specified window hint to the desired value.
 
void glfwWindowHintString (int hint, const char *value)
 Sets the specified window hint to the desired value.
 
GLFWwindowglfwCreateWindow (int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
 Creates a window and its associated context.
 
void glfwDestroyWindow (GLFWwindow *window)
 Destroys the specified window and its context.
 
int glfwWindowShouldClose (GLFWwindow *window)
 Checks the close flag of the specified window.
 
void glfwSetWindowShouldClose (GLFWwindow *window, int value)
 Sets the close flag of the specified window.
 
const char * glfwGetWindowTitle (GLFWwindow *window)
 Returns the title of the specified window.
 
void glfwSetWindowTitle (GLFWwindow *window, const char *title)
 Sets the title of the specified window.
 
void glfwSetWindowIcon (GLFWwindow *window, int count, const GLFWimage *images)
 Sets the icon for the specified window.
 
void glfwGetWindowPos (GLFWwindow *window, int *xpos, int *ypos)
 Retrieves the position of the content area of the specified window.
 
void glfwSetWindowPos (GLFWwindow *window, int xpos, int ypos)
 Sets the position of the content area of the specified window.
 
void glfwGetWindowSize (GLFWwindow *window, int *width, int *height)
 Retrieves the size of the content area of the specified window.
 
void glfwSetWindowSizeLimits (GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)
 Sets the size limits of the specified window.
 
void glfwSetWindowAspectRatio (GLFWwindow *window, int numer, int denom)
 Sets the aspect ratio of the specified window.
 
void glfwSetWindowSize (GLFWwindow *window, int width, int height)
 Sets the size of the content area of the specified window.
 
void glfwGetFramebufferSize (GLFWwindow *window, int *width, int *height)
 Retrieves the size of the framebuffer of the specified window.
 
void glfwGetWindowFrameSize (GLFWwindow *window, int *left, int *top, int *right, int *bottom)
 Retrieves the size of the frame of the window.
 
void glfwGetWindowContentScale (GLFWwindow *window, float *xscale, float *yscale)
 Retrieves the content scale for the specified window.
 
float glfwGetWindowOpacity (GLFWwindow *window)
 Returns the opacity of the whole window.
 
void glfwSetWindowOpacity (GLFWwindow *window, float opacity)
 Sets the opacity of the whole window.
 
void glfwIconifyWindow (GLFWwindow *window)
 Iconifies the specified window.
 
void glfwRestoreWindow (GLFWwindow *window)
 Restores the specified window.
 
void glfwMaximizeWindow (GLFWwindow *window)
 Maximizes the specified window.
 
void glfwShowWindow (GLFWwindow *window)
 Makes the specified window visible.
 
void glfwHideWindow (GLFWwindow *window)
 Hides the specified window.
 
void glfwFocusWindow (GLFWwindow *window)
 Brings the specified window to front and sets input focus.
 
void glfwRequestWindowAttention (GLFWwindow *window)
 Requests user attention to the specified window.
 
GLFWmonitorglfwGetWindowMonitor (GLFWwindow *window)
 Returns the monitor that the window uses for full screen mode.
 
void glfwSetWindowMonitor (GLFWwindow *window, GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)
 Sets the mode, monitor, video mode and placement of a window.
 
int glfwGetWindowAttrib (GLFWwindow *window, int attrib)
 Returns an attribute of the specified window.
 
void glfwSetWindowAttrib (GLFWwindow *window, int attrib, int value)
 Sets an attribute of the specified window.
 
void glfwSetWindowUserPointer (GLFWwindow *window, void *pointer)
 Sets the user pointer of the specified window.
 
void * glfwGetWindowUserPointer (GLFWwindow *window)
 Returns the user pointer of the specified window.
 
GLFWwindowposfun glfwSetWindowPosCallback (GLFWwindow *window, GLFWwindowposfun callback)
 Sets the position callback for the specified window.
 
GLFWwindowsizefun glfwSetWindowSizeCallback (GLFWwindow *window, GLFWwindowsizefun callback)
 Sets the size callback for the specified window.
 
GLFWwindowclosefun glfwSetWindowCloseCallback (GLFWwindow *window, GLFWwindowclosefun callback)
 Sets the close callback for the specified window.
 
GLFWwindowrefreshfun glfwSetWindowRefreshCallback (GLFWwindow *window, GLFWwindowrefreshfun callback)
 Sets the refresh callback for the specified window.
 
GLFWwindowfocusfun glfwSetWindowFocusCallback (GLFWwindow *window, GLFWwindowfocusfun callback)
 Sets the focus callback for the specified window.
 
GLFWwindowiconifyfun glfwSetWindowIconifyCallback (GLFWwindow *window, GLFWwindowiconifyfun callback)
 Sets the iconify callback for the specified window.
 
GLFWwindowmaximizefun glfwSetWindowMaximizeCallback (GLFWwindow *window, GLFWwindowmaximizefun callback)
 Sets the maximize callback for the specified window.
 
GLFWframebuffersizefun glfwSetFramebufferSizeCallback (GLFWwindow *window, GLFWframebuffersizefun callback)
 Sets the framebuffer resize callback for the specified window.
 
GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback (GLFWwindow *window, GLFWwindowcontentscalefun callback)
 Sets the window content scale callback for the specified window.
 
void glfwPollEvents (void)
 Processes all pending events.
 
void glfwWaitEvents (void)
 Waits until events are queued and processes them.
 
void glfwWaitEventsTimeout (double timeout)
 Waits with timeout until events are queued and processes them.
 
void glfwPostEmptyEvent (void)
 Posts an empty event to the event queue.
 
int glfwGetInputMode (GLFWwindow *window, int mode)
 Returns the value of an input option for the specified window.
 
void glfwSetInputMode (GLFWwindow *window, int mode, int value)
 Sets an input option for the specified window.
 
int glfwRawMouseMotionSupported (void)
 Returns whether raw mouse motion is supported.
 
const char * glfwGetKeyName (int key, int scancode)
 Returns the layout-specific name of the specified printable key.
 
int glfwGetKeyScancode (int key)
 Returns the platform-specific scancode of the specified key.
 
int glfwGetKey (GLFWwindow *window, int key)
 Returns the last reported state of a keyboard key for the specified window.
 
int glfwGetMouseButton (GLFWwindow *window, int button)
 Returns the last reported state of a mouse button for the specified window.
 
void glfwGetCursorPos (GLFWwindow *window, double *xpos, double *ypos)
 Retrieves the position of the cursor relative to the content area of the window.
 
void glfwSetCursorPos (GLFWwindow *window, double xpos, double ypos)
 Sets the position of the cursor, relative to the content area of the window.
 
GLFWcursorglfwCreateCursor (const GLFWimage *image, int xhot, int yhot)
 Creates a custom cursor.
 
GLFWcursorglfwCreateStandardCursor (int shape)
 Creates a cursor with a standard shape.
 
void glfwDestroyCursor (GLFWcursor *cursor)
 Destroys a cursor.
 
void glfwSetCursor (GLFWwindow *window, GLFWcursor *cursor)
 Sets the cursor for the window.
 
GLFWkeyfun glfwSetKeyCallback (GLFWwindow *window, GLFWkeyfun callback)
 Sets the key callback.
 
GLFWcharfun glfwSetCharCallback (GLFWwindow *window, GLFWcharfun callback)
 Sets the Unicode character callback.
 
GLFWcharmodsfun glfwSetCharModsCallback (GLFWwindow *window, GLFWcharmodsfun callback)
 Sets the Unicode character with modifiers callback.
 
GLFWmousebuttonfun glfwSetMouseButtonCallback (GLFWwindow *window, GLFWmousebuttonfun callback)
 Sets the mouse button callback.
 
GLFWcursorposfun glfwSetCursorPosCallback (GLFWwindow *window, GLFWcursorposfun callback)
 Sets the cursor position callback.
 
GLFWcursorenterfun glfwSetCursorEnterCallback (GLFWwindow *window, GLFWcursorenterfun callback)
 Sets the cursor enter/leave callback.
 
GLFWscrollfun glfwSetScrollCallback (GLFWwindow *window, GLFWscrollfun callback)
 Sets the scroll callback.
 
GLFWdropfun glfwSetDropCallback (GLFWwindow *window, GLFWdropfun callback)
 Sets the path drop callback.
 
int glfwJoystickPresent (int jid)
 Returns whether the specified joystick is present.
 
const float * glfwGetJoystickAxes (int jid, int *count)
 Returns the values of all axes of the specified joystick.
 
const unsigned char * glfwGetJoystickButtons (int jid, int *count)
 Returns the state of all buttons of the specified joystick.
 
const unsigned char * glfwGetJoystickHats (int jid, int *count)
 Returns the state of all hats of the specified joystick.
 
const char * glfwGetJoystickName (int jid)
 Returns the name of the specified joystick.
 
const char * glfwGetJoystickGUID (int jid)
 Returns the SDL compatible GUID of the specified joystick.
 
void glfwSetJoystickUserPointer (int jid, void *pointer)
 Sets the user pointer of the specified joystick.
 
void * glfwGetJoystickUserPointer (int jid)
 Returns the user pointer of the specified joystick.
 
int glfwJoystickIsGamepad (int jid)
 Returns whether the specified joystick has a gamepad mapping.
 
GLFWjoystickfun glfwSetJoystickCallback (GLFWjoystickfun callback)
 Sets the joystick configuration callback.
 
int glfwUpdateGamepadMappings (const char *string)
 Adds the specified SDL_GameControllerDB gamepad mappings.
 
const char * glfwGetGamepadName (int jid)
 Returns the human-readable gamepad name for the specified joystick.
 
int glfwGetGamepadState (int jid, GLFWgamepadstate *state)
 Retrieves the state of the specified joystick remapped as a gamepad.
 
void glfwSetClipboardString (GLFWwindow *window, const char *string)
 Sets the clipboard to the specified string.
 
const char * glfwGetClipboardString (GLFWwindow *window)
 Returns the contents of the clipboard as a string.
 
double glfwGetTime (void)
 Returns the GLFW time.
 
void glfwSetTime (double time)
 Sets the GLFW time.
 
uint64_t glfwGetTimerValue (void)
 Returns the current value of the raw timer.
 
uint64_t glfwGetTimerFrequency (void)
 Returns the frequency, in Hz, of the raw timer.
 
void glfwMakeContextCurrent (GLFWwindow *window)
 Makes the context of the specified window current for the calling thread.
 
GLFWwindowglfwGetCurrentContext (void)
 Returns the window whose context is current on the calling thread.
 
void glfwSwapBuffers (GLFWwindow *window)
 Swaps the front and back buffers of the specified window.
 
void glfwSwapInterval (int interval)
 Sets the swap interval for the current context.
 
int glfwExtensionSupported (const char *extension)
 Returns whether the specified extension is available.
 
GLFWglproc glfwGetProcAddress (const char *procname)
 Returns the address of the specified function for the current context.
 
int glfwVulkanSupported (void)
 Returns whether the Vulkan loader and an ICD have been found.
 
const char ** glfwGetRequiredInstanceExtensions (uint32_t *count)
 Returns the Vulkan instance extensions required by GLFW.
 
GLFWvkproc glfwGetInstanceProcAddress (VkInstance instance, const char *procname)
 Returns the address of the specified Vulkan instance function.
 
int glfwGetPhysicalDevicePresentationSupport (VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily)
 Returns whether the specified queue family can present images.
 
VkResult glfwCreateWindowSurface (VkInstance instance, GLFWwindow *window, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
 Creates a Vulkan surface for the specified window.
 
+

Macro Definition Documentation

+ +

◆ GLFW_APIENTRY_DEFINED

+ +
+
+ + + + +
#define GLFW_APIENTRY_DEFINED
+
+ +
+
+ +

◆ GLFW_NO_API

+ +
+
+ + + + +
#define GLFW_NO_API   0
+
+ +
+
+ +

◆ GLFW_OPENGL_API

+ +
+
+ + + + +
#define GLFW_OPENGL_API   0x00030001
+
+ +
+
+ +

◆ GLFW_OPENGL_ES_API

+ +
+
+ + + + +
#define GLFW_OPENGL_ES_API   0x00030002
+
+ +
+
+ +

◆ GLFW_NO_ROBUSTNESS

+ +
+
+ + + + +
#define GLFW_NO_ROBUSTNESS   0
+
+ +
+
+ +

◆ GLFW_NO_RESET_NOTIFICATION

+ +
+
+ + + + +
#define GLFW_NO_RESET_NOTIFICATION   0x00031001
+
+ +
+
+ +

◆ GLFW_LOSE_CONTEXT_ON_RESET

+ +
+
+ + + + +
#define GLFW_LOSE_CONTEXT_ON_RESET   0x00031002
+
+ +
+
+ +

◆ GLFW_OPENGL_ANY_PROFILE

+ +
+
+ + + + +
#define GLFW_OPENGL_ANY_PROFILE   0
+
+ +
+
+ +

◆ GLFW_OPENGL_CORE_PROFILE

+ +
+
+ + + + +
#define GLFW_OPENGL_CORE_PROFILE   0x00032001
+
+ +
+
+ +

◆ GLFW_OPENGL_COMPAT_PROFILE

+ +
+
+ + + + +
#define GLFW_OPENGL_COMPAT_PROFILE   0x00032002
+
+ +
+
+ +

◆ GLFW_CURSOR

+ +
+
+ + + + +
#define GLFW_CURSOR   0x00033001
+
+ +
+
+ +

◆ GLFW_STICKY_KEYS

+ +
+
+ + + + +
#define GLFW_STICKY_KEYS   0x00033002
+
+ +
+
+ +

◆ GLFW_STICKY_MOUSE_BUTTONS

+ +
+
+ + + + +
#define GLFW_STICKY_MOUSE_BUTTONS   0x00033003
+
+ +
+
+ +

◆ GLFW_LOCK_KEY_MODS

+ +
+
+ + + + +
#define GLFW_LOCK_KEY_MODS   0x00033004
+
+ +
+
+ +

◆ GLFW_RAW_MOUSE_MOTION

+ +
+
+ + + + +
#define GLFW_RAW_MOUSE_MOTION   0x00033005
+
+ +
+
+ +

◆ GLFW_CURSOR_NORMAL

+ +
+
+ + + + +
#define GLFW_CURSOR_NORMAL   0x00034001
+
+ +
+
+ +

◆ GLFW_CURSOR_HIDDEN

+ +
+
+ + + + +
#define GLFW_CURSOR_HIDDEN   0x00034002
+
+ +
+
+ +

◆ GLFW_CURSOR_DISABLED

+ +
+
+ + + + +
#define GLFW_CURSOR_DISABLED   0x00034003
+
+ +
+
+ +

◆ GLFW_CURSOR_CAPTURED

+ +
+
+ + + + +
#define GLFW_CURSOR_CAPTURED   0x00034004
+
+ +
+
+ +

◆ GLFW_ANY_RELEASE_BEHAVIOR

+ +
+
+ + + + +
#define GLFW_ANY_RELEASE_BEHAVIOR   0
+
+ +
+
+ +

◆ GLFW_RELEASE_BEHAVIOR_FLUSH

+ +
+
+ + + + +
#define GLFW_RELEASE_BEHAVIOR_FLUSH   0x00035001
+
+ +
+
+ +

◆ GLFW_RELEASE_BEHAVIOR_NONE

+ +
+
+ + + + +
#define GLFW_RELEASE_BEHAVIOR_NONE   0x00035002
+
+ +
+
+ +

◆ GLFW_NATIVE_CONTEXT_API

+ +
+
+ + + + +
#define GLFW_NATIVE_CONTEXT_API   0x00036001
+
+ +
+
+ +

◆ GLFW_EGL_CONTEXT_API

+ +
+
+ + + + +
#define GLFW_EGL_CONTEXT_API   0x00036002
+
+ +
+
+ +

◆ GLFW_OSMESA_CONTEXT_API

+ +
+
+ + + + +
#define GLFW_OSMESA_CONTEXT_API   0x00036003
+
+ +
+
+ +

◆ GLFW_ANGLE_PLATFORM_TYPE_NONE

+ +
+
+ + + + +
#define GLFW_ANGLE_PLATFORM_TYPE_NONE   0x00037001
+
+ +
+
+ +

◆ GLFW_ANGLE_PLATFORM_TYPE_OPENGL

+ +
+
+ + + + +
#define GLFW_ANGLE_PLATFORM_TYPE_OPENGL   0x00037002
+
+ +
+
+ +

◆ GLFW_ANGLE_PLATFORM_TYPE_OPENGLES

+ +
+
+ + + + +
#define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES   0x00037003
+
+ +
+
+ +

◆ GLFW_ANGLE_PLATFORM_TYPE_D3D9

+ +
+
+ + + + +
#define GLFW_ANGLE_PLATFORM_TYPE_D3D9   0x00037004
+
+ +
+
+ +

◆ GLFW_ANGLE_PLATFORM_TYPE_D3D11

+ +
+
+ + + + +
#define GLFW_ANGLE_PLATFORM_TYPE_D3D11   0x00037005
+
+ +
+
+ +

◆ GLFW_ANGLE_PLATFORM_TYPE_VULKAN

+ +
+
+ + + + +
#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN   0x00037007
+
+ +
+
+ +

◆ GLFW_ANGLE_PLATFORM_TYPE_METAL

+ +
+
+ + + + +
#define GLFW_ANGLE_PLATFORM_TYPE_METAL   0x00037008
+
+ +
+
+ +

◆ GLFW_WAYLAND_PREFER_LIBDECOR

+ +
+
+ + + + +
#define GLFW_WAYLAND_PREFER_LIBDECOR   0x00038001
+
+ +
+
+ +

◆ GLFW_WAYLAND_DISABLE_LIBDECOR

+ +
+
+ + + + +
#define GLFW_WAYLAND_DISABLE_LIBDECOR   0x00038002
+
+ +
+
+ +

◆ GLFW_ANY_POSITION

+ +
+
+ + + + +
#define GLFW_ANY_POSITION   0x80000000
+
+ +
+
+ +

◆ GLFW_CONNECTED

+ +
+
+ + + + +
#define GLFW_CONNECTED   0x00040001
+
+ +
+
+ +

◆ GLFW_DISCONNECTED

+ +
+
+ + + + +
#define GLFW_DISCONNECTED   0x00040002
+
+ +
+
+ +

◆ GLFW_DONT_CARE

+ +
+
+ + + + +
#define GLFW_DONT_CARE   -1
+
+ +
+
+ +

◆ GLAPIENTRY

+ +
+
+ + + + +
#define GLAPIENTRY   APIENTRY
+
+ +
+
+ +

◆ GLFW_GLAPIENTRY_DEFINED

+ +
+
+ + + + +
#define GLFW_GLAPIENTRY_DEFINED
+
+ +
+
+
+ + + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/glfw3_8h_source.html b/src/lib/src/vendor/glfw-3.4/docs/html/glfw3_8h_source.html similarity index 66% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/glfw3_8h_source.html rename to src/lib/src/vendor/glfw-3.4/docs/html/glfw3_8h_source.html index be04039..9af3200 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/glfw3_8h_source.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/glfw3_8h_source.html @@ -4,7 +4,7 @@ - + GLFW: glfw3.h Source File @@ -28,10 +28,10 @@
- + @@ -45,6 +45,11 @@ $(function() { /* @license-end */ +
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -69,7 +81,7 @@ $(function() {
Go to the documentation of this file.
1/*************************************************************************
-
2 * GLFW 3.3 - www.glfw.org
+
2 * GLFW 3.4 - www.glfw.org
3 * A library for OpenGL, window and input
4 *------------------------------------------------------------------------
5 * Copyright (c) 2002-2006 Marcus Geelnard
@@ -288,7 +300,7 @@ $(function() {
266 #define GLFWAPI __declspec(dllimport)
267#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)
268 /* We are building GLFW as a Unix shared library */
-
269 #define GLFWAPI __attribute__((visibility("default")))
+
269 #define GLFWAPI __attribute__((visibility("default")))
270#else
271 #define GLFWAPI
272#endif
@@ -299,8 +311,8 @@ $(function() {
277 *************************************************************************/
278
287#define GLFW_VERSION_MAJOR 3
-
294#define GLFW_VERSION_MINOR 3
-
301#define GLFW_VERSION_REVISION 8
+
294#define GLFW_VERSION_MINOR 4
+
301#define GLFW_VERSION_REVISION 0
312#define GLFW_TRUE 1
321#define GLFW_FALSE 0
322
@@ -316,722 +328,812 @@ $(function() {
361#define GLFW_HAT_RIGHT_DOWN (GLFW_HAT_RIGHT | GLFW_HAT_DOWN)
362#define GLFW_HAT_LEFT_UP (GLFW_HAT_LEFT | GLFW_HAT_UP)
363#define GLFW_HAT_LEFT_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN)
-
390/* The unknown key */
-
391#define GLFW_KEY_UNKNOWN -1
-
392
-
393/* Printable keys */
-
394#define GLFW_KEY_SPACE 32
-
395#define GLFW_KEY_APOSTROPHE 39 /* ' */
-
396#define GLFW_KEY_COMMA 44 /* , */
-
397#define GLFW_KEY_MINUS 45 /* - */
-
398#define GLFW_KEY_PERIOD 46 /* . */
-
399#define GLFW_KEY_SLASH 47 /* / */
-
400#define GLFW_KEY_0 48
-
401#define GLFW_KEY_1 49
-
402#define GLFW_KEY_2 50
-
403#define GLFW_KEY_3 51
-
404#define GLFW_KEY_4 52
-
405#define GLFW_KEY_5 53
-
406#define GLFW_KEY_6 54
-
407#define GLFW_KEY_7 55
-
408#define GLFW_KEY_8 56
-
409#define GLFW_KEY_9 57
-
410#define GLFW_KEY_SEMICOLON 59 /* ; */
-
411#define GLFW_KEY_EQUAL 61 /* = */
-
412#define GLFW_KEY_A 65
-
413#define GLFW_KEY_B 66
-
414#define GLFW_KEY_C 67
-
415#define GLFW_KEY_D 68
-
416#define GLFW_KEY_E 69
-
417#define GLFW_KEY_F 70
-
418#define GLFW_KEY_G 71
-
419#define GLFW_KEY_H 72
-
420#define GLFW_KEY_I 73
-
421#define GLFW_KEY_J 74
-
422#define GLFW_KEY_K 75
-
423#define GLFW_KEY_L 76
-
424#define GLFW_KEY_M 77
-
425#define GLFW_KEY_N 78
-
426#define GLFW_KEY_O 79
-
427#define GLFW_KEY_P 80
-
428#define GLFW_KEY_Q 81
-
429#define GLFW_KEY_R 82
-
430#define GLFW_KEY_S 83
-
431#define GLFW_KEY_T 84
-
432#define GLFW_KEY_U 85
-
433#define GLFW_KEY_V 86
-
434#define GLFW_KEY_W 87
-
435#define GLFW_KEY_X 88
-
436#define GLFW_KEY_Y 89
-
437#define GLFW_KEY_Z 90
-
438#define GLFW_KEY_LEFT_BRACKET 91 /* [ */
-
439#define GLFW_KEY_BACKSLASH 92 /* \ */
-
440#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */
-
441#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */
-
442#define GLFW_KEY_WORLD_1 161 /* non-US #1 */
-
443#define GLFW_KEY_WORLD_2 162 /* non-US #2 */
-
444
-
445/* Function keys */
-
446#define GLFW_KEY_ESCAPE 256
-
447#define GLFW_KEY_ENTER 257
-
448#define GLFW_KEY_TAB 258
-
449#define GLFW_KEY_BACKSPACE 259
-
450#define GLFW_KEY_INSERT 260
-
451#define GLFW_KEY_DELETE 261
-
452#define GLFW_KEY_RIGHT 262
-
453#define GLFW_KEY_LEFT 263
-
454#define GLFW_KEY_DOWN 264
-
455#define GLFW_KEY_UP 265
-
456#define GLFW_KEY_PAGE_UP 266
-
457#define GLFW_KEY_PAGE_DOWN 267
-
458#define GLFW_KEY_HOME 268
-
459#define GLFW_KEY_END 269
-
460#define GLFW_KEY_CAPS_LOCK 280
-
461#define GLFW_KEY_SCROLL_LOCK 281
-
462#define GLFW_KEY_NUM_LOCK 282
-
463#define GLFW_KEY_PRINT_SCREEN 283
-
464#define GLFW_KEY_PAUSE 284
-
465#define GLFW_KEY_F1 290
-
466#define GLFW_KEY_F2 291
-
467#define GLFW_KEY_F3 292
-
468#define GLFW_KEY_F4 293
-
469#define GLFW_KEY_F5 294
-
470#define GLFW_KEY_F6 295
-
471#define GLFW_KEY_F7 296
-
472#define GLFW_KEY_F8 297
-
473#define GLFW_KEY_F9 298
-
474#define GLFW_KEY_F10 299
-
475#define GLFW_KEY_F11 300
-
476#define GLFW_KEY_F12 301
-
477#define GLFW_KEY_F13 302
-
478#define GLFW_KEY_F14 303
-
479#define GLFW_KEY_F15 304
-
480#define GLFW_KEY_F16 305
-
481#define GLFW_KEY_F17 306
-
482#define GLFW_KEY_F18 307
-
483#define GLFW_KEY_F19 308
-
484#define GLFW_KEY_F20 309
-
485#define GLFW_KEY_F21 310
-
486#define GLFW_KEY_F22 311
-
487#define GLFW_KEY_F23 312
-
488#define GLFW_KEY_F24 313
-
489#define GLFW_KEY_F25 314
-
490#define GLFW_KEY_KP_0 320
-
491#define GLFW_KEY_KP_1 321
-
492#define GLFW_KEY_KP_2 322
-
493#define GLFW_KEY_KP_3 323
-
494#define GLFW_KEY_KP_4 324
-
495#define GLFW_KEY_KP_5 325
-
496#define GLFW_KEY_KP_6 326
-
497#define GLFW_KEY_KP_7 327
-
498#define GLFW_KEY_KP_8 328
-
499#define GLFW_KEY_KP_9 329
-
500#define GLFW_KEY_KP_DECIMAL 330
-
501#define GLFW_KEY_KP_DIVIDE 331
-
502#define GLFW_KEY_KP_MULTIPLY 332
-
503#define GLFW_KEY_KP_SUBTRACT 333
-
504#define GLFW_KEY_KP_ADD 334
-
505#define GLFW_KEY_KP_ENTER 335
-
506#define GLFW_KEY_KP_EQUAL 336
-
507#define GLFW_KEY_LEFT_SHIFT 340
-
508#define GLFW_KEY_LEFT_CONTROL 341
-
509#define GLFW_KEY_LEFT_ALT 342
-
510#define GLFW_KEY_LEFT_SUPER 343
-
511#define GLFW_KEY_RIGHT_SHIFT 344
-
512#define GLFW_KEY_RIGHT_CONTROL 345
-
513#define GLFW_KEY_RIGHT_ALT 346
-
514#define GLFW_KEY_RIGHT_SUPER 347
-
515#define GLFW_KEY_MENU 348
-
516
-
517#define GLFW_KEY_LAST GLFW_KEY_MENU
+
364
+
367#define GLFW_KEY_UNKNOWN -1
+
368
+
395/* Printable keys */
+
396#define GLFW_KEY_SPACE 32
+
397#define GLFW_KEY_APOSTROPHE 39 /* ' */
+
398#define GLFW_KEY_COMMA 44 /* , */
+
399#define GLFW_KEY_MINUS 45 /* - */
+
400#define GLFW_KEY_PERIOD 46 /* . */
+
401#define GLFW_KEY_SLASH 47 /* / */
+
402#define GLFW_KEY_0 48
+
403#define GLFW_KEY_1 49
+
404#define GLFW_KEY_2 50
+
405#define GLFW_KEY_3 51
+
406#define GLFW_KEY_4 52
+
407#define GLFW_KEY_5 53
+
408#define GLFW_KEY_6 54
+
409#define GLFW_KEY_7 55
+
410#define GLFW_KEY_8 56
+
411#define GLFW_KEY_9 57
+
412#define GLFW_KEY_SEMICOLON 59 /* ; */
+
413#define GLFW_KEY_EQUAL 61 /* = */
+
414#define GLFW_KEY_A 65
+
415#define GLFW_KEY_B 66
+
416#define GLFW_KEY_C 67
+
417#define GLFW_KEY_D 68
+
418#define GLFW_KEY_E 69
+
419#define GLFW_KEY_F 70
+
420#define GLFW_KEY_G 71
+
421#define GLFW_KEY_H 72
+
422#define GLFW_KEY_I 73
+
423#define GLFW_KEY_J 74
+
424#define GLFW_KEY_K 75
+
425#define GLFW_KEY_L 76
+
426#define GLFW_KEY_M 77
+
427#define GLFW_KEY_N 78
+
428#define GLFW_KEY_O 79
+
429#define GLFW_KEY_P 80
+
430#define GLFW_KEY_Q 81
+
431#define GLFW_KEY_R 82
+
432#define GLFW_KEY_S 83
+
433#define GLFW_KEY_T 84
+
434#define GLFW_KEY_U 85
+
435#define GLFW_KEY_V 86
+
436#define GLFW_KEY_W 87
+
437#define GLFW_KEY_X 88
+
438#define GLFW_KEY_Y 89
+
439#define GLFW_KEY_Z 90
+
440#define GLFW_KEY_LEFT_BRACKET 91 /* [ */
+
441#define GLFW_KEY_BACKSLASH 92 /* \ */
+
442#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */
+
443#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */
+
444#define GLFW_KEY_WORLD_1 161 /* non-US #1 */
+
445#define GLFW_KEY_WORLD_2 162 /* non-US #2 */
+
446
+
447/* Function keys */
+
448#define GLFW_KEY_ESCAPE 256
+
449#define GLFW_KEY_ENTER 257
+
450#define GLFW_KEY_TAB 258
+
451#define GLFW_KEY_BACKSPACE 259
+
452#define GLFW_KEY_INSERT 260
+
453#define GLFW_KEY_DELETE 261
+
454#define GLFW_KEY_RIGHT 262
+
455#define GLFW_KEY_LEFT 263
+
456#define GLFW_KEY_DOWN 264
+
457#define GLFW_KEY_UP 265
+
458#define GLFW_KEY_PAGE_UP 266
+
459#define GLFW_KEY_PAGE_DOWN 267
+
460#define GLFW_KEY_HOME 268
+
461#define GLFW_KEY_END 269
+
462#define GLFW_KEY_CAPS_LOCK 280
+
463#define GLFW_KEY_SCROLL_LOCK 281
+
464#define GLFW_KEY_NUM_LOCK 282
+
465#define GLFW_KEY_PRINT_SCREEN 283
+
466#define GLFW_KEY_PAUSE 284
+
467#define GLFW_KEY_F1 290
+
468#define GLFW_KEY_F2 291
+
469#define GLFW_KEY_F3 292
+
470#define GLFW_KEY_F4 293
+
471#define GLFW_KEY_F5 294
+
472#define GLFW_KEY_F6 295
+
473#define GLFW_KEY_F7 296
+
474#define GLFW_KEY_F8 297
+
475#define GLFW_KEY_F9 298
+
476#define GLFW_KEY_F10 299
+
477#define GLFW_KEY_F11 300
+
478#define GLFW_KEY_F12 301
+
479#define GLFW_KEY_F13 302
+
480#define GLFW_KEY_F14 303
+
481#define GLFW_KEY_F15 304
+
482#define GLFW_KEY_F16 305
+
483#define GLFW_KEY_F17 306
+
484#define GLFW_KEY_F18 307
+
485#define GLFW_KEY_F19 308
+
486#define GLFW_KEY_F20 309
+
487#define GLFW_KEY_F21 310
+
488#define GLFW_KEY_F22 311
+
489#define GLFW_KEY_F23 312
+
490#define GLFW_KEY_F24 313
+
491#define GLFW_KEY_F25 314
+
492#define GLFW_KEY_KP_0 320
+
493#define GLFW_KEY_KP_1 321
+
494#define GLFW_KEY_KP_2 322
+
495#define GLFW_KEY_KP_3 323
+
496#define GLFW_KEY_KP_4 324
+
497#define GLFW_KEY_KP_5 325
+
498#define GLFW_KEY_KP_6 326
+
499#define GLFW_KEY_KP_7 327
+
500#define GLFW_KEY_KP_8 328
+
501#define GLFW_KEY_KP_9 329
+
502#define GLFW_KEY_KP_DECIMAL 330
+
503#define GLFW_KEY_KP_DIVIDE 331
+
504#define GLFW_KEY_KP_MULTIPLY 332
+
505#define GLFW_KEY_KP_SUBTRACT 333
+
506#define GLFW_KEY_KP_ADD 334
+
507#define GLFW_KEY_KP_ENTER 335
+
508#define GLFW_KEY_KP_EQUAL 336
+
509#define GLFW_KEY_LEFT_SHIFT 340
+
510#define GLFW_KEY_LEFT_CONTROL 341
+
511#define GLFW_KEY_LEFT_ALT 342
+
512#define GLFW_KEY_LEFT_SUPER 343
+
513#define GLFW_KEY_RIGHT_SHIFT 344
+
514#define GLFW_KEY_RIGHT_CONTROL 345
+
515#define GLFW_KEY_RIGHT_ALT 346
+
516#define GLFW_KEY_RIGHT_SUPER 347
+
517#define GLFW_KEY_MENU 348
518
-
533#define GLFW_MOD_SHIFT 0x0001
-
538#define GLFW_MOD_CONTROL 0x0002
-
543#define GLFW_MOD_ALT 0x0004
-
548#define GLFW_MOD_SUPER 0x0008
-
554#define GLFW_MOD_CAPS_LOCK 0x0010
-
560#define GLFW_MOD_NUM_LOCK 0x0020
-
561
-
571#define GLFW_MOUSE_BUTTON_1 0
-
572#define GLFW_MOUSE_BUTTON_2 1
-
573#define GLFW_MOUSE_BUTTON_3 2
-
574#define GLFW_MOUSE_BUTTON_4 3
-
575#define GLFW_MOUSE_BUTTON_5 4
-
576#define GLFW_MOUSE_BUTTON_6 5
-
577#define GLFW_MOUSE_BUTTON_7 6
-
578#define GLFW_MOUSE_BUTTON_8 7
-
579#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8
-
580#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1
-
581#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2
-
582#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3
-
592#define GLFW_JOYSTICK_1 0
-
593#define GLFW_JOYSTICK_2 1
-
594#define GLFW_JOYSTICK_3 2
-
595#define GLFW_JOYSTICK_4 3
-
596#define GLFW_JOYSTICK_5 4
-
597#define GLFW_JOYSTICK_6 5
-
598#define GLFW_JOYSTICK_7 6
-
599#define GLFW_JOYSTICK_8 7
-
600#define GLFW_JOYSTICK_9 8
-
601#define GLFW_JOYSTICK_10 9
-
602#define GLFW_JOYSTICK_11 10
-
603#define GLFW_JOYSTICK_12 11
-
604#define GLFW_JOYSTICK_13 12
-
605#define GLFW_JOYSTICK_14 13
-
606#define GLFW_JOYSTICK_15 14
-
607#define GLFW_JOYSTICK_16 15
-
608#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16
-
618#define GLFW_GAMEPAD_BUTTON_A 0
-
619#define GLFW_GAMEPAD_BUTTON_B 1
-
620#define GLFW_GAMEPAD_BUTTON_X 2
-
621#define GLFW_GAMEPAD_BUTTON_Y 3
-
622#define GLFW_GAMEPAD_BUTTON_LEFT_BUMPER 4
-
623#define GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER 5
-
624#define GLFW_GAMEPAD_BUTTON_BACK 6
-
625#define GLFW_GAMEPAD_BUTTON_START 7
-
626#define GLFW_GAMEPAD_BUTTON_GUIDE 8
-
627#define GLFW_GAMEPAD_BUTTON_LEFT_THUMB 9
-
628#define GLFW_GAMEPAD_BUTTON_RIGHT_THUMB 10
-
629#define GLFW_GAMEPAD_BUTTON_DPAD_UP 11
-
630#define GLFW_GAMEPAD_BUTTON_DPAD_RIGHT 12
-
631#define GLFW_GAMEPAD_BUTTON_DPAD_DOWN 13
-
632#define GLFW_GAMEPAD_BUTTON_DPAD_LEFT 14
-
633#define GLFW_GAMEPAD_BUTTON_LAST GLFW_GAMEPAD_BUTTON_DPAD_LEFT
-
634
-
635#define GLFW_GAMEPAD_BUTTON_CROSS GLFW_GAMEPAD_BUTTON_A
-
636#define GLFW_GAMEPAD_BUTTON_CIRCLE GLFW_GAMEPAD_BUTTON_B
-
637#define GLFW_GAMEPAD_BUTTON_SQUARE GLFW_GAMEPAD_BUTTON_X
-
638#define GLFW_GAMEPAD_BUTTON_TRIANGLE GLFW_GAMEPAD_BUTTON_Y
-
648#define GLFW_GAMEPAD_AXIS_LEFT_X 0
-
649#define GLFW_GAMEPAD_AXIS_LEFT_Y 1
-
650#define GLFW_GAMEPAD_AXIS_RIGHT_X 2
-
651#define GLFW_GAMEPAD_AXIS_RIGHT_Y 3
-
652#define GLFW_GAMEPAD_AXIS_LEFT_TRIGGER 4
-
653#define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER 5
-
654#define GLFW_GAMEPAD_AXIS_LAST GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
-
670#define GLFW_NO_ERROR 0
-
679#define GLFW_NOT_INITIALIZED 0x00010001
-
689#define GLFW_NO_CURRENT_CONTEXT 0x00010002
-
697#define GLFW_INVALID_ENUM 0x00010003
-
708#define GLFW_INVALID_VALUE 0x00010004
-
716#define GLFW_OUT_OF_MEMORY 0x00010005
-
732#define GLFW_API_UNAVAILABLE 0x00010006
-
749#define GLFW_VERSION_UNAVAILABLE 0x00010007
-
760#define GLFW_PLATFORM_ERROR 0x00010008
-
779#define GLFW_FORMAT_UNAVAILABLE 0x00010009
-
787#define GLFW_NO_WINDOW_CONTEXT 0x0001000A
-
797#define GLFW_FOCUSED 0x00020001
-
802#define GLFW_ICONIFIED 0x00020002
-
808#define GLFW_RESIZABLE 0x00020003
-
814#define GLFW_VISIBLE 0x00020004
-
820#define GLFW_DECORATED 0x00020005
-
826#define GLFW_AUTO_ICONIFY 0x00020006
-
832#define GLFW_FLOATING 0x00020007
-
838#define GLFW_MAXIMIZED 0x00020008
-
843#define GLFW_CENTER_CURSOR 0x00020009
-
850#define GLFW_TRANSPARENT_FRAMEBUFFER 0x0002000A
-
855#define GLFW_HOVERED 0x0002000B
-
861#define GLFW_FOCUS_ON_SHOW 0x0002000C
-
862
-
867#define GLFW_RED_BITS 0x00021001
-
872#define GLFW_GREEN_BITS 0x00021002
-
877#define GLFW_BLUE_BITS 0x00021003
-
882#define GLFW_ALPHA_BITS 0x00021004
-
887#define GLFW_DEPTH_BITS 0x00021005
-
892#define GLFW_STENCIL_BITS 0x00021006
-
897#define GLFW_ACCUM_RED_BITS 0x00021007
-
902#define GLFW_ACCUM_GREEN_BITS 0x00021008
-
907#define GLFW_ACCUM_BLUE_BITS 0x00021009
-
912#define GLFW_ACCUM_ALPHA_BITS 0x0002100A
-
917#define GLFW_AUX_BUFFERS 0x0002100B
-
922#define GLFW_STEREO 0x0002100C
-
927#define GLFW_SAMPLES 0x0002100D
-
932#define GLFW_SRGB_CAPABLE 0x0002100E
-
937#define GLFW_REFRESH_RATE 0x0002100F
-
942#define GLFW_DOUBLEBUFFER 0x00021010
+
519#define GLFW_KEY_LAST GLFW_KEY_MENU
+
520
+
535#define GLFW_MOD_SHIFT 0x0001
+
540#define GLFW_MOD_CONTROL 0x0002
+
545#define GLFW_MOD_ALT 0x0004
+
550#define GLFW_MOD_SUPER 0x0008
+
556#define GLFW_MOD_CAPS_LOCK 0x0010
+
562#define GLFW_MOD_NUM_LOCK 0x0020
+
563
+
573#define GLFW_MOUSE_BUTTON_1 0
+
574#define GLFW_MOUSE_BUTTON_2 1
+
575#define GLFW_MOUSE_BUTTON_3 2
+
576#define GLFW_MOUSE_BUTTON_4 3
+
577#define GLFW_MOUSE_BUTTON_5 4
+
578#define GLFW_MOUSE_BUTTON_6 5
+
579#define GLFW_MOUSE_BUTTON_7 6
+
580#define GLFW_MOUSE_BUTTON_8 7
+
581#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8
+
582#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1
+
583#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2
+
584#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3
+
594#define GLFW_JOYSTICK_1 0
+
595#define GLFW_JOYSTICK_2 1
+
596#define GLFW_JOYSTICK_3 2
+
597#define GLFW_JOYSTICK_4 3
+
598#define GLFW_JOYSTICK_5 4
+
599#define GLFW_JOYSTICK_6 5
+
600#define GLFW_JOYSTICK_7 6
+
601#define GLFW_JOYSTICK_8 7
+
602#define GLFW_JOYSTICK_9 8
+
603#define GLFW_JOYSTICK_10 9
+
604#define GLFW_JOYSTICK_11 10
+
605#define GLFW_JOYSTICK_12 11
+
606#define GLFW_JOYSTICK_13 12
+
607#define GLFW_JOYSTICK_14 13
+
608#define GLFW_JOYSTICK_15 14
+
609#define GLFW_JOYSTICK_16 15
+
610#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16
+
620#define GLFW_GAMEPAD_BUTTON_A 0
+
621#define GLFW_GAMEPAD_BUTTON_B 1
+
622#define GLFW_GAMEPAD_BUTTON_X 2
+
623#define GLFW_GAMEPAD_BUTTON_Y 3
+
624#define GLFW_GAMEPAD_BUTTON_LEFT_BUMPER 4
+
625#define GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER 5
+
626#define GLFW_GAMEPAD_BUTTON_BACK 6
+
627#define GLFW_GAMEPAD_BUTTON_START 7
+
628#define GLFW_GAMEPAD_BUTTON_GUIDE 8
+
629#define GLFW_GAMEPAD_BUTTON_LEFT_THUMB 9
+
630#define GLFW_GAMEPAD_BUTTON_RIGHT_THUMB 10
+
631#define GLFW_GAMEPAD_BUTTON_DPAD_UP 11
+
632#define GLFW_GAMEPAD_BUTTON_DPAD_RIGHT 12
+
633#define GLFW_GAMEPAD_BUTTON_DPAD_DOWN 13
+
634#define GLFW_GAMEPAD_BUTTON_DPAD_LEFT 14
+
635#define GLFW_GAMEPAD_BUTTON_LAST GLFW_GAMEPAD_BUTTON_DPAD_LEFT
+
636
+
637#define GLFW_GAMEPAD_BUTTON_CROSS GLFW_GAMEPAD_BUTTON_A
+
638#define GLFW_GAMEPAD_BUTTON_CIRCLE GLFW_GAMEPAD_BUTTON_B
+
639#define GLFW_GAMEPAD_BUTTON_SQUARE GLFW_GAMEPAD_BUTTON_X
+
640#define GLFW_GAMEPAD_BUTTON_TRIANGLE GLFW_GAMEPAD_BUTTON_Y
+
650#define GLFW_GAMEPAD_AXIS_LEFT_X 0
+
651#define GLFW_GAMEPAD_AXIS_LEFT_Y 1
+
652#define GLFW_GAMEPAD_AXIS_RIGHT_X 2
+
653#define GLFW_GAMEPAD_AXIS_RIGHT_Y 3
+
654#define GLFW_GAMEPAD_AXIS_LEFT_TRIGGER 4
+
655#define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER 5
+
656#define GLFW_GAMEPAD_AXIS_LAST GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
+
672#define GLFW_NO_ERROR 0
+
681#define GLFW_NOT_INITIALIZED 0x00010001
+
691#define GLFW_NO_CURRENT_CONTEXT 0x00010002
+
699#define GLFW_INVALID_ENUM 0x00010003
+
710#define GLFW_INVALID_VALUE 0x00010004
+
718#define GLFW_OUT_OF_MEMORY 0x00010005
+
734#define GLFW_API_UNAVAILABLE 0x00010006
+
751#define GLFW_VERSION_UNAVAILABLE 0x00010007
+
762#define GLFW_PLATFORM_ERROR 0x00010008
+
781#define GLFW_FORMAT_UNAVAILABLE 0x00010009
+
789#define GLFW_NO_WINDOW_CONTEXT 0x0001000A
+
800#define GLFW_CURSOR_UNAVAILABLE 0x0001000B
+
814#define GLFW_FEATURE_UNAVAILABLE 0x0001000C
+
827#define GLFW_FEATURE_UNIMPLEMENTED 0x0001000D
+
849#define GLFW_PLATFORM_UNAVAILABLE 0x0001000E
+
859#define GLFW_FOCUSED 0x00020001
+
864#define GLFW_ICONIFIED 0x00020002
+
870#define GLFW_RESIZABLE 0x00020003
+
876#define GLFW_VISIBLE 0x00020004
+
882#define GLFW_DECORATED 0x00020005
+
888#define GLFW_AUTO_ICONIFY 0x00020006
+
894#define GLFW_FLOATING 0x00020007
+
900#define GLFW_MAXIMIZED 0x00020008
+
905#define GLFW_CENTER_CURSOR 0x00020009
+
912#define GLFW_TRANSPARENT_FRAMEBUFFER 0x0002000A
+
917#define GLFW_HOVERED 0x0002000B
+
923#define GLFW_FOCUS_ON_SHOW 0x0002000C
+
924
+
930#define GLFW_MOUSE_PASSTHROUGH 0x0002000D
+
931
+
936#define GLFW_POSITION_X 0x0002000E
+
937
+
942#define GLFW_POSITION_Y 0x0002000F
943
-
949#define GLFW_CLIENT_API 0x00022001
-
955#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
-
961#define GLFW_CONTEXT_VERSION_MINOR 0x00022003
-
967#define GLFW_CONTEXT_REVISION 0x00022004
-
973#define GLFW_CONTEXT_ROBUSTNESS 0x00022005
-
979#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
-
985#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007
-
991#define GLFW_OPENGL_PROFILE 0x00022008
-
997#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
-
1003#define GLFW_CONTEXT_NO_ERROR 0x0002200A
-
1009#define GLFW_CONTEXT_CREATION_API 0x0002200B
-
1013#define GLFW_SCALE_TO_MONITOR 0x0002200C
-
1017#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
-
1021#define GLFW_COCOA_FRAME_NAME 0x00023002
-
1025#define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003
-
1029#define GLFW_X11_CLASS_NAME 0x00024001
-
1033#define GLFW_X11_INSTANCE_NAME 0x00024002
-
1036#define GLFW_NO_API 0
-
1037#define GLFW_OPENGL_API 0x00030001
-
1038#define GLFW_OPENGL_ES_API 0x00030002
-
1039
-
1040#define GLFW_NO_ROBUSTNESS 0
-
1041#define GLFW_NO_RESET_NOTIFICATION 0x00031001
-
1042#define GLFW_LOSE_CONTEXT_ON_RESET 0x00031002
-
1043
-
1044#define GLFW_OPENGL_ANY_PROFILE 0
-
1045#define GLFW_OPENGL_CORE_PROFILE 0x00032001
-
1046#define GLFW_OPENGL_COMPAT_PROFILE 0x00032002
-
1047
-
1048#define GLFW_CURSOR 0x00033001
-
1049#define GLFW_STICKY_KEYS 0x00033002
-
1050#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
-
1051#define GLFW_LOCK_KEY_MODS 0x00033004
-
1052#define GLFW_RAW_MOUSE_MOTION 0x00033005
-
1053
-
1054#define GLFW_CURSOR_NORMAL 0x00034001
-
1055#define GLFW_CURSOR_HIDDEN 0x00034002
-
1056#define GLFW_CURSOR_DISABLED 0x00034003
-
1057
-
1058#define GLFW_ANY_RELEASE_BEHAVIOR 0
-
1059#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001
-
1060#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002
-
1061
-
1062#define GLFW_NATIVE_CONTEXT_API 0x00036001
-
1063#define GLFW_EGL_CONTEXT_API 0x00036002
-
1064#define GLFW_OSMESA_CONTEXT_API 0x00036003
-
1065
-
1078#define GLFW_ARROW_CURSOR 0x00036001
-
1083#define GLFW_IBEAM_CURSOR 0x00036002
-
1088#define GLFW_CROSSHAIR_CURSOR 0x00036003
-
1093#define GLFW_HAND_CURSOR 0x00036004
-
1098#define GLFW_HRESIZE_CURSOR 0x00036005
-
1103#define GLFW_VRESIZE_CURSOR 0x00036006
-
1106#define GLFW_CONNECTED 0x00040001
-
1107#define GLFW_DISCONNECTED 0x00040002
-
1108
-
1115#define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001
-
1120#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001
-
1125#define GLFW_COCOA_MENUBAR 0x00051002
-
1128#define GLFW_DONT_CARE -1
-
1129
-
1130
-
1131/*************************************************************************
-
1132 * GLFW API types
-
1133 *************************************************************************/
-
1134
-
1147typedef void (*GLFWglproc)(void);
-
1148
-
1161typedef void (*GLFWvkproc)(void);
+
948#define GLFW_RED_BITS 0x00021001
+
953#define GLFW_GREEN_BITS 0x00021002
+
958#define GLFW_BLUE_BITS 0x00021003
+
963#define GLFW_ALPHA_BITS 0x00021004
+
968#define GLFW_DEPTH_BITS 0x00021005
+
973#define GLFW_STENCIL_BITS 0x00021006
+
978#define GLFW_ACCUM_RED_BITS 0x00021007
+
983#define GLFW_ACCUM_GREEN_BITS 0x00021008
+
988#define GLFW_ACCUM_BLUE_BITS 0x00021009
+
993#define GLFW_ACCUM_ALPHA_BITS 0x0002100A
+
998#define GLFW_AUX_BUFFERS 0x0002100B
+
1003#define GLFW_STEREO 0x0002100C
+
1008#define GLFW_SAMPLES 0x0002100D
+
1013#define GLFW_SRGB_CAPABLE 0x0002100E
+
1018#define GLFW_REFRESH_RATE 0x0002100F
+
1024#define GLFW_DOUBLEBUFFER 0x00021010
+
1025
+
1031#define GLFW_CLIENT_API 0x00022001
+
1037#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
+
1043#define GLFW_CONTEXT_VERSION_MINOR 0x00022003
+
1049#define GLFW_CONTEXT_REVISION 0x00022004
+
1055#define GLFW_CONTEXT_ROBUSTNESS 0x00022005
+
1061#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
+
1067#define GLFW_CONTEXT_DEBUG 0x00022007
+
1072#define GLFW_OPENGL_DEBUG_CONTEXT GLFW_CONTEXT_DEBUG
+
1078#define GLFW_OPENGL_PROFILE 0x00022008
+
1084#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
+
1090#define GLFW_CONTEXT_NO_ERROR 0x0002200A
+
1096#define GLFW_CONTEXT_CREATION_API 0x0002200B
+
1100#define GLFW_SCALE_TO_MONITOR 0x0002200C
+
1104#define GLFW_SCALE_FRAMEBUFFER 0x0002200D
+
1111#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
+
1115#define GLFW_COCOA_FRAME_NAME 0x00023002
+
1119#define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003
+
1123#define GLFW_X11_CLASS_NAME 0x00024001
+
1127#define GLFW_X11_INSTANCE_NAME 0x00024002
+
1128#define GLFW_WIN32_KEYBOARD_MENU 0x00025001
+
1131#define GLFW_WIN32_SHOWDEFAULT 0x00025002
+
1137#define GLFW_WAYLAND_APP_ID 0x00026001
+
1140#define GLFW_NO_API 0
+
1141#define GLFW_OPENGL_API 0x00030001
+
1142#define GLFW_OPENGL_ES_API 0x00030002
+
1143
+
1144#define GLFW_NO_ROBUSTNESS 0
+
1145#define GLFW_NO_RESET_NOTIFICATION 0x00031001
+
1146#define GLFW_LOSE_CONTEXT_ON_RESET 0x00031002
+
1147
+
1148#define GLFW_OPENGL_ANY_PROFILE 0
+
1149#define GLFW_OPENGL_CORE_PROFILE 0x00032001
+
1150#define GLFW_OPENGL_COMPAT_PROFILE 0x00032002
+
1151
+
1152#define GLFW_CURSOR 0x00033001
+
1153#define GLFW_STICKY_KEYS 0x00033002
+
1154#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
+
1155#define GLFW_LOCK_KEY_MODS 0x00033004
+
1156#define GLFW_RAW_MOUSE_MOTION 0x00033005
+
1157
+
1158#define GLFW_CURSOR_NORMAL 0x00034001
+
1159#define GLFW_CURSOR_HIDDEN 0x00034002
+
1160#define GLFW_CURSOR_DISABLED 0x00034003
+
1161#define GLFW_CURSOR_CAPTURED 0x00034004
1162
- -
1174
-
1185typedef struct GLFWwindow GLFWwindow;
-
1186
-
1197typedef struct GLFWcursor GLFWcursor;
-
1198
-
1221typedef void (* GLFWerrorfun)(int error_code, const char* description);
-
1222
-
1244typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos);
-
1245
-
1266typedef void (* GLFWwindowsizefun)(GLFWwindow* window, int width, int height);
-
1267
-
1286typedef void (* GLFWwindowclosefun)(GLFWwindow* window);
-
1287
-
1306typedef void (* GLFWwindowrefreshfun)(GLFWwindow* window);
-
1307
-
1327typedef void (* GLFWwindowfocusfun)(GLFWwindow* window, int focused);
-
1328
-
1348typedef void (* GLFWwindowiconifyfun)(GLFWwindow* window, int iconified);
-
1349
-
1369typedef void (* GLFWwindowmaximizefun)(GLFWwindow* window, int maximized);
-
1370
-
1390typedef void (* GLFWframebuffersizefun)(GLFWwindow* window, int width, int height);
-
1391
-
1411typedef void (* GLFWwindowcontentscalefun)(GLFWwindow* window, float xscale, float yscale);
-
1412
-
1437typedef void (* GLFWmousebuttonfun)(GLFWwindow* window, int button, int action, int mods);
-
1438
-
1460typedef void (* GLFWcursorposfun)(GLFWwindow* window, double xpos, double ypos);
-
1461
-
1481typedef void (* GLFWcursorenterfun)(GLFWwindow* window, int entered);
-
1482
-
1502typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffset);
-
1503
-
1528typedef void (* GLFWkeyfun)(GLFWwindow* window, int key, int scancode, int action, int mods);
-
1529
-
1549typedef void (* GLFWcharfun)(GLFWwindow* window, unsigned int codepoint);
-
1550
-
1576typedef void (* GLFWcharmodsfun)(GLFWwindow* window, unsigned int codepoint, int mods);
-
1577
-
1600typedef void (* GLFWdropfun)(GLFWwindow* window, int path_count, const char* paths[]);
-
1601
-
1621typedef void (* GLFWmonitorfun)(GLFWmonitor* monitor, int event);
-
1622
-
1642typedef void (* GLFWjoystickfun)(int jid, int event);
-
1643
-
1657typedef struct GLFWvidmode
-
1658{
- - - - - - - -
1678
-
1691typedef struct GLFWgammaramp
-
1692{
-
1695 unsigned short* red;
-
1698 unsigned short* green;
-
1701 unsigned short* blue;
-
1704 unsigned int size;
- -
1706
-
1720typedef struct GLFWimage
-
1721{
- - -
1730 unsigned char* pixels;
- -
1732
-
1744typedef struct GLFWgamepadstate
-
1745{
-
1749 unsigned char buttons[15];
-
1753 float axes[6];
- -
1755
-
1756
-
1757/*************************************************************************
-
1758 * GLFW API functions
-
1759 *************************************************************************/
+
1163#define GLFW_ANY_RELEASE_BEHAVIOR 0
+
1164#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001
+
1165#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002
+
1166
+
1167#define GLFW_NATIVE_CONTEXT_API 0x00036001
+
1168#define GLFW_EGL_CONTEXT_API 0x00036002
+
1169#define GLFW_OSMESA_CONTEXT_API 0x00036003
+
1170
+
1171#define GLFW_ANGLE_PLATFORM_TYPE_NONE 0x00037001
+
1172#define GLFW_ANGLE_PLATFORM_TYPE_OPENGL 0x00037002
+
1173#define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES 0x00037003
+
1174#define GLFW_ANGLE_PLATFORM_TYPE_D3D9 0x00037004
+
1175#define GLFW_ANGLE_PLATFORM_TYPE_D3D11 0x00037005
+
1176#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007
+
1177#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008
+
1178
+
1179#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001
+
1180#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002
+
1181
+
1182#define GLFW_ANY_POSITION 0x80000000
+
1183
+
1197#define GLFW_ARROW_CURSOR 0x00036001
+
1202#define GLFW_IBEAM_CURSOR 0x00036002
+
1207#define GLFW_CROSSHAIR_CURSOR 0x00036003
+
1212#define GLFW_POINTING_HAND_CURSOR 0x00036004
+
1218#define GLFW_RESIZE_EW_CURSOR 0x00036005
+
1224#define GLFW_RESIZE_NS_CURSOR 0x00036006
+
1239#define GLFW_RESIZE_NWSE_CURSOR 0x00036007
+
1254#define GLFW_RESIZE_NESW_CURSOR 0x00036008
+
1260#define GLFW_RESIZE_ALL_CURSOR 0x00036009
+
1272#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A
+
1277#define GLFW_HRESIZE_CURSOR GLFW_RESIZE_EW_CURSOR
+
1282#define GLFW_VRESIZE_CURSOR GLFW_RESIZE_NS_CURSOR
+
1287#define GLFW_HAND_CURSOR GLFW_POINTING_HAND_CURSOR
+
1290#define GLFW_CONNECTED 0x00040001
+
1291#define GLFW_DISCONNECTED 0x00040002
+
1292
+
1299#define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001
+
1304#define GLFW_ANGLE_PLATFORM_TYPE 0x00050002
+
1309#define GLFW_PLATFORM 0x00050003
+
1314#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001
+
1319#define GLFW_COCOA_MENUBAR 0x00051002
+
1324#define GLFW_X11_XCB_VULKAN_SURFACE 0x00052001
+
1329#define GLFW_WAYLAND_LIBDECOR 0x00053001
+
1338#define GLFW_ANY_PLATFORM 0x00060000
+
1339#define GLFW_PLATFORM_WIN32 0x00060001
+
1340#define GLFW_PLATFORM_COCOA 0x00060002
+
1341#define GLFW_PLATFORM_WAYLAND 0x00060003
+
1342#define GLFW_PLATFORM_X11 0x00060004
+
1343#define GLFW_PLATFORM_NULL 0x00060005
+
1346#define GLFW_DONT_CARE -1
+
1347
+
1348
+
1349/*************************************************************************
+
1350 * GLFW API types
+
1351 *************************************************************************/
+
1352
+
1365typedef void (*GLFWglproc)(void);
+
1366
+
1379typedef void (*GLFWvkproc)(void);
+
1380
+ +
1392
+
1403typedef struct GLFWwindow GLFWwindow;
+
1404
+
1415typedef struct GLFWcursor GLFWcursor;
+
1416
+
1468typedef void* (* GLFWallocatefun)(size_t size, void* user);
+
1469
+
1524typedef void* (* GLFWreallocatefun)(void* block, size_t size, void* user);
+
1525
+
1566typedef void (* GLFWdeallocatefun)(void* block, void* user);
+
1567
+
1590typedef void (* GLFWerrorfun)(int error_code, const char* description);
+
1591
+
1613typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos);
+
1614
+
1635typedef void (* GLFWwindowsizefun)(GLFWwindow* window, int width, int height);
+
1636
+
1655typedef void (* GLFWwindowclosefun)(GLFWwindow* window);
+
1656
+
1675typedef void (* GLFWwindowrefreshfun)(GLFWwindow* window);
+
1676
+
1696typedef void (* GLFWwindowfocusfun)(GLFWwindow* window, int focused);
+
1697
+
1717typedef void (* GLFWwindowiconifyfun)(GLFWwindow* window, int iconified);
+
1718
+
1738typedef void (* GLFWwindowmaximizefun)(GLFWwindow* window, int maximized);
+
1739
+
1759typedef void (* GLFWframebuffersizefun)(GLFWwindow* window, int width, int height);
1760
-
1797GLFWAPI int glfwInit(void);
-
1798
-
1831GLFWAPI void glfwTerminate(void);
-
1832
-
1863GLFWAPI void glfwInitHint(int hint, int value);
-
1864
-
1890GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
-
1891
-
1921GLFWAPI const char* glfwGetVersionString(void);
-
1922
-
1952GLFWAPI int glfwGetError(const char** description);
-
1953
- -
1999
-
2027GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);
-
2028
- -
2052
-
2076GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);
-
2077
-
2107GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
-
2108
-
2141GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM);
-
2142
-
2173GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* monitor, float* xscale, float* yscale);
-
2174
-
2199GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);
-
2200
-
2225GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* monitor, void* pointer);
-
2226
- -
2250
- -
2280
-
2313GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);
-
2314
- -
2342
-
2374GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
-
2375
- -
2405
-
2445GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);
-
2446
-
2464GLFWAPI void glfwDefaultWindowHints(void);
-
2465
-
2499GLFWAPI void glfwWindowHint(int hint, int value);
-
2500
-
2537GLFWAPI void glfwWindowHintString(int hint, const char* value);
-
2538
-
2691GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
-
2692
-
2720GLFWAPI void glfwDestroyWindow(GLFWwindow* window);
-
2721
- -
2741
-
2762GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);
-
2763
-
2787GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
-
2788
-
2834GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images);
-
2835
-
2866GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
-
2867
-
2901GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
-
2902
-
2931GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
-
2932
-
2974GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
-
2975
-
3017GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
-
3018
-
3058GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
-
3059
-
3087GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height);
-
3088
-
3124GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom);
-
3125
-
3157GLFWAPI void glfwGetWindowContentScale(GLFWwindow* window, float* xscale, float* yscale);
-
3158
-
3184GLFWAPI float glfwGetWindowOpacity(GLFWwindow* window);
-
3185
-
3213GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
-
3214
-
3241GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
-
3242
-
3268GLFWAPI void glfwRestoreWindow(GLFWwindow* window);
-
3269
-
3293GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
-
3294
-
3325GLFWAPI void glfwShowWindow(GLFWwindow* window);
-
3326
-
3347GLFWAPI void glfwHideWindow(GLFWwindow* window);
-
3348
-
3386GLFWAPI void glfwFocusWindow(GLFWwindow* window);
-
3387
- +
1780typedef void (* GLFWwindowcontentscalefun)(GLFWwindow* window, float xscale, float yscale);
+
1781
+
1806typedef void (* GLFWmousebuttonfun)(GLFWwindow* window, int button, int action, int mods);
+
1807
+
1829typedef void (* GLFWcursorposfun)(GLFWwindow* window, double xpos, double ypos);
+
1830
+
1850typedef void (* GLFWcursorenterfun)(GLFWwindow* window, int entered);
+
1851
+
1871typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffset);
+
1872
+
1897typedef void (* GLFWkeyfun)(GLFWwindow* window, int key, int scancode, int action, int mods);
+
1898
+
1918typedef void (* GLFWcharfun)(GLFWwindow* window, unsigned int codepoint);
+
1919
+
1945typedef void (* GLFWcharmodsfun)(GLFWwindow* window, unsigned int codepoint, int mods);
+
1946
+
1969typedef void (* GLFWdropfun)(GLFWwindow* window, int path_count, const char* paths[]);
+
1970
+
1990typedef void (* GLFWmonitorfun)(GLFWmonitor* monitor, int event);
+
1991
+
2011typedef void (* GLFWjoystickfun)(int jid, int event);
+
2012
+
+
2026typedef struct GLFWvidmode
+
2027{
+ + + + + + + +
+
2047
+
+
2060typedef struct GLFWgammaramp
+
2061{
+
2064 unsigned short* red;
+
2067 unsigned short* green;
+
2070 unsigned short* blue;
+
2073 unsigned int size;
+ +
+
2075
+
+
2089typedef struct GLFWimage
+
2090{
+ + +
2099 unsigned char* pixels;
+ +
+
2101
+
+
2113typedef struct GLFWgamepadstate
+
2114{
+
2118 unsigned char buttons[15];
+
2122 float axes[6];
+ +
+
2124
+ +
2156
+
2157
+
2158/*************************************************************************
+
2159 * GLFW API functions
+
2160 *************************************************************************/
+
2161
+
2220GLFWAPI int glfwInit(void);
+
2221
+
2254GLFWAPI void glfwTerminate(void);
+
2255
+
2286GLFWAPI void glfwInitHint(int hint, int value);
+
2287
+
2317GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator);
+
2318
+
2319#if defined(VK_VERSION_1_0)
+
2320
+
2363GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader);
+
2364
+
2365#endif /*VK_VERSION_1_0*/
+
2366
+
2392GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
+
2393
+
2426GLFWAPI const char* glfwGetVersionString(void);
+
2427
+
2457GLFWAPI int glfwGetError(const char** description);
+
2458
+ +
2504
+
2524GLFWAPI int glfwGetPlatform(void);
+
2525
+
2548GLFWAPI int glfwPlatformSupported(int platform);
+
2549
+
2577GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);
+
2578
+ +
2602
+
2626GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);
+
2627
+
2657GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
+
2658
+
2692GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM);
+
2693
+
2727GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* monitor, float* xscale, float* yscale);
+
2728
+
2753GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);
+
2754
+
2779GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* monitor, void* pointer);
+
2780
+ +
2804
+ +
2834
+
2867GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);
+
2868
+ +
2896
+
2928GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
+
2929
+ +
2959
+
2999GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);
+
3000
+
3018GLFWAPI void glfwDefaultWindowHints(void);
+
3019
+
3053GLFWAPI void glfwWindowHint(int hint, int value);
+
3054
+
3091GLFWAPI void glfwWindowHintString(int hint, const char* value);
+
3092
+
3235GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
+
3236
+
3264GLFWAPI void glfwDestroyWindow(GLFWwindow* window);
+
3265
+ +
3285
+
3306GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);
+
3307
+
3338GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window);
+
3339
+
3364GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
+
3365
+
3413GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images);
3414
- -
3436
-
3494GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
-
3495
-
3531GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
-
3532
-
3568GLFWAPI void glfwSetWindowAttrib(GLFWwindow* window, int attrib, int value);
-
3569
-
3591GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);
-
3592
- -
3613
- -
3648
- -
3680
- -
3720
- -
3756
- -
3791
- -
3824
- -
3854
- -
3884
- -
3915
-
3952GLFWAPI void glfwPollEvents(void);
-
3953
-
3997GLFWAPI void glfwWaitEvents(void);
-
3998
-
4046GLFWAPI void glfwWaitEventsTimeout(double timeout);
-
4047
-
4066GLFWAPI void glfwPostEmptyEvent(void);
-
4067
-
4091GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
-
4092
-
4153GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
+
3445GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
+
3446
+
3480GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
+
3481
+
3510GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
+
3511
+
3553GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
+
3554
+
3596GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
+
3597
+
3634GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
+
3635
+
3663GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height);
+
3664
+
3700GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom);
+
3701
+
3733GLFWAPI void glfwGetWindowContentScale(GLFWwindow* window, float* xscale, float* yscale);
+
3734
+
3760GLFWAPI float glfwGetWindowOpacity(GLFWwindow* window);
+
3761
+
3792GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
+
3793
+
3824GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
+
3825
+
3851GLFWAPI void glfwRestoreWindow(GLFWwindow* window);
+
3852
+
3876GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
+
3877
+
3908GLFWAPI void glfwShowWindow(GLFWwindow* window);
+
3909
+
3930GLFWAPI void glfwHideWindow(GLFWwindow* window);
+
3931
+
3969GLFWAPI void glfwFocusWindow(GLFWwindow* window);
+
3970
+ +
3997
+ +
4019
+
4074GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
+
4075
+
4111GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
+
4112
+
4153GLFWAPI void glfwSetWindowAttrib(GLFWwindow* window, int attrib, int value);
4154
- -
4183
-
4250GLFWAPI const char* glfwGetKeyName(int key, int scancode);
-
4251
-
4274GLFWAPI int glfwGetKeyScancode(int key);
-
4275
-
4313GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
-
4314
-
4342GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
-
4343
-
4380GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
-
4381
-
4420GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
-
4421
-
4458GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);
-
4459
- -
4482
-
4508GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);
-
4509
-
4535GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
-
4536
- -
4586
- +
4176GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);
+
4177
+ +
4198
+ +
4233
+ +
4265
+ +
4305
+ +
4341
+ +
4376
+ +
4406
+ +
4436
+ +
4466
+ +
4497
+
4534GLFWAPI void glfwPollEvents(void);
+
4535
+
4579GLFWAPI void glfwWaitEvents(void);
+
4580
+
4628GLFWAPI void glfwWaitEventsTimeout(double timeout);
4629
- -
4671
- -
4708
- -
4740
- -
4771
- -
4805
- -
4842
-
4865GLFWAPI int glfwJoystickPresent(int jid);
-
4866
-
4898GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count);
-
4899
-
4939GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count);
-
4940
-
4996GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count);
-
4997
-
5027GLFWAPI const char* glfwGetJoystickName(int jid);
-
5028
-
5068GLFWAPI const char* glfwGetJoystickGUID(int jid);
-
5069
-
5094GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer);
+
4648GLFWAPI void glfwPostEmptyEvent(void);
+
4649
+
4673GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
+
4674
+
4738GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
+
4739
+ +
4768
+
4835GLFWAPI const char* glfwGetKeyName(int key, int scancode);
+
4836
+
4862GLFWAPI int glfwGetKeyScancode(int key);
+
4863
+
4901GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
+
4902
+
4930GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
+
4931
+
4968GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
+
4969
+
5008GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
+
5009
+
5046GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);
+
5047
+
5095
-
5118GLFWAPI void* glfwGetJoystickUserPointer(int jid);
-
5119
-
5146GLFWAPI int glfwJoystickIsGamepad(int jid);
-
5147
- -
5183
-
5216GLFWAPI int glfwUpdateGamepadMappings(const char* string);
-
5217
-
5248GLFWAPI const char* glfwGetGamepadName(int jid);
-
5249
-
5286GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
-
5287
-
5311GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
-
5312
-
5341GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
-
5342
-
5371GLFWAPI double glfwGetTime(void);
-
5372
-
5401GLFWAPI void glfwSetTime(double time);
-
5402
-
5423GLFWAPI uint64_t glfwGetTimerValue(void);
-
5424
-
5443GLFWAPI uint64_t glfwGetTimerFrequency(void);
-
5444
- -
5482
- -
5503
-
5536GLFWAPI void glfwSwapBuffers(GLFWwindow* window);
-
5537
-
5582GLFWAPI void glfwSwapInterval(int interval);
-
5583
-
5620GLFWAPI int glfwExtensionSupported(const char* extension);
-
5621
-
5662GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
-
5663
-
5688GLFWAPI int glfwVulkanSupported(void);
-
5689
-
5732GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count);
-
5733
-
5734#if defined(VK_VERSION_1_0)
-
5735
-
5775GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname);
-
5776
-
5812GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
-
5813
-
5875GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
-
5876
-
5877#endif /*VK_VERSION_1_0*/
-
5878
-
5879
-
5880/*************************************************************************
-
5881 * Global definition cleanup
-
5882 *************************************************************************/
-
5883
-
5884/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */
-
5885
-
5886#ifdef GLFW_WINGDIAPI_DEFINED
-
5887 #undef WINGDIAPI
-
5888 #undef GLFW_WINGDIAPI_DEFINED
-
5889#endif
-
5890
-
5891#ifdef GLFW_CALLBACK_DEFINED
-
5892 #undef CALLBACK
-
5893 #undef GLFW_CALLBACK_DEFINED
-
5894#endif
-
5895
-
5896/* Some OpenGL related headers need GLAPIENTRY, but it is unconditionally
-
5897 * defined by some gl.h variants (OpenBSD) so define it after if needed.
-
5898 */
-
5899#ifndef GLAPIENTRY
-
5900 #define GLAPIENTRY APIENTRY
-
5901 #define GLFW_GLAPIENTRY_DEFINED
-
5902#endif
-
5903
-
5904/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */
-
5905
-
5906
-
5907#ifdef __cplusplus
-
5908}
-
5909#endif
-
5910
-
5911#endif /* _glfw3_h_ */
-
5912
+
5121GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);
+
5122
+
5148GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
+
5149
+ +
5199
+ +
5242
+ +
5284
+ +
5321
+ +
5353
+ +
5384
+ +
5418
+ +
5453
+
5476GLFWAPI int glfwJoystickPresent(int jid);
+
5477
+
5509GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count);
+
5510
+
5550GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count);
+
5551
+
5607GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count);
+
5608
+
5638GLFWAPI const char* glfwGetJoystickName(int jid);
+
5639
+
5679GLFWAPI const char* glfwGetJoystickGUID(int jid);
+
5680
+
5705GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer);
+
5706
+
5729GLFWAPI void* glfwGetJoystickUserPointer(int jid);
+
5730
+
5757GLFWAPI int glfwJoystickIsGamepad(int jid);
+
5758
+ +
5794
+
5827GLFWAPI int glfwUpdateGamepadMappings(const char* string);
+
5828
+
5859GLFWAPI const char* glfwGetGamepadName(int jid);
+
5860
+
5897GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
+
5898
+
5927GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
+
5928
+
5962GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
+
5963
+
5992GLFWAPI double glfwGetTime(void);
+
5993
+
6022GLFWAPI void glfwSetTime(double time);
+
6023
+
6044GLFWAPI uint64_t glfwGetTimerValue(void);
+
6045
+
6064GLFWAPI uint64_t glfwGetTimerFrequency(void);
+
6065
+ +
6110
+ +
6131
+
6164GLFWAPI void glfwSwapBuffers(GLFWwindow* window);
+
6165
+
6210GLFWAPI void glfwSwapInterval(int interval);
+
6211
+
6248GLFWAPI int glfwExtensionSupported(const char* extension);
+
6249
+
6290GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
+
6291
+
6316GLFWAPI int glfwVulkanSupported(void);
+
6317
+
6360GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count);
+
6361
+
6362#if defined(VK_VERSION_1_0)
+
6363
+
6403GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname);
+
6404
+
6440GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
+
6441
+
6510GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
+
6511
+
6512#endif /*VK_VERSION_1_0*/
+
6513
+
6514
+
6515/*************************************************************************
+
6516 * Global definition cleanup
+
6517 *************************************************************************/
+
6518
+
6519/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */
+
6520
+
6521#ifdef GLFW_WINGDIAPI_DEFINED
+
6522 #undef WINGDIAPI
+
6523 #undef GLFW_WINGDIAPI_DEFINED
+
6524#endif
+
6525
+
6526#ifdef GLFW_CALLBACK_DEFINED
+
6527 #undef CALLBACK
+
6528 #undef GLFW_CALLBACK_DEFINED
+
6529#endif
+
6530
+
6531/* Some OpenGL related headers need GLAPIENTRY, but it is unconditionally
+
6532 * defined by some gl.h variants (OpenBSD) so define it after if needed.
+
6533 */
+
6534#ifndef GLAPIENTRY
+
6535 #define GLAPIENTRY APIENTRY
+
6536 #define GLFW_GLAPIENTRY_DEFINED
+
6537#endif
+
6538
+
6539/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */
+
6540
+
6541
+
6542#ifdef __cplusplus
+
6543}
+
6544#endif
+
6545
+
6546#endif /* _glfw3_h_ */
+
6547
void glfwMakeContextCurrent(GLFWwindow *window)
Makes the context of the specified window current for the calling thread.
GLFWglproc glfwGetProcAddress(const char *procname)
Returns the address of the specified function for the current context.
-
void(* GLFWglproc)(void)
Client API function pointer type.
Definition: glfw3.h:1147
+
void(* GLFWglproc)(void)
Client API function pointer type.
Definition glfw3.h:1365
void glfwSwapInterval(int interval)
Sets the swap interval for the current context.
int glfwExtensionSupported(const char *extension)
Returns whether the specified extension is available.
GLFWwindow * glfwGetCurrentContext(void)
Returns the window whose context is current on the calling thread.
const char * glfwGetVersionString(void)
Returns a string describing the compile-time configuration.
void glfwInitHint(int hint, int value)
Sets the specified init hint to the desired value.
int glfwInit(void)
Initializes the GLFW library.
-
void(* GLFWerrorfun)(int error_code, const char *description)
The function pointer type for error callbacks.
Definition: glfw3.h:1221
+
void *(* GLFWreallocatefun)(void *block, size_t size, void *user)
The function pointer type for memory reallocation callbacks.
Definition glfw3.h:1524
+
void *(* GLFWallocatefun)(size_t size, void *user)
The function pointer type for memory allocation callbacks.
Definition glfw3.h:1468
+
int glfwGetPlatform(void)
Returns the currently selected platform.
+
void(* GLFWdeallocatefun)(void *block, void *user)
The function pointer type for memory deallocation callbacks.
Definition glfw3.h:1566
+
void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader)
Sets the desired Vulkan vkGetInstanceProcAddr function.
+
void(* GLFWerrorfun)(int error_code, const char *description)
The function pointer type for error callbacks.
Definition glfw3.h:1590
+
int glfwPlatformSupported(int platform)
Returns whether the library includes support for the specified platform.
int glfwGetError(const char **description)
Returns and clears the last error for the calling thread.
+
void glfwInitAllocator(const GLFWallocator *allocator)
Sets the init allocator to the desired value.
void glfwGetVersion(int *major, int *minor, int *rev)
Retrieves the version of the GLFW library.
void glfwTerminate(void)
Terminates the GLFW library.
GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun callback)
Sets the error callback.
-
void(* GLFWmousebuttonfun)(GLFWwindow *window, int button, int action, int mods)
The function pointer type for mouse button callbacks.
Definition: glfw3.h:1437
+
void(* GLFWmousebuttonfun)(GLFWwindow *window, int button, int action, int mods)
The function pointer type for mouse button callbacks.
Definition glfw3.h:1806
void glfwGetCursorPos(GLFWwindow *window, double *xpos, double *ypos)
Retrieves the position of the cursor relative to the content area of the window.
void glfwSetCursorPos(GLFWwindow *window, double xpos, double ypos)
Sets the position of the cursor, relative to the content area of the window.
const unsigned char * glfwGetJoystickHats(int jid, int *count)
Returns the state of all hats of the specified joystick.
uint64_t glfwGetTimerValue(void)
Returns the current value of the raw timer.
GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow *window, GLFWcharmodsfun callback)
Sets the Unicode character with modifiers callback.
void * glfwGetJoystickUserPointer(int jid)
Returns the user pointer of the specified joystick.
-
void(* GLFWcharfun)(GLFWwindow *window, unsigned int codepoint)
The function pointer type for Unicode character callbacks.
Definition: glfw3.h:1549
+
void(* GLFWcharfun)(GLFWwindow *window, unsigned int codepoint)
The function pointer type for Unicode character callbacks.
Definition glfw3.h:1918
GLFWkeyfun glfwSetKeyCallback(GLFWwindow *window, GLFWkeyfun callback)
Sets the key callback.
GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun callback)
Sets the joystick configuration callback.
uint64_t glfwGetTimerFrequency(void)
Returns the frequency, in Hz, of the raw timer.
GLFWcursor * glfwCreateCursor(const GLFWimage *image, int xhot, int yhot)
Creates a custom cursor.
GLFWscrollfun glfwSetScrollCallback(GLFWwindow *window, GLFWscrollfun callback)
Sets the scroll callback.
-
void(* GLFWkeyfun)(GLFWwindow *window, int key, int scancode, int action, int mods)
The function pointer type for keyboard key callbacks.
Definition: glfw3.h:1528
+
void(* GLFWkeyfun)(GLFWwindow *window, int key, int scancode, int action, int mods)
The function pointer type for keyboard key callbacks.
Definition glfw3.h:1897
const unsigned char * glfwGetJoystickButtons(int jid, int *count)
Returns the state of all buttons of the specified joystick.
-
struct GLFWgamepadstate GLFWgamepadstate
Gamepad input state.
const char * glfwGetJoystickGUID(int jid)
Returns the SDL compatible GUID of the specified joystick.
int glfwGetKeyScancode(int key)
Returns the platform-specific scancode of the specified key.
GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow *window, GLFWmousebuttonfun callback)
Sets the mouse button callback.
void glfwSetJoystickUserPointer(int jid, void *pointer)
Sets the user pointer of the specified joystick.
const char * glfwGetClipboardString(GLFWwindow *window)
Returns the contents of the clipboard as a string.
void glfwDestroyCursor(GLFWcursor *cursor)
Destroys a cursor.
-
struct GLFWcursor GLFWcursor
Opaque cursor object.
Definition: glfw3.h:1197
+
struct GLFWcursor GLFWcursor
Opaque cursor object.
Definition glfw3.h:1415
const char * glfwGetGamepadName(int jid)
Returns the human-readable gamepad name for the specified joystick.
-
void(* GLFWjoystickfun)(int jid, int event)
The function pointer type for joystick configuration callbacks.
Definition: glfw3.h:1642
+
void(* GLFWjoystickfun)(int jid, int event)
The function pointer type for joystick configuration callbacks.
Definition glfw3.h:2011
double glfwGetTime(void)
Returns the GLFW time.
void glfwSetInputMode(GLFWwindow *window, int mode, int value)
Sets an input option for the specified window.
-
void(* GLFWcursorenterfun)(GLFWwindow *window, int entered)
The function pointer type for cursor enter/leave callbacks.
Definition: glfw3.h:1481
-
void(* GLFWdropfun)(GLFWwindow *window, int path_count, const char *paths[])
The function pointer type for path drop callbacks.
Definition: glfw3.h:1600
+
void(* GLFWcursorenterfun)(GLFWwindow *window, int entered)
The function pointer type for cursor enter/leave callbacks.
Definition glfw3.h:1850
+
void(* GLFWdropfun)(GLFWwindow *window, int path_count, const char *paths[])
The function pointer type for path drop callbacks.
Definition glfw3.h:1969
GLFWcharfun glfwSetCharCallback(GLFWwindow *window, GLFWcharfun callback)
Sets the Unicode character callback.
GLFWdropfun glfwSetDropCallback(GLFWwindow *window, GLFWdropfun callback)
Sets the path drop callback.
void glfwSetClipboardString(GLFWwindow *window, const char *string)
Sets the clipboard to the specified string.
int glfwGetMouseButton(GLFWwindow *window, int button)
Returns the last reported state of a mouse button for the specified window.
GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow *window, GLFWcursorposfun callback)
Sets the cursor position callback.
-
void(* GLFWcharmodsfun)(GLFWwindow *window, unsigned int codepoint, int mods)
The function pointer type for Unicode character with modifiers callbacks.
Definition: glfw3.h:1576
+
void(* GLFWcharmodsfun)(GLFWwindow *window, unsigned int codepoint, int mods)
The function pointer type for Unicode character with modifiers callbacks.
Definition glfw3.h:1945
const char * glfwGetJoystickName(int jid)
Returns the name of the specified joystick.
int glfwJoystickIsGamepad(int jid)
Returns whether the specified joystick has a gamepad mapping.
GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow *window, GLFWcursorenterfun callback)
Sets the cursor enter/leave callback.
void glfwSetCursor(GLFWwindow *window, GLFWcursor *cursor)
Sets the cursor for the window.
-
void(* GLFWcursorposfun)(GLFWwindow *window, double xpos, double ypos)
The function pointer type for cursor position callbacks.
Definition: glfw3.h:1460
+
void(* GLFWcursorposfun)(GLFWwindow *window, double xpos, double ypos)
The function pointer type for cursor position callbacks.
Definition glfw3.h:1829
int glfwGetGamepadState(int jid, GLFWgamepadstate *state)
Retrieves the state of the specified joystick remapped as a gamepad.
int glfwGetKey(GLFWwindow *window, int key)
Returns the last reported state of a keyboard key for the specified window.
int glfwRawMouseMotionSupported(void)
Returns whether raw mouse motion is supported.
@@ -1042,7 +1144,7 @@ $(function() {
GLFWcursor * glfwCreateStandardCursor(int shape)
Creates a cursor with a standard shape.
void glfwSetTime(double time)
Sets the GLFW time.
int glfwGetInputMode(GLFWwindow *window, int mode)
Returns the value of an input option for the specified window.
-
void(* GLFWscrollfun)(GLFWwindow *window, double xoffset, double yoffset)
The function pointer type for scroll callbacks.
Definition: glfw3.h:1502
+
void(* GLFWscrollfun)(GLFWwindow *window, double xoffset, double yoffset)
The function pointer type for scroll callbacks.
Definition glfw3.h:1871
void glfwGetMonitorPos(GLFWmonitor *monitor, int *xpos, int *ypos)
Returns the position of the monitor's viewport on the virtual screen.
void * glfwGetMonitorUserPointer(GLFWmonitor *monitor)
Returns the user pointer of the specified monitor.
void glfwSetGammaRamp(GLFWmonitor *monitor, const GLFWgammaramp *ramp)
Sets the current gamma ramp for the specified monitor.
@@ -1053,10 +1155,8 @@ $(function() {
const GLFWgammaramp * glfwGetGammaRamp(GLFWmonitor *monitor)
Returns the current gamma ramp for the specified monitor.
const char * glfwGetMonitorName(GLFWmonitor *monitor)
Returns the name of the specified monitor.
void glfwGetMonitorPhysicalSize(GLFWmonitor *monitor, int *widthMM, int *heightMM)
Returns the physical size of the monitor.
-
struct GLFWmonitor GLFWmonitor
Opaque monitor object.
Definition: glfw3.h:1173
-
struct GLFWvidmode GLFWvidmode
Video mode type.
-
struct GLFWgammaramp GLFWgammaramp
Gamma ramp.
-
void(* GLFWmonitorfun)(GLFWmonitor *monitor, int event)
The function pointer type for monitor configuration callbacks.
Definition: glfw3.h:1621
+
struct GLFWmonitor GLFWmonitor
Opaque monitor object.
Definition glfw3.h:1391
+
void(* GLFWmonitorfun)(GLFWmonitor *monitor, int event)
The function pointer type for monitor configuration callbacks.
Definition glfw3.h:1990
GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun callback)
Sets the monitor configuration callback.
const GLFWvidmode * glfwGetVideoMode(GLFWmonitor *monitor)
Returns the current mode of the specified monitor.
GLFWmonitor * glfwGetPrimaryMonitor(void)
Returns the primary monitor.
@@ -1064,7 +1164,7 @@ $(function() {
void glfwGetMonitorContentScale(GLFWmonitor *monitor, float *xscale, float *yscale)
Retrieves the content scale for the specified monitor.
VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow *window, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
Creates a Vulkan surface for the specified window.
int glfwVulkanSupported(void)
Returns whether the Vulkan loader and an ICD have been found.
-
void(* GLFWvkproc)(void)
Vulkan API function pointer type.
Definition: glfw3.h:1161
+
void(* GLFWvkproc)(void)
Vulkan API function pointer type.
Definition glfw3.h:1379
const char ** glfwGetRequiredInstanceExtensions(uint32_t *count)
Returns the Vulkan instance extensions required by GLFW.
GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char *procname)
Returns the address of the specified Vulkan instance function.
int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily)
Returns whether the specified queue family can present images.
@@ -1077,15 +1177,15 @@ $(function() {
GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow *window, GLFWwindowrefreshfun callback)
Sets the refresh callback for the specified window.
int glfwWindowShouldClose(GLFWwindow *window)
Checks the close flag of the specified window.
void glfwRequestWindowAttention(GLFWwindow *window)
Requests user attention to the specified window.
-
void(* GLFWwindowmaximizefun)(GLFWwindow *window, int maximized)
The function pointer type for window maximize callbacks.
Definition: glfw3.h:1369
+
void(* GLFWwindowmaximizefun)(GLFWwindow *window, int maximized)
The function pointer type for window maximize callbacks.
Definition glfw3.h:1738
GLFWwindow * glfwCreateWindow(int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
Creates a window and its associated context.
-
void(* GLFWwindowiconifyfun)(GLFWwindow *window, int iconified)
The function pointer type for window iconify callbacks.
Definition: glfw3.h:1348
+
void(* GLFWwindowiconifyfun)(GLFWwindow *window, int iconified)
The function pointer type for window iconify callbacks.
Definition glfw3.h:1717
void glfwSetWindowSize(GLFWwindow *window, int width, int height)
Sets the size of the content area of the specified window.
void glfwPollEvents(void)
Processes all pending events.
-
struct GLFWwindow GLFWwindow
Opaque window object.
Definition: glfw3.h:1185
+
struct GLFWwindow GLFWwindow
Opaque window object.
Definition glfw3.h:1403
void glfwSetWindowUserPointer(GLFWwindow *window, void *pointer)
Sets the user pointer of the specified window.
void glfwMaximizeWindow(GLFWwindow *window)
Maximizes the specified window.
-
void(* GLFWwindowrefreshfun)(GLFWwindow *window)
The function pointer type for window content refresh callbacks.
Definition: glfw3.h:1306
+
void(* GLFWwindowrefreshfun)(GLFWwindow *window)
The function pointer type for window content refresh callbacks.
Definition glfw3.h:1675
void glfwHideWindow(GLFWwindow *window)
Hides the specified window.
void glfwSetWindowShouldClose(GLFWwindow *window, int value)
Sets the close flag of the specified window.
GLFWmonitor * glfwGetWindowMonitor(GLFWwindow *window)
Returns the monitor that the window uses for full screen mode.
@@ -1096,8 +1196,7 @@ $(function() {
void glfwShowWindow(GLFWwindow *window)
Makes the specified window visible.
void glfwSetWindowAspectRatio(GLFWwindow *window, int numer, int denom)
Sets the aspect ratio of the specified window.
void glfwGetWindowPos(GLFWwindow *window, int *xpos, int *ypos)
Retrieves the position of the content area of the specified window.
-
void(* GLFWwindowcontentscalefun)(GLFWwindow *window, float xscale, float yscale)
The function pointer type for window content scale callbacks.
Definition: glfw3.h:1411
-
struct GLFWimage GLFWimage
Image data.
+
void(* GLFWwindowcontentscalefun)(GLFWwindow *window, float xscale, float yscale)
The function pointer type for window content scale callbacks.
Definition glfw3.h:1780
void glfwWindowHint(int hint, int value)
Sets the specified window hint to the desired value.
void glfwSetWindowMonitor(GLFWwindow *window, GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)
Sets the mode, monitor, video mode and placement of a window.
void glfwFocusWindow(GLFWwindow *window)
Brings the specified window to front and sets input focus.
@@ -1105,12 +1204,13 @@ $(function() {
void glfwDefaultWindowHints(void)
Resets all window hints to their default values.
GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow *window, GLFWframebuffersizefun callback)
Sets the framebuffer resize callback for the specified window.
void glfwPostEmptyEvent(void)
Posts an empty event to the event queue.
-
void(* GLFWwindowfocusfun)(GLFWwindow *window, int focused)
The function pointer type for window focus callbacks.
Definition: glfw3.h:1327
-
void(* GLFWwindowposfun)(GLFWwindow *window, int xpos, int ypos)
The function pointer type for window position callbacks.
Definition: glfw3.h:1244
-
void(* GLFWwindowclosefun)(GLFWwindow *window)
The function pointer type for window close callbacks.
Definition: glfw3.h:1286
+
void(* GLFWwindowfocusfun)(GLFWwindow *window, int focused)
The function pointer type for window focus callbacks.
Definition glfw3.h:1696
+
void(* GLFWwindowposfun)(GLFWwindow *window, int xpos, int ypos)
The function pointer type for window position callbacks.
Definition glfw3.h:1613
+
void(* GLFWwindowclosefun)(GLFWwindow *window)
The function pointer type for window close callbacks.
Definition glfw3.h:1655
GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow *window, GLFWwindowfocusfun callback)
Sets the focus callback for the specified window.
void glfwSetWindowSizeLimits(GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)
Sets the size limits of the specified window.
void glfwSetWindowOpacity(GLFWwindow *window, float opacity)
Sets the opacity of the whole window.
+
const char * glfwGetWindowTitle(GLFWwindow *window)
Returns the title of the specified window.
GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow *window, GLFWwindowiconifyfun callback)
Sets the iconify callback for the specified window.
GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow *window, GLFWwindowmaximizefun callback)
Sets the maximize callback for the specified window.
int glfwGetWindowAttrib(GLFWwindow *window, int attrib)
Returns an attribute of the specified window.
@@ -1120,35 +1220,40 @@ $(function() {
GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow *window, GLFWwindowsizefun callback)
Sets the size callback for the specified window.
GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow *window, GLFWwindowclosefun callback)
Sets the close callback for the specified window.
void glfwSetWindowIcon(GLFWwindow *window, int count, const GLFWimage *images)
Sets the icon for the specified window.
-
void(* GLFWframebuffersizefun)(GLFWwindow *window, int width, int height)
The function pointer type for framebuffer size callbacks.
Definition: glfw3.h:1390
+
void(* GLFWframebuffersizefun)(GLFWwindow *window, int width, int height)
The function pointer type for framebuffer size callbacks.
Definition glfw3.h:1759
void * glfwGetWindowUserPointer(GLFWwindow *window)
Returns the user pointer of the specified window.
-
void(* GLFWwindowsizefun)(GLFWwindow *window, int width, int height)
The function pointer type for window size callbacks.
Definition: glfw3.h:1266
+
void(* GLFWwindowsizefun)(GLFWwindow *window, int width, int height)
The function pointer type for window size callbacks.
Definition glfw3.h:1635
void glfwGetWindowSize(GLFWwindow *window, int *width, int *height)
Retrieves the size of the content area of the specified window.
GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow *window, GLFWwindowcontentscalefun callback)
Sets the window content scale callback for the specified window.
void glfwGetWindowContentScale(GLFWwindow *window, float *xscale, float *yscale)
Retrieves the content scale for the specified window.
-
Gamepad input state.
Definition: glfw3.h:1745
-
unsigned char buttons[15]
Definition: glfw3.h:1749
-
float axes[6]
Definition: glfw3.h:1753
-
Gamma ramp.
Definition: glfw3.h:1692
-
unsigned short * red
Definition: glfw3.h:1695
-
unsigned short * blue
Definition: glfw3.h:1701
-
unsigned int size
Definition: glfw3.h:1704
-
unsigned short * green
Definition: glfw3.h:1698
-
Image data.
Definition: glfw3.h:1721
-
int height
Definition: glfw3.h:1727
-
unsigned char * pixels
Definition: glfw3.h:1730
-
int width
Definition: glfw3.h:1724
-
Video mode type.
Definition: glfw3.h:1658
-
int greenBits
Definition: glfw3.h:1670
-
int redBits
Definition: glfw3.h:1667
-
int width
Definition: glfw3.h:1661
-
int refreshRate
Definition: glfw3.h:1676
-
int height
Definition: glfw3.h:1664
-
int blueBits
Definition: glfw3.h:1673
+
Custom heap memory allocator.
Definition glfw3.h:2138
+
GLFWallocatefun allocate
Definition glfw3.h:2142
+
GLFWdeallocatefun deallocate
Definition glfw3.h:2150
+
GLFWreallocatefun reallocate
Definition glfw3.h:2146
+
void * user
Definition glfw3.h:2154
+
Gamepad input state.
Definition glfw3.h:2114
+
unsigned char buttons[15]
Definition glfw3.h:2118
+
float axes[6]
Definition glfw3.h:2122
+
Gamma ramp.
Definition glfw3.h:2061
+
unsigned short * red
Definition glfw3.h:2064
+
unsigned short * blue
Definition glfw3.h:2070
+
unsigned int size
Definition glfw3.h:2073
+
unsigned short * green
Definition glfw3.h:2067
+
Image data.
Definition glfw3.h:2090
+
int height
Definition glfw3.h:2096
+
unsigned char * pixels
Definition glfw3.h:2099
+
int width
Definition glfw3.h:2093
+
Video mode type.
Definition glfw3.h:2027
+
int greenBits
Definition glfw3.h:2039
+
int redBits
Definition glfw3.h:2036
+
int width
Definition glfw3.h:2030
+
int refreshRate
Definition glfw3.h:2045
+
int height
Definition glfw3.h:2033
+
int blueBits
Definition glfw3.h:2042
diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/glfw3native_8h.html b/src/lib/src/vendor/glfw-3.4/docs/html/glfw3native_8h.html new file mode 100644 index 0000000..eb555d7 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/glfw3native_8h.html @@ -0,0 +1,170 @@ + + + + + + + +GLFW: glfw3native.h File Reference + + + + + + + + + + +
+ + + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+ +
glfw3native.h File Reference
+
+
+

Description

+

This is the header file of the native access functions. See Native access for more information.

+
+

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

const char * glfwGetWin32Adapter (GLFWmonitor *monitor)
 Returns the adapter device name of the specified monitor.
 
const char * glfwGetWin32Monitor (GLFWmonitor *monitor)
 Returns the display device name of the specified monitor.
 
HWND glfwGetWin32Window (GLFWwindow *window)
 Returns the HWND of the specified window.
 
HGLRC glfwGetWGLContext (GLFWwindow *window)
 Returns the HGLRC of the specified window.
 
CGDirectDisplayID glfwGetCocoaMonitor (GLFWmonitor *monitor)
 Returns the CGDirectDisplayID of the specified monitor.
 
id glfwGetCocoaWindow (GLFWwindow *window)
 Returns the NSWindow of the specified window.
 
id glfwGetCocoaView (GLFWwindow *window)
 Returns the NSView of the specified window.
 
id glfwGetNSGLContext (GLFWwindow *window)
 Returns the NSOpenGLContext of the specified window.
 
Display * glfwGetX11Display (void)
 Returns the Display used by GLFW.
 
RRCrtc glfwGetX11Adapter (GLFWmonitor *monitor)
 Returns the RRCrtc of the specified monitor.
 
RROutput glfwGetX11Monitor (GLFWmonitor *monitor)
 Returns the RROutput of the specified monitor.
 
Window glfwGetX11Window (GLFWwindow *window)
 Returns the Window of the specified window.
 
void glfwSetX11SelectionString (const char *string)
 Sets the current primary selection to the specified string.
 
const char * glfwGetX11SelectionString (void)
 Returns the contents of the current primary selection as a string.
 
GLXContext glfwGetGLXContext (GLFWwindow *window)
 Returns the GLXContext of the specified window.
 
GLXWindow glfwGetGLXWindow (GLFWwindow *window)
 Returns the GLXWindow of the specified window.
 
struct wl_display * glfwGetWaylandDisplay (void)
 Returns the struct wl_display* used by GLFW.
 
struct wl_output * glfwGetWaylandMonitor (GLFWmonitor *monitor)
 Returns the struct wl_output* of the specified monitor.
 
struct wl_surface * glfwGetWaylandWindow (GLFWwindow *window)
 Returns the main struct wl_surface* of the specified window.
 
EGLDisplay glfwGetEGLDisplay (void)
 Returns the EGLDisplay used by GLFW.
 
EGLContext glfwGetEGLContext (GLFWwindow *window)
 Returns the EGLContext of the specified window.
 
EGLSurface glfwGetEGLSurface (GLFWwindow *window)
 Returns the EGLSurface of the specified window.
 
int glfwGetOSMesaColorBuffer (GLFWwindow *window, int *width, int *height, int *format, void **buffer)
 Retrieves the color buffer associated with the specified window.
 
int glfwGetOSMesaDepthBuffer (GLFWwindow *window, int *width, int *height, int *bytesPerValue, void **buffer)
 Retrieves the depth buffer associated with the specified window.
 
OSMesaContext glfwGetOSMesaContext (GLFWwindow *window)
 Returns the OSMesaContext of the specified window.
 
+
+ + + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/glfw3native_8h_source.html b/src/lib/src/vendor/glfw-3.4/docs/html/glfw3native_8h_source.html similarity index 70% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/glfw3native_8h_source.html rename to src/lib/src/vendor/glfw-3.4/docs/html/glfw3native_8h_source.html index 31a0c40..4077989 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/glfw3native_8h_source.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/glfw3native_8h_source.html @@ -4,7 +4,7 @@ - + GLFW: glfw3native.h Source File @@ -28,10 +28,10 @@ - + @@ -45,6 +45,11 @@ $(function() { /* @license-end */ +
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -69,7 +81,7 @@ $(function() {
Go to the documentation of this file.
1/*************************************************************************
-
2 * GLFW 3.3 - www.glfw.org
+
2 * GLFW 3.4 - www.glfw.org
3 * A library for OpenGL, window and input
4 *------------------------------------------------------------------------
5 * Copyright (c) 2002-2006 Marcus Geelnard
@@ -124,132 +136,140 @@ $(function() {
103 #undef GLFW_APIENTRY_DEFINED
104 #endif
105 #include <windows.h>
-
106 #elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
-
107 #if defined(__OBJC__)
-
108 #import <Cocoa/Cocoa.h>
-
109 #else
-
110 #include <ApplicationServices/ApplicationServices.h>
-
111 #include <objc/objc.h>
-
112 #endif
-
113 #elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
-
114 #include <X11/Xlib.h>
-
115 #include <X11/extensions/Xrandr.h>
-
116 #elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
-
117 #include <wayland-client.h>
-
118 #endif
-
119
-
120 #if defined(GLFW_EXPOSE_NATIVE_WGL)
-
121 /* WGL is declared by windows.h */
-
122 #endif
-
123 #if defined(GLFW_EXPOSE_NATIVE_NSGL)
-
124 /* NSGL is declared by Cocoa.h */
-
125 #endif
-
126 #if defined(GLFW_EXPOSE_NATIVE_GLX)
-
127 /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
-
128 * default it also acts as an OpenGL header
-
129 * However, glx.h will include gl.h, which will define it unconditionally
-
130 */
-
131 #if defined(GLFW_GLAPIENTRY_DEFINED)
-
132 #undef GLAPIENTRY
-
133 #undef GLFW_GLAPIENTRY_DEFINED
-
134 #endif
-
135 #include <GL/glx.h>
-
136 #endif
-
137 #if defined(GLFW_EXPOSE_NATIVE_EGL)
-
138 #include <EGL/egl.h>
-
139 #endif
-
140 #if defined(GLFW_EXPOSE_NATIVE_OSMESA)
-
141 /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
-
142 * default it also acts as an OpenGL header
-
143 * However, osmesa.h will include gl.h, which will define it unconditionally
-
144 */
-
145 #if defined(GLFW_GLAPIENTRY_DEFINED)
-
146 #undef GLAPIENTRY
-
147 #undef GLFW_GLAPIENTRY_DEFINED
-
148 #endif
-
149 #include <GL/osmesa.h>
-
150 #endif
-
151
-
152#endif /*GLFW_NATIVE_INCLUDE_NONE*/
-
153
-
154
-
155/*************************************************************************
-
156 * Functions
-
157 *************************************************************************/
-
158
-
159#if defined(GLFW_EXPOSE_NATIVE_WIN32)
-
175GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
-
176
-
192GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
-
193
-
216GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
-
217#endif
-
218
-
219#if defined(GLFW_EXPOSE_NATIVE_WGL)
-
243GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
-
244#endif
-
245
-
246#if defined(GLFW_EXPOSE_NATIVE_COCOA)
-
261GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
-
262
-
277GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
-
278#endif
-
279
-
280#if defined(GLFW_EXPOSE_NATIVE_NSGL)
-
296GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
-
297#endif
-
298
-
299#if defined(GLFW_EXPOSE_NATIVE_X11)
-
314GLFWAPI Display* glfwGetX11Display(void);
-
315
-
330GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
-
331
-
346GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
-
347
-
362GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
-
363
-
384GLFWAPI void glfwSetX11SelectionString(const char* string);
-
385
-
412GLFWAPI const char* glfwGetX11SelectionString(void);
-
413#endif
-
414
-
415#if defined(GLFW_EXPOSE_NATIVE_GLX)
-
431GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
-
432
-
448GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
-
449#endif
-
450
-
451#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
-
466GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
-
467
-
482GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
-
483
-
498GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
-
499#endif
+
106 #endif
+
107
+
108 #if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
+
109 #if defined(__OBJC__)
+
110 #import <Cocoa/Cocoa.h>
+
111 #else
+
112 #include <ApplicationServices/ApplicationServices.h>
+
113 #include <objc/objc.h>
+
114 #endif
+
115 #endif
+
116
+
117 #if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
+
118 #include <X11/Xlib.h>
+
119 #include <X11/extensions/Xrandr.h>
+
120 #endif
+
121
+
122 #if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
+
123 #include <wayland-client.h>
+
124 #endif
+
125
+
126 #if defined(GLFW_EXPOSE_NATIVE_WGL)
+
127 /* WGL is declared by windows.h */
+
128 #endif
+
129 #if defined(GLFW_EXPOSE_NATIVE_NSGL)
+
130 /* NSGL is declared by Cocoa.h */
+
131 #endif
+
132 #if defined(GLFW_EXPOSE_NATIVE_GLX)
+
133 /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
+
134 * default it also acts as an OpenGL header
+
135 * However, glx.h will include gl.h, which will define it unconditionally
+
136 */
+
137 #if defined(GLFW_GLAPIENTRY_DEFINED)
+
138 #undef GLAPIENTRY
+
139 #undef GLFW_GLAPIENTRY_DEFINED
+
140 #endif
+
141 #include <GL/glx.h>
+
142 #endif
+
143 #if defined(GLFW_EXPOSE_NATIVE_EGL)
+
144 #include <EGL/egl.h>
+
145 #endif
+
146 #if defined(GLFW_EXPOSE_NATIVE_OSMESA)
+
147 /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
+
148 * default it also acts as an OpenGL header
+
149 * However, osmesa.h will include gl.h, which will define it unconditionally
+
150 */
+
151 #if defined(GLFW_GLAPIENTRY_DEFINED)
+
152 #undef GLAPIENTRY
+
153 #undef GLFW_GLAPIENTRY_DEFINED
+
154 #endif
+
155 #include <GL/osmesa.h>
+
156 #endif
+
157
+
158#endif /*GLFW_NATIVE_INCLUDE_NONE*/
+
159
+
160
+
161/*************************************************************************
+
162 * Functions
+
163 *************************************************************************/
+
164
+
165#if defined(GLFW_EXPOSE_NATIVE_WIN32)
+
182GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
+
183
+
200GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
+
201
+
225GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
+
226#endif
+
227
+
228#if defined(GLFW_EXPOSE_NATIVE_WGL)
+
252GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
+
253#endif
+
254
+
255#if defined(GLFW_EXPOSE_NATIVE_COCOA)
+
271GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
+
272
+
288GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
+
289
+
305GLFWAPI id glfwGetCocoaView(GLFWwindow* window);
+
306#endif
+
307
+
308#if defined(GLFW_EXPOSE_NATIVE_NSGL)
+
324GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
+
325#endif
+
326
+
327#if defined(GLFW_EXPOSE_NATIVE_X11)
+
343GLFWAPI Display* glfwGetX11Display(void);
+
344
+
360GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
+
361
+
377GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
+
378
+
394GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
+
395
+
416GLFWAPI void glfwSetX11SelectionString(const char* string);
+
417
+
444GLFWAPI const char* glfwGetX11SelectionString(void);
+
445#endif
+
446
+
447#if defined(GLFW_EXPOSE_NATIVE_GLX)
+
463GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
+
464
+
480GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
+
481#endif
+
482
+
483#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
+
499GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
500
-
501#if defined(GLFW_EXPOSE_NATIVE_EGL)
-
519GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
-
520
-
536GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
-
537
-
553GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
-
554#endif
+
516GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
+
517
+
533GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
+
534#endif
+
535
+
536#if defined(GLFW_EXPOSE_NATIVE_EGL)
+
554GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
555
-
556#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
-
579GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
-
580
-
603GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
-
604
-
620GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
-
621#endif
-
622
-
623#ifdef __cplusplus
-
624}
-
625#endif
-
626
-
627#endif /* _glfw3_native_h_ */
-
628
-
struct GLFWmonitor GLFWmonitor
Opaque monitor object.
Definition: glfw3.h:1173
+
571GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
+
572
+
588GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
+
589#endif
+
590
+
591#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
+
614GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
+
615
+
638GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
+
639
+
655GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
+
656#endif
+
657
+
658#ifdef __cplusplus
+
659}
+
660#endif
+
661
+
662#endif /* _glfw3_native_h_ */
+
663
+
struct GLFWmonitor GLFWmonitor
Opaque monitor object.
Definition glfw3.h:1391
RRCrtc glfwGetX11Adapter(GLFWmonitor *monitor)
Returns the RRCrtc of the specified monitor.
EGLDisplay glfwGetEGLDisplay(void)
Returns the EGLDisplay used by GLFW.
GLXWindow glfwGetGLXWindow(GLFWwindow *window)
Returns the GLXWindow of the specified window.
@@ -263,6 +283,7 @@ $(function() {
EGLContext glfwGetEGLContext(GLFWwindow *window)
Returns the EGLContext of the specified window.
int glfwGetOSMesaDepthBuffer(GLFWwindow *window, int *width, int *height, int *bytesPerValue, void **buffer)
Retrieves the depth buffer associated with the specified window.
Display * glfwGetX11Display(void)
Returns the Display used by GLFW.
+
id glfwGetCocoaView(GLFWwindow *window)
Returns the NSView of the specified window.
Window glfwGetX11Window(GLFWwindow *window)
Returns the Window of the specified window.
OSMesaContext glfwGetOSMesaContext(GLFWwindow *window)
Returns the OSMesaContext of the specified window.
RROutput glfwGetX11Monitor(GLFWmonitor *monitor)
Returns the RROutput of the specified monitor.
@@ -274,11 +295,11 @@ $(function() {
const char * glfwGetX11SelectionString(void)
Returns the contents of the current primary selection as a string.
CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor *monitor)
Returns the CGDirectDisplayID of the specified monitor.
HWND glfwGetWin32Window(GLFWwindow *window)
Returns the HWND of the specified window.
-
struct GLFWwindow GLFWwindow
Opaque window object.
Definition: glfw3.h:1185
+
struct GLFWwindow GLFWwindow
Opaque window object.
Definition glfw3.h:1403
diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__buttons.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__buttons.html similarity index 62% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/group__buttons.html rename to src/lib/src/vendor/glfw-3.4/docs/html/group__buttons.html index 7f1bb3d..efa3a35 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__buttons.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__buttons.html @@ -4,7 +4,7 @@ - + GLFW: Mouse buttons @@ -28,10 +28,10 @@ - + @@ -55,9 +55,16 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -67,38 +74,38 @@ $(function() {

Description

-

See mouse button input for how these are used.

+

See mouse button input for how these are used.

- + - + - + - + - + - + - + - + - + - + - + - +

Macros

#define GLFW_MOUSE_BUTTON_1   0
#define GLFW_MOUSE_BUTTON_1   0
 
#define GLFW_MOUSE_BUTTON_2   1
#define GLFW_MOUSE_BUTTON_2   1
 
#define GLFW_MOUSE_BUTTON_3   2
#define GLFW_MOUSE_BUTTON_3   2
 
#define GLFW_MOUSE_BUTTON_4   3
#define GLFW_MOUSE_BUTTON_4   3
 
#define GLFW_MOUSE_BUTTON_5   4
#define GLFW_MOUSE_BUTTON_5   4
 
#define GLFW_MOUSE_BUTTON_6   5
#define GLFW_MOUSE_BUTTON_6   5
 
#define GLFW_MOUSE_BUTTON_7   6
#define GLFW_MOUSE_BUTTON_7   6
 
#define GLFW_MOUSE_BUTTON_8   7
#define GLFW_MOUSE_BUTTON_8   7
 
#define GLFW_MOUSE_BUTTON_LAST   GLFW_MOUSE_BUTTON_8
#define GLFW_MOUSE_BUTTON_LAST   GLFW_MOUSE_BUTTON_8
 
#define GLFW_MOUSE_BUTTON_LEFT   GLFW_MOUSE_BUTTON_1
#define GLFW_MOUSE_BUTTON_LEFT   GLFW_MOUSE_BUTTON_1
 
#define GLFW_MOUSE_BUTTON_RIGHT   GLFW_MOUSE_BUTTON_2
#define GLFW_MOUSE_BUTTON_RIGHT   GLFW_MOUSE_BUTTON_2
 
#define GLFW_MOUSE_BUTTON_MIDDLE   GLFW_MOUSE_BUTTON_3
#define GLFW_MOUSE_BUTTON_MIDDLE   GLFW_MOUSE_BUTTON_3
 

Macro Definition Documentation

-

◆ GLFW_MOUSE_BUTTON_1

+

◆ GLFW_MOUSE_BUTTON_1

@@ -112,7 +119,7 @@ Macros
-

◆ GLFW_MOUSE_BUTTON_2

+

◆ GLFW_MOUSE_BUTTON_2

@@ -126,7 +133,7 @@ Macros
-

◆ GLFW_MOUSE_BUTTON_3

+

◆ GLFW_MOUSE_BUTTON_3

@@ -140,7 +147,7 @@ Macros
-

◆ GLFW_MOUSE_BUTTON_4

+

◆ GLFW_MOUSE_BUTTON_4

@@ -154,7 +161,7 @@ Macros
-

◆ GLFW_MOUSE_BUTTON_5

+

◆ GLFW_MOUSE_BUTTON_5

@@ -168,7 +175,7 @@ Macros
-

◆ GLFW_MOUSE_BUTTON_6

+

◆ GLFW_MOUSE_BUTTON_6

@@ -182,7 +189,7 @@ Macros
-

◆ GLFW_MOUSE_BUTTON_7

+

◆ GLFW_MOUSE_BUTTON_7

@@ -196,7 +203,7 @@ Macros
-

◆ GLFW_MOUSE_BUTTON_8

+

◆ GLFW_MOUSE_BUTTON_8

@@ -210,7 +217,7 @@ Macros
-

◆ GLFW_MOUSE_BUTTON_LAST

+

◆ GLFW_MOUSE_BUTTON_LAST

@@ -224,7 +231,7 @@ Macros
-

◆ GLFW_MOUSE_BUTTON_LEFT

+

◆ GLFW_MOUSE_BUTTON_LEFT

@@ -238,7 +245,7 @@ Macros
-

◆ GLFW_MOUSE_BUTTON_RIGHT

+

◆ GLFW_MOUSE_BUTTON_RIGHT

@@ -252,7 +259,7 @@ Macros
-

◆ GLFW_MOUSE_BUTTON_MIDDLE

+

◆ GLFW_MOUSE_BUTTON_MIDDLE

@@ -268,7 +275,7 @@ Macros
diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__context.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__context.html similarity index 63% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/group__context.html rename to src/lib/src/vendor/glfw-3.4/docs/html/group__context.html index 2913ea0..bbe33e4 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__context.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__context.html @@ -4,7 +4,7 @@ - + GLFW: Context reference @@ -28,10 +28,10 @@
- + @@ -55,9 +55,16 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -68,35 +75,35 @@ $(function() {

Description

-

This is the reference documentation for OpenGL and OpenGL ES context related functions. For more task-oriented information, see the Context guide.

+

This is the reference documentation for OpenGL and OpenGL ES context related functions. For more task-oriented information, see the Context guide.

- - + +

Typedefs

typedef void(* GLFWglproc) (void)
 Client API function pointer type. More...
typedef void(* GLFWglproc) (void)
 Client API function pointer type.
 
- - + + - - + + - - + + - - + + - - + +

Functions

void glfwMakeContextCurrent (GLFWwindow *window)
 Makes the context of the specified window current for the calling thread. More...
void glfwMakeContextCurrent (GLFWwindow *window)
 Makes the context of the specified window current for the calling thread.
 
GLFWwindowglfwGetCurrentContext (void)
 Returns the window whose context is current on the calling thread. More...
GLFWwindowglfwGetCurrentContext (void)
 Returns the window whose context is current on the calling thread.
 
void glfwSwapInterval (int interval)
 Sets the swap interval for the current context. More...
void glfwSwapInterval (int interval)
 Sets the swap interval for the current context.
 
int glfwExtensionSupported (const char *extension)
 Returns whether the specified extension is available. More...
int glfwExtensionSupported (const char *extension)
 Returns whether the specified extension is available.
 
GLFWglproc glfwGetProcAddress (const char *procname)
 Returns the address of the specified function for the current context. More...
GLFWglproc glfwGetProcAddress (const char *procname)
 Returns the address of the specified function for the current context.
 

Typedef Documentation

-

◆ GLFWglproc

+

◆ GLFWglproc

@@ -106,7 +113,7 @@ Functions
-

Generic function pointer used for returning client API function pointers without forcing a cast from a regular pointer.

+

Generic function pointer used for returning client API function pointers without forcing a cast from a regular pointer.

See also
OpenGL and OpenGL ES extensions
glfwGetProcAddress
@@ -116,7 +123,7 @@ Functions

Function Documentation

-

◆ glfwMakeContextCurrent()

+

◆ glfwMakeContextCurrent()

@@ -130,16 +137,18 @@ Functions
-

This function makes the OpenGL or OpenGL ES context of the specified window current on the calling thread. A context must only be made current on a single thread at a time and each thread can have only a single current context at a time.

-

When moving a context between threads, you must make it non-current on the old thread before making it current on the new one.

-

By default, making a context non-current implicitly forces a pipeline flush. On machines that support GL_KHR_context_flush_control, you can control whether a context performs this flush by setting the GLFW_CONTEXT_RELEASE_BEHAVIOR hint.

-

The specified window must have an OpenGL or OpenGL ES context. Specifying a window without a context will generate a GLFW_NO_WINDOW_CONTEXT error.

+

This function makes the OpenGL or OpenGL ES context of the specified window current on the calling thread. It can also detach the current context from the calling thread without making a new one current by passing in NULL.

+

A context must only be made current on a single thread at a time and each thread can have only a single current context at a time. Making a context current detaches any previously current context on the calling thread.

+

When moving a context between threads, you must detach it (make it non-current) on the old thread before making it current on the new one.

+

By default, making a context non-current implicitly forces a pipeline flush. On machines that support GL_KHR_context_flush_control, you can control whether a context performs this flush by setting the GLFW_CONTEXT_RELEASE_BEHAVIOR hint.

+

The specified window must have an OpenGL or OpenGL ES context. Specifying a window without a context will generate a GLFW_NO_WINDOW_CONTEXT error.

Parameters
[in]windowThe window whose context to make current, or NULL to detach the current context.
+
Remarks
If the previously current context was created via a different context creation API than the one passed to this function, GLFW will still detach the previous one from its API before making the new one current.
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_NO_WINDOW_CONTEXT and GLFW_PLATFORM_ERROR.
Thread safety
This function may be called from any thread.
See also
Current context
@@ -150,7 +159,7 @@ Functions
-

◆ glfwGetCurrentContext()

+

◆ glfwGetCurrentContext()

@@ -164,7 +173,7 @@ Functions
-

This function returns the window whose OpenGL or OpenGL ES context is current on the calling thread.

+

This function returns the window whose OpenGL or OpenGL ES context is current on the calling thread.

Returns
The window whose context is current, or NULL if no window's context is current.
Errors
Possible errors include GLFW_NOT_INITIALIZED.
Thread safety
This function may be called from any thread.
@@ -176,7 +185,7 @@ Functions
-

◆ glfwSwapInterval()

+

◆ glfwSwapInterval()

@@ -190,10 +199,10 @@ Functions
-

This function sets the swap interval for the current OpenGL or OpenGL ES context, i.e. the number of screen updates to wait from the time glfwSwapBuffers was called before swapping the buffers and returning. This is sometimes called vertical synchronization, vertical retrace synchronization or just vsync.

-

A context that supports either of the WGL_EXT_swap_control_tear and GLX_EXT_swap_control_tear extensions also accepts negative swap intervals, which allows the driver to swap immediately even if a frame arrives a little bit late. You can check for these extensions with glfwExtensionSupported.

-

A context must be current on the calling thread. Calling this function without a current context will cause a GLFW_NO_CURRENT_CONTEXT error.

-

This function does not apply to Vulkan. If you are rendering with Vulkan, see the present mode of your swapchain instead.

+

This function sets the swap interval for the current OpenGL or OpenGL ES context, i.e. the number of screen updates to wait from the time glfwSwapBuffers was called before swapping the buffers and returning. This is sometimes called vertical synchronization, vertical retrace synchronization or just vsync.

+

A context that supports either of the WGL_EXT_swap_control_tear and GLX_EXT_swap_control_tear extensions also accepts negative swap intervals, which allows the driver to swap immediately even if a frame arrives a little bit late. You can check for these extensions with glfwExtensionSupported.

+

A context must be current on the calling thread. Calling this function without a current context will cause a GLFW_NO_CURRENT_CONTEXT error.

+

This function does not apply to Vulkan. If you are rendering with Vulkan, see the present mode of your swapchain instead.

Parameters
@@ -201,7 +210,7 @@ Functions
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_NO_CURRENT_CONTEXT and GLFW_PLATFORM_ERROR.
-
Remarks
This function is not called during context creation, leaving the swap interval set to whatever is the default on that platform. This is done because some swap interval extensions used by GLFW do not allow the swap interval to be reset to zero once it has been set to a non-zero value.
+
Remarks
This function is not called during context creation, leaving the swap interval set to whatever is the default for that API. This is done because some swap interval extensions used by GLFW do not allow the swap interval to be reset to zero once it has been set to a non-zero value.
Some GPU drivers do not honor the requested swap interval, either because of a user setting that overrides the application's request or due to bugs in the driver.
Thread safety
This function may be called from any thread.
@@ -213,7 +222,7 @@ Some GPU drivers do not honor the requested swap interval, either because of a u -

◆ glfwExtensionSupported()

+

◆ glfwExtensionSupported()

@@ -227,10 +236,10 @@ Some GPU drivers do not honor the requested swap interval, either because of a u
[in]intervalThe minimum number of screen updates to wait for until the buffers are swapped by glfwSwapBuffers.
-

This function returns whether the specified API extension is supported by the current OpenGL or OpenGL ES context. It searches both for client API extension and context creation API extensions.

-

A context must be current on the calling thread. Calling this function without a current context will cause a GLFW_NO_CURRENT_CONTEXT error.

-

As this functions retrieves and searches one or more extension strings each call, it is recommended that you cache its results if it is going to be used frequently. The extension strings will not change during the lifetime of a context, so there is no danger in doing this.

-

This function does not apply to Vulkan. If you are using Vulkan, see glfwGetRequiredInstanceExtensions, vkEnumerateInstanceExtensionProperties and vkEnumerateDeviceExtensionProperties instead.

+

This function returns whether the specified API extension is supported by the current OpenGL or OpenGL ES context. It searches both for client API extension and context creation API extensions.

+

A context must be current on the calling thread. Calling this function without a current context will cause a GLFW_NO_CURRENT_CONTEXT error.

+

As this functions retrieves and searches one or more extension strings each call, it is recommended that you cache its results if it is going to be used frequently. The extension strings will not change during the lifetime of a context, so there is no danger in doing this.

+

This function does not apply to Vulkan. If you are using Vulkan, see glfwGetRequiredInstanceExtensions, vkEnumerateInstanceExtensionProperties and vkEnumerateDeviceExtensionProperties instead.

Parameters
@@ -248,7 +257,7 @@ Some GPU drivers do not honor the requested swap interval, either because of a u -

◆ glfwGetProcAddress()

+

◆ glfwGetProcAddress()

@@ -262,9 +271,9 @@ Some GPU drivers do not honor the requested swap interval, either because of a u
[in]extensionThe ASCII encoded name of the extension.
-

This function returns the address of the specified OpenGL or OpenGL ES core or extension function, if it is supported by the current context.

-

A context must be current on the calling thread. Calling this function without a current context will cause a GLFW_NO_CURRENT_CONTEXT error.

-

This function does not apply to Vulkan. If you are rendering with Vulkan, see glfwGetInstanceProcAddress, vkGetInstanceProcAddr and vkGetDeviceProcAddr instead.

+

This function returns the address of the specified OpenGL or OpenGL ES core or extension function, if it is supported by the current context.

+

A context must be current on the calling thread. Calling this function without a current context will cause a GLFW_NO_CURRENT_CONTEXT error.

+

This function does not apply to Vulkan. If you are rendering with Vulkan, see glfwGetInstanceProcAddress, vkGetInstanceProcAddr and vkGetDeviceProcAddr instead.

Parameters
@@ -288,7 +297,7 @@ This function may return a non-NULL address despite the associated diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/group__errors.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__errors.html new file mode 100644 index 0000000..3f1b5d6 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__errors.html @@ -0,0 +1,384 @@ + + + + + + + +GLFW: Error codes + + + + + + + + + + +
+ + + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+

Description

+

See error handling for how these are used.

+
[in]procnameThe ASCII encoded name of the function.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

#define GLFW_NO_ERROR   0
 No error has occurred.
 
#define GLFW_NOT_INITIALIZED   0x00010001
 GLFW has not been initialized.
 
#define GLFW_NO_CURRENT_CONTEXT   0x00010002
 No context is current for this thread.
 
#define GLFW_INVALID_ENUM   0x00010003
 One of the arguments to the function was an invalid enum value.
 
#define GLFW_INVALID_VALUE   0x00010004
 One of the arguments to the function was an invalid value.
 
#define GLFW_OUT_OF_MEMORY   0x00010005
 A memory allocation failed.
 
#define GLFW_API_UNAVAILABLE   0x00010006
 GLFW could not find support for the requested API on the system.
 
#define GLFW_VERSION_UNAVAILABLE   0x00010007
 The requested OpenGL or OpenGL ES version is not available.
 
#define GLFW_PLATFORM_ERROR   0x00010008
 A platform-specific error occurred that does not match any of the more specific categories.
 
#define GLFW_FORMAT_UNAVAILABLE   0x00010009
 The requested format is not supported or available.
 
#define GLFW_NO_WINDOW_CONTEXT   0x0001000A
 The specified window does not have an OpenGL or OpenGL ES context.
 
#define GLFW_CURSOR_UNAVAILABLE   0x0001000B
 The specified cursor shape is not available.
 
#define GLFW_FEATURE_UNAVAILABLE   0x0001000C
 The requested feature is not provided by the platform.
 
#define GLFW_FEATURE_UNIMPLEMENTED   0x0001000D
 The requested feature is not implemented for the platform.
 
#define GLFW_PLATFORM_UNAVAILABLE   0x0001000E
 Platform unavailable or no matching platform was found.
 
+

Macro Definition Documentation

+ +

◆ GLFW_NO_ERROR

+ +
+
+ + + + +
#define GLFW_NO_ERROR   0
+
+

No error has occurred.

+
Analysis
Yay.
+ +
+
+ +

◆ GLFW_NOT_INITIALIZED

+ +
+
+ + + + +
#define GLFW_NOT_INITIALIZED   0x00010001
+
+

This occurs if a GLFW function was called that must not be called unless the library is initialized.

+
Analysis
Application programmer error. Initialize GLFW before calling any function that requires initialization.
+ +
+
+ +

◆ GLFW_NO_CURRENT_CONTEXT

+ +
+
+ + + + +
#define GLFW_NO_CURRENT_CONTEXT   0x00010002
+
+

This occurs if a GLFW function was called that needs and operates on the current OpenGL or OpenGL ES context but no context is current on the calling thread. One such function is glfwSwapInterval.

+
Analysis
Application programmer error. Ensure a context is current before calling functions that require a current context.
+ +
+
+ +

◆ GLFW_INVALID_ENUM

+ +
+
+ + + + +
#define GLFW_INVALID_ENUM   0x00010003
+
+

One of the arguments to the function was an invalid enum value, for example requesting GLFW_RED_BITS with glfwGetWindowAttrib.

+
Analysis
Application programmer error. Fix the offending call.
+ +
+
+ +

◆ GLFW_INVALID_VALUE

+ +
+
+ + + + +
#define GLFW_INVALID_VALUE   0x00010004
+
+

One of the arguments to the function was an invalid value, for example requesting a non-existent OpenGL or OpenGL ES version like 2.7.

+

Requesting a valid but unavailable OpenGL or OpenGL ES version will instead result in a GLFW_VERSION_UNAVAILABLE error.

+
Analysis
Application programmer error. Fix the offending call.
+ +
+
+ +

◆ GLFW_OUT_OF_MEMORY

+ +
+
+ + + + +
#define GLFW_OUT_OF_MEMORY   0x00010005
+
+

A memory allocation failed.

+
Analysis
A bug in GLFW or the underlying operating system. Report the bug to our issue tracker.
+ +
+
+ +

◆ GLFW_API_UNAVAILABLE

+ +
+
+ + + + +
#define GLFW_API_UNAVAILABLE   0x00010006
+
+

GLFW could not find support for the requested API on the system.

+
Analysis
The installed graphics driver does not support the requested API, or does not support it via the chosen context creation API. Below are a few examples.
+
Some pre-installed Windows graphics drivers do not support OpenGL. AMD only supports OpenGL ES via EGL, while Nvidia and Intel only support it via a WGL or GLX extension. macOS does not provide OpenGL ES at all. The Mesa EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary driver. Older graphics drivers do not support Vulkan.
+ +
+
+ +

◆ GLFW_VERSION_UNAVAILABLE

+ +
+
+ + + + +
#define GLFW_VERSION_UNAVAILABLE   0x00010007
+
+

The requested OpenGL or OpenGL ES version (including any requested context or framebuffer hints) is not available on this machine.

+
Analysis
The machine does not support your requirements. If your application is sufficiently flexible, downgrade your requirements and try again. Otherwise, inform the user that their machine does not match your requirements.
+
Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0 comes out before the 4.x series gets that far, also fail with this error and not GLFW_INVALID_VALUE, because GLFW cannot know what future versions will exist.
+ +
+
+ +

◆ GLFW_PLATFORM_ERROR

+ +
+
+ + + + +
#define GLFW_PLATFORM_ERROR   0x00010008
+
+

A platform-specific error occurred that does not match any of the more specific categories.

+
Analysis
A bug or configuration error in GLFW, the underlying operating system or its drivers, or a lack of required resources. Report the issue to our issue tracker.
+ +
+
+ +

◆ GLFW_FORMAT_UNAVAILABLE

+ +
+
+ + + + +
#define GLFW_FORMAT_UNAVAILABLE   0x00010009
+
+

If emitted during window creation, the requested pixel format is not supported.

+

If emitted when querying the clipboard, the contents of the clipboard could not be converted to the requested format.

+
Analysis
If emitted during window creation, one or more hard constraints did not match any of the available pixel formats. If your application is sufficiently flexible, downgrade your requirements and try again. Otherwise, inform the user that their machine does not match your requirements.
+
If emitted when querying the clipboard, ignore the error or report it to the user, as appropriate.
+ +
+
+ +

◆ GLFW_NO_WINDOW_CONTEXT

+ +
+
+ + + + +
#define GLFW_NO_WINDOW_CONTEXT   0x0001000A
+
+

A window that does not have an OpenGL or OpenGL ES context was passed to a function that requires it to have one.

+
Analysis
Application programmer error. Fix the offending call.
+ +
+
+ +

◆ GLFW_CURSOR_UNAVAILABLE

+ +
+
+ + + + +
#define GLFW_CURSOR_UNAVAILABLE   0x0001000B
+
+

The specified standard cursor shape is not available, either because the current platform cursor theme does not provide it or because it is not available on the platform.

+
Analysis
Platform or system settings limitation. Pick another standard cursor shape or create a custom cursor.
+ +
+
+ +

◆ GLFW_FEATURE_UNAVAILABLE

+ +
+
+ + + + +
#define GLFW_FEATURE_UNAVAILABLE   0x0001000C
+
+

The requested feature is not provided by the platform, so GLFW is unable to implement it. The documentation for each function notes if it could emit this error.

+
Analysis
Platform or platform version limitation. The error can be ignored unless the feature is critical to the application.
+
A function call that emits this error has no effect other than the error and updating any existing out parameters.
+ +
+
+ +

◆ GLFW_FEATURE_UNIMPLEMENTED

+ +
+
+ + + + +
#define GLFW_FEATURE_UNIMPLEMENTED   0x0001000D
+
+

The requested feature has not yet been implemented in GLFW for this platform.

+
Analysis
An incomplete implementation of GLFW for this platform, hopefully fixed in a future release. The error can be ignored unless the feature is critical to the application.
+
A function call that emits this error has no effect other than the error and updating any existing out parameters.
+ +
+
+ +

◆ GLFW_PLATFORM_UNAVAILABLE

+ +
+
+ + + + +
#define GLFW_PLATFORM_UNAVAILABLE   0x0001000E
+
+

If emitted during initialization, no matching platform was found. If the GLFW_PLATFORM init hint was set to GLFW_ANY_PLATFORM, GLFW could not detect any of the platforms supported by this library binary, except for the Null platform. If the init hint was set to a specific platform, it is either not supported by this library binary or GLFW was not able to detect it.

+

If emitted by a native access function, GLFW was initialized for a different platform than the function is for.

+
Analysis
Failure to detect any platform usually only happens on non-macOS Unix systems, either when no window system is running or the program was run from a terminal that does not have the necessary environment variables. Fall back to a different platform if possible or notify the user that no usable platform was detected.
+

Failure to detect a specific platform may have the same cause as above or be because support for that platform was not compiled in. Call glfwPlatformSupported to check whether a specific platform is supported by a library binary.

+ +
+
+
+ + + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__gamepad__axes.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__gamepad__axes.html similarity index 65% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/group__gamepad__axes.html rename to src/lib/src/vendor/glfw-3.4/docs/html/group__gamepad__axes.html index 5dc84be..dafbf6c 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__gamepad__axes.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__gamepad__axes.html @@ -4,7 +4,7 @@ - + GLFW: Gamepad axes @@ -28,10 +28,10 @@
- + @@ -55,9 +55,16 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -67,28 +74,28 @@ $(function() {

Description

-

See Gamepad input for how these are used.

+

See Gamepad input for how these are used.

- + - + - + - + - + - + - +

Macros

#define GLFW_GAMEPAD_AXIS_LEFT_X   0
#define GLFW_GAMEPAD_AXIS_LEFT_X   0
 
#define GLFW_GAMEPAD_AXIS_LEFT_Y   1
#define GLFW_GAMEPAD_AXIS_LEFT_Y   1
 
#define GLFW_GAMEPAD_AXIS_RIGHT_X   2
#define GLFW_GAMEPAD_AXIS_RIGHT_X   2
 
#define GLFW_GAMEPAD_AXIS_RIGHT_Y   3
#define GLFW_GAMEPAD_AXIS_RIGHT_Y   3
 
#define GLFW_GAMEPAD_AXIS_LEFT_TRIGGER   4
#define GLFW_GAMEPAD_AXIS_LEFT_TRIGGER   4
 
#define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER   5
#define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER   5
 
#define GLFW_GAMEPAD_AXIS_LAST   GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
#define GLFW_GAMEPAD_AXIS_LAST   GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
 

Macro Definition Documentation

-

◆ GLFW_GAMEPAD_AXIS_LEFT_X

+

◆ GLFW_GAMEPAD_AXIS_LEFT_X

@@ -102,7 +109,7 @@ Macros
-

◆ GLFW_GAMEPAD_AXIS_LEFT_Y

+

◆ GLFW_GAMEPAD_AXIS_LEFT_Y

@@ -116,7 +123,7 @@ Macros
-

◆ GLFW_GAMEPAD_AXIS_RIGHT_X

+

◆ GLFW_GAMEPAD_AXIS_RIGHT_X

@@ -130,7 +137,7 @@ Macros
-

◆ GLFW_GAMEPAD_AXIS_RIGHT_Y

+

◆ GLFW_GAMEPAD_AXIS_RIGHT_Y

@@ -144,7 +151,7 @@ Macros
-

◆ GLFW_GAMEPAD_AXIS_LEFT_TRIGGER

+

◆ GLFW_GAMEPAD_AXIS_LEFT_TRIGGER

@@ -158,7 +165,7 @@ Macros
-

◆ GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER

+

◆ GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER

@@ -172,7 +179,7 @@ Macros
-

◆ GLFW_GAMEPAD_AXIS_LAST

+

◆ GLFW_GAMEPAD_AXIS_LAST

@@ -188,7 +195,7 @@ Macros
diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__gamepad__buttons.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__gamepad__buttons.html similarity index 59% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/group__gamepad__buttons.html rename to src/lib/src/vendor/glfw-3.4/docs/html/group__gamepad__buttons.html index 51c027d..c5e01c0 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__gamepad__buttons.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__gamepad__buttons.html @@ -4,7 +4,7 @@ - + GLFW: Gamepad buttons @@ -28,10 +28,10 @@
- + @@ -55,9 +55,16 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -67,54 +74,54 @@ $(function() {

Description

-

See Gamepad input for how these are used.

+

See Gamepad input for how these are used.

- + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +

Macros

#define GLFW_GAMEPAD_BUTTON_A   0
#define GLFW_GAMEPAD_BUTTON_A   0
 
#define GLFW_GAMEPAD_BUTTON_B   1
#define GLFW_GAMEPAD_BUTTON_B   1
 
#define GLFW_GAMEPAD_BUTTON_X   2
#define GLFW_GAMEPAD_BUTTON_X   2
 
#define GLFW_GAMEPAD_BUTTON_Y   3
#define GLFW_GAMEPAD_BUTTON_Y   3
 
#define GLFW_GAMEPAD_BUTTON_LEFT_BUMPER   4
#define GLFW_GAMEPAD_BUTTON_LEFT_BUMPER   4
 
#define GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER   5
#define GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER   5
 
#define GLFW_GAMEPAD_BUTTON_BACK   6
#define GLFW_GAMEPAD_BUTTON_BACK   6
 
#define GLFW_GAMEPAD_BUTTON_START   7
#define GLFW_GAMEPAD_BUTTON_START   7
 
#define GLFW_GAMEPAD_BUTTON_GUIDE   8
#define GLFW_GAMEPAD_BUTTON_GUIDE   8
 
#define GLFW_GAMEPAD_BUTTON_LEFT_THUMB   9
#define GLFW_GAMEPAD_BUTTON_LEFT_THUMB   9
 
#define GLFW_GAMEPAD_BUTTON_RIGHT_THUMB   10
#define GLFW_GAMEPAD_BUTTON_RIGHT_THUMB   10
 
#define GLFW_GAMEPAD_BUTTON_DPAD_UP   11
#define GLFW_GAMEPAD_BUTTON_DPAD_UP   11
 
#define GLFW_GAMEPAD_BUTTON_DPAD_RIGHT   12
#define GLFW_GAMEPAD_BUTTON_DPAD_RIGHT   12
 
#define GLFW_GAMEPAD_BUTTON_DPAD_DOWN   13
#define GLFW_GAMEPAD_BUTTON_DPAD_DOWN   13
 
#define GLFW_GAMEPAD_BUTTON_DPAD_LEFT   14
#define GLFW_GAMEPAD_BUTTON_DPAD_LEFT   14
 
#define GLFW_GAMEPAD_BUTTON_LAST   GLFW_GAMEPAD_BUTTON_DPAD_LEFT
#define GLFW_GAMEPAD_BUTTON_LAST   GLFW_GAMEPAD_BUTTON_DPAD_LEFT
 
#define GLFW_GAMEPAD_BUTTON_CROSS   GLFW_GAMEPAD_BUTTON_A
#define GLFW_GAMEPAD_BUTTON_CROSS   GLFW_GAMEPAD_BUTTON_A
 
#define GLFW_GAMEPAD_BUTTON_CIRCLE   GLFW_GAMEPAD_BUTTON_B
#define GLFW_GAMEPAD_BUTTON_CIRCLE   GLFW_GAMEPAD_BUTTON_B
 
#define GLFW_GAMEPAD_BUTTON_SQUARE   GLFW_GAMEPAD_BUTTON_X
#define GLFW_GAMEPAD_BUTTON_SQUARE   GLFW_GAMEPAD_BUTTON_X
 
#define GLFW_GAMEPAD_BUTTON_TRIANGLE   GLFW_GAMEPAD_BUTTON_Y
#define GLFW_GAMEPAD_BUTTON_TRIANGLE   GLFW_GAMEPAD_BUTTON_Y
 

Macro Definition Documentation

-

◆ GLFW_GAMEPAD_BUTTON_A

+

◆ GLFW_GAMEPAD_BUTTON_A

@@ -128,7 +135,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_B

+

◆ GLFW_GAMEPAD_BUTTON_B

@@ -142,7 +149,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_X

+

◆ GLFW_GAMEPAD_BUTTON_X

@@ -156,7 +163,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_Y

+

◆ GLFW_GAMEPAD_BUTTON_Y

@@ -170,7 +177,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_LEFT_BUMPER

+

◆ GLFW_GAMEPAD_BUTTON_LEFT_BUMPER

@@ -184,7 +191,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER

+

◆ GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER

@@ -198,7 +205,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_BACK

+

◆ GLFW_GAMEPAD_BUTTON_BACK

@@ -212,7 +219,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_START

+

◆ GLFW_GAMEPAD_BUTTON_START

@@ -226,7 +233,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_GUIDE

+

◆ GLFW_GAMEPAD_BUTTON_GUIDE

@@ -240,7 +247,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_LEFT_THUMB

+

◆ GLFW_GAMEPAD_BUTTON_LEFT_THUMB

@@ -254,7 +261,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_RIGHT_THUMB

+

◆ GLFW_GAMEPAD_BUTTON_RIGHT_THUMB

@@ -268,7 +275,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_DPAD_UP

+

◆ GLFW_GAMEPAD_BUTTON_DPAD_UP

@@ -282,7 +289,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_DPAD_RIGHT

+

◆ GLFW_GAMEPAD_BUTTON_DPAD_RIGHT

@@ -296,7 +303,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_DPAD_DOWN

+

◆ GLFW_GAMEPAD_BUTTON_DPAD_DOWN

@@ -310,7 +317,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_DPAD_LEFT

+

◆ GLFW_GAMEPAD_BUTTON_DPAD_LEFT

@@ -324,7 +331,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_LAST

+

◆ GLFW_GAMEPAD_BUTTON_LAST

@@ -338,7 +345,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_CROSS

+

◆ GLFW_GAMEPAD_BUTTON_CROSS

@@ -352,7 +359,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_CIRCLE

+

◆ GLFW_GAMEPAD_BUTTON_CIRCLE

@@ -366,7 +373,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_SQUARE

+

◆ GLFW_GAMEPAD_BUTTON_SQUARE

@@ -380,7 +387,7 @@ Macros
-

◆ GLFW_GAMEPAD_BUTTON_TRIANGLE

+

◆ GLFW_GAMEPAD_BUTTON_TRIANGLE

@@ -396,7 +403,7 @@ Macros
diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__hat__state.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__hat__state.html similarity index 62% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/group__hat__state.html rename to src/lib/src/vendor/glfw-3.4/docs/html/group__hat__state.html index d08f541..bbee7aa 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__hat__state.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__hat__state.html @@ -4,7 +4,7 @@ - + GLFW: Joystick hat states @@ -28,10 +28,10 @@
- + @@ -55,9 +55,16 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -67,32 +74,32 @@ $(function() {

Description

-

See joystick hat input for how these are used.

+

See joystick hat input for how these are used.

- + - + - + - + - + - + - + - + - +

Macros

#define GLFW_HAT_CENTERED   0
#define GLFW_HAT_CENTERED   0
 
#define GLFW_HAT_UP   1
#define GLFW_HAT_UP   1
 
#define GLFW_HAT_RIGHT   2
#define GLFW_HAT_RIGHT   2
 
#define GLFW_HAT_DOWN   4
#define GLFW_HAT_DOWN   4
 
#define GLFW_HAT_LEFT   8
#define GLFW_HAT_LEFT   8
 
#define GLFW_HAT_RIGHT_UP   (GLFW_HAT_RIGHT | GLFW_HAT_UP)
#define GLFW_HAT_RIGHT_UP   (GLFW_HAT_RIGHT | GLFW_HAT_UP)
 
#define GLFW_HAT_RIGHT_DOWN   (GLFW_HAT_RIGHT | GLFW_HAT_DOWN)
#define GLFW_HAT_RIGHT_DOWN   (GLFW_HAT_RIGHT | GLFW_HAT_DOWN)
 
#define GLFW_HAT_LEFT_UP   (GLFW_HAT_LEFT | GLFW_HAT_UP)
#define GLFW_HAT_LEFT_UP   (GLFW_HAT_LEFT | GLFW_HAT_UP)
 
#define GLFW_HAT_LEFT_DOWN   (GLFW_HAT_LEFT | GLFW_HAT_DOWN)
#define GLFW_HAT_LEFT_DOWN   (GLFW_HAT_LEFT | GLFW_HAT_DOWN)
 

Macro Definition Documentation

-

◆ GLFW_HAT_CENTERED

+

◆ GLFW_HAT_CENTERED

@@ -106,7 +113,7 @@ Macros
-

◆ GLFW_HAT_UP

+

◆ GLFW_HAT_UP

@@ -120,7 +127,7 @@ Macros
-

◆ GLFW_HAT_RIGHT

+

◆ GLFW_HAT_RIGHT

@@ -134,7 +141,7 @@ Macros
-

◆ GLFW_HAT_DOWN

+

◆ GLFW_HAT_DOWN

@@ -148,7 +155,7 @@ Macros
-

◆ GLFW_HAT_LEFT

+

◆ GLFW_HAT_LEFT

@@ -162,7 +169,7 @@ Macros
-

◆ GLFW_HAT_RIGHT_UP

+

◆ GLFW_HAT_RIGHT_UP

@@ -176,7 +183,7 @@ Macros
-

◆ GLFW_HAT_RIGHT_DOWN

+

◆ GLFW_HAT_RIGHT_DOWN

@@ -190,7 +197,7 @@ Macros
-

◆ GLFW_HAT_LEFT_UP

+

◆ GLFW_HAT_LEFT_UP

@@ -204,7 +211,7 @@ Macros
-

◆ GLFW_HAT_LEFT_DOWN

+

◆ GLFW_HAT_LEFT_DOWN

@@ -220,7 +227,7 @@ Macros
diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/group__init.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__init.html new file mode 100644 index 0000000..f910fb7 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__init.html @@ -0,0 +1,1015 @@ + + + + + + + +GLFW: Initialization, version and error reference + + + + + + + + + + +
+ + + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
Initialization, version and error reference
+
+
+

Description

+

This is the reference documentation for initialization and termination of the library, version management and error handling. For more task-oriented information, see the Introduction to the API.

+ + + + + +

+Modules

 Error codes
 Error codes.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

#define GLFW_TRUE   1
 One.
 
#define GLFW_FALSE   0
 Zero.
 
#define GLFW_JOYSTICK_HAT_BUTTONS   0x00050001
 Joystick hat buttons init hint.
 
#define GLFW_ANGLE_PLATFORM_TYPE   0x00050002
 ANGLE rendering backend init hint.
 
#define GLFW_PLATFORM   0x00050003
 Platform selection init hint.
 
#define GLFW_COCOA_CHDIR_RESOURCES   0x00051001
 macOS specific init hint.
 
#define GLFW_COCOA_MENUBAR   0x00051002
 macOS specific init hint.
 
#define GLFW_X11_XCB_VULKAN_SURFACE   0x00052001
 X11 specific init hint.
 
#define GLFW_WAYLAND_LIBDECOR   0x00053001
 Wayland specific init hint.
 
#define GLFW_ANY_PLATFORM   0x00060000
 Hint value that enables automatic platform selection.
 
#define GLFW_PLATFORM_WIN32   0x00060001
 
#define GLFW_PLATFORM_COCOA   0x00060002
 
#define GLFW_PLATFORM_WAYLAND   0x00060003
 
#define GLFW_PLATFORM_X11   0x00060004
 
#define GLFW_PLATFORM_NULL   0x00060005
 
+ + + + + + + + + + + + + + + + +

+Typedefs

typedef void *(* GLFWallocatefun) (size_t size, void *user)
 The function pointer type for memory allocation callbacks.
 
typedef void *(* GLFWreallocatefun) (void *block, size_t size, void *user)
 The function pointer type for memory reallocation callbacks.
 
typedef void(* GLFWdeallocatefun) (void *block, void *user)
 The function pointer type for memory deallocation callbacks.
 
typedef void(* GLFWerrorfun) (int error_code, const char *description)
 The function pointer type for error callbacks.
 
typedef struct GLFWallocator GLFWallocator
 Custom heap memory allocator.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

int glfwInit (void)
 Initializes the GLFW library.
 
void glfwTerminate (void)
 Terminates the GLFW library.
 
void glfwInitHint (int hint, int value)
 Sets the specified init hint to the desired value.
 
void glfwInitAllocator (const GLFWallocator *allocator)
 Sets the init allocator to the desired value.
 
void glfwInitVulkanLoader (PFN_vkGetInstanceProcAddr loader)
 Sets the desired Vulkan vkGetInstanceProcAddr function.
 
void glfwGetVersion (int *major, int *minor, int *rev)
 Retrieves the version of the GLFW library.
 
const char * glfwGetVersionString (void)
 Returns a string describing the compile-time configuration.
 
int glfwGetError (const char **description)
 Returns and clears the last error for the calling thread.
 
GLFWerrorfun glfwSetErrorCallback (GLFWerrorfun callback)
 Sets the error callback.
 
int glfwGetPlatform (void)
 Returns the currently selected platform.
 
int glfwPlatformSupported (int platform)
 Returns whether the library includes support for the specified platform.
 
+

Macro Definition Documentation

+ +

◆ GLFW_VERSION_MAJOR

+ +
+
+ + + + +
#define GLFW_VERSION_MAJOR   3
+
+

The major version number of the GLFW header. This is incremented when the API is changed in non-compatible ways.

+ +
+
+ +

◆ GLFW_VERSION_MINOR

+ +
+
+ + + + +
#define GLFW_VERSION_MINOR   4
+
+

The minor version number of the GLFW header. This is incremented when features are added to the API but it remains backward-compatible.

+ +
+
+ +

◆ GLFW_VERSION_REVISION

+ +
+
+ + + + +
#define GLFW_VERSION_REVISION   0
+
+

The revision number of the GLFW header. This is incremented when a bug fix release is made that does not contain any API changes.

+ +
+
+ +

◆ GLFW_TRUE

+ +
+
+ + + + +
#define GLFW_TRUE   1
+
+

This is only semantic sugar for the number 1. You can instead use 1 or true or _True or GL_TRUE or VK_TRUE or anything else that is equal to one.

+ +
+
+ +

◆ GLFW_FALSE

+ +
+
+ + + + +
#define GLFW_FALSE   0
+
+

This is only semantic sugar for the number 0. You can instead use 0 or false or _False or GL_FALSE or VK_FALSE or anything else that is equal to zero.

+ +
+
+ +

◆ GLFW_JOYSTICK_HAT_BUTTONS

+ +
+
+ + + + +
#define GLFW_JOYSTICK_HAT_BUTTONS   0x00050001
+
+

Joystick hat buttons init hint.

+ +
+
+ +

◆ GLFW_ANGLE_PLATFORM_TYPE

+ +
+
+ + + + +
#define GLFW_ANGLE_PLATFORM_TYPE   0x00050002
+
+

ANGLE rendering backend init hint.

+ +
+
+ +

◆ GLFW_PLATFORM

+ +
+
+ + + + +
#define GLFW_PLATFORM   0x00050003
+
+

Platform selection init hint.

+ +
+
+ +

◆ GLFW_COCOA_CHDIR_RESOURCES

+ +
+
+ + + + +
#define GLFW_COCOA_CHDIR_RESOURCES   0x00051001
+
+

macOS specific init hint.

+ +
+
+ +

◆ GLFW_COCOA_MENUBAR

+ +
+
+ + + + +
#define GLFW_COCOA_MENUBAR   0x00051002
+
+

macOS specific init hint.

+ +
+
+ +

◆ GLFW_X11_XCB_VULKAN_SURFACE

+ +
+
+ + + + +
#define GLFW_X11_XCB_VULKAN_SURFACE   0x00052001
+
+

X11 specific init hint.

+ +
+
+ +

◆ GLFW_WAYLAND_LIBDECOR

+ +
+
+ + + + +
#define GLFW_WAYLAND_LIBDECOR   0x00053001
+
+

Wayland specific init hint.

+ +
+
+ +

◆ GLFW_ANY_PLATFORM

+ +
+
+ + + + +
#define GLFW_ANY_PLATFORM   0x00060000
+
+

Hint value for GLFW_PLATFORM that enables automatic platform selection.

+ +
+
+ +

◆ GLFW_PLATFORM_WIN32

+ +
+
+ + + + +
#define GLFW_PLATFORM_WIN32   0x00060001
+
+ +
+
+ +

◆ GLFW_PLATFORM_COCOA

+ +
+
+ + + + +
#define GLFW_PLATFORM_COCOA   0x00060002
+
+ +
+
+ +

◆ GLFW_PLATFORM_WAYLAND

+ +
+
+ + + + +
#define GLFW_PLATFORM_WAYLAND   0x00060003
+
+ +
+
+ +

◆ GLFW_PLATFORM_X11

+ +
+
+ + + + +
#define GLFW_PLATFORM_X11   0x00060004
+
+ +
+
+ +

◆ GLFW_PLATFORM_NULL

+ +
+
+ + + + +
#define GLFW_PLATFORM_NULL   0x00060005
+
+ +
+
+

Typedef Documentation

+ +

◆ GLFWallocatefun

+ +
+
+ + + + +
typedef void *(* GLFWallocatefun) (size_t size, void *user)
+
+

This is the function pointer type for memory allocation callbacks. A memory allocation callback function has the following signature:

void* function_name(size_t size, void* user)
+

This function must return either a memory block at least size bytes long, or NULL if allocation failed. Note that not all parts of GLFW handle allocation failures gracefully yet.

+

This function must support being called during glfwInit but before the library is flagged as initialized, as well as during glfwTerminate after the library is no longer flagged as initialized.

+

Any memory allocated via this function will be deallocated via the same allocator during library termination or earlier.

+

Any memory allocated via this function must be suitably aligned for any object type. If you are using C99 or earlier, this alignment is platform-dependent but will be the same as what malloc provides. If you are using C11 or later, this is the value of alignof(max_align_t).

+

The size will always be greater than zero. Allocations of size zero are filtered out before reaching the custom allocator.

+

If this function returns NULL, GLFW will emit GLFW_OUT_OF_MEMORY.

+

This function must not call any GLFW function.

+
Parameters
+ + + +
[in]sizeThe minimum size, in bytes, of the memory block.
[in]userThe user-defined pointer from the allocator.
+
+
+
Returns
The address of the newly allocated memory block, or NULL if an error occurred.
+
Pointer lifetime
The returned memory block must be valid at least until it is deallocated.
+
Reentrancy
This function should not call any GLFW function.
+
Thread safety
This function must support being called from any thread that calls GLFW functions.
+
See also
Custom heap memory allocator
+
+GLFWallocator
+
Since
Added in version 3.4.
+ +
+
+ +

◆ GLFWreallocatefun

+ +
+
+ + + + +
typedef void *(* GLFWreallocatefun) (void *block, size_t size, void *user)
+
+

This is the function pointer type for memory reallocation callbacks. A memory reallocation callback function has the following signature:

void* function_name(void* block, size_t size, void* user)
+

This function must return a memory block at least size bytes long, or NULL if allocation failed. Note that not all parts of GLFW handle allocation failures gracefully yet.

+

This function must support being called during glfwInit but before the library is flagged as initialized, as well as during glfwTerminate after the library is no longer flagged as initialized.

+

Any memory allocated via this function will be deallocated via the same allocator during library termination or earlier.

+

Any memory allocated via this function must be suitably aligned for any object type. If you are using C99 or earlier, this alignment is platform-dependent but will be the same as what realloc provides. If you are using C11 or later, this is the value of alignof(max_align_t).

+

The block address will never be NULL and the size will always be greater than zero. Reallocations of a block to size zero are converted into deallocations before reaching the custom allocator. Reallocations of NULL to a non-zero size are converted into regular allocations before reaching the custom allocator.

+

If this function returns NULL, GLFW will emit GLFW_OUT_OF_MEMORY.

+

This function must not call any GLFW function.

+
Parameters
+ + + + +
[in]blockThe address of the memory block to reallocate.
[in]sizeThe new minimum size, in bytes, of the memory block.
[in]userThe user-defined pointer from the allocator.
+
+
+
Returns
The address of the newly allocated or resized memory block, or NULL if an error occurred.
+
Pointer lifetime
The returned memory block must be valid at least until it is deallocated.
+
Reentrancy
This function should not call any GLFW function.
+
Thread safety
This function must support being called from any thread that calls GLFW functions.
+
See also
Custom heap memory allocator
+
+GLFWallocator
+
Since
Added in version 3.4.
+ +
+
+ +

◆ GLFWdeallocatefun

+ +
+
+ + + + +
typedef void(* GLFWdeallocatefun) (void *block, void *user)
+
+

This is the function pointer type for memory deallocation callbacks. A memory deallocation callback function has the following signature:

void function_name(void* block, void* user)
+

This function may deallocate the specified memory block. This memory block will have been allocated with the same allocator.

+

This function must support being called during glfwInit but before the library is flagged as initialized, as well as during glfwTerminate after the library is no longer flagged as initialized.

+

The block address will never be NULL. Deallocations of NULL are filtered out before reaching the custom allocator.

+

If this function returns NULL, GLFW will emit GLFW_OUT_OF_MEMORY.

+

This function must not call any GLFW function.

+
Parameters
+ + + +
[in]blockThe address of the memory block to deallocate.
[in]userThe user-defined pointer from the allocator.
+
+
+
Pointer lifetime
The specified memory block will not be accessed by GLFW after this function is called.
+
Reentrancy
This function should not call any GLFW function.
+
Thread safety
This function must support being called from any thread that calls GLFW functions.
+
See also
Custom heap memory allocator
+
+GLFWallocator
+
Since
Added in version 3.4.
+ +
+
+ +

◆ GLFWerrorfun

+ +
+
+ + + + +
typedef void(* GLFWerrorfun) (int error_code, const char *description)
+
+

This is the function pointer type for error callbacks. An error callback function has the following signature:

void callback_name(int error_code, const char* description)
+
Parameters
+ + + +
[in]error_codeAn error code. Future releases may add more error codes.
[in]descriptionA UTF-8 encoded string describing the error.
+
+
+
Pointer lifetime
The error description string is valid until the callback function returns.
+
See also
Error handling
+
+glfwSetErrorCallback
+
Since
Added in version 3.0.
+ +
+
+ +

◆ GLFWallocator

+ +
+
+ + + + +
typedef struct GLFWallocator GLFWallocator
+
+

This describes a custom heap memory allocator for GLFW. To set an allocator, pass it to glfwInitAllocator before initializing the library.

+
See also
Custom heap memory allocator
+
+glfwInitAllocator
+
Since
Added in version 3.4.
+ +
+
+

Function Documentation

+ +

◆ glfwInit()

+ +
+
+ + + + + + + + +
int glfwInit (void )
+
+

This function initializes the GLFW library. Before most GLFW functions can be used, GLFW must be initialized, and before an application terminates GLFW should be terminated in order to free any resources allocated during or after initialization.

+

If this function fails, it calls glfwTerminate before returning. If it succeeds, you should call glfwTerminate before the application exits.

+

Additional calls to this function after successful initialization but before termination will return GLFW_TRUE immediately.

+

The GLFW_PLATFORM init hint controls which platforms are considered during initialization. This also depends on which platforms the library was compiled to support.

+
Returns
GLFW_TRUE if successful, or GLFW_FALSE if an error occurred.
+
Errors
Possible errors include GLFW_PLATFORM_UNAVAILABLE and GLFW_PLATFORM_ERROR.
+
Remarks
macOS: This function will change the current directory of the application to the Contents/Resources subdirectory of the application's bundle, if present. This can be disabled with the GLFW_COCOA_CHDIR_RESOURCES init hint.
+
+macOS: This function will create the main menu and dock icon for the application. If GLFW finds a MainMenu.nib it is loaded and assumed to contain a menu bar. Otherwise a minimal menu bar is created manually with common commands like Hide, Quit and About. The About entry opens a minimal about dialog with information from the application's bundle. The menu bar and dock icon can be disabled entirely with the GLFW_COCOA_MENUBAR init hint.
+
+Wayland, X11: If the library was compiled with support for both Wayland and X11, and the GLFW_PLATFORM init hint is set to GLFW_ANY_PLATFORM, the XDG_SESSION_TYPE environment variable affects which platform is picked. If the environment variable is not set, or is set to something other than wayland or x11, the regular detection mechanism will be used instead.
+
+X11: This function will set the LC_CTYPE category of the application locale according to the current environment if that category is still "C". This is because the "C" locale breaks Unicode text input.
+
Thread safety
This function must only be called from the main thread.
+
See also
Initialization and termination
+
+glfwInitHint
+
+glfwInitAllocator
+
+glfwTerminate
+
Since
Added in version 1.0.
+ +
+
+ +

◆ glfwTerminate()

+ +
+
+ + + + + + + + +
void glfwTerminate (void )
+
+

This function destroys all remaining windows and cursors, restores any modified gamma ramps and frees any other allocated resources. Once this function is called, you must again call glfwInit successfully before you will be able to use most GLFW functions.

+

If GLFW has been successfully initialized, this function should be called before the application exits. If initialization fails, there is no need to call this function, as it is called by glfwInit before it returns failure.

+

This function has no effect if GLFW is not initialized.

+
Errors
Possible errors include GLFW_PLATFORM_ERROR.
+
Remarks
This function may be called before glfwInit.
+
Warning
The contexts of any remaining windows must not be current on any other thread when this function is called.
+
Reentrancy
This function must not be called from a callback.
+
Thread safety
This function must only be called from the main thread.
+
See also
Initialization and termination
+
+glfwInit
+
Since
Added in version 1.0.
+ +
+
+ +

◆ glfwInitHint()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void glfwInitHint (int hint,
int value 
)
+
+

This function sets hints for the next initialization of GLFW.

+

The values you set hints to are never reset by GLFW, but they only take effect during initialization. Once GLFW has been initialized, any values you set will be ignored until the library is terminated and initialized again.

+

Some hints are platform specific. These may be set on any platform but they will only affect their specific platform. Other platforms will ignore them. Setting these hints requires no platform specific headers or functions.

+
Parameters
+ + + +
[in]hintThe init hint to set.
[in]valueThe new value of the init hint.
+
+
+
Errors
Possible errors include GLFW_INVALID_ENUM and GLFW_INVALID_VALUE.
+
Remarks
This function may be called before glfwInit.
+
Thread safety
This function must only be called from the main thread.
+
See also
init_hints
+
+glfwInit
+
Since
Added in version 3.3.
+ +
+
+ +

◆ glfwInitAllocator()

+ +
+
+ + + + + + + + +
void glfwInitAllocator (const GLFWallocatorallocator)
+
+

To use the default allocator, call this function with a NULL argument.

+

If you specify an allocator struct, every member must be a valid function pointer. If any member is NULL, this function will emit GLFW_INVALID_VALUE and the init allocator will be unchanged.

+

The functions in the allocator must fulfil a number of requirements. See the documentation for GLFWallocatefun, GLFWreallocatefun and GLFWdeallocatefun for details.

+
Parameters
+ + +
[in]allocatorThe allocator to use at the next initialization, or NULL to use the default one.
+
+
+
Errors
Possible errors include GLFW_INVALID_VALUE.
+
Pointer lifetime
The specified allocator is copied before this function returns.
+
Thread safety
This function must only be called from the main thread.
+
See also
Custom heap memory allocator
+
+glfwInit
+
Since
Added in version 3.4.
+ +
+
+ +

◆ glfwInitVulkanLoader()

+ +
+
+ + + + + + + + +
void glfwInitVulkanLoader (PFN_vkGetInstanceProcAddr loader)
+
+

This function sets the vkGetInstanceProcAddr function that GLFW will use for all Vulkan related entry point queries.

+

This feature is mostly useful on macOS, if your copy of the Vulkan loader is in a location where GLFW cannot find it through dynamic loading, or if you are still using the static library version of the loader.

+

If set to NULL, GLFW will try to load the Vulkan loader dynamically by its standard name and get this function from there. This is the default behavior.

+

The standard name of the loader is vulkan-1.dll on Windows, libvulkan.so.1 on Linux and other Unix-like systems and libvulkan.1.dylib on macOS. If your code is also loading it via these names then you probably don't need to use this function.

+

The function address you set is never reset by GLFW, but it only takes effect during initialization. Once GLFW has been initialized, any updates will be ignored until the library is terminated and initialized again.

+
Parameters
+ + +
[in]loaderThe address of the function to use, or NULL.
+
+
+
Loader function signature
PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance instance, const char* name)
+
For more information about this function, see the Vulkan Registry.
+
Errors
None.
+
Remarks
This function may be called before glfwInit.
+
Thread safety
This function must only be called from the main thread.
+
See also
Finding the Vulkan loader
+
+glfwInit
+
Since
Added in version 3.4.
+ +
+
+ +

◆ glfwGetVersion()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void glfwGetVersion (int * major,
int * minor,
int * rev 
)
+
+

This function retrieves the major, minor and revision numbers of the GLFW library. It is intended for when you are using GLFW as a shared library and want to ensure that you are using the minimum required version.

+

Any or all of the version arguments may be NULL.

+
Parameters
+ + + + +
[out]majorWhere to store the major version number, or NULL.
[out]minorWhere to store the minor version number, or NULL.
[out]revWhere to store the revision number, or NULL.
+
+
+
Errors
None.
+
Remarks
This function may be called before glfwInit.
+
Thread safety
This function may be called from any thread.
+
See also
Version management
+
+glfwGetVersionString
+
Since
Added in version 1.0.
+ +
+
+ +

◆ glfwGetVersionString()

+ +
+
+ + + + + + + + +
const char * glfwGetVersionString (void )
+
+

This function returns the compile-time generated version string of the GLFW library binary. It describes the version, platforms, compiler and any platform or operating system specific compile-time options. It should not be confused with the OpenGL or OpenGL ES version string, queried with glGetString.

+

Do not use the version string to parse the GLFW library version. The glfwGetVersion function provides the version of the running library binary in numerical format.

+

Do not use the version string to parse what platforms are supported. The glfwPlatformSupported function lets you query platform support.

+
Returns
The ASCII encoded GLFW version string.
+
Errors
None.
+
Remarks
This function may be called before glfwInit.
+
Pointer lifetime
The returned string is static and compile-time generated.
+
Thread safety
This function may be called from any thread.
+
See also
Version management
+
+glfwGetVersion
+
Since
Added in version 3.0.
+ +
+
+ +

◆ glfwGetError()

+ +
+
+ + + + + + + + +
int glfwGetError (const char ** description)
+
+

This function returns and clears the error code of the last error that occurred on the calling thread, and optionally a UTF-8 encoded human-readable description of it. If no error has occurred since the last call, it returns GLFW_NO_ERROR (zero) and the description pointer is set to NULL.

+
Parameters
+ + +
[in]descriptionWhere to store the error description pointer, or NULL.
+
+
+
Returns
The last error code for the calling thread, or GLFW_NO_ERROR (zero).
+
Errors
None.
+
Pointer lifetime
The returned string is allocated and freed by GLFW. You should not free it yourself. It is guaranteed to be valid only until the next error occurs or the library is terminated.
+
Remarks
This function may be called before glfwInit.
+
Thread safety
This function may be called from any thread.
+
See also
Error handling
+
+glfwSetErrorCallback
+
Since
Added in version 3.3.
+ +
+
+ +

◆ glfwSetErrorCallback()

+ +
+
+ + + + + + + + +
GLFWerrorfun glfwSetErrorCallback (GLFWerrorfun callback)
+
+

This function sets the error callback, which is called with an error code and a human-readable description each time a GLFW error occurs.

+

The error code is set before the callback is called. Calling glfwGetError from the error callback will return the same value as the error code argument.

+

The error callback is called on the thread where the error occurred. If you are using GLFW from multiple threads, your error callback needs to be written accordingly.

+

Because the description string may have been generated specifically for that error, it is not guaranteed to be valid after the callback has returned. If you wish to use it after the callback returns, you need to make a copy.

+

Once set, the error callback remains set even after the library has been terminated.

+
Parameters
+ + +
[in]callbackThe new callback, or NULL to remove the currently set callback.
+
+
+
Returns
The previously set callback, or NULL if no callback was set.
+
Callback signature
void callback_name(int error_code, const char* description)
+
For more information about the callback parameters, see the callback pointer type.
+
Errors
None.
+
Remarks
This function may be called before glfwInit.
+
Thread safety
This function must only be called from the main thread.
+
See also
Error handling
+
+glfwGetError
+
Since
Added in version 3.0.
+ +
+
+ +

◆ glfwGetPlatform()

+ +
+
+ + + + + + + + +
int glfwGetPlatform (void )
+
+

This function returns the platform that was selected during initialization. The returned value will be one of GLFW_PLATFORM_WIN32, GLFW_PLATFORM_COCOA, GLFW_PLATFORM_WAYLAND, GLFW_PLATFORM_X11 or GLFW_PLATFORM_NULL.

+
Returns
The currently selected platform, or zero if an error occurred.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED.
+
Thread safety
This function may be called from any thread.
+
See also
Runtime platform selection
+
+glfwPlatformSupported
+
Since
Added in version 3.4.
+ +
+
+ +

◆ glfwPlatformSupported()

+ +
+
+ + + + + + + + +
int glfwPlatformSupported (int platform)
+
+

This function returns whether the library was compiled with support for the specified platform. The platform must be one of GLFW_PLATFORM_WIN32, GLFW_PLATFORM_COCOA, GLFW_PLATFORM_WAYLAND, GLFW_PLATFORM_X11 or GLFW_PLATFORM_NULL.

+
Parameters
+ + +
[in]platformThe platform to query.
+
+
+
Returns
GLFW_TRUE if the platform is supported, or GLFW_FALSE otherwise.
+
Errors
Possible errors include GLFW_INVALID_ENUM.
+
Remarks
This function may be called before glfwInit.
+
Thread safety
This function may be called from any thread.
+
See also
Runtime platform selection
+
+glfwGetPlatform
+
Since
Added in version 3.4.
+ +
+
+
+ + + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__input.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__input.html similarity index 64% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/group__input.html rename to src/lib/src/vendor/glfw-3.4/docs/html/group__input.html index 18cf6f2..14d44ba 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__input.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__input.html @@ -4,7 +4,7 @@ - + GLFW: Input reference @@ -28,10 +28,10 @@
- + @@ -55,211 +55,224 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
Input reference

Description

-

This is the reference documentation for input related functions and types. For more task-oriented information, see the Input guide.

+

This is the reference documentation for input related functions and types. For more task-oriented information, see the Input guide.

- + - + - + - + - - + + - + - + - +

Modules

 Gamepad axes
 Gamepad axes
 Gamepad axes.
 
 Gamepad buttons
 Gamepad buttons
 Gamepad buttons.
 
 Joystick hat states
 Joystick hat states
 Joystick hat states.
 
 Joysticks
 Joysticks
 Joystick IDs.
 
 Keyboard keys
 Keyboard key IDs.
 Keyboard key tokens
 Keyboard key tokens.
 
 Modifier key flags
 Modifier key flags
 Modifier key flags.
 
 Mouse buttons
 Mouse buttons
 Mouse button IDs.
 
 Standard cursor shapes
 Standard cursor shapes
 Standard system cursor shapes.
 
+ + + +

+Macros

#define GLFW_KEY_UNKNOWN   -1
 
- - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +

Typedefs

typedef struct GLFWcursor GLFWcursor
 Opaque cursor object. More...
typedef struct GLFWcursor GLFWcursor
 Opaque cursor object.
 
typedef void(* GLFWmousebuttonfun) (GLFWwindow *window, int button, int action, int mods)
 The function pointer type for mouse button callbacks. More...
typedef void(* GLFWmousebuttonfun) (GLFWwindow *window, int button, int action, int mods)
 The function pointer type for mouse button callbacks.
 
typedef void(* GLFWcursorposfun) (GLFWwindow *window, double xpos, double ypos)
 The function pointer type for cursor position callbacks. More...
typedef void(* GLFWcursorposfun) (GLFWwindow *window, double xpos, double ypos)
 The function pointer type for cursor position callbacks.
 
typedef void(* GLFWcursorenterfun) (GLFWwindow *window, int entered)
 The function pointer type for cursor enter/leave callbacks. More...
typedef void(* GLFWcursorenterfun) (GLFWwindow *window, int entered)
 The function pointer type for cursor enter/leave callbacks.
 
typedef void(* GLFWscrollfun) (GLFWwindow *window, double xoffset, double yoffset)
 The function pointer type for scroll callbacks. More...
typedef void(* GLFWscrollfun) (GLFWwindow *window, double xoffset, double yoffset)
 The function pointer type for scroll callbacks.
 
typedef void(* GLFWkeyfun) (GLFWwindow *window, int key, int scancode, int action, int mods)
 The function pointer type for keyboard key callbacks. More...
typedef void(* GLFWkeyfun) (GLFWwindow *window, int key, int scancode, int action, int mods)
 The function pointer type for keyboard key callbacks.
 
typedef void(* GLFWcharfun) (GLFWwindow *window, unsigned int codepoint)
 The function pointer type for Unicode character callbacks. More...
typedef void(* GLFWcharfun) (GLFWwindow *window, unsigned int codepoint)
 The function pointer type for Unicode character callbacks.
 
typedef void(* GLFWcharmodsfun) (GLFWwindow *window, unsigned int codepoint, int mods)
 The function pointer type for Unicode character with modifiers callbacks. More...
typedef void(* GLFWcharmodsfun) (GLFWwindow *window, unsigned int codepoint, int mods)
 The function pointer type for Unicode character with modifiers callbacks.
 
typedef void(* GLFWdropfun) (GLFWwindow *window, int path_count, const char *paths[])
 The function pointer type for path drop callbacks. More...
typedef void(* GLFWdropfun) (GLFWwindow *window, int path_count, const char *paths[])
 The function pointer type for path drop callbacks.
 
typedef void(* GLFWjoystickfun) (int jid, int event)
 The function pointer type for joystick configuration callbacks. More...
typedef void(* GLFWjoystickfun) (int jid, int event)
 The function pointer type for joystick configuration callbacks.
 
typedef struct GLFWgamepadstate GLFWgamepadstate
 Gamepad input state. More...
typedef struct GLFWgamepadstate GLFWgamepadstate
 Gamepad input state.
 
- - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +

Functions

int glfwGetInputMode (GLFWwindow *window, int mode)
 Returns the value of an input option for the specified window. More...
int glfwGetInputMode (GLFWwindow *window, int mode)
 Returns the value of an input option for the specified window.
 
void glfwSetInputMode (GLFWwindow *window, int mode, int value)
 Sets an input option for the specified window. More...
void glfwSetInputMode (GLFWwindow *window, int mode, int value)
 Sets an input option for the specified window.
 
int glfwRawMouseMotionSupported (void)
 Returns whether raw mouse motion is supported. More...
int glfwRawMouseMotionSupported (void)
 Returns whether raw mouse motion is supported.
 
const char * glfwGetKeyName (int key, int scancode)
 Returns the layout-specific name of the specified printable key. More...
const char * glfwGetKeyName (int key, int scancode)
 Returns the layout-specific name of the specified printable key.
 
int glfwGetKeyScancode (int key)
 Returns the platform-specific scancode of the specified key. More...
int glfwGetKeyScancode (int key)
 Returns the platform-specific scancode of the specified key.
 
int glfwGetKey (GLFWwindow *window, int key)
 Returns the last reported state of a keyboard key for the specified window. More...
int glfwGetKey (GLFWwindow *window, int key)
 Returns the last reported state of a keyboard key for the specified window.
 
int glfwGetMouseButton (GLFWwindow *window, int button)
 Returns the last reported state of a mouse button for the specified window. More...
int glfwGetMouseButton (GLFWwindow *window, int button)
 Returns the last reported state of a mouse button for the specified window.
 
void glfwGetCursorPos (GLFWwindow *window, double *xpos, double *ypos)
 Retrieves the position of the cursor relative to the content area of the window. More...
void glfwGetCursorPos (GLFWwindow *window, double *xpos, double *ypos)
 Retrieves the position of the cursor relative to the content area of the window.
 
void glfwSetCursorPos (GLFWwindow *window, double xpos, double ypos)
 Sets the position of the cursor, relative to the content area of the window. More...
void glfwSetCursorPos (GLFWwindow *window, double xpos, double ypos)
 Sets the position of the cursor, relative to the content area of the window.
 
GLFWcursorglfwCreateCursor (const GLFWimage *image, int xhot, int yhot)
 Creates a custom cursor. More...
GLFWcursorglfwCreateCursor (const GLFWimage *image, int xhot, int yhot)
 Creates a custom cursor.
 
GLFWcursorglfwCreateStandardCursor (int shape)
 Creates a cursor with a standard shape. More...
GLFWcursorglfwCreateStandardCursor (int shape)
 Creates a cursor with a standard shape.
 
void glfwDestroyCursor (GLFWcursor *cursor)
 Destroys a cursor. More...
void glfwDestroyCursor (GLFWcursor *cursor)
 Destroys a cursor.
 
void glfwSetCursor (GLFWwindow *window, GLFWcursor *cursor)
 Sets the cursor for the window. More...
void glfwSetCursor (GLFWwindow *window, GLFWcursor *cursor)
 Sets the cursor for the window.
 
GLFWkeyfun glfwSetKeyCallback (GLFWwindow *window, GLFWkeyfun callback)
 Sets the key callback. More...
GLFWkeyfun glfwSetKeyCallback (GLFWwindow *window, GLFWkeyfun callback)
 Sets the key callback.
 
GLFWcharfun glfwSetCharCallback (GLFWwindow *window, GLFWcharfun callback)
 Sets the Unicode character callback. More...
GLFWcharfun glfwSetCharCallback (GLFWwindow *window, GLFWcharfun callback)
 Sets the Unicode character callback.
 
GLFWcharmodsfun glfwSetCharModsCallback (GLFWwindow *window, GLFWcharmodsfun callback)
 Sets the Unicode character with modifiers callback. More...
GLFWcharmodsfun glfwSetCharModsCallback (GLFWwindow *window, GLFWcharmodsfun callback)
 Sets the Unicode character with modifiers callback.
 
GLFWmousebuttonfun glfwSetMouseButtonCallback (GLFWwindow *window, GLFWmousebuttonfun callback)
 Sets the mouse button callback. More...
GLFWmousebuttonfun glfwSetMouseButtonCallback (GLFWwindow *window, GLFWmousebuttonfun callback)
 Sets the mouse button callback.
 
GLFWcursorposfun glfwSetCursorPosCallback (GLFWwindow *window, GLFWcursorposfun callback)
 Sets the cursor position callback. More...
GLFWcursorposfun glfwSetCursorPosCallback (GLFWwindow *window, GLFWcursorposfun callback)
 Sets the cursor position callback.
 
GLFWcursorenterfun glfwSetCursorEnterCallback (GLFWwindow *window, GLFWcursorenterfun callback)
 Sets the cursor enter/leave callback. More...
GLFWcursorenterfun glfwSetCursorEnterCallback (GLFWwindow *window, GLFWcursorenterfun callback)
 Sets the cursor enter/leave callback.
 
GLFWscrollfun glfwSetScrollCallback (GLFWwindow *window, GLFWscrollfun callback)
 Sets the scroll callback. More...
GLFWscrollfun glfwSetScrollCallback (GLFWwindow *window, GLFWscrollfun callback)
 Sets the scroll callback.
 
GLFWdropfun glfwSetDropCallback (GLFWwindow *window, GLFWdropfun callback)
 Sets the path drop callback. More...
GLFWdropfun glfwSetDropCallback (GLFWwindow *window, GLFWdropfun callback)
 Sets the path drop callback.
 
int glfwJoystickPresent (int jid)
 Returns whether the specified joystick is present. More...
int glfwJoystickPresent (int jid)
 Returns whether the specified joystick is present.
 
const float * glfwGetJoystickAxes (int jid, int *count)
 Returns the values of all axes of the specified joystick. More...
const float * glfwGetJoystickAxes (int jid, int *count)
 Returns the values of all axes of the specified joystick.
 
const unsigned char * glfwGetJoystickButtons (int jid, int *count)
 Returns the state of all buttons of the specified joystick. More...
const unsigned char * glfwGetJoystickButtons (int jid, int *count)
 Returns the state of all buttons of the specified joystick.
 
const unsigned char * glfwGetJoystickHats (int jid, int *count)
 Returns the state of all hats of the specified joystick. More...
const unsigned char * glfwGetJoystickHats (int jid, int *count)
 Returns the state of all hats of the specified joystick.
 
const char * glfwGetJoystickName (int jid)
 Returns the name of the specified joystick. More...
const char * glfwGetJoystickName (int jid)
 Returns the name of the specified joystick.
 
const char * glfwGetJoystickGUID (int jid)
 Returns the SDL compatible GUID of the specified joystick. More...
const char * glfwGetJoystickGUID (int jid)
 Returns the SDL compatible GUID of the specified joystick.
 
void glfwSetJoystickUserPointer (int jid, void *pointer)
 Sets the user pointer of the specified joystick. More...
void glfwSetJoystickUserPointer (int jid, void *pointer)
 Sets the user pointer of the specified joystick.
 
void * glfwGetJoystickUserPointer (int jid)
 Returns the user pointer of the specified joystick. More...
void * glfwGetJoystickUserPointer (int jid)
 Returns the user pointer of the specified joystick.
 
int glfwJoystickIsGamepad (int jid)
 Returns whether the specified joystick has a gamepad mapping. More...
int glfwJoystickIsGamepad (int jid)
 Returns whether the specified joystick has a gamepad mapping.
 
GLFWjoystickfun glfwSetJoystickCallback (GLFWjoystickfun callback)
 Sets the joystick configuration callback. More...
GLFWjoystickfun glfwSetJoystickCallback (GLFWjoystickfun callback)
 Sets the joystick configuration callback.
 
int glfwUpdateGamepadMappings (const char *string)
 Adds the specified SDL_GameControllerDB gamepad mappings. More...
int glfwUpdateGamepadMappings (const char *string)
 Adds the specified SDL_GameControllerDB gamepad mappings.
 
const char * glfwGetGamepadName (int jid)
 Returns the human-readable gamepad name for the specified joystick. More...
const char * glfwGetGamepadName (int jid)
 Returns the human-readable gamepad name for the specified joystick.
 
int glfwGetGamepadState (int jid, GLFWgamepadstate *state)
 Retrieves the state of the specified joystick remapped as a gamepad. More...
int glfwGetGamepadState (int jid, GLFWgamepadstate *state)
 Retrieves the state of the specified joystick remapped as a gamepad.
 
void glfwSetClipboardString (GLFWwindow *window, const char *string)
 Sets the clipboard to the specified string. More...
void glfwSetClipboardString (GLFWwindow *window, const char *string)
 Sets the clipboard to the specified string.
 
const char * glfwGetClipboardString (GLFWwindow *window)
 Returns the contents of the clipboard as a string. More...
const char * glfwGetClipboardString (GLFWwindow *window)
 Returns the contents of the clipboard as a string.
 
double glfwGetTime (void)
 Returns the GLFW time. More...
double glfwGetTime (void)
 Returns the GLFW time.
 
void glfwSetTime (double time)
 Sets the GLFW time. More...
void glfwSetTime (double time)
 Sets the GLFW time.
 
uint64_t glfwGetTimerValue (void)
 Returns the current value of the raw timer. More...
uint64_t glfwGetTimerValue (void)
 Returns the current value of the raw timer.
 
uint64_t glfwGetTimerFrequency (void)
 Returns the frequency, in Hz, of the raw timer. More...
uint64_t glfwGetTimerFrequency (void)
 Returns the frequency, in Hz, of the raw timer.
 

Macro Definition Documentation

-

◆ GLFW_RELEASE

+

◆ GLFW_RELEASE

@@ -269,12 +282,12 @@ Functions
-

The key or mouse button was released.

+

The key or mouse button was released.

-

◆ GLFW_PRESS

+

◆ GLFW_PRESS

@@ -284,12 +297,12 @@ Functions
-

The key or mouse button was pressed.

+

The key or mouse button was pressed.

-

◆ GLFW_REPEAT

+

◆ GLFW_REPEAT

@@ -299,13 +312,27 @@ Functions
-

The key was held down until it repeated.

+

The key was held down until it repeated.

+ +
+
+ +

◆ GLFW_KEY_UNKNOWN

+ +
+
+ + + + +
#define GLFW_KEY_UNKNOWN   -1
+

Typedef Documentation

-

◆ GLFWcursor

+

◆ GLFWcursor

@@ -315,14 +342,14 @@ Functions
-

Opaque cursor object.

+

Opaque cursor object.

See also
Cursor objects
Since
Added in version 3.1.
-

◆ GLFWmousebuttonfun

+

◆ GLFWmousebuttonfun

@@ -332,8 +359,8 @@ Functions
-

This is the function pointer type for mouse button callback functions. A mouse button callback function has the following signature:

void function_name(GLFWwindow* window, int button, int action, int mods)
-
struct GLFWwindow GLFWwindow
Opaque window object.
Definition: glfw3.h:1185
+

This is the function pointer type for mouse button callback functions. A mouse button callback function has the following signature:

void function_name(GLFWwindow* window, int button, int action, int mods)
+
struct GLFWwindow GLFWwindow
Opaque window object.
Definition glfw3.h:1403
Parameters
@@ -351,7 +378,7 @@ Functions -

◆ GLFWcursorposfun

+

◆ GLFWcursorposfun

@@ -361,7 +388,7 @@ Functions
[in]windowThe window that received the event.
-

This is the function pointer type for cursor position callbacks. A cursor position callback function has the following signature:

void function_name(GLFWwindow* window, double xpos, double ypos);
+

This is the function pointer type for cursor position callbacks. A cursor position callback function has the following signature:

void function_name(GLFWwindow* window, double xpos, double ypos);
Parameters
@@ -378,7 +405,7 @@ Functions -

◆ GLFWcursorenterfun

+

◆ GLFWcursorenterfun

@@ -388,7 +415,7 @@ Functions
[in]windowThe window that received the event.
-

This is the function pointer type for cursor enter/leave callbacks. A cursor enter/leave callback function has the following signature:

void function_name(GLFWwindow* window, int entered)
+

This is the function pointer type for cursor enter/leave callbacks. A cursor enter/leave callback function has the following signature:

void function_name(GLFWwindow* window, int entered)
Parameters
@@ -404,7 +431,7 @@ Functions -

◆ GLFWscrollfun

+

◆ GLFWscrollfun

@@ -414,7 +441,7 @@ Functions
[in]windowThe window that received the event.
-

This is the function pointer type for scroll callbacks. A scroll callback function has the following signature:

void function_name(GLFWwindow* window, double xoffset, double yoffset)
+

This is the function pointer type for scroll callbacks. A scroll callback function has the following signature:

void function_name(GLFWwindow* window, double xoffset, double yoffset)
Parameters
@@ -431,7 +458,7 @@ Functions -

◆ GLFWkeyfun

+

◆ GLFWkeyfun

@@ -441,12 +468,12 @@ Functions
[in]windowThe window that received the event.
-

This is the function pointer type for keyboard key callbacks. A keyboard key callback function has the following signature:

void function_name(GLFWwindow* window, int key, int scancode, int action, int mods)
+

This is the function pointer type for keyboard key callbacks. A keyboard key callback function has the following signature:

void function_name(GLFWwindow* window, int key, int scancode, int action, int mods)
Parameters
- +
[in]windowThe window that received the event.
[in]keyThe keyboard key that was pressed or released.
[in]scancodeThe system-specific scancode of the key.
[in]scancodeThe platform-specific scancode of the key.
[in]actionGLFW_PRESS, GLFW_RELEASE or GLFW_REPEAT. Future releases may add more actions.
[in]modsBit field describing which modifier keys were held down.
@@ -460,7 +487,7 @@ Functions
-

◆ GLFWcharfun

+

◆ GLFWcharfun

@@ -470,7 +497,7 @@ Functions
-

This is the function pointer type for Unicode character callbacks. A Unicode character callback function has the following signature:

void function_name(GLFWwindow* window, unsigned int codepoint)
+

This is the function pointer type for Unicode character callbacks. A Unicode character callback function has the following signature:

void function_name(GLFWwindow* window, unsigned int codepoint)
Parameters
@@ -486,7 +513,7 @@ Functions -

◆ GLFWcharmodsfun

+

◆ GLFWcharmodsfun

@@ -496,7 +523,7 @@ Functions
[in]windowThe window that received the event.
-

This is the function pointer type for Unicode character with modifiers callbacks. It is called for each input character, regardless of what modifier keys are held down. A Unicode character with modifiers callback function has the following signature:

void function_name(GLFWwindow* window, unsigned int codepoint, int mods)
+

This is the function pointer type for Unicode character with modifiers callbacks. It is called for each input character, regardless of what modifier keys are held down. A Unicode character with modifiers callback function has the following signature:

void function_name(GLFWwindow* window, unsigned int codepoint, int mods)
Parameters
@@ -514,7 +541,7 @@ Functions -

◆ GLFWdropfun

+

◆ GLFWdropfun

@@ -524,7 +551,7 @@ Functions
[in]windowThe window that received the event.
-

This is the function pointer type for path drop callbacks. A path drop callback function has the following signature:

void function_name(GLFWwindow* window, int path_count, const char* paths[])
+

This is the function pointer type for path drop callbacks. A path drop callback function has the following signature:

void function_name(GLFWwindow* window, int path_count, const char* paths[])
Parameters
@@ -542,7 +569,7 @@ Functions -

◆ GLFWjoystickfun

+

◆ GLFWjoystickfun

@@ -552,7 +579,7 @@ Functions
[in]windowThe window that received the event.
-

This is the function pointer type for joystick configuration callbacks. A joystick configuration callback function has the following signature:

void function_name(int jid, int event)
+

This is the function pointer type for joystick configuration callbacks. A joystick configuration callback function has the following signature:

void function_name(int jid, int event)
Parameters
@@ -568,17 +595,17 @@ Functions -

◆ GLFWgamepadstate

+

◆ GLFWgamepadstate

[in]jidThe joystick that was connected or disconnected.
- +
typedef struct GLFWgamepadstate GLFWgamepadstatetypedef struct GLFWgamepadstate GLFWgamepadstate
-

This describes the input state of a gamepad.

+

This describes the input state of a gamepad.

See also
Gamepad input
glfwGetGamepadState
@@ -588,7 +615,7 @@ Functions

Function Documentation

-

◆ glfwGetInputMode()

+

◆ glfwGetInputMode()

@@ -612,7 +639,7 @@ Functions
-

This function returns the value of an input option for the specified window. The mode must be one of GLFW_CURSOR, GLFW_STICKY_KEYS, GLFW_STICKY_MOUSE_BUTTONS, GLFW_LOCK_KEY_MODS or GLFW_RAW_MOUSE_MOTION.

+

This function returns the value of an input option for the specified window. The mode must be one of GLFW_CURSOR, GLFW_STICKY_KEYS, GLFW_STICKY_MOUSE_BUTTONS, GLFW_LOCK_KEY_MODS or GLFW_RAW_MOUSE_MOTION.

Parameters
@@ -628,7 +655,7 @@ Functions -

◆ glfwSetInputMode()

+

◆ glfwSetInputMode()

@@ -658,16 +685,17 @@ Functions
[in]windowThe window to query.
-

This function sets an input mode option for the specified window. The mode must be one of GLFW_CURSOR, GLFW_STICKY_KEYS, GLFW_STICKY_MOUSE_BUTTONS, GLFW_LOCK_KEY_MODS or GLFW_RAW_MOUSE_MOTION.

-

If the mode is GLFW_CURSOR, the value must be one of the following cursor modes:

    +

    This function sets an input mode option for the specified window. The mode must be one of GLFW_CURSOR, GLFW_STICKY_KEYS, GLFW_STICKY_MOUSE_BUTTONS, GLFW_LOCK_KEY_MODS or GLFW_RAW_MOUSE_MOTION.

    +

    If the mode is GLFW_CURSOR, the value must be one of the following cursor modes:

    • GLFW_CURSOR_NORMAL makes the cursor visible and behaving normally.
    • GLFW_CURSOR_HIDDEN makes the cursor invisible when it is over the content area of the window but does not restrict the cursor from leaving.
    • GLFW_CURSOR_DISABLED hides and grabs the cursor, providing virtual and unlimited cursor movement. This is useful for implementing for example 3D camera controls.
    • +
    • GLFW_CURSOR_CAPTURED makes the cursor visible and confines it to the content area of the window.
    -

    If the mode is GLFW_STICKY_KEYS, the value must be either GLFW_TRUE to enable sticky keys, or GLFW_FALSE to disable it. If sticky keys are enabled, a key press will ensure that glfwGetKey returns GLFW_PRESS the next time it is called even if the key had been released before the call. This is useful when you are only interested in whether keys have been pressed but not when or in which order.

    -

    If the mode is GLFW_STICKY_MOUSE_BUTTONS, the value must be either GLFW_TRUE to enable sticky mouse buttons, or GLFW_FALSE to disable it. If sticky mouse buttons are enabled, a mouse button press will ensure that glfwGetMouseButton returns GLFW_PRESS the next time it is called even if the mouse button had been released before the call. This is useful when you are only interested in whether mouse buttons have been pressed but not when or in which order.

    -

    If the mode is GLFW_LOCK_KEY_MODS, the value must be either GLFW_TRUE to enable lock key modifier bits, or GLFW_FALSE to disable them. If enabled, callbacks that receive modifier bits will also have the GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on, and the GLFW_MOD_NUM_LOCK bit when Num Lock was on.

    -

    If the mode is GLFW_RAW_MOUSE_MOTION, the value must be either GLFW_TRUE to enable raw (unscaled and unaccelerated) mouse motion when the cursor is disabled, or GLFW_FALSE to disable it. If raw motion is not supported, attempting to set this will emit GLFW_PLATFORM_ERROR. Call glfwRawMouseMotionSupported to check for support.

    +

    If the mode is GLFW_STICKY_KEYS, the value must be either GLFW_TRUE to enable sticky keys, or GLFW_FALSE to disable it. If sticky keys are enabled, a key press will ensure that glfwGetKey returns GLFW_PRESS the next time it is called even if the key had been released before the call. This is useful when you are only interested in whether keys have been pressed but not when or in which order.

    +

    If the mode is GLFW_STICKY_MOUSE_BUTTONS, the value must be either GLFW_TRUE to enable sticky mouse buttons, or GLFW_FALSE to disable it. If sticky mouse buttons are enabled, a mouse button press will ensure that glfwGetMouseButton returns GLFW_PRESS the next time it is called even if the mouse button had been released before the call. This is useful when you are only interested in whether mouse buttons have been pressed but not when or in which order.

    +

    If the mode is GLFW_LOCK_KEY_MODS, the value must be either GLFW_TRUE to enable lock key modifier bits, or GLFW_FALSE to disable them. If enabled, callbacks that receive modifier bits will also have the GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on, and the GLFW_MOD_NUM_LOCK bit when Num Lock was on.

    +

    If the mode is GLFW_RAW_MOUSE_MOTION, the value must be either GLFW_TRUE to enable raw (unscaled and unaccelerated) mouse motion when the cursor is disabled, or GLFW_FALSE to disable it. If raw motion is not supported, attempting to set this will emit GLFW_FEATURE_UNAVAILABLE. Call glfwRawMouseMotionSupported to check for support.

    Parameters
    @@ -676,7 +704,7 @@ Functions
    [in]windowThe window whose input mode to set.
    -
    Errors
    Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_ENUM and GLFW_PLATFORM_ERROR.
    +
    Errors
    Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_ENUM, GLFW_PLATFORM_ERROR and GLFW_FEATURE_UNAVAILABLE (see above).
    Thread safety
    This function must only be called from the main thread.
    See also
    glfwGetInputMode
    Since
    Added in version 3.0. Replaces glfwEnable and glfwDisable.
    @@ -684,7 +712,7 @@ Functions
-

◆ glfwRawMouseMotionSupported()

+

◆ glfwRawMouseMotionSupported()

@@ -698,8 +726,8 @@ Functions
-

This function returns whether raw mouse motion is supported on the current system. This status does not change after GLFW has been initialized so you only need to check this once. If you attempt to enable raw motion on a system that does not support it, GLFW_PLATFORM_ERROR will be emitted.

-

Raw mouse motion is closer to the actual motion of the mouse across a surface. It is not affected by the scaling and acceleration applied to the motion of the desktop cursor. That processing is suitable for a cursor while raw motion is better for controlling for example a 3D camera. Because of this, raw mouse motion is only provided when the cursor is disabled.

+

This function returns whether raw mouse motion is supported on the current system. This status does not change after GLFW has been initialized so you only need to check this once. If you attempt to enable raw motion on a system that does not support it, GLFW_PLATFORM_ERROR will be emitted.

+

Raw mouse motion is closer to the actual motion of the mouse across a surface. It is not affected by the scaling and acceleration applied to the motion of the desktop cursor. That processing is suitable for a cursor while raw motion is better for controlling for example a 3D camera. Because of this, raw mouse motion is only provided when the cursor is disabled.

Returns
GLFW_TRUE if raw mouse motion is supported on the current machine, or GLFW_FALSE otherwise.
Errors
Possible errors include GLFW_NOT_INITIALIZED.
Thread safety
This function must only be called from the main thread.
@@ -711,7 +739,7 @@ Functions
-

◆ glfwGetKeyName()

+

◆ glfwGetKeyName()

@@ -735,11 +763,11 @@ Functions
-

This function returns the name of the specified printable key, encoded as UTF-8. This is typically the character that key would produce without any modifier keys, intended for displaying key bindings to the user. For dead keys, it is typically the diacritic it would add to a character.

-

Do not use this function for text input. You will break text input for many languages even if it happens to work for yours.

-

If the key is GLFW_KEY_UNKNOWN, the scancode is used to identify the key, otherwise the scancode is ignored. If you specify a non-printable key, or GLFW_KEY_UNKNOWN and a scancode that maps to a non-printable key, this function returns NULL but does not emit an error.

-

This behavior allows you to always pass in the arguments in the key callback without modification.

-

The printable keys are:

    +

    This function returns the name of the specified printable key, encoded as UTF-8. This is typically the character that key would produce without any modifier keys, intended for displaying key bindings to the user. For dead keys, it is typically the diacritic it would add to a character.

    +

    Do not use this function for text input. You will break text input for many languages even if it happens to work for yours.

    +

    If the key is GLFW_KEY_UNKNOWN, the scancode is used to identify the key, otherwise the scancode is ignored. If you specify a non-printable key, or GLFW_KEY_UNKNOWN and a scancode that maps to a non-printable key, this function returns NULL but does not emit an error.

    +

    This behavior allows you to always pass in the arguments in the key callback without modification.

    +

    The printable keys are:

    • GLFW_KEY_APOSTROPHE
    • GLFW_KEY_COMMA
    • GLFW_KEY_MINUS
    • @@ -762,7 +790,7 @@ Functions
    • GLFW_KEY_KP_ADD
    • GLFW_KEY_KP_EQUAL
    -

    Names for printable keys depend on keyboard layout, while names for non-printable keys are the same across layouts but depend on the application language and should be localized along with other user interface text.

    +

    Names for printable keys depend on keyboard layout, while names for non-printable keys are the same across layouts but depend on the application language and should be localized along with other user interface text.

    Parameters
    @@ -771,7 +799,7 @@ Functions
    Returns
    The UTF-8 encoded, layout-specific name of the key, or NULL.
    -
    Errors
    Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
    +
    Errors
    Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_VALUE, GLFW_INVALID_ENUM and GLFW_PLATFORM_ERROR.
    Remarks
    The contents of the returned string may change when a keyboard layout change event is received.
    Pointer lifetime
    The returned string is allocated and freed by GLFW. You should not free it yourself. It is valid until the library is terminated.
    Thread safety
    This function must only be called from the main thread.
    @@ -781,7 +809,7 @@ Functions -

    ◆ glfwGetKeyScancode()

    +

    ◆ glfwGetKeyScancode()

    @@ -795,16 +823,16 @@ Functions
    [in]keyThe key to query, or GLFW_KEY_UNKNOWN.
-

This function returns the platform-specific scancode of the specified key.

-

If the key is GLFW_KEY_UNKNOWN or does not exist on the keyboard this method will return -1.

+

This function returns the platform-specific scancode of the specified key.

+

If the specified key token corresponds to a physical key not supported on the current platform then this method will return -1. Calling this function with anything other than a key token will return -1 and generate a GLFW_INVALID_ENUM error.

Parameters
- +
[in]keyAny named key.
[in]keyAny key token.
-
Returns
The platform-specific scancode for the key, or -1 if an error occurred.
-
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_ENUM and GLFW_PLATFORM_ERROR.
+
Returns
The platform-specific scancode for the key, or -1 if the key is not supported on the current platform or an error occurred.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_INVALID_ENUM.
Thread safety
This function may be called from any thread.
See also
Key input
Since
Added in version 3.3.
@@ -812,7 +840,7 @@ Functions
-

◆ glfwGetKey()

+

◆ glfwGetKey()

@@ -836,11 +864,11 @@ Functions
-

This function returns the last state reported for the specified key to the specified window. The returned state is one of GLFW_PRESS or GLFW_RELEASE. The action GLFW_REPEAT is only reported to the key callback.

-

If the GLFW_STICKY_KEYS input mode is enabled, this function returns GLFW_PRESS the first time you call it for a key that was pressed, even if that key has already been released.

-

The key functions deal with physical keys, with key tokens named after their use on the standard US keyboard layout. If you want to input text, use the Unicode character callback instead.

-

The modifier key bit masks are not key tokens and cannot be used with this function.

-

Do not use this function to implement text input.

+

This function returns the last state reported for the specified key to the specified window. The returned state is one of GLFW_PRESS or GLFW_RELEASE. The action GLFW_REPEAT is only reported to the key callback.

+

If the GLFW_STICKY_KEYS input mode is enabled, this function returns GLFW_PRESS the first time you call it for a key that was pressed, even if that key has already been released.

+

The key functions deal with physical keys, with key tokens named after their use on the standard US keyboard layout. If you want to input text, use the Unicode character callback instead.

+

The modifier key bit masks are not key tokens and cannot be used with this function.

+

Do not use this function to implement text input.

Parameters
@@ -857,7 +885,7 @@ Functions -

◆ glfwGetMouseButton()

+

◆ glfwGetMouseButton()

@@ -881,8 +909,8 @@ Functions
[in]windowThe desired window.
-

This function returns the last state reported for the specified mouse button to the specified window. The returned state is one of GLFW_PRESS or GLFW_RELEASE.

-

If the GLFW_STICKY_MOUSE_BUTTONS input mode is enabled, this function returns GLFW_PRESS the first time you call it for a mouse button that was pressed, even if that mouse button has already been released.

+

This function returns the last state reported for the specified mouse button to the specified window. The returned state is one of GLFW_PRESS or GLFW_RELEASE.

+

If the GLFW_STICKY_MOUSE_BUTTONS input mode is enabled, this function returns GLFW_PRESS the first time you call it for a mouse button that was pressed, even if that mouse button has already been released.

Parameters
@@ -899,7 +927,7 @@ Functions -

◆ glfwGetCursorPos()

+

◆ glfwGetCursorPos()

@@ -929,10 +957,10 @@ Functions
[in]windowThe desired window.
-

This function returns the position of the cursor, in screen coordinates, relative to the upper-left corner of the content area of the specified window.

-

If the cursor is disabled (with GLFW_CURSOR_DISABLED) then the cursor position is unbounded and limited only by the minimum and maximum values of a double.

-

The coordinate can be converted to their integer equivalents with the floor function. Casting directly to an integer type works for positive coordinates, but fails for negative ones.

-

Any or all of the position arguments may be NULL. If an error occurs, all non-NULL position arguments will be set to zero.

+

This function returns the position of the cursor, in screen coordinates, relative to the upper-left corner of the content area of the specified window.

+

If the cursor is disabled (with GLFW_CURSOR_DISABLED) then the cursor position is unbounded and limited only by the minimum and maximum values of a double.

+

The coordinate can be converted to their integer equivalents with the floor function. Casting directly to an integer type works for positive coordinates, but fails for negative ones.

+

Any or all of the position arguments may be NULL. If an error occurs, all non-NULL position arguments will be set to zero.

Parameters
@@ -951,7 +979,7 @@ Functions -

◆ glfwSetCursorPos()

+

◆ glfwSetCursorPos()

@@ -981,9 +1009,9 @@ Functions
[in]windowThe desired window.
-

This function sets the position, in screen coordinates, of the cursor relative to the upper-left corner of the content area of the specified window. The window must have input focus. If the window does not have input focus when this function is called, it fails silently.

-

Do not use this function to implement things like camera controls. GLFW already provides the GLFW_CURSOR_DISABLED cursor mode that hides the cursor, transparently re-centers it and provides unconstrained cursor motion. See glfwSetInputMode for more information.

-

If the cursor mode is GLFW_CURSOR_DISABLED then the cursor position is unconstrained and limited only by the minimum and maximum values of a double.

+

This function sets the position, in screen coordinates, of the cursor relative to the upper-left corner of the content area of the specified window. The window must have input focus. If the window does not have input focus when this function is called, it fails silently.

+

Do not use this function to implement things like camera controls. GLFW already provides the GLFW_CURSOR_DISABLED cursor mode that hides the cursor, transparently re-centers it and provides unconstrained cursor motion. See glfwSetInputMode for more information.

+

If the cursor mode is GLFW_CURSOR_DISABLED then the cursor position is unconstrained and limited only by the minimum and maximum values of a double.

Parameters
@@ -992,8 +1020,8 @@ Functions
[in]windowThe desired window.
-
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
-
Remarks
Wayland: This function will only work when the cursor mode is GLFW_CURSOR_DISABLED, otherwise it will do nothing.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_PLATFORM_ERROR and GLFW_FEATURE_UNAVAILABLE (see remarks).
+
Remarks
Wayland: This function will only work when the cursor mode is GLFW_CURSOR_DISABLED, otherwise it will emit GLFW_FEATURE_UNAVAILABLE.
Thread safety
This function must only be called from the main thread.
See also
Cursor position
@@ -1003,7 +1031,7 @@ Functions
-

◆ glfwCreateCursor()

+

◆ glfwCreateCursor()

@@ -1011,7 +1039,7 @@ Functions GLFWcursor * glfwCreateCursor ( - const GLFWimage *  + const GLFWimageimage, @@ -1033,9 +1061,9 @@ Functions
-

Creates a new custom cursor image that can be set for a window with glfwSetCursor. The cursor can be destroyed with glfwDestroyCursor. Any remaining cursors are destroyed by glfwTerminate.

-

The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits per channel with the red channel first. They are arranged canonically as packed sequential rows, starting from the top-left corner.

-

The cursor hotspot is specified in pixels, relative to the upper-left corner of the cursor image. Like all other coordinate systems in GLFW, the X-axis points to the right and the Y-axis points down.

+

Creates a new custom cursor image that can be set for a window with glfwSetCursor. The cursor can be destroyed with glfwDestroyCursor. Any remaining cursors are destroyed by glfwTerminate.

+

The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits per channel with the red channel first. They are arranged canonically as packed sequential rows, starting from the top-left corner.

+

The cursor hotspot is specified in pixels, relative to the upper-left corner of the cursor image. Like all other coordinate systems in GLFW, the X-axis points to the right and the Y-axis points down.

Parameters
@@ -1058,7 +1086,7 @@ Functions -

◆ glfwCreateStandardCursor()

+

◆ glfwCreateStandardCursor()

@@ -1072,7 +1100,35 @@ Functions
[in]imageThe desired cursor image.
-

Returns a cursor with a standard shape, that can be set for a window with glfwSetCursor.

+

Returns a cursor with a standard shape, that can be set for a window with glfwSetCursor. The images for these cursors come from the system cursor theme and their exact appearance will vary between platforms.

+

Most of these shapes are guaranteed to exist on every supported platform but a few may not be present. See the table below for details.

+ + + + + + + + + + + + + + + + + + + + + + + +
Cursor shape Windows macOS X11 Wayland
GLFW_ARROW_CURSOR Yes Yes Yes Yes
GLFW_IBEAM_CURSOR Yes Yes Yes Yes
GLFW_CROSSHAIR_CURSOR Yes Yes Yes Yes
GLFW_POINTING_HAND_CURSOR Yes Yes Yes Yes
GLFW_RESIZE_EW_CURSOR Yes Yes Yes Yes
GLFW_RESIZE_NS_CURSOR Yes Yes Yes Yes
GLFW_RESIZE_NWSE_CURSOR Yes Yes1 Maybe2 Maybe2
GLFW_RESIZE_NESW_CURSOR Yes Yes1 Maybe2 Maybe2
GLFW_RESIZE_ALL_CURSOR Yes Yes Yes Yes
GLFW_NOT_ALLOWED_CURSOR Yes Yes Maybe2 Maybe2
+

1) This uses a private system API and may fail in the future.

+

2) This uses a newer standard that not all cursor themes support.

+

If the requested shape is not available, this function emits a GLFW_CURSOR_UNAVAILABLE error and returns NULL.

Parameters
@@ -1080,9 +1136,9 @@ Functions
Returns
A new cursor ready to use or NULL if an error occurred.
-
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_ENUM and GLFW_PLATFORM_ERROR.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_ENUM, GLFW_CURSOR_UNAVAILABLE and GLFW_PLATFORM_ERROR.
Thread safety
This function must only be called from the main thread.
-
See also
Cursor objects
+
See also
Standard cursor creation
glfwCreateCursor
Since
Added in version 3.1.
@@ -1090,7 +1146,7 @@ Functions -

◆ glfwDestroyCursor()

+

◆ glfwDestroyCursor()

@@ -1104,8 +1160,8 @@ Functions
[in]shapeOne of the standard shapes.
-

This function destroys a cursor previously created with glfwCreateCursor. Any remaining cursors will be destroyed by glfwTerminate.

-

If the specified cursor is current for any window, that window will be reverted to the default cursor. This does not affect the cursor mode.

+

This function destroys a cursor previously created with glfwCreateCursor. Any remaining cursors will be destroyed by glfwTerminate.

+

If the specified cursor is current for any window, that window will be reverted to the default cursor. This does not affect the cursor mode.

Parameters
@@ -1123,7 +1179,7 @@ Functions -

◆ glfwSetCursor()

+

◆ glfwSetCursor()

@@ -1147,8 +1203,8 @@ Functions
[in]cursorThe cursor object to destroy.
-

This function sets the cursor image to be used when the cursor is over the content area of the specified window. The set cursor will only be visible when the cursor mode of the window is GLFW_CURSOR_NORMAL.

-

On some platforms, the set cursor may not be visible unless the window also has input focus.

+

This function sets the cursor image to be used when the cursor is over the content area of the specified window. The set cursor will only be visible when the cursor mode of the window is GLFW_CURSOR_NORMAL.

+

On some platforms, the set cursor may not be visible unless the window also has input focus.

Parameters
@@ -1164,7 +1220,7 @@ Functions -

◆ glfwSetKeyCallback()

+

◆ glfwSetKeyCallback()

@@ -1188,11 +1244,11 @@ Functions
[in]windowThe window to set the cursor for.
-

This function sets the key callback of the specified window, which is called when a key is pressed, repeated or released.

-

The key functions deal with physical keys, with layout independent key tokens named after their values in the standard US keyboard layout. If you want to input text, use the character callback instead.

-

When a window loses input focus, it will generate synthetic key release events for all pressed keys. You can tell these events from user-generated events by the fact that the synthetic ones are generated after the focus loss event has been processed, i.e. after the window focus callback has been called.

-

The scancode of a key is specific to that platform or sometimes even to that machine. Scancodes are intended to allow users to bind keys that don't have a GLFW key token. Such keys have key set to GLFW_KEY_UNKNOWN, their state is not saved and so it cannot be queried with glfwGetKey.

-

Sometimes GLFW needs to generate synthetic key events, in which case the scancode may be zero.

+

This function sets the key callback of the specified window, which is called when a key is pressed, repeated or released.

+

The key functions deal with physical keys, with layout independent key tokens named after their values in the standard US keyboard layout. If you want to input text, use the character callback instead.

+

When a window loses input focus, it will generate synthetic key release events for all pressed keys with associated key tokens. You can tell these events from user-generated events by the fact that the synthetic ones are generated after the focus loss event has been processed, i.e. after the window focus callback has been called.

+

The scancode of a key is specific to that platform or sometimes even to that machine. Scancodes are intended to allow users to bind keys that don't have a GLFW key token. Such keys have key set to GLFW_KEY_UNKNOWN, their state is not saved and so it cannot be queried with glfwGetKey.

+

Sometimes GLFW needs to generate synthetic key events, in which case the scancode may be zero.

Parameters
@@ -1211,7 +1267,7 @@ Functions -

◆ glfwSetCharCallback()

+

◆ glfwSetCharCallback()

@@ -1235,9 +1291,9 @@ Functions
[in]windowThe window whose callback to set.
-

This function sets the character callback of the specified window, which is called when a Unicode character is input.

-

The character callback is intended for Unicode text input. As it deals with characters, it is keyboard layout dependent, whereas the key callback is not. Characters do not map 1:1 to physical keys, as a key may produce zero, one or more characters. If you want to know whether a specific physical key was pressed or released, see the key callback instead.

-

The character callback behaves as system text input normally does and will not be called if modifier keys are held down that would prevent normal text input on that platform, for example a Super (Command) key on macOS or Alt key on Windows.

+

This function sets the character callback of the specified window, which is called when a Unicode character is input.

+

The character callback is intended for Unicode text input. As it deals with characters, it is keyboard layout dependent, whereas the key callback is not. Characters do not map 1:1 to physical keys, as a key may produce zero, one or more characters. If you want to know whether a specific physical key was pressed or released, see the key callback instead.

+

The character callback behaves as system text input normally does and will not be called if modifier keys are held down that would prevent normal text input on that platform, for example a Super (Command) key on macOS or Alt key on Windows.

Parameters
@@ -1256,7 +1312,7 @@ Functions -

◆ glfwSetCharModsCallback()

+

◆ glfwSetCharModsCallback()

@@ -1280,8 +1336,8 @@ Functions
[in]windowThe window whose callback to set.
-

This function sets the character with modifiers callback of the specified window, which is called when a Unicode character is input regardless of what modifier keys are used.

-

The character with modifiers callback is intended for implementing custom Unicode character input. For regular Unicode text input, see the character callback. Like the character callback, the character with modifiers callback deals with characters and is keyboard layout dependent. Characters do not map 1:1 to physical keys, as a key may produce zero, one or more characters. If you want to know whether a specific physical key was pressed or released, see the key callback instead.

+

This function sets the character with modifiers callback of the specified window, which is called when a Unicode character is input regardless of what modifier keys are used.

+

The character with modifiers callback is intended for implementing custom Unicode character input. For regular Unicode text input, see the character callback. Like the character callback, the character with modifiers callback deals with characters and is keyboard layout dependent. Characters do not map 1:1 to physical keys, as a key may produce zero, one or more characters. If you want to know whether a specific physical key was pressed or released, see the key callback instead.

Parameters
@@ -1301,7 +1357,7 @@ Functions -

◆ glfwSetMouseButtonCallback()

+

◆ glfwSetMouseButtonCallback()

@@ -1325,8 +1381,8 @@ Functions
[in]windowThe window whose callback to set.
-

This function sets the mouse button callback of the specified window, which is called when a mouse button is pressed or released.

-

When a window loses input focus, it will generate synthetic mouse button release events for all pressed mouse buttons. You can tell these events from user-generated events by the fact that the synthetic ones are generated after the focus loss event has been processed, i.e. after the window focus callback has been called.

+

This function sets the mouse button callback of the specified window, which is called when a mouse button is pressed or released.

+

When a window loses input focus, it will generate synthetic mouse button release events for all pressed mouse buttons. You can tell these events from user-generated events by the fact that the synthetic ones are generated after the focus loss event has been processed, i.e. after the window focus callback has been called.

Parameters
@@ -1345,7 +1401,7 @@ Functions -

◆ glfwSetCursorPosCallback()

+

◆ glfwSetCursorPosCallback()

@@ -1369,7 +1425,7 @@ Functions
[in]windowThe window whose callback to set.
-

This function sets the cursor position callback of the specified window, which is called when the cursor is moved. The callback is provided with the position, in screen coordinates, relative to the upper-left corner of the content area of the window.

+

This function sets the cursor position callback of the specified window, which is called when the cursor is moved. The callback is provided with the position, in screen coordinates, relative to the upper-left corner of the content area of the window.

Parameters
@@ -1388,7 +1444,7 @@ Functions -

◆ glfwSetCursorEnterCallback()

+

◆ glfwSetCursorEnterCallback()

@@ -1412,7 +1468,7 @@ Functions
[in]windowThe window whose callback to set.
-

This function sets the cursor boundary crossing callback of the specified window, which is called when the cursor enters or leaves the content area of the window.

+

This function sets the cursor boundary crossing callback of the specified window, which is called when the cursor enters or leaves the content area of the window.

Parameters
@@ -1431,7 +1487,7 @@ Functions -

◆ glfwSetScrollCallback()

+

◆ glfwSetScrollCallback()

@@ -1455,8 +1511,8 @@ Functions
[in]windowThe window whose callback to set.
-

This function sets the scroll callback of the specified window, which is called when a scrolling device is used, such as a mouse wheel or scrolling area of a touchpad.

-

The scroll callback receives all scrolling input, like that from a mouse wheel or a touchpad scrolling area.

+

This function sets the scroll callback of the specified window, which is called when a scrolling device is used, such as a mouse wheel or scrolling area of a touchpad.

+

The scroll callback receives all scrolling input, like that from a mouse wheel or a touchpad scrolling area.

Parameters
@@ -1475,7 +1531,7 @@ Functions -

◆ glfwSetDropCallback()

+

◆ glfwSetDropCallback()

@@ -1499,8 +1555,8 @@ Functions
[in]windowThe window whose callback to set.
-

This function sets the path drop callback of the specified window, which is called when one or more dragged paths are dropped on the window.

-

Because the path array and its strings may have been generated specifically for that event, they are not guaranteed to be valid after the callback has returned. If you wish to use them after the callback returns, you need to make a deep copy.

+

This function sets the path drop callback of the specified window, which is called when one or more dragged paths are dropped on the window.

+

Because the path array and its strings may have been generated specifically for that event, they are not guaranteed to be valid after the callback has returned. If you wish to use them after the callback returns, you need to make a deep copy.

Parameters
@@ -1512,7 +1568,6 @@ Functions
Callback signature
void function_name(GLFWwindow* window, int path_count, const char* paths[])
For more information about the callback parameters, see the function pointer type.
Errors
Possible errors include GLFW_NOT_INITIALIZED.
-
Remarks
Wayland: File drop is currently unimplemented.
Thread safety
This function must only be called from the main thread.
See also
Path drop input
Since
Added in version 3.1.
@@ -1520,7 +1575,7 @@ Functions -

◆ glfwJoystickPresent()

+

◆ glfwJoystickPresent()

@@ -1534,8 +1589,8 @@ Functions
[in]windowThe window whose callback to set.
-

This function returns whether the specified joystick is present.

-

There is no need to call this function before other functions that accept a joystick ID, as they all check for presence before performing any other work.

+

This function returns whether the specified joystick is present.

+

There is no need to call this function before other functions that accept a joystick ID, as they all check for presence before performing any other work.

Parameters
@@ -1551,7 +1606,7 @@ Functions -

◆ glfwGetJoystickAxes()

+

◆ glfwGetJoystickAxes()

@@ -1575,8 +1630,8 @@ Functions
[in]jidThe joystick to query.
-

This function returns the values of all axes of the specified joystick. Each element in the array is a value between -1.0 and 1.0.

-

If the specified joystick is not present this function will return NULL but will not generate an error. This can be used instead of first calling glfwJoystickPresent.

+

This function returns the values of all axes of the specified joystick. Each element in the array is a value between -1.0 and 1.0.

+

If the specified joystick is not present this function will return NULL but will not generate an error. This can be used instead of first calling glfwJoystickPresent.

Parameters
@@ -1594,7 +1649,7 @@ Functions -

◆ glfwGetJoystickButtons()

+

◆ glfwGetJoystickButtons()

@@ -1618,9 +1673,9 @@ Functions
[in]jidThe joystick to query.
-

This function returns the state of all buttons of the specified joystick. Each element in the array is either GLFW_PRESS or GLFW_RELEASE.

-

For backward compatibility with earlier versions that did not have glfwGetJoystickHats, the button array also includes all hats, each represented as four buttons. The hats are in the same order as returned by glfwGetJoystickHats and are in the order up, right, down and left. To disable these extra buttons, set the GLFW_JOYSTICK_HAT_BUTTONS init hint before initialization.

-

If the specified joystick is not present this function will return NULL but will not generate an error. This can be used instead of first calling glfwJoystickPresent.

+

This function returns the state of all buttons of the specified joystick. Each element in the array is either GLFW_PRESS or GLFW_RELEASE.

+

For backward compatibility with earlier versions that did not have glfwGetJoystickHats, the button array also includes all hats, each represented as four buttons. The hats are in the same order as returned by glfwGetJoystickHats and are in the order up, right, down and left. To disable these extra buttons, set the GLFW_JOYSTICK_HAT_BUTTONS init hint before initialization.

+

If the specified joystick is not present this function will return NULL but will not generate an error. This can be used instead of first calling glfwJoystickPresent.

Parameters
@@ -1638,7 +1693,7 @@ Functions -

◆ glfwGetJoystickHats()

+

◆ glfwGetJoystickHats()

@@ -1662,7 +1717,7 @@ Functions
[in]jidThe joystick to query.
-

This function returns the state of all hats of the specified joystick. Each element in the array is one of the following values:

+

This function returns the state of all hats of the specified joystick. Each element in the array is one of the following values:

@@ -1685,13 +1740,13 @@ Functions
Name Value
GLFW_HAT_LEFT_DOWN GLFW_HAT_LEFT | GLFW_HAT_DOWN
-

The diagonal directions are bitwise combinations of the primary (up, right, down and left) directions and you can test for these individually by ANDing it with the corresponding direction.

+

The diagonal directions are bitwise combinations of the primary (up, right, down and left) directions and you can test for these individually by ANDing it with the corresponding direction.

if (hats[2] & GLFW_HAT_RIGHT)
{
// State of hat 2 could be right-up, right or right-down
}
-
#define GLFW_HAT_RIGHT
Definition: glfw3.h:357
-

If the specified joystick is not present this function will return NULL but will not generate an error. This can be used instead of first calling glfwJoystickPresent.

+
#define GLFW_HAT_RIGHT
Definition glfw3.h:357
+

If the specified joystick is not present this function will return NULL but will not generate an error. This can be used instead of first calling glfwJoystickPresent.

Parameters
@@ -1709,7 +1764,7 @@ Functions -

◆ glfwGetJoystickName()

+

◆ glfwGetJoystickName()

@@ -1723,8 +1778,8 @@ Functions
[in]jidThe joystick to query.
-

This function returns the name, encoded as UTF-8, of the specified joystick. The returned string is allocated and freed by GLFW. You should not free it yourself.

-

If the specified joystick is not present this function will return NULL but will not generate an error. This can be used instead of first calling glfwJoystickPresent.

+

This function returns the name, encoded as UTF-8, of the specified joystick. The returned string is allocated and freed by GLFW. You should not free it yourself.

+

If the specified joystick is not present this function will return NULL but will not generate an error. This can be used instead of first calling glfwJoystickPresent.

Parameters
@@ -1741,7 +1796,7 @@ Functions -

◆ glfwGetJoystickGUID()

+

◆ glfwGetJoystickGUID()

@@ -1755,10 +1810,10 @@ Functions
[in]jidThe joystick to query.
-

This function returns the SDL compatible GUID, as a UTF-8 encoded hexadecimal string, of the specified joystick. The returned string is allocated and freed by GLFW. You should not free it yourself.

-

The GUID is what connects a joystick to a gamepad mapping. A connected joystick will always have a GUID even if there is no gamepad mapping assigned to it.

-

If the specified joystick is not present this function will return NULL but will not generate an error. This can be used instead of first calling glfwJoystickPresent.

-

The GUID uses the format introduced in SDL 2.0.5. This GUID tries to uniquely identify the make and model of a joystick but does not identify a specific unit, e.g. all wired Xbox 360 controllers will have the same GUID on that platform. The GUID for a unit may vary between platforms depending on what hardware information the platform specific APIs provide.

+

This function returns the SDL compatible GUID, as a UTF-8 encoded hexadecimal string, of the specified joystick. The returned string is allocated and freed by GLFW. You should not free it yourself.

+

The GUID is what connects a joystick to a gamepad mapping. A connected joystick will always have a GUID even if there is no gamepad mapping assigned to it.

+

If the specified joystick is not present this function will return NULL but will not generate an error. This can be used instead of first calling glfwJoystickPresent.

+

The GUID uses the format introduced in SDL 2.0.5. This GUID tries to uniquely identify the make and model of a joystick but does not identify a specific unit, e.g. all wired Xbox 360 controllers will have the same GUID on that platform. The GUID for a unit may vary between platforms depending on what hardware information the platform specific APIs provide.

Parameters
@@ -1775,7 +1830,7 @@ Functions -

◆ glfwSetJoystickUserPointer()

+

◆ glfwSetJoystickUserPointer()

@@ -1799,8 +1854,8 @@ Functions
[in]jidThe joystick to query.
-

This function sets the user-defined pointer of the specified joystick. The current value is retained until the joystick is disconnected. The initial value is NULL.

-

This function may be called from the joystick callback, even for a joystick that is being disconnected.

+

This function sets the user-defined pointer of the specified joystick. The current value is retained until the joystick is disconnected. The initial value is NULL.

+

This function may be called from the joystick callback, even for a joystick that is being disconnected.

Parameters
@@ -1818,7 +1873,7 @@ Functions -

◆ glfwGetJoystickUserPointer()

+

◆ glfwGetJoystickUserPointer()

@@ -1832,8 +1887,8 @@ Functions
[in]jidThe joystick whose pointer to set.
-

This function returns the current value of the user-defined pointer of the specified joystick. The initial value is NULL.

-

This function may be called from the joystick callback, even for a joystick that is being disconnected.

+

This function returns the current value of the user-defined pointer of the specified joystick. The initial value is NULL.

+

This function may be called from the joystick callback, even for a joystick that is being disconnected.

Parameters
@@ -1850,7 +1905,7 @@ Functions -

◆ glfwJoystickIsGamepad()

+

◆ glfwJoystickIsGamepad()

@@ -1864,8 +1919,8 @@ Functions
[in]jidThe joystick whose pointer to return.
-

This function returns whether the specified joystick is both present and has a gamepad mapping.

-

If the specified joystick is present but does not have a gamepad mapping this function will return GLFW_FALSE but will not generate an error. Call glfwJoystickPresent to check if a joystick is present regardless of whether it has a mapping.

+

This function returns whether the specified joystick is both present and has a gamepad mapping.

+

If the specified joystick is present but does not have a gamepad mapping this function will return GLFW_FALSE but will not generate an error. Call glfwJoystickPresent to check if a joystick is present regardless of whether it has a mapping.

Parameters
@@ -1883,7 +1938,7 @@ Functions -

◆ glfwSetJoystickCallback()

+

◆ glfwSetJoystickCallback()

@@ -1897,8 +1952,8 @@ Functions
[in]jidThe joystick to query.
-

This function sets the joystick configuration callback, or removes the currently set callback. This is called when a joystick is connected to or disconnected from the system.

-

For joystick connection and disconnection events to be delivered on all platforms, you need to call one of the event processing functions. Joystick disconnection may also be detected and the callback called by joystick functions. The function will then return whatever it returns if the joystick is not present.

+

This function sets the joystick configuration callback, or removes the currently set callback. This is called when a joystick is connected to or disconnected from the system.

+

For joystick connection and disconnection events to be delivered on all platforms, you need to call one of the event processing functions. Joystick disconnection may also be detected and the callback called by joystick functions. The function will then return whatever it returns if the joystick is not present.

Parameters
@@ -1916,7 +1971,7 @@ Functions -

◆ glfwUpdateGamepadMappings()

+

◆ glfwUpdateGamepadMappings()

@@ -1930,9 +1985,9 @@ Functions
[in]callbackThe new callback, or NULL to remove the currently set callback.
-

This function parses the specified ASCII encoded string and updates the internal list with any gamepad mappings it finds. This string may contain either a single gamepad mapping or many mappings separated by newlines. The parser supports the full format of the gamecontrollerdb.txt source file including empty lines and comments.

-

See Gamepad mappings for a description of the format.

-

If there is already a gamepad mapping for a given GUID in the internal list, it will be replaced by the one passed to this function. If the library is terminated and re-initialized the internal list will revert to the built-in default.

+

This function parses the specified ASCII encoded string and updates the internal list with any gamepad mappings it finds. This string may contain either a single gamepad mapping or many mappings separated by newlines. The parser supports the full format of the gamecontrollerdb.txt source file including empty lines and comments.

+

See Gamepad mappings for a description of the format.

+

If there is already a gamepad mapping for a given GUID in the internal list, it will be replaced by the one passed to this function. If the library is terminated and re-initialized the internal list will revert to the built-in default.

Parameters
@@ -1952,7 +2007,7 @@ Functions -

◆ glfwGetGamepadName()

+

◆ glfwGetGamepadName()

@@ -1966,8 +2021,8 @@ Functions
[in]stringThe string containing the gamepad mappings.
-

This function returns the human-readable name of the gamepad from the gamepad mapping assigned to the specified joystick.

-

If the specified joystick is not present or does not have a gamepad mapping this function will return NULL but will not generate an error. Call glfwJoystickPresent to check whether it is present regardless of whether it has a mapping.

+

This function returns the human-readable name of the gamepad from the gamepad mapping assigned to the specified joystick.

+

If the specified joystick is not present or does not have a gamepad mapping this function will return NULL but will not generate an error. Call glfwJoystickPresent to check whether it is present regardless of whether it has a mapping.

Parameters
@@ -1986,7 +2041,7 @@ Functions -

◆ glfwGetGamepadState()

+

◆ glfwGetGamepadState()

@@ -2000,7 +2055,7 @@ Functions
- + @@ -2010,10 +2065,10 @@ Functions
[in]jidThe joystick to query.
GLFWgamepadstateGLFWgamepadstate state 
-

This function retrieves the state of the specified joystick remapped to an Xbox-like gamepad.

-

If the specified joystick is not present or does not have a gamepad mapping this function will return GLFW_FALSE but will not generate an error. Call glfwJoystickPresent to check whether it is present regardless of whether it has a mapping.

-

The Guide button may not be available for input as it is often hooked by the system or the Steam client.

-

Not all devices have all the buttons or axes provided by GLFWgamepadstate. Unavailable buttons and axes will always report GLFW_RELEASE and 0.0 respectively.

+

This function retrieves the state of the specified joystick remapped to an Xbox-like gamepad.

+

If the specified joystick is not present or does not have a gamepad mapping this function will return GLFW_FALSE but will not generate an error. Call glfwJoystickPresent to check whether it is present regardless of whether it has a mapping.

+

The Guide button may not be available for input as it is often hooked by the system or the Steam client.

+

Not all devices have all the buttons or axes provided by GLFWgamepadstate. Unavailable buttons and axes will always report GLFW_RELEASE and 0.0 respectively.

Parameters
@@ -2034,7 +2089,7 @@ Functions -

◆ glfwSetClipboardString()

+

◆ glfwSetClipboardString()

@@ -2058,7 +2113,7 @@ Functions
[in]jidThe joystick to query.
-

This function sets the system clipboard to the specified, UTF-8 encoded string.

+

This function sets the system clipboard to the specified, UTF-8 encoded string.

Parameters
@@ -2067,6 +2122,7 @@ Functions
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
+
Remarks
Windows: The clipboard on Windows has a single global lock for reading and writing. GLFW tries to acquire it a few times, which is almost always enough. If it cannot acquire the lock then this function emits GLFW_PLATFORM_ERROR and returns. It is safe to try this multiple times.
Pointer lifetime
The specified string is copied before this function returns.
Thread safety
This function must only be called from the main thread.
See also
Clipboard input and output
@@ -2077,7 +2133,7 @@ Functions -

◆ glfwGetClipboardString()

+

◆ glfwGetClipboardString()

@@ -2091,7 +2147,7 @@ Functions
[in]windowDeprecated. Any valid window or NULL.
-

This function returns the contents of the system clipboard, if it contains or is convertible to a UTF-8 encoded string. If the clipboard is empty or if its contents cannot be converted, NULL is returned and a GLFW_FORMAT_UNAVAILABLE error is generated.

+

This function returns the contents of the system clipboard, if it contains or is convertible to a UTF-8 encoded string. If the clipboard is empty or if its contents cannot be converted, NULL is returned and a GLFW_FORMAT_UNAVAILABLE error is generated.

Parameters
@@ -2100,6 +2156,7 @@ Functions
Returns
The contents of the clipboard as a UTF-8 encoded string, or NULL if an error occurred.
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_FORMAT_UNAVAILABLE and GLFW_PLATFORM_ERROR.
+
Remarks
Windows: The clipboard on Windows has a single global lock for reading and writing. GLFW tries to acquire it a few times, which is almost always enough. If it cannot acquire the lock then this function emits GLFW_PLATFORM_ERROR and returns. It is safe to try this multiple times.
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 glfwGetClipboardString or glfwSetClipboardString, or until the library is terminated.
Thread safety
This function must only be called from the main thread.
See also
Clipboard input and output
@@ -2110,7 +2167,7 @@ Functions -

◆ glfwGetTime()

+

◆ glfwGetTime()

@@ -2124,9 +2181,9 @@ Functions
[in]windowDeprecated. Any valid window or NULL.
-

This function returns the current GLFW time, in seconds. Unless the time has been set using glfwSetTime it measures time elapsed since GLFW was initialized.

-

This function and glfwSetTime are helper functions on top of glfwGetTimerFrequency and glfwGetTimerValue.

-

The resolution of the timer is system dependent, but is usually on the order of a few micro- or nanoseconds. It uses the highest-resolution monotonic time source on each supported platform.

+

This function returns the current GLFW time, in seconds. Unless the time has been set using glfwSetTime it measures time elapsed since GLFW was initialized.

+

This function and glfwSetTime are helper functions on top of glfwGetTimerFrequency and glfwGetTimerValue.

+

The resolution of the timer is system dependent, but is usually on the order of a few micro- or nanoseconds. It uses the highest-resolution monotonic time source on each operating system.

Returns
The current time, in seconds, or zero if an error occurred.
Errors
Possible errors include GLFW_NOT_INITIALIZED.
Thread safety
This function may be called from any thread. Reading and writing of the internal base time is not atomic, so it needs to be externally synchronized with calls to glfwSetTime.
@@ -2136,7 +2193,7 @@ Functions
-

◆ glfwSetTime()

+

◆ glfwSetTime()

@@ -2150,8 +2207,8 @@ Functions
-

This function sets the current GLFW time, in seconds. The value must be a positive finite number less than or equal to 18446744073.0, which is approximately 584.5 years.

-

This function and glfwGetTime are helper functions on top of glfwGetTimerFrequency and glfwGetTimerValue.

+

This function sets the current GLFW time, in seconds. The value must be a positive finite number less than or equal to 18446744073.0, which is approximately 584.5 years.

+

This function and glfwGetTime are helper functions on top of glfwGetTimerFrequency and glfwGetTimerValue.

Parameters
@@ -2167,7 +2224,7 @@ Functions -

◆ glfwGetTimerValue()

+

◆ glfwGetTimerValue()

@@ -2181,7 +2238,7 @@ Functions
[in]timeThe new value, in seconds.
-

This function returns the current value of the raw timer, measured in 1 / frequency seconds. To get the frequency, call glfwGetTimerFrequency.

+

This function returns the current value of the raw timer, measured in 1 / frequency seconds. To get the frequency, call glfwGetTimerFrequency.

Returns
The value of the timer, or zero if an error occurred.
Errors
Possible errors include GLFW_NOT_INITIALIZED.
Thread safety
This function may be called from any thread.
@@ -2193,7 +2250,7 @@ Functions
-

◆ glfwGetTimerFrequency()

+

◆ glfwGetTimerFrequency()

@@ -2207,7 +2264,7 @@ Functions
-

This function returns the frequency, in Hz, of the raw timer.

+

This function returns the frequency, in Hz, of the raw timer.

Returns
The frequency of the timer, in Hz, or zero if an error occurred.
Errors
Possible errors include GLFW_NOT_INITIALIZED.
Thread safety
This function may be called from any thread.
@@ -2221,7 +2278,7 @@ Functions
diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__joysticks.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__joysticks.html similarity index 61% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/group__joysticks.html rename to src/lib/src/vendor/glfw-3.4/docs/html/group__joysticks.html index 34f86b2..31c77ce 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__joysticks.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__joysticks.html @@ -4,7 +4,7 @@ - + GLFW: Joysticks @@ -28,10 +28,10 @@
- + @@ -55,9 +55,16 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -67,48 +74,48 @@ $(function() {

Description

-

See joystick input for how these are used.

+

See joystick input for how these are used.

- + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +

Macros

#define GLFW_JOYSTICK_1   0
#define GLFW_JOYSTICK_1   0
 
#define GLFW_JOYSTICK_2   1
#define GLFW_JOYSTICK_2   1
 
#define GLFW_JOYSTICK_3   2
#define GLFW_JOYSTICK_3   2
 
#define GLFW_JOYSTICK_4   3
#define GLFW_JOYSTICK_4   3
 
#define GLFW_JOYSTICK_5   4
#define GLFW_JOYSTICK_5   4
 
#define GLFW_JOYSTICK_6   5
#define GLFW_JOYSTICK_6   5
 
#define GLFW_JOYSTICK_7   6
#define GLFW_JOYSTICK_7   6
 
#define GLFW_JOYSTICK_8   7
#define GLFW_JOYSTICK_8   7
 
#define GLFW_JOYSTICK_9   8
#define GLFW_JOYSTICK_9   8
 
#define GLFW_JOYSTICK_10   9
#define GLFW_JOYSTICK_10   9
 
#define GLFW_JOYSTICK_11   10
#define GLFW_JOYSTICK_11   10
 
#define GLFW_JOYSTICK_12   11
#define GLFW_JOYSTICK_12   11
 
#define GLFW_JOYSTICK_13   12
#define GLFW_JOYSTICK_13   12
 
#define GLFW_JOYSTICK_14   13
#define GLFW_JOYSTICK_14   13
 
#define GLFW_JOYSTICK_15   14
#define GLFW_JOYSTICK_15   14
 
#define GLFW_JOYSTICK_16   15
#define GLFW_JOYSTICK_16   15
 
#define GLFW_JOYSTICK_LAST   GLFW_JOYSTICK_16
#define GLFW_JOYSTICK_LAST   GLFW_JOYSTICK_16
 

Macro Definition Documentation

-

◆ GLFW_JOYSTICK_1

+

◆ GLFW_JOYSTICK_1

@@ -122,7 +129,7 @@ Macros
-

◆ GLFW_JOYSTICK_2

+

◆ GLFW_JOYSTICK_2

@@ -136,7 +143,7 @@ Macros
-

◆ GLFW_JOYSTICK_3

+

◆ GLFW_JOYSTICK_3

@@ -150,7 +157,7 @@ Macros
-

◆ GLFW_JOYSTICK_4

+

◆ GLFW_JOYSTICK_4

@@ -164,7 +171,7 @@ Macros
-

◆ GLFW_JOYSTICK_5

+

◆ GLFW_JOYSTICK_5

@@ -178,7 +185,7 @@ Macros
-

◆ GLFW_JOYSTICK_6

+

◆ GLFW_JOYSTICK_6

@@ -192,7 +199,7 @@ Macros
-

◆ GLFW_JOYSTICK_7

+

◆ GLFW_JOYSTICK_7

@@ -206,7 +213,7 @@ Macros
-

◆ GLFW_JOYSTICK_8

+

◆ GLFW_JOYSTICK_8

@@ -220,7 +227,7 @@ Macros
-

◆ GLFW_JOYSTICK_9

+

◆ GLFW_JOYSTICK_9

@@ -234,7 +241,7 @@ Macros
-

◆ GLFW_JOYSTICK_10

+

◆ GLFW_JOYSTICK_10

@@ -248,7 +255,7 @@ Macros
-

◆ GLFW_JOYSTICK_11

+

◆ GLFW_JOYSTICK_11

@@ -262,7 +269,7 @@ Macros
-

◆ GLFW_JOYSTICK_12

+

◆ GLFW_JOYSTICK_12

@@ -276,7 +283,7 @@ Macros
-

◆ GLFW_JOYSTICK_13

+

◆ GLFW_JOYSTICK_13

@@ -290,7 +297,7 @@ Macros
-

◆ GLFW_JOYSTICK_14

+

◆ GLFW_JOYSTICK_14

@@ -304,7 +311,7 @@ Macros
-

◆ GLFW_JOYSTICK_15

+

◆ GLFW_JOYSTICK_15

@@ -318,7 +325,7 @@ Macros
-

◆ GLFW_JOYSTICK_16

+

◆ GLFW_JOYSTICK_16

@@ -332,7 +339,7 @@ Macros
-

◆ GLFW_JOYSTICK_LAST

+

◆ GLFW_JOYSTICK_LAST

@@ -348,7 +355,7 @@ Macros
diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__keys.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__keys.html similarity index 57% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/group__keys.html rename to src/lib/src/vendor/glfw-3.4/docs/html/group__keys.html index f899864..d40e5f1 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__keys.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__keys.html @@ -4,8 +4,8 @@ - -GLFW: Keyboard keys + +GLFW: Keyboard key tokens @@ -28,10 +28,10 @@
- + @@ -55,23 +55,30 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
-
Keyboard keys
+
Keyboard key tokens

Description

-

See key input for how these are used.

-

These key codes are inspired by the USB HID Usage Tables v1.12 (p. 53-60), but re-arranged to map to 7-bit ASCII for printable keys (function keys are put in the 256+ range).

-

The naming of the key codes follow these rules:

- + @@ -55,9 +55,16 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -67,32 +74,32 @@ $(function() {

Description

-

See key input for how these are used.

+

See key input for how these are used.

- - + + - - + + - - + + - - + + - - + + - - + +

Macros

#define GLFW_MOD_SHIFT   0x0001
 If this bit is set one or more Shift keys were held down. More...
#define GLFW_MOD_SHIFT   0x0001
 If this bit is set one or more Shift keys were held down.
 
#define GLFW_MOD_CONTROL   0x0002
 If this bit is set one or more Control keys were held down. More...
#define GLFW_MOD_CONTROL   0x0002
 If this bit is set one or more Control keys were held down.
 
#define GLFW_MOD_ALT   0x0004
 If this bit is set one or more Alt keys were held down. More...
#define GLFW_MOD_ALT   0x0004
 If this bit is set one or more Alt keys were held down.
 
#define GLFW_MOD_SUPER   0x0008
 If this bit is set one or more Super keys were held down. More...
#define GLFW_MOD_SUPER   0x0008
 If this bit is set one or more Super keys were held down.
 
#define GLFW_MOD_CAPS_LOCK   0x0010
 If this bit is set the Caps Lock key is enabled. More...
#define GLFW_MOD_CAPS_LOCK   0x0010
 If this bit is set the Caps Lock key is enabled.
 
#define GLFW_MOD_NUM_LOCK   0x0020
 If this bit is set the Num Lock key is enabled. More...
#define GLFW_MOD_NUM_LOCK   0x0020
 If this bit is set the Num Lock key is enabled.
 

Macro Definition Documentation

-

◆ GLFW_MOD_SHIFT

+

◆ GLFW_MOD_SHIFT

@@ -102,12 +109,12 @@ Macros
-

If this bit is set one or more Shift keys were held down.

+

If this bit is set one or more Shift keys were held down.

-

◆ GLFW_MOD_CONTROL

+

◆ GLFW_MOD_CONTROL

@@ -117,12 +124,12 @@ Macros
-

If this bit is set one or more Control keys were held down.

+

If this bit is set one or more Control keys were held down.

-

◆ GLFW_MOD_ALT

+

◆ GLFW_MOD_ALT

@@ -132,12 +139,12 @@ Macros
-

If this bit is set one or more Alt keys were held down.

+

If this bit is set one or more Alt keys were held down.

-

◆ GLFW_MOD_SUPER

+

◆ GLFW_MOD_SUPER

@@ -147,12 +154,12 @@ Macros
-

If this bit is set one or more Super keys were held down.

+

If this bit is set one or more Super keys were held down.

-

◆ GLFW_MOD_CAPS_LOCK

+

◆ GLFW_MOD_CAPS_LOCK

@@ -162,12 +169,12 @@ Macros
-

If this bit is set the Caps Lock key is enabled and the GLFW_LOCK_KEY_MODS input mode is set.

+

If this bit is set the Caps Lock key is enabled and the GLFW_LOCK_KEY_MODS input mode is set.

-

◆ GLFW_MOD_NUM_LOCK

+

◆ GLFW_MOD_NUM_LOCK

@@ -177,14 +184,14 @@ Macros
-

If this bit is set the Num Lock key is enabled and the GLFW_LOCK_KEY_MODS input mode is set.

+

If this bit is set the Num Lock key is enabled and the GLFW_LOCK_KEY_MODS input mode is set.

diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__monitor.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__monitor.html similarity index 69% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/group__monitor.html rename to src/lib/src/vendor/glfw-3.4/docs/html/group__monitor.html index 4df6209..3b2044a 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__monitor.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__monitor.html @@ -4,7 +4,7 @@ - + GLFW: Monitor reference @@ -28,10 +28,10 @@
- + @@ -55,9 +55,16 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -68,74 +75,74 @@ $(function() {

Description

-

This is the reference documentation for monitor related functions and types. For more task-oriented information, see the Monitor guide.

+

This is the reference documentation for monitor related functions and types. For more task-oriented information, see the Monitor guide.

- - + + - - + + - - + + - - + +

Typedefs

typedef struct GLFWmonitor GLFWmonitor
 Opaque monitor object. More...
typedef struct GLFWmonitor GLFWmonitor
 Opaque monitor object.
 
typedef void(* GLFWmonitorfun) (GLFWmonitor *monitor, int event)
 The function pointer type for monitor configuration callbacks. More...
typedef void(* GLFWmonitorfun) (GLFWmonitor *monitor, int event)
 The function pointer type for monitor configuration callbacks.
 
typedef struct GLFWvidmode GLFWvidmode
 Video mode type. More...
typedef struct GLFWvidmode GLFWvidmode
 Video mode type.
 
typedef struct GLFWgammaramp GLFWgammaramp
 Gamma ramp. More...
typedef struct GLFWgammaramp GLFWgammaramp
 Gamma ramp.
 
- - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +

Functions

GLFWmonitor ** glfwGetMonitors (int *count)
 Returns the currently connected monitors. More...
GLFWmonitor ** glfwGetMonitors (int *count)
 Returns the currently connected monitors.
 
GLFWmonitorglfwGetPrimaryMonitor (void)
 Returns the primary monitor. More...
GLFWmonitorglfwGetPrimaryMonitor (void)
 Returns the primary monitor.
 
void glfwGetMonitorPos (GLFWmonitor *monitor, int *xpos, int *ypos)
 Returns the position of the monitor's viewport on the virtual screen. More...
void glfwGetMonitorPos (GLFWmonitor *monitor, int *xpos, int *ypos)
 Returns the position of the monitor's viewport on the virtual screen.
 
void glfwGetMonitorWorkarea (GLFWmonitor *monitor, int *xpos, int *ypos, int *width, int *height)
 Retrieves the work area of the monitor. More...
void glfwGetMonitorWorkarea (GLFWmonitor *monitor, int *xpos, int *ypos, int *width, int *height)
 Retrieves the work area of the monitor.
 
void glfwGetMonitorPhysicalSize (GLFWmonitor *monitor, int *widthMM, int *heightMM)
 Returns the physical size of the monitor. More...
void glfwGetMonitorPhysicalSize (GLFWmonitor *monitor, int *widthMM, int *heightMM)
 Returns the physical size of the monitor.
 
void glfwGetMonitorContentScale (GLFWmonitor *monitor, float *xscale, float *yscale)
 Retrieves the content scale for the specified monitor. More...
void glfwGetMonitorContentScale (GLFWmonitor *monitor, float *xscale, float *yscale)
 Retrieves the content scale for the specified monitor.
 
const char * glfwGetMonitorName (GLFWmonitor *monitor)
 Returns the name of the specified monitor. More...
const char * glfwGetMonitorName (GLFWmonitor *monitor)
 Returns the name of the specified monitor.
 
void glfwSetMonitorUserPointer (GLFWmonitor *monitor, void *pointer)
 Sets the user pointer of the specified monitor. More...
void glfwSetMonitorUserPointer (GLFWmonitor *monitor, void *pointer)
 Sets the user pointer of the specified monitor.
 
void * glfwGetMonitorUserPointer (GLFWmonitor *monitor)
 Returns the user pointer of the specified monitor. More...
void * glfwGetMonitorUserPointer (GLFWmonitor *monitor)
 Returns the user pointer of the specified monitor.
 
GLFWmonitorfun glfwSetMonitorCallback (GLFWmonitorfun callback)
 Sets the monitor configuration callback. More...
GLFWmonitorfun glfwSetMonitorCallback (GLFWmonitorfun callback)
 Sets the monitor configuration callback.
 
const GLFWvidmodeglfwGetVideoModes (GLFWmonitor *monitor, int *count)
 Returns the available video modes for the specified monitor. More...
const GLFWvidmodeglfwGetVideoModes (GLFWmonitor *monitor, int *count)
 Returns the available video modes for the specified monitor.
 
const GLFWvidmodeglfwGetVideoMode (GLFWmonitor *monitor)
 Returns the current mode of the specified monitor. More...
const GLFWvidmodeglfwGetVideoMode (GLFWmonitor *monitor)
 Returns the current mode of the specified monitor.
 
void glfwSetGamma (GLFWmonitor *monitor, float gamma)
 Generates a gamma ramp and sets it for the specified monitor. More...
void glfwSetGamma (GLFWmonitor *monitor, float gamma)
 Generates a gamma ramp and sets it for the specified monitor.
 
const GLFWgammarampglfwGetGammaRamp (GLFWmonitor *monitor)
 Returns the current gamma ramp for the specified monitor. More...
const GLFWgammarampglfwGetGammaRamp (GLFWmonitor *monitor)
 Returns the current gamma ramp for the specified monitor.
 
void glfwSetGammaRamp (GLFWmonitor *monitor, const GLFWgammaramp *ramp)
 Sets the current gamma ramp for the specified monitor. More...
void glfwSetGammaRamp (GLFWmonitor *monitor, const GLFWgammaramp *ramp)
 Sets the current gamma ramp for the specified monitor.
 

Typedef Documentation

-

◆ GLFWmonitor

+

◆ GLFWmonitor

@@ -145,14 +152,14 @@ Functions
-

Opaque monitor object.

+

Opaque monitor object.

See also
Monitor objects
Since
Added in version 3.0.
-

◆ GLFWmonitorfun

+

◆ GLFWmonitorfun

@@ -162,8 +169,8 @@ Functions
-

This is the function pointer type for monitor configuration callbacks. A monitor callback function has the following signature:

void function_name(GLFWmonitor* monitor, int event)
-
struct GLFWmonitor GLFWmonitor
Opaque monitor object.
Definition: glfw3.h:1173
+

This is the function pointer type for monitor configuration callbacks. A monitor callback function has the following signature:

void function_name(GLFWmonitor* monitor, int event)
+
struct GLFWmonitor GLFWmonitor
Opaque monitor object.
Definition glfw3.h:1391
Parameters
@@ -179,17 +186,17 @@ Functions -

◆ GLFWvidmode

+

◆ GLFWvidmode

[in]monitorThe monitor that was connected or disconnected.
- +
typedef struct GLFWvidmode GLFWvidmodetypedef struct GLFWvidmode GLFWvidmode
-

This describes a single video mode.

+

This describes a single video mode.

See also
Video modes
glfwGetVideoMode
@@ -200,17 +207,17 @@ Functions
-

◆ GLFWgammaramp

+

◆ GLFWgammaramp

- +
typedef struct GLFWgammaramp GLFWgammaramptypedef struct GLFWgammaramp GLFWgammaramp
-

This describes the gamma ramp for a monitor.

+

This describes the gamma ramp for a monitor.

See also
Gamma ramp
glfwGetGammaRamp
@@ -222,7 +229,7 @@ Functions

Function Documentation

-

◆ glfwGetMonitors()

+

◆ glfwGetMonitors()

@@ -236,7 +243,7 @@ Functions
-

This function returns an array of handles for all currently connected monitors. The primary monitor is always first in the returned array. If no monitors were found, this function returns NULL.

+

This function returns an array of handles for all currently connected monitors. The primary monitor is always first in the returned array. If no monitors were found, this function returns NULL.

Parameters
@@ -257,7 +264,7 @@ Functions -

◆ glfwGetPrimaryMonitor()

+

◆ glfwGetPrimaryMonitor()

@@ -271,7 +278,7 @@ Functions
[out]countWhere to store the number of monitors in the returned array. This is set to zero if an error occurred.
-

This function returns the primary monitor. This is usually the monitor where elements like the task bar or global menu bar are located.

+

This function returns the primary monitor. This is usually the monitor where elements like the task bar or global menu bar are located.

Returns
The primary monitor, or NULL if no monitors were found or if an error occurred.
Errors
Possible errors include GLFW_NOT_INITIALIZED.
Thread safety
This function must only be called from the main thread.
@@ -284,7 +291,7 @@ Functions
-

◆ glfwGetMonitorPos()

+

◆ glfwGetMonitorPos()

@@ -314,8 +321,8 @@ Functions
-

This function returns the position, in screen coordinates, of the upper-left corner of the specified monitor.

-

Any or all of the position arguments may be NULL. If an error occurs, all non-NULL position arguments will be set to zero.

+

This function returns the position, in screen coordinates, of the upper-left corner of the specified monitor.

+

Any or all of the position arguments may be NULL. If an error occurs, all non-NULL position arguments will be set to zero.

Parameters
@@ -332,7 +339,7 @@ Functions -

◆ glfwGetMonitorWorkarea()

+

◆ glfwGetMonitorWorkarea()

@@ -374,8 +381,8 @@ Functions
[in]monitorThe monitor to query.
-

This function returns the position, in screen coordinates, of the upper-left corner of the work area of the specified monitor along with the work area size in screen coordinates. The work area is defined as the area of the monitor not occluded by the operating system task bar where present. If no task bar exists then the work area is the monitor resolution in screen coordinates.

-

Any or all of the position and size arguments may be NULL. If an error occurs, all non-NULL position and size arguments will be set to zero.

+

This function returns the position, in screen coordinates, of the upper-left corner of the work area of the specified monitor along with the work area size in screen coordinates. The work area is defined as the area of the monitor not occluded by the window system task bar where present. If no task bar exists then the work area is the monitor resolution in screen coordinates.

+

Any or all of the position and size arguments may be NULL. If an error occurs, all non-NULL position and size arguments will be set to zero.

Parameters
@@ -394,7 +401,7 @@ Functions -

◆ glfwGetMonitorPhysicalSize()

+

◆ glfwGetMonitorPhysicalSize()

@@ -424,9 +431,9 @@ Functions
[in]monitorThe monitor to query.
-

This function returns the size, in millimetres, of the display area of the specified monitor.

-

Some systems do not provide accurate monitor size information, either because the monitor EDID data is incorrect or because the driver does not report it accurately.

-

Any or all of the size arguments may be NULL. If an error occurs, all non-NULL size arguments will be set to zero.

+

This function returns the size, in millimetres, of the display area of the specified monitor.

+

Some platforms do not provide accurate monitor size information, either because the monitor EDID data is incorrect or because the driver does not report it accurately.

+

Any or all of the size arguments may be NULL. If an error occurs, all non-NULL size arguments will be set to zero.

Parameters
@@ -444,7 +451,7 @@ Functions -

◆ glfwGetMonitorContentScale()

+

◆ glfwGetMonitorContentScale()

@@ -474,8 +481,8 @@ Functions
[in]monitorThe monitor to query.
-

This function retrieves the content scale for the specified monitor. The content scale is the ratio between the current DPI and the platform's default DPI. This is especially important for text and any UI elements. If the pixel dimensions of your UI scaled by this look appropriate on your machine then it should appear at a reasonable size on other machines regardless of their DPI and scaling settings. This relies on the system DPI and scaling settings being somewhat correct.

-

The content scale may depend on both the monitor resolution and pixel density and on user settings. It may be very different from the raw DPI calculated from the physical size and current resolution.

+

This function retrieves the content scale for the specified monitor. The content scale is the ratio between the current DPI and the platform's default DPI. This is especially important for text and any UI elements. If the pixel dimensions of your UI scaled by this look appropriate on your machine then it should appear at a reasonable size on other machines regardless of their DPI and scaling settings. This relies on the system DPI and scaling settings being somewhat correct.

+

The content scale may depend on both the monitor resolution and pixel density and on user settings. It may be very different from the raw DPI calculated from the physical size and current resolution.

Parameters
@@ -485,6 +492,7 @@ Functions
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
+
Remarks
Wayland: Fractional scaling information is not yet available for monitors, so this function only returns integer content scales.
Thread safety
This function must only be called from the main thread.
See also
Content scale
@@ -494,7 +502,7 @@ Functions -

◆ glfwGetMonitorName()

+

◆ glfwGetMonitorName()

@@ -508,7 +516,7 @@ Functions
[in]monitorThe monitor to query.
-

This function returns a human-readable name, encoded as UTF-8, of the specified monitor. The name typically reflects the make and model of the monitor and is not guaranteed to be unique among the connected monitors.

+

This function returns a human-readable name, encoded as UTF-8, of the specified monitor. The name typically reflects the make and model of the monitor and is not guaranteed to be unique among the connected monitors.

Parameters
@@ -525,7 +533,7 @@ Functions -

◆ glfwSetMonitorUserPointer()

+

◆ glfwSetMonitorUserPointer()

@@ -549,8 +557,8 @@ Functions
[in]monitorThe monitor to query.
-

This function sets the user-defined pointer of the specified monitor. The current value is retained until the monitor is disconnected. The initial value is NULL.

-

This function may be called from the monitor callback, even for a monitor that is being disconnected.

+

This function sets the user-defined pointer of the specified monitor. The current value is retained until the monitor is disconnected. The initial value is NULL.

+

This function may be called from the monitor callback, even for a monitor that is being disconnected.

Parameters
@@ -568,7 +576,7 @@ Functions -

◆ glfwGetMonitorUserPointer()

+

◆ glfwGetMonitorUserPointer()

@@ -582,8 +590,8 @@ Functions
[in]monitorThe monitor whose pointer to set.
-

This function returns the current value of the user-defined pointer of the specified monitor. The initial value is NULL.

-

This function may be called from the monitor callback, even for a monitor that is being disconnected.

+

This function returns the current value of the user-defined pointer of the specified monitor. The initial value is NULL.

+

This function may be called from the monitor callback, even for a monitor that is being disconnected.

Parameters
@@ -600,7 +608,7 @@ Functions -

◆ glfwSetMonitorCallback()

+

◆ glfwSetMonitorCallback()

@@ -614,7 +622,7 @@ Functions
[in]monitorThe monitor whose pointer to return.
-

This function sets the monitor configuration callback, or removes the currently set callback. This is called when a monitor is connected to or disconnected from the system.

+

This function sets the monitor configuration callback, or removes the currently set callback. This is called when a monitor is connected to or disconnected from the system.

Parameters
@@ -632,13 +640,13 @@ Functions -

◆ glfwGetVideoModes()

+

◆ glfwGetVideoModes()

[in]callbackThe new callback, or NULL to remove the currently set callback.
- + @@ -656,7 +664,7 @@ Functions
const GLFWvidmode * glfwGetVideoModes const GLFWvidmode * glfwGetVideoModes ( GLFWmonitor monitor,
-

This function returns an array of all video modes supported by the specified monitor. The returned array is sorted in ascending order, first by color bit depth (the sum of all channel depths), then by resolution area (the product of width and height), then resolution width and finally by refresh rate.

+

This function returns an array of all video modes supported by the specified monitor. The returned array is sorted in ascending order, first by color bit depth (the sum of all channel depths), then by resolution area (the product of width and height), then resolution width and finally by refresh rate.

Parameters
@@ -676,13 +684,13 @@ Functions -

◆ glfwGetVideoMode()

+

◆ glfwGetVideoMode()

[in]monitorThe monitor to query.
- + @@ -690,7 +698,7 @@ Functions
const GLFWvidmode * glfwGetVideoMode const GLFWvidmode * glfwGetVideoMode ( GLFWmonitor monitor)
-

This function returns the current video mode of the specified monitor. If you have created a full screen window for that monitor, the return value will depend on whether that window is iconified.

+

This function returns the current video mode of the specified monitor. If you have created a full screen window for that monitor, the return value will depend on whether that window is iconified.

Parameters
@@ -709,7 +717,7 @@ Functions -

◆ glfwSetGamma()

+

◆ glfwSetGamma()

@@ -733,9 +741,9 @@ Functions
[in]monitorThe monitor to query.
-

This function generates an appropriately sized gamma ramp from the specified exponent and then calls glfwSetGammaRamp with it. The value must be a finite number greater than zero.

-

The software controlled gamma ramp is applied in addition to the hardware gamma correction, which today is usually an approximation of sRGB gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will produce the default (usually sRGB-like) behavior.

-

For gamma correct rendering with OpenGL or OpenGL ES, see the GLFW_SRGB_CAPABLE hint.

+

This function generates an appropriately sized gamma ramp from the specified exponent and then calls glfwSetGammaRamp with it. The value must be a finite number greater than zero.

+

The software controlled gamma ramp is applied in addition to the hardware gamma correction, which today is usually an approximation of sRGB gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will produce the default (usually sRGB-like) behavior.

+

For gamma correct rendering with OpenGL or OpenGL ES, see the GLFW_SRGB_CAPABLE hint.

Parameters
@@ -743,8 +751,8 @@ Functions
[in]monitorThe monitor whose gamma ramp to set.
-
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_VALUE and GLFW_PLATFORM_ERROR.
-
Remarks
Wayland: Gamma handling is a privileged protocol, this function will thus never be implemented and emits GLFW_PLATFORM_ERROR.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_VALUE, GLFW_PLATFORM_ERROR and GLFW_FEATURE_UNAVAILABLE (see remarks).
+
Remarks
Wayland: Gamma handling is a privileged protocol, this function will thus never be implemented and emits GLFW_FEATURE_UNAVAILABLE.
Thread safety
This function must only be called from the main thread.
See also
Gamma ramp
Since
Added in version 3.0.
@@ -752,13 +760,13 @@ Functions
-

◆ glfwGetGammaRamp()

+

◆ glfwGetGammaRamp()

- + @@ -766,7 +774,7 @@ Functions
const GLFWgammaramp * glfwGetGammaRamp const GLFWgammaramp * glfwGetGammaRamp ( GLFWmonitor monitor)
-

This function returns the current gamma ramp of the specified monitor.

+

This function returns the current gamma ramp of the specified monitor.

Parameters
@@ -774,8 +782,8 @@ Functions
Returns
The current gamma ramp, or NULL if an error occurred.
-
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
-
Remarks
Wayland: Gamma handling is a privileged protocol, this function will thus never be implemented and emits GLFW_PLATFORM_ERROR while returning NULL.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_PLATFORM_ERROR and GLFW_FEATURE_UNAVAILABLE (see remarks).
+
Remarks
Wayland: Gamma handling is a privileged protocol, this function will thus never be implemented and emits GLFW_FEATURE_UNAVAILABLE while returning NULL.
Pointer lifetime
The returned structure and its arrays are allocated and freed by GLFW. You should not free them yourself. They are valid until the specified monitor is disconnected, this function is called again for that monitor or the library is terminated.
Thread safety
This function must only be called from the main thread.
See also
Gamma ramp
@@ -784,7 +792,7 @@ Functions -

◆ glfwSetGammaRamp()

+

◆ glfwSetGammaRamp()

@@ -798,7 +806,7 @@ Functions
- + @@ -808,9 +816,9 @@ Functions
[in]monitorThe monitor to query.
const GLFWgammarampconst GLFWgammaramp ramp 
-

This function sets the current gamma ramp for the specified monitor. The original gamma ramp for that monitor is saved by GLFW the first time this function is called and is restored by glfwTerminate.

-

The software controlled gamma ramp is applied in addition to the hardware gamma correction, which today is usually an approximation of sRGB gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will produce the default (usually sRGB-like) behavior.

-

For gamma correct rendering with OpenGL or OpenGL ES, see the GLFW_SRGB_CAPABLE hint.

+

This function sets the current gamma ramp for the specified monitor. The original gamma ramp for that monitor is saved by GLFW the first time this function is called and is restored by glfwTerminate.

+

The software controlled gamma ramp is applied in addition to the hardware gamma correction, which today is usually an approximation of sRGB gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will produce the default (usually sRGB-like) behavior.

+

For gamma correct rendering with OpenGL or OpenGL ES, see the GLFW_SRGB_CAPABLE hint.

Parameters
@@ -818,12 +826,12 @@ Functions
[in]monitorThe monitor whose gamma ramp to set.
-
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_PLATFORM_ERROR and GLFW_FEATURE_UNAVAILABLE (see remarks).
Remarks
The size of the specified gamma ramp should match the size of the current ramp for that monitor.
Windows: The gamma ramp size must be 256.
-Wayland: Gamma handling is a privileged protocol, this function will thus never be implemented and emits GLFW_PLATFORM_ERROR.
+Wayland: Gamma handling is a privileged protocol, this function will thus never be implemented and emits GLFW_FEATURE_UNAVAILABLE.
Pointer lifetime
The specified gamma ramp is copied before this function returns.
Thread safety
This function must only be called from the main thread.
See also
Gamma ramp
@@ -834,7 +842,7 @@ Functions
diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__native.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__native.html similarity index 67% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/group__native.html rename to src/lib/src/vendor/glfw-3.4/docs/html/group__native.html index 5adef3b..fff036f 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__native.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__native.html @@ -4,7 +4,7 @@ - + GLFW: Native access @@ -28,10 +28,10 @@
- + @@ -55,9 +55,16 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -67,24 +74,24 @@ $(function() {

Description

-

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 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:

    +

    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 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:

      +

      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 glfw3native.h header.

      +

      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 glfw3native.h header.

      #define GLFW_EXPOSE_NATIVE_WIN32
      #define GLFW_EXPOSE_NATIVE_WGL
      #define GLFW_NATIVE_INCLUDE_NONE
      @@ -93,82 +100,85 @@ $(function() {
      - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +

      Functions

      const char * glfwGetWin32Adapter (GLFWmonitor *monitor)
       Returns the adapter device name of the specified monitor. More...
      const char * glfwGetWin32Adapter (GLFWmonitor *monitor)
       Returns the adapter device name of the specified monitor.
       
      const char * glfwGetWin32Monitor (GLFWmonitor *monitor)
       Returns the display device name of the specified monitor. More...
      const char * glfwGetWin32Monitor (GLFWmonitor *monitor)
       Returns the display device name of the specified monitor.
       
      HWND glfwGetWin32Window (GLFWwindow *window)
       Returns the HWND of the specified window. More...
      HWND glfwGetWin32Window (GLFWwindow *window)
       Returns the HWND of the specified window.
       
      HGLRC glfwGetWGLContext (GLFWwindow *window)
       Returns the HGLRC of the specified window. More...
      HGLRC glfwGetWGLContext (GLFWwindow *window)
       Returns the HGLRC of the specified window.
       
      CGDirectDisplayID glfwGetCocoaMonitor (GLFWmonitor *monitor)
       Returns the CGDirectDisplayID of the specified monitor. More...
      CGDirectDisplayID glfwGetCocoaMonitor (GLFWmonitor *monitor)
       Returns the CGDirectDisplayID of the specified monitor.
       
      id glfwGetCocoaWindow (GLFWwindow *window)
       Returns the NSWindow of the specified window. More...
      id glfwGetCocoaWindow (GLFWwindow *window)
       Returns the NSWindow of the specified window.
       
      id glfwGetNSGLContext (GLFWwindow *window)
       Returns the NSOpenGLContext of the specified window. More...
      id glfwGetCocoaView (GLFWwindow *window)
       Returns the NSView of the specified window.
       
      id glfwGetNSGLContext (GLFWwindow *window)
       Returns the NSOpenGLContext of the specified window.
       
      Display * glfwGetX11Display (void)
       Returns the Display used by GLFW. More...
      Display * glfwGetX11Display (void)
       Returns the Display used by GLFW.
       
      RRCrtc glfwGetX11Adapter (GLFWmonitor *monitor)
       Returns the RRCrtc of the specified monitor. More...
      RRCrtc glfwGetX11Adapter (GLFWmonitor *monitor)
       Returns the RRCrtc of the specified monitor.
       
      RROutput glfwGetX11Monitor (GLFWmonitor *monitor)
       Returns the RROutput of the specified monitor. More...
      RROutput glfwGetX11Monitor (GLFWmonitor *monitor)
       Returns the RROutput of the specified monitor.
       
      Window glfwGetX11Window (GLFWwindow *window)
       Returns the Window of the specified window. More...
      Window glfwGetX11Window (GLFWwindow *window)
       Returns the Window of the specified window.
       
      void glfwSetX11SelectionString (const char *string)
       Sets the current primary selection to the specified string. More...
      void glfwSetX11SelectionString (const char *string)
       Sets the current primary selection to the specified string.
       
      const char * glfwGetX11SelectionString (void)
       Returns the contents of the current primary selection as a string. More...
      const char * glfwGetX11SelectionString (void)
       Returns the contents of the current primary selection as a string.
       
      GLXContext glfwGetGLXContext (GLFWwindow *window)
       Returns the GLXContext of the specified window. More...
      GLXContext glfwGetGLXContext (GLFWwindow *window)
       Returns the GLXContext of the specified window.
       
      GLXWindow glfwGetGLXWindow (GLFWwindow *window)
       Returns the GLXWindow of the specified window. More...
      GLXWindow glfwGetGLXWindow (GLFWwindow *window)
       Returns the GLXWindow of the specified window.
       
      struct wl_display * glfwGetWaylandDisplay (void)
       Returns the struct wl_display* used by GLFW. More...
      struct wl_display * glfwGetWaylandDisplay (void)
       Returns the struct wl_display* used by GLFW.
       
      struct wl_output * glfwGetWaylandMonitor (GLFWmonitor *monitor)
       Returns the struct wl_output* of the specified monitor. More...
      struct wl_output * glfwGetWaylandMonitor (GLFWmonitor *monitor)
       Returns the struct wl_output* of the specified monitor.
       
      struct wl_surface * glfwGetWaylandWindow (GLFWwindow *window)
       Returns the main struct wl_surface* of the specified window. More...
      struct wl_surface * glfwGetWaylandWindow (GLFWwindow *window)
       Returns the main struct wl_surface* of the specified window.
       
      EGLDisplay glfwGetEGLDisplay (void)
       Returns the EGLDisplay used by GLFW. More...
      EGLDisplay glfwGetEGLDisplay (void)
       Returns the EGLDisplay used by GLFW.
       
      EGLContext glfwGetEGLContext (GLFWwindow *window)
       Returns the EGLContext of the specified window. More...
      EGLContext glfwGetEGLContext (GLFWwindow *window)
       Returns the EGLContext of the specified window.
       
      EGLSurface glfwGetEGLSurface (GLFWwindow *window)
       Returns the EGLSurface of the specified window. More...
      EGLSurface glfwGetEGLSurface (GLFWwindow *window)
       Returns the EGLSurface of the specified window.
       
      int glfwGetOSMesaColorBuffer (GLFWwindow *window, int *width, int *height, int *format, void **buffer)
       Retrieves the color buffer associated with the specified window. More...
      int glfwGetOSMesaColorBuffer (GLFWwindow *window, int *width, int *height, int *format, void **buffer)
       Retrieves the color buffer associated with the specified window.
       
      int glfwGetOSMesaDepthBuffer (GLFWwindow *window, int *width, int *height, int *bytesPerValue, void **buffer)
       Retrieves the depth buffer associated with the specified window. More...
      int glfwGetOSMesaDepthBuffer (GLFWwindow *window, int *width, int *height, int *bytesPerValue, void **buffer)
       Retrieves the depth buffer associated with the specified window.
       
      OSMesaContext glfwGetOSMesaContext (GLFWwindow *window)
       Returns the OSMesaContext of the specified window. More...
      OSMesaContext glfwGetOSMesaContext (GLFWwindow *window)
       Returns the OSMesaContext of the specified window.
       

      Function Documentation

      -

      ◆ glfwGetWin32Adapter()

      +

      ◆ glfwGetWin32Adapter()

      @@ -183,14 +193,14 @@ Functions
      Returns
      The UTF-8 encoded adapter device name (for example \\.\DISPLAY1) of the specified monitor, or NULL if an error occurred.
      -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_UNAVAILABLE.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.1.
      -

      ◆ glfwGetWin32Monitor()

      +

      ◆ glfwGetWin32Monitor()

      @@ -205,14 +215,14 @@ Functions
      Returns
      The UTF-8 encoded display device name (for example \\.\DISPLAY1\Monitor0) of the specified monitor, or NULL if an error occurred.
      -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_UNAVAILABLE.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.1.
      -

      ◆ glfwGetWin32Window()

      +

      ◆ glfwGetWin32Window()

      @@ -227,7 +237,7 @@ Functions
      Returns
      The HWND of the specified window, or NULL if an error occurred.
      -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_UNAVAILABLE.
      Remarks
      The HDC associated with the window can be queried with the GetDC function.
      HDC dc = GetDC(glfwGetWin32Window(window));
      HWND glfwGetWin32Window(GLFWwindow *window)
      Returns the HWND of the specified window.
      This DC is private and does not need to be released.
      @@ -237,7 +247,7 @@ Functions
      -

      ◆ glfwGetWGLContext()

      +

      ◆ glfwGetWGLContext()

      @@ -252,7 +262,7 @@ Functions
      Returns
      The HGLRC of the specified window, or NULL if an error occurred.
      -
      Errors
      Possible errors include GLFW_NO_WINDOW_CONTEXT and GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED, GLFW_PLATFORM_UNAVAILABLE and GLFW_NO_WINDOW_CONTEXT.
      Remarks
      The HDC associated with the window can be queried with the GetDC function.
      HDC dc = GetDC(glfwGetWin32Window(window));
      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.
      @@ -261,7 +271,7 @@ Functions
      -

      ◆ glfwGetCocoaMonitor()

      +

      ◆ glfwGetCocoaMonitor()

      @@ -276,14 +286,14 @@ Functions
      Returns
      The CGDirectDisplayID of the specified monitor, or kCGNullDirectDisplay if an error occurred.
      -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_UNAVAILABLE.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.1.
      -

      ◆ glfwGetCocoaWindow()

      +

      ◆ glfwGetCocoaWindow()

      @@ -298,14 +308,36 @@ Functions
      Returns
      The NSWindow of the specified window, or nil if an error occurred.
      -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_UNAVAILABLE.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.0.
      +
      +
      + +

      ◆ glfwGetCocoaView()

      + +
      +
      + + + + + + + + +
      id glfwGetCocoaView (GLFWwindowwindow)
      +
      +
      Returns
      The NSView of the specified window, or nil if an error occurred.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_UNAVAILABLE.
      +
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      +
      Since
      Added in version 3.4.
      +
      -

      ◆ glfwGetNSGLContext()

      +

      ◆ glfwGetNSGLContext()

      @@ -320,14 +352,14 @@ Functions
      Returns
      The NSOpenGLContext of the specified window, or nil if an error occurred.
      -
      Errors
      Possible errors include GLFW_NO_WINDOW_CONTEXT and GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED, GLFW_PLATFORM_UNAVAILABLE and GLFW_NO_WINDOW_CONTEXT.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.0.
      -

      ◆ glfwGetX11Display()

      +

      ◆ glfwGetX11Display()

      @@ -342,14 +374,14 @@ Functions
      Returns
      The Display used by GLFW, or NULL if an error occurred.
      -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_UNAVAILABLE.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.0.
      -

      ◆ glfwGetX11Adapter()

      +

      ◆ glfwGetX11Adapter()

      @@ -364,14 +396,14 @@ Functions
      Returns
      The RRCrtc of the specified monitor, or None if an error occurred.
      -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_UNAVAILABLE.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.1.
      -

      ◆ glfwGetX11Monitor()

      +

      ◆ glfwGetX11Monitor()

      @@ -386,14 +418,14 @@ Functions
      Returns
      The RROutput of the specified monitor, or None if an error occurred.
      -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_UNAVAILABLE.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.1.
      -

      ◆ glfwGetX11Window()

      +

      ◆ glfwGetX11Window()

      @@ -408,14 +440,14 @@ Functions
      Returns
      The Window of the specified window, or None if an error occurred.
      -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_UNAVAILABLE.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.0.
      -

      ◆ glfwSetX11SelectionString()

      +

      ◆ glfwSetX11SelectionString()

      @@ -435,7 +467,7 @@ Functions -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED, GLFW_PLATFORM_UNAVAILABLE and 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.
      See also
      Clipboard input and output
      @@ -448,7 +480,7 @@ Functions
      -

      ◆ glfwGetX11SelectionString()

      +

      ◆ glfwGetX11SelectionString()

      @@ -462,9 +494,9 @@ Functions
      -

      If the selection is empty or if its contents cannot be converted, NULL is returned and a GLFW_FORMAT_UNAVAILABLE error is generated.

      +

      If the selection is empty or if its contents cannot be converted, NULL is returned and a GLFW_FORMAT_UNAVAILABLE error is generated.

      Returns
      The contents of the selection as a UTF-8 encoded string, or NULL if an error occurred.
      -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED, GLFW_PLATFORM_UNAVAILABLE and 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 glfwGetX11SelectionString or glfwSetX11SelectionString, or until the library is terminated.
      Thread safety
      This function must only be called from the main thread.
      See also
      Clipboard input and output
      @@ -477,7 +509,7 @@ Functions
      -

      ◆ glfwGetGLXContext()

      +

      ◆ glfwGetGLXContext()

      @@ -492,14 +524,14 @@ Functions
      Returns
      The GLXContext of the specified window, or NULL if an error occurred.
      -
      Errors
      Possible errors include GLFW_NO_WINDOW_CONTEXT and GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED, GLFW_NO_WINDOW_CONTEXT and GLFW_PLATFORM_UNAVAILABLE.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.0.
      -

      ◆ glfwGetGLXWindow()

      +

      ◆ glfwGetGLXWindow()

      @@ -514,14 +546,14 @@ Functions
      Returns
      The GLXWindow of the specified window, or None if an error occurred.
      -
      Errors
      Possible errors include GLFW_NO_WINDOW_CONTEXT and GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED, GLFW_NO_WINDOW_CONTEXT and GLFW_PLATFORM_UNAVAILABLE.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.2.
      -

      ◆ glfwGetWaylandDisplay()

      +

      ◆ glfwGetWaylandDisplay()

      @@ -536,14 +568,14 @@ Functions
      Returns
      The struct wl_display* used by GLFW, or NULL if an error occurred.
      -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_UNAVAILABLE.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.2.
      -

      ◆ glfwGetWaylandMonitor()

      +

      ◆ glfwGetWaylandMonitor()

      @@ -558,14 +590,14 @@ Functions
      Returns
      The struct wl_output* of the specified monitor, or NULL if an error occurred.
      -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_UNAVAILABLE.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.2.
      -

      ◆ glfwGetWaylandWindow()

      +

      ◆ glfwGetWaylandWindow()

      @@ -580,14 +612,14 @@ Functions
      Returns
      The main struct wl_surface* of the specified window, or NULL if an error occurred.
      -
      Errors
      Possible errors include GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_UNAVAILABLE.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.2.
      -

      ◆ glfwGetEGLDisplay()

      +

      ◆ glfwGetEGLDisplay()

      @@ -610,7 +642,7 @@ Functions
      -

      ◆ glfwGetEGLContext()

      +

      ◆ glfwGetEGLContext()

      @@ -625,14 +657,14 @@ Functions
      Returns
      The EGLContext of the specified window, or EGL_NO_CONTEXT if an error occurred.
      -
      Errors
      Possible errors include GLFW_NO_WINDOW_CONTEXT and GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_NO_WINDOW_CONTEXT.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.0.
      -

      ◆ glfwGetEGLSurface()

      +

      ◆ glfwGetEGLSurface()

      @@ -647,14 +679,14 @@ Functions
      Returns
      The EGLSurface of the specified window, or EGL_NO_SURFACE if an error occurred.
      -
      Errors
      Possible errors include GLFW_NO_WINDOW_CONTEXT and GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_NO_WINDOW_CONTEXT.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.0.
      -

      ◆ glfwGetOSMesaColorBuffer()

      +

      ◆ glfwGetOSMesaColorBuffer()

      @@ -707,14 +739,14 @@ Functions
      Returns
      GLFW_TRUE if successful, or GLFW_FALSE if an error occurred.
      -
      Errors
      Possible errors include GLFW_NO_WINDOW_CONTEXT and GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_NO_WINDOW_CONTEXT.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.3.
      -

      ◆ glfwGetOSMesaDepthBuffer()

      +

      ◆ glfwGetOSMesaDepthBuffer()

      @@ -767,14 +799,14 @@ Functions
      Returns
      GLFW_TRUE if successful, or GLFW_FALSE if an error occurred.
      -
      Errors
      Possible errors include GLFW_NO_WINDOW_CONTEXT and GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_NO_WINDOW_CONTEXT.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.3.
      -

      ◆ glfwGetOSMesaContext()

      +

      ◆ glfwGetOSMesaContext()

      @@ -789,7 +821,7 @@ Functions
      Returns
      The OSMesaContext of the specified window, or NULL if an error occurred.
      -
      Errors
      Possible errors include GLFW_NO_WINDOW_CONTEXT and GLFW_NOT_INITIALIZED.
      +
      Errors
      Possible errors include GLFW_NOT_INITIALIZED and GLFW_NO_WINDOW_CONTEXT.
      Thread safety
      This function may be called from any thread. Access is not synchronized.
      Since
      Added in version 3.3.
      @@ -798,7 +830,7 @@ Functions
      diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/group__shapes.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__shapes.html new file mode 100644 index 0000000..09e7287 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__shapes.html @@ -0,0 +1,337 @@ + + + + + + + +GLFW: Standard cursor shapes + + + + + + + + + + +
      + + + + + + + + +
      + +
      +
      + + +
      +
      +
      +
      +
      +
      Loading...
      +
      Searching...
      +
      No Matches
      +
      +
      +
      +
      + +
      + +
      Standard cursor shapes
      +
      +
      +

      Description

      +

      These are the standard cursor shapes that can be requested from the platform (window system).

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

      +Macros

      #define GLFW_ARROW_CURSOR   0x00036001
       The regular arrow cursor shape.
       
      #define GLFW_IBEAM_CURSOR   0x00036002
       The text input I-beam cursor shape.
       
      #define GLFW_CROSSHAIR_CURSOR   0x00036003
       The crosshair cursor shape.
       
      #define GLFW_POINTING_HAND_CURSOR   0x00036004
       The pointing hand cursor shape.
       
      #define GLFW_RESIZE_EW_CURSOR   0x00036005
       The horizontal resize/move arrow shape.
       
      #define GLFW_RESIZE_NS_CURSOR   0x00036006
       The vertical resize/move arrow shape.
       
      #define GLFW_RESIZE_NWSE_CURSOR   0x00036007
       The top-left to bottom-right diagonal resize/move arrow shape.
       
      #define GLFW_RESIZE_NESW_CURSOR   0x00036008
       The top-right to bottom-left diagonal resize/move arrow shape.
       
      #define GLFW_RESIZE_ALL_CURSOR   0x00036009
       The omni-directional resize/move cursor shape.
       
      #define GLFW_NOT_ALLOWED_CURSOR   0x0003600A
       The operation-not-allowed shape.
       
      #define GLFW_HRESIZE_CURSOR   GLFW_RESIZE_EW_CURSOR
       Legacy name for compatibility.
       
      #define GLFW_VRESIZE_CURSOR   GLFW_RESIZE_NS_CURSOR
       Legacy name for compatibility.
       
      #define GLFW_HAND_CURSOR   GLFW_POINTING_HAND_CURSOR
       Legacy name for compatibility.
       
      +

      Macro Definition Documentation

      + +

      ◆ GLFW_ARROW_CURSOR

      + +
      +
      + + + + +
      #define GLFW_ARROW_CURSOR   0x00036001
      +
      +

      The regular arrow cursor shape.

      + +
      +
      + +

      ◆ GLFW_IBEAM_CURSOR

      + +
      +
      + + + + +
      #define GLFW_IBEAM_CURSOR   0x00036002
      +
      +

      The text input I-beam cursor shape.

      + +
      +
      + +

      ◆ GLFW_CROSSHAIR_CURSOR

      + +
      +
      + + + + +
      #define GLFW_CROSSHAIR_CURSOR   0x00036003
      +
      +

      The crosshair cursor shape.

      + +
      +
      + +

      ◆ GLFW_POINTING_HAND_CURSOR

      + +
      +
      + + + + +
      #define GLFW_POINTING_HAND_CURSOR   0x00036004
      +
      +

      The pointing hand cursor shape.

      + +
      +
      + +

      ◆ GLFW_RESIZE_EW_CURSOR

      + +
      +
      + + + + +
      #define GLFW_RESIZE_EW_CURSOR   0x00036005
      +
      +

      The horizontal resize/move arrow shape. This is usually a horizontal double-headed arrow.

      + +
      +
      + +

      ◆ GLFW_RESIZE_NS_CURSOR

      + +
      +
      + + + + +
      #define GLFW_RESIZE_NS_CURSOR   0x00036006
      +
      +

      The vertical resize/move shape. This is usually a vertical double-headed arrow.

      + +
      +
      + +

      ◆ GLFW_RESIZE_NWSE_CURSOR

      + +
      +
      + + + + +
      #define GLFW_RESIZE_NWSE_CURSOR   0x00036007
      +
      +

      The top-left to bottom-right diagonal resize/move shape. This is usually a diagonal double-headed arrow.

      +
      Note
      macOS: This shape is provided by a private system API and may fail with GLFW_CURSOR_UNAVAILABLE in the future.
      +
      +Wayland: This shape is provided by a newer standard not supported by all cursor themes.
      +
      +X11: This shape is provided by a newer standard not supported by all cursor themes.
      + +
      +
      + +

      ◆ GLFW_RESIZE_NESW_CURSOR

      + +
      +
      + + + + +
      #define GLFW_RESIZE_NESW_CURSOR   0x00036008
      +
      +

      The top-right to bottom-left diagonal resize/move shape. This is usually a diagonal double-headed arrow.

      +
      Note
      macOS: This shape is provided by a private system API and may fail with GLFW_CURSOR_UNAVAILABLE in the future.
      +
      +Wayland: This shape is provided by a newer standard not supported by all cursor themes.
      +
      +X11: This shape is provided by a newer standard not supported by all cursor themes.
      + +
      +
      + +

      ◆ GLFW_RESIZE_ALL_CURSOR

      + +
      +
      + + + + +
      #define GLFW_RESIZE_ALL_CURSOR   0x00036009
      +
      +

      The omni-directional resize cursor/move shape. This is usually either a combined horizontal and vertical double-headed arrow or a grabbing hand.

      + +
      +
      + +

      ◆ GLFW_NOT_ALLOWED_CURSOR

      + +
      +
      + + + + +
      #define GLFW_NOT_ALLOWED_CURSOR   0x0003600A
      +
      +

      The operation-not-allowed shape. This is usually a circle with a diagonal line through it.

      +
      Note
      Wayland: This shape is provided by a newer standard not supported by all cursor themes.
      +
      +X11: This shape is provided by a newer standard not supported by all cursor themes.
      + +
      +
      + +

      ◆ GLFW_HRESIZE_CURSOR

      + +
      +
      + + + + +
      #define GLFW_HRESIZE_CURSOR   GLFW_RESIZE_EW_CURSOR
      +
      +

      This is an alias for compatibility with earlier versions.

      + +
      +
      + +

      ◆ GLFW_VRESIZE_CURSOR

      + +
      +
      + + + + +
      #define GLFW_VRESIZE_CURSOR   GLFW_RESIZE_NS_CURSOR
      +
      +

      This is an alias for compatibility with earlier versions.

      + +
      +
      + +

      ◆ GLFW_HAND_CURSOR

      + +
      +
      + + + + +
      #define GLFW_HAND_CURSOR   GLFW_POINTING_HAND_CURSOR
      +
      +

      This is an alias for compatibility with earlier versions.

      + +
      +
      +
      + + + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__vulkan.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__vulkan.html similarity index 66% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/group__vulkan.html rename to src/lib/src/vendor/glfw-3.4/docs/html/group__vulkan.html index f80f4a9..6c2eb66 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__vulkan.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__vulkan.html @@ -4,7 +4,7 @@ - + GLFW: Vulkan support reference @@ -28,10 +28,10 @@
- + @@ -55,9 +55,16 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -68,35 +75,35 @@ $(function() {

Description

-

This is the reference documentation for Vulkan related functions and types. For more task-oriented information, see the Vulkan guide.

+

This is the reference documentation for Vulkan related functions and types. For more task-oriented information, see the Vulkan guide.

- - + +

Typedefs

typedef void(* GLFWvkproc) (void)
 Vulkan API function pointer type. More...
typedef void(* GLFWvkproc) (void)
 Vulkan API function pointer type.
 
- - + + - - + + - - + + - - + + - - + +

Functions

int glfwVulkanSupported (void)
 Returns whether the Vulkan loader and an ICD have been found. More...
int glfwVulkanSupported (void)
 Returns whether the Vulkan loader and an ICD have been found.
 
const char ** glfwGetRequiredInstanceExtensions (uint32_t *count)
 Returns the Vulkan instance extensions required by GLFW. More...
const char ** glfwGetRequiredInstanceExtensions (uint32_t *count)
 Returns the Vulkan instance extensions required by GLFW.
 
GLFWvkproc glfwGetInstanceProcAddress (VkInstance instance, const char *procname)
 Returns the address of the specified Vulkan instance function. More...
GLFWvkproc glfwGetInstanceProcAddress (VkInstance instance, const char *procname)
 Returns the address of the specified Vulkan instance function.
 
int glfwGetPhysicalDevicePresentationSupport (VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily)
 Returns whether the specified queue family can present images. More...
int glfwGetPhysicalDevicePresentationSupport (VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily)
 Returns whether the specified queue family can present images.
 
VkResult glfwCreateWindowSurface (VkInstance instance, GLFWwindow *window, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
 Creates a Vulkan surface for the specified window. More...
VkResult glfwCreateWindowSurface (VkInstance instance, GLFWwindow *window, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
 Creates a Vulkan surface for the specified window.
 

Typedef Documentation

-

◆ GLFWvkproc

+

◆ GLFWvkproc

@@ -106,7 +113,7 @@ Functions
-

Generic function pointer used for returning Vulkan API function pointers without forcing a cast from a regular pointer.

+

Generic function pointer used for returning Vulkan API function pointers without forcing a cast from a regular pointer.

See also
Querying Vulkan function pointers
glfwGetInstanceProcAddress
@@ -116,7 +123,7 @@ Functions

Function Documentation

-

◆ glfwVulkanSupported()

+

◆ glfwVulkanSupported()

@@ -130,8 +137,8 @@ Functions
-

This function returns whether the Vulkan loader and any minimally functional ICD have been found.

-

The availability of a Vulkan loader and even an ICD does not by itself guarantee that surface creation or even instance creation is possible. Call glfwGetRequiredInstanceExtensions to check whether the extensions necessary for Vulkan surface creation are available and glfwGetPhysicalDevicePresentationSupport to check whether a queue family of a physical device supports image presentation.

+

This function returns whether the Vulkan loader and any minimally functional ICD have been found.

+

The availability of a Vulkan loader and even an ICD does not by itself guarantee that surface creation or even instance creation is possible. Call glfwGetRequiredInstanceExtensions to check whether the extensions necessary for Vulkan surface creation are available and glfwGetPhysicalDevicePresentationSupport to check whether a queue family of a physical device supports image presentation.

Returns
GLFW_TRUE if Vulkan is minimally available, or GLFW_FALSE otherwise.
Errors
Possible errors include GLFW_NOT_INITIALIZED.
Thread safety
This function may be called from any thread.
@@ -141,7 +148,7 @@ Functions
-

◆ glfwGetRequiredInstanceExtensions()

+

◆ glfwGetRequiredInstanceExtensions()

@@ -155,9 +162,9 @@ Functions
-

This function returns an array of names of Vulkan instance extensions required by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the list will always contain VK_KHR_surface, so if you don't require any additional extensions you can pass this list directly to the VkInstanceCreateInfo struct.

-

If Vulkan is not available on the machine, this function returns NULL and generates a GLFW_API_UNAVAILABLE error. Call glfwVulkanSupported to check whether Vulkan is at least minimally available.

-

If Vulkan is available but no set of extensions allowing window surface creation was found, this function returns NULL. You may still use Vulkan for off-screen rendering and compute work.

+

This function returns an array of names of Vulkan instance extensions required by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the list will always contain VK_KHR_surface, so if you don't require any additional extensions you can pass this list directly to the VkInstanceCreateInfo struct.

+

If Vulkan is not available on the machine, this function returns NULL and generates a GLFW_API_UNAVAILABLE error. Call glfwVulkanSupported to check whether Vulkan is at least minimally available.

+

If Vulkan is available but no set of extensions allowing window surface creation was found, this function returns NULL. You may still use Vulkan for off-screen rendering and compute work.

Parameters
@@ -177,7 +184,7 @@ Functions -

◆ glfwGetInstanceProcAddress()

+

◆ glfwGetInstanceProcAddress()

@@ -201,15 +208,15 @@ Functions
[out]countWhere to store the number of extensions in the returned array. This is set to zero if an error occurred.
-

This function returns the address of the specified Vulkan core or extension function for the specified instance. If instance is set to NULL it can return any function exported from the Vulkan loader, including at least the following functions:

+

This function returns the address of the specified Vulkan core or extension function for the specified instance. If instance is set to NULL it can return any function exported from the Vulkan loader, including at least the following functions:

  • vkEnumerateInstanceExtensionProperties
  • vkEnumerateInstanceLayerProperties
  • vkCreateInstance
  • vkGetInstanceProcAddr
-

If Vulkan is not available on the machine, this function returns NULL and generates a GLFW_API_UNAVAILABLE error. Call glfwVulkanSupported to check whether Vulkan is at least minimally available.

-

This function is equivalent to calling vkGetInstanceProcAddr with a platform-specific query of the Vulkan loader as a fallback.

+

If Vulkan is not available on the machine, this function returns NULL and generates a GLFW_API_UNAVAILABLE error. Call glfwVulkanSupported to check whether Vulkan is at least minimally available.

+

This function is equivalent to calling vkGetInstanceProcAddr with a platform-specific query of the Vulkan loader as a fallback.

Parameters
@@ -227,7 +234,7 @@ Functions -

◆ glfwGetPhysicalDevicePresentationSupport()

+

◆ glfwGetPhysicalDevicePresentationSupport()

@@ -257,8 +264,8 @@ Functions
[in]instanceThe Vulkan instance to query, or NULL to retrieve functions related to instance creation.
-

This function returns whether the specified queue family of the specified physical device supports presentation to the platform GLFW was built for.

-

If Vulkan or the required window surface creation instance extensions are not available on the machine, or if the specified instance was not created with the required extensions, this function returns GLFW_FALSE and generates a GLFW_API_UNAVAILABLE error. Call glfwVulkanSupported to check whether Vulkan is at least minimally available and glfwGetRequiredInstanceExtensions to check what instance extensions are required.

+

This function returns whether the specified queue family of the specified physical device supports presentation to the platform GLFW was built for.

+

If Vulkan or the required window surface creation instance extensions are not available on the machine, or if the specified instance was not created with the required extensions, this function returns GLFW_FALSE and generates a GLFW_API_UNAVAILABLE error. Call glfwVulkanSupported to check whether Vulkan is at least minimally available and glfwGetRequiredInstanceExtensions to check what instance extensions are required.

Parameters
@@ -277,7 +284,7 @@ Functions -

◆ glfwCreateWindowSurface()

+

◆ glfwCreateWindowSurface()

@@ -313,11 +320,11 @@ Functions
[in]instanceThe instance that the physical device belongs to.
-

This function creates a Vulkan surface for the specified window.

-

If the Vulkan loader or at least one minimally functional ICD were not found, this function returns VK_ERROR_INITIALIZATION_FAILED and generates a GLFW_API_UNAVAILABLE error. Call glfwVulkanSupported to check whether Vulkan is at least minimally available.

-

If the required window surface creation instance extensions are not available or if the specified instance was not created with these extensions enabled, this function returns VK_ERROR_EXTENSION_NOT_PRESENT and generates a GLFW_API_UNAVAILABLE error. Call glfwGetRequiredInstanceExtensions to check what instance extensions are required.

-

The window surface cannot be shared with another API so the window must have been created with the client api hint set to GLFW_NO_API otherwise it generates a GLFW_INVALID_VALUE error and returns VK_ERROR_NATIVE_WINDOW_IN_USE_KHR.

-

The window surface must be destroyed before the specified Vulkan instance. It is the responsibility of the caller to destroy the window surface. GLFW does not destroy it for you. Call vkDestroySurfaceKHR to destroy the surface.

+

This function creates a Vulkan surface for the specified window.

+

If the Vulkan loader or at least one minimally functional ICD were not found, this function returns VK_ERROR_INITIALIZATION_FAILED and generates a GLFW_API_UNAVAILABLE error. Call glfwVulkanSupported to check whether Vulkan is at least minimally available.

+

If the required window surface creation instance extensions are not available or if the specified instance was not created with these extensions enabled, this function returns VK_ERROR_EXTENSION_NOT_PRESENT and generates a GLFW_API_UNAVAILABLE error. Call glfwGetRequiredInstanceExtensions to check what instance extensions are required.

+

The window surface cannot be shared with another API so the window must have been created with the client api hint set to GLFW_NO_API otherwise it generates a GLFW_INVALID_VALUE error and returns VK_ERROR_NATIVE_WINDOW_IN_USE_KHR.

+

The window surface must be destroyed before the specified Vulkan instance. It is the responsibility of the caller to destroy the window surface. GLFW does not destroy it for you. Call vkDestroySurfaceKHR to destroy the surface.

Parameters
@@ -333,7 +340,9 @@ Functions
macOS: GLFW prefers the VK_EXT_metal_surface extension, with the VK_MVK_macos_surface extension as a fallback. The name of the selected extension, if any, is included in the array returned by glfwGetRequiredInstanceExtensions.
-macOS: This function creates and sets a CAMetalLayer instance for the window content view, which is required for MoltenVK to function.
+macOS: This function creates and sets a CAMetalLayer instance for the window content view, which is required for MoltenVK to function. +
+X11: By default GLFW prefers the VK_KHR_xcb_surface extension, with the VK_KHR_xlib_surface extension as a fallback. You can make VK_KHR_xlib_surface the preferred extension by setting the GLFW_X11_XCB_VULKAN_SURFACE init hint. The name of the selected extension, if any, is included in the array returned by glfwGetRequiredInstanceExtensions.
Thread safety
This function may be called from any thread. For synchronization details of Vulkan objects, see the Vulkan specification.
See also
Creating a Vulkan window surface
@@ -345,7 +354,7 @@ Functions diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__window.html b/src/lib/src/vendor/glfw-3.4/docs/html/group__window.html similarity index 61% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/group__window.html rename to src/lib/src/vendor/glfw-3.4/docs/html/group__window.html index 0a44b40..c797455 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/group__window.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/group__window.html @@ -4,7 +4,7 @@ - + GLFW: Window reference @@ -28,10 +28,10 @@ - + @@ -55,9 +55,16 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -69,329 +76,355 @@ $(function() {

Description

-

This is the reference documentation for window related functions and types, including creation, deletion and event polling. For more task-oriented information, see the Window guide.

+

This is the reference documentation for window related functions and types, including creation, deletion and event polling. For more task-oriented information, see the Window guide.

[in]instanceThe Vulkan instance to create the surface in.
- - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + - - + + - - + + - - + + - - + + - - + + - - + + + + + - - + + - - + + - - + + - - + + + + + + + + + +

Macros

#define GLFW_FOCUSED   0x00020001
 Input focus window hint and attribute. More...
#define GLFW_FOCUSED   0x00020001
 Input focus window hint and attribute.
 
#define GLFW_ICONIFIED   0x00020002
 Window iconification window attribute. More...
#define GLFW_ICONIFIED   0x00020002
 Window iconification window attribute.
 
#define GLFW_RESIZABLE   0x00020003
 Window resize-ability window hint and attribute. More...
#define GLFW_RESIZABLE   0x00020003
 Window resize-ability window hint and attribute.
 
#define GLFW_VISIBLE   0x00020004
 Window visibility window hint and attribute. More...
#define GLFW_VISIBLE   0x00020004
 Window visibility window hint and attribute.
 
#define GLFW_DECORATED   0x00020005
 Window decoration window hint and attribute. More...
#define GLFW_DECORATED   0x00020005
 Window decoration window hint and attribute.
 
#define GLFW_AUTO_ICONIFY   0x00020006
 Window auto-iconification window hint and attribute. More...
#define GLFW_AUTO_ICONIFY   0x00020006
 Window auto-iconification window hint and attribute.
 
#define GLFW_FLOATING   0x00020007
 Window decoration window hint and attribute. More...
#define GLFW_FLOATING   0x00020007
 Window decoration window hint and attribute.
 
#define GLFW_MAXIMIZED   0x00020008
 Window maximization window hint and attribute. More...
#define GLFW_MAXIMIZED   0x00020008
 Window maximization window hint and attribute.
 
#define GLFW_CENTER_CURSOR   0x00020009
 Cursor centering window hint. More...
#define GLFW_CENTER_CURSOR   0x00020009
 Cursor centering window hint.
 
#define GLFW_TRANSPARENT_FRAMEBUFFER   0x0002000A
 Window framebuffer transparency hint and attribute. More...
#define GLFW_TRANSPARENT_FRAMEBUFFER   0x0002000A
 Window framebuffer transparency hint and attribute.
 
#define GLFW_HOVERED   0x0002000B
 Mouse cursor hover window attribute. More...
#define GLFW_HOVERED   0x0002000B
 Mouse cursor hover window attribute.
 
#define GLFW_FOCUS_ON_SHOW   0x0002000C
 Input focus on calling show window hint and attribute. More...
#define GLFW_FOCUS_ON_SHOW   0x0002000C
 Input focus on calling show window hint and attribute.
 
#define GLFW_RED_BITS   0x00021001
 Framebuffer bit depth hint. More...
#define GLFW_MOUSE_PASSTHROUGH   0x0002000D
 Mouse input transparency window hint and attribute.
 
#define GLFW_POSITION_X   0x0002000E
 Initial position x-coordinate window hint.
 
#define GLFW_POSITION_Y   0x0002000F
 Initial position y-coordinate window hint.
 
#define GLFW_RED_BITS   0x00021001
 Framebuffer bit depth hint.
 
#define GLFW_GREEN_BITS   0x00021002
 Framebuffer bit depth hint. More...
#define GLFW_GREEN_BITS   0x00021002
 Framebuffer bit depth hint.
 
#define GLFW_BLUE_BITS   0x00021003
 Framebuffer bit depth hint. More...
#define GLFW_BLUE_BITS   0x00021003
 Framebuffer bit depth hint.
 
#define GLFW_ALPHA_BITS   0x00021004
 Framebuffer bit depth hint. More...
#define GLFW_ALPHA_BITS   0x00021004
 Framebuffer bit depth hint.
 
#define GLFW_DEPTH_BITS   0x00021005
 Framebuffer bit depth hint. More...
#define GLFW_DEPTH_BITS   0x00021005
 Framebuffer bit depth hint.
 
#define GLFW_STENCIL_BITS   0x00021006
 Framebuffer bit depth hint. More...
#define GLFW_STENCIL_BITS   0x00021006
 Framebuffer bit depth hint.
 
#define GLFW_ACCUM_RED_BITS   0x00021007
 Framebuffer bit depth hint. More...
#define GLFW_ACCUM_RED_BITS   0x00021007
 Framebuffer bit depth hint.
 
#define GLFW_ACCUM_GREEN_BITS   0x00021008
 Framebuffer bit depth hint. More...
#define GLFW_ACCUM_GREEN_BITS   0x00021008
 Framebuffer bit depth hint.
 
#define GLFW_ACCUM_BLUE_BITS   0x00021009
 Framebuffer bit depth hint. More...
#define GLFW_ACCUM_BLUE_BITS   0x00021009
 Framebuffer bit depth hint.
 
#define GLFW_ACCUM_ALPHA_BITS   0x0002100A
 Framebuffer bit depth hint. More...
#define GLFW_ACCUM_ALPHA_BITS   0x0002100A
 Framebuffer bit depth hint.
 
#define GLFW_AUX_BUFFERS   0x0002100B
 Framebuffer auxiliary buffer hint. More...
#define GLFW_AUX_BUFFERS   0x0002100B
 Framebuffer auxiliary buffer hint.
 
#define GLFW_STEREO   0x0002100C
 OpenGL stereoscopic rendering hint. More...
#define GLFW_STEREO   0x0002100C
 OpenGL stereoscopic rendering hint.
 
#define GLFW_SAMPLES   0x0002100D
 Framebuffer MSAA samples hint. More...
#define GLFW_SAMPLES   0x0002100D
 Framebuffer MSAA samples hint.
 
#define GLFW_SRGB_CAPABLE   0x0002100E
 Framebuffer sRGB hint. More...
#define GLFW_SRGB_CAPABLE   0x0002100E
 Framebuffer sRGB hint.
 
#define GLFW_REFRESH_RATE   0x0002100F
 Monitor refresh rate hint. More...
#define GLFW_REFRESH_RATE   0x0002100F
 Monitor refresh rate hint.
 
#define GLFW_DOUBLEBUFFER   0x00021010
 Framebuffer double buffering hint. More...
#define GLFW_DOUBLEBUFFER   0x00021010
 Framebuffer double buffering hint and attribute.
 
#define GLFW_CLIENT_API   0x00022001
 Context client API hint and attribute. More...
#define GLFW_CLIENT_API   0x00022001
 Context client API hint and attribute.
 
#define GLFW_CONTEXT_VERSION_MAJOR   0x00022002
 Context client API major version hint and attribute. More...
#define GLFW_CONTEXT_VERSION_MAJOR   0x00022002
 Context client API major version hint and attribute.
 
#define GLFW_CONTEXT_VERSION_MINOR   0x00022003
 Context client API minor version hint and attribute. More...
#define GLFW_CONTEXT_VERSION_MINOR   0x00022003
 Context client API minor version hint and attribute.
 
#define GLFW_CONTEXT_REVISION   0x00022004
 Context client API revision number attribute. More...
#define GLFW_CONTEXT_REVISION   0x00022004
 Context client API revision number attribute.
 
#define GLFW_CONTEXT_ROBUSTNESS   0x00022005
 Context robustness hint and attribute. More...
#define GLFW_CONTEXT_ROBUSTNESS   0x00022005
 Context robustness hint and attribute.
 
#define GLFW_OPENGL_FORWARD_COMPAT   0x00022006
 OpenGL forward-compatibility hint and attribute. More...
#define GLFW_OPENGL_FORWARD_COMPAT   0x00022006
 OpenGL forward-compatibility hint and attribute.
 
#define GLFW_OPENGL_DEBUG_CONTEXT   0x00022007
 Debug mode context hint and attribute. More...
#define GLFW_CONTEXT_DEBUG   0x00022007
 Debug mode context hint and attribute.
 
#define GLFW_OPENGL_DEBUG_CONTEXT   GLFW_CONTEXT_DEBUG
 Legacy name for compatibility.
 
#define GLFW_OPENGL_PROFILE   0x00022008
 OpenGL profile hint and attribute. More...
#define GLFW_OPENGL_PROFILE   0x00022008
 OpenGL profile hint and attribute.
 
#define GLFW_CONTEXT_RELEASE_BEHAVIOR   0x00022009
 Context flush-on-release hint and attribute. More...
#define GLFW_CONTEXT_RELEASE_BEHAVIOR   0x00022009
 Context flush-on-release hint and attribute.
 
#define GLFW_CONTEXT_NO_ERROR   0x0002200A
 Context error suppression hint and attribute. More...
#define GLFW_CONTEXT_NO_ERROR   0x0002200A
 Context error suppression hint and attribute.
 
#define GLFW_CONTEXT_CREATION_API   0x0002200B
 Context creation API hint and attribute. More...
#define GLFW_CONTEXT_CREATION_API   0x0002200B
 Context creation API hint and attribute.
 
#define GLFW_SCALE_TO_MONITOR   0x0002200C
 Window content area scaling window window hint. More...
#define GLFW_SCALE_TO_MONITOR   0x0002200C
 Window content area scaling window window hint.
 
#define GLFW_COCOA_RETINA_FRAMEBUFFER   0x00023001
 macOS specific window hint. More...
#define GLFW_SCALE_FRAMEBUFFER   0x0002200D
 Window framebuffer scaling window hint.
 
#define GLFW_COCOA_RETINA_FRAMEBUFFER   0x00023001
 Legacy name for compatibility.
 
#define GLFW_COCOA_FRAME_NAME   0x00023002
 macOS specific window hint. More...
#define GLFW_COCOA_FRAME_NAME   0x00023002
 macOS specific window hint.
 
#define GLFW_COCOA_GRAPHICS_SWITCHING   0x00023003
 macOS specific window hint. More...
#define GLFW_COCOA_GRAPHICS_SWITCHING   0x00023003
 macOS specific window hint.
 
#define GLFW_X11_CLASS_NAME   0x00024001
 X11 specific window hint. More...
#define GLFW_X11_CLASS_NAME   0x00024001
 X11 specific window hint.
 
#define GLFW_X11_INSTANCE_NAME   0x00024002
 X11 specific window hint. More...
#define GLFW_X11_INSTANCE_NAME   0x00024002
 X11 specific window hint.
 
#define GLFW_WIN32_KEYBOARD_MENU   0x00025001
 
#define GLFW_WIN32_SHOWDEFAULT   0x00025002
 Win32 specific window hint.
 
#define GLFW_WAYLAND_APP_ID   0x00026001
 Wayland specific window hint.
 
- - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +

Typedefs

typedef struct GLFWwindow GLFWwindow
 Opaque window object. More...
typedef struct GLFWwindow GLFWwindow
 Opaque window object.
 
typedef void(* GLFWwindowposfun) (GLFWwindow *window, int xpos, int ypos)
 The function pointer type for window position callbacks. More...
typedef void(* GLFWwindowposfun) (GLFWwindow *window, int xpos, int ypos)
 The function pointer type for window position callbacks.
 
typedef void(* GLFWwindowsizefun) (GLFWwindow *window, int width, int height)
 The function pointer type for window size callbacks. More...
typedef void(* GLFWwindowsizefun) (GLFWwindow *window, int width, int height)
 The function pointer type for window size callbacks.
 
typedef void(* GLFWwindowclosefun) (GLFWwindow *window)
 The function pointer type for window close callbacks. More...
typedef void(* GLFWwindowclosefun) (GLFWwindow *window)
 The function pointer type for window close callbacks.
 
typedef void(* GLFWwindowrefreshfun) (GLFWwindow *window)
 The function pointer type for window content refresh callbacks. More...
typedef void(* GLFWwindowrefreshfun) (GLFWwindow *window)
 The function pointer type for window content refresh callbacks.
 
typedef void(* GLFWwindowfocusfun) (GLFWwindow *window, int focused)
 The function pointer type for window focus callbacks. More...
typedef void(* GLFWwindowfocusfun) (GLFWwindow *window, int focused)
 The function pointer type for window focus callbacks.
 
typedef void(* GLFWwindowiconifyfun) (GLFWwindow *window, int iconified)
 The function pointer type for window iconify callbacks. More...
typedef void(* GLFWwindowiconifyfun) (GLFWwindow *window, int iconified)
 The function pointer type for window iconify callbacks.
 
typedef void(* GLFWwindowmaximizefun) (GLFWwindow *window, int maximized)
 The function pointer type for window maximize callbacks. More...
typedef void(* GLFWwindowmaximizefun) (GLFWwindow *window, int maximized)
 The function pointer type for window maximize callbacks.
 
typedef void(* GLFWframebuffersizefun) (GLFWwindow *window, int width, int height)
 The function pointer type for framebuffer size callbacks. More...
typedef void(* GLFWframebuffersizefun) (GLFWwindow *window, int width, int height)
 The function pointer type for framebuffer size callbacks.
 
typedef void(* GLFWwindowcontentscalefun) (GLFWwindow *window, float xscale, float yscale)
 The function pointer type for window content scale callbacks. More...
typedef void(* GLFWwindowcontentscalefun) (GLFWwindow *window, float xscale, float yscale)
 The function pointer type for window content scale callbacks.
 
typedef struct GLFWimage GLFWimage
 Image data. More...
typedef struct GLFWimage GLFWimage
 Image data.
 
- - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +

Functions

void glfwDefaultWindowHints (void)
 Resets all window hints to their default values. More...
void glfwDefaultWindowHints (void)
 Resets all window hints to their default values.
 
void glfwWindowHint (int hint, int value)
 Sets the specified window hint to the desired value. More...
void glfwWindowHint (int hint, int value)
 Sets the specified window hint to the desired value.
 
void glfwWindowHintString (int hint, const char *value)
 Sets the specified window hint to the desired value. More...
void glfwWindowHintString (int hint, const char *value)
 Sets the specified window hint to the desired value.
 
GLFWwindowglfwCreateWindow (int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
 Creates a window and its associated context. More...
GLFWwindowglfwCreateWindow (int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
 Creates a window and its associated context.
 
void glfwDestroyWindow (GLFWwindow *window)
 Destroys the specified window and its context. More...
void glfwDestroyWindow (GLFWwindow *window)
 Destroys the specified window and its context.
 
int glfwWindowShouldClose (GLFWwindow *window)
 Checks the close flag of the specified window. More...
int glfwWindowShouldClose (GLFWwindow *window)
 Checks the close flag of the specified window.
 
void glfwSetWindowShouldClose (GLFWwindow *window, int value)
 Sets the close flag of the specified window. More...
void glfwSetWindowShouldClose (GLFWwindow *window, int value)
 Sets the close flag of the specified window.
 
void glfwSetWindowTitle (GLFWwindow *window, const char *title)
 Sets the title of the specified window. More...
const char * glfwGetWindowTitle (GLFWwindow *window)
 Returns the title of the specified window.
 
void glfwSetWindowTitle (GLFWwindow *window, const char *title)
 Sets the title of the specified window.
 
void glfwSetWindowIcon (GLFWwindow *window, int count, const GLFWimage *images)
 Sets the icon for the specified window. More...
void glfwSetWindowIcon (GLFWwindow *window, int count, const GLFWimage *images)
 Sets the icon for the specified window.
 
void glfwGetWindowPos (GLFWwindow *window, int *xpos, int *ypos)
 Retrieves the position of the content area of the specified window. More...
void glfwGetWindowPos (GLFWwindow *window, int *xpos, int *ypos)
 Retrieves the position of the content area of the specified window.
 
void glfwSetWindowPos (GLFWwindow *window, int xpos, int ypos)
 Sets the position of the content area of the specified window. More...
void glfwSetWindowPos (GLFWwindow *window, int xpos, int ypos)
 Sets the position of the content area of the specified window.
 
void glfwGetWindowSize (GLFWwindow *window, int *width, int *height)
 Retrieves the size of the content area of the specified window. More...
void glfwGetWindowSize (GLFWwindow *window, int *width, int *height)
 Retrieves the size of the content area of the specified window.
 
void glfwSetWindowSizeLimits (GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)
 Sets the size limits of the specified window. More...
void glfwSetWindowSizeLimits (GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)
 Sets the size limits of the specified window.
 
void glfwSetWindowAspectRatio (GLFWwindow *window, int numer, int denom)
 Sets the aspect ratio of the specified window. More...
void glfwSetWindowAspectRatio (GLFWwindow *window, int numer, int denom)
 Sets the aspect ratio of the specified window.
 
void glfwSetWindowSize (GLFWwindow *window, int width, int height)
 Sets the size of the content area of the specified window. More...
void glfwSetWindowSize (GLFWwindow *window, int width, int height)
 Sets the size of the content area of the specified window.
 
void glfwGetFramebufferSize (GLFWwindow *window, int *width, int *height)
 Retrieves the size of the framebuffer of the specified window. More...
void glfwGetFramebufferSize (GLFWwindow *window, int *width, int *height)
 Retrieves the size of the framebuffer of the specified window.
 
void glfwGetWindowFrameSize (GLFWwindow *window, int *left, int *top, int *right, int *bottom)
 Retrieves the size of the frame of the window. More...
void glfwGetWindowFrameSize (GLFWwindow *window, int *left, int *top, int *right, int *bottom)
 Retrieves the size of the frame of the window.
 
void glfwGetWindowContentScale (GLFWwindow *window, float *xscale, float *yscale)
 Retrieves the content scale for the specified window. More...
void glfwGetWindowContentScale (GLFWwindow *window, float *xscale, float *yscale)
 Retrieves the content scale for the specified window.
 
float glfwGetWindowOpacity (GLFWwindow *window)
 Returns the opacity of the whole window. More...
float glfwGetWindowOpacity (GLFWwindow *window)
 Returns the opacity of the whole window.
 
void glfwSetWindowOpacity (GLFWwindow *window, float opacity)
 Sets the opacity of the whole window. More...
void glfwSetWindowOpacity (GLFWwindow *window, float opacity)
 Sets the opacity of the whole window.
 
void glfwIconifyWindow (GLFWwindow *window)
 Iconifies the specified window. More...
void glfwIconifyWindow (GLFWwindow *window)
 Iconifies the specified window.
 
void glfwRestoreWindow (GLFWwindow *window)
 Restores the specified window. More...
void glfwRestoreWindow (GLFWwindow *window)
 Restores the specified window.
 
void glfwMaximizeWindow (GLFWwindow *window)
 Maximizes the specified window. More...
void glfwMaximizeWindow (GLFWwindow *window)
 Maximizes the specified window.
 
void glfwShowWindow (GLFWwindow *window)
 Makes the specified window visible. More...
void glfwShowWindow (GLFWwindow *window)
 Makes the specified window visible.
 
void glfwHideWindow (GLFWwindow *window)
 Hides the specified window. More...
void glfwHideWindow (GLFWwindow *window)
 Hides the specified window.
 
void glfwFocusWindow (GLFWwindow *window)
 Brings the specified window to front and sets input focus. More...
void glfwFocusWindow (GLFWwindow *window)
 Brings the specified window to front and sets input focus.
 
void glfwRequestWindowAttention (GLFWwindow *window)
 Requests user attention to the specified window. More...
void glfwRequestWindowAttention (GLFWwindow *window)
 Requests user attention to the specified window.
 
GLFWmonitorglfwGetWindowMonitor (GLFWwindow *window)
 Returns the monitor that the window uses for full screen mode. More...
GLFWmonitorglfwGetWindowMonitor (GLFWwindow *window)
 Returns the monitor that the window uses for full screen mode.
 
void glfwSetWindowMonitor (GLFWwindow *window, GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)
 Sets the mode, monitor, video mode and placement of a window. More...
void glfwSetWindowMonitor (GLFWwindow *window, GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)
 Sets the mode, monitor, video mode and placement of a window.
 
int glfwGetWindowAttrib (GLFWwindow *window, int attrib)
 Returns an attribute of the specified window. More...
int glfwGetWindowAttrib (GLFWwindow *window, int attrib)
 Returns an attribute of the specified window.
 
void glfwSetWindowAttrib (GLFWwindow *window, int attrib, int value)
 Sets an attribute of the specified window. More...
void glfwSetWindowAttrib (GLFWwindow *window, int attrib, int value)
 Sets an attribute of the specified window.
 
void glfwSetWindowUserPointer (GLFWwindow *window, void *pointer)
 Sets the user pointer of the specified window. More...
void glfwSetWindowUserPointer (GLFWwindow *window, void *pointer)
 Sets the user pointer of the specified window.
 
void * glfwGetWindowUserPointer (GLFWwindow *window)
 Returns the user pointer of the specified window. More...
void * glfwGetWindowUserPointer (GLFWwindow *window)
 Returns the user pointer of the specified window.
 
GLFWwindowposfun glfwSetWindowPosCallback (GLFWwindow *window, GLFWwindowposfun callback)
 Sets the position callback for the specified window. More...
GLFWwindowposfun glfwSetWindowPosCallback (GLFWwindow *window, GLFWwindowposfun callback)
 Sets the position callback for the specified window.
 
GLFWwindowsizefun glfwSetWindowSizeCallback (GLFWwindow *window, GLFWwindowsizefun callback)
 Sets the size callback for the specified window. More...
GLFWwindowsizefun glfwSetWindowSizeCallback (GLFWwindow *window, GLFWwindowsizefun callback)
 Sets the size callback for the specified window.
 
GLFWwindowclosefun glfwSetWindowCloseCallback (GLFWwindow *window, GLFWwindowclosefun callback)
 Sets the close callback for the specified window. More...
GLFWwindowclosefun glfwSetWindowCloseCallback (GLFWwindow *window, GLFWwindowclosefun callback)
 Sets the close callback for the specified window.
 
GLFWwindowrefreshfun glfwSetWindowRefreshCallback (GLFWwindow *window, GLFWwindowrefreshfun callback)
 Sets the refresh callback for the specified window. More...
GLFWwindowrefreshfun glfwSetWindowRefreshCallback (GLFWwindow *window, GLFWwindowrefreshfun callback)
 Sets the refresh callback for the specified window.
 
GLFWwindowfocusfun glfwSetWindowFocusCallback (GLFWwindow *window, GLFWwindowfocusfun callback)
 Sets the focus callback for the specified window. More...
GLFWwindowfocusfun glfwSetWindowFocusCallback (GLFWwindow *window, GLFWwindowfocusfun callback)
 Sets the focus callback for the specified window.
 
GLFWwindowiconifyfun glfwSetWindowIconifyCallback (GLFWwindow *window, GLFWwindowiconifyfun callback)
 Sets the iconify callback for the specified window. More...
GLFWwindowiconifyfun glfwSetWindowIconifyCallback (GLFWwindow *window, GLFWwindowiconifyfun callback)
 Sets the iconify callback for the specified window.
 
GLFWwindowmaximizefun glfwSetWindowMaximizeCallback (GLFWwindow *window, GLFWwindowmaximizefun callback)
 Sets the maximize callback for the specified window. More...
GLFWwindowmaximizefun glfwSetWindowMaximizeCallback (GLFWwindow *window, GLFWwindowmaximizefun callback)
 Sets the maximize callback for the specified window.
 
GLFWframebuffersizefun glfwSetFramebufferSizeCallback (GLFWwindow *window, GLFWframebuffersizefun callback)
 Sets the framebuffer resize callback for the specified window. More...
GLFWframebuffersizefun glfwSetFramebufferSizeCallback (GLFWwindow *window, GLFWframebuffersizefun callback)
 Sets the framebuffer resize callback for the specified window.
 
GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback (GLFWwindow *window, GLFWwindowcontentscalefun callback)
 Sets the window content scale callback for the specified window. More...
GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback (GLFWwindow *window, GLFWwindowcontentscalefun callback)
 Sets the window content scale callback for the specified window.
 
void glfwPollEvents (void)
 Processes all pending events. More...
void glfwPollEvents (void)
 Processes all pending events.
 
void glfwWaitEvents (void)
 Waits until events are queued and processes them. More...
void glfwWaitEvents (void)
 Waits until events are queued and processes them.
 
void glfwWaitEventsTimeout (double timeout)
 Waits with timeout until events are queued and processes them. More...
void glfwWaitEventsTimeout (double timeout)
 Waits with timeout until events are queued and processes them.
 
void glfwPostEmptyEvent (void)
 Posts an empty event to the event queue. More...
void glfwPostEmptyEvent (void)
 Posts an empty event to the event queue.
 
void glfwSwapBuffers (GLFWwindow *window)
 Swaps the front and back buffers of the specified window. More...
void glfwSwapBuffers (GLFWwindow *window)
 Swaps the front and back buffers of the specified window.
 

Macro Definition Documentation

-

◆ GLFW_FOCUSED

+

◆ GLFW_FOCUSED

@@ -401,12 +434,12 @@ Functions
-

Input focus window hint or window attribute.

+

Input focus window hint or window attribute.

-

◆ GLFW_ICONIFIED

+

◆ GLFW_ICONIFIED

@@ -416,12 +449,12 @@ Functions
-

Window iconification window attribute.

+

Window iconification window attribute.

-

◆ GLFW_RESIZABLE

+

◆ GLFW_RESIZABLE

@@ -431,12 +464,12 @@ Functions
-

Window resize-ability window hint and window attribute.

+

Window resize-ability window hint and window attribute.

-

◆ GLFW_VISIBLE

+

◆ GLFW_VISIBLE

@@ -446,12 +479,12 @@ Functions
-

Window visibility window hint and window attribute.

+

Window visibility window hint and window attribute.

-

◆ GLFW_DECORATED

+

◆ GLFW_DECORATED

@@ -461,12 +494,12 @@ Functions
-

Window decoration window hint and window attribute.

+

Window decoration window hint and window attribute.

-

◆ GLFW_AUTO_ICONIFY

+

◆ GLFW_AUTO_ICONIFY

@@ -476,12 +509,12 @@ Functions
-

Window auto-iconification window hint and window attribute.

+

Window auto-iconification window hint and window attribute.

-

◆ GLFW_FLOATING

+

◆ GLFW_FLOATING

@@ -491,12 +524,12 @@ Functions
-

Window decoration window hint and window attribute.

+

Window decoration window hint and window attribute.

-

◆ GLFW_MAXIMIZED

+

◆ GLFW_MAXIMIZED

@@ -506,12 +539,12 @@ Functions
-

Window maximization window hint and window attribute.

+

Window maximization window hint and window attribute.

-

◆ GLFW_CENTER_CURSOR

+

◆ GLFW_CENTER_CURSOR

@@ -521,12 +554,12 @@ Functions
-

Cursor centering window hint.

+

Cursor centering window hint.

-

◆ GLFW_TRANSPARENT_FRAMEBUFFER

+

◆ GLFW_TRANSPARENT_FRAMEBUFFER

@@ -536,12 +569,12 @@ Functions
-

Window framebuffer transparency window hint and window attribute.

+

Window framebuffer transparency window hint and window attribute.

-

◆ GLFW_HOVERED

+

◆ GLFW_HOVERED

@@ -551,12 +584,12 @@ Functions
-

Mouse cursor hover window attribute.

+

Mouse cursor hover window attribute.

-

◆ GLFW_FOCUS_ON_SHOW

+

◆ GLFW_FOCUS_ON_SHOW

@@ -566,12 +599,57 @@ Functions
-

Input focus window hint or window attribute.

+

Input focus window hint or window attribute.

+ +
+
+ +

◆ GLFW_MOUSE_PASSTHROUGH

+ +
+
+ + + + +
#define GLFW_MOUSE_PASSTHROUGH   0x0002000D
+
+

Mouse input transparency window hint or window attribute.

+ +
+
+ +

◆ GLFW_POSITION_X

+ +
+
+ + + + +
#define GLFW_POSITION_X   0x0002000E
+
+

Initial position x-coordinate window hint.

+ +
+
+ +

◆ GLFW_POSITION_Y

+ +
+
+ + + + +
#define GLFW_POSITION_Y   0x0002000F
+
+

Initial position y-coordinate window hint.

-

◆ GLFW_RED_BITS

+

◆ GLFW_RED_BITS

@@ -581,12 +659,12 @@ Functions
-

Framebuffer bit depth hint.

+

Framebuffer bit depth hint.

-

◆ GLFW_GREEN_BITS

+

◆ GLFW_GREEN_BITS

@@ -596,12 +674,12 @@ Functions
-

Framebuffer bit depth hint.

+

Framebuffer bit depth hint.

-

◆ GLFW_BLUE_BITS

+

◆ GLFW_BLUE_BITS

@@ -611,12 +689,12 @@ Functions
-

Framebuffer bit depth hint.

+

Framebuffer bit depth hint.

-

◆ GLFW_ALPHA_BITS

+

◆ GLFW_ALPHA_BITS

@@ -626,12 +704,12 @@ Functions
-

Framebuffer bit depth hint.

+

Framebuffer bit depth hint.

-

◆ GLFW_DEPTH_BITS

+

◆ GLFW_DEPTH_BITS

@@ -641,12 +719,12 @@ Functions
-

Framebuffer bit depth hint.

+

Framebuffer bit depth hint.

-

◆ GLFW_STENCIL_BITS

+

◆ GLFW_STENCIL_BITS

@@ -656,12 +734,12 @@ Functions
-

Framebuffer bit depth hint.

+

Framebuffer bit depth hint.

-

◆ GLFW_ACCUM_RED_BITS

+

◆ GLFW_ACCUM_RED_BITS

@@ -671,12 +749,12 @@ Functions
-

Framebuffer bit depth hint.

+

Framebuffer bit depth hint.

-

◆ GLFW_ACCUM_GREEN_BITS

+

◆ GLFW_ACCUM_GREEN_BITS

@@ -686,12 +764,12 @@ Functions
-

Framebuffer bit depth hint.

+

Framebuffer bit depth hint.

-

◆ GLFW_ACCUM_BLUE_BITS

+

◆ GLFW_ACCUM_BLUE_BITS

@@ -701,12 +779,12 @@ Functions
-

Framebuffer bit depth hint.

+

Framebuffer bit depth hint.

-

◆ GLFW_ACCUM_ALPHA_BITS

+

◆ GLFW_ACCUM_ALPHA_BITS

@@ -716,12 +794,12 @@ Functions
-

Framebuffer bit depth hint.

+

Framebuffer bit depth hint.

-

◆ GLFW_AUX_BUFFERS

+

◆ GLFW_AUX_BUFFERS

@@ -731,12 +809,12 @@ Functions
-

Framebuffer auxiliary buffer hint.

+

Framebuffer auxiliary buffer hint.

-

◆ GLFW_STEREO

+

◆ GLFW_STEREO

@@ -746,12 +824,12 @@ Functions
-

OpenGL stereoscopic rendering hint.

+

OpenGL stereoscopic rendering hint.

-

◆ GLFW_SAMPLES

+

◆ GLFW_SAMPLES

@@ -761,12 +839,12 @@ Functions
-

Framebuffer MSAA samples hint.

+

Framebuffer MSAA samples hint.

-

◆ GLFW_SRGB_CAPABLE

+

◆ GLFW_SRGB_CAPABLE

@@ -776,12 +854,12 @@ Functions
-

Framebuffer sRGB hint.

+

Framebuffer sRGB hint.

-

◆ GLFW_REFRESH_RATE

+

◆ GLFW_REFRESH_RATE

@@ -791,12 +869,12 @@ Functions
-

Monitor refresh rate hint.

+

Monitor refresh rate hint.

-

◆ GLFW_DOUBLEBUFFER

+

◆ GLFW_DOUBLEBUFFER

@@ -806,12 +884,12 @@ Functions
-

Framebuffer double buffering hint.

+

Framebuffer double buffering hint and attribute.

-

◆ GLFW_CLIENT_API

+

◆ GLFW_CLIENT_API

@@ -821,12 +899,12 @@ Functions
-

Context client API hint and attribute.

+

Context client API hint and attribute.

-

◆ GLFW_CONTEXT_VERSION_MAJOR

+

◆ GLFW_CONTEXT_VERSION_MAJOR

@@ -836,12 +914,12 @@ Functions
-

Context client API major version hint and attribute.

+

Context client API major version hint and attribute.

-

◆ GLFW_CONTEXT_VERSION_MINOR

+

◆ GLFW_CONTEXT_VERSION_MINOR

@@ -851,12 +929,12 @@ Functions
-

Context client API minor version hint and attribute.

+

Context client API minor version hint and attribute.

-

◆ GLFW_CONTEXT_REVISION

+

◆ GLFW_CONTEXT_REVISION

@@ -866,12 +944,12 @@ Functions
-

Context client API revision number attribute.

+

Context client API revision number attribute.

-

◆ GLFW_CONTEXT_ROBUSTNESS

+

◆ GLFW_CONTEXT_ROBUSTNESS

@@ -881,12 +959,12 @@ Functions
-

Context client API revision number hint and attribute.

+

Context client API revision number hint and attribute.

-

◆ GLFW_OPENGL_FORWARD_COMPAT

+

◆ GLFW_OPENGL_FORWARD_COMPAT

@@ -896,27 +974,42 @@ Functions
-

OpenGL forward-compatibility hint and attribute.

+

OpenGL forward-compatibility hint and attribute.

- -

◆ GLFW_OPENGL_DEBUG_CONTEXT

+ +

◆ GLFW_CONTEXT_DEBUG

- +
#define GLFW_OPENGL_DEBUG_CONTEXT   0x00022007#define GLFW_CONTEXT_DEBUG   0x00022007
-

Debug mode context hint and attribute.

+

Debug mode context hint and attribute.

+ +
+
+ +

◆ GLFW_OPENGL_DEBUG_CONTEXT

+ +
+
+ + + + +
#define GLFW_OPENGL_DEBUG_CONTEXT   GLFW_CONTEXT_DEBUG
+
+

This is an alias for compatibility with earlier versions.

-

◆ GLFW_OPENGL_PROFILE

+

◆ GLFW_OPENGL_PROFILE

@@ -926,12 +1019,12 @@ Functions
-

OpenGL profile hint and attribute.

+

OpenGL profile hint and attribute.

-

◆ GLFW_CONTEXT_RELEASE_BEHAVIOR

+

◆ GLFW_CONTEXT_RELEASE_BEHAVIOR

@@ -941,12 +1034,12 @@ Functions
-

Context flush-on-release hint and attribute.

+

Context flush-on-release hint and attribute.

-

◆ GLFW_CONTEXT_NO_ERROR

+

◆ GLFW_CONTEXT_NO_ERROR

@@ -956,12 +1049,12 @@ Functions
-

Context error suppression hint and attribute.

+

Context error suppression hint and attribute.

-

◆ GLFW_CONTEXT_CREATION_API

+

◆ GLFW_CONTEXT_CREATION_API

@@ -971,12 +1064,12 @@ Functions
-

Context creation API hint and attribute.

+

Context creation API hint and attribute.

-

◆ GLFW_SCALE_TO_MONITOR

+

◆ GLFW_SCALE_TO_MONITOR

@@ -987,10 +1080,24 @@ Functions
+
+
+ +

◆ GLFW_SCALE_FRAMEBUFFER

+ +
+
+ + + + +
#define GLFW_SCALE_FRAMEBUFFER   0x0002200D
+
+
-

◆ GLFW_COCOA_RETINA_FRAMEBUFFER

+

◆ GLFW_COCOA_RETINA_FRAMEBUFFER

@@ -1000,11 +1107,12 @@ Functions
+

This is an alias for the GLFW_SCALE_FRAMEBUFFER window hint for compatibility with earlier versions.

-

◆ GLFW_COCOA_FRAME_NAME

+

◆ GLFW_COCOA_FRAME_NAME

@@ -1018,7 +1126,7 @@ Functions
-

◆ GLFW_COCOA_GRAPHICS_SWITCHING

+

◆ GLFW_COCOA_GRAPHICS_SWITCHING

@@ -1032,7 +1140,7 @@ Functions
-

◆ GLFW_X11_CLASS_NAME

+

◆ GLFW_X11_CLASS_NAME

@@ -1046,7 +1154,7 @@ Functions
-

◆ GLFW_X11_INSTANCE_NAME

+

◆ GLFW_X11_INSTANCE_NAME

@@ -1057,11 +1165,54 @@ Functions
+
+
+ +

◆ GLFW_WIN32_KEYBOARD_MENU

+ +
+
+ + + + +
#define GLFW_WIN32_KEYBOARD_MENU   0x00025001
+
+ +
+
+ +

◆ GLFW_WIN32_SHOWDEFAULT

+ +
+
+ + + + +
#define GLFW_WIN32_SHOWDEFAULT   0x00025002
+
+ +
+
+ +

◆ GLFW_WAYLAND_APP_ID

+ +
+
+ + + + +
#define GLFW_WAYLAND_APP_ID   0x00026001
+
+

Allows specification of the Wayland app_id.

+

Typedef Documentation

-

◆ GLFWwindow

+

◆ GLFWwindow

@@ -1071,14 +1222,14 @@ Functions
-

Opaque window object.

+

Opaque window object.

See also
Window objects
Since
Added in version 3.0.
-

◆ GLFWwindowposfun

+

◆ GLFWwindowposfun

@@ -1088,8 +1239,8 @@ Functions
-

This is the function pointer type for window position callbacks. A window position callback function has the following signature:

void callback_name(GLFWwindow* window, int xpos, int ypos)
-
struct GLFWwindow GLFWwindow
Opaque window object.
Definition: glfw3.h:1185
+

This is the function pointer type for window position callbacks. A window position callback function has the following signature:

void callback_name(GLFWwindow* window, int xpos, int ypos)
+
struct GLFWwindow GLFWwindow
Opaque window object.
Definition glfw3.h:1403
Parameters
@@ -1106,7 +1257,7 @@ Functions -

◆ GLFWwindowsizefun

+

◆ GLFWwindowsizefun

@@ -1116,7 +1267,7 @@ Functions
[in]windowThe window that was moved.
-

This is the function pointer type for window size callbacks. A window size callback function has the following signature:

void callback_name(GLFWwindow* window, int width, int height)
+

This is the function pointer type for window size callbacks. A window size callback function has the following signature:

void callback_name(GLFWwindow* window, int width, int height)
Parameters
@@ -1133,7 +1284,7 @@ Functions -

◆ GLFWwindowclosefun

+

◆ GLFWwindowclosefun

@@ -1143,7 +1294,7 @@ Functions
[in]windowThe window that was resized.
-

This is the function pointer type for window close callbacks. A window close callback function has the following signature:

void function_name(GLFWwindow* window)
+

This is the function pointer type for window close callbacks. A window close callback function has the following signature:

void function_name(GLFWwindow* window)
Parameters
@@ -1158,7 +1309,7 @@ Functions -

◆ GLFWwindowrefreshfun

+

◆ GLFWwindowrefreshfun

@@ -1168,7 +1319,7 @@ Functions
[in]windowThe window that the user attempted to close.
-

This is the function pointer type for window content refresh callbacks. A window content refresh callback function has the following signature:

void function_name(GLFWwindow* window);
+

This is the function pointer type for window content refresh callbacks. A window content refresh callback function has the following signature:

void function_name(GLFWwindow* window);
Parameters
@@ -1183,7 +1334,7 @@ Functions -

◆ GLFWwindowfocusfun

+

◆ GLFWwindowfocusfun

@@ -1193,7 +1344,7 @@ Functions
[in]windowThe window whose content needs to be refreshed.
-

This is the function pointer type for window focus callbacks. A window focus callback function has the following signature:

void function_name(GLFWwindow* window, int focused)
+

This is the function pointer type for window focus callbacks. A window focus callback function has the following signature:

void function_name(GLFWwindow* window, int focused)
Parameters
@@ -1209,7 +1360,7 @@ Functions -

◆ GLFWwindowiconifyfun

+

◆ GLFWwindowiconifyfun

@@ -1219,7 +1370,7 @@ Functions
[in]windowThe window that gained or lost input focus.
-

This is the function pointer type for window iconify callbacks. A window iconify callback function has the following signature:

void function_name(GLFWwindow* window, int iconified)
+

This is the function pointer type for window iconify callbacks. A window iconify callback function has the following signature:

void function_name(GLFWwindow* window, int iconified)
Parameters
@@ -1235,7 +1386,7 @@ Functions -

◆ GLFWwindowmaximizefun

+

◆ GLFWwindowmaximizefun

@@ -1245,7 +1396,7 @@ Functions
[in]windowThe window that was iconified or restored.
-

This is the function pointer type for window maximize callbacks. A window maximize callback function has the following signature:

void function_name(GLFWwindow* window, int maximized)
+

This is the function pointer type for window maximize callbacks. A window maximize callback function has the following signature:

void function_name(GLFWwindow* window, int maximized)
Parameters
@@ -1261,7 +1412,7 @@ Functions -

◆ GLFWframebuffersizefun

+

◆ GLFWframebuffersizefun

@@ -1271,7 +1422,7 @@ Functions
[in]windowThe window that was maximized or restored.
-

This is the function pointer type for framebuffer size callbacks. A framebuffer size callback function has the following signature:

void function_name(GLFWwindow* window, int width, int height)
+

This is the function pointer type for framebuffer size callbacks. A framebuffer size callback function has the following signature:

void function_name(GLFWwindow* window, int width, int height)
Parameters
@@ -1288,7 +1439,7 @@ Functions -

◆ GLFWwindowcontentscalefun

+

◆ GLFWwindowcontentscalefun

@@ -1298,7 +1449,7 @@ Functions
[in]windowThe window whose framebuffer was resized.
-

This is the function pointer type for window content scale callbacks. A window content scale callback function has the following signature:

void function_name(GLFWwindow* window, float xscale, float yscale)
+

This is the function pointer type for window content scale callbacks. A window content scale callback function has the following signature:

void function_name(GLFWwindow* window, float xscale, float yscale)
Parameters
@@ -1315,17 +1466,17 @@ Functions -

◆ GLFWimage

+

◆ GLFWimage

[in]windowThe window whose content scale changed.
- +
typedef struct GLFWimage GLFWimagetypedef struct GLFWimage GLFWimage
-

This describes a single 2D image. See the documentation for each related function what the expected pixel format is.

+

This describes a single 2D image. See the documentation for each related function what the expected pixel format is.

See also
Custom cursor creation
Window icon
@@ -1335,7 +1486,7 @@ Functions

Function Documentation

-

◆ glfwDefaultWindowHints()

+

◆ glfwDefaultWindowHints()

@@ -1349,7 +1500,7 @@ Functions
-

This function resets all window hints to their default values.

+

This function resets all window hints to their default values.

Errors
Possible errors include GLFW_NOT_INITIALIZED.
Thread safety
This function must only be called from the main thread.
See also
Window creation hints
@@ -1362,7 +1513,7 @@ Functions
-

◆ glfwWindowHint()

+

◆ glfwWindowHint()

@@ -1386,10 +1537,10 @@ Functions
-

This function sets hints for the next call to glfwCreateWindow. The hints, once set, retain their values until changed by a call to this function or glfwDefaultWindowHints, or until the library is terminated.

-

Only integer value hints can be set with this function. String value hints are set with glfwWindowHintString.

-

This function does not check whether the specified hint values are valid. If you set hints to invalid values this will instead be reported by the next call to glfwCreateWindow.

-

Some hints are platform specific. These may be set on any platform but they will only affect their specific platform. Other platforms will ignore them. Setting these hints requires no platform specific headers or functions.

+

This function sets hints for the next call to glfwCreateWindow. The hints, once set, retain their values until changed by a call to this function or glfwDefaultWindowHints, or until the library is terminated.

+

Only integer value hints can be set with this function. String value hints are set with glfwWindowHintString.

+

This function does not check whether the specified hint values are valid. If you set hints to invalid values this will instead be reported by the next call to glfwCreateWindow.

+

Some hints are platform specific. These may be set on any platform but they will only affect their specific platform. Other platforms will ignore them. Setting these hints requires no platform specific headers or functions.

Parameters
@@ -1409,7 +1560,7 @@ Functions -

◆ glfwWindowHintString()

+

◆ glfwWindowHintString()

@@ -1433,10 +1584,10 @@ Functions
[in]hintThe window hint to set.
-

This function sets hints for the next call to glfwCreateWindow. The hints, once set, retain their values until changed by a call to this function or glfwDefaultWindowHints, or until the library is terminated.

-

Only string type hints can be set with this function. Integer value hints are set with glfwWindowHint.

-

This function does not check whether the specified hint values are valid. If you set hints to invalid values this will instead be reported by the next call to glfwCreateWindow.

-

Some hints are platform specific. These may be set on any platform but they will only affect their specific platform. Other platforms will ignore them. Setting these hints requires no platform specific headers or functions.

+

This function sets hints for the next call to glfwCreateWindow. The hints, once set, retain their values until changed by a call to this function or glfwDefaultWindowHints, or until the library is terminated.

+

Only string type hints can be set with this function. Integer value hints are set with glfwWindowHint.

+

This function does not check whether the specified hint values are valid. If you set hints to invalid values this will instead be reported by the next call to glfwCreateWindow.

+

Some hints are platform specific. These may be set on any platform but they will only affect their specific platform. Other platforms will ignore them. Setting these hints requires no platform specific headers or functions.

Parameters
@@ -1457,7 +1608,7 @@ Functions -

◆ glfwCreateWindow()

+

◆ glfwCreateWindow()

@@ -1499,16 +1650,16 @@ Functions
[in]hintThe window hint to set.
-

This function creates a window and its associated OpenGL or OpenGL ES context. Most of the options controlling how the window and its context should be created are specified with window hints.

-

Successful creation does not change which context is current. Before you can use the newly created context, you need to make it current. For information about the share parameter, see Context object sharing.

-

The created window, framebuffer and context may differ from what you requested, as not all parameters and hints are hard constraints. This includes the size of the window, especially for full screen windows. To query the actual attributes of the created window, framebuffer and context, see glfwGetWindowAttrib, glfwGetWindowSize and glfwGetFramebufferSize.

-

To create a full screen window, you need to specify the monitor the window will cover. If no monitor is specified, the window will be windowed mode. Unless you have a way for the user to choose a specific monitor, it is recommended that you pick the primary monitor. For more information on how to query connected monitors, see Retrieving monitors.

-

For full screen windows, the specified size becomes the resolution of the window's desired video mode. As long as a full screen window is not iconified, the supported video mode most closely matching the desired video mode is set for the specified monitor. For more information about full screen windows, including the creation of so called windowed full screen or borderless full screen windows, see "Windowed full screen" windows.

-

Once you have created the window, you can switch it between windowed and full screen mode with glfwSetWindowMonitor. This will not affect its OpenGL or OpenGL ES context.

-

By default, newly created windows use the placement recommended by the window system. To create the window at a specific position, make it initially invisible using the GLFW_VISIBLE window hint, set its position and then show it.

-

As long as at least one full screen window is not iconified, the screensaver is prohibited from starting.

-

Window systems put limits on window sizes. Very large or very small window dimensions may be overridden by the window system on creation. Check the actual size after creation.

-

The swap interval is not set during window creation and the initial value may vary depending on driver settings and defaults.

+

This function creates a window and its associated OpenGL or OpenGL ES context. Most of the options controlling how the window and its context should be created are specified with window hints.

+

Successful creation does not change which context is current. Before you can use the newly created context, you need to make it current. For information about the share parameter, see Context object sharing.

+

The created window, framebuffer and context may differ from what you requested, as not all parameters and hints are hard constraints. This includes the size of the window, especially for full screen windows. To query the actual attributes of the created window, framebuffer and context, see glfwGetWindowAttrib, glfwGetWindowSize and glfwGetFramebufferSize.

+

To create a full screen window, you need to specify the monitor the window will cover. If no monitor is specified, the window will be windowed mode. Unless you have a way for the user to choose a specific monitor, it is recommended that you pick the primary monitor. For more information on how to query connected monitors, see Retrieving monitors.

+

For full screen windows, the specified size becomes the resolution of the window's desired video mode. As long as a full screen window is not iconified, the supported video mode most closely matching the desired video mode is set for the specified monitor. For more information about full screen windows, including the creation of so called windowed full screen or borderless full screen windows, see "Windowed full screen" windows.

+

Once you have created the window, you can switch it between windowed and full screen mode with glfwSetWindowMonitor. This will not affect its OpenGL or OpenGL ES context.

+

By default, newly created windows use the placement recommended by the window system. To create the window at a specific position, set the GLFW_POSITION_X and GLFW_POSITION_Y window hints before creation. To restore the default behavior, set either or both hints back to GLFW_ANY_POSITION.

+

As long as at least one full screen window is not iconified, the screensaver is prohibited from starting.

+

Window systems put limits on window sizes. Very large or very small window dimensions may be overridden by the window system on creation. Check the actual size after creation.

+

The swap interval is not set during window creation and the initial value may vary depending on driver settings and defaults.

Parameters
@@ -1520,34 +1671,28 @@ Functions
Returns
The handle of the created window, or NULL if an error occurred.
-
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_ENUM, GLFW_INVALID_VALUE, GLFW_API_UNAVAILABLE, GLFW_VERSION_UNAVAILABLE, GLFW_FORMAT_UNAVAILABLE and GLFW_PLATFORM_ERROR.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_ENUM, GLFW_INVALID_VALUE, GLFW_API_UNAVAILABLE, GLFW_VERSION_UNAVAILABLE, GLFW_FORMAT_UNAVAILABLE, GLFW_NO_WINDOW_CONTEXT and GLFW_PLATFORM_ERROR.
Remarks
Windows: Window creation will fail if the Microsoft GDI software OpenGL implementation is the only one available.
Windows: If the executable has an icon resource named GLFW_ICON, it will be set as the initial icon for the window. If no such icon is present, the IDI_APPLICATION icon will be used instead. To set a different icon, see glfwSetWindowIcon.
Windows: The context to share resources with must not be current on any other thread.
-macOS: The OS only supports forward-compatible core profile contexts for OpenGL versions 3.2 and later. Before creating an OpenGL context of version 3.2 or later you must set the GLFW_OPENGL_FORWARD_COMPAT and GLFW_OPENGL_PROFILE hints accordingly. OpenGL 3.0 and 3.1 contexts are not supported at all on macOS.
+macOS: The OS only supports core profile contexts for OpenGL versions 3.2 and later. Before creating an OpenGL context of version 3.2 or later you must set the GLFW_OPENGL_PROFILE hint accordingly. OpenGL 3.0 and 3.1 contexts are not supported at all on macOS.
macOS: The GLFW window has no icon, as it is not a document window, but the dock icon will be the same as the application bundle's icon. For more information on bundles, see the Bundle Programming Guide in the Mac Developer Library.
-macOS: The first time a window is created the menu bar is created. If GLFW finds a MainMenu.nib it is loaded and assumed to contain a menu bar. Otherwise a minimal menu bar is created manually with common commands like Hide, Quit and About. The About entry opens a minimal about dialog with information from the application's bundle. Menu bar creation can be disabled entirely with the GLFW_COCOA_MENUBAR init hint.
-
-macOS: On OS X 10.10 and later the window frame will not be rendered at full resolution on Retina displays unless the GLFW_COCOA_RETINA_FRAMEBUFFER hint is GLFW_TRUE and the NSHighResolutionCapable key is enabled in the application bundle's Info.plist. For more information, see High Resolution Guidelines for OS X in the Mac Developer Library. The GLFW test and example programs use a custom Info.plist template for this, which can be found as CMake/MacOSXBundleInfo.plist.in in the source tree.
+macOS: On OS X 10.10 and later the window frame will not be rendered at full resolution on Retina displays unless the GLFW_SCALE_FRAMEBUFFER hint is GLFW_TRUE and the NSHighResolutionCapable key is enabled in the application bundle's Info.plist. For more information, see High Resolution Guidelines for OS X in the Mac Developer Library. The GLFW test and example programs use a custom Info.plist template for this, which can be found as CMake/Info.plist.in in the source tree.
macOS: When activating frame autosaving with GLFW_COCOA_FRAME_NAME, the specified window size and position may be overridden by previously saved values.
+Wayland: GLFW uses libdecor where available to create its window decorations. This in turn uses server-side XDG decorations where available and provides high quality client-side decorations on compositors like GNOME. If both XDG decorations and libdecor are unavailable, GLFW falls back to a very simple set of window decorations that only support moving, resizing and the window manager's right-click menu.
+
X11: Some window managers will not respect the placement of initially hidden windows.
X11: Due to the asynchronous nature of X11, it may take a moment for a window to reach its requested state. This means you may not be able to query the final size, position or other attributes directly after window creation.
-X11: The class part of the WM_CLASS window property will by default be set to the window title passed to this function. The instance part will use the contents of the RESOURCE_NAME environment variable, if present and not empty, or fall back to the window title. Set the GLFW_X11_CLASS_NAME and GLFW_X11_INSTANCE_NAME window hints to override this.
-
-Wayland: Compositors should implement the xdg-decoration protocol for GLFW to decorate the window properly. If this protocol isn't supported, or if the compositor prefers client-side decorations, a very simple fallback frame will be drawn using the wp_viewporter protocol. A compositor can still emit close, maximize or fullscreen events, using for instance a keybind mechanism. If neither of these protocols is supported, the window won't be decorated.
-
-Wayland: A full screen window will not attempt to change the mode, no matter what the requested size or refresh rate.
-
-Wayland: Screensaver inhibition requires the idle-inhibit protocol to be implemented in the user's compositor.
+X11: The class part of the WM_CLASS window property will by default be set to the window title passed to this function. The instance part will use the contents of the RESOURCE_NAME environment variable, if present and not empty, or fall back to the window title. Set the GLFW_X11_CLASS_NAME and GLFW_X11_INSTANCE_NAME window hints to override this.
Thread safety
This function must only be called from the main thread.
See also
Window creation
@@ -1557,7 +1702,7 @@ Functions -

◆ glfwDestroyWindow()

+

◆ glfwDestroyWindow()

@@ -1571,8 +1716,8 @@ Functions
[in]widthThe desired width, in screen coordinates, of the window. This must be greater than zero.
-

This function destroys the specified window and its context. On calling this function, no further callbacks will be called for that window.

-

If the context of the specified window is current on the main thread, it is detached before being destroyed.

+

This function destroys the specified window and its context. On calling this function, no further callbacks will be called for that window.

+

If the context of the specified window is current on the main thread, it is detached before being destroyed.

Parameters
@@ -1591,7 +1736,7 @@ Functions -

◆ glfwWindowShouldClose()

+

◆ glfwWindowShouldClose()

@@ -1605,7 +1750,7 @@ Functions
[in]windowThe window to destroy.
-

This function returns the value of the close flag of the specified window.

+

This function returns the value of the close flag of the specified window.

Parameters
@@ -1621,7 +1766,7 @@ Functions -

◆ glfwSetWindowShouldClose()

+

◆ glfwSetWindowShouldClose()

@@ -1645,7 +1790,7 @@ Functions
[in]windowThe window to query.
-

This function sets the value of the close flag of the specified window. This can be used to override the user's attempt to close the window, or to signal that it should be closed.

+

This function sets the value of the close flag of the specified window. This can be used to override the user's attempt to close the window, or to signal that it should be closed.

Parameters
@@ -1658,10 +1803,44 @@ Functions
See also
Window closing and close flag
Since
Added in version 3.0.
+ + + +

◆ glfwGetWindowTitle()

+ +
+
+
[in]windowThe window whose flag to change.
+ + + + + + + +
const char * glfwGetWindowTitle (GLFWwindowwindow)
+
+

This function returns the window title, encoded as UTF-8, of the specified window. This is the title set previously by glfwCreateWindow or glfwSetWindowTitle.

+
Parameters
+ + +
[in]windowThe window to query.
+
+
+
Returns
The UTF-8 encoded window title, or NULL if an error occurred.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED.
+
Remarks
The returned title is currently a copy of the title last set by glfwCreateWindow or glfwSetWindowTitle. It does not include any additional text which may be appended by the platform or another program.
+
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 glfwGetWindowTitle or glfwSetWindowTitle, or until the library is terminated.
+
Thread safety
This function must only be called from the main thread.
+
See also
Window title
+
+glfwSetWindowTitle
+
Since
Added in version 3.4.
+
-

◆ glfwSetWindowTitle()

+

◆ glfwSetWindowTitle()

@@ -1685,7 +1864,7 @@ Functions
-

This function sets the window title, encoded as UTF-8, of the specified window.

+

This function sets the window title, encoded as UTF-8, of the specified window.

Parameters
@@ -1696,13 +1875,15 @@ Functions
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
Remarks
macOS: The window title will not be updated until the next time you process events.
Thread safety
This function must only be called from the main thread.
-
See also
Window title
+
See also
Window title
+
+glfwGetWindowTitle
Since
Added in version 1.0. GLFW 3: Added window handle parameter.
-

◆ glfwSetWindowIcon()

+

◆ glfwSetWindowIcon()

@@ -1722,7 +1903,7 @@ Functions
- + @@ -1732,9 +1913,9 @@ Functions
[in]windowThe window whose title to change.
const GLFWimageconst GLFWimage images 
-

This function sets the icon of the specified window. If passed an array of candidate images, those of or closest to the sizes desired by the system are selected. If no images are specified, the window reverts to its default icon.

-

The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits per channel with the red channel first. They are arranged canonically as packed sequential rows, starting from the top-left corner.

-

The desired image sizes varies depending on platform and system settings. The selected images will be rescaled as needed. Good sizes include 16x16, 32x32 and 48x48.

+

This function sets the icon of the specified window. If passed an array of candidate images, those of or closest to the sizes desired by the system are selected. If no images are specified, the window reverts to its default icon.

+

The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits per channel with the red channel first. They are arranged canonically as packed sequential rows, starting from the top-left corner.

+

The desired image sizes varies depending on platform and system settings. The selected images will be rescaled as needed. Good sizes include 16x16, 32x32 and 48x48.

Parameters
@@ -1743,11 +1924,11 @@ Functions
[in]windowThe window whose icon to set.
-
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_VALUE and GLFW_PLATFORM_ERROR.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_VALUE, GLFW_PLATFORM_ERROR and GLFW_FEATURE_UNAVAILABLE (see remarks).
Pointer lifetime
The specified image data is copied before this function returns.
-
Remarks
macOS: The GLFW window has no icon, as it is not a document window, so this function does nothing. The dock icon will be the same as the application bundle's icon. For more information on bundles, see the Bundle Programming Guide in the Mac Developer Library.
+
Remarks
macOS: Regular windows do not have icons on macOS. This function will emit GLFW_FEATURE_UNAVAILABLE. The dock icon will be the same as the application bundle's icon. For more information on bundles, see the Bundle Programming Guide in the Mac Developer Library.
-Wayland: There is no existing protocol to change an icon, the window will thus inherit the one defined in the application's desktop file. This function always emits GLFW_PLATFORM_ERROR.
+Wayland: There is no existing protocol to change an icon, the window will thus inherit the one defined in the application's desktop file. This function will emit GLFW_FEATURE_UNAVAILABLE.
Thread safety
This function must only be called from the main thread.
See also
Window icon
Since
Added in version 3.2.
@@ -1755,7 +1936,7 @@ Functions
-

◆ glfwGetWindowPos()

+

◆ glfwGetWindowPos()

@@ -1785,8 +1966,8 @@ Functions
-

This function retrieves the position, in screen coordinates, of the upper-left corner of the content area of the specified window.

-

Any or all of the position arguments may be NULL. If an error occurs, all non-NULL position arguments will be set to zero.

+

This function retrieves the position, in screen coordinates, of the upper-left corner of the content area of the specified window.

+

Any or all of the position arguments may be NULL. If an error occurs, all non-NULL position arguments will be set to zero.

Parameters
@@ -1795,8 +1976,8 @@ Functions
[in]windowThe window to query.
-
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
-
Remarks
Wayland: There is no way for an application to retrieve the global position of its windows, this function will always emit GLFW_PLATFORM_ERROR.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_PLATFORM_ERROR and GLFW_FEATURE_UNAVAILABLE (see remarks).
+
Remarks
Wayland: There is no way for an application to retrieve the global position of its windows. This function will emit GLFW_FEATURE_UNAVAILABLE.
Thread safety
This function must only be called from the main thread.
See also
Window position
@@ -1806,7 +1987,7 @@ Functions
-

◆ glfwSetWindowPos()

+

◆ glfwSetWindowPos()

@@ -1836,9 +2017,9 @@ Functions
-

This function sets the position, in screen coordinates, of the upper-left corner of the content area of the specified windowed mode window. If the window is a full screen window, this function does nothing.

-

Do not use this function to move an already visible window unless you have very good reasons for doing so, as it will confuse and annoy the user.

-

The window manager may put limits on what positions are allowed. GLFW cannot and should not override these limits.

+

This function sets the position, in screen coordinates, of the upper-left corner of the content area of the specified windowed mode window. If the window is a full screen window, this function does nothing.

+

Do not use this function to move an already visible window unless you have very good reasons for doing so, as it will confuse and annoy the user.

+

The window manager may put limits on what positions are allowed. GLFW cannot and should not override these limits.

Parameters
@@ -1847,8 +2028,8 @@ Functions
[in]windowThe window to query.
-
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
-
Remarks
Wayland: There is no way for an application to set the global position of its windows, this function will always emit GLFW_PLATFORM_ERROR.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_PLATFORM_ERROR and GLFW_FEATURE_UNAVAILABLE (see remarks).
+
Remarks
Wayland: There is no way for an application to set the global position of its windows. This function will emit GLFW_FEATURE_UNAVAILABLE.
Thread safety
This function must only be called from the main thread.
See also
Window position
@@ -1858,7 +2039,7 @@ Functions
-

◆ glfwGetWindowSize()

+

◆ glfwGetWindowSize()

@@ -1888,8 +2069,8 @@ Functions
-

This function retrieves the size, in screen coordinates, of the content area of the specified window. If you wish to retrieve the size of the framebuffer of the window in pixels, see glfwGetFramebufferSize.

-

Any or all of the size arguments may be NULL. If an error occurs, all non-NULL size arguments will be set to zero.

+

This function retrieves the size, in screen coordinates, of the content area of the specified window. If you wish to retrieve the size of the framebuffer of the window in pixels, see glfwGetFramebufferSize.

+

Any or all of the size arguments may be NULL. If an error occurs, all non-NULL size arguments will be set to zero.

Parameters
@@ -1908,7 +2089,7 @@ Functions -

◆ glfwSetWindowSizeLimits()

+

◆ glfwSetWindowSizeLimits()

@@ -1950,9 +2131,9 @@ Functions
[in]windowThe window whose size to retrieve.
-

This function sets the size limits of the content area of the specified window. If the window is full screen, the size limits only take effect once it is made windowed. If the window is not resizable, this function does nothing.

-

The size limits are applied immediately to a windowed mode window and may cause it to be resized.

-

The maximum dimensions must be greater than or equal to the minimum dimensions and all must be greater than or equal to zero.

+

This function sets the size limits of the content area of the specified window. If the window is full screen, the size limits only take effect once it is made windowed. If the window is not resizable, this function does nothing.

+

The size limits are applied immediately to a windowed mode window and may cause it to be resized.

+

The maximum dimensions must be greater than or equal to the minimum dimensions and all must be greater than or equal to zero.

Parameters
@@ -1976,7 +2157,7 @@ Functions -

◆ glfwSetWindowAspectRatio()

+

◆ glfwSetWindowAspectRatio()

@@ -2006,10 +2187,10 @@ Functions
[in]windowThe window to set limits for.
-

This function sets the required aspect ratio of the content area of the specified window. If the window is full screen, the aspect ratio only takes effect once it is made windowed. If the window is not resizable, this function does nothing.

-

The aspect ratio is specified as a numerator and a denominator and both values must be greater than zero. For example, the common 16:9 aspect ratio is specified as 16 and 9, respectively.

-

If the numerator and denominator is set to GLFW_DONT_CARE then the aspect ratio limit is disabled.

-

The aspect ratio is applied immediately to a windowed mode window and may cause it to be resized.

+

This function sets the required aspect ratio of the content area of the specified window. If the window is full screen, the aspect ratio only takes effect once it is made windowed. If the window is not resizable, this function does nothing.

+

The aspect ratio is specified as a numerator and a denominator and both values must be greater than zero. For example, the common 16:9 aspect ratio is specified as 16 and 9, respectively.

+

If the numerator and denominator is set to GLFW_DONT_CARE then the aspect ratio limit is disabled.

+

The aspect ratio is applied immediately to a windowed mode window and may cause it to be resized.

Parameters
@@ -2031,7 +2212,7 @@ Functions -

◆ glfwSetWindowSize()

+

◆ glfwSetWindowSize()

@@ -2061,10 +2242,10 @@ Functions
[in]windowThe window to set limits for.
-

This function sets the size, in screen coordinates, of the content area of the specified window.

-

For full screen windows, this function updates the resolution of its desired video mode and switches to the video mode closest to it, without affecting the window's context. As the context is unaffected, the bit depths of the framebuffer remain unchanged.

-

If you wish to update the refresh rate of the desired video mode in addition to its resolution, see glfwSetWindowMonitor.

-

The window manager may put limits on what sizes are allowed. GLFW cannot and should not override these limits.

+

This function sets the size, in screen coordinates, of the content area of the specified window.

+

For full screen windows, this function updates the resolution of its desired video mode and switches to the video mode closest to it, without affecting the window's context. As the context is unaffected, the bit depths of the framebuffer remain unchanged.

+

If you wish to update the refresh rate of the desired video mode in addition to its resolution, see glfwSetWindowMonitor.

+

The window manager may put limits on what sizes are allowed. GLFW cannot and should not override these limits.

Parameters
@@ -2074,7 +2255,6 @@ Functions
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
-
Remarks
Wayland: A full screen window will not attempt to change the mode, no matter what the requested size.
Thread safety
This function must only be called from the main thread.
See also
Window size
@@ -2086,7 +2266,7 @@ Functions -

◆ glfwGetFramebufferSize()

+

◆ glfwGetFramebufferSize()

@@ -2116,8 +2296,8 @@ Functions
[in]windowThe window to resize.
-

This function retrieves the size, in pixels, of the framebuffer of the specified window. If you wish to retrieve the size of the window in screen coordinates, see glfwGetWindowSize.

-

Any or all of the size arguments may be NULL. If an error occurs, all non-NULL size arguments will be set to zero.

+

This function retrieves the size, in pixels, of the framebuffer of the specified window. If you wish to retrieve the size of the window in screen coordinates, see glfwGetWindowSize.

+

Any or all of the size arguments may be NULL. If an error occurs, all non-NULL size arguments will be set to zero.

Parameters
@@ -2136,7 +2316,7 @@ Functions -

◆ glfwGetWindowFrameSize()

+

◆ glfwGetWindowFrameSize()

@@ -2178,9 +2358,9 @@ Functions
[in]windowThe window whose framebuffer to query.
-

This function retrieves the size, in screen coordinates, of each edge of the frame of the specified window. This size includes the title bar, if the window has one. The size of the frame may vary depending on the window-related hints used to create it.

-

Because this function retrieves the size of each window frame edge and not the offset along a particular coordinate axis, the retrieved values will always be zero or positive.

-

Any or all of the size arguments may be NULL. If an error occurs, all non-NULL size arguments will be set to zero.

+

This function retrieves the size, in screen coordinates, of each edge of the frame of the specified window. This size includes the title bar, if the window has one. The size of the frame may vary depending on the window-related hints used to create it.

+

Because this function retrieves the size of each window frame edge and not the offset along a particular coordinate axis, the retrieved values will always be zero or positive.

+

Any or all of the size arguments may be NULL. If an error occurs, all non-NULL size arguments will be set to zero.

Parameters
@@ -2199,7 +2379,7 @@ Functions -

◆ glfwGetWindowContentScale()

+

◆ glfwGetWindowContentScale()

@@ -2229,8 +2409,8 @@ Functions
[in]windowThe window whose frame size to query.
-

This function retrieves the content scale for the specified window. The content scale is the ratio between the current DPI and the platform's default DPI. This is especially important for text and any UI elements. If the pixel dimensions of your UI scaled by this look appropriate on your machine then it should appear at a reasonable size on other machines regardless of their DPI and scaling settings. This relies on the system DPI and scaling settings being somewhat correct.

-

On systems where each monitors can have its own content scale, the window content scale will depend on which monitor the system considers the window to be on.

+

This function retrieves the content scale for the specified window. The content scale is the ratio between the current DPI and the platform's default DPI. This is especially important for text and any UI elements. If the pixel dimensions of your UI scaled by this look appropriate on your machine then it should appear at a reasonable size on other machines regardless of their DPI and scaling settings. This relies on the system DPI and scaling settings being somewhat correct.

+

On platforms where each monitors can have its own content scale, the window content scale will depend on which monitor the system considers the window to be on.

Parameters
@@ -2251,7 +2431,7 @@ Functions -

◆ glfwGetWindowOpacity()

+

◆ glfwGetWindowOpacity()

@@ -2265,9 +2445,9 @@ Functions
[in]windowThe window to query.
-

This function returns the opacity of the window, including any decorations.

-

The opacity (or alpha) value is a positive finite number between zero and one, where zero is fully transparent and one is fully opaque. If the system does not support whole window transparency, this function always returns one.

-

The initial opacity value for newly created windows is one.

+

This function returns the opacity of the window, including any decorations.

+

The opacity (or alpha) value is a positive finite number between zero and one, where zero is fully transparent and one is fully opaque. If the system does not support whole window transparency, this function always returns one.

+

The initial opacity value for newly created windows is one.

Parameters
@@ -2285,7 +2465,7 @@ Functions -

◆ glfwSetWindowOpacity()

+

◆ glfwSetWindowOpacity()

@@ -2309,10 +2489,10 @@ Functions
[in]windowThe window to query.
-

This function sets the opacity of the window, including any decorations.

-

The opacity (or alpha) value is a positive finite number between zero and one, where zero is fully transparent and one is fully opaque.

-

The initial opacity value for newly created windows is one.

-

A window created with framebuffer transparency may not use whole window transparency. The results of doing this are undefined.

+

This function sets the opacity of the window, including any decorations.

+

The opacity (or alpha) value is a positive finite number between zero and one, where zero is fully transparent and one is fully opaque.

+

The initial opacity value for newly created windows is one.

+

A window created with framebuffer transparency may not use whole window transparency. The results of doing this are undefined.

Parameters
@@ -2320,7 +2500,8 @@ Functions
[in]windowThe window to set the opacity for.
-
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_PLATFORM_ERROR and GLFW_FEATURE_UNAVAILABLE (see remarks).
+
Remarks
Wayland: There is no way to set an opacity factor for a window. This function will emit GLFW_FEATURE_UNAVAILABLE.
Thread safety
This function must only be called from the main thread.
See also
Window transparency
@@ -2330,7 +2511,7 @@ Functions
-

◆ glfwIconifyWindow()

+

◆ glfwIconifyWindow()

@@ -2344,8 +2525,8 @@ Functions
-

This function iconifies (minimizes) the specified window if it was previously restored. If the window is already iconified, this function does nothing.

-

If the specified window is a full screen window, GLFW restores the original video mode of the monitor. The window's desired video mode is set again when the window is restored.

+

This function iconifies (minimizes) the specified window if it was previously restored. If the window is already iconified, this function does nothing.

+

If the specified window is a full screen window, GLFW restores the original video mode of the monitor. The window's desired video mode is set again when the window is restored.

Parameters
@@ -2353,6 +2534,7 @@ Functions
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
+
Remarks
Wayland: Once a window is iconified, glfwRestoreWindow won’t be able to restore it. This is a design decision of the xdg-shell protocol.
Thread safety
This function must only be called from the main thread.
See also
Window iconification
@@ -2364,7 +2546,7 @@ Functions -

◆ glfwRestoreWindow()

+

◆ glfwRestoreWindow()

@@ -2378,8 +2560,8 @@ Functions
[in]windowThe window to iconify.
-

This function restores the specified window if it was previously iconified (minimized) or maximized. If the window is already restored, this function does nothing.

-

If the specified window is an iconified full screen window, its desired video mode is set again for its monitor when the window is restored.

+

This function restores the specified window if it was previously iconified (minimized) or maximized. If the window is already restored, this function does nothing.

+

If the specified window is an iconified full screen window, its desired video mode is set again for its monitor when the window is restored.

Parameters
@@ -2398,7 +2580,7 @@ Functions -

◆ glfwMaximizeWindow()

+

◆ glfwMaximizeWindow()

@@ -2412,8 +2594,8 @@ Functions
[in]windowThe window to restore.
-

This function maximizes the specified window if it was previously not maximized. If the window is already maximized, this function does nothing.

-

If the specified window is a full screen window, this function does nothing.

+

This function maximizes the specified window if it was previously not maximized. If the window is already maximized, this function does nothing.

+

If the specified window is a full screen window, this function does nothing.

Parameters
@@ -2432,7 +2614,7 @@ Functions -

◆ glfwShowWindow()

+

◆ glfwShowWindow()

@@ -2446,8 +2628,8 @@ Functions
[in]windowThe window to maximize.
-

This function makes the specified window visible if it was previously hidden. If the window is already visible or is in full screen mode, this function does nothing.

-

By default, windowed mode windows are focused when shown Set the GLFW_FOCUS_ON_SHOW window hint to change this behavior for all newly created windows, or change the behavior for an existing window with glfwSetWindowAttrib.

+

This function makes the specified window visible if it was previously hidden. If the window is already visible or is in full screen mode, this function does nothing.

+

By default, windowed mode windows are focused when shown Set the GLFW_FOCUS_ON_SHOW window hint to change this behavior for all newly created windows, or change the behavior for an existing window with glfwSetWindowAttrib.

Parameters
@@ -2465,7 +2647,7 @@ Functions -

◆ glfwHideWindow()

+

◆ glfwHideWindow()

@@ -2479,7 +2661,7 @@ Functions
[in]windowThe window to make visible.
-

This function hides the specified window if it was previously visible. If the window is already hidden or is in full screen mode, this function does nothing.

+

This function hides the specified window if it was previously visible. If the window is already hidden or is in full screen mode, this function does nothing.

Parameters
@@ -2496,7 +2678,7 @@ Functions -

◆ glfwFocusWindow()

+

◆ glfwFocusWindow()

@@ -2510,11 +2692,11 @@ Functions
[in]windowThe window to hide.
-

This function brings the specified window to front and sets input focus. The window should already be visible and not iconified.

-

By default, both windowed and full screen mode windows are focused when initially created. Set the GLFW_FOCUSED to disable this behavior.

-

Also by default, windowed mode windows are focused when shown with glfwShowWindow. Set the GLFW_FOCUS_ON_SHOW to disable this behavior.

-

Do not use this function to steal focus from other applications unless you are certain that is what the user wants. Focus stealing can be extremely disruptive.

-

For a less disruptive way of getting the user's attention, see attention requests.

+

This function brings the specified window to front and sets input focus. The window should already be visible and not iconified.

+

By default, both windowed and full screen mode windows are focused when initially created. Set the GLFW_FOCUSED to disable this behavior.

+

Also by default, windowed mode windows are focused when shown with glfwShowWindow. Set the GLFW_FOCUS_ON_SHOW to disable this behavior.

+

Do not use this function to steal focus from other applications unless you are certain that is what the user wants. Focus stealing can be extremely disruptive.

+

For a less disruptive way of getting the user's attention, see attention requests.

Parameters
@@ -2522,7 +2704,7 @@ Functions
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
-
Remarks
Wayland: It is not possible for an application to bring its windows to front, this function will always emit GLFW_PLATFORM_ERROR.
+
Remarks
Wayland: The compositor will likely ignore focus requests unless another window created by the same application already has input focus.
Thread safety
This function must only be called from the main thread.
See also
Window input focus
@@ -2532,7 +2714,7 @@ Functions -

◆ glfwRequestWindowAttention()

+

◆ glfwRequestWindowAttention()

@@ -2546,8 +2728,8 @@ Functions
[in]windowThe window to give input focus.
-

This function requests user attention to the specified window. On platforms where this is not supported, attention is requested to the application as a whole.

-

Once the user has given attention, usually by focusing the window or application, the system will end the request automatically.

+

This function requests user attention to the specified window. On platforms where this is not supported, attention is requested to the application as a whole.

+

Once the user has given attention, usually by focusing the window or application, the system will end the request automatically.

Parameters
@@ -2563,7 +2745,7 @@ Functions -

◆ glfwGetWindowMonitor()

+

◆ glfwGetWindowMonitor()

@@ -2577,7 +2759,7 @@ Functions
[in]windowThe window to request attention to.
-

This function returns the handle of the monitor that the specified window is in full screen on.

+

This function returns the handle of the monitor that the specified window is in full screen on.

Parameters
@@ -2595,7 +2777,7 @@ Functions -

◆ glfwSetWindowMonitor()

+

◆ glfwSetWindowMonitor()

@@ -2649,11 +2831,11 @@ Functions
[in]windowThe window to query.
-

This function sets the monitor that the window uses for full screen mode or, if the monitor is NULL, makes it windowed mode.

-

When setting a monitor, this function updates the width, height and refresh rate of the desired video mode and switches to the video mode closest to it. The window position is ignored when setting a monitor.

-

When the monitor is NULL, the position, width and height are used to place the window content area. The refresh rate is ignored when no monitor is specified.

-

If you only wish to update the resolution of a full screen window or the size of a windowed mode window, see glfwSetWindowSize.

-

When a window transitions from full screen to windowed mode, this function restores any previous window settings such as whether it is decorated, floating, resizable, has size or aspect ratio limits, etc.

+

This function sets the monitor that the window uses for full screen mode or, if the monitor is NULL, makes it windowed mode.

+

When setting a monitor, this function updates the width, height and refresh rate of the desired video mode and switches to the video mode closest to it. The window position is ignored when setting a monitor.

+

When the monitor is NULL, the position, width and height are used to place the window content area. The refresh rate is ignored when no monitor is specified.

+

If you only wish to update the resolution of a full screen window or the size of a windowed mode window, see glfwSetWindowSize.

+

When a window transitions from full screen to windowed mode, this function restores any previous window settings such as whether it is decorated, floating, resizable, has size or aspect ratio limits, etc.

Parameters
@@ -2669,9 +2851,7 @@ Functions
Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
Remarks
The OpenGL or OpenGL ES context will not be destroyed or otherwise affected by any resizing or mode switching, although you may need to update your viewport if the framebuffer size has changed.
-Wayland: The desired window position is ignored, as there is no way for an application to set this property.
-
-Wayland: Setting the window to full screen will not attempt to change the mode, no matter what the requested size or refresh rate.
+Wayland: The desired window position is ignored, as there is no way for an application to set this property.
Thread safety
This function must only be called from the main thread.
See also
Window monitor
@@ -2685,7 +2865,7 @@ Functions -

◆ glfwGetWindowAttrib()

+

◆ glfwGetWindowAttrib()

@@ -2709,7 +2889,7 @@ Functions
[in]windowThe window whose monitor, size or video mode to set.
-

This function returns the value of an attribute of the specified window or its OpenGL or OpenGL ES context.

+

This function returns the value of an attribute of the specified window or its OpenGL or OpenGL ES context.

Parameters
@@ -2733,7 +2913,7 @@ Zero is a valid value for many window and context related attributes so you cann -

◆ glfwSetWindowAttrib()

+

◆ glfwSetWindowAttrib()

@@ -2763,10 +2943,10 @@ Zero is a valid value for many window and context related attributes so you cann
[in]windowThe window to query.
-

This function sets the value of an attribute of the specified window.

-

The supported attributes are GLFW_DECORATED, GLFW_RESIZABLE, GLFW_FLOATING, GLFW_AUTO_ICONIFY and GLFW_FOCUS_ON_SHOW.

-

Some of these attributes are ignored for full screen windows. The new value will take effect if the window is later made windowed.

-

Some of these attributes are ignored for windowed mode windows. The new value will take effect if the window is later made full screen.

+

This function sets the value of an attribute of the specified window.

+

The supported attributes are GLFW_DECORATED, GLFW_RESIZABLE, GLFW_FLOATING, GLFW_AUTO_ICONIFY and GLFW_FOCUS_ON_SHOW. GLFW_MOUSE_PASSTHROUGH

+

Some of these attributes are ignored for full screen windows. The new value will take effect if the window is later made windowed.

+

Some of these attributes are ignored for windowed mode windows. The new value will take effect if the window is later made full screen.

Parameters
@@ -2775,8 +2955,10 @@ Zero is a valid value for many window and context related attributes so you cann
[in]windowThe window to set the attribute for.
-
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_ENUM, GLFW_INVALID_VALUE and GLFW_PLATFORM_ERROR.
-
Remarks
Calling glfwGetWindowAttrib will always return the latest value, even if that value is ignored by the current mode of the window.
+
Errors
Possible errors include GLFW_NOT_INITIALIZED, GLFW_INVALID_ENUM, GLFW_INVALID_VALUE, GLFW_PLATFORM_ERROR and GLFW_FEATURE_UNAVAILABLE (see remarks).
+
Remarks
Calling glfwGetWindowAttrib will always return the latest value, even if that value is ignored by the current mode of the window.
+
+Wayland: The GLFW_FLOATING window attribute is not supported. Setting this will emit GLFW_FEATURE_UNAVAILABLE.
Thread safety
This function must only be called from the main thread.
See also
Window attributes
@@ -2786,7 +2968,7 @@ Zero is a valid value for many window and context related attributes so you cann
-

◆ glfwSetWindowUserPointer()

+

◆ glfwSetWindowUserPointer()

@@ -2810,7 +2992,7 @@ Zero is a valid value for many window and context related attributes so you cann
-

This function sets the user-defined pointer of the specified window. The current value is retained until the window is destroyed. The initial value is NULL.

+

This function sets the user-defined pointer of the specified window. The current value is retained until the window is destroyed. The initial value is NULL.

Parameters
@@ -2828,7 +3010,7 @@ Zero is a valid value for many window and context related attributes so you cann -

◆ glfwGetWindowUserPointer()

+

◆ glfwGetWindowUserPointer()

@@ -2842,7 +3024,7 @@ Zero is a valid value for many window and context related attributes so you cann
[in]windowThe window whose pointer to set.
-

This function returns the current value of the user-defined pointer of the specified window. The initial value is NULL.

+

This function returns the current value of the user-defined pointer of the specified window. The initial value is NULL.

Parameters
@@ -2859,7 +3041,7 @@ Zero is a valid value for many window and context related attributes so you cann -

◆ glfwSetWindowPosCallback()

+

◆ glfwSetWindowPosCallback()

@@ -2883,7 +3065,7 @@ Zero is a valid value for many window and context related attributes so you cann
[in]windowThe window whose pointer to return.
-

This function sets the position callback of the specified window, which is called when the window is moved. The callback is provided with the position, in screen coordinates, of the upper-left corner of the content area of the window.

+

This function sets the position callback of the specified window, which is called when the window is moved. The callback is provided with the position, in screen coordinates, of the upper-left corner of the content area of the window.

Parameters
@@ -2903,7 +3085,7 @@ Zero is a valid value for many window and context related attributes so you cann -

◆ glfwSetWindowSizeCallback()

+

◆ glfwSetWindowSizeCallback()

@@ -2927,7 +3109,7 @@ Zero is a valid value for many window and context related attributes so you cann
[in]windowThe window whose callback to set.
-

This function sets the size callback of the specified window, which is called when the window is resized. The callback is provided with the size, in screen coordinates, of the content area of the window.

+

This function sets the size callback of the specified window, which is called when the window is resized. The callback is provided with the size, in screen coordinates, of the content area of the window.

Parameters
@@ -2946,7 +3128,7 @@ Zero is a valid value for many window and context related attributes so you cann -

◆ glfwSetWindowCloseCallback()

+

◆ glfwSetWindowCloseCallback()

@@ -2970,9 +3152,9 @@ Zero is a valid value for many window and context related attributes so you cann
[in]windowThe window whose callback to set.
-

This function sets the close callback of the specified window, which is called when the user attempts to close the window, for example by clicking the close widget in the title bar.

-

The close flag is set before this callback is called, but you can modify it at any time with glfwSetWindowShouldClose.

-

The close callback is not triggered by glfwDestroyWindow.

+

This function sets the close callback of the specified window, which is called when the user attempts to close the window, for example by clicking the close widget in the title bar.

+

The close flag is set before this callback is called, but you can modify it at any time with glfwSetWindowShouldClose.

+

The close callback is not triggered by glfwDestroyWindow.

Parameters
@@ -2992,7 +3174,7 @@ Zero is a valid value for many window and context related attributes so you cann -

◆ glfwSetWindowRefreshCallback()

+

◆ glfwSetWindowRefreshCallback()

@@ -3016,8 +3198,8 @@ Zero is a valid value for many window and context related attributes so you cann
[in]windowThe window whose callback to set.
-

This function sets the refresh callback of the specified window, which is called when the content area of the window needs to be redrawn, for example if the window has been exposed after having been covered by another window.

-

On compositing window systems such as Aero, Compiz, Aqua or Wayland, where the window contents are saved off-screen, this callback may be called only very infrequently or never at all.

+

This function sets the refresh callback of the specified window, which is called when the content area of the window needs to be redrawn, for example if the window has been exposed after having been covered by another window.

+

On compositing window systems such as Aero, Compiz, Aqua or Wayland, where the window contents are saved off-screen, this callback may be called only very infrequently or never at all.

Parameters
@@ -3036,7 +3218,7 @@ Zero is a valid value for many window and context related attributes so you cann -

◆ glfwSetWindowFocusCallback()

+

◆ glfwSetWindowFocusCallback()

@@ -3060,8 +3242,8 @@ Zero is a valid value for many window and context related attributes so you cann
[in]windowThe window whose callback to set.
-

This function sets the focus callback of the specified window, which is called when the window gains or loses input focus.

-

After the focus callback is called for a window that lost input focus, synthetic key and mouse button release events will be generated for all such that had been pressed. For more information, see glfwSetKeyCallback and glfwSetMouseButtonCallback.

+

This function sets the focus callback of the specified window, which is called when the window gains or loses input focus.

+

After the focus callback is called for a window that lost input focus, synthetic key and mouse button release events will be generated for all such that had been pressed. For more information, see glfwSetKeyCallback and glfwSetMouseButtonCallback.

Parameters
@@ -3080,7 +3262,7 @@ Zero is a valid value for many window and context related attributes so you cann -

◆ glfwSetWindowIconifyCallback()

+

◆ glfwSetWindowIconifyCallback()

@@ -3104,7 +3286,7 @@ Zero is a valid value for many window and context related attributes so you cann
[in]windowThe window whose callback to set.
-

This function sets the iconification callback of the specified window, which is called when the window is iconified or restored.

+

This function sets the iconification callback of the specified window, which is called when the window is iconified or restored.

Parameters
@@ -3116,7 +3298,6 @@ Zero is a valid value for many window and context related attributes so you cann
Callback signature
void function_name(GLFWwindow* window, int iconified)
For more information about the callback parameters, see the function pointer type.
Errors
Possible errors include GLFW_NOT_INITIALIZED.
-
Remarks
Wayland: The XDG-shell protocol has no event for iconification, so this callback will never be called.
Thread safety
This function must only be called from the main thread.
See also
Window iconification
Since
Added in version 3.0.
@@ -3124,7 +3305,7 @@ Zero is a valid value for many window and context related attributes so you cann -

◆ glfwSetWindowMaximizeCallback()

+

◆ glfwSetWindowMaximizeCallback()

@@ -3148,7 +3329,7 @@ Zero is a valid value for many window and context related attributes so you cann
[in]windowThe window whose callback to set.
-

This function sets the maximization callback of the specified window, which is called when the window is maximized or restored.

+

This function sets the maximization callback of the specified window, which is called when the window is maximized or restored.

Parameters
@@ -3167,7 +3348,7 @@ Zero is a valid value for many window and context related attributes so you cann -

◆ glfwSetFramebufferSizeCallback()

+

◆ glfwSetFramebufferSizeCallback()

@@ -3191,7 +3372,7 @@ Zero is a valid value for many window and context related attributes so you cann
[in]windowThe window whose callback to set.
-

This function sets the framebuffer resize callback of the specified window, which is called when the framebuffer of the specified window is resized.

+

This function sets the framebuffer resize callback of the specified window, which is called when the framebuffer of the specified window is resized.

Parameters
@@ -3210,7 +3391,7 @@ Zero is a valid value for many window and context related attributes so you cann -

◆ glfwSetWindowContentScaleCallback()

+

◆ glfwSetWindowContentScaleCallback()

@@ -3234,7 +3415,7 @@ Zero is a valid value for many window and context related attributes so you cann
[in]windowThe window whose callback to set.
-

This function sets the window content scale callback of the specified window, which is called when the content scale of the specified window changes.

+

This function sets the window content scale callback of the specified window, which is called when the content scale of the specified window changes.

Parameters
@@ -3255,7 +3436,7 @@ Zero is a valid value for many window and context related attributes so you cann -

◆ glfwPollEvents()

+

◆ glfwPollEvents()

@@ -3269,10 +3450,10 @@ Zero is a valid value for many window and context related attributes so you cann
[in]windowThe window whose callback to set.
-

This function processes only those events that are already in the event queue and then returns immediately. Processing events will cause the window and input callbacks associated with those events to be called.

-

On some platforms, a window move, resize or menu operation will cause event processing to block. This is due to how event processing is designed on those platforms. You can use the window refresh callback to redraw the contents of your window when necessary during such operations.

-

Do not assume that callbacks you set will only be called in response to event processing functions like this one. While it is necessary to poll for events, window systems that require GLFW to register callbacks of its own can pass events to GLFW in response to many window system function calls. GLFW will pass those events on to the application callbacks before returning.

-

Event processing is not required for joystick input to work.

+

This function processes only those events that are already in the event queue and then returns immediately. Processing events will cause the window and input callbacks associated with those events to be called.

+

On some platforms, a window move, resize or menu operation will cause event processing to block. This is due to how event processing is designed on those platforms. You can use the window refresh callback to redraw the contents of your window when necessary during such operations.

+

Do not assume that callbacks you set will only be called in response to event processing functions like this one. While it is necessary to poll for events, window systems that require GLFW to register callbacks of its own can pass events to GLFW in response to many window system function calls. GLFW will pass those events on to the application callbacks before returning.

+

Event processing is not required for joystick input to work.

Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
Reentrancy
This function must not be called from a callback.
Thread safety
This function must only be called from the main thread.
@@ -3286,7 +3467,7 @@ Zero is a valid value for many window and context related attributes so you cann
-

◆ glfwWaitEvents()

+

◆ glfwWaitEvents()

@@ -3300,11 +3481,11 @@ Zero is a valid value for many window and context related attributes so you cann
-

This function puts the calling thread to sleep until at least one event is available in the event queue. Once one or more events are available, it behaves exactly like glfwPollEvents, i.e. the events in the queue are processed and the function then returns immediately. Processing events will cause the window and input callbacks associated with those events to be called.

-

Since not all events are associated with callbacks, this function may return without a callback having been called even if you are monitoring all callbacks.

-

On some platforms, a window move, resize or menu operation will cause event processing to block. This is due to how event processing is designed on those platforms. You can use the window refresh callback to redraw the contents of your window when necessary during such operations.

-

Do not assume that callbacks you set will only be called in response to event processing functions like this one. While it is necessary to poll for events, window systems that require GLFW to register callbacks of its own can pass events to GLFW in response to many window system function calls. GLFW will pass those events on to the application callbacks before returning.

-

Event processing is not required for joystick input to work.

+

This function puts the calling thread to sleep until at least one event is available in the event queue. Once one or more events are available, it behaves exactly like glfwPollEvents, i.e. the events in the queue are processed and the function then returns immediately. Processing events will cause the window and input callbacks associated with those events to be called.

+

Since not all events are associated with callbacks, this function may return without a callback having been called even if you are monitoring all callbacks.

+

On some platforms, a window move, resize or menu operation will cause event processing to block. This is due to how event processing is designed on those platforms. You can use the window refresh callback to redraw the contents of your window when necessary during such operations.

+

Do not assume that callbacks you set will only be called in response to event processing functions like this one. While it is necessary to poll for events, window systems that require GLFW to register callbacks of its own can pass events to GLFW in response to many window system function calls. GLFW will pass those events on to the application callbacks before returning.

+

Event processing is not required for joystick input to work.

Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
Reentrancy
This function must not be called from a callback.
Thread safety
This function must only be called from the main thread.
@@ -3318,7 +3499,7 @@ Zero is a valid value for many window and context related attributes so you cann
-

◆ glfwWaitEventsTimeout()

+

◆ glfwWaitEventsTimeout()

@@ -3332,12 +3513,12 @@ Zero is a valid value for many window and context related attributes so you cann
-

This function puts the calling thread to sleep until at least one event is available in the event queue, or until the specified timeout is reached. If one or more events are available, it behaves exactly like glfwPollEvents, i.e. the events in the queue are processed and the function then returns immediately. Processing events will cause the window and input callbacks associated with those events to be called.

-

The timeout value must be a positive finite number.

-

Since not all events are associated with callbacks, this function may return without a callback having been called even if you are monitoring all callbacks.

-

On some platforms, a window move, resize or menu operation will cause event processing to block. This is due to how event processing is designed on those platforms. You can use the window refresh callback to redraw the contents of your window when necessary during such operations.

-

Do not assume that callbacks you set will only be called in response to event processing functions like this one. While it is necessary to poll for events, window systems that require GLFW to register callbacks of its own can pass events to GLFW in response to many window system function calls. GLFW will pass those events on to the application callbacks before returning.

-

Event processing is not required for joystick input to work.

+

This function puts the calling thread to sleep until at least one event is available in the event queue, or until the specified timeout is reached. If one or more events are available, it behaves exactly like glfwPollEvents, i.e. the events in the queue are processed and the function then returns immediately. Processing events will cause the window and input callbacks associated with those events to be called.

+

The timeout value must be a positive finite number.

+

Since not all events are associated with callbacks, this function may return without a callback having been called even if you are monitoring all callbacks.

+

On some platforms, a window move, resize or menu operation will cause event processing to block. This is due to how event processing is designed on those platforms. You can use the window refresh callback to redraw the contents of your window when necessary during such operations.

+

Do not assume that callbacks you set will only be called in response to event processing functions like this one. While it is necessary to poll for events, window systems that require GLFW to register callbacks of its own can pass events to GLFW in response to many window system function calls. GLFW will pass those events on to the application callbacks before returning.

+

Event processing is not required for joystick input to work.

Parameters
@@ -3357,7 +3538,7 @@ Zero is a valid value for many window and context related attributes so you cann -

◆ glfwPostEmptyEvent()

+

◆ glfwPostEmptyEvent()

@@ -3371,7 +3552,7 @@ Zero is a valid value for many window and context related attributes so you cann
[in]timeoutThe maximum amount of time, in seconds, to wait.
-

This function posts an empty event from the current thread to the event queue, causing glfwWaitEvents or glfwWaitEventsTimeout to return.

+

This function posts an empty event from the current thread to the event queue, causing glfwWaitEvents or glfwWaitEventsTimeout to return.

Errors
Possible errors include GLFW_NOT_INITIALIZED and GLFW_PLATFORM_ERROR.
Thread safety
This function may be called from any thread.
See also
Event processing
@@ -3384,7 +3565,7 @@ Zero is a valid value for many window and context related attributes so you cann
-

◆ glfwSwapBuffers()

+

◆ glfwSwapBuffers()

@@ -3398,9 +3579,9 @@ Zero is a valid value for many window and context related attributes so you cann
-

This function swaps the front and back buffers of the specified window when rendering with OpenGL or OpenGL ES. If the swap interval is greater than zero, the GPU driver waits the specified number of screen updates before swapping the buffers.

-

The specified window must have an OpenGL or OpenGL ES context. Specifying a window without a context will generate a GLFW_NO_WINDOW_CONTEXT error.

-

This function does not apply to Vulkan. If you are rendering with Vulkan, see vkQueuePresentKHR instead.

+

This function swaps the front and back buffers of the specified window when rendering with OpenGL or OpenGL ES. If the swap interval is greater than zero, the GPU driver waits the specified number of screen updates before swapping the buffers.

+

The specified window must have an OpenGL or OpenGL ES context. Specifying a window without a context will generate a GLFW_NO_WINDOW_CONTEXT error.

+

This function does not apply to Vulkan. If you are rendering with Vulkan, see vkQueuePresentKHR instead.

Parameters
@@ -3420,7 +3601,7 @@ Zero is a valid value for many window and context related attributes so you cann diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/index.html b/src/lib/src/vendor/glfw-3.4/docs/html/index.html similarity index 55% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/index.html rename to src/lib/src/vendor/glfw-3.4/docs/html/index.html index 072fcc5..484e216 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/index.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/index.html @@ -4,8 +4,8 @@ - -GLFW: Main Page + +GLFW: Introduction @@ -28,10 +28,10 @@ - + @@ -55,18 +55,26 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
-
-

-Introduction

-

GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan application development. It provides a simple, platform-independent API for creating windows, contexts and surfaces, reading input, handling events, etc.

-

Release notes for version 3.3 list new features, caveats and deprecations.

-

Getting started is a guide for users new to GLFW. It takes you through how to write a small but complete program.

-

There are guides for each section of the API:

+
+
Introduction
+
+
+

GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan application development. It provides a simple, platform-independent API for creating windows, contexts and surfaces, reading input, handling events, etc.

+

Release notes for version 3.4 list new features, caveats and deprecations.

+

Getting started is a guide for users new to GLFW. It takes you through how to write a small but complete program.

+

There are guides for each section of the API:

  • Introduction to the API – initialization, error handling and high-level design
  • Window guide – creating and working with windows and framebuffers
  • @@ -75,18 +83,17 @@ Introduction
  • Monitor guide – enumerating and working with monitors and video modes
  • Input guide – receiving events, polling and processing input
-

Once you have written a program, see Compiling GLFW and Building applications.

-

The reference documentation provides more detailed information about specific functions.

-

Moving from GLFW 2 to 3 explains what has changed and how to update existing code to use the new API.

-

There is a section on Guarantees and limitations for pointer lifetimes, reentrancy, thread safety, event order and backward and forward compatibility.

-

The FAQ answers many common questions about the design, implementation and use of GLFW.

-

Finally, Standards conformance explains what APIs, standards and protocols GLFW uses and what happens when they are not present on a given machine.

-

This documentation was generated with Doxygen. The sources for it are available in both the source distribution and GitHub repository.

+

Once you have written a program, see Compiling GLFW and Building applications.

+

The reference documentation provides more detailed information about specific functions.

+

Moving from GLFW 2 to 3 explains what has changed and how to update existing code to use the new API.

+

There is a section on Guarantees and limitations for pointer lifetimes, reentrancy, thread safety, event order and backward and forward compatibility.

+

Finally, Standards conformance explains what APIs, standards and protocols GLFW uses and what happens when they are not present on a given machine.

+

This documentation was generated with Doxygen. The sources for it are available in both the source distribution and GitHub repository.

diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/news_8dox.html b/src/lib/src/vendor/glfw-3.4/docs/html/input_8md.html similarity index 80% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/news_8dox.html rename to src/lib/src/vendor/glfw-3.4/docs/html/input_8md.html index e200170..21ae1dd 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/news_8dox.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/input_8md.html @@ -4,8 +4,8 @@ - -GLFW: news.dox File Reference + +GLFW: input.md File Reference @@ -28,10 +28,10 @@
- + @@ -54,20 +54,27 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
-
news.dox File Reference
+
input.md File Reference
diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/input_guide.html b/src/lib/src/vendor/glfw-3.4/docs/html/input_guide.html similarity index 55% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/input_guide.html rename to src/lib/src/vendor/glfw-3.4/docs/html/input_guide.html index 9c8c25f..d388671 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/input_guide.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/input_guide.html @@ -4,7 +4,7 @@ - +GLFW: Input guide @@ -28,10 +28,10 @@ - + @@ -54,14 +54,21 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
-
Input guide
+
Input guide

Table of Contents

@@ -100,7 +107,7 @@ $(function() {
  • Path drop input
  • -

    This guide introduces the input related functions of GLFW. For details on a specific function in this category, see the Input reference. There are also guides for the other areas of GLFW.

    +

    This guide introduces the input related functions of GLFW. For details on a specific function in this category, see the Input reference. There are also guides for the other areas of GLFW.

    -

    GLFW provides many kinds of input. While some can only be polled, like time, or only received via callbacks, like scrolling, many provide both callbacks and polling. Callbacks are more work to use than polling but is less CPU intensive and guarantees that you do not miss state changes.

    -

    All input callbacks receive a window handle. By using the window user pointer, you can access non-global structures or objects from your callbacks.

    -

    To get a better feel for how the various events callbacks behave, run the events test program. It register every callback supported by GLFW and prints out all arguments provided for every event, along with time and sequence information.

    +

    GLFW provides many kinds of input. While some can only be polled, like time, or only received via callbacks, like scrolling, many provide both callbacks and polling. Callbacks are more work to use than polling but is less CPU intensive and guarantees that you do not miss state changes.

    +

    All input callbacks receive a window handle. By using the window user pointer, you can access non-global structures or objects from your callbacks.

    +

    To get a better feel for how the various events callbacks behave, run the events test program. It registers every callback supported by GLFW and prints out all arguments provided for every event, along with time and sequence information.

    Event processing

    -

    GLFW needs to poll the window system for events both to provide input to the application and to prove to the window system that the application hasn't locked up. Event processing is normally done each frame after buffer swapping. Even when you have no windows, event polling needs to be done in order to receive monitor and joystick connection events.

    -

    There are three functions for processing pending events. glfwPollEvents, processes only those events that have already been received and then returns immediately.

    +

    GLFW needs to poll the window system for events both to provide input to the application and to prove to the window system that the application hasn't locked up. Event processing is normally done each frame after buffer swapping. Even when you have no windows, event polling needs to be done in order to receive monitor and joystick connection events.

    +

    There are three functions for processing pending events. glfwPollEvents, processes only those events that have already been received and then returns immediately.

    void glfwPollEvents(void)
    Processes all pending events.
    -

    This is the best choice when rendering continuously, like most games do.

    -

    If you only need to update the contents of the window when you receive new input, glfwWaitEvents is a better choice.

    +

    This is the best choice when rendering continuously, like most games do.

    +

    If you only need to update the contents of the window when you receive new input, glfwWaitEvents is a better choice.

    void glfwWaitEvents(void)
    Waits until events are queued and processes them.
    -

    It puts the thread to sleep until at least one event has been received and then processes all received events. This saves a great deal of CPU cycles and is useful for, for example, editing tools.

    -

    If you want to wait for events but have UI elements or other tasks that need periodic updates, glfwWaitEventsTimeout lets you specify a timeout.

    +

    It puts the thread to sleep until at least one event has been received and then processes all received events. This saves a great deal of CPU cycles and is useful for, for example, editing tools.

    +

    If you want to wait for events but have UI elements or other tasks that need periodic updates, glfwWaitEventsTimeout lets you specify a timeout.

    void glfwWaitEventsTimeout(double timeout)
    Waits with timeout until events are queued and processes them.
    -

    It puts the thread to sleep until at least one event has been received, or until the specified number of seconds have elapsed. It then processes any received events.

    -

    If the main thread is sleeping in glfwWaitEvents, you can wake it from another thread by posting an empty event to the event queue with glfwPostEmptyEvent.

    +

    It puts the thread to sleep until at least one event has been received, or until the specified number of seconds have elapsed. It then processes any received events.

    +

    If the main thread is sleeping in glfwWaitEvents, you can wake it from another thread by posting an empty event to the event queue with glfwPostEmptyEvent.

    void glfwPostEmptyEvent(void)
    Posts an empty event to the event queue.
    -

    Do not assume that callbacks will only be called in response to the above functions. While it is necessary to process events in one or more of the ways above, window systems that require GLFW to register callbacks of its own can pass events to GLFW in response to many window system function calls. GLFW will pass those events on to the application callbacks before returning.

    -

    For example, on Windows the system function that glfwSetWindowSize is implemented with will send window size events directly to the event callback that every window has and that GLFW implements for its windows. If you have set a window size callback GLFW will call it in turn with the new size before everything returns back out of the glfwSetWindowSize call.

    +

    Do not assume that callbacks will only be called in response to the above functions. While it is necessary to process events in one or more of the ways above, window systems that require GLFW to register callbacks of its own can pass events to GLFW in response to many window system function calls. GLFW will pass those events on to the application callbacks before returning.

    +

    For example, on Windows the system function that glfwSetWindowSize is implemented with will send window size events directly to the event callback that every window has and that GLFW implements for its windows. If you have set a window size callback GLFW will call it in turn with the new size before everything returns back out of the glfwSetWindowSize call.

    Keyboard input

    -

    GLFW divides keyboard input into two categories; key events and character events. Key events relate to actual physical keyboard keys, whereas character events relate to the Unicode code points generated by pressing some of them.

    -

    Keys and characters do not map 1:1. A single key press may produce several characters, and a single character may require several keys to produce. This may not be the case on your machine, but your users are likely not all using the same keyboard layout, input method or even operating system as you.

    +

    GLFW divides keyboard input into two categories; key events and character events. Key events relate to actual physical keyboard keys, whereas character events relate to the text that is generated by pressing some of them.

    +

    Keys and characters do not map 1:1. A single key press may produce several characters, and a single character may require several keys to produce. This may not be the case on your machine, but your users are likely not all using the same keyboard layout, input method or even operating system as you.

    Key input

    -

    If you wish to be notified when a physical key is pressed or released or when it repeats, set a key callback.

    +

    If you wish to be notified when a physical key is pressed or released or when it repeats, set a key callback.

    glfwSetKeyCallback(window, key_callback);
    GLFWkeyfun glfwSetKeyCallback(GLFWwindow *window, GLFWkeyfun callback)
    Sets the key callback.
    -

    The callback function receives the keyboard key, platform-specific scancode, key action and modifier bits.

    +

    The callback function receives the keyboard key, platform-specific scancode, key action and modifier bits.

    void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
    {
    if (key == GLFW_KEY_E && action == GLFW_PRESS)
    activate_airship();
    }
    -
    #define GLFW_PRESS
    The key or mouse button was pressed.
    Definition: glfw3.h:338
    -
    #define GLFW_KEY_E
    Definition: glfw3.h:416
    -
    struct GLFWwindow GLFWwindow
    Opaque window object.
    Definition: glfw3.h:1185
    -

    The action is one of GLFW_PRESS, GLFW_REPEAT or GLFW_RELEASE. Events with GLFW_PRESS and GLFW_RELEASE actions are emitted for every key press. Most keys will also emit events with GLFW_REPEAT actions while a key is held down.

    -

    Key events with GLFW_REPEAT actions are intended for text input. They are emitted at the rate set in the user's keyboard settings. At most one key is repeated even if several keys are held down. GLFW_REPEAT actions should not be relied on to know which keys are being held down or to drive animation. Instead you should either save the state of relevant keys based on GLFW_PRESS and GLFW_RELEASE actions, or call glfwGetKey, which provides basic cached key state.

    -

    The key will be one of the existing key tokens, or GLFW_KEY_UNKNOWN if GLFW lacks a token for it, for example E-mail and Play keys.

    -

    The scancode is unique for every key, regardless of whether it has a key token. Scancodes are platform-specific but consistent over time, so keys will have different scancodes depending on the platform but they are safe to save to disk. You can query the scancode for any named key on the current platform with glfwGetKeyScancode.

    +
    #define GLFW_PRESS
    The key or mouse button was pressed.
    Definition glfw3.h:338
    +
    #define GLFW_KEY_E
    Definition glfw3.h:418
    +
    struct GLFWwindow GLFWwindow
    Opaque window object.
    Definition glfw3.h:1403
    +

    The action is one of GLFW_PRESS, GLFW_REPEAT or GLFW_RELEASE. Events with GLFW_PRESS and GLFW_RELEASE actions are emitted for every key press. Most keys will also emit events with GLFW_REPEAT actions while a key is held down.

    +

    Note that many keyboards have a limit on how many keys being simultaneous held down that they can detect. This limit is called key rollover.

    +

    Key events with GLFW_REPEAT actions are intended for text input. They are emitted at the rate set in the user's keyboard settings. At most one key is repeated even if several keys are held down. GLFW_REPEAT actions should not be relied on to know which keys are being held down or to drive animation. Instead you should either save the state of relevant keys based on GLFW_PRESS and GLFW_RELEASE actions, or call glfwGetKey, which provides basic cached key state.

    +

    The key will be one of the existing key tokens, or GLFW_KEY_UNKNOWN if GLFW lacks a token for it, for example E-mail and Play keys.

    +

    The scancode is unique for every key, regardless of whether it has a key token. Scancodes are platform-specific but consistent over time, so keys will have different scancodes depending on the platform but they are safe to save to disk. You can query the scancode for any key token supported on the current platform with glfwGetKeyScancode.

    const int scancode = glfwGetKeyScancode(GLFW_KEY_X);
    set_key_mapping(scancode, swap_weapons);
    int glfwGetKeyScancode(int key)
    Returns the platform-specific scancode of the specified key.
    -
    #define GLFW_KEY_X
    Definition: glfw3.h:435
    -

    The last reported state for every named key is also saved in per-window state arrays that can be polled with glfwGetKey.

    +
    #define GLFW_KEY_X
    Definition glfw3.h:437
    +

    The last reported state for every physical key with a key token is also saved in per-window state arrays that can be polled with glfwGetKey.

    int state = glfwGetKey(window, GLFW_KEY_E);
    if (state == GLFW_PRESS)
    {
    activate_airship();
    }
    int glfwGetKey(GLFWwindow *window, int key)
    Returns the last reported state of a keyboard key for the specified window.
    -

    The returned state is one of GLFW_PRESS or GLFW_RELEASE.

    -

    This function only returns cached key event state. It does not poll the system for the current physical state of the key.

    -

    Whenever you poll state, you risk missing the state change you are looking for. If a pressed key is released again before you poll its state, you will have missed the key press. The recommended solution for this is to use a key callback, but there is also the GLFW_STICKY_KEYS input mode.

    +

    The returned state is one of GLFW_PRESS or GLFW_RELEASE.

    +

    This function only returns cached key event state. It does not poll the system for the current state of the physical key. It also does not provide any key repeat information.

    +

    Whenever you poll state, you risk missing the state change you are looking for. If a pressed key is released again before you poll its state, you will have missed the key press. The recommended solution for this is to use a key callback, but there is also the GLFW_STICKY_KEYS input mode.

    -
    #define GLFW_STICKY_KEYS
    Definition: glfw3.h:1049
    -
    #define GLFW_TRUE
    One.
    Definition: glfw3.h:312
    +
    #define GLFW_STICKY_KEYS
    Definition glfw3.h:1153
    +
    #define GLFW_TRUE
    One.
    Definition glfw3.h:312
    void glfwSetInputMode(GLFWwindow *window, int mode, int value)
    Sets an input option for the specified window.
    -

    When sticky keys mode is enabled, the pollable state of a key will remain GLFW_PRESS until the state of that key is polled with glfwGetKey. Once it has been polled, if a key release event had been processed in the meantime, the state will reset to GLFW_RELEASE, otherwise it will remain GLFW_PRESS.

    -

    If you wish to know what the state of the Caps Lock and Num Lock keys was when input events were generated, set the GLFW_LOCK_KEY_MODS input mode.

    +

    When sticky keys mode is enabled, the pollable state of a key will remain GLFW_PRESS until the state of that key is polled with glfwGetKey. Once it has been polled, if a key release event had been processed in the meantime, the state will reset to GLFW_RELEASE, otherwise it will remain GLFW_PRESS.

    +

    If you wish to know what the state of the Caps Lock and Num Lock keys was when input events were generated, set the GLFW_LOCK_KEY_MODS input mode.

    -
    #define GLFW_LOCK_KEY_MODS
    Definition: glfw3.h:1051
    -

    When this input mode is enabled, any callback that receives modifier bits will have the GLFW_MOD_CAPS_LOCK bit set if Caps Lock was on when the event occurred and the GLFW_MOD_NUM_LOCK bit set if Num Lock was on.

    -

    The GLFW_KEY_LAST constant holds the highest value of any named key.

    +
    #define GLFW_LOCK_KEY_MODS
    Definition glfw3.h:1155
    +

    When this input mode is enabled, any callback that receives modifier bits will have the GLFW_MOD_CAPS_LOCK bit set if Caps Lock was on when the event occurred and the GLFW_MOD_NUM_LOCK bit set if Num Lock was on.

    +

    The GLFW_KEY_LAST constant holds the highest value of any key token.

    Text input

    -

    GLFW supports text input in the form of a stream of Unicode code points, as produced by the operating system text input system. Unlike key input, text input obeys keyboard layouts and modifier keys and supports composing characters using dead keys. Once received, you can encode the code points into UTF-8 or any other encoding you prefer.

    -

    Because an unsigned int is 32 bits long on all platforms supported by GLFW, you can treat the code point argument as native endian UTF-32.

    -

    If you wish to offer regular text input, set a character callback.

    +

    GLFW supports text input in the form of a stream of Unicode code points, as produced by the operating system text input system. Unlike key input, text input is affected by keyboard layouts and modifier keys and supports composing characters using dead keys. Once received, you can encode the code points into UTF-8 or any other encoding you prefer.

    +

    Because an unsigned int is 32 bits long on all platforms supported by GLFW, you can treat the code point argument as native endian UTF-32.

    +

    If you wish to offer regular text input, set a character callback.

    glfwSetCharCallback(window, character_callback);
    GLFWcharfun glfwSetCharCallback(GLFWwindow *window, GLFWcharfun callback)
    Sets the Unicode character callback.
    -

    The callback function receives Unicode code points for key events that would have led to regular text input and generally behaves as a standard text field on that platform.

    +

    The callback function receives Unicode code points for key events that would have led to regular text input and generally behaves as a standard text field on that platform.

    void character_callback(GLFWwindow* window, unsigned int codepoint)
    {
    }

    Key names

    -

    If you wish to refer to keys by name, you can query the keyboard layout dependent name of printable keys with glfwGetKeyName.

    +

    If you wish to refer to keys by name, you can query the keyboard layout dependent name of printable keys with glfwGetKeyName.

    const char* key_name = glfwGetKeyName(GLFW_KEY_W, 0);
    show_tutorial_hint("Press %s to move forward", key_name);
    const char * glfwGetKeyName(int key, int scancode)
    Returns the layout-specific name of the specified printable key.
    -
    #define GLFW_KEY_W
    Definition: glfw3.h:434
    -

    This function can handle both keys and scancodes. If the specified key is GLFW_KEY_UNKNOWN then the scancode is used, otherwise it is ignored. This matches the behavior of the key callback, meaning the callback arguments can always be passed unmodified to this function.

    +
    #define GLFW_KEY_W
    Definition glfw3.h:436
    +

    This function can handle both keys and scancodes. If the specified key is GLFW_KEY_UNKNOWN then the scancode is used, otherwise it is ignored. This matches the behavior of the key callback, meaning the callback arguments can always be passed unmodified to this function.

    Mouse input

    -

    Mouse input comes in many forms, including mouse motion, button presses and scrolling offsets. The cursor appearance can also be changed, either to a custom image or a standard cursor shape from the system theme.

    +

    Mouse input comes in many forms, including mouse motion, button presses and scrolling offsets. The cursor appearance can also be changed, either to a custom image or a standard cursor shape from the system theme.

    Cursor position

    -

    If you wish to be notified when the cursor moves over the window, set a cursor position callback.

    +

    If you wish to be notified when the cursor moves over the window, set a cursor position callback.

    glfwSetCursorPosCallback(window, cursor_position_callback);
    GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow *window, GLFWcursorposfun callback)
    Sets the cursor position callback.
    -

    The callback functions receives the cursor position, measured in screen coordinates but relative to the top-left corner of the window content area. On platforms that provide it, the full sub-pixel cursor position is passed on.

    +

    The callback functions receives the cursor position, measured in screen coordinates but relative to the top-left corner of the window content area. On platforms that provide it, the full sub-pixel cursor position is passed on.

    static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos)
    {
    }
    -

    The cursor position is also saved per-window and can be polled with glfwGetCursorPos.

    +

    The cursor position is also saved per-window and can be polled with glfwGetCursorPos.

    double xpos, ypos;
    glfwGetCursorPos(window, &xpos, &ypos);
    void glfwGetCursorPos(GLFWwindow *window, double *xpos, double *ypos)
    Retrieves the position of the cursor relative to the content area of the window.

    Cursor mode

    -

    The GLFW_CURSOR input mode provides several cursor modes for special forms of mouse motion input. By default, the cursor mode is GLFW_CURSOR_NORMAL, meaning the regular arrow cursor (or another cursor set with glfwSetCursor) is used and cursor motion is not limited.

    -

    If you wish to implement mouse motion based camera controls or other input schemes that require unlimited mouse movement, set the cursor mode to GLFW_CURSOR_DISABLED.

    +

    The GLFW_CURSOR input mode provides several cursor modes for special forms of mouse motion input. By default, the cursor mode is GLFW_CURSOR_NORMAL, meaning the regular arrow cursor (or another cursor set with glfwSetCursor) is used and cursor motion is not limited.

    +

    If you wish to implement mouse motion based camera controls or other input schemes that require unlimited mouse movement, set the cursor mode to GLFW_CURSOR_DISABLED.

    -
    #define GLFW_CURSOR_DISABLED
    Definition: glfw3.h:1056
    -
    #define GLFW_CURSOR
    Definition: glfw3.h:1048
    -

    This will hide the cursor and lock it to the specified window. GLFW will then take care of all the details of cursor re-centering and offset calculation and providing the application with a virtual cursor position. This virtual position is provided normally via both the cursor position callback and through polling.

    +
    #define GLFW_CURSOR_DISABLED
    Definition glfw3.h:1160
    +
    #define GLFW_CURSOR
    Definition glfw3.h:1152
    +

    This will hide the cursor and lock it to the specified window. GLFW will then take care of all the details of cursor re-centering and offset calculation and providing the application with a virtual cursor position. This virtual position is provided normally via both the cursor position callback and through polling.

    Note
    You should not implement your own version of this functionality using other features of GLFW. It is not supported and will not work as robustly as GLFW_CURSOR_DISABLED.

    If you only wish the cursor to become hidden when it is over a window but still want it to behave normally, set the cursor mode to GLFW_CURSOR_HIDDEN.

    -
    #define GLFW_CURSOR_HIDDEN
    Definition: glfw3.h:1055
    -

    This mode puts no limit on the motion of the cursor.

    -

    To exit out of either of these special modes, restore the GLFW_CURSOR_NORMAL cursor mode.

    +
    #define GLFW_CURSOR_HIDDEN
    Definition glfw3.h:1159
    +

    This mode puts no limit on the motion of the cursor.

    +

    If you wish the cursor to be visible but confined to the content area of the window, set the cursor mode to GLFW_CURSOR_CAPTURED.

    +
    +
    #define GLFW_CURSOR_CAPTURED
    Definition glfw3.h:1161
    +

    The cursor will behave normally inside the content area but will not be able to leave unless the window loses focus.

    +

    To exit out of either of these special modes, restore the GLFW_CURSOR_NORMAL cursor mode.

    -
    #define GLFW_CURSOR_NORMAL
    Definition: glfw3.h:1054
    -

    +
    #define GLFW_CURSOR_NORMAL
    Definition glfw3.h:1158
    +

    If the cursor was disabled, this will move it back to its last visible position.

    +

    Raw mouse motion

    -

    When the cursor is disabled, raw (unscaled and unaccelerated) mouse motion can be enabled if available.

    -

    Raw mouse motion is closer to the actual motion of the mouse across a surface. It is not affected by the scaling and acceleration applied to the motion of the desktop cursor. That processing is suitable for a cursor while raw motion is better for controlling for example a 3D camera. Because of this, raw mouse motion is only provided when the cursor is disabled.

    -

    Call glfwRawMouseMotionSupported to check if the current machine provides raw motion and set the GLFW_RAW_MOUSE_MOTION input mode to enable it. It is disabled by default.

    +

    When the cursor is disabled, raw (unscaled and unaccelerated) mouse motion can be enabled if available.

    +

    Raw mouse motion is closer to the actual motion of the mouse across a surface. It is not affected by the scaling and acceleration applied to the motion of the desktop cursor. That processing is suitable for a cursor while raw motion is better for controlling for example a 3D camera. Because of this, raw mouse motion is only provided when the cursor is disabled.

    +

    Call glfwRawMouseMotionSupported to check if the current machine provides raw motion and set the GLFW_RAW_MOUSE_MOTION input mode to enable it. It is disabled by default.

    -
    #define GLFW_RAW_MOUSE_MOTION
    Definition: glfw3.h:1052
    +
    #define GLFW_RAW_MOUSE_MOTION
    Definition glfw3.h:1156
    int glfwRawMouseMotionSupported(void)
    Returns whether raw mouse motion is supported.
    -

    If supported, raw mouse motion can be enabled or disabled per-window and at any time but it will only be provided when the cursor is disabled.

    +

    If supported, raw mouse motion can be enabled or disabled per-window and at any time but it will only be provided when the cursor is disabled.

    Cursor objects

    -

    GLFW supports creating both custom and system theme cursor images, encapsulated as GLFWcursor objects. They are created with glfwCreateCursor or glfwCreateStandardCursor and destroyed with glfwDestroyCursor, or glfwTerminate, if any remain.

    +

    GLFW supports creating both custom and system theme cursor images, encapsulated as GLFWcursor objects. They are created with glfwCreateCursor or glfwCreateStandardCursor and destroyed with glfwDestroyCursor, or glfwTerminate, if any remain.

    Custom cursor creation

    -

    A custom cursor is created with glfwCreateCursor, which returns a handle to the created cursor object. For example, this creates a 16x16 white square cursor with the hot-spot in the upper-left corner:

    +

    A custom cursor is created with glfwCreateCursor, which returns a handle to the created cursor object. For example, this creates a 16x16 white square cursor with the hot-spot in the upper-left corner:

    unsigned char pixels[16 * 16 * 4];
    memset(pixels, 0xff, sizeof(pixels));
    -
    GLFWimage image;
    -
    image.width = 16;
    -
    image.height = 16;
    -
    image.pixels = pixels;
    +
    GLFWimage image;
    +
    image.width = 16;
    +
    image.height = 16;
    +
    image.pixels = pixels;
    GLFWcursor* cursor = glfwCreateCursor(&image, 0, 0);
    GLFWcursor * glfwCreateCursor(const GLFWimage *image, int xhot, int yhot)
    Creates a custom cursor.
    -
    struct GLFWcursor GLFWcursor
    Opaque cursor object.
    Definition: glfw3.h:1197
    -
    Image data.
    Definition: glfw3.h:1721
    -
    int height
    Definition: glfw3.h:1727
    -
    unsigned char * pixels
    Definition: glfw3.h:1730
    -
    int width
    Definition: glfw3.h:1724
    -

    If cursor creation fails, NULL will be returned, so it is necessary to check the return value.

    -

    The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits per channel with the red channel first. The pixels are arranged canonically as sequential rows, starting from the top-left corner.

    +
    struct GLFWcursor GLFWcursor
    Opaque cursor object.
    Definition glfw3.h:1415
    +
    Image data.
    Definition glfw3.h:2090
    +
    int height
    Definition glfw3.h:2096
    +
    unsigned char * pixels
    Definition glfw3.h:2099
    +
    int width
    Definition glfw3.h:2093
    +

    If cursor creation fails, NULL will be returned, so it is necessary to check the return value.

    +

    The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits per channel with the red channel first. The pixels are arranged canonically as sequential rows, starting from the top-left corner.

    Standard cursor creation

    -

    A cursor with a standard shape from the current system cursor theme can be can be created with glfwCreateStandardCursor.

    -
    +

    A cursor with a standard shape from the current system cursor theme can be created with glfwCreateStandardCursor.

    +
    GLFWcursor * glfwCreateStandardCursor(int shape)
    Creates a cursor with a standard shape.
    -
    #define GLFW_HRESIZE_CURSOR
    The horizontal resize arrow shape.
    Definition: glfw3.h:1098
    -

    These cursor objects behave in the exact same way as those created with glfwCreateCursor except that the system cursor theme provides the actual image.

    +
    #define GLFW_POINTING_HAND_CURSOR
    The pointing hand cursor shape.
    Definition glfw3.h:1212
    +

    These cursor objects behave in the exact same way as those created with glfwCreateCursor except that the system cursor theme provides the actual image.

    +

    A few of these shapes are not available everywhere. If a shape is unavailable, NULL is returned. See glfwCreateStandardCursor for details.

    Cursor destruction

    -

    When a cursor is no longer needed, destroy it with glfwDestroyCursor.

    +

    When a cursor is no longer needed, destroy it with glfwDestroyCursor.

    void glfwDestroyCursor(GLFWcursor *cursor)
    Destroys a cursor.
    -

    Cursor destruction always succeeds. If the cursor is current for any window, that window will revert to the default cursor. This does not affect the cursor mode. All remaining cursors are destroyed when glfwTerminate is called.

    +

    Cursor destruction always succeeds. If the cursor is current for any window, that window will revert to the default cursor. This does not affect the cursor mode. All remaining cursors are destroyed when glfwTerminate is called.

    Cursor setting

    -

    A cursor can be set as current for a window with glfwSetCursor.

    +

    A cursor can be set as current for a window with glfwSetCursor.

    glfwSetCursor(window, cursor);
    void glfwSetCursor(GLFWwindow *window, GLFWcursor *cursor)
    Sets the cursor for the window.
    -

    Once set, the cursor image will be used as long as the system cursor is over the content area of the window and the cursor mode is set to GLFW_CURSOR_NORMAL.

    -

    A single cursor may be set for any number of windows.

    -

    To revert to the default cursor, set the cursor of that window to NULL.

    +

    Once set, the cursor image will be used as long as the system cursor is over the content area of the window and the cursor mode is set to GLFW_CURSOR_NORMAL.

    +

    A single cursor may be set for any number of windows.

    +

    To revert to the default cursor, set the cursor of that window to NULL.

    glfwSetCursor(window, NULL);
    -

    When a cursor is destroyed, any window that has it set will revert to the default cursor. This does not affect the cursor mode.

    +

    When a cursor is destroyed, any window that has it set will revert to the default cursor. This does not affect the cursor mode.

    Cursor enter/leave events

    -

    If you wish to be notified when the cursor enters or leaves the content area of a window, set a cursor enter/leave callback.

    +

    If you wish to be notified when the cursor enters or leaves the content area of a window, set a cursor enter/leave callback.

    glfwSetCursorEnterCallback(window, cursor_enter_callback);
    GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow *window, GLFWcursorenterfun callback)
    Sets the cursor enter/leave callback.
    -

    The callback function receives the new classification of the cursor.

    +

    The callback function receives the new classification of the cursor.

    void cursor_enter_callback(GLFWwindow* window, int entered)
    {
    if (entered)
    @@ -302,86 +316,86 @@ Cursor enter/leave events
    // The cursor left the content area of the window
    }
    }
    -

    You can query whether the cursor is currently inside the content area of the window with the GLFW_HOVERED window attribute.

    +

    You can query whether the cursor is currently inside the content area of the window with the GLFW_HOVERED window attribute.

    {
    highlight_interface();
    }
    -
    #define GLFW_HOVERED
    Mouse cursor hover window attribute.
    Definition: glfw3.h:855
    +
    #define GLFW_HOVERED
    Mouse cursor hover window attribute.
    Definition glfw3.h:917
    int glfwGetWindowAttrib(GLFWwindow *window, int attrib)
    Returns an attribute of the specified window.

    Mouse button input

    -

    If you wish to be notified when a mouse button is pressed or released, set a mouse button callback.

    +

    If you wish to be notified when a mouse button is pressed or released, set a mouse button callback.

    glfwSetMouseButtonCallback(window, mouse_button_callback);
    GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow *window, GLFWmousebuttonfun callback)
    Sets the mouse button callback.
    -

    The callback function receives the mouse button, button action and modifier bits.

    +

    The callback function receives the mouse button, button action and modifier bits.

    void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
    {
    if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
    popup_menu();
    }
    -
    #define GLFW_MOUSE_BUTTON_RIGHT
    Definition: glfw3.h:581
    -

    The action is one of GLFW_PRESS or GLFW_RELEASE.

    -

    Mouse button states for named buttons are also saved in per-window state arrays that can be polled with glfwGetMouseButton.

    +
    #define GLFW_MOUSE_BUTTON_RIGHT
    Definition glfw3.h:583
    +

    The action is one of GLFW_PRESS or GLFW_RELEASE.

    +

    The last reported state for every supported mouse button is also saved in per-window state arrays that can be polled with glfwGetMouseButton.

    if (state == GLFW_PRESS)
    {
    upgrade_cow();
    }
    -
    #define GLFW_MOUSE_BUTTON_LEFT
    Definition: glfw3.h:580
    +
    #define GLFW_MOUSE_BUTTON_LEFT
    Definition glfw3.h:582
    int glfwGetMouseButton(GLFWwindow *window, int button)
    Returns the last reported state of a mouse button for the specified window.
    -

    The returned state is one of GLFW_PRESS or GLFW_RELEASE.

    -

    This function only returns cached mouse button event state. It does not poll the system for the current state of the mouse button.

    -

    Whenever you poll state, you risk missing the state change you are looking for. If a pressed mouse button is released again before you poll its state, you will have missed the button press. The recommended solution for this is to use a mouse button callback, but there is also the GLFW_STICKY_MOUSE_BUTTONS input mode.

    +

    The returned state is one of GLFW_PRESS or GLFW_RELEASE.

    +

    This function only returns cached mouse button event state. It does not poll the system for the current state of the mouse button.

    +

    Whenever you poll state, you risk missing the state change you are looking for. If a pressed mouse button is released again before you poll its state, you will have missed the button press. The recommended solution for this is to use a mouse button callback, but there is also the GLFW_STICKY_MOUSE_BUTTONS input mode.

    -
    #define GLFW_STICKY_MOUSE_BUTTONS
    Definition: glfw3.h:1050
    -

    When sticky mouse buttons mode is enabled, the pollable state of a mouse button will remain GLFW_PRESS until the state of that button is polled with glfwGetMouseButton. Once it has been polled, if a mouse button release event had been processed in the meantime, the state will reset to GLFW_RELEASE, otherwise it will remain GLFW_PRESS.

    -

    The GLFW_MOUSE_BUTTON_LAST constant holds the highest value of any named button.

    +
    #define GLFW_STICKY_MOUSE_BUTTONS
    Definition glfw3.h:1154
    +

    When sticky mouse buttons mode is enabled, the pollable state of a mouse button will remain GLFW_PRESS until the state of that button is polled with glfwGetMouseButton. Once it has been polled, if a mouse button release event had been processed in the meantime, the state will reset to GLFW_RELEASE, otherwise it will remain GLFW_PRESS.

    +

    The GLFW_MOUSE_BUTTON_LAST constant holds the highest value of any supported mouse button.

    Scroll input

    -

    If you wish to be notified when the user scrolls, whether with a mouse wheel or touchpad gesture, set a scroll callback.

    +

    If you wish to be notified when the user scrolls, whether with a mouse wheel or touchpad gesture, set a scroll callback.

    glfwSetScrollCallback(window, scroll_callback);
    GLFWscrollfun glfwSetScrollCallback(GLFWwindow *window, GLFWscrollfun callback)
    Sets the scroll callback.
    -

    The callback function receives two-dimensional scroll offsets.

    +

    The callback function receives two-dimensional scroll offsets.

    void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
    {
    }
    -

    A normal mouse wheel, being vertical, provides offsets along the Y-axis.

    +

    A normal mouse wheel, being vertical, provides offsets along the Y-axis.

    Joystick input

    -

    The joystick functions expose connected joysticks and controllers, with both referred to as joysticks. It supports up to sixteen joysticks, ranging from GLFW_JOYSTICK_1, GLFW_JOYSTICK_2 up to and including GLFW_JOYSTICK_16 or GLFW_JOYSTICK_LAST. You can test whether a joystick is present with glfwJoystickPresent.

    +

    The joystick functions expose connected joysticks and controllers, with both referred to as joysticks. It supports up to sixteen joysticks, ranging from GLFW_JOYSTICK_1, GLFW_JOYSTICK_2 up to and including GLFW_JOYSTICK_16 or GLFW_JOYSTICK_LAST. You can test whether a joystick is present with glfwJoystickPresent.

    int glfwJoystickPresent(int jid)
    Returns whether the specified joystick is present.
    -
    #define GLFW_JOYSTICK_1
    Definition: glfw3.h:592
    -

    Each joystick has zero or more axes, zero or more buttons, zero or more hats, a human-readable name, a user pointer and an SDL compatible GUID.

    -

    When GLFW is initialized, detected joysticks are added to the beginning of the array. Once a joystick is detected, it keeps its assigned ID until it is disconnected or the library is terminated, so as joysticks are connected and disconnected, there may appear gaps in the IDs.

    -

    Joystick axis, button and hat state is updated when polled and does not require a window to be created or events to be processed. However, if you want joystick connection and disconnection events reliably delivered to the joystick callback then you must process events.

    -

    To see all the properties of all connected joysticks in real-time, run the joysticks test program.

    +
    #define GLFW_JOYSTICK_1
    Definition glfw3.h:594
    +

    Each joystick has zero or more axes, zero or more buttons, zero or more hats, a human-readable name, a user pointer and an SDL compatible GUID.

    +

    Detected joysticks are added to the beginning of the array. Once a joystick is detected, it keeps its assigned ID until it is disconnected or the library is terminated, so as joysticks are connected and disconnected, there may appear gaps in the IDs.

    +

    Joystick axis, button and hat state is updated when polled and does not require a window to be created or events to be processed. However, if you want joystick connection and disconnection events reliably delivered to the joystick callback then you must process events.

    +

    To see all the properties of all connected joysticks in real-time, run the joysticks test program.

    Joystick axis states

    -

    The positions of all axes of a joystick are returned by glfwGetJoystickAxes. See the reference documentation for the lifetime of the returned array.

    +

    The positions of all axes of a joystick are returned by glfwGetJoystickAxes. See the reference documentation for the lifetime of the returned array.

    int count;
    const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_5, &count);
    const float * glfwGetJoystickAxes(int jid, int *count)
    Returns the values of all axes of the specified joystick.
    -
    #define GLFW_JOYSTICK_5
    Definition: glfw3.h:596
    -

    Each element in the returned array is a value between -1.0 and 1.0.

    +
    #define GLFW_JOYSTICK_5
    Definition glfw3.h:598
    +

    Each element in the returned array is a value between -1.0 and 1.0.

    Joystick button states

    -

    The states of all buttons of a joystick are returned by glfwGetJoystickButtons. See the reference documentation for the lifetime of the returned array.

    +

    The states of all buttons of a joystick are returned by glfwGetJoystickButtons. See the reference documentation for the lifetime of the returned array.

    int count;
    const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_3, &count);
    const unsigned char * glfwGetJoystickButtons(int jid, int *count)
    Returns the state of all buttons of the specified joystick.
    -
    #define GLFW_JOYSTICK_3
    Definition: glfw3.h:594
    -

    Each element in the returned array is either GLFW_PRESS or GLFW_RELEASE.

    -

    For backward compatibility with earlier versions that did not have glfwGetJoystickHats, the button array by default also includes all hats. See the reference documentation for glfwGetJoystickButtons for details.

    +
    #define GLFW_JOYSTICK_3
    Definition glfw3.h:596
    +

    Each element in the returned array is either GLFW_PRESS or GLFW_RELEASE.

    +

    For backward compatibility with earlier versions that did not have glfwGetJoystickHats, the button array by default also includes all hats. See the reference documentation for glfwGetJoystickButtons for details.

    Joystick hat states

    -

    The states of all hats are returned by glfwGetJoystickHats. See the reference documentation for the lifetime of the returned array.

    +

    The states of all hats are returned by glfwGetJoystickHats. See the reference documentation for the lifetime of the returned array.

    int count;
    const unsigned char* hats = glfwGetJoystickHats(GLFW_JOYSTICK_7, &count);
    const unsigned char * glfwGetJoystickHats(int jid, int *count)
    Returns the state of all hats of the specified joystick.
    -
    #define GLFW_JOYSTICK_7
    Definition: glfw3.h:598
    -

    Each element in the returned array is one of the following:

    +
    #define GLFW_JOYSTICK_7
    Definition glfw3.h:600
    +

    Each element in the returned array is one of the following:

    [in]windowThe window whose buffers to swap.
    @@ -404,30 +418,30 @@ Joystick hat states
    Name Value
    GLFW_HAT_LEFT_DOWN GLFW_HAT_LEFT | GLFW_HAT_DOWN
    -

    The diagonal directions are bitwise combinations of the primary (up, right, down and left) directions and you can test for these individually by ANDing it with the corresponding direction.

    +

    The diagonal directions are bitwise combinations of the primary (up, right, down and left) directions and you can test for these individually by ANDing it with the corresponding direction.

    if (hats[2] & GLFW_HAT_RIGHT)
    {
    // State of hat 2 could be right-up, right or right-down
    }
    -
    #define GLFW_HAT_RIGHT
    Definition: glfw3.h:357
    -

    For backward compatibility with earlier versions that did not have glfwGetJoystickHats, all hats are by default also included in the button array. See the reference documentation for glfwGetJoystickButtons for details.

    +
    #define GLFW_HAT_RIGHT
    Definition glfw3.h:357
    +

    For backward compatibility with earlier versions that did not have glfwGetJoystickHats, all hats are by default also included in the button array. See the reference documentation for glfwGetJoystickButtons for details.

    Joystick name

    -

    The human-readable, UTF-8 encoded name of a joystick is returned by glfwGetJoystickName. See the reference documentation for the lifetime of the returned string.

    +

    The human-readable, UTF-8 encoded name of a joystick is returned by glfwGetJoystickName. See the reference documentation for the lifetime of the returned string.

    const char * glfwGetJoystickName(int jid)
    Returns the name of the specified joystick.
    -
    #define GLFW_JOYSTICK_4
    Definition: glfw3.h:595
    -

    Joystick names are not guaranteed to be unique. Two joysticks of the same model and make may have the same name. Only the joystick ID is guaranteed to be unique, and only until that joystick is disconnected.

    +
    #define GLFW_JOYSTICK_4
    Definition glfw3.h:597
    +

    Joystick names are not guaranteed to be unique. Two joysticks of the same model and make may have the same name. Only the joystick ID is guaranteed to be unique, and only until that joystick is disconnected.

    Joystick user pointer

    -

    Each joystick has a user pointer that can be set with glfwSetJoystickUserPointer and queried with glfwGetJoystickUserPointer. This can be used for any purpose you need and will not be modified by GLFW. The value will be kept until the joystick is disconnected or until the library is terminated.

    -

    The initial value of the pointer is NULL.

    +

    Each joystick has a user pointer that can be set with glfwSetJoystickUserPointer and queried with glfwGetJoystickUserPointer. This can be used for any purpose you need and will not be modified by GLFW. The value will be kept until the joystick is disconnected or until the library is terminated.

    +

    The initial value of the pointer is NULL.

    Joystick configuration changes

    -

    If you wish to be notified when a joystick is connected or disconnected, set a joystick callback.

    +

    If you wish to be notified when a joystick is connected or disconnected, set a joystick callback.

    glfwSetJoystickCallback(joystick_callback);
    GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun callback)
    Sets the joystick configuration callback.
    -

    The callback function receives the ID of the joystick that has been connected and disconnected and the event that occurred.

    +

    The callback function receives the ID of the joystick that has been connected and disconnected and the event that occurred.

    void joystick_callback(int jid, int event)
    {
    if (event == GLFW_CONNECTED)
    @@ -439,71 +453,71 @@ Joystick configuration changes
    // The joystick was disconnected
    }
    }
    -
    #define GLFW_DISCONNECTED
    Definition: glfw3.h:1107
    -
    #define GLFW_CONNECTED
    Definition: glfw3.h:1106
    -

    For joystick connection and disconnection events to be delivered on all platforms, you need to call one of the event processing functions. Joystick disconnection may also be detected and the callback called by joystick functions. The function will then return whatever it returns for a disconnected joystick.

    -

    Only glfwGetJoystickName and glfwGetJoystickUserPointer will return useful values for a disconnected joystick and only before the monitor callback returns.

    +
    #define GLFW_DISCONNECTED
    Definition glfw3.h:1291
    +
    #define GLFW_CONNECTED
    Definition glfw3.h:1290
    +

    For joystick connection and disconnection events to be delivered on all platforms, you need to call one of the event processing functions. Joystick disconnection may also be detected and the callback called by joystick functions. The function will then return whatever it returns for a disconnected joystick.

    +

    Only glfwGetJoystickName and glfwGetJoystickUserPointer will return useful values for a disconnected joystick and only before the monitor callback returns.

    Gamepad input

    -

    The joystick functions provide unlabeled axes, buttons and hats, with no indication of where they are located on the device. Their order may also vary between platforms even with the same device.

    -

    To solve this problem the SDL community crowdsourced the SDL_GameControllerDB project, a database of mappings from many different devices to an Xbox-like gamepad.

    -

    GLFW supports this mapping format and contains a copy of the mappings available at the time of release. See Gamepad mappings for how to update this at runtime. Mappings will be assigned to joysticks automatically any time a joystick is connected or the mappings are updated.

    -

    You can check whether a joystick is both present and has a gamepad mapping with glfwJoystickIsGamepad.

    +

    The joystick functions provide unlabeled axes, buttons and hats, with no indication of where they are located on the device. Their order may also vary between platforms even with the same device.

    +

    To solve this problem the SDL community crowdsourced the SDL_GameControllerDB project, a database of mappings from many different devices to an Xbox-like gamepad.

    +

    GLFW supports this mapping format and contains a copy of the mappings available at the time of release. See Gamepad mappings for how to update this at runtime. Mappings will be assigned to joysticks automatically any time a joystick is connected or the mappings are updated.

    +

    You can check whether a joystick is both present and has a gamepad mapping with glfwJoystickIsGamepad.

    {
    // Use as gamepad
    }
    int glfwJoystickIsGamepad(int jid)
    Returns whether the specified joystick has a gamepad mapping.
    -
    #define GLFW_JOYSTICK_2
    Definition: glfw3.h:593
    -

    If you are only interested in gamepad input you can use this function instead of glfwJoystickPresent.

    -

    You can query the human-readable name provided by the gamepad mapping with glfwGetGamepadName. This may or may not be the same as the joystick name.

    +
    #define GLFW_JOYSTICK_2
    Definition glfw3.h:595
    +

    If you are only interested in gamepad input you can use this function instead of glfwJoystickPresent.

    +

    You can query the human-readable name provided by the gamepad mapping with glfwGetGamepadName. This may or may not be the same as the joystick name.

    const char* name = glfwGetGamepadName(GLFW_JOYSTICK_7);
    const char * glfwGetGamepadName(int jid)
    Returns the human-readable gamepad name for the specified joystick.
    -

    To retrieve the gamepad state of a joystick, call glfwGetGamepadState.

    -

    To retrieve the gamepad state of a joystick, call glfwGetGamepadState.

    +
    {
    - +
    {
    input_jump();
    }
    - +
    }
    -
    #define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
    Definition: glfw3.h:653
    -
    #define GLFW_GAMEPAD_BUTTON_A
    Definition: glfw3.h:618
    +
    #define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
    Definition glfw3.h:655
    +
    #define GLFW_GAMEPAD_BUTTON_A
    Definition glfw3.h:620
    int glfwGetGamepadState(int jid, GLFWgamepadstate *state)
    Retrieves the state of the specified joystick remapped as a gamepad.
    -
    Gamepad input state.
    Definition: glfw3.h:1745
    -
    unsigned char buttons[15]
    Definition: glfw3.h:1749
    -
    float axes[6]
    Definition: glfw3.h:1753
    -

    The GLFWgamepadstate struct has two arrays; one for button states and one for axis states. The values for each button and axis are the same as for the glfwGetJoystickButtons and glfwGetJoystickAxes functions, i.e. GLFW_PRESS or GLFW_RELEASE for buttons and -1.0 to 1.0 inclusive for axes.

    -

    The sizes of the arrays and the positions within each array are fixed.

    -

    The button indices are GLFW_GAMEPAD_BUTTON_A, GLFW_GAMEPAD_BUTTON_B, GLFW_GAMEPAD_BUTTON_X, GLFW_GAMEPAD_BUTTON_Y, GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, GLFW_GAMEPAD_BUTTON_BACK, GLFW_GAMEPAD_BUTTON_START, GLFW_GAMEPAD_BUTTON_GUIDE, GLFW_GAMEPAD_BUTTON_LEFT_THUMB, GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, GLFW_GAMEPAD_BUTTON_DPAD_DOWN and GLFW_GAMEPAD_BUTTON_DPAD_LEFT.

    -

    For those who prefer, there are also the GLFW_GAMEPAD_BUTTON_CROSS, GLFW_GAMEPAD_BUTTON_CIRCLE, GLFW_GAMEPAD_BUTTON_SQUARE and GLFW_GAMEPAD_BUTTON_TRIANGLE aliases for the A, B, X and Y button indices.

    -

    The axis indices are GLFW_GAMEPAD_AXIS_LEFT_X, GLFW_GAMEPAD_AXIS_LEFT_Y, GLFW_GAMEPAD_AXIS_RIGHT_X, GLFW_GAMEPAD_AXIS_RIGHT_Y, GLFW_GAMEPAD_AXIS_LEFT_TRIGGER and GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER.

    -

    The GLFW_GAMEPAD_BUTTON_LAST and GLFW_GAMEPAD_AXIS_LAST constants equal the largest available index for each array.

    +
    Gamepad input state.
    Definition glfw3.h:2114
    +
    unsigned char buttons[15]
    Definition glfw3.h:2118
    +
    float axes[6]
    Definition glfw3.h:2122
    +

    The GLFWgamepadstate struct has two arrays; one for button states and one for axis states. The values for each button and axis are the same as for the glfwGetJoystickButtons and glfwGetJoystickAxes functions, i.e. GLFW_PRESS or GLFW_RELEASE for buttons and -1.0 to 1.0 inclusive for axes.

    +

    The sizes of the arrays and the positions within each array are fixed.

    +

    The button indices are GLFW_GAMEPAD_BUTTON_A, GLFW_GAMEPAD_BUTTON_B, GLFW_GAMEPAD_BUTTON_X, GLFW_GAMEPAD_BUTTON_Y, GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, GLFW_GAMEPAD_BUTTON_BACK, GLFW_GAMEPAD_BUTTON_START, GLFW_GAMEPAD_BUTTON_GUIDE, GLFW_GAMEPAD_BUTTON_LEFT_THUMB, GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, GLFW_GAMEPAD_BUTTON_DPAD_DOWN and GLFW_GAMEPAD_BUTTON_DPAD_LEFT.

    +

    For those who prefer, there are also the GLFW_GAMEPAD_BUTTON_CROSS, GLFW_GAMEPAD_BUTTON_CIRCLE, GLFW_GAMEPAD_BUTTON_SQUARE and GLFW_GAMEPAD_BUTTON_TRIANGLE aliases for the A, B, X and Y button indices.

    +

    The axis indices are GLFW_GAMEPAD_AXIS_LEFT_X, GLFW_GAMEPAD_AXIS_LEFT_Y, GLFW_GAMEPAD_AXIS_RIGHT_X, GLFW_GAMEPAD_AXIS_RIGHT_Y, GLFW_GAMEPAD_AXIS_LEFT_TRIGGER and GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER.

    +

    The GLFW_GAMEPAD_BUTTON_LAST and GLFW_GAMEPAD_AXIS_LAST constants equal the largest available index for each array.

    Gamepad mappings

    -

    GLFW contains a copy of the mappings available in SDL_GameControllerDB at the time of release. Newer ones can be added at runtime with glfwUpdateGamepadMappings.

    +

    GLFW contains a copy of the mappings available in SDL_GameControllerDB at the time of release. Newer ones can be added at runtime with glfwUpdateGamepadMappings.

    const char* mappings = load_file_contents("game/data/gamecontrollerdb.txt");
    int glfwUpdateGamepadMappings(const char *string)
    Adds the specified SDL_GameControllerDB gamepad mappings.
    -

    This function supports everything from single lines up to and including the unmodified contents of the whole gamecontrollerdb.txt file.

    -

    If you are compiling GLFW from source with CMake you can update the built-in mappings by building the update_mappings target. This runs the GenerateMappings.cmake CMake script, which downloads gamecontrollerdb.txt and regenerates the mappings.h header file.

    -

    Below is a description of the mapping format. Please keep in mind that this description is not authoritative. The format is defined by the SDL and SDL_GameControllerDB projects and their documentation and code takes precedence.

    -

    Each mapping is a single line of comma-separated values describing the GUID, name and layout of the gamepad. Lines that do not begin with a hexadecimal digit are ignored.

    -

    The first value is always the gamepad GUID, a 32 character long hexadecimal string that typically identifies its make, model, revision and the type of connection to the computer. When this information is not available, the GUID is generated using the gamepad name. GLFW uses the SDL 2.0.5+ GUID format but can convert from the older formats.

    -

    The second value is always the human-readable name of the gamepad.

    -

    All subsequent values are in the form <field>:<value> and describe the layout of the mapping. These fields may not all be present and may occur in any order.

    -

    The button fields are a, b, x, y, back, start, guide, dpup, dpright, dpdown, dpleft, leftshoulder, rightshoulder, leftstick and rightstick.

    -

    The axis fields are leftx, lefty, rightx, righty, lefttrigger and righttrigger.

    -

    The value of an axis or button field can be a joystick button, a joystick axis, a hat bitmask or empty. Joystick buttons are specified as bN, for example b2 for the third button. Joystick axes are specified as aN, for example a7 for the eighth button. Joystick hat bit masks are specified as hN.N, for example h0.8 for left on the first hat. More than one bit may be set in the mask.

    -

    Before an axis there may be a + or - range modifier, for example +a3 for the positive half of the fourth axis. This restricts input to only the positive or negative halves of the joystick axis. After an axis or half-axis there may be the ~ inversion modifier, for example a2~ or -a7~. This negates the values of the gamepad axis.

    -

    The hat bit mask match the hat states in the joystick functions.

    -

    There is also the special platform field that specifies which platform the mapping is valid for. Possible values are Windows, Mac OS X and Linux.

    -

    Below is an example of what a gamepad mapping might look like. It is the one built into GLFW for Xbox controllers accessed via the XInput API on Windows. This example has been broken into several lines to fit on the page, but real gamepad mappings must be a single line.

    +

    This function supports everything from single lines up to and including the unmodified contents of the whole gamecontrollerdb.txt file.

    +

    If you are compiling GLFW from source with CMake you can update the built-in mappings by building the update_mappings target. This runs the GenerateMappings.cmake CMake script, which downloads gamecontrollerdb.txt and regenerates the mappings.h header file.

    +

    Below is a description of the mapping format. Please keep in mind that this description is not authoritative. The format is defined by the SDL and SDL_GameControllerDB projects and their documentation and code takes precedence.

    +

    Each mapping is a single line of comma-separated values describing the GUID, name and layout of the gamepad. Lines that do not begin with a hexadecimal digit are ignored.

    +

    The first value is always the gamepad GUID, a 32 character long hexadecimal string that typically identifies its make, model, revision and the type of connection to the computer. When this information is not available, the GUID is generated using the gamepad name. GLFW uses the SDL 2.0.5+ GUID format but can convert from the older formats.

    +

    The second value is always the human-readable name of the gamepad.

    +

    All subsequent values are in the form <field>:<value> and describe the layout of the mapping. These fields may not all be present and may occur in any order.

    +

    The button fields are a, b, x, y, back, start, guide, dpup, dpright, dpdown, dpleft, leftshoulder, rightshoulder, leftstick and rightstick.

    +

    The axis fields are leftx, lefty, rightx, righty, lefttrigger and righttrigger.

    +

    The value of an axis or button field can be a joystick button, a joystick axis, a hat bitmask or empty. Joystick buttons are specified as bN, for example b2 for the third button. Joystick axes are specified as aN, for example a7 for the eighth button. Joystick hat bit masks are specified as hN.N, for example h0.8 for left on the first hat. More than one bit may be set in the mask.

    +

    Before an axis there may be a + or - range modifier, for example +a3 for the positive half of the fourth axis. This restricts input to only the positive or negative halves of the joystick axis. After an axis or half-axis there may be the ~ inversion modifier, for example a2~ or -a7~. This negates the values of the gamepad axis.

    +

    The hat bit mask match the hat states in the joystick functions.

    +

    There is also the special platform field that specifies which platform the mapping is valid for. Possible values are Windows, Mac OS X and Linux.

    +

    Below is an example of what a gamepad mapping might look like. It is the one built into GLFW for Xbox controllers accessed via the XInput API on Windows. This example has been broken into several lines to fit on the page, but real gamepad mappings must be a single line.

    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,
    @@ -511,51 +525,51 @@ Gamepad mappings
    Note
    GLFW does not yet support the output range and modifiers + and - that were recently added to SDL. The input modifiers +, - and ~ are supported and described above.

    Time input

    -

    GLFW provides high-resolution time input, in seconds, with glfwGetTime.

    +

    GLFW provides high-resolution time input, in seconds, with glfwGetTime.

    double seconds = glfwGetTime();
    double glfwGetTime(void)
    Returns the GLFW time.
    -

    It returns the number of seconds since the library was initialized with glfwInit. The platform-specific time sources used typically have micro- or nanosecond resolution.

    -

    You can modify the base time with glfwSetTime.

    +

    It returns the number of seconds since the library was initialized with glfwInit. The platform-specific time sources used typically have micro- or nanosecond resolution.

    +

    You can modify the base time with glfwSetTime.

    void glfwSetTime(double time)
    Sets the GLFW time.
    -

    This sets the time to the specified time, in seconds, and it continues to count from there.

    -

    You can also access the raw timer used to implement the functions above, with glfwGetTimerValue.

    +

    This sets the time to the specified time, in seconds, and it continues to count from there.

    +

    You can also access the raw timer used to implement the functions above, with glfwGetTimerValue.

    uint64_t value = glfwGetTimerValue();
    uint64_t glfwGetTimerValue(void)
    Returns the current value of the raw timer.
    -

    This value is in 1 / frequency seconds. The frequency of the raw timer varies depending on the operating system and hardware. You can query the frequency, in Hz, with glfwGetTimerFrequency.

    +

    This value is in 1 / frequency seconds. The frequency of the raw timer varies depending on the operating system and hardware. You can query the frequency, in Hz, with glfwGetTimerFrequency.

    uint64_t frequency = glfwGetTimerFrequency();
    uint64_t glfwGetTimerFrequency(void)
    Returns the frequency, in Hz, of the raw timer.

    Clipboard input and output

    -

    If the system clipboard contains a UTF-8 encoded string or if it can be converted to one, you can retrieve it with glfwGetClipboardString. See the reference documentation for the lifetime of the returned string.

    +

    If the system clipboard contains a UTF-8 encoded string or if it can be converted to one, you can retrieve it with glfwGetClipboardString. See the reference documentation for the lifetime of the returned string.

    const char* text = glfwGetClipboardString(NULL);
    if (text)
    {
    insert_text(text);
    }
    const char * glfwGetClipboardString(GLFWwindow *window)
    Returns the contents of the clipboard as a string.
    -

    If the clipboard is empty or if its contents could not be converted, NULL is returned.

    -

    The contents of the system clipboard can be set to a UTF-8 encoded string with glfwSetClipboardString.

    +

    If the clipboard is empty or if its contents could not be converted, NULL is returned.

    +

    The contents of the system clipboard can be set to a UTF-8 encoded string with glfwSetClipboardString.

    glfwSetClipboardString(NULL, "A string with words in it");
    void glfwSetClipboardString(GLFWwindow *window, const char *string)
    Sets the clipboard to the specified string.

    Path drop input

    -

    If you wish to receive the paths of files and/or directories dropped on a window, set a file drop callback.

    +

    If you wish to receive the paths of files and/or directories dropped on a window, set a file drop callback.

    glfwSetDropCallback(window, drop_callback);
    GLFWdropfun glfwSetDropCallback(GLFWwindow *window, GLFWdropfun callback)
    Sets the path drop callback.
    -

    The callback function receives an array of paths encoded as UTF-8.

    +

    The callback function receives an array of paths encoded as UTF-8.

    void drop_callback(GLFWwindow* window, int count, const char** paths)
    {
    int i;
    for (i = 0; i < count; i++)
    handle_dropped_file(paths[i]);
    }
    -

    The path array and its strings are only valid until the file drop callback returns, as they may have been generated specifically for that event. You need to make a deep copy of the array if you want to keep the paths.

    +

    The path array and its strings are only valid until the file drop callback returns, as they may have been generated specifically for that event. You need to make a deep copy of the array if you want to keep the paths.

    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/context_8dox.html b/src/lib/src/vendor/glfw-3.4/docs/html/internal_8md.html similarity index 80% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/context_8dox.html rename to src/lib/src/vendor/glfw-3.4/docs/html/internal_8md.html index 89cb318..d5950fd 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/context_8dox.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/internal_8md.html @@ -4,8 +4,8 @@ - -GLFW: context.dox File Reference + +GLFW: internal.md File Reference @@ -28,10 +28,10 @@ - + @@ -54,20 +54,27 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    context.dox File Reference
    +
    internal.md File Reference
    diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/internals_guide.html b/src/lib/src/vendor/glfw-3.4/docs/html/internals_guide.html new file mode 100644 index 0000000..c1c5d9c --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/internals_guide.html @@ -0,0 +1,135 @@ + + + + + + + +GLFW: Internal structure + + + + + + + + + + +
    + + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    +
    Internal structure
    +
    +
    + +

    There are several interfaces inside GLFW. Each interface has its own area of responsibility and its own naming conventions.

    +

    +Public interface

    +

    The most well-known is the public interface, described in the glfw3.h header file. This is implemented in source files shared by all platforms and these files contain no platform-specific code. This code usually ends up calling the platform and internal interfaces to do the actual work.

    +

    The public interface uses the OpenGL naming conventions except with GLFW and glfw instead of GL and gl. For struct members, where OpenGL sets no precedent, it use headless camel case.

    +

    Examples: glfwCreateWindow, GLFWwindow, GLFW_RED_BITS

    +

    +Native interface

    +

    The native interface is a small set of publicly available but platform-specific functions, described in the glfw3native.h header file and used to gain access to the underlying window, context and (on some platforms) display handles used by the platform interface.

    +

    The function names of the native interface are similar to those of the public interface, but embeds the name of the interface that the returned handle is from.

    +

    Examples: glfwGetX11Window, glfwGetWGLContext

    +

    +Internal interface

    +

    The internal interface consists of utility functions used by all other interfaces. It is shared code implemented in the same shared source files as the public and event interfaces. The internal interface is described in the internal.h header file.

    +

    The internal interface is in charge of GLFW's global data, which it stores in a _GLFWlibrary struct named _glfw.

    +

    The internal interface uses the same style as the public interface, except all global names have a leading underscore.

    +

    Examples: _glfwIsValidContextConfig, _GLFWwindow, _glfw.monitorCount

    +

    +Platform interface

    +

    The platform interface implements all platform-specific operations as a service to the public interface. This includes event processing. The platform interface is never directly called by application code and never directly calls application-provided callbacks. It is also prohibited from modifying the platform-independent part of the internal structs. Instead, it calls the event interface when events interesting to GLFW are received.

    +

    The platform interface mostly mirrors those parts of the public interface that needs to perform platform-specific operations on some or all platforms.

    +

    The window system bits of the platform API is called through the _GLFWplatform struct of function pointers, to allow runtime selection of platform. This includes the window and context creation, input and event processing, monitor and Vulkan surface creation parts of GLFW. This is located in the global _glfw struct.

    +

    Examples: _glfw.platform.createWindow

    +

    The timer, threading and module loading bits of the platform API are plain functions with a _glfwPlatform prefix, as these things are independent of what window system is being used.

    +

    Examples: _glfwPlatformGetTimerValue

    +

    The platform interface also defines structs that contain platform-specific global and per-object state. Their names mirror those of the internal interface, except that an interface-specific suffix is added.

    +

    Examples: _GLFWwindowX11, _GLFWcontextWGL

    +

    These structs are incorporated as members into the internal interface structs using special macros that name them after the specific interface used. This prevents shared code from accidentally using these members.

    +

    Examples: window->win32.handle, _glfw.x11.display

    +

    +Event interface

    +

    The event interface is implemented in the same shared source files as the public interface and is responsible for delivering the events it receives to the application, either via callbacks, via window state changes or both.

    +

    The function names of the event interface use a _glfwInput prefix and the ObjectEvent pattern.

    +

    Examples: _glfwInputWindowFocus, _glfwInputCursorPos

    +

    +Static functions

    +

    Static functions may be used by any interface and have no prefixes or suffixes. These use headless camel case.

    +

    Examples: isValidElementForJoystick

    +

    +Configuration macros

    +

    GLFW uses a number of configuration macros to select at compile time which interfaces and code paths to use. They are defined in the GLFW CMake target.

    +

    Configuration macros the same style as tokens in the public interface, except with a leading underscore.

    +

    Examples: _GLFW_WIN32, _GLFW_BUILD_DLL

    +
    +
    + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/intro_8md.html b/src/lib/src/vendor/glfw-3.4/docs/html/intro_8md.html new file mode 100644 index 0000000..521a643 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/intro_8md.html @@ -0,0 +1,81 @@ + + + + + + + +GLFW: intro.md File Reference + + + + + + + + + + +
    + + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    +
    intro.md File Reference
    +
    +
    +
    + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/intro_guide.html b/src/lib/src/vendor/glfw-3.4/docs/html/intro_guide.html new file mode 100644 index 0000000..682a4fc --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/intro_guide.html @@ -0,0 +1,429 @@ + + + + + + + +GLFW: Introduction to the API + + + + + + + + + + +
    + + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    +
    Introduction to the API
    +
    +
    + +

    This guide introduces the basic concepts of GLFW and describes initialization, error handling and API guarantees and limitations. For a broad but shallow tutorial, see Getting started instead. For details on a specific function in this category, see the Initialization, version and error reference.

    +

    There are also guides for the other areas of GLFW.

    + +

    +Initialization and termination

    +

    Before most GLFW functions may be called, the library must be initialized. This initialization checks what features are available on the machine, enumerates monitors, initializes the timer and performs any required platform-specific initialization.

    +

    Only the following functions may be called before the library has been successfully initialized, and only from the main thread.

    + +

    Calling any other function before successful initialization will cause a GLFW_NOT_INITIALIZED error.

    +

    +Initializing GLFW

    +

    The library is initialized with glfwInit, which returns GLFW_FALSE if an error occurred.

    +
    if (!glfwInit())
    +
    {
    +
    // Handle initialization failure
    +
    }
    +
    int glfwInit(void)
    Initializes the GLFW library.
    +

    If any part of initialization fails, any parts that succeeded are terminated as if glfwTerminate had been called. The library only needs to be initialized once and additional calls to an already initialized library will return GLFW_TRUE immediately.

    +

    Once the library has been successfully initialized, it should be terminated before the application exits. Modern systems are very good at freeing resources allocated by programs that exit, but GLFW sometimes has to change global system settings and these might not be restored without termination.

    +

    macOS: When the library is initialized the main menu and dock icon are created. These are not desirable for a command-line only program. The creation of the main menu and dock icon can be disabled with the GLFW_COCOA_MENUBAR init hint.

    +

    +Initialization hints

    +

    Initialization hints are set before glfwInit and affect how the library behaves until termination. Hints are set with glfwInitHint.

    +
    +
    void glfwInitHint(int hint, int value)
    Sets the specified init hint to the desired value.
    +
    #define GLFW_JOYSTICK_HAT_BUTTONS
    Joystick hat buttons init hint.
    Definition glfw3.h:1299
    +
    #define GLFW_FALSE
    Zero.
    Definition glfw3.h:321
    +

    The values you set hints to are never reset by GLFW, but they only take effect during initialization. Once GLFW has been initialized, any values you set will be ignored until the library is terminated and initialized again.

    +

    Some hints are platform specific. These may be set on any platform but they will only affect their specific platform. Other platforms will ignore them. Setting these hints requires no platform specific headers or functions.

    +

    +Shared init hints

    +

    GLFW_PLATFORM specifies the platform to use for windowing and input. Possible values are GLFW_ANY_PLATFORM, GLFW_PLATFORM_WIN32, GLFW_PLATFORM_COCOA, GLFW_PLATFORM_WAYLAND, GLFW_PLATFORM_X11 and GLFW_PLATFORM_NULL. The default value is GLFW_ANY_PLATFORM, which will choose any platform the library includes support for except for the Null backend.

    +

    GLFW_JOYSTICK_HAT_BUTTONS specifies whether to also expose joystick hats as buttons, for compatibility with earlier versions of GLFW that did not have glfwGetJoystickHats. Possible values are GLFW_TRUE and GLFW_FALSE.

    +

    GLFW_ANGLE_PLATFORM_TYPE specifies the platform type (rendering backend) to request when using OpenGL ES and EGL via ANGLE. If the requested platform type is unavailable, ANGLE will use its default. Possible values are one of GLFW_ANGLE_PLATFORM_TYPE_NONE, GLFW_ANGLE_PLATFORM_TYPE_OPENGL, GLFW_ANGLE_PLATFORM_TYPE_OPENGLES, GLFW_ANGLE_PLATFORM_TYPE_D3D9, GLFW_ANGLE_PLATFORM_TYPE_D3D11, GLFW_ANGLE_PLATFORM_TYPE_VULKAN and GLFW_ANGLE_PLATFORM_TYPE_METAL.

    +

    The ANGLE platform type is specified via the EGL_ANGLE_platform_angle extension. This extension is not used if this hint is GLFW_ANGLE_PLATFORM_TYPE_NONE, which is the default value.

    +

    +macOS specific init hints

    +

    GLFW_COCOA_CHDIR_RESOURCES specifies whether to set the current directory to the application to the Contents/Resources subdirectory of the application's bundle, if present. Possible values are GLFW_TRUE and GLFW_FALSE. This is ignored on other platforms.

    +

    GLFW_COCOA_MENUBAR specifies whether to create the menu bar and dock icon when GLFW is initialized. This applies whether the menu bar is created from a nib or manually by GLFW. Possible values are GLFW_TRUE and GLFW_FALSE. This is ignored on other platforms.

    +

    +Wayland specific init hints

    +

    GLFW_WAYLAND_LIBDECOR specifies whether to use libdecor for window decorations where available. Possible values are GLFW_WAYLAND_PREFER_LIBDECOR and GLFW_WAYLAND_DISABLE_LIBDECOR. This is ignored on other platforms.

    +

    +X11 specific init hints

    +

    GLFW_X11_XCB_VULKAN_SURFACE specifies whether to prefer the VK_KHR_xcb_surface extension for creating Vulkan surfaces, or whether to use the VK_KHR_xlib_surface extension. Possible values are GLFW_TRUE and GLFW_FALSE. This is ignored on other platforms.

    +

    +Supported and default values

    + + + + + + + + + + + + + + + + + +
    Initialization hint Default value Supported values
    GLFW_PLATFORM GLFW_ANY_PLATFORM GLFW_ANY_PLATFORM, GLFW_PLATFORM_WIN32, GLFW_PLATFORM_COCOA, GLFW_PLATFORM_WAYLAND, GLFW_PLATFORM_X11 or GLFW_PLATFORM_NULL
    GLFW_JOYSTICK_HAT_BUTTONS GLFW_TRUE GLFW_TRUE or GLFW_FALSE
    GLFW_ANGLE_PLATFORM_TYPE GLFW_ANGLE_PLATFORM_TYPE_NONE GLFW_ANGLE_PLATFORM_TYPE_NONE, GLFW_ANGLE_PLATFORM_TYPE_OPENGL, GLFW_ANGLE_PLATFORM_TYPE_OPENGLES, GLFW_ANGLE_PLATFORM_TYPE_D3D9, GLFW_ANGLE_PLATFORM_TYPE_D3D11, GLFW_ANGLE_PLATFORM_TYPE_VULKAN or GLFW_ANGLE_PLATFORM_TYPE_METAL
    GLFW_COCOA_CHDIR_RESOURCES GLFW_TRUE GLFW_TRUE or GLFW_FALSE
    GLFW_COCOA_MENUBAR GLFW_TRUE GLFW_TRUE or GLFW_FALSE
    GLFW_WAYLAND_LIBDECOR GLFW_WAYLAND_PREFER_LIBDECOR GLFW_WAYLAND_PREFER_LIBDECOR or GLFW_WAYLAND_DISABLE_LIBDECOR
    GLFW_X11_XCB_VULKAN_SURFACE GLFW_TRUE GLFW_TRUE or GLFW_FALSE
    +

    +Runtime platform selection

    +

    GLFW can be compiled for more than one platform (window system) at once. This lets a single library binary support both Wayland and X11 on Linux and other Unix-like systems.

    +

    You can control platform selection via the GLFW_PLATFORM initialization hint. By default, this is set to GLFW_ANY_PLATFORM, which will look for supported window systems in order of priority and select the first one it finds. It can also be set to any specific platform to have GLFW only look for that one.

    +
    +
    #define GLFW_PLATFORM
    Platform selection init hint.
    Definition glfw3.h:1309
    +
    #define GLFW_PLATFORM_X11
    Definition glfw3.h:1342
    +

    This mechanism also provides the Null platform, which is always supported but needs to be explicitly requested. This platform is effectively a stub, emulating a window system on a single 1080p monitor, but will not interact with any actual window system.

    +
    +
    #define GLFW_PLATFORM_NULL
    Definition glfw3.h:1343
    +

    You can test whether a library binary was compiled with support for a specific platform with glfwPlatformSupported.

    +
    + +
    int glfwPlatformSupported(int platform)
    Returns whether the library includes support for the specified platform.
    +
    #define GLFW_PLATFORM_WAYLAND
    Definition glfw3.h:1341
    +

    Once GLFW has been initialized, you can query which platform was selected with glfwGetPlatform.

    +
    int platform = glfwGetPlatform();
    +
    int glfwGetPlatform(void)
    Returns the currently selected platform.
    +

    If you are using any native access functions, especially on Linux and other Unix-like systems, then you may need to check that you are calling the ones matching the selected platform.

    +

    +Custom heap memory allocator

    +

    The heap memory allocator can be customized before initialization with glfwInitAllocator.

    +
    GLFWallocator allocator;
    +
    allocator.allocate = my_malloc;
    +
    allocator.reallocate = my_realloc;
    +
    allocator.deallocate = my_free;
    +
    allocator.user = NULL;
    +
    +
    glfwInitAllocator(&allocator);
    +
    void glfwInitAllocator(const GLFWallocator *allocator)
    Sets the init allocator to the desired value.
    +
    Custom heap memory allocator.
    Definition glfw3.h:2138
    +
    GLFWallocatefun allocate
    Definition glfw3.h:2142
    +
    GLFWdeallocatefun deallocate
    Definition glfw3.h:2150
    +
    GLFWreallocatefun reallocate
    Definition glfw3.h:2146
    +
    void * user
    Definition glfw3.h:2154
    +

    The allocator will be made active at the beginning of initialization and will be used by GLFW until the library has been fully terminated. Any allocator set after initialization will be picked up only at the next initialization.

    +

    The allocator will only be used for allocations that would have been made with the C standard library. Memory allocations that must be made with platform specific APIs will still use those.

    +

    The allocation function must have a signature matching GLFWallocatefun. It receives the desired size, in bytes, and the user pointer passed to glfwInitAllocator and returns the address to the allocated memory block.

    +
    void* my_malloc(size_t size, void* user)
    +
    {
    +
    ...
    +
    }
    +

    The documentation for GLFWallocatefun also lists the requirements and limitations for an allocation function. If the active one does not meet all of these, GLFW may fail.

    +

    The reallocation function must have a function signature matching GLFWreallocatefun. It receives the memory block to be reallocated, the new desired size, in bytes, and the user pointer passed to glfwInitAllocator and returns the address to the resized memory block.

    +
    void* my_realloc(void* block, size_t size, void* user)
    +
    {
    +
    ...
    +
    }
    +

    The documentation for GLFWreallocatefun also lists the requirements and limitations for a reallocation function. If the active one does not meet all of these, GLFW may fail.

    +

    The deallocation function must have a function signature matching GLFWdeallocatefun. It receives the memory block to be deallocated and the user pointer passed to glfwInitAllocator.

    +
    void my_free(void* block, void* user)
    +
    {
    +
    ...
    +
    }
    +

    The documentation for GLFWdeallocatefun also lists the requirements and limitations for a deallocation function. If the active one does not meet all of these, GLFW may fail.

    +

    +Terminating GLFW

    +

    Before your application exits, you should terminate the GLFW library if it has been initialized. This is done with glfwTerminate.

    +
    +
    void glfwTerminate(void)
    Terminates the GLFW library.
    +

    This will destroy any remaining window, monitor and cursor objects, restore any modified gamma ramps, re-enable the screensaver if it had been disabled and free any other resources allocated by GLFW.

    +

    Once the library is terminated, it is as if it had never been initialized, therefore you will need to initialize it again before being able to use GLFW. If the library was not initialized or had already been terminated, it returns immediately.

    +

    +Error handling

    +

    Some GLFW functions have return values that indicate an error, but this is often not very helpful when trying to figure out what happened or why it occurred. Other functions have no return value reserved for errors, so error notification needs a separate channel. Finally, far from all GLFW functions have return values.

    +

    The last error code for the calling thread can be queried at any time with glfwGetError.

    +
    int code = glfwGetError(NULL);
    +
    +
    if (code != GLFW_NO_ERROR)
    +
    handle_error(code);
    +
    #define GLFW_NO_ERROR
    No error has occurred.
    Definition glfw3.h:672
    +
    int glfwGetError(const char **description)
    Returns and clears the last error for the calling thread.
    +

    If no error has occurred since the last call, GLFW_NO_ERROR (zero) is returned. The error is cleared before the function returns.

    +

    The error code indicates the general category of the error. Some error codes, such as GLFW_NOT_INITIALIZED has only a single meaning, whereas others like GLFW_PLATFORM_ERROR are used for many different errors.

    +

    GLFW often has more information about an error than its general category. You can retrieve a UTF-8 encoded human-readable description along with the error code. If no error has occurred since the last call, the description is set to NULL.

    +
    const char* description;
    +
    int code = glfwGetError(&description);
    +
    +
    if (description)
    +
    display_error_message(code, description);
    +

    The retrieved description string is only valid until the next error occurs. This means you must make a copy of it if you want to keep it.

    +

    You can also set an error callback, which will be called each time an error occurs. It is set with glfwSetErrorCallback.

    +
    glfwSetErrorCallback(error_callback);
    +
    GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun callback)
    Sets the error callback.
    +

    The error callback receives the same error code and human-readable description returned by glfwGetError.

    +
    void error_callback(int code, const char* description)
    +
    {
    +
    display_error_message(code, description);
    +
    }
    +

    The error callback is called after the error is stored, so calling glfwGetError from within the error callback returns the same values as the callback argument.

    +

    The description string passed to the callback is only valid until the error callback returns. This means you must make a copy of it if you want to keep it.

    +

    Reported errors are never fatal. As long as GLFW was successfully initialized, it will remain initialized and in a safe state until terminated regardless of how many errors occur. If an error occurs during initialization that causes glfwInit to fail, any part of the library that was initialized will be safely terminated.

    +

    Do not rely on a currently invalid call to generate a specific error, as in the future that same call may generate a different error or become valid.

    +

    +Coordinate systems

    +

    GLFW has two primary coordinate systems: the virtual screen and the window content area or content area. Both use the same unit: virtual screen coordinates, or just screen coordinates, which don't necessarily correspond to pixels.

    +

    +

    Both the virtual screen and the content area coordinate systems have the X-axis pointing to the right and the Y-axis pointing down.

    +

    Window and monitor positions are specified as the position of the upper-left corners of their content areas relative to the virtual screen, while cursor positions are specified relative to a window's content area.

    +

    Because the origin of the window's content area coordinate system is also the point from which the window position is specified, you can translate content area coordinates to the virtual screen by adding the window position. The window frame, when present, extends out from the content area but does not affect the window position.

    +

    Almost all positions and sizes in GLFW are measured in screen coordinates relative to one of the two origins above. This includes cursor positions, window positions and sizes, window frame sizes, monitor positions and video mode resolutions.

    +

    Two exceptions are the monitor physical size, which is measured in millimetres, and framebuffer size, which is measured in pixels.

    +

    Pixels and screen coordinates may map 1:1 on your machine, but they won't on every other machine, for example on a Mac with a Retina display. The ratio between screen coordinates and pixels may also change at run-time depending on which monitor the window is currently considered to be on.

    +

    +Guarantees and limitations

    +

    This section describes the conditions under which GLFW can be expected to function, barring bugs in the operating system or drivers. Use of GLFW outside these limits may work on some platforms, or on some machines, or some of the time, or on some versions of GLFW, but it may break at any time and this will not be considered a bug.

    +

    +Pointer lifetimes

    +

    GLFW will never free any pointer you provide to it, and you must never free any pointer it provides to you.

    +

    Many GLFW functions return pointers to dynamically allocated structures, strings or arrays, and some callbacks are provided with strings or arrays. These are always managed by GLFW and should never be freed by the application. The lifetime of these pointers is documented for each GLFW function and callback. If you need to keep this data, you must copy it before its lifetime expires.

    +

    Many GLFW functions accept pointers to structures or strings allocated by the application. These are never freed by GLFW and are always the responsibility of the application. If GLFW needs to keep the data in these structures or strings, it is copied before the function returns.

    +

    Pointer lifetimes are guaranteed not to be shortened in future minor or patch releases.

    +

    +Reentrancy

    +

    GLFW event processing and object destruction are not reentrant. This means that the following functions must not be called from any callback function:

    + +

    These functions may be made reentrant in future minor or patch releases, but functions not on this list will not be made non-reentrant.

    +

    +Thread safety

    +

    Most GLFW functions must only be called from the main thread (the thread that calls main), but some may be called from any thread once the library has been initialized. Before initialization the whole library is thread-unsafe.

    +

    The reference documentation for every GLFW function states whether it is limited to the main thread.

    +

    Initialization, termination, event processing and the creation and destruction of windows, cursors and OpenGL and OpenGL ES contexts are all restricted to the main thread due to limitations of one or several platforms.

    +

    Because event processing must be performed on the main thread, all callbacks except for the error callback will only be called on that thread. The error callback may be called on any thread, as any GLFW function may generate errors.

    +

    The error code and description may be queried from any thread.

    + +

    Empty events may be posted from any thread.

    + +

    The window user pointer and close flag may be read and written from any thread, but this is not synchronized by GLFW.

    + +

    These functions for working with OpenGL and OpenGL ES contexts may be called from any thread, but the window object is not synchronized by GLFW.

    + +

    The raw timer functions may be called from any thread.

    + +

    The regular timer may be used from any thread, but reading and writing the timer offset is not synchronized by GLFW.

    + +

    Library version information may be queried from any thread.

    + +

    Platform information may be queried from any thread.

    + +

    All Vulkan related functions may be called from any thread.

    + +

    GLFW uses synchronization objects internally only to manage the per-thread context and error states. Additional synchronization is left to the application.

    +

    Functions that may currently be called from any thread will always remain so, but functions that are currently limited to the main thread may be updated to allow calls from any thread in future releases.

    +

    +Version compatibility

    +

    GLFW uses Semantic Versioning. This guarantees source and binary backward compatibility with earlier minor versions of the API. This means that you can drop in a newer version of the library and existing programs will continue to compile and existing binaries will continue to run.

    +

    Once a function or constant has been added, the signature of that function or value of that constant will remain unchanged until the next major version of GLFW. No compatibility of any kind is guaranteed between major versions.

    +

    Undocumented behavior, i.e. behavior that is not described in the documentation, may change at any time until it is documented.

    +

    If the reference documentation and the implementation differ, the reference documentation will almost always take precedence and the implementation will be fixed in the next release. The reference documentation will also take precedence over anything stated in a guide.

    +

    +Event order

    +

    The order of arrival of related events is not guaranteed to be consistent across platforms. The exception is synthetic key and mouse button release events, which are always delivered after the window defocus event.

    +

    +Version management

    +

    GLFW provides mechanisms for identifying what version of GLFW your application was compiled against as well as what version it is currently running against. If you are loading GLFW dynamically (not just linking dynamically), you can use this to verify that the library binary is compatible with your application.

    +

    +Compile-time version

    +

    The compile-time version of GLFW is provided by the GLFW header with the GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR and GLFW_VERSION_REVISION macros.

    +
    printf("Compiled against GLFW %i.%i.%i\n",
    + + + +
    #define GLFW_VERSION_MAJOR
    The major version number of the GLFW header.
    Definition glfw3.h:287
    +
    #define GLFW_VERSION_REVISION
    The revision number of the GLFW header.
    Definition glfw3.h:301
    +
    #define GLFW_VERSION_MINOR
    The minor version number of the GLFW header.
    Definition glfw3.h:294
    +

    +Run-time version

    +

    The run-time version can be retrieved with glfwGetVersion, a function that may be called regardless of whether GLFW is initialized.

    +
    int major, minor, revision;
    +
    glfwGetVersion(&major, &minor, &revision);
    +
    +
    printf("Running against GLFW %i.%i.%i\n", major, minor, revision);
    +
    void glfwGetVersion(int *major, int *minor, int *rev)
    Retrieves the version of the GLFW library.
    +

    +Version string

    +

    GLFW 3 also provides a compile-time generated version string that describes the version, platform, compiler and any platform-specific compile-time options. This is primarily intended for submitting bug reports, to allow developers to see which code paths are enabled in a binary.

    +

    The version string is returned by glfwGetVersionString, a function that may be called regardless of whether GLFW is initialized.

    +

    Do not use the version string to parse the GLFW library version. The glfwGetVersion function already provides the version of the running library binary.

    +

    Do not use the version string to parse what platforms are supported. The glfwPlatformSupported function lets you query platform support.

    +

    GLFW 3.4: The format of this string was changed to support the addition of runtime platform selection.

    +

    The format of the string is as follows:

      +
    • The version of GLFW
    • +
    • For each supported platform:
        +
      • The name of the window system API
      • +
      • The name of the window system specific context creation API, if applicable
      • +
      +
    • +
    • The names of the always supported context creation APIs EGL and OSMesa
    • +
    • Any additional compile-time options, APIs and (on Windows) what compiler was used
    • +
    +

    For example, compiling GLFW 3.4 with MinGW as a DLL for Windows, may result in a version string like this:

    +
    3.4.0 Win32 WGL Null EGL OSMesa MinGW DLL
    +

    Compiling GLFW as a static library for Linux, with both Wayland and X11 enabled, may result in a version string like this:

    +
    3.4.0 Wayland X11 GLX Null EGL OSMesa monotonic
    +
    +
    + + + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/jquery.js b/src/lib/src/vendor/glfw-3.4/docs/html/jquery.js similarity index 77% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/jquery.js rename to src/lib/src/vendor/glfw-3.4/docs/html/jquery.js index c9ed3d9..1dffb65 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/jquery.js +++ b/src/lib/src/vendor/glfw-3.4/docs/html/jquery.js @@ -1,12 +1,11 @@ /*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),h=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):h=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
    ",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
    "),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,(i>0||u>a(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
    ").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("
    "),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
    "),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element -},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),m&&(p-=l),g&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable});/** +!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(y){"use strict";y.ui=y.ui||{};y.ui.version="1.13.2";var n,i=0,h=Array.prototype.hasOwnProperty,a=Array.prototype.slice;y.cleanData=(n=y.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)(e=y._data(i,"events"))&&e.remove&&y(i).triggerHandler("remove");n(t)}),y.widget=function(t,i,e){var s,n,o,h={},a=t.split(".")[0],r=a+"-"+(t=t.split(".")[1]);return e||(e=i,i=y.Widget),Array.isArray(e)&&(e=y.extend.apply(null,[{}].concat(e))),y.expr.pseudos[r.toLowerCase()]=function(t){return!!y.data(t,r)},y[a]=y[a]||{},s=y[a][t],n=y[a][t]=function(t,e){if(!this||!this._createWidget)return new n(t,e);arguments.length&&this._createWidget(t,e)},y.extend(n,s,{version:e.version,_proto:y.extend({},e),_childConstructors:[]}),(o=new i).options=y.widget.extend({},o.options),y.each(e,function(e,s){function n(){return i.prototype[e].apply(this,arguments)}function o(t){return i.prototype[e].apply(this,t)}h[e]="function"==typeof s?function(){var t,e=this._super,i=this._superApply;return this._super=n,this._superApply=o,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}:s}),n.prototype=y.widget.extend(o,{widgetEventPrefix:s&&o.widgetEventPrefix||t},h,{constructor:n,namespace:a,widgetName:t,widgetFullName:r}),s?(y.each(s._childConstructors,function(t,e){var i=e.prototype;y.widget(i.namespace+"."+i.widgetName,n,e._proto)}),delete s._childConstructors):i._childConstructors.push(n),y.widget.bridge(t,n),n},y.widget.extend=function(t){for(var e,i,s=a.call(arguments,1),n=0,o=s.length;n",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=y(e||this.defaultElement||this)[0],this.element=y(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=y(),this.hoverable=y(),this.focusable=y(),this.classesElementLookup={},e!==this&&(y.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=y(e.style?e.ownerDocument:e.document||e),this.window=y(this.document[0].defaultView||this.document[0].parentWindow)),this.options=y.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:y.noop,_create:y.noop,_init:y.noop,destroy:function(){var i=this;this._destroy(),y.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:y.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return y.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=y.widget.extend({},this.options[t]),n=0;n
    "),i=e.children()[0];return y("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthx(D(s),D(n))?o.important="horizontal":o.important="vertical",p.using.call(this,t,o)}),h.offset(y.extend(l,{using:t}))})},y.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,h=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),y.ui.plugin={add:function(t,e,i){var s,n=y.ui[t].prototype;for(s in i)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;n
    ").css({overflow:"hidden",position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(t),this._proportionallyResize()),this._setupHandles(),e.autoHide&&y(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy(),this._addedHandles.remove();function t(t){y(t).removeData("resizable").removeData("ui-resizable").off(".resizable")}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;case"aspectRatio":this._aspectRatio=!!e}},_setupHandles:function(){var t,e,i,s,n,o=this.options,h=this;if(this.handles=o.handles||(y(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=y(),this._addedHandles=y(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e"),this._addClass(n,"ui-resizable-handle "+s),n.css({zIndex:o.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.children(this.handles[t]).length||(this.element.append(n),this._addedHandles=this._addedHandles.add(n));this._renderAxis=function(t){var e,i,s;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=y(this.handles[e]),this._on(this.handles[e],{mousedown:h._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(i=y(this.handles[e],this.element),s=/sw|ne|nw|se|n|s/.test(e)?i.outerHeight():i.outerWidth(),i=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){h.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),h.axis=n&&n[1]?n[1]:"se")}),o.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._addedHandles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=y(this.handles[e])[0])!==t.target&&!y.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s=this.options,n=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),s.containment&&(e+=y(s.containment).scrollLeft()||0,i+=y(s.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:n.width(),height:n.height()},this.originalSize=this._helper?{width:n.outerWidth(),height:n.outerHeight()}:{width:n.width(),height:n.height()},this.sizeDiff={width:n.outerWidth()-n.width(),height:n.outerHeight()-n.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof s.aspectRatio?s.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=y(".ui-resizable-"+this.axis).css("cursor"),y("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e=this.originalMousePosition,i=this.axis,s=t.pageX-e.left||0,e=t.pageY-e.top||0,i=this._change[i];return this._updatePrevProperties(),i&&(e=i.apply(this,[t,s,e]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(e=this._updateRatio(e,t)),e=this._respectSize(e,t),this._updateCache(e),this._propagate("resize",t),e=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),y.isEmptyObject(e)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,n=this.options,o=this;return this._helper&&(s=(e=(i=this._proportionallyResizeElements).length&&/textarea/i.test(i[0].nodeName))&&this._hasScroll(i[0],"left")?0:o.sizeDiff.height,i=e?0:o.sizeDiff.width,e={width:o.helper.width()-i,height:o.helper.height()-s},i=parseFloat(o.element.css("left"))+(o.position.left-o.originalPosition.left)||null,s=parseFloat(o.element.css("top"))+(o.position.top-o.originalPosition.top)||null,n.animate||this.element.css(y.extend(e,{top:s,left:i})),o.helper.height(o.size.height),o.helper.width(o.size.width),this._helper&&!n.animate&&this._proportionallyResize()),y("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s=this.options,n={minWidth:this._isNumber(s.minWidth)?s.minWidth:0,maxWidth:this._isNumber(s.maxWidth)?s.maxWidth:1/0,minHeight:this._isNumber(s.minHeight)?s.minHeight:0,maxHeight:this._isNumber(s.maxHeight)?s.maxHeight:1/0};(this._aspectRatio||t)&&(e=n.minHeight*this.aspectRatio,i=n.minWidth/this.aspectRatio,s=n.maxHeight*this.aspectRatio,t=n.maxWidth/this.aspectRatio,e>n.minWidth&&(n.minWidth=e),i>n.minHeight&&(n.minHeight=i),st.width,h=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,r=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),i=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),h&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=a-e.minWidth),s&&l&&(t.left=a-e.maxWidth),h&&i&&(t.top=r-e.minHeight),n&&i&&(t.top=r-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e").css({overflow:"hidden"}),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){y.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),y.ui.plugin.add("resizable","animate",{stop:function(e){var i=y(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,n=s.length&&/textarea/i.test(s[0].nodeName),o=n&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,h=n?0:i.sizeDiff.width,n={width:i.size.width-h,height:i.size.height-o},h=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,o=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(y.extend(n,o&&h?{top:o,left:h}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&y(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),y.ui.plugin.add("resizable","containment",{start:function(){var i,s,n=y(this).resizable("instance"),t=n.options,e=n.element,o=t.containment,h=o instanceof y?o.get(0):/parent/.test(o)?e.parent().get(0):o;h&&(n.containerElement=y(h),/document/.test(o)||o===document?(n.containerOffset={left:0,top:0},n.containerPosition={left:0,top:0},n.parentData={element:y(document),left:0,top:0,width:y(document).width(),height:y(document).height()||document.body.parentNode.scrollHeight}):(i=y(h),s=[],y(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=n._num(i.css("padding"+e))}),n.containerOffset=i.offset(),n.containerPosition=i.position(),n.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},t=n.containerOffset,e=n.containerSize.height,o=n.containerSize.width,o=n._hasScroll(h,"left")?h.scrollWidth:o,e=n._hasScroll(h)?h.scrollHeight:e,n.parentData={element:h,left:t.left,top:t.top,width:o,height:e}))},resize:function(t){var e=y(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.position,o=e._aspectRatio||t.shiftKey,h={top:0,left:0},a=e.containerElement,t=!0;a[0]!==document&&/static/.test(a.css("position"))&&(h=s),n.left<(e._helper?s.left:0)&&(e.size.width=e.size.width+(e._helper?e.position.left-s.left:e.position.left-h.left),o&&(e.size.height=e.size.width/e.aspectRatio,t=!1),e.position.left=i.helper?s.left:0),n.top<(e._helper?s.top:0)&&(e.size.height=e.size.height+(e._helper?e.position.top-s.top:e.position.top),o&&(e.size.width=e.size.height*e.aspectRatio,t=!1),e.position.top=e._helper?s.top:0),i=e.containerElement.get(0)===e.element.parent().get(0),n=/relative|absolute/.test(e.containerElement.css("position")),i&&n?(e.offset.left=e.parentData.left+e.position.left,e.offset.top=e.parentData.top+e.position.top):(e.offset.left=e.element.offset().left,e.offset.top=e.element.offset().top),n=Math.abs(e.sizeDiff.width+(e._helper?e.offset.left-h.left:e.offset.left-s.left)),s=Math.abs(e.sizeDiff.height+(e._helper?e.offset.top-h.top:e.offset.top-s.top)),n+e.size.width>=e.parentData.width&&(e.size.width=e.parentData.width-n,o&&(e.size.height=e.size.width/e.aspectRatio,t=!1)),s+e.size.height>=e.parentData.height&&(e.size.height=e.parentData.height-s,o&&(e.size.width=e.size.height*e.aspectRatio,t=!1)),t||(e.position.left=e.prevPosition.left,e.position.top=e.prevPosition.top,e.size.width=e.prevSize.width,e.size.height=e.prevSize.height)},stop:function(){var t=y(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,n=t.containerElement,o=y(t.helper),h=o.offset(),a=o.outerWidth()-t.sizeDiff.width,o=o.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o}),t._helper&&!e.animate&&/static/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o})}}),y.ui.plugin.add("resizable","alsoResize",{start:function(){var t=y(this).resizable("instance").options;y(t.alsoResize).each(function(){var t=y(this);t.data("ui-resizable-alsoresize",{width:parseFloat(t.width()),height:parseFloat(t.height()),left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=y(this).resizable("instance"),s=e.options,n=e.originalSize,o=e.originalPosition,h={height:e.size.height-n.height||0,width:e.size.width-n.width||0,top:e.position.top-o.top||0,left:e.position.left-o.left||0};y(s.alsoResize).each(function(){var t=y(this),s=y(this).data("ui-resizable-alsoresize"),n={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];y.each(e,function(t,e){var i=(s[e]||0)+(h[e]||0);i&&0<=i&&(n[e]=i||null)}),t.css(n)})},stop:function(){y(this).removeData("ui-resizable-alsoresize")}}),y.ui.plugin.add("resizable","ghost",{start:function(){var t=y(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!1!==y.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=y(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=y(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),y.ui.plugin.add("resizable","grid",{resize:function(){var t,e=y(this).resizable("instance"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,h=e.axis,a="number"==typeof i.grid?[i.grid,i.grid]:i.grid,r=a[0]||1,l=a[1]||1,u=Math.round((s.width-n.width)/r)*r,p=Math.round((s.height-n.height)/l)*l,d=n.width+u,c=n.height+p,f=i.maxWidth&&i.maxWidthd,s=i.minHeight&&i.minHeight>c;i.grid=a,m&&(d+=r),s&&(c+=l),f&&(d-=r),g&&(c-=l),/^(se|s|e)$/.test(h)?(e.size.width=d,e.size.height=c):/^(ne)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.top=o.top-p):/^(sw)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.left=o.left-u):((c-l<=0||d-r<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0 - -GLFW: compile.dox File Reference + +GLFW: main.md File Reference @@ -28,10 +28,10 @@ - + @@ -54,20 +54,27 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    compile.dox File Reference
    +
    main.md File Reference
    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/menu.js b/src/lib/src/vendor/glfw-3.4/docs/html/menu.js similarity index 86% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/menu.js rename to src/lib/src/vendor/glfw-3.4/docs/html/menu.js index 818b859..b0b2693 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/menu.js +++ b/src/lib/src/vendor/glfw-3.4/docs/html/menu.js @@ -44,28 +44,26 @@ function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { } return result; } - var searchBox; + var searchBoxHtml; if (searchEnabled) { if (serverSide) { - searchBox='
    '+ + searchBoxHtml='
    '+ '
    '+ '
    '+ - ' '+ + ''+ + ' onblur="searchBox.OnSearchFieldFocus(false)"/>'+ '
    '+ '
    '+ '
    '+ '
    '; } else { - searchBox='
    '+ + searchBoxHtml='
    '+ ''+ - ''+ - ' '+ + ''+ @@ -73,8 +71,8 @@ function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { ''+ '' - '' + 'search/close.svg" alt=""/>'+ + ''+ '
    '; } } @@ -87,7 +85,7 @@ function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { '
    '); $('#main-nav').append(makeTree(menudata,relPath)); $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); - if (searchBox) { + if (searchBoxHtml) { $('#main-menu').append('
  • '); } var $mainMenuState = $('#main-menu-state'); @@ -116,14 +114,17 @@ function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { if (newWidth!=prevWidth) { if ($(window).outerWidth()<768) { $mainMenuState.prop('checked',false); $menu.hide(); - $('#searchBoxPos1').html(searchBox); + $('#searchBoxPos1').html(searchBoxHtml); $('#searchBoxPos2').hide(); } else { $menu.show(); $('#searchBoxPos1').empty(); - $('#searchBoxPos2').html(searchBox); + $('#searchBoxPos2').html(searchBoxHtml); $('#searchBoxPos2').show(); } + if (typeof searchBox!=='undefined') { + searchBox.CloseResultsWindow(); + } prevWidth = newWidth; } } diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/menudata.js b/src/lib/src/vendor/glfw-3.4/docs/html/menudata.js similarity index 97% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/menudata.js rename to src/lib/src/vendor/glfw-3.4/docs/html/menudata.js index 082dbe1..5f5dd18 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/menudata.js +++ b/src/lib/src/vendor/glfw-3.4/docs/html/menudata.js @@ -26,5 +26,5 @@ var menudata={children:[ {text:"Introduction",url:"index.html"}, {text:"Tutorial",url:"quick_guide.html"}, {text:"Guides",url:"pages.html"}, -{text:"Reference",url:"modules.html"}, +{text:"Reference",url:"topics.html"}, {text:"Files",url:"files.html"}]} diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/minus.svg b/src/lib/src/vendor/glfw-3.4/docs/html/minus.svg new file mode 100644 index 0000000..f70d0c1 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/minus.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/minusd.svg b/src/lib/src/vendor/glfw-3.4/docs/html/minusd.svg new file mode 100644 index 0000000..5f8e879 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/minusd.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/compat_8dox.html b/src/lib/src/vendor/glfw-3.4/docs/html/monitor_8md.html similarity index 80% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/compat_8dox.html rename to src/lib/src/vendor/glfw-3.4/docs/html/monitor_8md.html index 64a2e2e..13cf4a4 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/compat_8dox.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/monitor_8md.html @@ -4,8 +4,8 @@ - -GLFW: compat.dox File Reference + +GLFW: monitor.md File Reference @@ -28,10 +28,10 @@
    - + @@ -54,20 +54,27 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    compat.dox File Reference
    +
    monitor.md File Reference
    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/monitor_guide.html b/src/lib/src/vendor/glfw-3.4/docs/html/monitor_guide.html similarity index 54% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/monitor_guide.html rename to src/lib/src/vendor/glfw-3.4/docs/html/monitor_guide.html index 76f47a5..425e261 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/monitor_guide.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/monitor_guide.html @@ -4,7 +4,7 @@ - + GLFW: Monitor guide @@ -28,10 +28,10 @@ - + @@ -54,14 +54,21 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    Monitor guide
    +
    Monitor guide

    Table of Contents

    @@ -81,7 +88,7 @@ $(function() {
    -

    This guide introduces the monitor related functions of GLFW. For details on a specific function in this category, see the Monitor reference. There are also guides for the other areas of GLFW.

    +

    This guide introduces the monitor related functions of GLFW. For details on a specific function in this category, see the Monitor reference. There are also guides for the other areas of GLFW.

    Monitor objects

    -

    A monitor object represents a currently connected monitor and is represented as a pointer to the opaque type GLFWmonitor. Monitor objects cannot be created or destroyed by the application and retain their addresses until the monitors they represent are disconnected or until the library is terminated.

    -

    Each monitor has a current video mode, a list of supported video modes, a virtual position, a human-readable name, an estimated physical size and a gamma ramp. One of the monitors is the primary monitor.

    -

    The virtual position of a monitor is in screen coordinates and, together with the current video mode, describes the viewports that the connected monitors provide into the virtual desktop that spans them.

    -

    To see how GLFW views your monitor setup and its available video modes, run the monitors test program.

    +

    A monitor object represents a currently connected monitor and is represented as a pointer to the opaque type GLFWmonitor. Monitor objects cannot be created or destroyed by the application and retain their addresses until the monitors they represent are disconnected or until the library is terminated.

    +

    Each monitor has a current video mode, a list of supported video modes, a virtual position, a human-readable name, an estimated physical size and a gamma ramp. One of the monitors is the primary monitor.

    +

    The virtual position of a monitor is in screen coordinates and, together with the current video mode, describes the viewports that the connected monitors provide into the virtual desktop that spans them.

    +

    To see how GLFW views your monitor setup and its available video modes, run the monitors test program.

    Retrieving monitors

    -

    The primary monitor is returned by glfwGetPrimaryMonitor. It is the user's preferred monitor and is usually the one with global UI elements like task bar or menu bar.

    +

    The primary monitor is returned by glfwGetPrimaryMonitor. It is the user's preferred monitor and is usually the one with global UI elements like task bar or menu bar.

    -
    struct GLFWmonitor GLFWmonitor
    Opaque monitor object.
    Definition: glfw3.h:1173
    +
    struct GLFWmonitor GLFWmonitor
    Opaque monitor object.
    Definition glfw3.h:1391
    GLFWmonitor * glfwGetPrimaryMonitor(void)
    Returns the primary monitor.
    -

    You can retrieve all currently connected monitors with glfwGetMonitors. See the reference documentation for the lifetime of the returned array.

    +

    You can retrieve all currently connected monitors with glfwGetMonitors. See the reference documentation for the lifetime of the returned array.

    int count;
    GLFWmonitor** monitors = glfwGetMonitors(&count);
    GLFWmonitor ** glfwGetMonitors(int *count)
    Returns the currently connected monitors.
    -

    The primary monitor is always the first monitor in the returned array, but other monitors may be moved to a different index when a monitor is connected or disconnected.

    +

    The primary monitor is always the first monitor in the returned array, but other monitors may be moved to a different index when a monitor is connected or disconnected.

    Monitor configuration changes

    -

    If you wish to be notified when a monitor is connected or disconnected, set a monitor callback.

    +

    If you wish to be notified when a monitor is connected or disconnected, set a monitor callback.

    glfwSetMonitorCallback(monitor_callback);
    GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun callback)
    Sets the monitor configuration callback.
    -

    The callback function receives the handle for the monitor that has been connected or disconnected and the event that occurred.

    +

    The callback function receives the handle for the monitor that has been connected or disconnected and the event that occurred.

    void monitor_callback(GLFWmonitor* monitor, int event)
    {
    if (event == GLFW_CONNECTED)
    @@ -123,99 +130,98 @@ Monitor configuration changes
    // The monitor was disconnected
    }
    }
    -
    #define GLFW_DISCONNECTED
    Definition: glfw3.h:1107
    -
    #define GLFW_CONNECTED
    Definition: glfw3.h:1106
    -

    If a monitor is disconnected, all windows that are full screen on it will be switched to windowed mode before the callback is called. Only glfwGetMonitorName and glfwGetMonitorUserPointer will return useful values for a disconnected monitor and only before the monitor callback returns.

    +
    #define GLFW_DISCONNECTED
    Definition glfw3.h:1291
    +
    #define GLFW_CONNECTED
    Definition glfw3.h:1290
    +

    If a monitor is disconnected, all windows that are full screen on it will be switched to windowed mode before the callback is called. Only glfwGetMonitorName and glfwGetMonitorUserPointer will return useful values for a disconnected monitor and only before the monitor callback returns.

    Monitor properties

    -

    Each monitor has a current video mode, a list of supported video modes, a virtual position, a content scale, a human-readable name, a user pointer, an estimated physical size and a gamma ramp.

    +

    Each monitor has a current video mode, a list of supported video modes, a virtual position, a content scale, a human-readable name, a user pointer, an estimated physical size and a gamma ramp.

    Video modes

    -

    GLFW generally does a good job selecting a suitable video mode when you create a full screen window, change its video mode or make a windowed one full screen, but it is sometimes useful to know exactly which video modes are supported.

    -

    Video modes are represented as GLFWvidmode structures. You can get an array of the video modes supported by a monitor with glfwGetVideoModes. See the reference documentation for the lifetime of the returned array.

    +

    GLFW generally does a good job selecting a suitable video mode when you create a full screen window, change its video mode or make a windowed one full screen, but it is sometimes useful to know exactly which video modes are supported.

    +

    Video modes are represented as GLFWvidmode structures. You can get an array of the video modes supported by a monitor with glfwGetVideoModes. See the reference documentation for the lifetime of the returned array.

    int count;
    -
    GLFWvidmode* modes = glfwGetVideoModes(monitor, &count);
    +
    GLFWvidmode* modes = glfwGetVideoModes(monitor, &count);
    const GLFWvidmode * glfwGetVideoModes(GLFWmonitor *monitor, int *count)
    Returns the available video modes for the specified monitor.
    -
    Video mode type.
    Definition: glfw3.h:1658
    -

    To get the current video mode of a monitor call glfwGetVideoMode. See the reference documentation for the lifetime of the returned pointer.

    -
    const GLFWvidmode* mode = glfwGetVideoMode(monitor);
    +
    Video mode type.
    Definition glfw3.h:2027
    +

    To get the current video mode of a monitor call glfwGetVideoMode. See the reference documentation for the lifetime of the returned pointer.

    +
    const GLFWvidmode* mode = glfwGetVideoMode(monitor);
    const GLFWvidmode * glfwGetVideoMode(GLFWmonitor *monitor)
    Returns the current mode of the specified monitor.
    -

    The resolution of a video mode is specified in screen coordinates, not pixels.

    +

    The resolution of a video mode is specified in screen coordinates, not pixels.

    Physical size

    -

    The physical size of a monitor in millimetres, or an estimation of it, can be retrieved with glfwGetMonitorPhysicalSize. This has no relation to its current resolution, i.e. the width and height of its current video mode.

    +

    The physical size of a monitor in millimetres, or an estimation of it, can be retrieved with glfwGetMonitorPhysicalSize. This has no relation to its current resolution, i.e. the width and height of its current video mode.

    int width_mm, height_mm;
    glfwGetMonitorPhysicalSize(monitor, &width_mm, &height_mm);
    void glfwGetMonitorPhysicalSize(GLFWmonitor *monitor, int *widthMM, int *heightMM)
    Returns the physical size of the monitor.
    -

    While this can be used to calculate the raw DPI of a monitor, this is often not useful. Instead use the monitor content scale and window content scale to scale your content.

    +

    While this can be used to calculate the raw DPI of a monitor, this is often not useful. Instead, use the monitor content scale and window content scale to scale your content.

    Content scale

    -

    The content scale for a monitor can be retrieved with glfwGetMonitorContentScale.

    +

    The content scale for a monitor can be retrieved with glfwGetMonitorContentScale.

    float xscale, yscale;
    glfwGetMonitorContentScale(monitor, &xscale, &yscale);
    void glfwGetMonitorContentScale(GLFWmonitor *monitor, float *xscale, float *yscale)
    Retrieves the content scale for the specified monitor.
    -

    The content scale is the ratio between the current DPI and the platform's default DPI. This is especially important for text and any UI elements. If the pixel dimensions of your UI scaled by this look appropriate on your machine then it should appear at a reasonable size on other machines regardless of their DPI and scaling settings. This relies on the system DPI and scaling settings being somewhat correct.

    -

    The content scale may depend on both the monitor resolution and pixel density and on user settings. It may be very different from the raw DPI calculated from the physical size and current resolution.

    +

    For more information on what the content scale is and how to use it, see window content scale.

    Virtual position

    -

    The position of the monitor on the virtual desktop, in screen coordinates, can be retrieved with glfwGetMonitorPos.

    +

    The position of the monitor on the virtual desktop, in screen coordinates, can be retrieved with glfwGetMonitorPos.

    int xpos, ypos;
    glfwGetMonitorPos(monitor, &xpos, &ypos);
    void glfwGetMonitorPos(GLFWmonitor *monitor, int *xpos, int *ypos)
    Returns the position of the monitor's viewport on the virtual screen.

    Work area

    -

    The area of a monitor not occupied by global task bars or menu bars is the work area. This is specified in screen coordinates and can be retrieved with glfwGetMonitorWorkarea.

    +

    The area of a monitor not occupied by global task bars or menu bars is the work area. This is specified in screen coordinates and can be retrieved with glfwGetMonitorWorkarea.

    int xpos, ypos, width, height;
    glfwGetMonitorWorkarea(monitor, &xpos, &ypos, &width, &height);
    void glfwGetMonitorWorkarea(GLFWmonitor *monitor, int *xpos, int *ypos, int *width, int *height)
    Retrieves the work area of the monitor.

    Human-readable name

    -

    The human-readable, UTF-8 encoded name of a monitor is returned by glfwGetMonitorName. See the reference documentation for the lifetime of the returned string.

    +

    The human-readable, UTF-8 encoded name of a monitor is returned by glfwGetMonitorName. See the reference documentation for the lifetime of the returned string.

    const char* name = glfwGetMonitorName(monitor);
    const char * glfwGetMonitorName(GLFWmonitor *monitor)
    Returns the name of the specified monitor.
    -

    Monitor names are not guaranteed to be unique. Two monitors of the same model and make may have the same name. Only the monitor handle is guaranteed to be unique, and only until that monitor is disconnected.

    +

    Monitor names are not guaranteed to be unique. Two monitors of the same model and make may have the same name. Only the monitor handle is guaranteed to be unique, and only until that monitor is disconnected.

    User pointer

    -

    Each monitor has a user pointer that can be set with glfwSetMonitorUserPointer and queried with glfwGetMonitorUserPointer. This can be used for any purpose you need and will not be modified by GLFW. The value will be kept until the monitor is disconnected or until the library is terminated.

    -

    The initial value of the pointer is NULL.

    +

    Each monitor has a user pointer that can be set with glfwSetMonitorUserPointer and queried with glfwGetMonitorUserPointer. This can be used for any purpose you need and will not be modified by GLFW. The value will be kept until the monitor is disconnected or until the library is terminated.

    +

    The initial value of the pointer is NULL.

    Gamma ramp

    -

    The gamma ramp of a monitor can be set with glfwSetGammaRamp, which accepts a monitor handle and a pointer to a GLFWgammaramp structure.

    -
    +

    The gamma ramp of a monitor can be set with glfwSetGammaRamp, which accepts a monitor handle and a pointer to a GLFWgammaramp structure.

    +
    unsigned short red[256], green[256], blue[256];
    -
    ramp.size = 256;
    -
    ramp.red = red;
    -
    ramp.green = green;
    -
    ramp.blue = blue;
    +
    ramp.size = 256;
    +
    ramp.red = red;
    +
    ramp.green = green;
    +
    ramp.blue = blue;
    -
    for (i = 0; i < ramp.size; i++)
    +
    for (i = 0; i < ramp.size; i++)
    {
    // Fill out gamma ramp arrays as desired
    }
    glfwSetGammaRamp(monitor, &ramp);
    void glfwSetGammaRamp(GLFWmonitor *monitor, const GLFWgammaramp *ramp)
    Sets the current gamma ramp for the specified monitor.
    -
    Gamma ramp.
    Definition: glfw3.h:1692
    -
    unsigned short * red
    Definition: glfw3.h:1695
    -
    unsigned short * blue
    Definition: glfw3.h:1701
    -
    unsigned int size
    Definition: glfw3.h:1704
    -
    unsigned short * green
    Definition: glfw3.h:1698
    -

    The gamma ramp data is copied before the function returns, so there is no need to keep it around once the ramp has been set.

    -

    It is recommended that your gamma ramp have the same size as the current gamma ramp for that monitor.

    -

    The current gamma ramp for a monitor is returned by glfwGetGammaRamp. See the reference documentation for the lifetime of the returned structure.

    -
    const GLFWgammaramp* ramp = glfwGetGammaRamp(monitor);
    +
    Gamma ramp.
    Definition glfw3.h:2061
    +
    unsigned short * red
    Definition glfw3.h:2064
    +
    unsigned short * blue
    Definition glfw3.h:2070
    +
    unsigned int size
    Definition glfw3.h:2073
    +
    unsigned short * green
    Definition glfw3.h:2067
    +

    The gamma ramp data is copied before the function returns, so there is no need to keep it around once the ramp has been set.

    +

    It is recommended that your gamma ramp have the same size as the current gamma ramp for that monitor.

    +

    The current gamma ramp for a monitor is returned by glfwGetGammaRamp. See the reference documentation for the lifetime of the returned structure.

    +
    const GLFWgammaramp* ramp = glfwGetGammaRamp(monitor);
    const GLFWgammaramp * glfwGetGammaRamp(GLFWmonitor *monitor)
    Returns the current gamma ramp for the specified monitor.
    -

    If you wish to set a regular gamma ramp, you can have GLFW calculate it for you from the desired exponent with glfwSetGamma, which in turn calls glfwSetGammaRamp with the resulting ramp.

    +

    If you wish to set a regular gamma ramp, you can have GLFW calculate it for you from the desired exponent with glfwSetGamma, which in turn calls glfwSetGammaRamp with the resulting ramp.

    glfwSetGamma(monitor, 1.0);
    void glfwSetGamma(GLFWmonitor *monitor, float gamma)
    Generates a gamma ramp and sets it for the specified monitor.
    -

    To experiment with gamma correction via the glfwSetGamma function, run the gamma test program.

    -
    Note
    The software controlled gamma ramp is applied in addition to the hardware gamma correction, which today is usually an approximation of sRGB gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will produce the default (usually sRGB-like) behavior.
    +

    To experiment with gamma correction via the glfwSetGamma function, run the gamma test program.

    +
    Note
    The software controlled gamma ramp is applied in addition to the hardware gamma correction, which today is typically an approximation of sRGB gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will produce the default (usually sRGB-like) behavior.
    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/build_8dox.html b/src/lib/src/vendor/glfw-3.4/docs/html/moving_8md.html similarity index 80% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/build_8dox.html rename to src/lib/src/vendor/glfw-3.4/docs/html/moving_8md.html index 1f81575..f8ec12f 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/build_8dox.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/moving_8md.html @@ -4,8 +4,8 @@ - -GLFW: build.dox File Reference + +GLFW: moving.md File Reference @@ -28,10 +28,10 @@ - + @@ -54,20 +54,27 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    build.dox File Reference
    +
    moving.md File Reference
    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/moving_guide.html b/src/lib/src/vendor/glfw-3.4/docs/html/moving_guide.html similarity index 51% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/moving_guide.html rename to src/lib/src/vendor/glfw-3.4/docs/html/moving_guide.html index d8b1a2b..9f3b2b7 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/moving_guide.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/moving_guide.html @@ -4,7 +4,7 @@ - + GLFW: Moving from GLFW 2 to 3 @@ -28,10 +28,10 @@ - + @@ -54,14 +54,21 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    Moving from GLFW 2 to 3
    +
    Moving from GLFW 2 to 3

    Table of Contents

    @@ -97,66 +104,63 @@ $(function() {
    -

    This is a transition guide for moving from GLFW 2 to 3. It describes what has changed or been removed, but does not include new features unless they are required when moving an existing code base onto the new API. For example, the new multi-monitor functions are required to create full screen windows with GLFW 3.

    +

    This is a transition guide for moving from GLFW 2 to 3. It describes what has changed or been removed, but does not include new features unless they are required when moving an existing code base onto the new API. For example, the new multi-monitor functions are required to create full screen windows with GLFW 3.

    Changed and removed features

    Renamed library and header file

    -

    The GLFW 3 header is named glfw3.h and moved to the GLFW directory, to avoid collisions with the headers of other major versions. Similarly, the GLFW 3 library is named glfw3, except when it's installed as a shared library on Unix-like systems, where it uses the soname libglfw.so.3.

    -
    Old syntax
    #include <GL/glfw.h>
    -
    -
    New syntax
    #include <GLFW/glfw3.h>
    +

    The GLFW 3 header is named glfw3.h and moved to the GLFW directory, to avoid collisions with the headers of other major versions. Similarly, the GLFW 3 library is named glfw3, except when it's installed as a shared library on Unix-like systems, where it uses the soname libglfw.so.3.

    +

    Old syntax

    #include <GL/glfw.h>
    +

    New syntax

    #include <GLFW/glfw3.h>
    The header of the GLFW 3 API.
    -
    -

    +

    Removal of threading functions

    -

    The threading functions have been removed, including the per-thread sleep function. They were fairly primitive, under-used, poorly integrated and took time away from the focus of GLFW (i.e. context, input and window). There are better threading libraries available and native threading support is available in both C++11 and C11, both of which are gaining traction.

    -

    If you wish to use the C++11 or C11 facilities but your compiler doesn't yet support them, see the TinyThread++ and TinyCThread projects created by the original author of GLFW. These libraries implement a usable subset of the threading APIs in C++11 and C11, and in fact some GLFW 3 test programs use TinyCThread.

    -

    However, GLFW 3 has better support for use from multiple threads than GLFW 2 had. Contexts can be made current on any thread, although only a single thread at a time, and the documentation explicitly states which functions may be used from any thread and which must only be used from the main thread.

    -
    Removed functions
    glfwSleep, glfwCreateThread, glfwDestroyThread, glfwWaitThread, glfwGetThreadID, glfwCreateMutex, glfwDestroyMutex, glfwLockMutex, glfwUnlockMutex, glfwCreateCond, glfwDestroyCond, glfwWaitCond, glfwSignalCond, glfwBroadcastCond and glfwGetNumberOfProcessors.
    -
    Removed types
    GLFWthreadfun
    +

    The threading functions have been removed, including the per-thread sleep function. They were fairly primitive, under-used, poorly integrated and took time away from the focus of GLFW (i.e. context, input and window). There are better threading libraries available and native threading support is available in both C++11 and C11, both of which are gaining traction.

    +

    If you wish to use the C++11 or C11 facilities but your compiler doesn't yet support them, see the TinyThread++ and TinyCThread projects created by the original author of GLFW. These libraries implement a usable subset of the threading APIs in C++11 and C11, and in fact some GLFW 3 test programs use TinyCThread.

    +

    However, GLFW 3 has better support for use from multiple threads than GLFW 2 had. Contexts can be made current on any thread, although only a single thread at a time, and the documentation explicitly states which functions may be used from any thread and which must only be used from the main thread.

    +

    Removed functions

    +

    glfwSleep, glfwCreateThread, glfwDestroyThread, glfwWaitThread, glfwGetThreadID, glfwCreateMutex, glfwDestroyMutex, glfwLockMutex, glfwUnlockMutex, glfwCreateCond, glfwDestroyCond, glfwWaitCond, glfwSignalCond, glfwBroadcastCond and glfwGetNumberOfProcessors.

    +
    +

    Removed types

    +

    GLFWthreadfun

    +

    Removal of image and texture loading

    -

    The image and texture loading functions have been removed. They only supported the Targa image format, making them mostly useful for beginner level examples. To become of sufficiently high quality to warrant keeping them in GLFW 3, they would need not only to support other formats, but also modern extensions to OpenGL texturing. This would either add a number of external dependencies (libjpeg, libpng, etc.), or force GLFW to ship with inline versions of these libraries.

    -

    As there already are libraries doing this, it is unnecessary both to duplicate the work and to tie the duplicate to GLFW. The resulting library would also be platform-independent, as both OpenGL and stdio are available wherever GLFW is.

    -
    Removed functions
    glfwReadImage, glfwReadMemoryImage, glfwFreeImage, glfwLoadTexture2D, glfwLoadMemoryTexture2D and glfwLoadTextureImage2D.
    +

    The image and texture loading functions have been removed. They only supported the Targa image format, making them mostly useful for beginner level examples. To become of sufficiently high quality to warrant keeping them in GLFW 3, they would need not only to support other formats, but also modern extensions to OpenGL texturing. This would either add a number of external dependencies (libjpeg, libpng, etc.), or force GLFW to ship with inline versions of these libraries.

    +

    As there already are libraries doing this, it is unnecessary both to duplicate the work and to tie the duplicate to GLFW. The resulting library would also be platform-independent, as both OpenGL and stdio are available wherever GLFW is.

    +

    Removed functions

    +

    glfwReadImage, glfwReadMemoryImage, glfwFreeImage, glfwLoadTexture2D, glfwLoadMemoryTexture2D and glfwLoadTextureImage2D.

    +

    Removal of GLFWCALL macro

    -

    The GLFWCALL macro, which made callback functions use __stdcall on Windows, has been removed. GLFW is written in C, not Pascal. Removing this macro means there's one less thing for application programmers to remember, i.e. the requirement to mark all callback functions with GLFWCALL. It also simplifies the creation of DLLs and DLL link libraries, as there's no need to explicitly disable @n entry point suffixes.

    -
    Old syntax
    void GLFWCALL callback_function(...);
    -
    -
    New syntax
    void callback_function(...);
    -
    -

    +

    The GLFWCALL macro, which made callback functions use __stdcall on Windows, has been removed. GLFW is written in C, not Pascal. Removing this macro means there's one less thing for application programmers to remember, i.e. the requirement to mark all callback functions with GLFWCALL. It also simplifies the creation of DLLs and DLL link libraries, as there's no need to explicitly disable @n entry point suffixes.

    +

    Old syntax

    void GLFWCALL callback_function(...);
    +

    New syntax

    void callback_function(...);
    +

    Window handle parameters

    -

    Because GLFW 3 supports multiple windows, window handle parameters have been added to all window-related GLFW functions and callbacks. The handle of a newly created window is returned by glfwCreateWindow (formerly glfwOpenWindow). Window handles are pointers to the opaque type GLFWwindow.

    -
    Old syntax
    glfwSetWindowTitle("New Window Title");
    +

    Because GLFW 3 supports multiple windows, window handle parameters have been added to all window-related GLFW functions and callbacks. The handle of a newly created window is returned by glfwCreateWindow (formerly glfwOpenWindow). Window handles are pointers to the opaque type GLFWwindow.

    +

    Old syntax

    glfwSetWindowTitle("New Window Title");
    void glfwSetWindowTitle(GLFWwindow *window, const char *title)
    Sets the title of the specified window.
    -
    -
    New syntax
    glfwSetWindowTitle(window, "New Window Title");
    -
    -

    +

    New syntax

    glfwSetWindowTitle(window, "New Window Title");
    +

    Explicit monitor selection

    -

    GLFW 3 provides support for multiple monitors. To request a full screen mode window, instead of passing GLFW_FULLSCREEN you specify which monitor you wish the window to use. The glfwGetPrimaryMonitor function returns the monitor that GLFW 2 would have selected, but there are many other monitor functions. Monitor handles are pointers to the opaque type GLFWmonitor.

    -
    Old basic full screen
    glfwOpenWindow(640, 480, 8, 8, 8, 0, 24, 0, GLFW_FULLSCREEN);
    -
    -
    New basic full screen
    window = glfwCreateWindow(640, 480, "My Window", glfwGetPrimaryMonitor(), NULL);
    +

    GLFW 3 provides support for multiple monitors. To request a full screen mode window, instead of passing GLFW_FULLSCREEN you specify which monitor you wish the window to use. The glfwGetPrimaryMonitor function returns the monitor that GLFW 2 would have selected, but there are many other monitor functions. Monitor handles are pointers to the opaque type GLFWmonitor.

    +

    Old basic full screen

    glfwOpenWindow(640, 480, 8, 8, 8, 0, 24, 0, GLFW_FULLSCREEN);
    +

    New basic full screen

    window = glfwCreateWindow(640, 480, "My Window", glfwGetPrimaryMonitor(), NULL);
    GLFWmonitor * glfwGetPrimaryMonitor(void)
    Returns the primary monitor.
    GLFWwindow * glfwCreateWindow(int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
    Creates a window and its associated context.
    -
    -
    Note
    The framebuffer bit depth parameters of glfwOpenWindow have been turned into window hints, but as they have been given sane defaults you rarely need to set these hints.
    +
    Note
    The framebuffer bit depth parameters of glfwOpenWindow have been turned into window hints, but as they have been given sane defaults you rarely need to set these hints.

    Removal of automatic event polling

    -

    GLFW 3 does not automatically poll for events in glfwSwapBuffers, meaning you need to call glfwPollEvents or glfwWaitEvents yourself. Unlike buffer swap, which acts on a single window, the event processing functions act on all windows at once.

    -
    Old basic main loop
    while (...)
    +

    GLFW 3 does not automatically poll for events in glfwSwapBuffers, meaning you need to call glfwPollEvents or glfwWaitEvents yourself. Unlike buffer swap, which acts on a single window, the event processing functions act on all windows at once.

    +

    Old basic main loop

    while (...)
    {
    // Process input
    // Render output
    }
    void glfwSwapBuffers(GLFWwindow *window)
    Swaps the front and back buffers of the specified window.
    -
    -
    New basic main loop
    while (...)
    +

    New basic main loop

    while (...)
    {
    // Process input
    // Render output
    @@ -164,108 +168,97 @@ Removal of automatic event polling
    }
    void glfwPollEvents(void)
    Processes all pending events.
    -
    -

    +

    Explicit context management

    -

    Each GLFW 3 window has its own OpenGL context and only you, the application programmer, can know which context should be current on which thread at any given time. Therefore, GLFW 3 leaves that decision to you.

    -

    This means that you need to call glfwMakeContextCurrent after creating a window before you can call any OpenGL functions.

    +

    Each GLFW 3 window has its own OpenGL context and only you, the application programmer, can know which context should be current on which thread at any given time. Therefore, GLFW 3 leaves that decision to you.

    +

    This means that you need to call glfwMakeContextCurrent after creating a window before you can call any OpenGL functions.

    Separation of window and framebuffer sizes

    -

    Window positions and sizes now use screen coordinates, which may not be the same as pixels on machines with high-DPI monitors. This is important as OpenGL uses pixels, not screen coordinates. For example, the rectangle specified with glViewport needs to use pixels. Therefore, framebuffer size functions have been added. You can retrieve the size of the framebuffer of a window with glfwGetFramebufferSize function. A framebuffer size callback has also been added, which can be set with glfwSetFramebufferSizeCallback.

    -
    Old basic viewport setup
    glfwGetWindowSize(&width, &height);
    +

    Window positions and sizes now use screen coordinates, which may not be the same as pixels on machines with high-DPI monitors. This is important as OpenGL uses pixels, not screen coordinates. For example, the rectangle specified with glViewport needs to use pixels. Therefore, framebuffer size functions have been added. You can retrieve the size of the framebuffer of a window with glfwGetFramebufferSize function. A framebuffer size callback has also been added, which can be set with glfwSetFramebufferSizeCallback.

    +

    Old basic viewport setup

    glfwGetWindowSize(&width, &height);
    glViewport(0, 0, width, height);
    void glfwGetWindowSize(GLFWwindow *window, int *width, int *height)
    Retrieves the size of the content area of the specified window.
    -
    -
    New basic viewport setup
    glfwGetFramebufferSize(window, &width, &height);
    +

    New basic viewport setup

    glfwGetFramebufferSize(window, &width, &height);
    glViewport(0, 0, width, height);
    void glfwGetFramebufferSize(GLFWwindow *window, int *width, int *height)
    Retrieves the size of the framebuffer of the specified window.
    -
    -

    +

    Window closing changes

    -

    The GLFW_OPENED window parameter has been removed. As long as the window has not been destroyed, whether through glfwDestroyWindow or glfwTerminate, the window is "open".

    -

    A user attempting to close a window is now just an event like any other. Unlike GLFW 2, windows and contexts created with GLFW 3 will never be destroyed unless you choose them to be. Each window now has a close flag that is set to GLFW_TRUE when the user attempts to close that window. By default, nothing else happens and the window stays visible. It is then up to you to either destroy the window, take some other action or ignore the request.

    -

    You can query the close flag at any time with glfwWindowShouldClose and set it at any time with glfwSetWindowShouldClose.

    -
    Old basic main loop
    while (glfwGetWindowParam(GLFW_OPENED))
    +

    The GLFW_OPENED window parameter has been removed. As long as the window has not been destroyed, whether through glfwDestroyWindow or glfwTerminate, the window is "open".

    +

    A user attempting to close a window is now just an event like any other. Unlike GLFW 2, windows and contexts created with GLFW 3 will never be destroyed unless you choose them to be. Each window now has a close flag that is set to GLFW_TRUE when the user attempts to close that window. By default, nothing else happens and the window stays visible. It is then up to you to either destroy the window, take some other action or ignore the request.

    +

    You can query the close flag at any time with glfwWindowShouldClose and set it at any time with glfwSetWindowShouldClose.

    +

    Old basic main loop

    while (glfwGetWindowParam(GLFW_OPENED))
    {
    ...
    }
    -
    -
    New basic main loop
    while (!glfwWindowShouldClose(window))
    +

    New basic main loop

    while (!glfwWindowShouldClose(window))
    {
    ...
    }
    int glfwWindowShouldClose(GLFWwindow *window)
    Checks the close flag of the specified window.
    -
    -

    The close callback no longer returns a value. Instead, it is called after the close flag has been set so it can override its value, if it chooses to, before event processing completes. You may however not call glfwDestroyWindow from the close callback (or any other window related callback).

    -
    Old syntax
    int GLFWCALL window_close_callback(void);
    -
    -
    New syntax
    void window_close_callback(GLFWwindow* window);
    -
    struct GLFWwindow GLFWwindow
    Opaque window object.
    Definition: glfw3.h:1185
    -
    -
    Note
    GLFW never clears the close flag to GLFW_FALSE, meaning you can use it for other reasons to close the window as well, for example the user choosing Quit from an in-game menu.
    +

    The close callback no longer returns a value. Instead, it is called after the close flag has been set, so it can optionally override its value, before event processing completes. You may however not call glfwDestroyWindow from the close callback (or any other window related callback).

    +

    Old syntax

    int GLFWCALL window_close_callback(void);
    +

    New syntax

    void window_close_callback(GLFWwindow* window);
    +
    struct GLFWwindow GLFWwindow
    Opaque window object.
    Definition glfw3.h:1403
    +
    Note
    GLFW never clears the close flag to GLFW_FALSE, meaning you can use it for other reasons to close the window as well, for example the user choosing Quit from an in-game menu.

    Persistent window hints

    -

    The glfwOpenWindowHint function has been renamed to glfwWindowHint.

    -

    Window hints are no longer reset to their default values on window creation, but instead retain their values until modified by glfwWindowHint or glfwDefaultWindowHints, or until the library is terminated and re-initialized.

    +

    The glfwOpenWindowHint function has been renamed to glfwWindowHint.

    +

    Window hints are no longer reset to their default values on window creation, but instead retain their values until modified by glfwWindowHint or glfwDefaultWindowHints, or until the library is terminated and re-initialized.

    Video mode enumeration

    -

    Video mode enumeration is now per-monitor. The glfwGetVideoModes function now returns all available modes for a specific monitor instead of requiring you to guess how large an array you need. The glfwGetDesktopMode function, which had poorly defined behavior, has been replaced by glfwGetVideoMode, which returns the current mode of a monitor.

    +

    Video mode enumeration is now per-monitor. The glfwGetVideoModes function now returns all available modes for a specific monitor instead of requiring you to guess how large an array you need. The glfwGetDesktopMode function, which had poorly defined behavior, has been replaced by glfwGetVideoMode, which returns the current mode of a monitor.

    Removal of character actions

    -

    The action parameter of the character callback has been removed. This was an artefact of the origin of GLFW, i.e. being developed in English by a Swede. However, many keyboard layouts require more than one key to produce characters with diacritical marks. Even the Swedish keyboard layout requires this for uncommon cases like ü.

    -
    Old syntax
    void GLFWCALL character_callback(int character, int action);
    -
    -
    New syntax
    void character_callback(GLFWwindow* window, int character);
    -
    -

    +

    The action parameter of the character callback has been removed. This was an artefact of the origin of GLFW, i.e. being developed in English by a Swede. However, many keyboard layouts require more than one key to produce characters with diacritical marks. Even the Swedish keyboard layout requires this for uncommon cases like ü.

    +

    Old syntax

    void GLFWCALL character_callback(int character, int action);
    +

    New syntax

    void character_callback(GLFWwindow* window, int character);
    +

    Cursor position changes

    -

    The glfwGetMousePos function has been renamed to glfwGetCursorPos, glfwSetMousePos to glfwSetCursorPos and glfwSetMousePosCallback to glfwSetCursorPosCallback.

    -

    The cursor position is now double instead of int, both for the direct functions and for the callback. Some platforms can provide sub-pixel cursor movement and this data is now passed on to the application where available. On platforms where this is not provided, the decimal part is zero.

    -

    GLFW 3 only allows you to position the cursor within a window using glfwSetCursorPos (formerly glfwSetMousePos) when that window is active. Unless the window is active, the function fails silently.

    +

    The glfwGetMousePos function has been renamed to glfwGetCursorPos, glfwSetMousePos to glfwSetCursorPos and glfwSetMousePosCallback to glfwSetCursorPosCallback.

    +

    The cursor position is now double instead of int, both for the direct functions and for the callback. Some platforms can provide sub-pixel cursor movement and this data is now passed on to the application where available. On platforms where this is not provided, the decimal part is zero.

    +

    GLFW 3 only allows you to position the cursor within a window using glfwSetCursorPos (formerly glfwSetMousePos) when that window is active. Unless the window is active, the function fails silently.

    Wheel position replaced by scroll offsets

    -

    The glfwGetMouseWheel function has been removed. Scrolling is the input of offsets and has no absolute position. The mouse wheel callback has been replaced by a scroll callback that receives two-dimensional floating point scroll offsets. This allows you to receive precise scroll data from for example modern touchpads.

    -
    Old syntax
    void GLFWCALL mouse_wheel_callback(int position);
    -
    -
    New syntax
    void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
    -
    -
    Removed functions
    glfwGetMouseWheel
    +

    The glfwGetMouseWheel function has been removed. Scrolling is the input of offsets and has no absolute position. The mouse wheel callback has been replaced by a scroll callback that receives two-dimensional floating point scroll offsets. This allows you to receive precise scroll data from for example modern touchpads.

    +

    Old syntax

    void GLFWCALL mouse_wheel_callback(int position);
    +

    New syntax

    void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
    +

    Removed functions

    +

    glfwGetMouseWheel

    +

    Key repeat action

    -

    The GLFW_KEY_REPEAT enable has been removed and key repeat is always enabled for both keys and characters. A new key action, GLFW_REPEAT, has been added to allow the key callback to distinguish an initial key press from a repeat. Note that glfwGetKey still returns only GLFW_PRESS or GLFW_RELEASE.

    +

    The GLFW_KEY_REPEAT enable has been removed and key repeat is always enabled for both keys and characters. A new key action, GLFW_REPEAT, has been added to allow the key callback to distinguish an initial key press from a repeat. Note that glfwGetKey still returns only GLFW_PRESS or GLFW_RELEASE.

    Physical key input

    -

    GLFW 3 key tokens map to physical keys, unlike in GLFW 2 where they mapped to the values generated by the current keyboard layout. The tokens are named according to the values they would have using the standard US layout, but this is only a convenience, as most programmers are assumed to know that layout. This means that (for example) GLFW_KEY_LEFT_BRACKET is always a single key and is the same key in the same place regardless of what keyboard layouts the users of your program has.

    -

    The key input facility was never meant for text input, although using it that way worked slightly better in GLFW 2. If you were using it to input text, you should be using the character callback instead, on both GLFW 2 and 3. This will give you the characters being input, as opposed to the keys being pressed.

    -

    GLFW 3 has key tokens for all keys on a standard 105 key keyboard, so instead of having to remember whether to check for a or A, you now check for GLFW_KEY_A.

    +

    GLFW 3 key tokens map to physical keys, unlike in GLFW 2 where they mapped to the values generated by the current keyboard layout. The tokens are named according to the values they would have in the standard US layout, but this is only a convenience, as most programmers are assumed to know that layout. This means that (for example) GLFW_KEY_LEFT_BRACKET is always a single key and is the same key in the same place regardless of what keyboard layouts the users of your program have.

    +

    The key input facility was never meant for text input, although using it that way worked slightly better in GLFW 2. If you were using it to input text, you should be using the character callback instead, on both GLFW 2 and 3. This will give you the characters being input, as opposed to the keys being pressed.

    +

    GLFW 3 has key tokens for all keys on a standard 105 key keyboard, so instead of having to remember whether to check for a or A, you now check for GLFW_KEY_A.

    Joystick function changes

    -

    The glfwGetJoystickPos function has been renamed to glfwGetJoystickAxes.

    -

    The glfwGetJoystickParam function and the GLFW_PRESENT, GLFW_AXES and GLFW_BUTTONS tokens have been replaced by the glfwJoystickPresent function as well as axis and button counts returned by the glfwGetJoystickAxes and glfwGetJoystickButtons functions.

    +

    The glfwGetJoystickPos function has been renamed to glfwGetJoystickAxes.

    +

    The glfwGetJoystickParam function and the GLFW_PRESENT, GLFW_AXES and GLFW_BUTTONS tokens have been replaced by the glfwJoystickPresent function as well as axis and button counts returned by the glfwGetJoystickAxes and glfwGetJoystickButtons functions.

    Win32 MBCS support

    -

    The Win32 port of GLFW 3 will not compile in MBCS mode. However, because the use of the Unicode version of the Win32 API doesn't affect the process as a whole, but only those windows created using it, it's perfectly possible to call MBCS functions from other parts of the same application. Therefore, even if an application using GLFW has MBCS mode code, there's no need for GLFW itself to support it.

    +

    The Win32 port of GLFW 3 will not compile in MBCS mode. However, because the use of the Unicode version of the Win32 API doesn't affect the process as a whole, but only those windows created using it, it's perfectly possible to call MBCS functions from other parts of the same application. Therefore, even if an application using GLFW has MBCS mode code, there's no need for GLFW itself to support it.

    Support for versions of Windows older than XP

    -

    All explicit support for version of Windows older than XP has been removed. There is no code that actively prevents GLFW 3 from running on these earlier versions, but it uses Win32 functions that those versions lack.

    -

    Windows XP was released in 2001, and by now (January 2015) it has not only replaced almost all earlier versions of Windows, but is itself rapidly being replaced by Windows 7 and 8. The MSDN library doesn't even provide documentation for version older than Windows 2000, making it difficult to maintain compatibility with these versions even if it was deemed worth the effort.

    -

    The Win32 API has also not stood still, and GLFW 3 uses many functions only present on Windows XP or later. Even supporting an OS as new as XP (new from the perspective of GLFW 2, which still supports Windows 95) requires runtime checking for a number of functions that are present only on modern version of Windows.

    +

    All explicit support for version of Windows older than XP has been removed. There is no code that actively prevents GLFW 3 from running on these earlier versions, but it uses Win32 functions that those versions lack.

    +

    Windows XP was released in 2001, and by now (January 2015) it has not only replaced almost all earlier versions of Windows, but is itself rapidly being replaced by Windows 7 and 8. The MSDN library doesn't even provide documentation for version older than Windows 2000, making it difficult to maintain compatibility with these versions even if it was deemed worth the effort.

    +

    The Win32 API has also not stood still, and GLFW 3 uses many functions only present on Windows XP or later. Even supporting an OS as new as XP (new from the perspective of GLFW 2, which still supports Windows 95) requires runtime checking for a number of functions that are present only on modern version of Windows.

    Capture of system-wide hotkeys

    -

    The ability to disable and capture system-wide hotkeys like Alt+Tab has been removed. Modern applications, whether they're games, scientific visualisations or something else, are nowadays expected to be good desktop citizens and allow these hotkeys to function even when running in full screen mode.

    +

    The ability to disable and capture system-wide hotkeys like Alt+Tab has been removed. Modern applications, whether they're games, scientific visualisations or something else, are nowadays expected to be good desktop citizens and allow these hotkeys to function even when running in full screen mode.

    Automatic termination

    -

    GLFW 3 does not register glfwTerminate with atexit at initialization, because exit calls registered functions from the calling thread and while it is permitted to call exit from any thread, glfwTerminate must only be called from the main thread.

    -

    To release all resources allocated by GLFW, you should call glfwTerminate yourself, from the main thread, before the program terminates. Note that this destroys all windows not already destroyed with glfwDestroyWindow, invalidating any window handles you may still have.

    +

    GLFW 3 does not register glfwTerminate with atexit at initialization, because exit calls registered functions from the calling thread and while it is permitted to call exit from any thread, glfwTerminate must only be called from the main thread.

    +

    To release all resources allocated by GLFW, you should call glfwTerminate yourself, from the main thread, before the program terminates. Note that this destroys all windows not already destroyed with glfwDestroyWindow, invalidating any window handles you may still have.

    GLU header inclusion

    -

    GLFW 3 does not by default include the GLU header and GLU itself has been deprecated by Khronos. New projects should not use GLU, but if you need it for legacy code that has been moved to GLFW 3, you can request that the GLFW header includes it by defining GLFW_INCLUDE_GLU before the inclusion of the GLFW header.

    -
    Old syntax
    #include <GL/glfw.h>
    -
    -
    New syntax
    #define GLFW_INCLUDE_GLU
    +

    GLFW 3 does not by default include the GLU header and GLU itself has been deprecated by Khronos. New projects should not use GLU, but if you need it for legacy code that has been moved to GLFW 3, you can request that the GLFW header includes it by defining GLFW_INCLUDE_GLU before the inclusion of the GLFW header.

    +

    Old syntax

    #include <GL/glfw.h>
    +

    New syntax

    #define GLFW_INCLUDE_GLU
    #include <GLFW/glfw3.h>
    -
    -

    There are many libraries that offer replacements for the functionality offered by GLU. For the matrix helper functions, see math libraries like GLM (for C++), linmath.h (for C) and others. For the tessellation functions, see for example libtess2.

    +

    There are many libraries that offer replacements for the functionality offered by GLU. For the matrix helper functions, see math libraries like GLM (for C++), linmath.h (for C) and others. For the tessellation functions, see for example libtess2.

    Name change tables

    @@ -360,7 +353,7 @@ Renamed tokens

    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/nav_f.png b/src/lib/src/vendor/glfw-3.4/docs/html/nav_f.png similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/nav_f.png rename to src/lib/src/vendor/glfw-3.4/docs/html/nav_f.png diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/nav_fd.png b/src/lib/src/vendor/glfw-3.4/docs/html/nav_fd.png new file mode 100644 index 0000000000000000000000000000000000000000..032fbdd4c54f54fa9a2e6423b94ef4b2ebdfaceb GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQU#tajv*C{Z|C~*H7f|XvG1G8 zt7aS*L7xwMeS}!z6R#{C5tIw-s~AJ==F^i}x3XyJseHR@yF& zerFf(Zf;Dd{+(0lDIROL@Sj-Ju2JQ8&-n%4%q?>|^bShc&lR?}7HeMo@BDl5N(aHY Uj$gdr1MOz;boFyt=akR{0D!zeaR2}S literal 0 HcmV?d00001 diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/nav_g.png b/src/lib/src/vendor/glfw-3.4/docs/html/nav_g.png similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/nav_g.png rename to src/lib/src/vendor/glfw-3.4/docs/html/nav_g.png diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/nav_h.png b/src/lib/src/vendor/glfw-3.4/docs/html/nav_h.png similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/nav_h.png rename to src/lib/src/vendor/glfw-3.4/docs/html/nav_h.png diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/nav_hd.png b/src/lib/src/vendor/glfw-3.4/docs/html/nav_hd.png new file mode 100644 index 0000000000000000000000000000000000000000..de80f18ad6488b9990303f267a76fdc83f0ffd80 GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^j6lr8!2~3AUOE6t21`#D$B+ufw|9379#G(63FK{W z5s6W-eg#Jd_@e6*DPn)w;=|1H}Zvm9l6xXXB%>yL=NQU;mg M>FVdQ&MBb@0Bdt1Qvd(} literal 0 HcmV?d00001 diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/news.html b/src/lib/src/vendor/glfw-3.4/docs/html/news.html new file mode 100644 index 0000000..0232e15 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/news.html @@ -0,0 +1,336 @@ + + + + + + + +GLFW: Release notes for version 3.4 + + + + + + + + + + +
    + + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    +
    Release notes for version 3.4
    +
    +
    +

    Table of Contents

    + +
    +

    +New features

    +

    +Runtime platform selection

    +

    GLFW now supports being compiled for multiple backends and selecting between them at runtime with the GLFW_PLATFORM init hint. After initialization the selected platform can be queried with glfwGetPlatform. You can check if support for a given platform is compiled in with glfwPlatformSupported.

    +

    For more information see Runtime platform selection.

    +

    +More standard cursor shapes

    +

    GLFW now provides the standard cursor shapes GLFW_RESIZE_NWSE_CURSOR and GLFW_RESIZE_NESW_CURSOR for diagonal resizing, GLFW_RESIZE_ALL_CURSOR for omnidirectional resizing and GLFW_NOT_ALLOWED_CURSOR for showing an action is not allowed.

    +

    Unlike the original set, these shapes may not be available everywhere and creation will then fail with the new GLFW_CURSOR_UNAVAILABLE error.

    +

    The cursors for horizontal and vertical resizing are now referred to as GLFW_RESIZE_EW_CURSOR and GLFW_RESIZE_NS_CURSOR, and the pointing hand cursor is now referred to as GLFW_POINTING_HAND_CURSOR. The older names are still available.

    +

    For more information see Standard cursor creation.

    +

    +Mouse event passthrough

    +

    GLFW now provides the GLFW_MOUSE_PASSTHROUGH window hint for making a window transparent to mouse input, lettings events pass to whatever window is behind it. This can also be changed after window creation with the matching window attribute.

    +

    +Ability to get window title

    +

    GLFW now supports querying the title of a window with the glfwGetWindowTitle function.

    +

    For more information see Window title.

    +

    +Captured cursor mode

    +

    GLFW now supports confining the cursor to the window content area with the GLFW_CURSOR_CAPTURED cursor mode.

    +

    For more information see Cursor mode.

    +

    +Support for custom heap memory allocator

    +

    GLFW now supports plugging a custom heap memory allocator at initialization with glfwInitAllocator. The allocator is a struct of type GLFWallocator with function pointers corresponding to the standard library functions malloc, realloc and free.

    +

    For more information see Custom heap memory allocator.

    +

    +Window hint for framebuffer scaling

    +

    GLFW now allows provides the GLFW_SCALE_FRAMEBUFFER window hint for controlling framebuffer scaling on platforms that handle scaling by keeping the window size the same while resizing the framebuffer. The default value is to allow framebuffer scaling.

    +

    This was already possible on macOS via the GLFW_COCOA_RETINA_FRAMEBUFFER window hint. This is now another name for the same hint value.

    +

    For more information see Window content scale.

    +

    +Window hints for initial window position

    +

    GLFW now provides the GLFW_POSITION_X and GLFW_POSITION_Y window hints for specifying the initial position of the window. This removes the need to create a hidden window, move it and then show it. The default value of these hints is GLFW_ANY_POSITION, which selects the previous behavior.

    +

    For more information see Window position.

    +

    +ANGLE rendering backend hint

    +

    GLFW now provides the GLFW_ANGLE_PLATFORM_TYPE init hint for requesting a specific rendering backend when using ANGLE to create OpenGL ES contexts.

    +

    +Windows window menu keyboard access hint

    +

    GLFW now provides the GLFW_WIN32_KEYBOARD_MENU window hint for enabling keyboard access to the window menu via the Alt+Space and Alt-and-then-Space shortcuts. This may be useful for more GUI-oriented applications.

    +

    +Windows STARTUPINFO show command hint

    +

    GLFW now provides the GLFW_WIN32_SHOWDEFAULT window hint for applying the show command in the program's STARTUPINFO when showing the window for the first time. This may be useful for the main window of a windowed-mode tool.

    +

    +Cocoa NSView native access function

    +

    GLFW now provides the glfwGetCocoaView native access function for returning the Cocoa NSView.

    +

    +Wayland libdecor decorations

    +

    GLFW now supports improved client-side window decorations via libdecor. This provides fully featured window decorations on desktop environments like GNOME.

    +

    Support for libdecor can be toggled before GLFW is initialized with the GLFW_WAYLAND_LIBDECOR init hint. It is enabled by default.

    +

    This feature has also been available in GLFW 3.3 since 3.3.9.

    +

    +Wayland surface app_id hint

    +

    GLFW now supports specifying the app_id for a Wayland window using the GLFW_WAYLAND_APP_ID window hint string.

    +

    +X11 Vulkan window surface hint

    +

    GLFW now supports disabling the use of VK_KHR_xcb_surface over VK_KHR_xlib_surface where available, with the GLFW_X11_XCB_VULKAN_SURFACE init hint. This affects glfwGetRequiredInstanceExtensions and glfwCreateWindowSurface.

    +

    +Caveats

    +

    +Multiple sets of native access functions

    +

    Because GLFW now supports runtime selection of platform (window system), a library binary may export native access functions for multiple platforms. Starting with version 3.4 you must not assume that GLFW is running on a platform just because it exports native access functions for it. After initialization, you can query the selected platform with glfwGetPlatform.

    +

    +Version string format has been changed

    +

    Because GLFW now supports runtime selection of platform (window system), the version string returned by glfwGetVersionString has been expanded. It now contains the names of all APIs for all the platforms that the library binary supports.

    +

    The version string is intended for bug reporting and should not be parsed. See glfwGetVersion and glfwPlatformSupported instead.

    +

    +Joystick support is initialized on demand

    +

    The joystick part of GLFW is now initialized when first used, primarily to work around faulty Windows drivers that cause DirectInput to take up to several seconds to enumerate devices.

    +

    This change is mostly not observable. However, if your application waits for events without having first called any joystick function or created any visible windows, the wait may never unblock as GLFW may not yet have subscribed to joystick related OS events.

    +

    To work around this, call any joystick function before waiting for events, for example by setting a joystick callback.

    +

    +Tests and examples are disabled when built as a subproject

    +

    GLFW now by default does not build the tests or examples when it is added as a subdirectory of another CMake project. If you were setting GLFW_BUILD_TESTS or GLFW_BUILD_EXAMPLES to false in your CMake files, you can now remove this.

    +

    If you do want these to be built, set GLFW_BUILD_TESTS and GLFW_BUILD_EXAMPLES in your CMake files before adding the GLFW subdirectory.

    +
    set(GLFW_BUILD_EXAMPLES ON CACHE BOOL "" FORCE)
    +
    set(GLFW_BUILD_TESTS ON CACHE BOOL "" FORCE)
    +
    add_subdirectory(path/to/glfw)
    +

    +Configuration header is no longer generated

    +

    The glfw_config.h configuration header is no longer generated by CMake and the platform selection macros are now part of the GLFW CMake target. The _GLFW_USE_CONFIG_H macro is still supported in case you are generating a configuration header in a custom build setup.

    +

    +Documentation generation requires Doxygen 1.9.8 or later

    +

    Doxygen 1.9.8 or later is now required for the docs CMake target to be generated. This is because the documentation now uses more of the Markdown support in Doxygen and this support has until recently been relatively unstable.

    +

    +Windows 7 framebuffer transparency requires DWM transparency

    +

    GLFW no longer supports per-pixel framebuffer transparency via GLFW_TRANSPARENT_FRAMEBUFFER on Windows 7 if DWM transparency is off (the Transparency setting under Personalization > Window Color).

    +

    +macOS main menu now created at initialization

    +

    GLFW now creates the main menu and completes the initialization of NSApplication during initialization. Programs that do not want a main menu can disable it with the GLFW_COCOA_MENUBAR init hint.

    +

    +macOS CoreVideo dependency has been removed

    +

    GLFW no longer depends on the CoreVideo framework on macOS and it no longer needs to be specified during compilation or linking.

    +

    +Wayland framebuffer may lack alpha channel on older systems

    +

    On Wayland, when creating an EGL context on a machine lacking the new EGL_EXT_present_opaque extension, the GLFW_ALPHA_BITS window hint will be ignored and the framebuffer will not have an alpha channel. This is because some Wayland compositors treat any buffer with an alpha channel as per-pixel transparent.

    +

    If you want a per-pixel transparent window, see the GLFW_TRANSPARENT_FRAMEBUFFER window hint.

    +

    +X11 empty events no longer round-trip to server

    +

    Events posted with glfwPostEmptyEvent now use a separate unnamed pipe instead of sending an X11 client event to the helper window.

    +

    +Deprecations

    +

    +Windows XP and Vista support is deprecated

    +

    Support for Windows XP and Vista has been deprecated and will be removed in a future release. Windows XP has been out of extended support since 2014.

    +

    +Original MinGW support is deprecated

    +

    Support for the now unmaintained original MinGW distribution has been deprecated and will be removed in a future release.

    +

    This does not apply to the much more capable MinGW-w64, which remains fully supported, actively maintained and available on many platforms.

    +

    +OS X Yosemite support is deprecated

    +

    Support for OS X 10.10 Yosemite and earlier has been deprecated and will be removed in a future release. OS X 10.10 has been out of support since 2017.

    +

    +Removals

    +

    +GLFW_VULKAN_STATIC CMake option has been removed

    +

    This option was used to compile GLFW directly linked with the Vulkan loader, instead of using dynamic loading to get hold of vkGetInstanceProcAddr at initialization. This is now done by calling the glfwInitVulkanLoader function before initialization.

    +

    If you need backward compatibility, this macro can still be defined for GLFW 3.4 and will have no effect. The call to glfwInitVulkanLoader can be conditionally enabled in your code by checking the GLFW_VERSION_MAJOR and GLFW_VERSION_MINOR macros.

    +

    +GLFW_USE_WAYLAND CMake option has been removed

    +

    This option was used to compile GLFW for Wayland instead of X11. GLFW now supports selecting the platform at run-time. By default GLFW is compiled for both Wayland and X11 on Linux and other Unix-like systems.

    +

    To disable Wayland or X11 or both, set the GLFW_BUILD_WAYLAND and GLFW_BUILD_X11 CMake options.

    +

    The GLFW_USE_WAYLAND CMake variable must not be present in the CMake cache at all, or GLFW will fail to configure. If you are getting this error, delete the CMake cache for GLFW and configure again.

    +

    +GLFW_USE_OSMESA CMake option has been removed

    +

    This option was used to compile GLFW for the Null platform. The Null platform is now always available. To produce a library binary that only supports this platform, the way this CMake option used to do, you will instead need to disable the default platforms for the target OS. This means setting the GLFW_BUILD_WIN32, GLFW_BUILD_COCOA or GLFW_BUILD_WAYLAND and GLFW_BUILD_X11 CMake options to false.

    +

    You can set all of them to false and the ones that don't apply for the target OS will be ignored.

    +

    +wl_shell protocol support has been removed

    +

    Support for the deprecated wl_shell protocol has been removed and GLFW now only supports the XDG-Shell protocol. If your Wayland compositor does not support XDG-Shell then GLFW will fail to initialize.

    +

    +New symbols

    +

    +New functions

    + +

    +New types

    + +

    +New constants

    + +

    +Release notes for earlier versions

    + +
    +
    + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/news_8md.html b/src/lib/src/vendor/glfw-3.4/docs/html/news_8md.html new file mode 100644 index 0000000..51fec5b --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/news_8md.html @@ -0,0 +1,81 @@ + + + + + + + +GLFW: news.md File Reference + + + + + + + + + + +
    + + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    +
    news.md File Reference
    +
    +
    +
    + + + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/open.png b/src/lib/src/vendor/glfw-3.4/docs/html/open.png similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/open.png rename to src/lib/src/vendor/glfw-3.4/docs/html/open.png diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/pages.html b/src/lib/src/vendor/glfw-3.4/docs/html/pages.html similarity index 66% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/pages.html rename to src/lib/src/vendor/glfw-3.4/docs/html/pages.html index 6f2d4eb..06d40e0 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/pages.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/pages.html @@ -4,7 +4,7 @@ - + GLFW: Guides @@ -28,10 +28,10 @@ - + @@ -55,9 +55,16 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    @@ -66,26 +73,26 @@ $(function() { diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/plus.svg b/src/lib/src/vendor/glfw-3.4/docs/html/plus.svg new file mode 100644 index 0000000..0752016 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/plus.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/plusd.svg b/src/lib/src/vendor/glfw-3.4/docs/html/plusd.svg new file mode 100644 index 0000000..0c65bfe --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/plusd.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/quick_8md.html b/src/lib/src/vendor/glfw-3.4/docs/html/quick_8md.html new file mode 100644 index 0000000..697e7c3 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/quick_8md.html @@ -0,0 +1,81 @@ + + + + + + + +GLFW: quick.md File Reference + + + + + + + + + + +
    + + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    +
    quick.md File Reference
    +
    +
    +
    + + + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/quick_guide.html b/src/lib/src/vendor/glfw-3.4/docs/html/quick_guide.html similarity index 62% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/quick_guide.html rename to src/lib/src/vendor/glfw-3.4/docs/html/quick_guide.html index 6a31489..9ed1882 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/quick_guide.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/quick_guide.html @@ -4,7 +4,7 @@ - + GLFW: Getting started @@ -28,10 +28,10 @@
    - + @@ -54,14 +54,21 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    Getting started
    +
    Getting started

    Table of Contents

    @@ -81,155 +88,159 @@ $(function() {
  • Putting it together
  • -

    This guide takes you through writing a simple application using GLFW 3. The application will create a window and OpenGL context, render a rotating triangle and exit when the user closes the window or presses Escape. This guide will introduce a few of the most commonly used functions, but there are many more.

    -

    This guide assumes no experience with earlier versions of GLFW. If you have used GLFW 2 in the past, read Moving from GLFW 2 to 3, as some functions behave differently in GLFW 3.

    +

    This guide takes you through writing a small application using GLFW 3. The application will create a window and OpenGL context, render a rotating triangle and exit when the user closes the window or presses Escape. This guide will introduce a few of the most commonly used functions, but there are many more.

    +

    This guide assumes no experience with earlier versions of GLFW. If you have used GLFW 2 in the past, read Moving from GLFW 2 to 3, as some functions behave differently in GLFW 3.

    Step by step

    Including the GLFW header

    -

    In the source files of your application where you use GLFW, you need to include its header file.

    +

    In the source files of your application where you use GLFW, you need to include its header file.

    #include <GLFW/glfw3.h>
    The header of the GLFW 3 API.
    -

    This header provides all the constants, types and function prototypes of the GLFW API.

    -

    By default it also includes the OpenGL header from your development environment. On some platforms this header only supports older versions of OpenGL. The most extreme case is Windows, where it typically only supports OpenGL 1.2.

    -

    Most programs will instead use an extension loader library and include its header. This example uses files generated by glad. The GLFW header can detect most such headers if they are included first and will then not include the one from your development environment.

    +

    This header provides all the constants, types and function prototypes of the GLFW API.

    +

    By default it also includes the OpenGL header from your development environment. On some platforms this header only supports older versions of OpenGL. The most extreme case is Windows, where it typically only supports OpenGL 1.2.

    +

    Most programs will instead use an extension loader library and include its header. This example uses files generated by glad. The GLFW header can detect most such headers if they are included first and will then not include the one from your development environment.

    #include <glad/gl.h>
    #include <GLFW/glfw3.h>
    -

    To make sure there will be no header conflicts, you can define GLFW_INCLUDE_NONE before the GLFW header to explicitly disable inclusion of the development environment header. This also allows the two headers to be included in any order.

    +

    To make sure there will be no header conflicts, you can define GLFW_INCLUDE_NONE before the GLFW header to explicitly disable inclusion of the development environment header. This also allows the two headers to be included in any order.

    #define GLFW_INCLUDE_NONE
    #include <GLFW/glfw3.h>
    #include <glad/gl.h>

    Initializing and terminating GLFW

    -

    Before you can use most GLFW functions, the library must be initialized. On successful initialization, GLFW_TRUE is returned. If an error occurred, GLFW_FALSE is returned.

    +

    Before you can use most GLFW functions, the library must be initialized. On successful initialization, GLFW_TRUE is returned. If an error occurred, GLFW_FALSE is returned.

    if (!glfwInit())
    {
    // Initialization failed
    }
    int glfwInit(void)
    Initializes the GLFW library.
    -

    Note that GLFW_TRUE and GLFW_FALSE are and will always be one and zero.

    -

    When you are done using GLFW, typically just before the application exits, you need to terminate GLFW.

    +

    Note that GLFW_TRUE and GLFW_FALSE are and will always be one and zero.

    +

    When you are done using GLFW, typically just before the application exits, you need to terminate GLFW.

    void glfwTerminate(void)
    Terminates the GLFW library.
    -

    This destroys any remaining windows and releases any other resources allocated by GLFW. After this call, you must initialize GLFW again before using any GLFW functions that require it.

    +

    This destroys any remaining windows and releases any other resources allocated by GLFW. After this call, you must initialize GLFW again before using any GLFW functions that require it.

    Setting an error callback

    -

    Most events are reported through callbacks, whether it's a key being pressed, a GLFW window being moved, or an error occurring. Callbacks are C functions (or C++ static methods) that are called by GLFW with arguments describing the event.

    -

    In case a GLFW function fails, an error is reported to the GLFW error callback. You can receive these reports with an error callback. This function must have the signature below but may do anything permitted in other callbacks.

    +

    Most events are reported through callbacks, whether it's a key being pressed, a GLFW window being moved, or an error occurring. Callbacks are C functions (or C++ static methods) that are called by GLFW with arguments describing the event.

    +

    In case a GLFW function fails, an error is reported to the GLFW error callback. You can receive these reports with an error callback. This function must have the signature below but may do anything permitted in other callbacks.

    void error_callback(int error, const char* description)
    {
    fprintf(stderr, "Error: %s\n", description);
    }
    -

    Callback functions must be set, so GLFW knows to call them. The function to set the error callback is one of the few GLFW functions that may be called before initialization, which lets you be notified of errors both during and after initialization.

    +

    Callback functions must be set, so GLFW knows to call them. The function to set the error callback is one of the few GLFW functions that may be called before initialization, which lets you be notified of errors both during and after initialization.

    glfwSetErrorCallback(error_callback);
    GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun callback)
    Sets the error callback.

    Creating a window and context

    -

    The window and its OpenGL context are created with a single call to glfwCreateWindow, which returns a handle to the created combined window and context object

    +

    The window and its OpenGL context are created with a single call to glfwCreateWindow, which returns a handle to the created combined window and context object

    GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
    if (!window)
    {
    // Window or OpenGL context creation failed
    }
    GLFWwindow * glfwCreateWindow(int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
    Creates a window and its associated context.
    -
    struct GLFWwindow GLFWwindow
    Opaque window object.
    Definition: glfw3.h:1185
    -

    This creates a 640 by 480 windowed mode window with an OpenGL context. If window or OpenGL context creation fails, NULL will be returned. You should always check the return value. While window creation rarely fails, context creation depends on properly installed drivers and may fail even on machines with the necessary hardware.

    -

    By default, the OpenGL context GLFW creates may have any version. You can require a minimum OpenGL version by setting the GLFW_CONTEXT_VERSION_MAJOR and GLFW_CONTEXT_VERSION_MINOR hints before creation. If the required minimum version is not supported on the machine, context (and window) creation fails.

    -
    - +
    struct GLFWwindow GLFWwindow
    Opaque window object.
    Definition glfw3.h:1403
    +

    This creates a 640 by 480 windowed mode window with an OpenGL context. If window or OpenGL context creation fails, NULL will be returned. You should always check the return value. While window creation rarely fails, context creation depends on properly installed drivers and may fail even on machines with the necessary hardware.

    +

    By default, the OpenGL context GLFW creates may have any version. You can require a minimum OpenGL version by setting the GLFW_CONTEXT_VERSION_MAJOR and GLFW_CONTEXT_VERSION_MINOR hints before creation. If the required minimum version is not supported on the machine, context (and window) creation fails.

    +

    You can select the OpenGL profile by setting the GLFW_OPENGL_PROFILE hint. This program uses the core profile as that is the only profile macOS supports for OpenGL 3.x and 4.x.

    +
    + +
    GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
    if (!window)
    {
    // Window or context creation failed
    }
    -
    #define GLFW_CONTEXT_VERSION_MINOR
    Context client API minor version hint and attribute.
    Definition: glfw3.h:961
    +
    #define GLFW_OPENGL_CORE_PROFILE
    Definition glfw3.h:1149
    +
    #define GLFW_CONTEXT_VERSION_MINOR
    Context client API minor version hint and attribute.
    Definition glfw3.h:1043
    +
    #define GLFW_OPENGL_PROFILE
    OpenGL profile hint and attribute.
    Definition glfw3.h:1078
    void glfwWindowHint(int hint, int value)
    Sets the specified window hint to the desired value.
    -
    #define GLFW_CONTEXT_VERSION_MAJOR
    Context client API major version hint and attribute.
    Definition: glfw3.h:955
    -

    The window handle is passed to all window related functions and is provided to along to all window related callbacks, so they can tell which window received the event.

    -

    When a window and context is no longer needed, destroy it.

    +
    #define GLFW_CONTEXT_VERSION_MAJOR
    Context client API major version hint and attribute.
    Definition glfw3.h:1037
    +

    When a window and context is no longer needed, destroy it.

    void glfwDestroyWindow(GLFWwindow *window)
    Destroys the specified window and its context.
    -

    Once this function is called, no more events will be delivered for that window and its handle becomes invalid.

    +

    Once this function is called, no more events will be delivered for that window and its handle becomes invalid.

    Making the OpenGL context current

    -

    Before you can use the OpenGL API, you must have a current OpenGL context.

    +

    Before you can use the OpenGL API, you must have a current OpenGL context.

    void glfwMakeContextCurrent(GLFWwindow *window)
    Makes the context of the specified window current for the calling thread.
    -

    The context will remain current until you make another context current or until the window owning the current context is destroyed.

    -

    If you are using an extension loader library to access modern OpenGL then this is when to initialize it, as the loader needs a current context to load from. This example uses glad, but the same rule applies to all such libraries.

    +

    The context will remain current until you make another context current or until the window owning the current context is destroyed.

    +

    If you are using an extension loader library to access modern OpenGL then this is when to initialize it, as the loader needs a current context to load from. This example uses glad, but the same rule applies to all such libraries.

    gladLoadGL(glfwGetProcAddress);
    GLFWglproc glfwGetProcAddress(const char *procname)
    Returns the address of the specified function for the current context.

    Checking the window close flag

    -

    Each window has a flag indicating whether the window should be closed.

    -

    When the user attempts to close the window, either by pressing the close widget in the title bar or using a key combination like Alt+F4, this flag is set to 1. Note that the window isn't actually closed, so you are expected to monitor this flag and either destroy the window or give some kind of feedback to the user.

    +

    Each window has a flag indicating whether the window should be closed.

    +

    When the user attempts to close the window, either by pressing the close widget in the title bar or using a key combination like Alt+F4, this flag is set to 1. Note that the window isn't actually closed, so you are expected to monitor this flag and either destroy the window or give some kind of feedback to the user.

    while (!glfwWindowShouldClose(window))
    {
    // Keep running
    }
    int glfwWindowShouldClose(GLFWwindow *window)
    Checks the close flag of the specified window.
    -

    You can be notified when the user is attempting to close the window by setting a close callback with glfwSetWindowCloseCallback. The callback will be called immediately after the close flag has been set.

    -

    You can also set it yourself with glfwSetWindowShouldClose. This can be useful if you want to interpret other kinds of input as closing the window, like for example pressing the Escape key.

    +

    You can be notified when the user is attempting to close the window by setting a close callback with glfwSetWindowCloseCallback. The callback will be called immediately after the close flag has been set.

    +

    You can also set it yourself with glfwSetWindowShouldClose. This can be useful if you want to interpret other kinds of input as closing the window, like for example pressing the Escape key.

    Receiving input events

    -

    Each window has a large number of callbacks that can be set to receive all the various kinds of events. To receive key press and release events, create a key callback function.

    +

    Each window has a large number of callbacks that can be set to receive all the various kinds of events. To receive key press and release events, create a key callback function.

    static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
    {
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
    }
    -
    #define GLFW_TRUE
    One.
    Definition: glfw3.h:312
    -
    #define GLFW_PRESS
    The key or mouse button was pressed.
    Definition: glfw3.h:338
    -
    #define GLFW_KEY_ESCAPE
    Definition: glfw3.h:446
    +
    #define GLFW_TRUE
    One.
    Definition glfw3.h:312
    +
    #define GLFW_PRESS
    The key or mouse button was pressed.
    Definition glfw3.h:338
    +
    #define GLFW_KEY_ESCAPE
    Definition glfw3.h:448
    void glfwSetWindowShouldClose(GLFWwindow *window, int value)
    Sets the close flag of the specified window.
    -

    The key callback, like other window related callbacks, are set per-window.

    +

    The key callback, like other window related callbacks, are set per-window.

    glfwSetKeyCallback(window, key_callback);
    GLFWkeyfun glfwSetKeyCallback(GLFWwindow *window, GLFWkeyfun callback)
    Sets the key callback.
    -

    In order for event callbacks to be called when events occur, you need to process events as described below.

    +

    In order for event callbacks to be called when events occur, you need to process events as described below.

    Rendering with OpenGL

    -

    Once you have a current OpenGL context, you can use OpenGL normally. In this tutorial, a multi-colored rotating triangle will be rendered. The framebuffer size needs to be retrieved for glViewport.

    +

    Once you have a current OpenGL context, you can use OpenGL normally. In this tutorial, a multicolored rotating triangle will be rendered. The framebuffer size needs to be retrieved for glViewport.

    int width, height;
    glfwGetFramebufferSize(window, &width, &height);
    glViewport(0, 0, width, height);
    void glfwGetFramebufferSize(GLFWwindow *window, int *width, int *height)
    Retrieves the size of the framebuffer of the specified window.
    -

    You can also set a framebuffer size callback using glfwSetFramebufferSizeCallback and be notified when the size changes.

    -

    The details of how to render with OpenGL is outside the scope of this tutorial, but there are many excellent resources for learning modern OpenGL. Here are a few of them:

    +

    You can also set a framebuffer size callback using glfwSetFramebufferSizeCallback and be notified when the size changes.

    +

    The details of how to render with OpenGL is outside the scope of this tutorial, but there are many excellent resources for learning modern OpenGL. Here are a few of them:

    -

    These all happen to use GLFW, but OpenGL itself works the same whatever API you use to create the window and context.

    +

    These all happen to use GLFW, but OpenGL itself works the same whatever API you use to create the window and context.

    Reading the timer

    -

    To create smooth animation, a time source is needed. GLFW provides a timer that returns the number of seconds since initialization. The time source used is the most accurate on each platform and generally has micro- or nanosecond resolution.

    +

    To create smooth animation, a time source is needed. GLFW provides a timer that returns the number of seconds since initialization. The time source used is the most accurate on each platform and generally has micro- or nanosecond resolution.

    double time = glfwGetTime();
    double glfwGetTime(void)
    Returns the GLFW time.

    Swapping buffers

    -

    GLFW windows by default use double buffering. That means that each window has two rendering buffers; a front buffer and a back buffer. The front buffer is the one being displayed and the back buffer the one you render to.

    -

    When the entire frame has been rendered, the buffers need to be swapped with one another, so the back buffer becomes the front buffer and vice versa.

    +

    GLFW windows by default use double buffering. That means that each window has two rendering buffers; a front buffer and a back buffer. The front buffer is the one being displayed and the back buffer the one you render to.

    +

    When the entire frame has been rendered, the buffers need to be swapped with one another, so the back buffer becomes the front buffer and vice versa.

    void glfwSwapBuffers(GLFWwindow *window)
    Swaps the front and back buffers of the specified window.
    -

    The swap interval indicates how many frames to wait until swapping the buffers, commonly known as vsync. By default, the swap interval is zero, meaning buffer swapping will occur immediately. On fast machines, many of those frames will never be seen, as the screen is still only updated typically 60-75 times per second, so this wastes a lot of CPU and GPU cycles.

    -

    Also, because the buffers will be swapped in the middle the screen update, leading to screen tearing.

    -

    For these reasons, applications will typically want to set the swap interval to one. It can be set to higher values, but this is usually not recommended, because of the input latency it leads to.

    +

    The swap interval indicates how many frames to wait until swapping the buffers, commonly known as vsync. By default, the swap interval is zero, meaning buffer swapping will occur immediately. On fast machines, many of those frames will never be seen, as the screen is still only updated typically 60-75 times per second, so this wastes a lot of CPU and GPU cycles.

    +

    Also, because the buffers will be swapped in the middle the screen update, leading to screen tearing.

    +

    For these reasons, applications will typically want to set the swap interval to one. It can be set to higher values, but this is usually not recommended, because of the input latency it leads to.

    void glfwSwapInterval(int interval)
    Sets the swap interval for the current context.
    -

    This function acts on the current context and will fail unless a context is current.

    +

    This function acts on the current context and will fail unless a context is current.

    Processing events

    -

    GLFW needs to communicate regularly with the window system both in order to receive events and to show that the application hasn't locked up. Event processing must be done regularly while you have visible windows and is normally done each frame after buffer swapping.

    -

    There are two methods for processing pending events; polling and waiting. This example will use event polling, which processes only those events that have already been received and then returns immediately.

    +

    GLFW needs to communicate regularly with the window system both in order to receive events and to show that the application hasn't locked up. Event processing must be done regularly while you have visible windows and is normally done each frame after buffer swapping.

    +

    There are two methods for processing pending events; polling and waiting. This example will use event polling, which processes only those events that have already been received and then returns immediately.

    void glfwPollEvents(void)
    Processes all pending events.
    -

    This is the best choice when rendering continually, like most games do. If instead you only need to update your rendering once you have received new input, glfwWaitEvents is a better choice. It waits until at least one event has been received, putting the thread to sleep in the meantime, and then processes all received events. This saves a great deal of CPU cycles and is useful for, for example, many kinds of editing tools.

    +

    This is the best choice when rendering continually, like most games do. If instead you only need to update your rendering once you have received new input, glfwWaitEvents is a better choice. It waits until at least one event has been received, putting the thread to sleep in the meantime, and then processes all received events. This saves a great deal of CPU cycles and is useful for, for example, many kinds of editing tools.

    Putting it together

    -

    Now that you know how to initialize GLFW, create a window and poll for keyboard input, it's possible to create a simple program.

    -

    This program creates a 640 by 480 windowed mode window and starts a loop that clears the screen, renders a triangle and processes events until the user either presses Escape or closes the window.

    +

    Now that you know how to initialize GLFW, create a window and poll for keyboard input, it's possible to create a small program.

    +

    This program creates a 640 by 480 windowed mode window and starts a loop that clears the screen, renders a triangle and processes events until the user either presses Escape or closes the window.

    +
    #define GLAD_GL_IMPLEMENTATION
    #include <glad/gl.h>
    #define GLFW_INCLUDE_NONE
    #include <GLFW/glfw3.h>
    @@ -237,25 +248,28 @@ Putting it together
    #include "linmath.h"
    #include <stdlib.h>
    +
    #include <stddef.h>
    #include <stdio.h>
    -
    static const struct
    +
    typedef struct Vertex
    {
    -
    float x, y;
    -
    float r, g, b;
    -
    } vertices[3] =
    +
    vec2 pos;
    +
    vec3 col;
    +
    } Vertex;
    +
    +
    static const Vertex vertices[3] =
    {
    -
    { -0.6f, -0.4f, 1.f, 0.f, 0.f },
    -
    { 0.6f, -0.4f, 0.f, 1.f, 0.f },
    -
    { 0.f, 0.6f, 0.f, 0.f, 1.f }
    +
    { { -0.6f, -0.4f }, { 1.f, 0.f, 0.f } },
    +
    { { 0.6f, -0.4f }, { 0.f, 1.f, 0.f } },
    +
    { { 0.f, 0.6f }, { 0.f, 0.f, 1.f } }
    };
    static const char* vertex_shader_text =
    -
    "#version 110\n"
    +
    "#version 330\n"
    "uniform mat4 MVP;\n"
    -
    "attribute vec3 vCol;\n"
    -
    "attribute vec2 vPos;\n"
    -
    "varying vec3 color;\n"
    +
    "in vec3 vCol;\n"
    +
    "in vec2 vPos;\n"
    +
    "out vec3 color;\n"
    "void main()\n"
    "{\n"
    " gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
    @@ -263,11 +277,12 @@ Putting it together
    "}\n";
    static const char* fragment_shader_text =
    -
    "#version 110\n"
    -
    "varying vec3 color;\n"
    +
    "#version 330\n"
    +
    "in vec3 color;\n"
    +
    "out vec4 fragment;\n"
    "void main()\n"
    "{\n"
    -
    " gl_FragColor = vec4(color, 1.0);\n"
    +
    " fragment = vec4(color, 1.0);\n"
    "}\n";
    static void error_callback(int error, const char* description)
    @@ -283,19 +298,16 @@ Putting it together
    int main(void)
    {
    -
    GLFWwindow* window;
    -
    GLuint vertex_buffer, vertex_shader, fragment_shader, program;
    -
    GLint mvp_location, vpos_location, vcol_location;
    -
    glfwSetErrorCallback(error_callback);
    if (!glfwInit())
    exit(EXIT_FAILURE);
    - - + + +
    -
    window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
    +
    GLFWwindow* window = glfwCreateWindow(640, 480, "OpenGL Triangle", NULL, NULL);
    if (!window)
    {
    @@ -310,53 +322,56 @@ Putting it together
    // NOTE: OpenGL error checks have been omitted for brevity
    +
    GLuint vertex_buffer;
    glGenBuffers(1, &vertex_buffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    -
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    +
    const GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
    glCompileShader(vertex_shader);
    -
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    +
    const GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
    glCompileShader(fragment_shader);
    -
    program = glCreateProgram();
    +
    const GLuint program = glCreateProgram();
    glAttachShader(program, vertex_shader);
    glAttachShader(program, fragment_shader);
    glLinkProgram(program);
    -
    mvp_location = glGetUniformLocation(program, "MVP");
    -
    vpos_location = glGetAttribLocation(program, "vPos");
    -
    vcol_location = glGetAttribLocation(program, "vCol");
    +
    const GLint mvp_location = glGetUniformLocation(program, "MVP");
    +
    const GLint vpos_location = glGetAttribLocation(program, "vPos");
    +
    const GLint vcol_location = glGetAttribLocation(program, "vCol");
    +
    GLuint vertex_array;
    +
    glGenVertexArrays(1, &vertex_array);
    +
    glBindVertexArray(vertex_array);
    glEnableVertexAttribArray(vpos_location);
    glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
    -
    sizeof(vertices[0]), (void*) 0);
    +
    sizeof(Vertex), (void*) offsetof(Vertex, pos));
    glEnableVertexAttribArray(vcol_location);
    glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE,
    -
    sizeof(vertices[0]), (void*) (sizeof(float) * 2));
    +
    sizeof(Vertex), (void*) offsetof(Vertex, col));
    while (!glfwWindowShouldClose(window))
    {
    -
    float ratio;
    int width, height;
    -
    mat4x4 m, p, mvp;
    -
    glfwGetFramebufferSize(window, &width, &height);
    -
    ratio = width / (float) height;
    +
    const float ratio = width / (float) height;
    glViewport(0, 0, width, height);
    glClear(GL_COLOR_BUFFER_BIT);
    +
    mat4x4 m, p, mvp;
    mat4x4_identity(m);
    mat4x4_rotate_Z(m, m, (float) glfwGetTime());
    mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f);
    mat4x4_mul(mvp, p, m);
    glUseProgram(program);
    -
    glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp);
    +
    glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) &mvp);
    +
    glBindVertexArray(vertex_array);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glfwSwapBuffers(window);
    @@ -369,8 +384,8 @@ Putting it together
    exit(EXIT_SUCCESS);
    }
    -

    The program above can be found in the source package as examples/simple.c and is compiled along with all other examples when you build GLFW. If you built GLFW from the source package then you already have this as simple.exe on Windows, simple on Linux or simple.app on macOS.

    -

    This tutorial used only a few of the many functions GLFW provides. There are guides for each of the areas covered by GLFW. Each guide will introduce all the functions for that category.

    +

    The program above can be found in the source package as examples/triangle-opengl.c and is compiled along with all other examples when you build GLFW. If you built GLFW from the source package then you already have this as triangle-opengl.exe on Windows, triangle-opengl on Linux or triangle-opengl.app on macOS.

    +

    This tutorial used only a few of the many functions GLFW provides. There are guides for each of the areas covered by GLFW. Each guide will introduce all the functions for that category.

    -

    You can access reference documentation for any GLFW function by clicking it and the reference for each function links to related functions and guide sections.

    -

    The tutorial ends here. Once you have written a program that uses GLFW, you will need to compile and link it. How to do that depends on the development environment you are using and is best explained by the documentation for that environment. To learn about the details that are specific to GLFW, see Building applications.

    +

    You can access reference documentation for any GLFW function by clicking it and the reference for each function links to related functions and guide sections.

    +

    The tutorial ends here. Once you have written a program that uses GLFW, you will need to compile and link it. How to do that depends on the development environment you are using and is best explained by the documentation for that environment. To learn about the details that are specific to GLFW, see Building applications.

    diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_0.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_0.js new file mode 100644 index 0000000..90bc96f --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['1_209_208_20or_20later_0',['Documentation generation requires Doxygen 1.9.8 or later',['../news.html#docs_target_caveat',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1.js new file mode 100644 index 0000000..ccae2b5 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['2_20to_203_0',['Moving from GLFW 2 to 3',['../moving_guide.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_10.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_10.js new file mode 100644 index 0000000..2fd24d1 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_10.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['joystick_20axis_20states_0',['Joystick axis states',['../input_guide.html#joystick_axis',1,'']]], + ['joystick_20button_20states_1',['Joystick button states',['../input_guide.html#joystick_button',1,'']]], + ['joystick_20configuration_20changes_2',['Joystick configuration changes',['../input_guide.html#joystick_event',1,'']]], + ['joystick_20function_20changes_3',['Joystick function changes',['../moving_guide.html#moving_joystick',1,'']]], + ['joystick_20hat_20states_4',['joystick hat states',['../group__hat__state.html',1,'Joystick hat states'],['../input_guide.html#joystick_hat',1,'Joystick hat states']]], + ['joystick_20input_5',['Joystick input',['../input_guide.html#joystick',1,'']]], + ['joystick_20name_6',['Joystick name',['../input_guide.html#joystick_name',1,'']]], + ['joystick_20support_20is_20initialized_20on_20demand_7',['Joystick support is initialized on demand',['../news.html#joystick_init_caveat',1,'']]], + ['joystick_20user_20pointer_8',['Joystick user pointer',['../input_guide.html#joystick_userptr',1,'']]], + ['joysticks_9',['Joysticks',['../group__joysticks.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_11.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_11.js new file mode 100644 index 0000000..6b48248 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_11.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['key_20flags_0',['Modifier key flags',['../group__mods.html',1,'']]], + ['key_20input_1',['key input',['../input_guide.html#input_key',1,'Key input'],['../moving_guide.html#moving_keys',1,'Physical key input']]], + ['key_20names_2',['Key names',['../input_guide.html#input_key_name',1,'']]], + ['key_20repeat_20action_3',['Key repeat action',['../moving_guide.html#moving_repeat',1,'']]], + ['key_20tokens_4',['Keyboard key tokens',['../group__keys.html',1,'']]], + ['keyboard_20access_20hint_5',['Windows window menu keyboard access hint',['../news.html#win32_keymenu_hint',1,'']]], + ['keyboard_20input_6',['Keyboard input',['../input_guide.html#input_keyboard',1,'']]], + ['keyboard_20key_20tokens_7',['Keyboard key tokens',['../group__keys.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_12.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_12.js new file mode 100644 index 0000000..1f30073 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_12.js @@ -0,0 +1,26 @@ +var searchData= +[ + ['lack_20alpha_20channel_20on_20older_20systems_0',['Wayland framebuffer may lack alpha channel on older systems',['../news.html#wayland_alpha_caveat',1,'']]], + ['later_1',['Documentation generation requires Doxygen 1.9.8 or later',['../news.html#docs_target_caveat',1,'']]], + ['leave_20events_2',['Cursor enter/leave events',['../input_guide.html#cursor_enter',1,'']]], + ['libdecor_20decorations_3',['Wayland libdecor decorations',['../news.html#wayland_libdecor_decorations',1,'']]], + ['libraries_4',['Link with the right libraries',['../build_guide.html#build_link',1,'']]], + ['library_5',['library',['../compile_guide.html#compile_compile',1,'Compiling the library'],['../context_guide.html#context_glext_auto',1,'Loading extension with a loader library']]], + ['library_20and_20header_20file_6',['Renamed library and header file',['../moving_guide.html#moving_renamed_files',1,'']]], + ['lifetimes_7',['Pointer lifetimes',['../intro_guide.html#lifetime',1,'']]], + ['like_20system_20specific_20cmake_20options_8',['Unix-like system specific CMake options',['../compile_guide.html#compile_options_unix',1,'']]], + ['limitations_9',['Guarantees and limitations',['../intro_guide.html#guarantees_limitations',1,'']]], + ['limits_10',['Window size limits',['../window_guide.html#window_sizelimits',1,'']]], + ['line_20cmake_11',['Generating with command-line CMake',['../compile_guide.html#compile_generate_cli',1,'']]], + ['line_20or_20makefile_20on_20macos_12',['With command-line or makefile on macOS',['../build_guide.html#build_link_osx',1,'']]], + ['link_20with_20the_20right_20libraries_13',['Link with the right libraries',['../build_guide.html#build_link',1,'']]], + ['list_14',['Deprecated List',['../deprecated.html',1,'']]], + ['loader_15',['Finding the Vulkan loader',['../vulkan_guide.html#vulkan_loader',1,'']]], + ['loader_20and_20api_16',['Vulkan loader and API',['../compat_guide.html#compat_vulkan',1,'']]], + ['loader_20library_17',['Loading extension with a loader library',['../context_guide.html#context_glext_auto',1,'']]], + ['loading_18',['Removal of image and texture loading',['../moving_guide.html#moving_image',1,'']]], + ['loading_20extension_20with_20a_20loader_20library_19',['Loading extension with a loader library',['../context_guide.html#context_glext_auto',1,'']]], + ['loading_20extensions_20manually_20',['Loading extensions manually',['../context_guide.html#context_glext_manual',1,'']]], + ['longer_20generated_21',['Configuration header is no longer generated',['../news.html#config_header_caveat',1,'']]], + ['longer_20round_20trip_20to_20server_22',['X11 empty events no longer round-trip to server',['../news.html#x11_emptyevent_caveat',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_13.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_13.js new file mode 100644 index 0000000..2804d16 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_13.js @@ -0,0 +1,51 @@ +var searchData= +[ + ['macos_0',['macos',['../compat_guide.html#compat_osx',1,'OpenGL on macOS'],['../build_guide.html#build_link_osx',1,'With command-line or makefile on macOS'],['../build_guide.html#build_link_xcode',1,'With Xcode on macOS']]], + ['macos_20corevideo_20dependency_20has_20been_20removed_1',['macOS CoreVideo dependency has been removed',['../news.html#corevideo_caveat',1,'']]], + ['macos_20main_20menu_20now_20created_20at_20initialization_2',['macOS main menu now created at initialization',['../news.html#macos_menu_caveat',1,'']]], + ['macos_20specific_20cmake_20options_3',['macOS specific CMake options',['../compile_guide.html#compile_options_macos',1,'']]], + ['macos_20specific_20hints_4',['macOS specific hints',['../window_guide.html#window_hints_osx',1,'']]], + ['macos_20specific_20init_20hints_5',['macOS specific init hints',['../intro_guide.html#init_hints_osx',1,'']]], + ['macro_6',['Removal of GLFWCALL macro',['../moving_guide.html#moving_stdcall',1,'']]], + ['macros_7',['macros',['../internals_guide.html#internals_config',1,'Configuration macros'],['../build_guide.html#build_macros',1,'GLFW header option macros']]], + ['main_20menu_20now_20created_20at_20initialization_8',['macOS main menu now created at initialization',['../news.html#macos_menu_caveat',1,'']]], + ['main_2emd_9',['main.md',['../main_8md.html',1,'']]], + ['makefile_20on_20macos_10',['With command-line or makefile on macOS',['../build_guide.html#build_link_osx',1,'']]], + ['making_20the_20opengl_20context_20current_11',['Making the OpenGL context current',['../quick_guide.html#quick_context_current',1,'']]], + ['management_12',['management',['../moving_guide.html#moving_context',1,'Explicit context management'],['../intro_guide.html#intro_version',1,'Version management']]], + ['manually_13',['manually',['../compile_guide.html#compile_manual',1,'Compiling GLFW manually'],['../context_guide.html#context_glext_manual',1,'Loading extensions manually']]], + ['mappings_14',['Gamepad mappings',['../input_guide.html#gamepad_mapping',1,'']]], + ['maximization_15',['Window maximization',['../window_guide.html#window_maximize',1,'']]], + ['may_20lack_20alpha_20channel_20on_20older_20systems_16',['Wayland framebuffer may lack alpha channel on older systems',['../news.html#wayland_alpha_caveat',1,'']]], + ['mbcs_20support_17',['Win32 MBCS support',['../moving_guide.html#moving_mbcs',1,'']]], + ['memory_20allocator_18',['memory allocator',['../intro_guide.html#init_allocator',1,'Custom heap memory allocator'],['../news.html#custom_heap_allocator',1,'Support for custom heap memory allocator']]], + ['menu_20keyboard_20access_20hint_19',['Windows window menu keyboard access hint',['../news.html#win32_keymenu_hint',1,'']]], + ['menu_20now_20created_20at_20initialization_20',['macOS main menu now created at initialization',['../news.html#macos_menu_caveat',1,'']]], + ['mingw_21',['Cross-compilation with CMake and MinGW',['../compile_guide.html#compile_mingw_cross',1,'']]], + ['mingw_20support_20is_20deprecated_22',['Original MinGW support is deprecated',['../news.html#mingw_deprecated',1,'']]], + ['mingw_20w64_20and_20glfw_20binaries_23',['With MinGW-w64 and GLFW binaries',['../build_guide.html#build_link_mingw',1,'']]], + ['mode_24',['mode',['../news.html#captured_cursor_mode',1,'Captured cursor mode'],['../input_guide.html#cursor_mode',1,'Cursor mode']]], + ['mode_20enumeration_25',['Video mode enumeration',['../moving_guide.html#moving_video_modes',1,'']]], + ['modes_26',['Video modes',['../monitor_guide.html#monitor_modes',1,'']]], + ['modifier_20key_20flags_27',['Modifier key flags',['../group__mods.html',1,'']]], + ['monitor_28',['Window monitor',['../window_guide.html#window_monitor',1,'']]], + ['monitor_20configuration_20changes_29',['Monitor configuration changes',['../monitor_guide.html#monitor_event',1,'']]], + ['monitor_20guide_30',['Monitor guide',['../monitor_guide.html',1,'']]], + ['monitor_20objects_31',['Monitor objects',['../monitor_guide.html#monitor_object',1,'']]], + ['monitor_20properties_32',['Monitor properties',['../monitor_guide.html#monitor_properties',1,'']]], + ['monitor_20reference_33',['Monitor reference',['../group__monitor.html',1,'']]], + ['monitor_20related_20hints_34',['Monitor related hints',['../window_guide.html#window_hints_mtr',1,'']]], + ['monitor_20selection_35',['Explicit monitor selection',['../moving_guide.html#moving_monitor',1,'']]], + ['monitor_2emd_36',['monitor.md',['../monitor_8md.html',1,'']]], + ['monitors_37',['Retrieving monitors',['../monitor_guide.html#monitor_monitors',1,'']]], + ['more_20standard_20cursor_20shapes_38',['More standard cursor shapes',['../news.html#more_cursor_shapes',1,'']]], + ['motion_39',['Raw mouse motion',['../input_guide.html#raw_mouse_motion',1,'']]], + ['mouse_20button_20input_40',['Mouse button input',['../input_guide.html#input_mouse_button',1,'']]], + ['mouse_20buttons_41',['Mouse buttons',['../group__buttons.html',1,'']]], + ['mouse_20event_20passthrough_42',['Mouse event passthrough',['../news.html#mouse_input_passthrough',1,'']]], + ['mouse_20input_43',['Mouse input',['../input_guide.html#input_mouse',1,'']]], + ['mouse_20motion_44',['Raw mouse motion',['../input_guide.html#raw_mouse_motion',1,'']]], + ['moving_20from_20glfw_202_20to_203_45',['Moving from GLFW 2 to 3',['../moving_guide.html',1,'']]], + ['moving_2emd_46',['moving.md',['../moving_8md.html',1,'']]], + ['multiple_20sets_20of_20native_20access_20functions_47',['Multiple sets of native access functions',['../news.html#multiplatform_caveat',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_14.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_14.js new file mode 100644 index 0000000..4cc60a7 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_14.js @@ -0,0 +1,22 @@ +var searchData= +[ + ['name_0',['name',['../monitor_guide.html#monitor_name',1,'Human-readable name'],['../input_guide.html#joystick_name',1,'Joystick name']]], + ['name_20change_20tables_1',['Name change tables',['../moving_guide.html#moving_tables',1,'']]], + ['names_2',['Key names',['../input_guide.html#input_key_name',1,'']]], + ['native_20access_3',['Native access',['../group__native.html',1,'']]], + ['native_20access_20function_4',['Cocoa NSView native access function',['../news.html#cocoa_nsview_function',1,'']]], + ['native_20access_20functions_5',['Multiple sets of native access functions',['../news.html#multiplatform_caveat',1,'']]], + ['native_20interface_6',['Native interface',['../internals_guide.html#internals_native',1,'']]], + ['new_20constants_7',['New constants',['../news.html#new_constants',1,'']]], + ['new_20features_8',['New features',['../news.html#features',1,'']]], + ['new_20functions_9',['New functions',['../news.html#new_functions',1,'']]], + ['new_20symbols_10',['New symbols',['../news.html#new_symbols',1,'']]], + ['new_20types_11',['New types',['../news.html#new_types',1,'']]], + ['news_2emd_12',['news.md',['../news_8md.html',1,'']]], + ['no_20longer_20generated_13',['Configuration header is no longer generated',['../news.html#config_header_caveat',1,'']]], + ['no_20longer_20round_20trip_20to_20server_14',['X11 empty events no longer round-trip to server',['../news.html#x11_emptyevent_caveat',1,'']]], + ['notes_20for_20earlier_20versions_15',['Release notes for earlier versions',['../news.html#news_archive',1,'']]], + ['notes_20for_20version_203_204_16',['Release notes for version 3.4',['../news.html',1,'']]], + ['now_20created_20at_20initialization_17',['macOS main menu now created at initialization',['../news.html#macos_menu_caveat',1,'']]], + ['nsview_20native_20access_20function_18',['Cocoa NSView native access function',['../news.html#cocoa_nsview_function',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_15.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_15.js new file mode 100644 index 0000000..3e32a8a --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_15.js @@ -0,0 +1,35 @@ +var searchData= +[ + ['object_20sharing_0',['Context object sharing',['../context_guide.html#context_sharing',1,'']]], + ['objects_1',['objects',['../context_guide.html#context_object',1,'Context objects'],['../input_guide.html#cursor_object',1,'Cursor objects'],['../monitor_guide.html#monitor_object',1,'Monitor objects'],['../window_guide.html#window_object',1,'Window objects']]], + ['of_20automatic_20event_20polling_2',['Removal of automatic event polling',['../moving_guide.html#moving_autopoll',1,'']]], + ['of_20character_20actions_3',['Removal of character actions',['../moving_guide.html#moving_char_up',1,'']]], + ['of_20glfwcall_20macro_4',['Removal of GLFWCALL macro',['../moving_guide.html#moving_stdcall',1,'']]], + ['of_20image_20and_20texture_20loading_5',['Removal of image and texture loading',['../moving_guide.html#moving_image',1,'']]], + ['of_20native_20access_20functions_6',['Multiple sets of native access functions',['../news.html#multiplatform_caveat',1,'']]], + ['of_20system_20wide_20hotkeys_7',['Capture of system-wide hotkeys',['../moving_guide.html#moving_syskeys',1,'']]], + ['of_20threading_20functions_8',['Removal of threading functions',['../moving_guide.html#moving_threads',1,'']]], + ['of_20window_20and_20framebuffer_20sizes_9',['Separation of window and framebuffer sizes',['../moving_guide.html#moving_hidpi',1,'']]], + ['of_20windows_20older_20than_20xp_10',['Support for versions of Windows older than XP',['../moving_guide.html#moving_windows',1,'']]], + ['offscreen_20contexts_11',['Offscreen contexts',['../context_guide.html#context_offscreen',1,'']]], + ['offsets_12',['Wheel position replaced by scroll offsets',['../moving_guide.html#moving_wheel',1,'']]], + ['older_20systems_13',['Wayland framebuffer may lack alpha channel on older systems',['../news.html#wayland_alpha_caveat',1,'']]], + ['older_20than_20xp_14',['Support for versions of Windows older than XP',['../moving_guide.html#moving_windows',1,'']]], + ['on_20demand_15',['Joystick support is initialized on demand',['../news.html#joystick_init_caveat',1,'']]], + ['on_20macos_16',['on macos',['../compat_guide.html#compat_osx',1,'OpenGL on macOS'],['../build_guide.html#build_link_osx',1,'With command-line or makefile on macOS'],['../build_guide.html#build_link_xcode',1,'With Xcode on macOS']]], + ['on_20older_20systems_17',['Wayland framebuffer may lack alpha channel on older systems',['../news.html#wayland_alpha_caveat',1,'']]], + ['on_20unix_18',['With pkg-config and GLFW binaries on Unix',['../build_guide.html#build_link_pkgconfig',1,'']]], + ['opengl_19',['Rendering with OpenGL',['../quick_guide.html#quick_render',1,'']]], + ['opengl_20and_20opengl_20es_20extensions_20',['OpenGL and OpenGL ES extensions',['../context_guide.html#context_glext',1,'']]], + ['opengl_20context_20current_21',['Making the OpenGL context current',['../quick_guide.html#quick_context_current',1,'']]], + ['opengl_20on_20macos_22',['OpenGL on macOS',['../compat_guide.html#compat_osx',1,'']]], + ['option_20has_20been_20removed_23',['option has been removed',['../news.html#use_osmesa_removed',1,'GLFW_USE_OSMESA CMake option has been removed'],['../news.html#use_wayland_removed',1,'GLFW_USE_WAYLAND CMake option has been removed'],['../news.html#vulkan_static_removed',1,'GLFW_VULKAN_STATIC CMake option has been removed']]], + ['option_20macros_24',['GLFW header option macros',['../build_guide.html#build_macros',1,'']]], + ['options_25',['options',['../compile_guide.html#compile_options',1,'CMake options'],['../compile_guide.html#compile_options_macos',1,'macOS specific CMake options'],['../compile_guide.html#compile_options_shared',1,'Shared CMake options'],['../compile_guide.html#compile_options_unix',1,'Unix-like system specific CMake options'],['../compile_guide.html#compile_options_win32',1,'Win32 specific CMake options']]], + ['or_20later_26',['Documentation generation requires Doxygen 1.9.8 or later',['../news.html#docs_target_caveat',1,'']]], + ['or_20makefile_20on_20macos_27',['With command-line or makefile on macOS',['../build_guide.html#build_link_osx',1,'']]], + ['order_28',['Event order',['../intro_guide.html#event_order',1,'']]], + ['original_20mingw_20support_20is_20deprecated_29',['Original MinGW support is deprecated',['../news.html#mingw_deprecated',1,'']]], + ['os_20x_20yosemite_20support_20is_20deprecated_30',['OS X Yosemite support is deprecated',['../news.html#yosemite_deprecated',1,'']]], + ['output_31',['Clipboard input and output',['../input_guide.html#clipboard',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_16.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_16.js new file mode 100644 index 0000000..06d2b29 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_16.js @@ -0,0 +1,29 @@ +var searchData= +[ + ['parameters_0',['Window handle parameters',['../moving_guide.html#moving_window_handles',1,'']]], + ['passthrough_1',['Mouse event passthrough',['../news.html#mouse_input_passthrough',1,'']]], + ['path_20drop_20input_2',['Path drop input',['../input_guide.html#path_drop',1,'']]], + ['persistent_20window_20hints_3',['Persistent window hints',['../moving_guide.html#moving_hints',1,'']]], + ['physical_20key_20input_4',['Physical key input',['../moving_guide.html#moving_keys',1,'']]], + ['physical_20size_5',['Physical size',['../monitor_guide.html#monitor_size',1,'']]], + ['pixels_6',['pixels',['../struct_g_l_f_wimage.html#a0c532a5c2bb715555279b7817daba0fb',1,'GLFWimage']]], + ['pkg_20config_20and_20glfw_20binaries_20on_20unix_7',['With pkg-config and GLFW binaries on Unix',['../build_guide.html#build_link_pkgconfig',1,'']]], + ['platform_20interface_8',['Platform interface',['../internals_guide.html#internals_platform',1,'']]], + ['platform_20selection_9',['platform selection',['../news.html#runtime_platform_selection',1,'Runtime platform selection'],['../intro_guide.html#platform',1,'Runtime platform selection']]], + ['pointer_10',['pointer',['../input_guide.html#joystick_userptr',1,'Joystick user pointer'],['../monitor_guide.html#monitor_userptr',1,'User pointer'],['../window_guide.html#window_userptr',1,'User pointer']]], + ['pointer_20lifetimes_11',['Pointer lifetimes',['../intro_guide.html#lifetime',1,'']]], + ['pointers_12',['pointers',['../context_guide.html#context_glext_proc',1,'Fetching function pointers'],['../vulkan_guide.html#vulkan_proc',1,'Querying Vulkan function pointers']]], + ['polling_13',['Removal of automatic event polling',['../moving_guide.html#moving_autopoll',1,'']]], + ['position_14',['position',['../input_guide.html#cursor_pos',1,'Cursor position'],['../monitor_guide.html#monitor_pos',1,'Virtual position'],['../news.html#window_position_hint',1,'Window hints for initial window position'],['../window_guide.html#window_pos',1,'Window position']]], + ['position_20changes_15',['Cursor position changes',['../moving_guide.html#moving_cursorpos',1,'']]], + ['position_20replaced_20by_20scroll_20offsets_16',['Wheel position replaced by scroll offsets',['../moving_guide.html#moving_wheel',1,'']]], + ['presentation_20support_17',['Querying for Vulkan presentation support',['../vulkan_guide.html#vulkan_present',1,'']]], + ['processing_18',['processing',['../input_guide.html#events',1,'Event processing'],['../window_guide.html#window_events',1,'Window event processing']]], + ['processing_20events_19',['Processing events',['../quick_guide.html#quick_process_events',1,'']]], + ['properties_20',['Monitor properties',['../monitor_guide.html#monitor_properties',1,'']]], + ['properties_20and_20events_21',['Window properties and events',['../window_guide.html#window_properties',1,'']]], + ['protocol_20support_20has_20been_20removed_22',['wl_shell protocol support has been removed',['../news.html#wl_shell_removed',1,'']]], + ['protocols_20and_20ipc_20standards_23',['protocols and ipc standards',['../compat_guide.html#compat_wayland',1,'Wayland protocols and IPC standards'],['../compat_guide.html#compat_x11',1,'X11 extensions, protocols and IPC standards']]], + ['public_20interface_24',['Public interface',['../internals_guide.html#internals_public',1,'']]], + ['putting_20it_20together_25',['Putting it together',['../quick_guide.html#quick_example',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_17.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_17.js new file mode 100644 index 0000000..38a5b24 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_17.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['querying_20for_20vulkan_20presentation_20support_0',['Querying for Vulkan presentation support',['../vulkan_guide.html#vulkan_present',1,'']]], + ['querying_20for_20vulkan_20support_1',['Querying for Vulkan support',['../vulkan_guide.html#vulkan_support',1,'']]], + ['querying_20required_20vulkan_20extensions_2',['Querying required Vulkan extensions',['../vulkan_guide.html#vulkan_ext',1,'']]], + ['querying_20vulkan_20function_20pointers_3',['Querying Vulkan function pointers',['../vulkan_guide.html#vulkan_proc',1,'']]], + ['quick_2emd_4',['quick.md',['../quick_8md.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_18.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_18.js new file mode 100644 index 0000000..27e0db0 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_18.js @@ -0,0 +1,44 @@ +var searchData= +[ + ['ramp_0',['Gamma ramp',['../monitor_guide.html#monitor_gamma',1,'']]], + ['raw_20mouse_20motion_1',['Raw mouse motion',['../input_guide.html#raw_mouse_motion',1,'']]], + ['readable_20name_2',['Human-readable name',['../monitor_guide.html#monitor_name',1,'']]], + ['reading_20the_20timer_3',['Reading the timer',['../quick_guide.html#quick_timer',1,'']]], + ['reallocate_4',['reallocate',['../struct_g_l_f_wallocator.html#af5a674af9e170095b968f467233437be',1,'GLFWallocator']]], + ['receiving_20input_20events_5',['Receiving input events',['../quick_guide.html#quick_key_input',1,'']]], + ['red_6',['red',['../struct_g_l_f_wgammaramp.html#a2cce5d968734b685623eef913e635138',1,'GLFWgammaramp']]], + ['redbits_7',['redBits',['../struct_g_l_f_wvidmode.html#a6066c4ecd251098700062d3b735dba1b',1,'GLFWvidmode']]], + ['reentrancy_8',['Reentrancy',['../intro_guide.html#reentrancy',1,'']]], + ['reference_9',['reference',['../group__context.html',1,'Context reference'],['../group__init.html',1,'Initialization, version and error reference'],['../group__input.html',1,'Input reference'],['../group__monitor.html',1,'Monitor reference'],['../group__vulkan.html',1,'Vulkan support reference'],['../group__window.html',1,'Window reference']]], + ['refresh_10',['Window damage and refresh',['../window_guide.html#window_refresh',1,'']]], + ['refreshrate_11',['refreshRate',['../struct_g_l_f_wvidmode.html#a791bdd6c7697b09f7e9c97054bf05649',1,'GLFWvidmode']]], + ['related_20attributes_12',['related attributes',['../window_guide.html#window_attribs_ctx',1,'Context related attributes'],['../window_guide.html#window_attribs_fb',1,'Framebuffer related attributes'],['../window_guide.html#window_attribs_wnd',1,'Window related attributes']]], + ['related_20hints_13',['related hints',['../window_guide.html#window_hints_ctx',1,'Context related hints'],['../window_guide.html#window_hints_fb',1,'Framebuffer related hints'],['../window_guide.html#window_hints_mtr',1,'Monitor related hints'],['../window_guide.html#window_hints_wnd',1,'Window related hints']]], + ['release_20notes_20for_20earlier_20versions_14',['Release notes for earlier versions',['../news.html#news_archive',1,'']]], + ['release_20notes_20for_20version_203_204_15',['Release notes for version 3.4',['../news.html',1,'']]], + ['removal_20of_20automatic_20event_20polling_16',['Removal of automatic event polling',['../moving_guide.html#moving_autopoll',1,'']]], + ['removal_20of_20character_20actions_17',['Removal of character actions',['../moving_guide.html#moving_char_up',1,'']]], + ['removal_20of_20glfwcall_20macro_18',['Removal of GLFWCALL macro',['../moving_guide.html#moving_stdcall',1,'']]], + ['removal_20of_20image_20and_20texture_20loading_19',['Removal of image and texture loading',['../moving_guide.html#moving_image',1,'']]], + ['removal_20of_20threading_20functions_20',['Removal of threading functions',['../moving_guide.html#moving_threads',1,'']]], + ['removals_21',['Removals',['../news.html#removals',1,'']]], + ['removed_22',['removed',['../news.html#use_osmesa_removed',1,'GLFW_USE_OSMESA CMake option has been removed'],['../news.html#use_wayland_removed',1,'GLFW_USE_WAYLAND CMake option has been removed'],['../news.html#vulkan_static_removed',1,'GLFW_VULKAN_STATIC CMake option has been removed'],['../news.html#corevideo_caveat',1,'macOS CoreVideo dependency has been removed'],['../news.html#wl_shell_removed',1,'wl_shell protocol support has been removed']]], + ['removed_20features_23',['Changed and removed features',['../moving_guide.html#moving_removed',1,'']]], + ['renamed_20functions_24',['Renamed functions',['../moving_guide.html#moving_renamed_functions',1,'']]], + ['renamed_20library_20and_20header_20file_25',['Renamed library and header file',['../moving_guide.html#moving_renamed_files',1,'']]], + ['renamed_20tokens_26',['Renamed tokens',['../moving_guide.html#moving_renamed_tokens',1,'']]], + ['renamed_20types_27',['Renamed types',['../moving_guide.html#moving_renamed_types',1,'']]], + ['rendering_20backend_20hint_28',['ANGLE rendering backend hint',['../news.html#angle_renderer_hint',1,'']]], + ['rendering_20with_20opengl_29',['Rendering with OpenGL',['../quick_guide.html#quick_render',1,'']]], + ['repeat_20action_30',['Key repeat action',['../moving_guide.html#moving_repeat',1,'']]], + ['replaced_20by_20scroll_20offsets_31',['Wheel position replaced by scroll offsets',['../moving_guide.html#moving_wheel',1,'']]], + ['request_32',['Window attention request',['../window_guide.html#window_attention',1,'']]], + ['required_20vulkan_20extensions_33',['Querying required Vulkan extensions',['../vulkan_guide.html#vulkan_ext',1,'']]], + ['requires_20doxygen_201_209_208_20or_20later_34',['Documentation generation requires Doxygen 1.9.8 or later',['../news.html#docs_target_caveat',1,'']]], + ['requires_20dwm_20transparency_35',['Windows 7 framebuffer transparency requires DWM transparency',['../news.html#win7_framebuffer_caveat',1,'']]], + ['retrieving_20monitors_36',['Retrieving monitors',['../monitor_guide.html#monitor_monitors',1,'']]], + ['right_20libraries_37',['Link with the right libraries',['../build_guide.html#build_link',1,'']]], + ['round_20trip_20to_20server_38',['X11 empty events no longer round-trip to server',['../news.html#x11_emptyevent_caveat',1,'']]], + ['run_20time_20version_39',['Run-time version',['../intro_guide.html#intro_version_runtime',1,'']]], + ['runtime_20platform_20selection_40',['runtime platform selection',['../intro_guide.html#platform',1,'Runtime platform selection'],['../news.html#runtime_platform_selection',1,'Runtime platform selection']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_19.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_19.js new file mode 100644 index 0000000..d831fe5 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_19.js @@ -0,0 +1,60 @@ +var searchData= +[ + ['safety_0',['Thread safety',['../intro_guide.html#thread_safety',1,'']]], + ['scale_1',['scale',['../monitor_guide.html#monitor_scale',1,'Content scale'],['../window_guide.html#window_scale',1,'Window content scale']]], + ['scaling_2',['Window hint for framebuffer scaling',['../news.html#scale_framebuffer_hint',1,'']]], + ['screen_20windows_3',['screen windows',['../window_guide.html#window_windowed_full_screen',1,'"Windowed full screen" windows'],['../window_guide.html#window_full_screen',1,'Full screen windows']]], + ['scroll_20input_4',['Scroll input',['../input_guide.html#scrolling',1,'']]], + ['scroll_20offsets_5',['Wheel position replaced by scroll offsets',['../moving_guide.html#moving_wheel',1,'']]], + ['selection_6',['selection',['../moving_guide.html#moving_monitor',1,'Explicit monitor selection'],['../news.html#runtime_platform_selection',1,'Runtime platform selection'],['../intro_guide.html#platform',1,'Runtime platform selection']]], + ['separation_20of_20window_20and_20framebuffer_20sizes_7',['Separation of window and framebuffer sizes',['../moving_guide.html#moving_hidpi',1,'']]], + ['server_8',['X11 empty events no longer round-trip to server',['../news.html#x11_emptyevent_caveat',1,'']]], + ['sets_20of_20native_20access_20functions_9',['Multiple sets of native access functions',['../news.html#multiplatform_caveat',1,'']]], + ['setting_10',['Cursor setting',['../input_guide.html#cursor_set',1,'']]], + ['setting_20an_20error_20callback_11',['Setting an error callback',['../quick_guide.html#quick_capture_error',1,'']]], + ['shapes_12',['shapes',['../news.html#more_cursor_shapes',1,'More standard cursor shapes'],['../group__shapes.html',1,'Standard cursor shapes']]], + ['shared_20cmake_20options_13',['Shared CMake options',['../compile_guide.html#compile_options_shared',1,'']]], + ['shared_20init_20hints_14',['Shared init hints',['../intro_guide.html#init_hints_shared',1,'']]], + ['sharing_15',['Context object sharing',['../context_guide.html#context_sharing',1,'']]], + ['show_20command_20hint_16',['Windows STARTUPINFO show command hint',['../news.html#win32_showdefault_hint',1,'']]], + ['size_17',['size',['../window_guide.html#window_fbsize',1,'Framebuffer size'],['../monitor_guide.html#monitor_size',1,'Physical size'],['../struct_g_l_f_wgammaramp.html#ad620e1cffbff9a32c51bca46301b59a5',1,'GLFWgammaramp::size'],['../window_guide.html#window_size',1,'Window size']]], + ['size_20limits_18',['Window size limits',['../window_guide.html#window_sizelimits',1,'']]], + ['sizes_19',['Separation of window and framebuffer sizes',['../moving_guide.html#moving_hidpi',1,'']]], + ['soft_20constraints_20',['Hard and soft constraints',['../window_guide.html#window_hints_hard',1,'']]], + ['source_21',['With CMake and GLFW source',['../build_guide.html#build_link_cmake_source',1,'']]], + ['specific_20cmake_20options_22',['specific cmake options',['../compile_guide.html#compile_options_macos',1,'macOS specific CMake options'],['../compile_guide.html#compile_options_unix',1,'Unix-like system specific CMake options'],['../compile_guide.html#compile_options_win32',1,'Win32 specific CMake options']]], + ['specific_20hints_23',['specific hints',['../window_guide.html#window_hints_osx',1,'macOS specific hints'],['../window_guide.html#window_hints_win32',1,'Win32 specific hints']]], + ['specific_20init_20hints_24',['specific init hints',['../intro_guide.html#init_hints_osx',1,'macOS specific init hints'],['../intro_guide.html#init_hints_wayland',1,'Wayland specific init hints'],['../intro_guide.html#init_hints_x11',1,'X11 specific init hints']]], + ['specific_20window_20hints_25',['specific window hints',['../window_guide.html#window_hints_wayland',1,'Wayland specific window hints'],['../window_guide.html#window_hints_x11',1,'X11 specific window hints']]], + ['standard_20cursor_20creation_26',['Standard cursor creation',['../input_guide.html#cursor_standard',1,'']]], + ['standard_20cursor_20shapes_27',['standard cursor shapes',['../news.html#more_cursor_shapes',1,'More standard cursor shapes'],['../group__shapes.html',1,'Standard cursor shapes']]], + ['standards_28',['standards',['../compat_guide.html#compat_wayland',1,'Wayland protocols and IPC standards'],['../compat_guide.html#compat_x11',1,'X11 extensions, protocols and IPC standards']]], + ['standards_20conformance_29',['Standards conformance',['../compat_guide.html',1,'']]], + ['started_30',['Getting started',['../quick_guide.html',1,'']]], + ['startupinfo_20show_20command_20hint_31',['Windows STARTUPINFO show command hint',['../news.html#win32_showdefault_hint',1,'']]], + ['states_32',['states',['../input_guide.html#joystick_axis',1,'Joystick axis states'],['../input_guide.html#joystick_button',1,'Joystick button states'],['../input_guide.html#joystick_hat',1,'Joystick hat states'],['../group__hat__state.html',1,'Joystick hat states']]], + ['static_20functions_33',['Static functions',['../internals_guide.html#internals_static',1,'']]], + ['step_34',['Step by step',['../quick_guide.html#quick_steps',1,'']]], + ['step_20by_20step_35',['Step by step',['../quick_guide.html#quick_steps',1,'']]], + ['string_36',['Version string',['../intro_guide.html#intro_version_string',1,'']]], + ['string_20format_20has_20been_20changed_37',['Version string format has been changed',['../news.html#version_string_caveat',1,'']]], + ['structure_38',['Internal structure',['../internals_guide.html',1,'']]], + ['subproject_39',['Tests and examples are disabled when built as a subproject',['../news.html#standalone_caveat',1,'']]], + ['support_40',['support',['../vulkan_guide.html#vulkan_present',1,'Querying for Vulkan presentation support'],['../vulkan_guide.html#vulkan_support',1,'Querying for Vulkan support'],['../moving_guide.html#moving_mbcs',1,'Win32 MBCS support']]], + ['support_20for_20custom_20heap_20memory_20allocator_41',['Support for custom heap memory allocator',['../news.html#custom_heap_allocator',1,'']]], + ['support_20for_20versions_20of_20windows_20older_20than_20xp_42',['Support for versions of Windows older than XP',['../moving_guide.html#moving_windows',1,'']]], + ['support_20has_20been_20removed_43',['wl_shell protocol support has been removed',['../news.html#wl_shell_removed',1,'']]], + ['support_20is_20deprecated_44',['support is deprecated',['../news.html#mingw_deprecated',1,'Original MinGW support is deprecated'],['../news.html#yosemite_deprecated',1,'OS X Yosemite support is deprecated'],['../news.html#winxp_deprecated',1,'Windows XP and Vista support is deprecated']]], + ['support_20is_20initialized_20on_20demand_45',['Joystick support is initialized on demand',['../news.html#joystick_init_caveat',1,'']]], + ['support_20reference_46',['Vulkan support reference',['../group__vulkan.html',1,'']]], + ['supported_20and_20default_20values_47',['supported and default values',['../window_guide.html#window_hints_values',1,'Supported and default values'],['../intro_guide.html#init_hints_values',1,'Supported and default values']]], + ['surface_48',['Creating a Vulkan window surface',['../vulkan_guide.html#vulkan_surface',1,'']]], + ['surface_20app_5fid_20hint_49',['Wayland surface app_id hint',['../news.html#wayland_app_id_hint',1,'']]], + ['surface_20hint_50',['X11 Vulkan window surface hint',['../news.html#x11_xcb_vulkan_surface',1,'']]], + ['swapping_51',['swapping',['../context_guide.html#context_swap',1,'Buffer swapping'],['../window_guide.html#buffer_swap',1,'Buffer swapping']]], + ['swapping_20buffers_52',['Swapping buffers',['../quick_guide.html#quick_swap_buffers',1,'']]], + ['symbols_53',['New symbols',['../news.html#new_symbols',1,'']]], + ['system_20specific_20cmake_20options_54',['Unix-like system specific CMake options',['../compile_guide.html#compile_options_unix',1,'']]], + ['system_20wide_20hotkeys_55',['Capture of system-wide hotkeys',['../moving_guide.html#moving_syskeys',1,'']]], + ['systems_56',['systems',['../intro_guide.html#coordinate_systems',1,'Coordinate systems'],['../news.html#wayland_alpha_caveat',1,'Wayland framebuffer may lack alpha channel on older systems']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1a.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1a.js new file mode 100644 index 0000000..5e93fb8 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1a.js @@ -0,0 +1,39 @@ +var searchData= +[ + ['tables_0',['Name change tables',['../moving_guide.html#moving_tables',1,'']]], + ['terminating_20glfw_1',['terminating glfw',['../quick_guide.html#quick_init_term',1,'Initializing and terminating GLFW'],['../intro_guide.html#intro_init_terminate',1,'Terminating GLFW']]], + ['termination_2',['termination',['../moving_guide.html#moving_terminate',1,'Automatic termination'],['../intro_guide.html#intro_init',1,'Initialization and termination']]], + ['tests_20and_20examples_20are_20disabled_20when_20built_20as_20a_20subproject_3',['Tests and examples are disabled when built as a subproject',['../news.html#standalone_caveat',1,'']]], + ['text_20input_4',['Text input',['../input_guide.html#input_char',1,'']]], + ['texture_20loading_5',['Removal of image and texture loading',['../moving_guide.html#moving_image',1,'']]], + ['than_20xp_6',['Support for versions of Windows older than XP',['../moving_guide.html#moving_windows',1,'']]], + ['the_20api_7',['Introduction to the API',['../intro_guide.html',1,'']]], + ['the_20cmake_20gui_8',['Generating with the CMake GUI',['../compile_guide.html#compile_generate_gui',1,'']]], + ['the_20glext_20h_20header_9',['The glext.h header',['../context_guide.html#context_glext_header',1,'']]], + ['the_20glfw_20header_10',['Including the GLFW header',['../quick_guide.html#quick_include',1,'']]], + ['the_20glfw_20header_20file_11',['Including the GLFW header file',['../build_guide.html#build_include',1,'']]], + ['the_20library_12',['Compiling the library',['../compile_guide.html#compile_compile',1,'']]], + ['the_20opengl_20context_20current_13',['Making the OpenGL context current',['../quick_guide.html#quick_context_current',1,'']]], + ['the_20right_20libraries_14',['Link with the right libraries',['../build_guide.html#build_link',1,'']]], + ['the_20timer_15',['Reading the timer',['../quick_guide.html#quick_timer',1,'']]], + ['the_20vulkan_20header_20file_16',['Including the Vulkan header file',['../vulkan_guide.html#vulkan_include',1,'']]], + ['the_20vulkan_20loader_17',['Finding the Vulkan loader',['../vulkan_guide.html#vulkan_loader',1,'']]], + ['the_20window_18',['Creating the window',['../vulkan_guide.html#vulkan_window',1,'']]], + ['the_20window_20close_20flag_19',['Checking the window close flag',['../quick_guide.html#quick_window_close',1,'']]], + ['thread_20safety_20',['Thread safety',['../intro_guide.html#thread_safety',1,'']]], + ['threading_20functions_21',['Removal of threading functions',['../moving_guide.html#moving_threads',1,'']]], + ['time_20input_22',['Time input',['../input_guide.html#time',1,'']]], + ['time_20version_23',['time version',['../intro_guide.html#intro_version_compile',1,'Compile-time version'],['../intro_guide.html#intro_version_runtime',1,'Run-time version']]], + ['timer_24',['Reading the timer',['../quick_guide.html#quick_timer',1,'']]], + ['title_25',['title',['../news.html#window_title_function',1,'Ability to get window title'],['../window_guide.html#window_title',1,'Window title']]], + ['to_203_26',['Moving from GLFW 2 to 3',['../moving_guide.html',1,'']]], + ['to_20get_20window_20title_27',['Ability to get window title',['../news.html#window_title_function',1,'']]], + ['to_20server_28',['X11 empty events no longer round-trip to server',['../news.html#x11_emptyevent_caveat',1,'']]], + ['to_20the_20api_29',['Introduction to the API',['../intro_guide.html',1,'']]], + ['together_30',['Putting it together',['../quick_guide.html#quick_example',1,'']]], + ['tokens_31',['tokens',['../group__keys.html',1,'Keyboard key tokens'],['../moving_guide.html#moving_renamed_tokens',1,'Renamed tokens']]], + ['transparency_32',['Window transparency',['../window_guide.html#window_transparency',1,'']]], + ['transparency_20requires_20dwm_20transparency_33',['Windows 7 framebuffer transparency requires DWM transparency',['../news.html#win7_framebuffer_caveat',1,'']]], + ['trip_20to_20server_34',['X11 empty events no longer round-trip to server',['../news.html#x11_emptyevent_caveat',1,'']]], + ['types_35',['types',['../news.html#new_types',1,'New types'],['../moving_guide.html#moving_renamed_types',1,'Renamed types']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1b.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1b.js new file mode 100644 index 0000000..046ff34 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1b.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['unix_0',['With pkg-config and GLFW binaries on Unix',['../build_guide.html#build_link_pkgconfig',1,'']]], + ['unix_20like_20system_20specific_20cmake_20options_1',['Unix-like system specific CMake options',['../compile_guide.html#compile_options_unix',1,'']]], + ['user_2',['user',['../struct_g_l_f_wallocator.html#af6153be74dbaf7f0a7e8bd3bfc039910',1,'GLFWallocator']]], + ['user_20pointer_3',['user pointer',['../input_guide.html#joystick_userptr',1,'Joystick user pointer'],['../monitor_guide.html#monitor_userptr',1,'User pointer'],['../window_guide.html#window_userptr',1,'User pointer']]], + ['using_20cmake_4',['Using CMake',['../compile_guide.html#compile_cmake',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1c.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1c.js new file mode 100644 index 0000000..8be2c0d --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1c.js @@ -0,0 +1,32 @@ +var searchData= +[ + ['values_0',['values',['../intro_guide.html#init_hints_values',1,'Supported and default values'],['../window_guide.html#window_hints_values',1,'Supported and default values']]], + ['version_1',['version',['../intro_guide.html#intro_version_compile',1,'Compile-time version'],['../intro_guide.html#intro_version_runtime',1,'Run-time version']]], + ['version_203_204_2',['Release notes for version 3.4',['../news.html',1,'']]], + ['version_20and_20error_20reference_3',['Initialization, version and error reference',['../group__init.html',1,'']]], + ['version_20compatibility_4',['Version compatibility',['../intro_guide.html#compatibility',1,'']]], + ['version_20management_5',['Version management',['../intro_guide.html#intro_version',1,'']]], + ['version_20string_6',['Version string',['../intro_guide.html#intro_version_string',1,'']]], + ['version_20string_20format_20has_20been_20changed_7',['Version string format has been changed',['../news.html#version_string_caveat',1,'']]], + ['versions_8',['Release notes for earlier versions',['../news.html#news_archive',1,'']]], + ['versions_20of_20windows_20older_20than_20xp_9',['Support for versions of Windows older than XP',['../moving_guide.html#moving_windows',1,'']]], + ['video_20mode_20enumeration_10',['Video mode enumeration',['../moving_guide.html#moving_video_modes',1,'']]], + ['video_20modes_11',['Video modes',['../monitor_guide.html#monitor_modes',1,'']]], + ['virtual_20position_12',['Virtual position',['../monitor_guide.html#monitor_pos',1,'']]], + ['visibility_13',['Window visibility',['../window_guide.html#window_hide',1,'']]], + ['vista_20support_20is_20deprecated_14',['Windows XP and Vista support is deprecated',['../news.html#winxp_deprecated',1,'']]], + ['visual_20c_20and_20glfw_20binaries_15',['With Visual C++ and GLFW binaries',['../build_guide.html#build_link_win32',1,'']]], + ['vulkan_20extensions_16',['Querying required Vulkan extensions',['../vulkan_guide.html#vulkan_ext',1,'']]], + ['vulkan_20function_20pointers_17',['Querying Vulkan function pointers',['../vulkan_guide.html#vulkan_proc',1,'']]], + ['vulkan_20guide_18',['Vulkan guide',['../vulkan_guide.html',1,'']]], + ['vulkan_20header_20file_19',['Including the Vulkan header file',['../vulkan_guide.html#vulkan_include',1,'']]], + ['vulkan_20loader_20',['Finding the Vulkan loader',['../vulkan_guide.html#vulkan_loader',1,'']]], + ['vulkan_20loader_20and_20api_21',['Vulkan loader and API',['../compat_guide.html#compat_vulkan',1,'']]], + ['vulkan_20presentation_20support_22',['Querying for Vulkan presentation support',['../vulkan_guide.html#vulkan_present',1,'']]], + ['vulkan_20support_23',['Querying for Vulkan support',['../vulkan_guide.html#vulkan_support',1,'']]], + ['vulkan_20support_20reference_24',['Vulkan support reference',['../group__vulkan.html',1,'']]], + ['vulkan_20window_20surface_25',['Creating a Vulkan window surface',['../vulkan_guide.html#vulkan_surface',1,'']]], + ['vulkan_20window_20surface_20hint_26',['X11 Vulkan window surface hint',['../news.html#x11_xcb_vulkan_surface',1,'']]], + ['vulkan_20wsi_20extensions_27',['Vulkan WSI extensions',['../compat_guide.html#compat_wsi',1,'']]], + ['vulkan_2emd_28',['vulkan.md',['../vulkan_8md.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1d.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1d.js new file mode 100644 index 0000000..8a43794 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1d.js @@ -0,0 +1,84 @@ +var searchData= +[ + ['w64_20and_20glfw_20binaries_0',['With MinGW-w64 and GLFW binaries',['../build_guide.html#build_link_mingw',1,'']]], + ['wayland_20and_20x11_1',['Dependencies for Wayland and X11',['../compile_guide.html#compile_deps_wayland',1,'']]], + ['wayland_20framebuffer_20may_20lack_20alpha_20channel_20on_20older_20systems_2',['Wayland framebuffer may lack alpha channel on older systems',['../news.html#wayland_alpha_caveat',1,'']]], + ['wayland_20libdecor_20decorations_3',['Wayland libdecor decorations',['../news.html#wayland_libdecor_decorations',1,'']]], + ['wayland_20protocols_20and_20ipc_20standards_4',['Wayland protocols and IPC standards',['../compat_guide.html#compat_wayland',1,'']]], + ['wayland_20specific_20init_20hints_5',['Wayland specific init hints',['../intro_guide.html#init_hints_wayland',1,'']]], + ['wayland_20specific_20window_20hints_6',['Wayland specific window hints',['../window_guide.html#window_hints_wayland',1,'']]], + ['wayland_20surface_20app_5fid_20hint_7',['Wayland surface app_id hint',['../news.html#wayland_app_id_hint',1,'']]], + ['wgl_20extensions_8',['WGL extensions',['../compat_guide.html#compat_wgl',1,'']]], + ['wheel_20position_20replaced_20by_20scroll_20offsets_9',['Wheel position replaced by scroll offsets',['../moving_guide.html#moving_wheel',1,'']]], + ['when_20built_20as_20a_20subproject_10',['Tests and examples are disabled when built as a subproject',['../news.html#standalone_caveat',1,'']]], + ['wide_20hotkeys_11',['Capture of system-wide hotkeys',['../moving_guide.html#moving_syskeys',1,'']]], + ['width_12',['width',['../struct_g_l_f_wvidmode.html#a698dcb200562051a7249cb6ae154c71d',1,'GLFWvidmode::width'],['../struct_g_l_f_wimage.html#af6a71cc999fe6d3aea31dd7e9687d835',1,'GLFWimage::width']]], + ['win32_20mbcs_20support_13',['Win32 MBCS support',['../moving_guide.html#moving_mbcs',1,'']]], + ['win32_20specific_20cmake_20options_14',['Win32 specific CMake options',['../compile_guide.html#compile_options_win32',1,'']]], + ['win32_20specific_20hints_15',['Win32 specific hints',['../window_guide.html#window_hints_win32',1,'']]], + ['window_16',['Creating the window',['../vulkan_guide.html#vulkan_window',1,'']]], + ['window_20and_20context_17',['Creating a window and context',['../quick_guide.html#quick_create_window',1,'']]], + ['window_20and_20framebuffer_20sizes_18',['Separation of window and framebuffer sizes',['../moving_guide.html#moving_hidpi',1,'']]], + ['window_20attention_20request_19',['Window attention request',['../window_guide.html#window_attention',1,'']]], + ['window_20attributes_20',['Window attributes',['../window_guide.html#window_attribs',1,'']]], + ['window_20close_20flag_21',['Checking the window close flag',['../quick_guide.html#quick_window_close',1,'']]], + ['window_20closing_20and_20close_20flag_22',['Window closing and close flag',['../window_guide.html#window_close',1,'']]], + ['window_20closing_20changes_23',['Window closing changes',['../moving_guide.html#moving_window_close',1,'']]], + ['window_20content_20scale_24',['Window content scale',['../window_guide.html#window_scale',1,'']]], + ['window_20creation_25',['Window creation',['../window_guide.html#window_creation',1,'']]], + ['window_20creation_20hints_26',['Window creation hints',['../window_guide.html#window_hints',1,'']]], + ['window_20damage_20and_20refresh_27',['Window damage and refresh',['../window_guide.html#window_refresh',1,'']]], + ['window_20destruction_28',['Window destruction',['../window_guide.html#window_destruction',1,'']]], + ['window_20event_20processing_29',['Window event processing',['../window_guide.html#window_events',1,'']]], + ['window_20guide_30',['Window guide',['../window_guide.html',1,'']]], + ['window_20handle_20parameters_31',['Window handle parameters',['../moving_guide.html#moving_window_handles',1,'']]], + ['window_20hint_20for_20framebuffer_20scaling_32',['Window hint for framebuffer scaling',['../news.html#scale_framebuffer_hint',1,'']]], + ['window_20hints_33',['window hints',['../moving_guide.html#moving_hints',1,'Persistent window hints'],['../window_guide.html#window_hints_wayland',1,'Wayland specific window hints'],['../window_guide.html#window_hints_x11',1,'X11 specific window hints']]], + ['window_20hints_20for_20initial_20window_20position_34',['Window hints for initial window position',['../news.html#window_position_hint',1,'']]], + ['window_20icon_35',['Window icon',['../window_guide.html#window_icon',1,'']]], + ['window_20iconification_36',['Window iconification',['../window_guide.html#window_iconify',1,'']]], + ['window_20input_20focus_37',['Window input focus',['../window_guide.html#window_focus',1,'']]], + ['window_20maximization_38',['Window maximization',['../window_guide.html#window_maximize',1,'']]], + ['window_20menu_20keyboard_20access_20hint_39',['Windows window menu keyboard access hint',['../news.html#win32_keymenu_hint',1,'']]], + ['window_20monitor_40',['Window monitor',['../window_guide.html#window_monitor',1,'']]], + ['window_20objects_41',['Window objects',['../window_guide.html#window_object',1,'']]], + ['window_20position_42',['window position',['../news.html#window_position_hint',1,'Window hints for initial window position'],['../window_guide.html#window_pos',1,'Window position']]], + ['window_20properties_20and_20events_43',['Window properties and events',['../window_guide.html#window_properties',1,'']]], + ['window_20reference_44',['Window reference',['../group__window.html',1,'']]], + ['window_20related_20attributes_45',['Window related attributes',['../window_guide.html#window_attribs_wnd',1,'']]], + ['window_20related_20hints_46',['Window related hints',['../window_guide.html#window_hints_wnd',1,'']]], + ['window_20size_47',['Window size',['../window_guide.html#window_size',1,'']]], + ['window_20size_20limits_48',['Window size limits',['../window_guide.html#window_sizelimits',1,'']]], + ['window_20surface_49',['Creating a Vulkan window surface',['../vulkan_guide.html#vulkan_surface',1,'']]], + ['window_20surface_20hint_50',['X11 Vulkan window surface hint',['../news.html#x11_xcb_vulkan_surface',1,'']]], + ['window_20title_51',['window title',['../news.html#window_title_function',1,'Ability to get window title'],['../window_guide.html#window_title',1,'Window title']]], + ['window_20transparency_52',['Window transparency',['../window_guide.html#window_transparency',1,'']]], + ['window_20visibility_53',['Window visibility',['../window_guide.html#window_hide',1,'']]], + ['window_2emd_54',['window.md',['../window_8md.html',1,'']]], + ['windowed_20full_20screen_20windows_55',['"Windowed full screen" windows',['../window_guide.html#window_windowed_full_screen',1,'']]], + ['windows_56',['windows',['../window_guide.html#window_windowed_full_screen',1,'"Windowed full screen" windows'],['../window_guide.html#window_full_screen',1,'Full screen windows']]], + ['windows_207_20framebuffer_20transparency_20requires_20dwm_20transparency_57',['Windows 7 framebuffer transparency requires DWM transparency',['../news.html#win7_framebuffer_caveat',1,'']]], + ['windows_20older_20than_20xp_58',['Support for versions of Windows older than XP',['../moving_guide.html#moving_windows',1,'']]], + ['windows_20startupinfo_20show_20command_20hint_59',['Windows STARTUPINFO show command hint',['../news.html#win32_showdefault_hint',1,'']]], + ['windows_20window_20menu_20keyboard_20access_20hint_60',['Windows window menu keyboard access hint',['../news.html#win32_keymenu_hint',1,'']]], + ['windows_20without_20contexts_61',['Windows without contexts',['../context_guide.html#context_less',1,'']]], + ['windows_20xp_20and_20vista_20support_20is_20deprecated_62',['Windows XP and Vista support is deprecated',['../news.html#winxp_deprecated',1,'']]], + ['with_20a_20loader_20library_63',['Loading extension with a loader library',['../context_guide.html#context_glext_auto',1,'']]], + ['with_20cmake_64',['Generating build files with CMake',['../compile_guide.html#compile_generate',1,'']]], + ['with_20cmake_20and_20glfw_20source_65',['With CMake and GLFW source',['../build_guide.html#build_link_cmake_source',1,'']]], + ['with_20cmake_20and_20installed_20glfw_20binaries_66',['With CMake and installed GLFW binaries',['../build_guide.html#build_link_cmake_package',1,'']]], + ['with_20cmake_20and_20mingw_67',['Cross-compilation with CMake and MinGW',['../compile_guide.html#compile_mingw_cross',1,'']]], + ['with_20command_20line_20cmake_68',['Generating with command-line CMake',['../compile_guide.html#compile_generate_cli',1,'']]], + ['with_20command_20line_20or_20makefile_20on_20macos_69',['With command-line or makefile on macOS',['../build_guide.html#build_link_osx',1,'']]], + ['with_20mingw_20w64_20and_20glfw_20binaries_70',['With MinGW-w64 and GLFW binaries',['../build_guide.html#build_link_mingw',1,'']]], + ['with_20opengl_71',['Rendering with OpenGL',['../quick_guide.html#quick_render',1,'']]], + ['with_20pkg_20config_20and_20glfw_20binaries_20on_20unix_72',['With pkg-config and GLFW binaries on Unix',['../build_guide.html#build_link_pkgconfig',1,'']]], + ['with_20the_20cmake_20gui_73',['Generating with the CMake GUI',['../compile_guide.html#compile_generate_gui',1,'']]], + ['with_20the_20right_20libraries_74',['Link with the right libraries',['../build_guide.html#build_link',1,'']]], + ['with_20visual_20c_20and_20glfw_20binaries_75',['With Visual C++ and GLFW binaries',['../build_guide.html#build_link_win32',1,'']]], + ['with_20xcode_20on_20macos_76',['With Xcode on macOS',['../build_guide.html#build_link_xcode',1,'']]], + ['without_20contexts_77',['Windows without contexts',['../context_guide.html#context_less',1,'']]], + ['wl_5fshell_20protocol_20support_20has_20been_20removed_78',['wl_shell protocol support has been removed',['../news.html#wl_shell_removed',1,'']]], + ['work_20area_79',['Work area',['../monitor_guide.html#monitor_workarea',1,'']]], + ['wsi_20extensions_80',['Vulkan WSI extensions',['../compat_guide.html#compat_wsi',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1e.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1e.js new file mode 100644 index 0000000..db4d296 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1e.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['x_20yosemite_20support_20is_20deprecated_0',['OS X Yosemite support is deprecated',['../news.html#yosemite_deprecated',1,'']]], + ['x11_1',['Dependencies for Wayland and X11',['../compile_guide.html#compile_deps_wayland',1,'']]], + ['x11_20empty_20events_20no_20longer_20round_20trip_20to_20server_2',['X11 empty events no longer round-trip to server',['../news.html#x11_emptyevent_caveat',1,'']]], + ['x11_20extensions_20protocols_20and_20ipc_20standards_3',['X11 extensions, protocols and IPC standards',['../compat_guide.html#compat_x11',1,'']]], + ['x11_20specific_20init_20hints_4',['X11 specific init hints',['../intro_guide.html#init_hints_x11',1,'']]], + ['x11_20specific_20window_20hints_5',['X11 specific window hints',['../window_guide.html#window_hints_x11',1,'']]], + ['x11_20vulkan_20window_20surface_20hint_6',['X11 Vulkan window surface hint',['../news.html#x11_xcb_vulkan_surface',1,'']]], + ['xcode_20on_20macos_7',['With Xcode on macOS',['../build_guide.html#build_link_xcode',1,'']]], + ['xp_8',['Support for versions of Windows older than XP',['../moving_guide.html#moving_windows',1,'']]], + ['xp_20and_20vista_20support_20is_20deprecated_9',['Windows XP and Vista support is deprecated',['../news.html#winxp_deprecated',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1f.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1f.js new file mode 100644 index 0000000..4becbd5 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_1f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['yosemite_20support_20is_20deprecated_0',['OS X Yosemite support is deprecated',['../news.html#yosemite_deprecated',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_2.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_2.js new file mode 100644 index 0000000..162a517 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['3_0',['Moving from GLFW 2 to 3',['../moving_guide.html',1,'']]], + ['3_204_1',['Release notes for version 3.4',['../news.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_3.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_3.js new file mode 100644 index 0000000..090f8b6 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['4_0',['Release notes for version 3.4',['../news.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_4.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_4.js new file mode 100644 index 0000000..0d97849 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['7_20framebuffer_20transparency_20requires_20dwm_20transparency_0',['Windows 7 framebuffer transparency requires DWM transparency',['../news.html#win7_framebuffer_caveat',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_5.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_5.js new file mode 100644 index 0000000..14b2014 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['8_20or_20later_0',['Documentation generation requires Doxygen 1.9.8 or later',['../news.html#docs_target_caveat',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_6.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_6.js new file mode 100644 index 0000000..87cea99 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['9_208_20or_20later_0',['Documentation generation requires Doxygen 1.9.8 or later',['../news.html#docs_target_caveat',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_7.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_7.js new file mode 100644 index 0000000..4e1427c --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_7.js @@ -0,0 +1,58 @@ +var searchData= +[ + ['a_20loader_20library_0',['Loading extension with a loader library',['../context_guide.html#context_glext_auto',1,'']]], + ['a_20subproject_1',['Tests and examples are disabled when built as a subproject',['../news.html#standalone_caveat',1,'']]], + ['a_20vulkan_20window_20surface_2',['Creating a Vulkan window surface',['../vulkan_guide.html#vulkan_surface',1,'']]], + ['a_20window_20and_20context_3',['Creating a window and context',['../quick_guide.html#quick_create_window',1,'']]], + ['ability_20to_20get_20window_20title_4',['Ability to get window title',['../news.html#window_title_function',1,'']]], + ['access_5',['Native access',['../group__native.html',1,'']]], + ['access_20function_6',['Cocoa NSView native access function',['../news.html#cocoa_nsview_function',1,'']]], + ['access_20functions_7',['Multiple sets of native access functions',['../news.html#multiplatform_caveat',1,'']]], + ['access_20hint_8',['Windows window menu keyboard access hint',['../news.html#win32_keymenu_hint',1,'']]], + ['action_9',['Key repeat action',['../moving_guide.html#moving_repeat',1,'']]], + ['actions_10',['Removal of character actions',['../moving_guide.html#moving_char_up',1,'']]], + ['allocate_11',['allocate',['../struct_g_l_f_wallocator.html#a18a798136f17a9cb105be18312193bf7',1,'GLFWallocator']]], + ['allocator_12',['allocator',['../intro_guide.html#init_allocator',1,'Custom heap memory allocator'],['../news.html#custom_heap_allocator',1,'Support for custom heap memory allocator']]], + ['alpha_20channel_20on_20older_20systems_13',['Wayland framebuffer may lack alpha channel on older systems',['../news.html#wayland_alpha_caveat',1,'']]], + ['an_20error_20callback_14',['Setting an error callback',['../quick_guide.html#quick_capture_error',1,'']]], + ['and_20api_15',['Vulkan loader and API',['../compat_guide.html#compat_vulkan',1,'']]], + ['and_20close_20flag_16',['Window closing and close flag',['../window_guide.html#window_close',1,'']]], + ['and_20context_17',['Creating a window and context',['../quick_guide.html#quick_create_window',1,'']]], + ['and_20default_20values_18',['and default values',['../window_guide.html#window_hints_values',1,'Supported and default values'],['../intro_guide.html#init_hints_values',1,'Supported and default values']]], + ['and_20error_20reference_19',['Initialization, version and error reference',['../group__init.html',1,'']]], + ['and_20events_20',['Window properties and events',['../window_guide.html#window_properties',1,'']]], + ['and_20examples_20are_20disabled_20when_20built_20as_20a_20subproject_21',['Tests and examples are disabled when built as a subproject',['../news.html#standalone_caveat',1,'']]], + ['and_20framebuffer_20sizes_22',['Separation of window and framebuffer sizes',['../moving_guide.html#moving_hidpi',1,'']]], + ['and_20glfw_20binaries_23',['and glfw binaries',['../build_guide.html#build_link_mingw',1,'With MinGW-w64 and GLFW binaries'],['../build_guide.html#build_link_win32',1,'With Visual C++ and GLFW binaries']]], + ['and_20glfw_20binaries_20on_20unix_24',['With pkg-config and GLFW binaries on Unix',['../build_guide.html#build_link_pkgconfig',1,'']]], + ['and_20glfw_20source_25',['With CMake and GLFW source',['../build_guide.html#build_link_cmake_source',1,'']]], + ['and_20header_20file_26',['Renamed library and header file',['../moving_guide.html#moving_renamed_files',1,'']]], + ['and_20installed_20glfw_20binaries_27',['With CMake and installed GLFW binaries',['../build_guide.html#build_link_cmake_package',1,'']]], + ['and_20ipc_20standards_28',['and ipc standards',['../compat_guide.html#compat_wayland',1,'Wayland protocols and IPC standards'],['../compat_guide.html#compat_x11',1,'X11 extensions, protocols and IPC standards']]], + ['and_20limitations_29',['Guarantees and limitations',['../intro_guide.html#guarantees_limitations',1,'']]], + ['and_20mingw_30',['Cross-compilation with CMake and MinGW',['../compile_guide.html#compile_mingw_cross',1,'']]], + ['and_20opengl_20es_20extensions_31',['OpenGL and OpenGL ES extensions',['../context_guide.html#context_glext',1,'']]], + ['and_20output_32',['Clipboard input and output',['../input_guide.html#clipboard',1,'']]], + ['and_20refresh_33',['Window damage and refresh',['../window_guide.html#window_refresh',1,'']]], + ['and_20removed_20features_34',['Changed and removed features',['../moving_guide.html#moving_removed',1,'']]], + ['and_20soft_20constraints_35',['Hard and soft constraints',['../window_guide.html#window_hints_hard',1,'']]], + ['and_20terminating_20glfw_36',['Initializing and terminating GLFW',['../quick_guide.html#quick_init_term',1,'']]], + ['and_20termination_37',['Initialization and termination',['../intro_guide.html#intro_init',1,'']]], + ['and_20texture_20loading_38',['Removal of image and texture loading',['../moving_guide.html#moving_image',1,'']]], + ['and_20vista_20support_20is_20deprecated_39',['Windows XP and Vista support is deprecated',['../news.html#winxp_deprecated',1,'']]], + ['and_20x11_40',['Dependencies for Wayland and X11',['../compile_guide.html#compile_deps_wayland',1,'']]], + ['angle_20rendering_20backend_20hint_41',['ANGLE rendering backend hint',['../news.html#angle_renderer_hint',1,'']]], + ['api_42',['api',['../intro_guide.html',1,'Introduction to the API'],['../compat_guide.html#compat_vulkan',1,'Vulkan loader and API']]], + ['app_5fid_20hint_43',['Wayland surface app_id hint',['../news.html#wayland_app_id_hint',1,'']]], + ['applications_44',['Building applications',['../build_guide.html',1,'']]], + ['are_20disabled_20when_20built_20as_20a_20subproject_45',['Tests and examples are disabled when built as a subproject',['../news.html#standalone_caveat',1,'']]], + ['area_46',['Work area',['../monitor_guide.html#monitor_workarea',1,'']]], + ['as_20a_20subproject_47',['Tests and examples are disabled when built as a subproject',['../news.html#standalone_caveat',1,'']]], + ['at_20initialization_48',['macOS main menu now created at initialization',['../news.html#macos_menu_caveat',1,'']]], + ['attention_20request_49',['Window attention request',['../window_guide.html#window_attention',1,'']]], + ['attributes_50',['attributes',['../window_guide.html#window_attribs_ctx',1,'Context related attributes'],['../window_guide.html#window_attribs_fb',1,'Framebuffer related attributes'],['../window_guide.html#window_attribs',1,'Window attributes'],['../window_guide.html#window_attribs_wnd',1,'Window related attributes']]], + ['automatic_20event_20polling_51',['Removal of automatic event polling',['../moving_guide.html#moving_autopoll',1,'']]], + ['automatic_20termination_52',['Automatic termination',['../moving_guide.html#moving_terminate',1,'']]], + ['axes_53',['axes',['../struct_g_l_f_wgamepadstate.html#a8b2c8939b1d31458de5359998375c189',1,'GLFWgamepadstate::axes'],['../group__gamepad__axes.html',1,'Gamepad axes']]], + ['axis_20states_54',['Joystick axis states',['../input_guide.html#joystick_axis',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_8.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_8.js new file mode 100644 index 0000000..3065a50 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_8.js @@ -0,0 +1,21 @@ +var searchData= +[ + ['backend_20hint_0',['ANGLE rendering backend hint',['../news.html#angle_renderer_hint',1,'']]], + ['been_20changed_1',['Version string format has been changed',['../news.html#version_string_caveat',1,'']]], + ['been_20removed_2',['been removed',['../news.html#use_osmesa_removed',1,'GLFW_USE_OSMESA CMake option has been removed'],['../news.html#use_wayland_removed',1,'GLFW_USE_WAYLAND CMake option has been removed'],['../news.html#vulkan_static_removed',1,'GLFW_VULKAN_STATIC CMake option has been removed'],['../news.html#corevideo_caveat',1,'macOS CoreVideo dependency has been removed'],['../news.html#wl_shell_removed',1,'wl_shell protocol support has been removed']]], + ['binaries_3',['binaries',['../build_guide.html#build_link_cmake_package',1,'With CMake and installed GLFW binaries'],['../build_guide.html#build_link_mingw',1,'With MinGW-w64 and GLFW binaries'],['../build_guide.html#build_link_win32',1,'With Visual C++ and GLFW binaries']]], + ['binaries_20on_20unix_4',['With pkg-config and GLFW binaries on Unix',['../build_guide.html#build_link_pkgconfig',1,'']]], + ['blue_5',['blue',['../struct_g_l_f_wgammaramp.html#acf0c836d0efe29c392fe8d1a1042744b',1,'GLFWgammaramp']]], + ['bluebits_6',['blueBits',['../struct_g_l_f_wvidmode.html#af310977f58d2e3b188175b6e3d314047',1,'GLFWvidmode']]], + ['buffer_20swapping_7',['buffer swapping',['../context_guide.html#context_swap',1,'Buffer swapping'],['../window_guide.html#buffer_swap',1,'Buffer swapping']]], + ['buffers_8',['Swapping buffers',['../quick_guide.html#quick_swap_buffers',1,'']]], + ['build_20files_20with_20cmake_9',['Generating build files with CMake',['../compile_guide.html#compile_generate',1,'']]], + ['build_2emd_10',['build.md',['../build_8md.html',1,'']]], + ['building_20applications_11',['Building applications',['../build_guide.html',1,'']]], + ['built_20as_20a_20subproject_12',['Tests and examples are disabled when built as a subproject',['../news.html#standalone_caveat',1,'']]], + ['button_20input_13',['Mouse button input',['../input_guide.html#input_mouse_button',1,'']]], + ['button_20states_14',['Joystick button states',['../input_guide.html#joystick_button',1,'']]], + ['buttons_15',['buttons',['../struct_g_l_f_wgamepadstate.html#a27e9896b51c65df15fba2c7139bfdb9a',1,'GLFWgamepadstate::buttons'],['../group__gamepad__buttons.html',1,'Gamepad buttons'],['../group__buttons.html',1,'Mouse buttons']]], + ['by_20scroll_20offsets_16',['Wheel position replaced by scroll offsets',['../moving_guide.html#moving_wheel',1,'']]], + ['by_20step_17',['Step by step',['../quick_guide.html#quick_steps',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_9.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_9.js new file mode 100644 index 0000000..c3b5244 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_9.js @@ -0,0 +1,82 @@ +var searchData= +[ + ['c_20and_20glfw_20binaries_0',['With Visual C++ and GLFW binaries',['../build_guide.html#build_link_win32',1,'']]], + ['callback_1',['Setting an error callback',['../quick_guide.html#quick_capture_error',1,'']]], + ['capture_20of_20system_20wide_20hotkeys_2',['Capture of system-wide hotkeys',['../moving_guide.html#moving_syskeys',1,'']]], + ['captured_20cursor_20mode_3',['Captured cursor mode',['../news.html#captured_cursor_mode',1,'']]], + ['caveats_4',['Caveats',['../news.html#caveats',1,'']]], + ['change_20tables_5',['Name change tables',['../moving_guide.html#moving_tables',1,'']]], + ['changed_6',['Version string format has been changed',['../news.html#version_string_caveat',1,'']]], + ['changed_20and_20removed_20features_7',['Changed and removed features',['../moving_guide.html#moving_removed',1,'']]], + ['changes_8',['changes',['../moving_guide.html#moving_cursorpos',1,'Cursor position changes'],['../input_guide.html#joystick_event',1,'Joystick configuration changes'],['../moving_guide.html#moving_joystick',1,'Joystick function changes'],['../monitor_guide.html#monitor_event',1,'Monitor configuration changes'],['../moving_guide.html#moving_window_close',1,'Window closing changes']]], + ['channel_20on_20older_20systems_9',['Wayland framebuffer may lack alpha channel on older systems',['../news.html#wayland_alpha_caveat',1,'']]], + ['character_20actions_10',['Removal of character actions',['../moving_guide.html#moving_char_up',1,'']]], + ['checking_20for_20extensions_11',['Checking for extensions',['../context_guide.html#context_glext_string',1,'']]], + ['checking_20the_20window_20close_20flag_12',['Checking the window close flag',['../quick_guide.html#quick_window_close',1,'']]], + ['clipboard_20input_20and_20output_13',['Clipboard input and output',['../input_guide.html#clipboard',1,'']]], + ['close_20flag_14',['close flag',['../quick_guide.html#quick_window_close',1,'Checking the window close flag'],['../window_guide.html#window_close',1,'Window closing and close flag']]], + ['closing_20and_20close_20flag_15',['Window closing and close flag',['../window_guide.html#window_close',1,'']]], + ['closing_20changes_16',['Window closing changes',['../moving_guide.html#moving_window_close',1,'']]], + ['cmake_17',['cmake',['../compile_guide.html#compile_generate',1,'Generating build files with CMake'],['../compile_guide.html#compile_generate_cli',1,'Generating with command-line CMake'],['../compile_guide.html#compile_cmake',1,'Using CMake']]], + ['cmake_20and_20glfw_20source_18',['With CMake and GLFW source',['../build_guide.html#build_link_cmake_source',1,'']]], + ['cmake_20and_20installed_20glfw_20binaries_19',['With CMake and installed GLFW binaries',['../build_guide.html#build_link_cmake_package',1,'']]], + ['cmake_20and_20mingw_20',['Cross-compilation with CMake and MinGW',['../compile_guide.html#compile_mingw_cross',1,'']]], + ['cmake_20gui_21',['Generating with the CMake GUI',['../compile_guide.html#compile_generate_gui',1,'']]], + ['cmake_20option_20has_20been_20removed_22',['cmake option has been removed',['../news.html#use_osmesa_removed',1,'GLFW_USE_OSMESA CMake option has been removed'],['../news.html#use_wayland_removed',1,'GLFW_USE_WAYLAND CMake option has been removed'],['../news.html#vulkan_static_removed',1,'GLFW_VULKAN_STATIC CMake option has been removed']]], + ['cmake_20options_23',['cmake options',['../compile_guide.html#compile_options',1,'CMake options'],['../compile_guide.html#compile_options_macos',1,'macOS specific CMake options'],['../compile_guide.html#compile_options_shared',1,'Shared CMake options'],['../compile_guide.html#compile_options_unix',1,'Unix-like system specific CMake options'],['../compile_guide.html#compile_options_win32',1,'Win32 specific CMake options']]], + ['cocoa_20nsview_20native_20access_20function_24',['Cocoa NSView native access function',['../news.html#cocoa_nsview_function',1,'']]], + ['codes_25',['Error codes',['../group__errors.html',1,'']]], + ['command_20hint_26',['Windows STARTUPINFO show command hint',['../news.html#win32_showdefault_hint',1,'']]], + ['command_20line_20cmake_27',['Generating with command-line CMake',['../compile_guide.html#compile_generate_cli',1,'']]], + ['command_20line_20or_20makefile_20on_20macos_28',['With command-line or makefile on macOS',['../build_guide.html#build_link_osx',1,'']]], + ['compat_2emd_29',['compat.md',['../compat_8md.html',1,'']]], + ['compatibility_30',['Version compatibility',['../intro_guide.html#compatibility',1,'']]], + ['compilation_20with_20cmake_20and_20mingw_31',['Cross-compilation with CMake and MinGW',['../compile_guide.html#compile_mingw_cross',1,'']]], + ['compile_20time_20version_32',['Compile-time version',['../intro_guide.html#intro_version_compile',1,'']]], + ['compile_2emd_33',['compile.md',['../compile_8md.html',1,'']]], + ['compiling_20glfw_34',['Compiling GLFW',['../compile_guide.html',1,'']]], + ['compiling_20glfw_20manually_35',['Compiling GLFW manually',['../compile_guide.html#compile_manual',1,'']]], + ['compiling_20the_20library_36',['Compiling the library',['../compile_guide.html#compile_compile',1,'']]], + ['config_20and_20glfw_20binaries_20on_20unix_37',['With pkg-config and GLFW binaries on Unix',['../build_guide.html#build_link_pkgconfig',1,'']]], + ['configuration_20changes_38',['configuration changes',['../input_guide.html#joystick_event',1,'Joystick configuration changes'],['../monitor_guide.html#monitor_event',1,'Monitor configuration changes']]], + ['configuration_20header_20is_20no_20longer_20generated_39',['Configuration header is no longer generated',['../news.html#config_header_caveat',1,'']]], + ['configuration_20macros_40',['Configuration macros',['../internals_guide.html#internals_config',1,'']]], + ['conformance_41',['Standards conformance',['../compat_guide.html',1,'']]], + ['constants_42',['New constants',['../news.html#new_constants',1,'']]], + ['constraints_43',['Hard and soft constraints',['../window_guide.html#window_hints_hard',1,'']]], + ['content_20scale_44',['content scale',['../monitor_guide.html#monitor_scale',1,'Content scale'],['../window_guide.html#window_scale',1,'Window content scale']]], + ['context_45',['context',['../quick_guide.html#quick_create_window',1,'Creating a window and context'],['../context_guide.html#context_current',1,'Current context']]], + ['context_20creation_20hints_46',['Context creation hints',['../context_guide.html#context_hints',1,'']]], + ['context_20current_47',['Making the OpenGL context current',['../quick_guide.html#quick_context_current',1,'']]], + ['context_20guide_48',['Context guide',['../context_guide.html',1,'']]], + ['context_20management_49',['Explicit context management',['../moving_guide.html#moving_context',1,'']]], + ['context_20object_20sharing_50',['Context object sharing',['../context_guide.html#context_sharing',1,'']]], + ['context_20objects_51',['Context objects',['../context_guide.html#context_object',1,'']]], + ['context_20reference_52',['Context reference',['../group__context.html',1,'']]], + ['context_20related_20attributes_53',['Context related attributes',['../window_guide.html#window_attribs_ctx',1,'']]], + ['context_20related_20hints_54',['Context related hints',['../window_guide.html#window_hints_ctx',1,'']]], + ['context_2emd_55',['context.md',['../context_8md.html',1,'']]], + ['contexts_56',['contexts',['../context_guide.html#context_offscreen',1,'Offscreen contexts'],['../context_guide.html#context_less',1,'Windows without contexts']]], + ['coordinate_20systems_57',['Coordinate systems',['../intro_guide.html#coordinate_systems',1,'']]], + ['corevideo_20dependency_20has_20been_20removed_58',['macOS CoreVideo dependency has been removed',['../news.html#corevideo_caveat',1,'']]], + ['created_20at_20initialization_59',['macOS main menu now created at initialization',['../news.html#macos_menu_caveat',1,'']]], + ['creating_20a_20vulkan_20window_20surface_60',['Creating a Vulkan window surface',['../vulkan_guide.html#vulkan_surface',1,'']]], + ['creating_20a_20window_20and_20context_61',['Creating a window and context',['../quick_guide.html#quick_create_window',1,'']]], + ['creating_20the_20window_62',['Creating the window',['../vulkan_guide.html#vulkan_window',1,'']]], + ['creation_63',['creation',['../input_guide.html#cursor_custom',1,'Custom cursor creation'],['../input_guide.html#cursor_standard',1,'Standard cursor creation'],['../window_guide.html#window_creation',1,'Window creation']]], + ['creation_20hints_64',['creation hints',['../context_guide.html#context_hints',1,'Context creation hints'],['../window_guide.html#window_hints',1,'Window creation hints']]], + ['cross_20compilation_20with_20cmake_20and_20mingw_65',['Cross-compilation with CMake and MinGW',['../compile_guide.html#compile_mingw_cross',1,'']]], + ['current_66',['Making the OpenGL context current',['../quick_guide.html#quick_context_current',1,'']]], + ['current_20context_67',['Current context',['../context_guide.html#context_current',1,'']]], + ['cursor_20creation_68',['cursor creation',['../input_guide.html#cursor_custom',1,'Custom cursor creation'],['../input_guide.html#cursor_standard',1,'Standard cursor creation']]], + ['cursor_20destruction_69',['Cursor destruction',['../input_guide.html#cursor_destruction',1,'']]], + ['cursor_20enter_20leave_20events_70',['Cursor enter/leave events',['../input_guide.html#cursor_enter',1,'']]], + ['cursor_20mode_71',['cursor mode',['../news.html#captured_cursor_mode',1,'Captured cursor mode'],['../input_guide.html#cursor_mode',1,'Cursor mode']]], + ['cursor_20objects_72',['Cursor objects',['../input_guide.html#cursor_object',1,'']]], + ['cursor_20position_73',['Cursor position',['../input_guide.html#cursor_pos',1,'']]], + ['cursor_20position_20changes_74',['Cursor position changes',['../moving_guide.html#moving_cursorpos',1,'']]], + ['cursor_20setting_75',['Cursor setting',['../input_guide.html#cursor_set',1,'']]], + ['cursor_20shapes_76',['cursor shapes',['../news.html#more_cursor_shapes',1,'More standard cursor shapes'],['../group__shapes.html',1,'Standard cursor shapes']]], + ['custom_20cursor_20creation_77',['Custom cursor creation',['../input_guide.html#cursor_custom',1,'']]], + ['custom_20heap_20memory_20allocator_78',['custom heap memory allocator',['../intro_guide.html#init_allocator',1,'Custom heap memory allocator'],['../news.html#custom_heap_allocator',1,'Support for custom heap memory allocator']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_a.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_a.js new file mode 100644 index 0000000..1773cec --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_a.js @@ -0,0 +1,20 @@ +var searchData= +[ + ['damage_20and_20refresh_0',['Window damage and refresh',['../window_guide.html#window_refresh',1,'']]], + ['deallocate_1',['deallocate',['../struct_g_l_f_wallocator.html#ab74cf9a969e73e6eb65a6112a591a988',1,'GLFWallocator']]], + ['decorations_2',['Wayland libdecor decorations',['../news.html#wayland_libdecor_decorations',1,'']]], + ['default_20values_3',['default values',['../intro_guide.html#init_hints_values',1,'Supported and default values'],['../window_guide.html#window_hints_values',1,'Supported and default values']]], + ['demand_4',['Joystick support is initialized on demand',['../news.html#joystick_init_caveat',1,'']]], + ['dependencies_5',['Installing dependencies',['../compile_guide.html#compile_deps',1,'']]], + ['dependencies_20for_20wayland_20and_20x11_6',['Dependencies for Wayland and X11',['../compile_guide.html#compile_deps_wayland',1,'']]], + ['dependency_20has_20been_20removed_7',['macOS CoreVideo dependency has been removed',['../news.html#corevideo_caveat',1,'']]], + ['deprecated_8',['deprecated',['../news.html#mingw_deprecated',1,'Original MinGW support is deprecated'],['../news.html#yosemite_deprecated',1,'OS X Yosemite support is deprecated'],['../news.html#winxp_deprecated',1,'Windows XP and Vista support is deprecated']]], + ['deprecated_20list_9',['Deprecated List',['../deprecated.html',1,'']]], + ['deprecations_10',['Deprecations',['../news.html#deprecations',1,'']]], + ['destruction_11',['destruction',['../input_guide.html#cursor_destruction',1,'Cursor destruction'],['../window_guide.html#window_destruction',1,'Window destruction']]], + ['disabled_20when_20built_20as_20a_20subproject_12',['Tests and examples are disabled when built as a subproject',['../news.html#standalone_caveat',1,'']]], + ['documentation_20generation_20requires_20doxygen_201_209_208_20or_20later_13',['Documentation generation requires Doxygen 1.9.8 or later',['../news.html#docs_target_caveat',1,'']]], + ['doxygen_201_209_208_20or_20later_14',['Documentation generation requires Doxygen 1.9.8 or later',['../news.html#docs_target_caveat',1,'']]], + ['drop_20input_15',['Path drop input',['../input_guide.html#path_drop',1,'']]], + ['dwm_20transparency_16',['Windows 7 framebuffer transparency requires DWM transparency',['../news.html#win7_framebuffer_caveat',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_b.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_b.js new file mode 100644 index 0000000..eacc668 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_b.js @@ -0,0 +1,26 @@ +var searchData= +[ + ['earlier_20versions_0',['Release notes for earlier versions',['../news.html#news_archive',1,'']]], + ['empty_20events_20no_20longer_20round_20trip_20to_20server_1',['X11 empty events no longer round-trip to server',['../news.html#x11_emptyevent_caveat',1,'']]], + ['enter_20leave_20events_2',['Cursor enter/leave events',['../input_guide.html#cursor_enter',1,'']]], + ['enumeration_3',['Video mode enumeration',['../moving_guide.html#moving_video_modes',1,'']]], + ['error_20callback_4',['Setting an error callback',['../quick_guide.html#quick_capture_error',1,'']]], + ['error_20codes_5',['Error codes',['../group__errors.html',1,'']]], + ['error_20handling_6',['Error handling',['../intro_guide.html#error_handling',1,'']]], + ['error_20reference_7',['Initialization, version and error reference',['../group__init.html',1,'']]], + ['es_20extensions_8',['OpenGL and OpenGL ES extensions',['../context_guide.html#context_glext',1,'']]], + ['event_20interface_9',['Event interface',['../internals_guide.html#internals_event',1,'']]], + ['event_20order_10',['Event order',['../intro_guide.html#event_order',1,'']]], + ['event_20passthrough_11',['Mouse event passthrough',['../news.html#mouse_input_passthrough',1,'']]], + ['event_20polling_12',['Removal of automatic event polling',['../moving_guide.html#moving_autopoll',1,'']]], + ['event_20processing_13',['event processing',['../input_guide.html#events',1,'Event processing'],['../window_guide.html#window_events',1,'Window event processing']]], + ['events_14',['events',['../input_guide.html#cursor_enter',1,'Cursor enter/leave events'],['../quick_guide.html#quick_process_events',1,'Processing events'],['../quick_guide.html#quick_key_input',1,'Receiving input events'],['../window_guide.html#window_properties',1,'Window properties and events']]], + ['events_20no_20longer_20round_20trip_20to_20server_15',['X11 empty events no longer round-trip to server',['../news.html#x11_emptyevent_caveat',1,'']]], + ['examples_20are_20disabled_20when_20built_20as_20a_20subproject_16',['Tests and examples are disabled when built as a subproject',['../news.html#standalone_caveat',1,'']]], + ['explicit_20context_20management_17',['Explicit context management',['../moving_guide.html#moving_context',1,'']]], + ['explicit_20monitor_20selection_18',['Explicit monitor selection',['../moving_guide.html#moving_monitor',1,'']]], + ['extension_20with_20a_20loader_20library_19',['Loading extension with a loader library',['../context_guide.html#context_glext_auto',1,'']]], + ['extensions_20',['extensions',['../context_guide.html#context_glext_string',1,'Checking for extensions'],['../compat_guide.html#compat_glx',1,'GLX extensions'],['../context_guide.html#context_glext',1,'OpenGL and OpenGL ES extensions'],['../vulkan_guide.html#vulkan_ext',1,'Querying required Vulkan extensions'],['../compat_guide.html#compat_wsi',1,'Vulkan WSI extensions'],['../compat_guide.html#compat_wgl',1,'WGL extensions']]], + ['extensions_20manually_21',['Loading extensions manually',['../context_guide.html#context_glext_manual',1,'']]], + ['extensions_20protocols_20and_20ipc_20standards_22',['X11 extensions, protocols and IPC standards',['../compat_guide.html#compat_x11',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_c.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_c.js new file mode 100644 index 0000000..3d10dd5 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_c.js @@ -0,0 +1,35 @@ +var searchData= +[ + ['features_0',['features',['../moving_guide.html#moving_removed',1,'Changed and removed features'],['../news.html#features',1,'New features']]], + ['fetching_20function_20pointers_1',['Fetching function pointers',['../context_guide.html#context_glext_proc',1,'']]], + ['file_2',['file',['../build_guide.html#build_include',1,'Including the GLFW header file'],['../vulkan_guide.html#vulkan_include',1,'Including the Vulkan header file'],['../moving_guide.html#moving_renamed_files',1,'Renamed library and header file']]], + ['files_20with_20cmake_3',['Generating build files with CMake',['../compile_guide.html#compile_generate',1,'']]], + ['finding_20the_20vulkan_20loader_4',['Finding the Vulkan loader',['../vulkan_guide.html#vulkan_loader',1,'']]], + ['flag_5',['flag',['../quick_guide.html#quick_window_close',1,'Checking the window close flag'],['../window_guide.html#window_close',1,'Window closing and close flag']]], + ['flags_6',['Modifier key flags',['../group__mods.html',1,'']]], + ['focus_7',['Window input focus',['../window_guide.html#window_focus',1,'']]], + ['for_20custom_20heap_20memory_20allocator_8',['Support for custom heap memory allocator',['../news.html#custom_heap_allocator',1,'']]], + ['for_20earlier_20versions_9',['Release notes for earlier versions',['../news.html#news_archive',1,'']]], + ['for_20extensions_10',['Checking for extensions',['../context_guide.html#context_glext_string',1,'']]], + ['for_20framebuffer_20scaling_11',['Window hint for framebuffer scaling',['../news.html#scale_framebuffer_hint',1,'']]], + ['for_20initial_20window_20position_12',['Window hints for initial window position',['../news.html#window_position_hint',1,'']]], + ['for_20version_203_204_13',['Release notes for version 3.4',['../news.html',1,'']]], + ['for_20versions_20of_20windows_20older_20than_20xp_14',['Support for versions of Windows older than XP',['../moving_guide.html#moving_windows',1,'']]], + ['for_20vulkan_20presentation_20support_15',['Querying for Vulkan presentation support',['../vulkan_guide.html#vulkan_present',1,'']]], + ['for_20vulkan_20support_16',['Querying for Vulkan support',['../vulkan_guide.html#vulkan_support',1,'']]], + ['for_20wayland_20and_20x11_17',['Dependencies for Wayland and X11',['../compile_guide.html#compile_deps_wayland',1,'']]], + ['format_20has_20been_20changed_18',['Version string format has been changed',['../news.html#version_string_caveat',1,'']]], + ['framebuffer_20may_20lack_20alpha_20channel_20on_20older_20systems_19',['Wayland framebuffer may lack alpha channel on older systems',['../news.html#wayland_alpha_caveat',1,'']]], + ['framebuffer_20related_20attributes_20',['Framebuffer related attributes',['../window_guide.html#window_attribs_fb',1,'']]], + ['framebuffer_20related_20hints_21',['Framebuffer related hints',['../window_guide.html#window_hints_fb',1,'']]], + ['framebuffer_20scaling_22',['Window hint for framebuffer scaling',['../news.html#scale_framebuffer_hint',1,'']]], + ['framebuffer_20size_23',['Framebuffer size',['../window_guide.html#window_fbsize',1,'']]], + ['framebuffer_20sizes_24',['Separation of window and framebuffer sizes',['../moving_guide.html#moving_hidpi',1,'']]], + ['framebuffer_20transparency_20requires_20dwm_20transparency_25',['Windows 7 framebuffer transparency requires DWM transparency',['../news.html#win7_framebuffer_caveat',1,'']]], + ['from_20glfw_202_20to_203_26',['Moving from GLFW 2 to 3',['../moving_guide.html',1,'']]], + ['full_20screen_20windows_27',['full screen windows',['../window_guide.html#window_windowed_full_screen',1,'"Windowed full screen" windows'],['../window_guide.html#window_full_screen',1,'Full screen windows']]], + ['function_28',['Cocoa NSView native access function',['../news.html#cocoa_nsview_function',1,'']]], + ['function_20changes_29',['Joystick function changes',['../moving_guide.html#moving_joystick',1,'']]], + ['function_20pointers_30',['function pointers',['../context_guide.html#context_glext_proc',1,'Fetching function pointers'],['../vulkan_guide.html#vulkan_proc',1,'Querying Vulkan function pointers']]], + ['functions_31',['functions',['../news.html#multiplatform_caveat',1,'Multiple sets of native access functions'],['../news.html#new_functions',1,'New functions'],['../moving_guide.html#moving_threads',1,'Removal of threading functions'],['../moving_guide.html#moving_renamed_functions',1,'Renamed functions'],['../internals_guide.html#internals_static',1,'Static functions']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_d.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_d.js new file mode 100644 index 0000000..ad00ab7 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_d.js @@ -0,0 +1,555 @@ +var searchData= +[ + ['gamepad_20axes_0',['Gamepad axes',['../group__gamepad__axes.html',1,'']]], + ['gamepad_20buttons_1',['Gamepad buttons',['../group__gamepad__buttons.html',1,'']]], + ['gamepad_20input_2',['Gamepad input',['../input_guide.html#gamepad',1,'']]], + ['gamepad_20mappings_3',['Gamepad mappings',['../input_guide.html#gamepad_mapping',1,'']]], + ['gamma_20ramp_4',['Gamma ramp',['../monitor_guide.html#monitor_gamma',1,'']]], + ['generated_5',['Configuration header is no longer generated',['../news.html#config_header_caveat',1,'']]], + ['generating_20build_20files_20with_20cmake_6',['Generating build files with CMake',['../compile_guide.html#compile_generate',1,'']]], + ['generating_20with_20command_20line_20cmake_7',['Generating with command-line CMake',['../compile_guide.html#compile_generate_cli',1,'']]], + ['generating_20with_20the_20cmake_20gui_8',['Generating with the CMake GUI',['../compile_guide.html#compile_generate_gui',1,'']]], + ['generation_20requires_20doxygen_201_209_208_20or_20later_9',['Documentation generation requires Doxygen 1.9.8 or later',['../news.html#docs_target_caveat',1,'']]], + ['get_20window_20title_10',['Ability to get window title',['../news.html#window_title_function',1,'']]], + ['getting_20started_11',['Getting started',['../quick_guide.html',1,'']]], + ['glapientry_12',['GLAPIENTRY',['../glfw3_8h.html#aa97755eb47e4bf2727ad45d610e18206',1,'glfw3.h']]], + ['glext_20h_20header_13',['The glext.h header',['../context_guide.html#context_glext_header',1,'']]], + ['glfw_14',['glfw',['../compile_guide.html',1,'Compiling GLFW'],['../quick_guide.html#quick_init_term',1,'Initializing and terminating GLFW'],['../intro_guide.html#intro_init_init',1,'Initializing GLFW'],['../intro_guide.html#intro_init_terminate',1,'Terminating GLFW']]], + ['glfw_202_20to_203_15',['Moving from GLFW 2 to 3',['../moving_guide.html',1,'']]], + ['glfw_20binaries_16',['glfw binaries',['../build_guide.html#build_link_cmake_package',1,'With CMake and installed GLFW binaries'],['../build_guide.html#build_link_mingw',1,'With MinGW-w64 and GLFW binaries'],['../build_guide.html#build_link_win32',1,'With Visual C++ and GLFW binaries']]], + ['glfw_20binaries_20on_20unix_17',['With pkg-config and GLFW binaries on Unix',['../build_guide.html#build_link_pkgconfig',1,'']]], + ['glfw_20header_18',['Including the GLFW header',['../quick_guide.html#quick_include',1,'']]], + ['glfw_20header_20file_19',['Including the GLFW header file',['../build_guide.html#build_include',1,'']]], + ['glfw_20header_20option_20macros_20',['GLFW header option macros',['../build_guide.html#build_macros',1,'']]], + ['glfw_20manually_21',['Compiling GLFW manually',['../compile_guide.html#compile_manual',1,'']]], + ['glfw_20source_22',['With CMake and GLFW source',['../build_guide.html#build_link_cmake_source',1,'']]], + ['glfw3_2eh_23',['glfw3.h',['../glfw3_8h.html',1,'']]], + ['glfw3native_2eh_24',['glfw3native.h',['../glfw3native_8h.html',1,'']]], + ['glfw_5faccum_5falpha_5fbits_25',['GLFW_ACCUM_ALPHA_BITS',['../group__window.html#gae829b55591c18169a40ab4067a041b1f',1,'glfw3.h']]], + ['glfw_5faccum_5fblue_5fbits_26',['GLFW_ACCUM_BLUE_BITS',['../group__window.html#ga22bbe9104a8ce1f8b88fb4f186aa36ce',1,'glfw3.h']]], + ['glfw_5faccum_5fgreen_5fbits_27',['GLFW_ACCUM_GREEN_BITS',['../group__window.html#ga65713cee1326f8e9d806fdf93187b471',1,'glfw3.h']]], + ['glfw_5faccum_5fred_5fbits_28',['GLFW_ACCUM_RED_BITS',['../group__window.html#gaead34a9a683b2bc20eecf30ba738bfc6',1,'glfw3.h']]], + ['glfw_5falpha_5fbits_29',['GLFW_ALPHA_BITS',['../group__window.html#gafed79a3f468997877da86c449bd43e8c',1,'glfw3.h']]], + ['glfw_5fangle_5fplatform_5ftype_30',['GLFW_ANGLE_PLATFORM_TYPE',['../group__init.html#gaec269b24cf549ab46292c0125d8bbdce',1,'glfw3.h']]], + ['glfw_5fangle_5fplatform_5ftype_5fd3d11_31',['GLFW_ANGLE_PLATFORM_TYPE_D3D11',['../glfw3_8h.html#ad6eae659811a52a5cdc43c362aedfa33',1,'glfw3.h']]], + ['glfw_5fangle_5fplatform_5ftype_5fd3d9_32',['GLFW_ANGLE_PLATFORM_TYPE_D3D9',['../glfw3_8h.html#a6e8fdc83113d247ad792bb5c4e82c894',1,'glfw3.h']]], + ['glfw_5fangle_5fplatform_5ftype_5fmetal_33',['GLFW_ANGLE_PLATFORM_TYPE_METAL',['../glfw3_8h.html#ab56d91b26cf223dc67590a93a2f8507d',1,'glfw3.h']]], + ['glfw_5fangle_5fplatform_5ftype_5fnone_34',['GLFW_ANGLE_PLATFORM_TYPE_NONE',['../glfw3_8h.html#ae78e673449c2a2b8c560ca1b1e283228',1,'glfw3.h']]], + ['glfw_5fangle_5fplatform_5ftype_5fopengl_35',['GLFW_ANGLE_PLATFORM_TYPE_OPENGL',['../glfw3_8h.html#ad8d9e97ed7790811470366b338833623',1,'glfw3.h']]], + ['glfw_5fangle_5fplatform_5ftype_5fopengles_36',['GLFW_ANGLE_PLATFORM_TYPE_OPENGLES',['../glfw3_8h.html#a0003c089da020cbf957218e70245bb65',1,'glfw3.h']]], + ['glfw_5fangle_5fplatform_5ftype_5fvulkan_37',['GLFW_ANGLE_PLATFORM_TYPE_VULKAN',['../glfw3_8h.html#a579ac83506c7546709dad91960cc7ca1',1,'glfw3.h']]], + ['glfw_5fany_5fplatform_38',['GLFW_ANY_PLATFORM',['../group__init.html#ga18b2d37374d0dea28cd69194fa85b859',1,'glfw3.h']]], + ['glfw_5fany_5fposition_39',['GLFW_ANY_POSITION',['../glfw3_8h.html#aa0e681bf859ef1bb8355692a70b0ee92',1,'glfw3.h']]], + ['glfw_5fany_5frelease_5fbehavior_40',['GLFW_ANY_RELEASE_BEHAVIOR',['../glfw3_8h.html#a6b47d806f285efe9bfd7aeec667297ee',1,'glfw3.h']]], + ['glfw_5fapi_5funavailable_41',['GLFW_API_UNAVAILABLE',['../group__errors.html#ga56882b290db23261cc6c053c40c2d08e',1,'glfw3.h']]], + ['glfw_5fapientry_5fdefined_42',['GLFW_APIENTRY_DEFINED',['../glfw3_8h.html#a8a8538c5500308b4211844f2fb26c7b9',1,'glfw3.h']]], + ['glfw_5farrow_5fcursor_43',['GLFW_ARROW_CURSOR',['../group__shapes.html#ga8ab0e717245b85506cb0eaefdea39d0a',1,'glfw3.h']]], + ['glfw_5fauto_5ficonify_44',['GLFW_AUTO_ICONIFY',['../group__window.html#ga9d9874fc928200136a6dcdad726aa252',1,'glfw3.h']]], + ['glfw_5faux_5fbuffers_45',['GLFW_AUX_BUFFERS',['../group__window.html#gab05108c5029443b371112b031d1fa174',1,'glfw3.h']]], + ['glfw_5fblue_5fbits_46',['GLFW_BLUE_BITS',['../group__window.html#gab292ea403db6d514537b515311bf9ae3',1,'glfw3.h']]], + ['glfw_5fcenter_5fcursor_47',['GLFW_CENTER_CURSOR',['../group__window.html#ga5ac0847c0aa0b3619f2855707b8a7a77',1,'glfw3.h']]], + ['glfw_5fclient_5fapi_48',['GLFW_CLIENT_API',['../group__window.html#ga649309cf72a3d3de5b1348ca7936c95b',1,'glfw3.h']]], + ['glfw_5fcocoa_5fchdir_5fresources_49',['GLFW_COCOA_CHDIR_RESOURCES',['../group__init.html#gab937983147a3158d45f88fad7129d9f2',1,'glfw3.h']]], + ['glfw_5fcocoa_5fframe_5fname_50',['GLFW_COCOA_FRAME_NAME',['../group__window.html#ga70fa0fbc745de6aa824df79a580e84b5',1,'glfw3.h']]], + ['glfw_5fcocoa_5fgraphics_5fswitching_51',['GLFW_COCOA_GRAPHICS_SWITCHING',['../group__window.html#ga53c84ed2ddd94e15bbd44b1f6f7feafc',1,'glfw3.h']]], + ['glfw_5fcocoa_5fmenubar_52',['GLFW_COCOA_MENUBAR',['../group__init.html#ga71e0b4ce2f2696a84a9b8c5e12dc70cf',1,'glfw3.h']]], + ['glfw_5fcocoa_5fretina_5fframebuffer_53',['GLFW_COCOA_RETINA_FRAMEBUFFER',['../group__window.html#gab6ef2d02eb55800d249ccf1af253c35e',1,'glfw3.h']]], + ['glfw_5fconnected_54',['GLFW_CONNECTED',['../glfw3_8h.html#abe11513fd1ffbee5bb9b173f06028b9e',1,'glfw3.h']]], + ['glfw_5fcontext_5fcreation_5fapi_55',['GLFW_CONTEXT_CREATION_API',['../group__window.html#ga5154cebfcd831c1cc63a4d5ac9bb4486',1,'glfw3.h']]], + ['glfw_5fcontext_5fdebug_56',['GLFW_CONTEXT_DEBUG',['../group__window.html#ga8d55e3afec73c7de0509c3b7ad1d9e3f',1,'glfw3.h']]], + ['glfw_5fcontext_5fno_5ferror_57',['GLFW_CONTEXT_NO_ERROR',['../group__window.html#ga5a52fdfd46d8249c211f923675728082',1,'glfw3.h']]], + ['glfw_5fcontext_5frelease_5fbehavior_58',['GLFW_CONTEXT_RELEASE_BEHAVIOR',['../group__window.html#ga72b648a8378fe3310c7c7bbecc0f7be6',1,'glfw3.h']]], + ['glfw_5fcontext_5frevision_59',['GLFW_CONTEXT_REVISION',['../group__window.html#gafb9475071aa77c6fb05ca5a5c8678a08',1,'glfw3.h']]], + ['glfw_5fcontext_5frobustness_60',['GLFW_CONTEXT_ROBUSTNESS',['../group__window.html#gade3593916b4c507900aa2d6844810e00',1,'glfw3.h']]], + ['glfw_5fcontext_5fversion_5fmajor_61',['GLFW_CONTEXT_VERSION_MAJOR',['../group__window.html#gafe5e4922de1f9932d7e9849bb053b0c0',1,'glfw3.h']]], + ['glfw_5fcontext_5fversion_5fminor_62',['GLFW_CONTEXT_VERSION_MINOR',['../group__window.html#ga31aca791e4b538c4e4a771eb95cc2d07',1,'glfw3.h']]], + ['glfw_5fcrosshair_5fcursor_63',['GLFW_CROSSHAIR_CURSOR',['../group__shapes.html#ga8af88c0ea05ab9e8f9ac1530e8873c22',1,'glfw3.h']]], + ['glfw_5fcursor_64',['GLFW_CURSOR',['../glfw3_8h.html#aade31da5b884a84a7625c6b059b9132c',1,'glfw3.h']]], + ['glfw_5fcursor_5fcaptured_65',['GLFW_CURSOR_CAPTURED',['../glfw3_8h.html#ac1dbfa0cb4641a0edc93412ade0895dc',1,'glfw3.h']]], + ['glfw_5fcursor_5fdisabled_66',['GLFW_CURSOR_DISABLED',['../glfw3_8h.html#a2315b99a329ce53e6a13a9d46fd5ca88',1,'glfw3.h']]], + ['glfw_5fcursor_5fhidden_67',['GLFW_CURSOR_HIDDEN',['../glfw3_8h.html#ac4d5cb9d78de8573349c58763d53bf11',1,'glfw3.h']]], + ['glfw_5fcursor_5fnormal_68',['GLFW_CURSOR_NORMAL',['../glfw3_8h.html#ae04dd25c8577e19fa8c97368561f6c68',1,'glfw3.h']]], + ['glfw_5fcursor_5funavailable_69',['GLFW_CURSOR_UNAVAILABLE',['../group__errors.html#ga09d6943923a70ddef3a085f5baee786c',1,'glfw3.h']]], + ['glfw_5fdecorated_70',['GLFW_DECORATED',['../group__window.html#ga21b854d36314c94d65aed84405b2f25e',1,'glfw3.h']]], + ['glfw_5fdepth_5fbits_71',['GLFW_DEPTH_BITS',['../group__window.html#ga318a55eac1fee57dfe593b6d38149d07',1,'glfw3.h']]], + ['glfw_5fdisconnected_72',['GLFW_DISCONNECTED',['../glfw3_8h.html#aab64b25921ef21d89252d6f0a71bfc32',1,'glfw3.h']]], + ['glfw_5fdont_5fcare_73',['GLFW_DONT_CARE',['../glfw3_8h.html#a7a2edf2c18446833d27d07f1b7f3d571',1,'glfw3.h']]], + ['glfw_5fdoublebuffer_74',['GLFW_DOUBLEBUFFER',['../group__window.html#ga714a5d569e8a274ea58fdfa020955339',1,'glfw3.h']]], + ['glfw_5fegl_5fcontext_5fapi_75',['GLFW_EGL_CONTEXT_API',['../glfw3_8h.html#a03cf65c9ab01fc8b872ba58842c531c9',1,'glfw3.h']]], + ['glfw_5ffalse_76',['GLFW_FALSE',['../group__init.html#gac877fe3b627d21ef3a0a23e0a73ba8c5',1,'glfw3.h']]], + ['glfw_5ffeature_5funavailable_77',['GLFW_FEATURE_UNAVAILABLE',['../group__errors.html#ga526fba20a01504a8086c763b6ca53ce5',1,'glfw3.h']]], + ['glfw_5ffeature_5funimplemented_78',['GLFW_FEATURE_UNIMPLEMENTED',['../group__errors.html#ga5dda77e023e83151e8bd55a6758f946a',1,'glfw3.h']]], + ['glfw_5ffloating_79',['GLFW_FLOATING',['../group__window.html#ga7fb0be51407783b41adbf5bec0b09d80',1,'glfw3.h']]], + ['glfw_5ffocus_5fon_5fshow_80',['GLFW_FOCUS_ON_SHOW',['../group__window.html#gafa94b1da34bfd6488c0d709761504dfc',1,'glfw3.h']]], + ['glfw_5ffocused_81',['GLFW_FOCUSED',['../group__window.html#ga54ddb14825a1541a56e22afb5f832a9e',1,'glfw3.h']]], + ['glfw_5fformat_5funavailable_82',['GLFW_FORMAT_UNAVAILABLE',['../group__errors.html#ga196e125ef261d94184e2b55c05762f14',1,'glfw3.h']]], + ['glfw_5fgamepad_5faxis_5flast_83',['GLFW_GAMEPAD_AXIS_LAST',['../group__gamepad__axes.html#ga0818fd9433e1359692b7443293e5ac86',1,'glfw3.h']]], + ['glfw_5fgamepad_5faxis_5fleft_5ftrigger_84',['GLFW_GAMEPAD_AXIS_LEFT_TRIGGER',['../group__gamepad__axes.html#ga6d79561dd8907c37354426242901b86e',1,'glfw3.h']]], + ['glfw_5fgamepad_5faxis_5fleft_5fx_85',['GLFW_GAMEPAD_AXIS_LEFT_X',['../group__gamepad__axes.html#ga544e396d092036a7d80c1e5f233f7a38',1,'glfw3.h']]], + ['glfw_5fgamepad_5faxis_5fleft_5fy_86',['GLFW_GAMEPAD_AXIS_LEFT_Y',['../group__gamepad__axes.html#ga64dcf2c6e9be50b7c556ff7671996dd5',1,'glfw3.h']]], + ['glfw_5fgamepad_5faxis_5fright_5ftrigger_87',['GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER',['../group__gamepad__axes.html#ga121a7d5d20589a423cd1634dd6ee6eab',1,'glfw3.h']]], + ['glfw_5fgamepad_5faxis_5fright_5fx_88',['GLFW_GAMEPAD_AXIS_RIGHT_X',['../group__gamepad__axes.html#gabd6785106cd3c5a044a6e49a395ee2fc',1,'glfw3.h']]], + ['glfw_5fgamepad_5faxis_5fright_5fy_89',['GLFW_GAMEPAD_AXIS_RIGHT_Y',['../group__gamepad__axes.html#ga1cc20566d44d521b7183681a8e88e2e4',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fa_90',['GLFW_GAMEPAD_BUTTON_A',['../group__gamepad__buttons.html#gae055a12fbf4b48b5954c8e1cd129b810',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fb_91',['GLFW_GAMEPAD_BUTTON_B',['../group__gamepad__buttons.html#ga2228a6512fd5950cdb51ba07846546fa',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fback_92',['GLFW_GAMEPAD_BUTTON_BACK',['../group__gamepad__buttons.html#gabc7c0264ce778835b516a472b47f6caf',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fcircle_93',['GLFW_GAMEPAD_BUTTON_CIRCLE',['../group__gamepad__buttons.html#gaaef094b3dacbf15f272b274516839b82',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fcross_94',['GLFW_GAMEPAD_BUTTON_CROSS',['../group__gamepad__buttons.html#gaf08d0df26527c9305253422bd98ed63a',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fdpad_5fdown_95',['GLFW_GAMEPAD_BUTTON_DPAD_DOWN',['../group__gamepad__buttons.html#ga8f2b731b97d80f90f11967a83207665c',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fdpad_5fleft_96',['GLFW_GAMEPAD_BUTTON_DPAD_LEFT',['../group__gamepad__buttons.html#gaf0697e0e8607b2ebe1c93b0c6befe301',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fdpad_5fright_97',['GLFW_GAMEPAD_BUTTON_DPAD_RIGHT',['../group__gamepad__buttons.html#gae2a780d2a8c79e0b77c0b7b601ca57c6',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fdpad_5fup_98',['GLFW_GAMEPAD_BUTTON_DPAD_UP',['../group__gamepad__buttons.html#ga4f1ed6f974a47bc8930d4874a283476a',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fguide_99',['GLFW_GAMEPAD_BUTTON_GUIDE',['../group__gamepad__buttons.html#ga7fa48c32e5b2f5db2f080aa0b8b573dc',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5flast_100',['GLFW_GAMEPAD_BUTTON_LAST',['../group__gamepad__buttons.html#ga5cc98882f4f81dacf761639a567f61eb',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fleft_5fbumper_101',['GLFW_GAMEPAD_BUTTON_LEFT_BUMPER',['../group__gamepad__buttons.html#ga17d67b4f39a39d6b813bd1567a3507c3',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fleft_5fthumb_102',['GLFW_GAMEPAD_BUTTON_LEFT_THUMB',['../group__gamepad__buttons.html#ga3e089787327454f7bfca7364d6ca206a',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fright_5fbumper_103',['GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER',['../group__gamepad__buttons.html#gadfbc9ea9bf3aae896b79fa49fdc85c7f',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fright_5fthumb_104',['GLFW_GAMEPAD_BUTTON_RIGHT_THUMB',['../group__gamepad__buttons.html#ga1c003f52b5aebb45272475b48953b21a',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fsquare_105',['GLFW_GAMEPAD_BUTTON_SQUARE',['../group__gamepad__buttons.html#gafc7821e87d77d41ed2cd3e1f726ec35f',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fstart_106',['GLFW_GAMEPAD_BUTTON_START',['../group__gamepad__buttons.html#ga04606949dd9139434b8a1bedf4ac1021',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5ftriangle_107',['GLFW_GAMEPAD_BUTTON_TRIANGLE',['../group__gamepad__buttons.html#ga3a7ef6bcb768a08cd3bf142f7f09f802',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fx_108',['GLFW_GAMEPAD_BUTTON_X',['../group__gamepad__buttons.html#ga52cc94785cf3fe9a12e246539259887c',1,'glfw3.h']]], + ['glfw_5fgamepad_5fbutton_5fy_109',['GLFW_GAMEPAD_BUTTON_Y',['../group__gamepad__buttons.html#gafc931248bda494b530cbe057f386a5ed',1,'glfw3.h']]], + ['glfw_5fglapientry_5fdefined_110',['GLFW_GLAPIENTRY_DEFINED',['../glfw3_8h.html#a3b526ac796be993406ea2f1642c25fc3',1,'glfw3.h']]], + ['glfw_5fgreen_5fbits_111',['GLFW_GREEN_BITS',['../group__window.html#gafba3b72638c914e5fb8a237dd4c50d4d',1,'glfw3.h']]], + ['glfw_5fhand_5fcursor_112',['GLFW_HAND_CURSOR',['../group__shapes.html#ga1db35e20849e0837c82e3dc1fd797263',1,'glfw3.h']]], + ['glfw_5fhat_5fcentered_113',['GLFW_HAT_CENTERED',['../group__hat__state.html#gae2c0bcb7aec609e4736437554f6638fd',1,'glfw3.h']]], + ['glfw_5fhat_5fdown_114',['GLFW_HAT_DOWN',['../group__hat__state.html#gad60d1fd0dc85c18f2642cbae96d3deff',1,'glfw3.h']]], + ['glfw_5fhat_5fleft_115',['GLFW_HAT_LEFT',['../group__hat__state.html#gac775f4b3154fdf5db93eb432ba546dff',1,'glfw3.h']]], + ['glfw_5fhat_5fleft_5fdown_116',['GLFW_HAT_LEFT_DOWN',['../group__hat__state.html#ga76c02baf1ea345fcbe3e8ff176a73e19',1,'glfw3.h']]], + ['glfw_5fhat_5fleft_5fup_117',['GLFW_HAT_LEFT_UP',['../group__hat__state.html#ga638f0e20dc5de90de21a33564e8ce129',1,'glfw3.h']]], + ['glfw_5fhat_5fright_118',['GLFW_HAT_RIGHT',['../group__hat__state.html#ga252586e3bbde75f4b0e07ad3124867f5',1,'glfw3.h']]], + ['glfw_5fhat_5fright_5fdown_119',['GLFW_HAT_RIGHT_DOWN',['../group__hat__state.html#gad7f0e4f52fd68d734863aaeadab3a3f5',1,'glfw3.h']]], + ['glfw_5fhat_5fright_5fup_120',['GLFW_HAT_RIGHT_UP',['../group__hat__state.html#ga94aea0ae241a8b902883536c592ee693',1,'glfw3.h']]], + ['glfw_5fhat_5fup_121',['GLFW_HAT_UP',['../group__hat__state.html#ga8c9720c76cd1b912738159ed74c85b36',1,'glfw3.h']]], + ['glfw_5fhovered_122',['GLFW_HOVERED',['../group__window.html#ga8665c71c6fa3d22425c6a0e8a3f89d8a',1,'glfw3.h']]], + ['glfw_5fhresize_5fcursor_123',['GLFW_HRESIZE_CURSOR',['../group__shapes.html#gabb3eb0109f11bb808fc34659177ca962',1,'glfw3.h']]], + ['glfw_5fibeam_5fcursor_124',['GLFW_IBEAM_CURSOR',['../group__shapes.html#ga36185f4375eaada1b04e431244774c86',1,'glfw3.h']]], + ['glfw_5ficonified_125',['GLFW_ICONIFIED',['../group__window.html#ga39d44b7c056e55e581355a92d240b58a',1,'glfw3.h']]], + ['glfw_5finvalid_5fenum_126',['GLFW_INVALID_ENUM',['../group__errors.html#ga76f6bb9c4eea73db675f096b404593ce',1,'glfw3.h']]], + ['glfw_5finvalid_5fvalue_127',['GLFW_INVALID_VALUE',['../group__errors.html#gaaf2ef9aa8202c2b82ac2d921e554c687',1,'glfw3.h']]], + ['glfw_5fjoystick_5f1_128',['GLFW_JOYSTICK_1',['../group__joysticks.html#ga34a0443d059e9f22272cd4669073f73d',1,'glfw3.h']]], + ['glfw_5fjoystick_5f10_129',['GLFW_JOYSTICK_10',['../group__joysticks.html#gaef55389ee605d6dfc31aef6fe98c54ec',1,'glfw3.h']]], + ['glfw_5fjoystick_5f11_130',['GLFW_JOYSTICK_11',['../group__joysticks.html#gae7d26e3df447c2c14a569fcc18516af4',1,'glfw3.h']]], + ['glfw_5fjoystick_5f12_131',['GLFW_JOYSTICK_12',['../group__joysticks.html#gab91bbf5b7ca6be8d3ac5c4d89ff48ac7',1,'glfw3.h']]], + ['glfw_5fjoystick_5f13_132',['GLFW_JOYSTICK_13',['../group__joysticks.html#ga5c84fb4e49bf661d7d7c78eb4018c508',1,'glfw3.h']]], + ['glfw_5fjoystick_5f14_133',['GLFW_JOYSTICK_14',['../group__joysticks.html#ga89540873278ae5a42b3e70d64164dc74',1,'glfw3.h']]], + ['glfw_5fjoystick_5f15_134',['GLFW_JOYSTICK_15',['../group__joysticks.html#ga7b02ab70daf7a78bcc942d5d4cc1dcf9',1,'glfw3.h']]], + ['glfw_5fjoystick_5f16_135',['GLFW_JOYSTICK_16',['../group__joysticks.html#ga453edeeabf350827646b6857df4f80ce',1,'glfw3.h']]], + ['glfw_5fjoystick_5f2_136',['GLFW_JOYSTICK_2',['../group__joysticks.html#ga6eab65ec88e65e0850ef8413504cb50c',1,'glfw3.h']]], + ['glfw_5fjoystick_5f3_137',['GLFW_JOYSTICK_3',['../group__joysticks.html#gae6f3eedfeb42424c2f5e3161efb0b654',1,'glfw3.h']]], + ['glfw_5fjoystick_5f4_138',['GLFW_JOYSTICK_4',['../group__joysticks.html#ga97ddbcad02b7f48d74fad4ddb08fff59',1,'glfw3.h']]], + ['glfw_5fjoystick_5f5_139',['GLFW_JOYSTICK_5',['../group__joysticks.html#gae43281bc66d3fa5089fb50c3e7a28695',1,'glfw3.h']]], + ['glfw_5fjoystick_5f6_140',['GLFW_JOYSTICK_6',['../group__joysticks.html#ga74771620aa53bd68a487186dea66fd77',1,'glfw3.h']]], + ['glfw_5fjoystick_5f7_141',['GLFW_JOYSTICK_7',['../group__joysticks.html#ga20a9f4f3aaefed9ea5e66072fc588b87',1,'glfw3.h']]], + ['glfw_5fjoystick_5f8_142',['GLFW_JOYSTICK_8',['../group__joysticks.html#ga21a934c940bcf25db0e4c8fe9b364bdb',1,'glfw3.h']]], + ['glfw_5fjoystick_5f9_143',['GLFW_JOYSTICK_9',['../group__joysticks.html#ga87689d47df0ba6f9f5fcbbcaf7b3cecf',1,'glfw3.h']]], + ['glfw_5fjoystick_5fhat_5fbuttons_144',['GLFW_JOYSTICK_HAT_BUTTONS',['../group__init.html#gab9c0534709fda03ec8959201da3a9a18',1,'glfw3.h']]], + ['glfw_5fjoystick_5flast_145',['GLFW_JOYSTICK_LAST',['../group__joysticks.html#ga9ca13ebf24c331dd98df17d84a4b72c9',1,'glfw3.h']]], + ['glfw_5fkey_5f0_146',['GLFW_KEY_0',['../group__keys.html#ga50391730e9d7112ad4fd42d0bd1597c1',1,'glfw3.h']]], + ['glfw_5fkey_5f1_147',['GLFW_KEY_1',['../group__keys.html#ga05e4cae9ddb8d40cf6d82c8f11f2502f',1,'glfw3.h']]], + ['glfw_5fkey_5f2_148',['GLFW_KEY_2',['../group__keys.html#gadc8e66b3a4c4b5c39ad1305cf852863c',1,'glfw3.h']]], + ['glfw_5fkey_5f3_149',['GLFW_KEY_3',['../group__keys.html#ga812f0273fe1a981e1fa002ae73e92271',1,'glfw3.h']]], + ['glfw_5fkey_5f4_150',['GLFW_KEY_4',['../group__keys.html#ga9e14b6975a9cc8f66cdd5cb3d3861356',1,'glfw3.h']]], + ['glfw_5fkey_5f5_151',['GLFW_KEY_5',['../group__keys.html#ga4d74ddaa5d4c609993b4d4a15736c924',1,'glfw3.h']]], + ['glfw_5fkey_5f6_152',['GLFW_KEY_6',['../group__keys.html#ga9ea4ab80c313a227b14d0a7c6f810b5d',1,'glfw3.h']]], + ['glfw_5fkey_5f7_153',['GLFW_KEY_7',['../group__keys.html#gab79b1cfae7bd630cfc4604c1f263c666',1,'glfw3.h']]], + ['glfw_5fkey_5f8_154',['GLFW_KEY_8',['../group__keys.html#gadeaa109a0f9f5afc94fe4a108e686f6f',1,'glfw3.h']]], + ['glfw_5fkey_5f9_155',['GLFW_KEY_9',['../group__keys.html#ga2924cb5349ebbf97c8987f3521c44f39',1,'glfw3.h']]], + ['glfw_5fkey_5fa_156',['GLFW_KEY_A',['../group__keys.html#ga03e842608e1ea323370889d33b8f70ff',1,'glfw3.h']]], + ['glfw_5fkey_5fapostrophe_157',['GLFW_KEY_APOSTROPHE',['../group__keys.html#ga6059b0b048ba6980b6107fffbd3b4b24',1,'glfw3.h']]], + ['glfw_5fkey_5fb_158',['GLFW_KEY_B',['../group__keys.html#ga8e3fb647ff3aca9e8dbf14fe66332941',1,'glfw3.h']]], + ['glfw_5fkey_5fbackslash_159',['GLFW_KEY_BACKSLASH',['../group__keys.html#gab8155ea99d1ab27ff56f24f8dc73f8d1',1,'glfw3.h']]], + ['glfw_5fkey_5fbackspace_160',['GLFW_KEY_BACKSPACE',['../group__keys.html#ga6c0df1fe2f156bbd5a98c66d76ff3635',1,'glfw3.h']]], + ['glfw_5fkey_5fc_161',['GLFW_KEY_C',['../group__keys.html#ga00ccf3475d9ee2e679480d540d554669',1,'glfw3.h']]], + ['glfw_5fkey_5fcaps_5flock_162',['GLFW_KEY_CAPS_LOCK',['../group__keys.html#ga92c1d2c9d63485f3d70f94f688d48672',1,'glfw3.h']]], + ['glfw_5fkey_5fcomma_163',['GLFW_KEY_COMMA',['../group__keys.html#gab3d5d72e59d3055f494627b0a524926c',1,'glfw3.h']]], + ['glfw_5fkey_5fd_164',['GLFW_KEY_D',['../group__keys.html#ga011f7cdc9a654da984a2506479606933',1,'glfw3.h']]], + ['glfw_5fkey_5fdelete_165',['GLFW_KEY_DELETE',['../group__keys.html#gadb111e4df74b8a715f2c05dad58d2682',1,'glfw3.h']]], + ['glfw_5fkey_5fdown_166',['GLFW_KEY_DOWN',['../group__keys.html#gae2e3958c71595607416aa7bf082be2f9',1,'glfw3.h']]], + ['glfw_5fkey_5fe_167',['GLFW_KEY_E',['../group__keys.html#gabf48fcc3afbe69349df432b470c96ef2',1,'glfw3.h']]], + ['glfw_5fkey_5fend_168',['GLFW_KEY_END',['../group__keys.html#ga86587ea1df19a65978d3e3b8439bedd9',1,'glfw3.h']]], + ['glfw_5fkey_5fenter_169',['GLFW_KEY_ENTER',['../group__keys.html#ga9555a92ecbecdbc1f3435219c571d667',1,'glfw3.h']]], + ['glfw_5fkey_5fequal_170',['GLFW_KEY_EQUAL',['../group__keys.html#gae1a2de47240d6664423c204bdd91bd17',1,'glfw3.h']]], + ['glfw_5fkey_5fescape_171',['GLFW_KEY_ESCAPE',['../group__keys.html#gaac6596c350b635c245113b81c2123b93',1,'glfw3.h']]], + ['glfw_5fkey_5ff_172',['GLFW_KEY_F',['../group__keys.html#ga5df402e02aca08444240058fd9b42a55',1,'glfw3.h']]], + ['glfw_5fkey_5ff1_173',['GLFW_KEY_F1',['../group__keys.html#gafb8d66c573acf22e364049477dcbea30',1,'glfw3.h']]], + ['glfw_5fkey_5ff10_174',['GLFW_KEY_F10',['../group__keys.html#ga718d11d2f7d57471a2f6a894235995b1',1,'glfw3.h']]], + ['glfw_5fkey_5ff11_175',['GLFW_KEY_F11',['../group__keys.html#ga0bc04b11627e7d69339151e7306b2832',1,'glfw3.h']]], + ['glfw_5fkey_5ff12_176',['GLFW_KEY_F12',['../group__keys.html#gaf5908fa9b0a906ae03fc2c61ac7aa3e2',1,'glfw3.h']]], + ['glfw_5fkey_5ff13_177',['GLFW_KEY_F13',['../group__keys.html#gad637f4308655e1001bd6ad942bc0fd4b',1,'glfw3.h']]], + ['glfw_5fkey_5ff14_178',['GLFW_KEY_F14',['../group__keys.html#gaf14c66cff3396e5bd46e803c035e6c1f',1,'glfw3.h']]], + ['glfw_5fkey_5ff15_179',['GLFW_KEY_F15',['../group__keys.html#ga7f70970db6e8be1794da8516a6d14058',1,'glfw3.h']]], + ['glfw_5fkey_5ff16_180',['GLFW_KEY_F16',['../group__keys.html#gaa582dbb1d2ba2050aa1dca0838095b27',1,'glfw3.h']]], + ['glfw_5fkey_5ff17_181',['GLFW_KEY_F17',['../group__keys.html#ga972ce5c365e2394b36104b0e3125c748',1,'glfw3.h']]], + ['glfw_5fkey_5ff18_182',['GLFW_KEY_F18',['../group__keys.html#gaebf6391058d5566601e357edc5ea737c',1,'glfw3.h']]], + ['glfw_5fkey_5ff19_183',['GLFW_KEY_F19',['../group__keys.html#gaec011d9ba044058cb54529da710e9791',1,'glfw3.h']]], + ['glfw_5fkey_5ff2_184',['GLFW_KEY_F2',['../group__keys.html#ga0900750aff94889b940f5e428c07daee',1,'glfw3.h']]], + ['glfw_5fkey_5ff20_185',['GLFW_KEY_F20',['../group__keys.html#ga82b9c721ada04cd5ca8de767da38022f',1,'glfw3.h']]], + ['glfw_5fkey_5ff21_186',['GLFW_KEY_F21',['../group__keys.html#ga356afb14d3440ff2bb378f74f7ebc60f',1,'glfw3.h']]], + ['glfw_5fkey_5ff22_187',['GLFW_KEY_F22',['../group__keys.html#ga90960bd2a155f2b09675324d3dff1565',1,'glfw3.h']]], + ['glfw_5fkey_5ff23_188',['GLFW_KEY_F23',['../group__keys.html#ga43c21099aac10952d1be909a8ddee4d5',1,'glfw3.h']]], + ['glfw_5fkey_5ff24_189',['GLFW_KEY_F24',['../group__keys.html#ga8150374677b5bed3043408732152dea2',1,'glfw3.h']]], + ['glfw_5fkey_5ff25_190',['GLFW_KEY_F25',['../group__keys.html#gaa4bbd93ed73bb4c6ae7d83df880b7199',1,'glfw3.h']]], + ['glfw_5fkey_5ff3_191',['GLFW_KEY_F3',['../group__keys.html#gaed7cd729c0147a551bb8b7bb36c17015',1,'glfw3.h']]], + ['glfw_5fkey_5ff4_192',['GLFW_KEY_F4',['../group__keys.html#ga9b61ebd0c63b44b7332fda2c9763eaa6',1,'glfw3.h']]], + ['glfw_5fkey_5ff5_193',['GLFW_KEY_F5',['../group__keys.html#gaf258dda9947daa428377938ed577c8c2',1,'glfw3.h']]], + ['glfw_5fkey_5ff6_194',['GLFW_KEY_F6',['../group__keys.html#ga6dc2d3f87b9d51ffbbbe2ef0299d8e1d',1,'glfw3.h']]], + ['glfw_5fkey_5ff7_195',['GLFW_KEY_F7',['../group__keys.html#gacca6ef8a2162c52a0ac1d881e8d9c38a',1,'glfw3.h']]], + ['glfw_5fkey_5ff8_196',['GLFW_KEY_F8',['../group__keys.html#gac9d39390336ae14e4a93e295de43c7e8',1,'glfw3.h']]], + ['glfw_5fkey_5ff9_197',['GLFW_KEY_F9',['../group__keys.html#gae40de0de1c9f21cd26c9afa3d7050851',1,'glfw3.h']]], + ['glfw_5fkey_5fg_198',['GLFW_KEY_G',['../group__keys.html#gae74ecddf7cc96104ab23989b1cdab536',1,'glfw3.h']]], + ['glfw_5fkey_5fgrave_5faccent_199',['GLFW_KEY_GRAVE_ACCENT',['../group__keys.html#ga7a3701fb4e2a0b136ff4b568c3c8d668',1,'glfw3.h']]], + ['glfw_5fkey_5fh_200',['GLFW_KEY_H',['../group__keys.html#gad4cc98fc8f35f015d9e2fb94bf136076',1,'glfw3.h']]], + ['glfw_5fkey_5fhome_201',['GLFW_KEY_HOME',['../group__keys.html#ga41452c7287195d481e43207318c126a7',1,'glfw3.h']]], + ['glfw_5fkey_5fi_202',['GLFW_KEY_I',['../group__keys.html#ga274655c8bfe39742684ca393cf8ed093',1,'glfw3.h']]], + ['glfw_5fkey_5finsert_203',['GLFW_KEY_INSERT',['../group__keys.html#ga373ac7365435d6b0eb1068f470e34f47',1,'glfw3.h']]], + ['glfw_5fkey_5fj_204',['GLFW_KEY_J',['../group__keys.html#ga65ff2aedb129a3149ad9cb3e4159a75f',1,'glfw3.h']]], + ['glfw_5fkey_5fk_205',['GLFW_KEY_K',['../group__keys.html#ga4ae8debadf6d2a691badae0b53ea3ba0',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5f0_206',['GLFW_KEY_KP_0',['../group__keys.html#ga10515dafc55b71e7683f5b4fedd1c70d',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5f1_207',['GLFW_KEY_KP_1',['../group__keys.html#gaf3a29a334402c5eaf0b3439edf5587c3',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5f2_208',['GLFW_KEY_KP_2',['../group__keys.html#gaf82d5a802ab8213c72653d7480c16f13',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5f3_209',['GLFW_KEY_KP_3',['../group__keys.html#ga7e25ff30d56cd512828c1d4ae8d54ef2',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5f4_210',['GLFW_KEY_KP_4',['../group__keys.html#gada7ec86778b85e0b4de0beea72234aea',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5f5_211',['GLFW_KEY_KP_5',['../group__keys.html#ga9a5be274434866c51738cafbb6d26b45',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5f6_212',['GLFW_KEY_KP_6',['../group__keys.html#gafc141b0f8450519084c01092a3157faa',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5f7_213',['GLFW_KEY_KP_7',['../group__keys.html#ga8882f411f05d04ec77a9563974bbfa53',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5f8_214',['GLFW_KEY_KP_8',['../group__keys.html#gab2ea2e6a12f89d315045af520ac78cec',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5f9_215',['GLFW_KEY_KP_9',['../group__keys.html#gafb21426b630ed4fcc084868699ba74c1',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5fadd_216',['GLFW_KEY_KP_ADD',['../group__keys.html#gad09c7c98acc79e89aa6a0a91275becac',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5fdecimal_217',['GLFW_KEY_KP_DECIMAL',['../group__keys.html#ga4e231d968796331a9ea0dbfb98d4005b',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5fdivide_218',['GLFW_KEY_KP_DIVIDE',['../group__keys.html#gabca1733780a273d549129ad0f250d1e5',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5fenter_219',['GLFW_KEY_KP_ENTER',['../group__keys.html#ga4f728f8738f2986bd63eedd3d412e8cf',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5fequal_220',['GLFW_KEY_KP_EQUAL',['../group__keys.html#gaebdc76d4a808191e6d21b7e4ad2acd97',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5fmultiply_221',['GLFW_KEY_KP_MULTIPLY',['../group__keys.html#ga9ada267eb0e78ed2ada8701dd24a56ef',1,'glfw3.h']]], + ['glfw_5fkey_5fkp_5fsubtract_222',['GLFW_KEY_KP_SUBTRACT',['../group__keys.html#gaa3dbd60782ff93d6082a124bce1fa236',1,'glfw3.h']]], + ['glfw_5fkey_5fl_223',['GLFW_KEY_L',['../group__keys.html#gaaa8b54a13f6b1eed85ac86f82d550db2',1,'glfw3.h']]], + ['glfw_5fkey_5flast_224',['GLFW_KEY_LAST',['../group__keys.html#ga442cbaef7bfb9a4ba13594dd7fbf2789',1,'glfw3.h']]], + ['glfw_5fkey_5fleft_225',['GLFW_KEY_LEFT',['../group__keys.html#gae12a010d33c309a67ab9460c51eb2462',1,'glfw3.h']]], + ['glfw_5fkey_5fleft_5falt_226',['GLFW_KEY_LEFT_ALT',['../group__keys.html#ga7f27dabf63a7789daa31e1c96790219b',1,'glfw3.h']]], + ['glfw_5fkey_5fleft_5fbracket_227',['GLFW_KEY_LEFT_BRACKET',['../group__keys.html#gad1c8d9adac53925276ecb1d592511d8a',1,'glfw3.h']]], + ['glfw_5fkey_5fleft_5fcontrol_228',['GLFW_KEY_LEFT_CONTROL',['../group__keys.html#ga9f97b743e81460ac4b2deddecd10a464',1,'glfw3.h']]], + ['glfw_5fkey_5fleft_5fshift_229',['GLFW_KEY_LEFT_SHIFT',['../group__keys.html#ga8a530a28a65c44ab5d00b759b756d3f6',1,'glfw3.h']]], + ['glfw_5fkey_5fleft_5fsuper_230',['GLFW_KEY_LEFT_SUPER',['../group__keys.html#gafb1207c91997fc295afd1835fbc5641a',1,'glfw3.h']]], + ['glfw_5fkey_5fm_231',['GLFW_KEY_M',['../group__keys.html#ga4d7f0260c82e4ea3d6ebc7a21d6e3716',1,'glfw3.h']]], + ['glfw_5fkey_5fmenu_232',['GLFW_KEY_MENU',['../group__keys.html#ga9845be48a745fc232045c9ec174d8820',1,'glfw3.h']]], + ['glfw_5fkey_5fminus_233',['GLFW_KEY_MINUS',['../group__keys.html#gac556b360f7f6fca4b70ba0aecf313fd4',1,'glfw3.h']]], + ['glfw_5fkey_5fn_234',['GLFW_KEY_N',['../group__keys.html#gae00856dfeb5d13aafebf59d44de5cdda',1,'glfw3.h']]], + ['glfw_5fkey_5fnum_5flock_235',['GLFW_KEY_NUM_LOCK',['../group__keys.html#ga3946edc362aeff213b2be6304296cf43',1,'glfw3.h']]], + ['glfw_5fkey_5fo_236',['GLFW_KEY_O',['../group__keys.html#gaecbbb79130df419d58dd7f09a169efe9',1,'glfw3.h']]], + ['glfw_5fkey_5fp_237',['GLFW_KEY_P',['../group__keys.html#ga8fc15819c1094fb2afa01d84546b33e1',1,'glfw3.h']]], + ['glfw_5fkey_5fpage_5fdown_238',['GLFW_KEY_PAGE_DOWN',['../group__keys.html#gaee0a8fa442001cc2147812f84b59041c',1,'glfw3.h']]], + ['glfw_5fkey_5fpage_5fup_239',['GLFW_KEY_PAGE_UP',['../group__keys.html#ga3ab731f9622f0db280178a5f3cc6d586',1,'glfw3.h']]], + ['glfw_5fkey_5fpause_240',['GLFW_KEY_PAUSE',['../group__keys.html#ga8116b9692d87382afb5849b6d8907f18',1,'glfw3.h']]], + ['glfw_5fkey_5fperiod_241',['GLFW_KEY_PERIOD',['../group__keys.html#ga37e296b650eab419fc474ff69033d927',1,'glfw3.h']]], + ['glfw_5fkey_5fprint_5fscreen_242',['GLFW_KEY_PRINT_SCREEN',['../group__keys.html#gaf964c2e65e97d0cf785a5636ee8df642',1,'glfw3.h']]], + ['glfw_5fkey_5fq_243',['GLFW_KEY_Q',['../group__keys.html#gafdd01e38b120d67cf51e348bb47f3964',1,'glfw3.h']]], + ['glfw_5fkey_5fr_244',['GLFW_KEY_R',['../group__keys.html#ga4ce6c70a0c98c50b3fe4ab9a728d4d36',1,'glfw3.h']]], + ['glfw_5fkey_5fright_245',['GLFW_KEY_RIGHT',['../group__keys.html#ga06ba07662e8c291a4a84535379ffc7ac',1,'glfw3.h']]], + ['glfw_5fkey_5fright_5falt_246',['GLFW_KEY_RIGHT_ALT',['../group__keys.html#ga687b38009131cfdd07a8d05fff8fa446',1,'glfw3.h']]], + ['glfw_5fkey_5fright_5fbracket_247',['GLFW_KEY_RIGHT_BRACKET',['../group__keys.html#ga86ef225fd6a66404caae71044cdd58d8',1,'glfw3.h']]], + ['glfw_5fkey_5fright_5fcontrol_248',['GLFW_KEY_RIGHT_CONTROL',['../group__keys.html#gad1ca2094b2694e7251d0ab1fd34f8519',1,'glfw3.h']]], + ['glfw_5fkey_5fright_5fshift_249',['GLFW_KEY_RIGHT_SHIFT',['../group__keys.html#gaffca36b99c9dce1a19cb9befbadce691',1,'glfw3.h']]], + ['glfw_5fkey_5fright_5fsuper_250',['GLFW_KEY_RIGHT_SUPER',['../group__keys.html#gad4547a3e8e247594acb60423fe6502db',1,'glfw3.h']]], + ['glfw_5fkey_5fs_251',['GLFW_KEY_S',['../group__keys.html#ga1570e2ccaab036ea82bed66fc1dab2a9',1,'glfw3.h']]], + ['glfw_5fkey_5fscroll_5flock_252',['GLFW_KEY_SCROLL_LOCK',['../group__keys.html#gaf622b63b9537f7084c2ab649b8365630',1,'glfw3.h']]], + ['glfw_5fkey_5fsemicolon_253',['GLFW_KEY_SEMICOLON',['../group__keys.html#ga84233de9ee5bb3e8788a5aa07d80af7d',1,'glfw3.h']]], + ['glfw_5fkey_5fslash_254',['GLFW_KEY_SLASH',['../group__keys.html#gadf3d753b2d479148d711de34b83fd0db',1,'glfw3.h']]], + ['glfw_5fkey_5fspace_255',['GLFW_KEY_SPACE',['../group__keys.html#gaddb2c23772b97fd7e26e8ee66f1ad014',1,'glfw3.h']]], + ['glfw_5fkey_5ft_256',['GLFW_KEY_T',['../group__keys.html#ga90e0560422ec7a30e7f3f375bc9f37f9',1,'glfw3.h']]], + ['glfw_5fkey_5ftab_257',['GLFW_KEY_TAB',['../group__keys.html#ga6908a4bda9950a3e2b73f794bbe985df',1,'glfw3.h']]], + ['glfw_5fkey_5fu_258',['GLFW_KEY_U',['../group__keys.html#gacad52f3bf7d378fc0ffa72a76769256d',1,'glfw3.h']]], + ['glfw_5fkey_5funknown_259',['GLFW_KEY_UNKNOWN',['../group__input.html#ga99aacc875b6b27a072552631e13775c7',1,'glfw3.h']]], + ['glfw_5fkey_5fup_260',['GLFW_KEY_UP',['../group__keys.html#ga2f3342b194020d3544c67e3506b6f144',1,'glfw3.h']]], + ['glfw_5fkey_5fv_261',['GLFW_KEY_V',['../group__keys.html#ga22c7763899ecf7788862e5f90eacce6b',1,'glfw3.h']]], + ['glfw_5fkey_5fw_262',['GLFW_KEY_W',['../group__keys.html#gaa06a712e6202661fc03da5bdb7b6e545',1,'glfw3.h']]], + ['glfw_5fkey_5fworld_5f1_263',['GLFW_KEY_WORLD_1',['../group__keys.html#gadc78dad3dab76bcd4b5c20114052577a',1,'glfw3.h']]], + ['glfw_5fkey_5fworld_5f2_264',['GLFW_KEY_WORLD_2',['../group__keys.html#ga20494bfebf0bb4fc9503afca18ab2c5e',1,'glfw3.h']]], + ['glfw_5fkey_5fx_265',['GLFW_KEY_X',['../group__keys.html#gac1c42c0bf4192cea713c55598b06b744',1,'glfw3.h']]], + ['glfw_5fkey_5fy_266',['GLFW_KEY_Y',['../group__keys.html#gafd9f115a549effdf8e372a787c360313',1,'glfw3.h']]], + ['glfw_5fkey_5fz_267',['GLFW_KEY_Z',['../group__keys.html#gac489e208c26afda8d4938ed88718760a',1,'glfw3.h']]], + ['glfw_5flock_5fkey_5fmods_268',['GLFW_LOCK_KEY_MODS',['../glfw3_8h.html#a07b84de0b52143e1958f88a7d9105947',1,'glfw3.h']]], + ['glfw_5flose_5fcontext_5fon_5freset_269',['GLFW_LOSE_CONTEXT_ON_RESET',['../glfw3_8h.html#aec1132f245143fc915b2f0995228564c',1,'glfw3.h']]], + ['glfw_5fmaximized_270',['GLFW_MAXIMIZED',['../group__window.html#gad8ccb396253ad0b72c6d4c917eb38a03',1,'glfw3.h']]], + ['glfw_5fmod_5falt_271',['GLFW_MOD_ALT',['../group__mods.html#gad2acd5633463c29e07008687ea73c0f4',1,'glfw3.h']]], + ['glfw_5fmod_5fcaps_5flock_272',['GLFW_MOD_CAPS_LOCK',['../group__mods.html#gaefeef8fcf825a6e43e241b337897200f',1,'glfw3.h']]], + ['glfw_5fmod_5fcontrol_273',['GLFW_MOD_CONTROL',['../group__mods.html#ga6ed94871c3208eefd85713fa929d45aa',1,'glfw3.h']]], + ['glfw_5fmod_5fnum_5flock_274',['GLFW_MOD_NUM_LOCK',['../group__mods.html#ga64e020b8a42af8376e944baf61feecbe',1,'glfw3.h']]], + ['glfw_5fmod_5fshift_275',['GLFW_MOD_SHIFT',['../group__mods.html#ga14994d3196c290aaa347248e51740274',1,'glfw3.h']]], + ['glfw_5fmod_5fsuper_276',['GLFW_MOD_SUPER',['../group__mods.html#ga6b64ba10ea0227cf6f42efd0a220aba1',1,'glfw3.h']]], + ['glfw_5fmouse_5fbutton_5f1_277',['GLFW_MOUSE_BUTTON_1',['../group__buttons.html#ga181a6e875251fd8671654eff00f9112e',1,'glfw3.h']]], + ['glfw_5fmouse_5fbutton_5f2_278',['GLFW_MOUSE_BUTTON_2',['../group__buttons.html#ga604b39b92c88ce9bd332e97fc3f4156c',1,'glfw3.h']]], + ['glfw_5fmouse_5fbutton_5f3_279',['GLFW_MOUSE_BUTTON_3',['../group__buttons.html#ga0130d505563d0236a6f85545f19e1721',1,'glfw3.h']]], + ['glfw_5fmouse_5fbutton_5f4_280',['GLFW_MOUSE_BUTTON_4',['../group__buttons.html#ga53f4097bb01d5521c7d9513418c91ca9',1,'glfw3.h']]], + ['glfw_5fmouse_5fbutton_5f5_281',['GLFW_MOUSE_BUTTON_5',['../group__buttons.html#gaf08c4ddecb051d3d9667db1d5e417c9c',1,'glfw3.h']]], + ['glfw_5fmouse_5fbutton_5f6_282',['GLFW_MOUSE_BUTTON_6',['../group__buttons.html#gae8513e06aab8aa393b595f22c6d8257a',1,'glfw3.h']]], + ['glfw_5fmouse_5fbutton_5f7_283',['GLFW_MOUSE_BUTTON_7',['../group__buttons.html#ga8b02a1ab55dde45b3a3883d54ffd7dc7',1,'glfw3.h']]], + ['glfw_5fmouse_5fbutton_5f8_284',['GLFW_MOUSE_BUTTON_8',['../group__buttons.html#ga35d5c4263e0dc0d0a4731ca6c562f32c',1,'glfw3.h']]], + ['glfw_5fmouse_5fbutton_5flast_285',['GLFW_MOUSE_BUTTON_LAST',['../group__buttons.html#gab1fd86a4518a9141ec7bcde2e15a2fdf',1,'glfw3.h']]], + ['glfw_5fmouse_5fbutton_5fleft_286',['GLFW_MOUSE_BUTTON_LEFT',['../group__buttons.html#gaf37100431dcd5082d48f95ee8bc8cd56',1,'glfw3.h']]], + ['glfw_5fmouse_5fbutton_5fmiddle_287',['GLFW_MOUSE_BUTTON_MIDDLE',['../group__buttons.html#ga34a4d2a701434f763fd93a2ff842b95a',1,'glfw3.h']]], + ['glfw_5fmouse_5fbutton_5fright_288',['GLFW_MOUSE_BUTTON_RIGHT',['../group__buttons.html#ga3e2f2cf3c4942df73cc094247d275e74',1,'glfw3.h']]], + ['glfw_5fmouse_5fpassthrough_289',['GLFW_MOUSE_PASSTHROUGH',['../group__window.html#ga88981797d29800808ec242274ab5c03a',1,'glfw3.h']]], + ['glfw_5fnative_5fcontext_5fapi_290',['GLFW_NATIVE_CONTEXT_API',['../glfw3_8h.html#a0494c9bfd3f584ab41e6dbeeaa0e6a19',1,'glfw3.h']]], + ['glfw_5fno_5fapi_291',['GLFW_NO_API',['../glfw3_8h.html#a8f6dcdc968d214ff14779564f1389264',1,'glfw3.h']]], + ['glfw_5fno_5fcurrent_5fcontext_292',['GLFW_NO_CURRENT_CONTEXT',['../group__errors.html#gaa8290386e9528ccb9e42a3a4e16fc0d0',1,'glfw3.h']]], + ['glfw_5fno_5ferror_293',['GLFW_NO_ERROR',['../group__errors.html#gafa30deee5db4d69c4c93d116ed87dbf4',1,'glfw3.h']]], + ['glfw_5fno_5freset_5fnotification_294',['GLFW_NO_RESET_NOTIFICATION',['../glfw3_8h.html#aee84a679230d205005e22487ff678a85',1,'glfw3.h']]], + ['glfw_5fno_5frobustness_295',['GLFW_NO_ROBUSTNESS',['../glfw3_8h.html#a8b306cb27f5bb0d6d67c7356a0e0fc34',1,'glfw3.h']]], + ['glfw_5fno_5fwindow_5fcontext_296',['GLFW_NO_WINDOW_CONTEXT',['../group__errors.html#gacff24d2757da752ae4c80bf452356487',1,'glfw3.h']]], + ['glfw_5fnot_5fallowed_5fcursor_297',['GLFW_NOT_ALLOWED_CURSOR',['../group__shapes.html#ga297c503095b034bc8891393b637844b1',1,'glfw3.h']]], + ['glfw_5fnot_5finitialized_298',['GLFW_NOT_INITIALIZED',['../group__errors.html#ga2374ee02c177f12e1fa76ff3ed15e14a',1,'glfw3.h']]], + ['glfw_5fopengl_5fany_5fprofile_299',['GLFW_OPENGL_ANY_PROFILE',['../glfw3_8h.html#ad6f2335d6f21cc9bab96633b1c111d5f',1,'glfw3.h']]], + ['glfw_5fopengl_5fapi_300',['GLFW_OPENGL_API',['../glfw3_8h.html#a01b3f66db266341425e9abee6b257db2',1,'glfw3.h']]], + ['glfw_5fopengl_5fcompat_5fprofile_301',['GLFW_OPENGL_COMPAT_PROFILE',['../glfw3_8h.html#ac06b663d79c8fcf04669cc8fcc0b7670',1,'glfw3.h']]], + ['glfw_5fopengl_5fcore_5fprofile_302',['GLFW_OPENGL_CORE_PROFILE',['../glfw3_8h.html#af094bb16da76f66ebceb19ee213b3de8',1,'glfw3.h']]], + ['glfw_5fopengl_5fdebug_5fcontext_303',['GLFW_OPENGL_DEBUG_CONTEXT',['../group__window.html#ga87ec2df0b915201e950ca42d5d0831e1',1,'glfw3.h']]], + ['glfw_5fopengl_5fes_5fapi_304',['GLFW_OPENGL_ES_API',['../glfw3_8h.html#a28d9b3bc6c2a522d815c8e146595051f',1,'glfw3.h']]], + ['glfw_5fopengl_5fforward_5fcompat_305',['GLFW_OPENGL_FORWARD_COMPAT',['../group__window.html#ga13d24b12465da8b28985f46c8557925b',1,'glfw3.h']]], + ['glfw_5fopengl_5fprofile_306',['GLFW_OPENGL_PROFILE',['../group__window.html#ga44f3a6b4261fbe351e0b950b0f372e12',1,'glfw3.h']]], + ['glfw_5fosmesa_5fcontext_5fapi_307',['GLFW_OSMESA_CONTEXT_API',['../glfw3_8h.html#afd34a473af9fa81f317910ea371b19e3',1,'glfw3.h']]], + ['glfw_5fout_5fof_5fmemory_308',['GLFW_OUT_OF_MEMORY',['../group__errors.html#ga9023953a2bcb98c2906afd071d21ee7f',1,'glfw3.h']]], + ['glfw_5fplatform_309',['GLFW_PLATFORM',['../group__init.html#ga9d38bf1fdf4f91d6565401734a7cd967',1,'glfw3.h']]], + ['glfw_5fplatform_5fcocoa_310',['GLFW_PLATFORM_COCOA',['../group__init.html#ga83b18714254f75bc2f0cdbafa0f10b6b',1,'glfw3.h']]], + ['glfw_5fplatform_5ferror_311',['GLFW_PLATFORM_ERROR',['../group__errors.html#gad44162d78100ea5e87cdd38426b8c7a1',1,'glfw3.h']]], + ['glfw_5fplatform_5fnull_312',['GLFW_PLATFORM_NULL',['../group__init.html#gac06fad5a4866ae7a1d7b2675fac72d7f',1,'glfw3.h']]], + ['glfw_5fplatform_5funavailable_313',['GLFW_PLATFORM_UNAVAILABLE',['../group__errors.html#ga3608c6c29ab7a72f3bf019f4c3a2563d',1,'glfw3.h']]], + ['glfw_5fplatform_5fwayland_314',['GLFW_PLATFORM_WAYLAND',['../group__init.html#gac4b08906a3cbf26c518a4a543eedd740',1,'glfw3.h']]], + ['glfw_5fplatform_5fwin32_315',['GLFW_PLATFORM_WIN32',['../group__init.html#ga8d3d17df2ab57492cef665da52c603a1',1,'glfw3.h']]], + ['glfw_5fplatform_5fx11_316',['GLFW_PLATFORM_X11',['../group__init.html#gaf5333f3933e9c248a00cfda6523f386b',1,'glfw3.h']]], + ['glfw_5fpointing_5fhand_5fcursor_317',['GLFW_POINTING_HAND_CURSOR',['../group__shapes.html#gaad01a50929fb515bf27e4462c51f6ed0',1,'glfw3.h']]], + ['glfw_5fposition_5fx_318',['GLFW_POSITION_X',['../group__window.html#gaededa6b208b8e31343da56bb349c6fb2',1,'glfw3.h']]], + ['glfw_5fposition_5fy_319',['GLFW_POSITION_Y',['../group__window.html#ga6b3ccf63683c81f479e2a98f5027200e',1,'glfw3.h']]], + ['glfw_5fpress_320',['GLFW_PRESS',['../group__input.html#ga2485743d0b59df3791c45951c4195265',1,'glfw3.h']]], + ['glfw_5fraw_5fmouse_5fmotion_321',['GLFW_RAW_MOUSE_MOTION',['../glfw3_8h.html#aeeda1be76a44a1fc97c1282e06281fbb',1,'glfw3.h']]], + ['glfw_5fred_5fbits_322',['GLFW_RED_BITS',['../group__window.html#gaf78ed8e417dbcc1e354906cc2708c982',1,'glfw3.h']]], + ['glfw_5frefresh_5frate_323',['GLFW_REFRESH_RATE',['../group__window.html#ga0f20825e6e47ee8ba389024519682212',1,'glfw3.h']]], + ['glfw_5frelease_324',['GLFW_RELEASE',['../group__input.html#gada11d965c4da13090ad336e030e4d11f',1,'glfw3.h']]], + ['glfw_5frelease_5fbehavior_5fflush_325',['GLFW_RELEASE_BEHAVIOR_FLUSH',['../glfw3_8h.html#a999961d391db49cb4f949c1dece0e13b',1,'glfw3.h']]], + ['glfw_5frelease_5fbehavior_5fnone_326',['GLFW_RELEASE_BEHAVIOR_NONE',['../glfw3_8h.html#afca09088eccacdce4b59036cfae349c5',1,'glfw3.h']]], + ['glfw_5frepeat_327',['GLFW_REPEAT',['../group__input.html#gac96fd3b9fc66c6f0eebaf6532595338f',1,'glfw3.h']]], + ['glfw_5fresizable_328',['GLFW_RESIZABLE',['../group__window.html#gadba13c7a1b3aa40831eb2beedbd5bd1d',1,'glfw3.h']]], + ['glfw_5fresize_5fall_5fcursor_329',['GLFW_RESIZE_ALL_CURSOR',['../group__shapes.html#ga3a5f4811155f95ccafbbb4c9a899fc1d',1,'glfw3.h']]], + ['glfw_5fresize_5few_5fcursor_330',['GLFW_RESIZE_EW_CURSOR',['../group__shapes.html#ga2010a43dc1050a7c9154148a63cf01ad',1,'glfw3.h']]], + ['glfw_5fresize_5fnesw_5fcursor_331',['GLFW_RESIZE_NESW_CURSOR',['../group__shapes.html#gab06bba3b407f92807ba9b48de667a323',1,'glfw3.h']]], + ['glfw_5fresize_5fns_5fcursor_332',['GLFW_RESIZE_NS_CURSOR',['../group__shapes.html#gaa59214e8cdc8c8adf08fdf125ed68388',1,'glfw3.h']]], + ['glfw_5fresize_5fnwse_5fcursor_333',['GLFW_RESIZE_NWSE_CURSOR',['../group__shapes.html#gadf2c0a495ec9cef4e1a364cc99aa78da',1,'glfw3.h']]], + ['glfw_5fsamples_334',['GLFW_SAMPLES',['../group__window.html#ga2cdf86fdcb7722fb8829c4e201607535',1,'glfw3.h']]], + ['glfw_5fscale_5fframebuffer_335',['GLFW_SCALE_FRAMEBUFFER',['../group__window.html#gaa5a9c6b4722670fd33d6e8a88f2e21bc',1,'glfw3.h']]], + ['glfw_5fscale_5fto_5fmonitor_336',['GLFW_SCALE_TO_MONITOR',['../group__window.html#ga620bc4280c7eab81ac9f02204500ed47',1,'glfw3.h']]], + ['glfw_5fsrgb_5fcapable_337',['GLFW_SRGB_CAPABLE',['../group__window.html#ga444a8f00414a63220591f9fdb7b5642b',1,'glfw3.h']]], + ['glfw_5fstencil_5fbits_338',['GLFW_STENCIL_BITS',['../group__window.html#ga5339890a45a1fb38e93cb9fcc5fd069d',1,'glfw3.h']]], + ['glfw_5fstereo_339',['GLFW_STEREO',['../group__window.html#ga83d991efca02537e2d69969135b77b03',1,'glfw3.h']]], + ['glfw_5fsticky_5fkeys_340',['GLFW_STICKY_KEYS',['../glfw3_8h.html#ae3bbe2315b7691ab088159eb6c9110fc',1,'glfw3.h']]], + ['glfw_5fsticky_5fmouse_5fbuttons_341',['GLFW_STICKY_MOUSE_BUTTONS',['../glfw3_8h.html#a4d7ce8ce71030c3b04e2b78145bc59d1',1,'glfw3.h']]], + ['glfw_5ftransparent_5fframebuffer_342',['GLFW_TRANSPARENT_FRAMEBUFFER',['../group__window.html#ga60a0578c3b9449027d683a9c6abb9f14',1,'glfw3.h']]], + ['glfw_5ftrue_343',['GLFW_TRUE',['../group__init.html#ga2744fbb29b5631bb28802dbe0cf36eba',1,'glfw3.h']]], + ['glfw_5fuse_5fosmesa_20cmake_20option_20has_20been_20removed_344',['GLFW_USE_OSMESA CMake option has been removed',['../news.html#use_osmesa_removed',1,'']]], + ['glfw_5fuse_5fwayland_20cmake_20option_20has_20been_20removed_345',['GLFW_USE_WAYLAND CMake option has been removed',['../news.html#use_wayland_removed',1,'']]], + ['glfw_5fversion_5fmajor_346',['GLFW_VERSION_MAJOR',['../group__init.html#ga6337d9ea43b22fc529b2bba066b4a576',1,'glfw3.h']]], + ['glfw_5fversion_5fminor_347',['GLFW_VERSION_MINOR',['../group__init.html#gaf80d40f0aea7088ff337606e9c48f7a3',1,'glfw3.h']]], + ['glfw_5fversion_5frevision_348',['GLFW_VERSION_REVISION',['../group__init.html#gab72ae2e2035d9ea461abc3495eac0502',1,'glfw3.h']]], + ['glfw_5fversion_5funavailable_349',['GLFW_VERSION_UNAVAILABLE',['../group__errors.html#gad16c5565b4a69f9c2a9ac2c0dbc89462',1,'glfw3.h']]], + ['glfw_5fvisible_350',['GLFW_VISIBLE',['../group__window.html#gafb3cdc45297e06d8f1eb13adc69ca6c4',1,'glfw3.h']]], + ['glfw_5fvresize_5fcursor_351',['GLFW_VRESIZE_CURSOR',['../group__shapes.html#gaf024f0e1ff8366fb2b5c260509a1fce5',1,'glfw3.h']]], + ['glfw_5fvulkan_5fstatic_20cmake_20option_20has_20been_20removed_352',['GLFW_VULKAN_STATIC CMake option has been removed',['../news.html#vulkan_static_removed',1,'']]], + ['glfw_5fwayland_5fapp_5fid_353',['GLFW_WAYLAND_APP_ID',['../group__window.html#gafbf1ce7a4362c75e602a4df9e1bdecd3',1,'glfw3.h']]], + ['glfw_5fwayland_5fdisable_5flibdecor_354',['GLFW_WAYLAND_DISABLE_LIBDECOR',['../glfw3_8h.html#aadcea7c6afbf86b848404457c4253fd7',1,'glfw3.h']]], + ['glfw_5fwayland_5flibdecor_355',['GLFW_WAYLAND_LIBDECOR',['../group__init.html#ga2a3f2fd7695902c498b050215b3db452',1,'glfw3.h']]], + ['glfw_5fwayland_5fprefer_5flibdecor_356',['GLFW_WAYLAND_PREFER_LIBDECOR',['../glfw3_8h.html#a92b0d7e0eaeeefaccc0ccc2ccb130e99',1,'glfw3.h']]], + ['glfw_5fwin32_5fkeyboard_5fmenu_357',['GLFW_WIN32_KEYBOARD_MENU',['../group__window.html#gaf65ea8dafdc0edb07b821b9a336d5043',1,'glfw3.h']]], + ['glfw_5fwin32_5fshowdefault_358',['GLFW_WIN32_SHOWDEFAULT',['../group__window.html#gace10f3846571de62243b46f75d978487',1,'glfw3.h']]], + ['glfw_5fx11_5fclass_5fname_359',['GLFW_X11_CLASS_NAME',['../group__window.html#gae5a9ea2fccccd92edbd343fc56461114',1,'glfw3.h']]], + ['glfw_5fx11_5finstance_5fname_360',['GLFW_X11_INSTANCE_NAME',['../group__window.html#ga494c3c0d911e4b860b946530a3e389e8',1,'glfw3.h']]], + ['glfw_5fx11_5fxcb_5fvulkan_5fsurface_361',['GLFW_X11_XCB_VULKAN_SURFACE',['../group__init.html#gaa341e303ebeb8e4199b8ab8be84351f6',1,'glfw3.h']]], + ['glfwallocatefun_362',['GLFWallocatefun',['../group__init.html#ga4306a564e9f60f4de8cc8f31731a3120',1,'glfw3.h']]], + ['glfwallocator_363',['glfwallocator',['../group__init.html#ga145c57d7f2aeda0b704a5a4ba1d6104b',1,'GLFWallocator: glfw3.h'],['../struct_g_l_f_wallocator.html',1,'GLFWallocator']]], + ['glfwcall_20macro_364',['Removal of GLFWCALL macro',['../moving_guide.html#moving_stdcall',1,'']]], + ['glfwcharfun_365',['GLFWcharfun',['../group__input.html#ga1ab90a55cf3f58639b893c0f4118cb6e',1,'glfw3.h']]], + ['glfwcharmodsfun_366',['GLFWcharmodsfun',['../group__input.html#gac3cf64f90b6219c05ac7b7822d5a4b8f',1,'glfw3.h']]], + ['glfwcreatecursor_367',['glfwCreateCursor',['../group__input.html#ga556f604f73af156c0db0e97c081373c3',1,'glfw3.h']]], + ['glfwcreatestandardcursor_368',['glfwCreateStandardCursor',['../group__input.html#gaf2fb2eb2c9dd842d1cef8a34e3c6403e',1,'glfw3.h']]], + ['glfwcreatewindow_369',['glfwCreateWindow',['../group__window.html#ga3555a418df92ad53f917597fe2f64aeb',1,'glfw3.h']]], + ['glfwcreatewindowsurface_370',['glfwCreateWindowSurface',['../group__vulkan.html#ga1a24536bec3f80b08ead18e28e6ae965',1,'glfw3.h']]], + ['glfwcursor_371',['GLFWcursor',['../group__input.html#ga89261ae18c75e863aaf2656ecdd238f4',1,'glfw3.h']]], + ['glfwcursorenterfun_372',['GLFWcursorenterfun',['../group__input.html#gaa93dc4818ac9ab32532909d53a337cbe',1,'glfw3.h']]], + ['glfwcursorposfun_373',['GLFWcursorposfun',['../group__input.html#gad6fae41b3ac2e4209aaa87b596c57f68',1,'glfw3.h']]], + ['glfwdeallocatefun_374',['GLFWdeallocatefun',['../group__init.html#ga7181615eda94c4b07bd72bdcee39fa28',1,'glfw3.h']]], + ['glfwdefaultwindowhints_375',['glfwDefaultWindowHints',['../group__window.html#gaa77c4898dfb83344a6b4f76aa16b9a4a',1,'glfw3.h']]], + ['glfwdestroycursor_376',['glfwDestroyCursor',['../group__input.html#ga81b952cd1764274d0db7fb3c5a79ba6a',1,'glfw3.h']]], + ['glfwdestroywindow_377',['glfwDestroyWindow',['../group__window.html#gacdf43e51376051d2c091662e9fe3d7b2',1,'glfw3.h']]], + ['glfwdropfun_378',['GLFWdropfun',['../group__input.html#gaaba73c3274062c18723b7f05862d94b2',1,'glfw3.h']]], + ['glfwerrorfun_379',['GLFWerrorfun',['../group__init.html#ga8184701785c096b3862a75cda1bf44a3',1,'glfw3.h']]], + ['glfwextensionsupported_380',['glfwExtensionSupported',['../group__context.html#ga87425065c011cef1ebd6aac75e059dfa',1,'glfw3.h']]], + ['glfwfocuswindow_381',['glfwFocusWindow',['../group__window.html#ga873780357abd3f3a081d71a40aae45a1',1,'glfw3.h']]], + ['glfwframebuffersizefun_382',['GLFWframebuffersizefun',['../group__window.html#gae18026e294dde685ed2e5f759533144d',1,'glfw3.h']]], + ['glfwgamepadstate_383',['glfwgamepadstate',['../group__input.html#ga61acfb1f28f751438dd221225c5e725d',1,'GLFWgamepadstate: glfw3.h'],['../struct_g_l_f_wgamepadstate.html',1,'GLFWgamepadstate']]], + ['glfwgammaramp_384',['glfwgammaramp',['../struct_g_l_f_wgammaramp.html',1,'GLFWgammaramp'],['../group__monitor.html#ga939cf093cb0af0498b7b54dc2e181404',1,'GLFWgammaramp: glfw3.h']]], + ['glfwgetclipboardstring_385',['glfwGetClipboardString',['../group__input.html#ga71a5b20808ea92193d65c21b82580355',1,'glfw3.h']]], + ['glfwgetcocoamonitor_386',['glfwGetCocoaMonitor',['../group__native.html#gaf22f429aec4b1aab316142d66d9be3e6',1,'glfw3native.h']]], + ['glfwgetcocoaview_387',['glfwGetCocoaView',['../group__native.html#ga7274fb6595894e880fc95dc63156e9b1',1,'glfw3native.h']]], + ['glfwgetcocoawindow_388',['glfwGetCocoaWindow',['../group__native.html#gac3ed9d495d0c2bb9652de5a50c648715',1,'glfw3native.h']]], + ['glfwgetcurrentcontext_389',['glfwGetCurrentContext',['../group__context.html#gad94e80185397a6cf5fe2ab30567af71c',1,'glfw3.h']]], + ['glfwgetcursorpos_390',['glfwGetCursorPos',['../group__input.html#ga01d37b6c40133676b9cea60ca1d7c0cc',1,'glfw3.h']]], + ['glfwgeteglcontext_391',['glfwGetEGLContext',['../group__native.html#ga671c5072becd085f4ab5771a9c8efcf1',1,'glfw3native.h']]], + ['glfwgetegldisplay_392',['glfwGetEGLDisplay',['../group__native.html#ga1cd8d973f47aacb5532d368147cc3138',1,'glfw3native.h']]], + ['glfwgeteglsurface_393',['glfwGetEGLSurface',['../group__native.html#ga2199b36117a6a695fec8441d8052eee6',1,'glfw3native.h']]], + ['glfwgeterror_394',['glfwGetError',['../group__init.html#ga944986b4ec0b928d488141f92982aa18',1,'glfw3.h']]], + ['glfwgetframebuffersize_395',['glfwGetFramebufferSize',['../group__window.html#ga0e2637a4161afb283f5300c7f94785c9',1,'glfw3.h']]], + ['glfwgetgamepadname_396',['glfwGetGamepadName',['../group__input.html#ga8aea73a1a25cc6c0486a617019f56728',1,'glfw3.h']]], + ['glfwgetgamepadstate_397',['glfwGetGamepadState',['../group__input.html#gadccddea8bce6113fa459de379ddaf051',1,'glfw3.h']]], + ['glfwgetgammaramp_398',['glfwGetGammaRamp',['../group__monitor.html#ga76ba90debcf0062b5c4b73052b24f96f',1,'glfw3.h']]], + ['glfwgetglxcontext_399',['glfwGetGLXContext',['../group__native.html#ga62d884114b0abfcdc2930e89f20867e2',1,'glfw3native.h']]], + ['glfwgetglxwindow_400',['glfwGetGLXWindow',['../group__native.html#ga1ed27b8766e859a21381e8f8ce18d049',1,'glfw3native.h']]], + ['glfwgetinputmode_401',['glfwGetInputMode',['../group__input.html#gaf5b859dbe19bdf434e42695ea45cc5f4',1,'glfw3.h']]], + ['glfwgetinstanceprocaddress_402',['glfwGetInstanceProcAddress',['../group__vulkan.html#gadf228fac94c5fd8f12423ec9af9ff1e9',1,'glfw3.h']]], + ['glfwgetjoystickaxes_403',['glfwGetJoystickAxes',['../group__input.html#gaeb1c0191d3140a233a682987c61eb408',1,'glfw3.h']]], + ['glfwgetjoystickbuttons_404',['glfwGetJoystickButtons',['../group__input.html#ga5ffe34739d3dc97efe432ed2d81d9938',1,'glfw3.h']]], + ['glfwgetjoystickguid_405',['glfwGetJoystickGUID',['../group__input.html#ga6659411aec3c7fcef27780e2cb2d9600',1,'glfw3.h']]], + ['glfwgetjoystickhats_406',['glfwGetJoystickHats',['../group__input.html#ga06e660841b3e79c54da4f54a932c5a2c',1,'glfw3.h']]], + ['glfwgetjoystickname_407',['glfwGetJoystickName',['../group__input.html#gac6a8e769e18e0bcfa9097793fc2c3978',1,'glfw3.h']]], + ['glfwgetjoystickuserpointer_408',['glfwGetJoystickUserPointer',['../group__input.html#ga18cefd7265d1fa04f3fd38a6746db5f3',1,'glfw3.h']]], + ['glfwgetkey_409',['glfwGetKey',['../group__input.html#gadd341da06bc8d418b4dc3a3518af9ad2',1,'glfw3.h']]], + ['glfwgetkeyname_410',['glfwGetKeyName',['../group__input.html#gaeaed62e69c3bd62b7ff8f7b19913ce4f',1,'glfw3.h']]], + ['glfwgetkeyscancode_411',['glfwGetKeyScancode',['../group__input.html#ga67ddd1b7dcbbaff03e4a76c0ea67103a',1,'glfw3.h']]], + ['glfwgetmonitorcontentscale_412',['glfwGetMonitorContentScale',['../group__monitor.html#gad3152e84465fa620b601265ebfcdb21b',1,'glfw3.h']]], + ['glfwgetmonitorname_413',['glfwGetMonitorName',['../group__monitor.html#ga7af83e13489d90379588fb331b9e4b68',1,'glfw3.h']]], + ['glfwgetmonitorphysicalsize_414',['glfwGetMonitorPhysicalSize',['../group__monitor.html#ga7d8bffc6c55539286a6bd20d32a8d7ea',1,'glfw3.h']]], + ['glfwgetmonitorpos_415',['glfwGetMonitorPos',['../group__monitor.html#ga102f54e7acc9149edbcf0997152df8c9',1,'glfw3.h']]], + ['glfwgetmonitors_416',['glfwGetMonitors',['../group__monitor.html#ga70b1156d5d24e9928f145d6c864369d2',1,'glfw3.h']]], + ['glfwgetmonitoruserpointer_417',['glfwGetMonitorUserPointer',['../group__monitor.html#ga1adbfbfb8cd58b23cfee82e574fbbdc5',1,'glfw3.h']]], + ['glfwgetmonitorworkarea_418',['glfwGetMonitorWorkarea',['../group__monitor.html#ga7387a3bdb64bfe8ebf2b9e54f5b6c9d0',1,'glfw3.h']]], + ['glfwgetmousebutton_419',['glfwGetMouseButton',['../group__input.html#gac1473feacb5996c01a7a5a33b5066704',1,'glfw3.h']]], + ['glfwgetnsglcontext_420',['glfwGetNSGLContext',['../group__native.html#ga559e002e3cd63c979881770cd4dc63bc',1,'glfw3native.h']]], + ['glfwgetosmesacolorbuffer_421',['glfwGetOSMesaColorBuffer',['../group__native.html#ga3b36e3e3dcf308b776427b6bd73cc132',1,'glfw3native.h']]], + ['glfwgetosmesacontext_422',['glfwGetOSMesaContext',['../group__native.html#ga9e47700080094eb569cb053afaa88773',1,'glfw3native.h']]], + ['glfwgetosmesadepthbuffer_423',['glfwGetOSMesaDepthBuffer',['../group__native.html#ga6b64039ffc88a7a2f57f0956c0c75d53',1,'glfw3native.h']]], + ['glfwgetphysicaldevicepresentationsupport_424',['glfwGetPhysicalDevicePresentationSupport',['../group__vulkan.html#gaff3823355cdd7e2f3f9f4d9ea9518d92',1,'glfw3.h']]], + ['glfwgetplatform_425',['glfwGetPlatform',['../group__init.html#ga6d6a983d38bd4e8fd786d7a9061d399e',1,'glfw3.h']]], + ['glfwgetprimarymonitor_426',['glfwGetPrimaryMonitor',['../group__monitor.html#gac3adb24947eb709e1874028272e5dfc5',1,'glfw3.h']]], + ['glfwgetprocaddress_427',['glfwGetProcAddress',['../group__context.html#ga35f1837e6f666781842483937612f163',1,'glfw3.h']]], + ['glfwgetrequiredinstanceextensions_428',['glfwGetRequiredInstanceExtensions',['../group__vulkan.html#ga99ad342d82f4a3421e2864978cb6d1d6',1,'glfw3.h']]], + ['glfwgettime_429',['glfwGetTime',['../group__input.html#gaa6cf4e7a77158a3b8fd00328b1720a4a',1,'glfw3.h']]], + ['glfwgettimerfrequency_430',['glfwGetTimerFrequency',['../group__input.html#ga3289ee876572f6e91f06df3a24824443',1,'glfw3.h']]], + ['glfwgettimervalue_431',['glfwGetTimerValue',['../group__input.html#ga09b2bd37d328e0b9456c7ec575cc26aa',1,'glfw3.h']]], + ['glfwgetversion_432',['glfwGetVersion',['../group__init.html#ga9f8ffaacf3c269cc48eafbf8b9b71197',1,'glfw3.h']]], + ['glfwgetversionstring_433',['glfwGetVersionString',['../group__init.html#ga026abd003c8e6501981ab1662062f1c0',1,'glfw3.h']]], + ['glfwgetvideomode_434',['glfwGetVideoMode',['../group__monitor.html#gaba376fa7e76634b4788bddc505d6c9d5',1,'glfw3.h']]], + ['glfwgetvideomodes_435',['glfwGetVideoModes',['../group__monitor.html#gad2e24d2843cb7d6c26202cddd530fc1b',1,'glfw3.h']]], + ['glfwgetwaylanddisplay_436',['glfwGetWaylandDisplay',['../group__native.html#gacbe11f93ce20621de82989bbba94e62a',1,'glfw3native.h']]], + ['glfwgetwaylandmonitor_437',['glfwGetWaylandMonitor',['../group__native.html#ga4f16066bd4c59e2f99418adfcb43dd16',1,'glfw3native.h']]], + ['glfwgetwaylandwindow_438',['glfwGetWaylandWindow',['../group__native.html#ga5c597f2841229d9626f0811cca41ceb3',1,'glfw3native.h']]], + ['glfwgetwglcontext_439',['glfwGetWGLContext',['../group__native.html#gadc4010d91d9cc1134d040eeb1202a143',1,'glfw3native.h']]], + ['glfwgetwin32adapter_440',['glfwGetWin32Adapter',['../group__native.html#gad4d3e9242536c0ba6be88a98f4c73a41',1,'glfw3native.h']]], + ['glfwgetwin32monitor_441',['glfwGetWin32Monitor',['../group__native.html#gac845f7dbe4c1d7fdd682a3c6fdae6766',1,'glfw3native.h']]], + ['glfwgetwin32window_442',['glfwGetWin32Window',['../group__native.html#gafe5079aa79038b0079fc09d5f0a8e667',1,'glfw3native.h']]], + ['glfwgetwindowattrib_443',['glfwGetWindowAttrib',['../group__window.html#gacccb29947ea4b16860ebef42c2cb9337',1,'glfw3.h']]], + ['glfwgetwindowcontentscale_444',['glfwGetWindowContentScale',['../group__window.html#gaf5d31de9c19c4f994facea64d2b3106c',1,'glfw3.h']]], + ['glfwgetwindowframesize_445',['glfwGetWindowFrameSize',['../group__window.html#ga1a9fd382058c53101b21cf211898f1f1',1,'glfw3.h']]], + ['glfwgetwindowmonitor_446',['glfwGetWindowMonitor',['../group__window.html#ga4d766499ac02c60f02221a9dfab87299',1,'glfw3.h']]], + ['glfwgetwindowopacity_447',['glfwGetWindowOpacity',['../group__window.html#gad09f0bd7a6307c4533b7061828480a84',1,'glfw3.h']]], + ['glfwgetwindowpos_448',['glfwGetWindowPos',['../group__window.html#ga73cb526c000876fd8ddf571570fdb634',1,'glfw3.h']]], + ['glfwgetwindowsize_449',['glfwGetWindowSize',['../group__window.html#gaeea7cbc03373a41fb51cfbf9f2a5d4c6',1,'glfw3.h']]], + ['glfwgetwindowtitle_450',['glfwGetWindowTitle',['../group__window.html#gac6151765c54b789c4fe66c6bc6215953',1,'glfw3.h']]], + ['glfwgetwindowuserpointer_451',['glfwGetWindowUserPointer',['../group__window.html#gae77a4add0d2023ca21ff1443ced01653',1,'glfw3.h']]], + ['glfwgetx11adapter_452',['glfwGetX11Adapter',['../group__native.html#ga088fbfa80f50569402b41be71ad66e40',1,'glfw3native.h']]], + ['glfwgetx11display_453',['glfwGetX11Display',['../group__native.html#ga6e7822385cc8a1cc3b18f60352830189',1,'glfw3native.h']]], + ['glfwgetx11monitor_454',['glfwGetX11Monitor',['../group__native.html#gab2f8cc043905e9fa9b12bfdbbcfe874c',1,'glfw3native.h']]], + ['glfwgetx11selectionstring_455',['glfwGetX11SelectionString',['../group__native.html#gae084ef64dc0db140b455b1427256d3f7',1,'glfw3native.h']]], + ['glfwgetx11window_456',['glfwGetX11Window',['../group__native.html#ga90ca676322740842db446999a1b1f21d',1,'glfw3native.h']]], + ['glfwglproc_457',['GLFWglproc',['../group__context.html#ga3d47c2d2fbe0be9c505d0e04e91a133c',1,'glfw3.h']]], + ['glfwhidewindow_458',['glfwHideWindow',['../group__window.html#ga49401f82a1ba5f15db5590728314d47c',1,'glfw3.h']]], + ['glfwiconifywindow_459',['glfwIconifyWindow',['../group__window.html#ga1bb559c0ebaad63c5c05ad2a066779c4',1,'glfw3.h']]], + ['glfwimage_460',['glfwimage',['../struct_g_l_f_wimage.html',1,'GLFWimage'],['../group__window.html#ga7cc0a09de172fa7250872046f8c4d2ca',1,'GLFWimage: glfw3.h']]], + ['glfwinit_461',['glfwInit',['../group__init.html#ga317aac130a235ab08c6db0834907d85e',1,'glfw3.h']]], + ['glfwinitallocator_462',['glfwInitAllocator',['../group__init.html#ga9dde93e9891fa7dd17e4194c9f3ae7c6',1,'glfw3.h']]], + ['glfwinithint_463',['glfwInitHint',['../group__init.html#ga110fd1d3f0412822b4f1908c026f724a',1,'glfw3.h']]], + ['glfwinitvulkanloader_464',['glfwInitVulkanLoader',['../group__init.html#ga76af552d0307bb5f7791f245417d4752',1,'glfw3.h']]], + ['glfwjoystickfun_465',['GLFWjoystickfun',['../group__input.html#gaa21ad5986ae9a26077a40142efb56243',1,'glfw3.h']]], + ['glfwjoystickisgamepad_466',['glfwJoystickIsGamepad',['../group__input.html#gad0f676860f329d80f7e47e9f06a96f00',1,'glfw3.h']]], + ['glfwjoystickpresent_467',['glfwJoystickPresent',['../group__input.html#gaed0966cee139d815317f9ffcba64c9f1',1,'glfw3.h']]], + ['glfwkeyfun_468',['GLFWkeyfun',['../group__input.html#ga5bd751b27b90f865d2ea613533f0453c',1,'glfw3.h']]], + ['glfwmakecontextcurrent_469',['glfwMakeContextCurrent',['../group__context.html#ga1c04dc242268f827290fe40aa1c91157',1,'glfw3.h']]], + ['glfwmaximizewindow_470',['glfwMaximizeWindow',['../group__window.html#ga3f541387449d911274324ae7f17ec56b',1,'glfw3.h']]], + ['glfwmonitor_471',['GLFWmonitor',['../group__monitor.html#ga8d9efd1cde9426692c73fe40437d0ae3',1,'glfw3.h']]], + ['glfwmonitorfun_472',['GLFWmonitorfun',['../group__monitor.html#gaabe16caca8dea952504dfdebdf4cd249',1,'glfw3.h']]], + ['glfwmousebuttonfun_473',['GLFWmousebuttonfun',['../group__input.html#ga0184dcb59f6d85d735503dcaae809727',1,'glfw3.h']]], + ['glfwplatformsupported_474',['glfwPlatformSupported',['../group__init.html#ga8785d2b6b36632368d803e78079d38ed',1,'glfw3.h']]], + ['glfwpollevents_475',['glfwPollEvents',['../group__window.html#ga37bd57223967b4211d60ca1a0bf3c832',1,'glfw3.h']]], + ['glfwpostemptyevent_476',['glfwPostEmptyEvent',['../group__window.html#gab5997a25187e9fd5c6f2ecbbc8dfd7e9',1,'glfw3.h']]], + ['glfwrawmousemotionsupported_477',['glfwRawMouseMotionSupported',['../group__input.html#gae4ee0dbd0d256183e1ea4026d897e1c2',1,'glfw3.h']]], + ['glfwreallocatefun_478',['GLFWreallocatefun',['../group__init.html#ga3e88a829615d8efe8bec1746f7309c63',1,'glfw3.h']]], + ['glfwrequestwindowattention_479',['glfwRequestWindowAttention',['../group__window.html#ga2f8d59323fc4692c1d54ba08c863a703',1,'glfw3.h']]], + ['glfwrestorewindow_480',['glfwRestoreWindow',['../group__window.html#ga52527a5904b47d802b6b4bb519cdebc7',1,'glfw3.h']]], + ['glfwscrollfun_481',['GLFWscrollfun',['../group__input.html#gaf656112c33de3efdb227fa58f0134cf5',1,'glfw3.h']]], + ['glfwsetcharcallback_482',['glfwSetCharCallback',['../group__input.html#gab25c4a220fd8f5717718dbc487828996',1,'glfw3.h']]], + ['glfwsetcharmodscallback_483',['glfwSetCharModsCallback',['../group__input.html#ga0b7f4ad13c2b17435ff13b6dcfb4e43c',1,'glfw3.h']]], + ['glfwsetclipboardstring_484',['glfwSetClipboardString',['../group__input.html#gaba1f022c5eb07dfac421df34cdcd31dd',1,'glfw3.h']]], + ['glfwsetcursor_485',['glfwSetCursor',['../group__input.html#gad3b4f38c8d5dae036bc8fa959e18343e',1,'glfw3.h']]], + ['glfwsetcursorentercallback_486',['glfwSetCursorEnterCallback',['../group__input.html#gad27f8ad0142c038a281466c0966817d8',1,'glfw3.h']]], + ['glfwsetcursorpos_487',['glfwSetCursorPos',['../group__input.html#ga04b03af936d906ca123c8f4ee08b39e7',1,'glfw3.h']]], + ['glfwsetcursorposcallback_488',['glfwSetCursorPosCallback',['../group__input.html#gac1f879ab7435d54d4d79bb469fe225d7',1,'glfw3.h']]], + ['glfwsetdropcallback_489',['glfwSetDropCallback',['../group__input.html#gab773f0ee0a07cff77a210cea40bc1f6b',1,'glfw3.h']]], + ['glfwseterrorcallback_490',['glfwSetErrorCallback',['../group__init.html#gaff45816610d53f0b83656092a4034f40',1,'glfw3.h']]], + ['glfwsetframebuffersizecallback_491',['glfwSetFramebufferSizeCallback',['../group__window.html#gab3fb7c3366577daef18c0023e2a8591f',1,'glfw3.h']]], + ['glfwsetgamma_492',['glfwSetGamma',['../group__monitor.html#ga6ac582625c990220785ddd34efa3169a',1,'glfw3.h']]], + ['glfwsetgammaramp_493',['glfwSetGammaRamp',['../group__monitor.html#ga583f0ffd0d29613d8cd172b996bbf0dd',1,'glfw3.h']]], + ['glfwsetinputmode_494',['glfwSetInputMode',['../group__input.html#gaa92336e173da9c8834558b54ee80563b',1,'glfw3.h']]], + ['glfwsetjoystickcallback_495',['glfwSetJoystickCallback',['../group__input.html#ga2f60a0e5b7bd8d1b7344dc0a7cb32b4c',1,'glfw3.h']]], + ['glfwsetjoystickuserpointer_496',['glfwSetJoystickUserPointer',['../group__input.html#ga6b2f72d64d636b48a727b437cbb7489e',1,'glfw3.h']]], + ['glfwsetkeycallback_497',['glfwSetKeyCallback',['../group__input.html#ga1caf18159767e761185e49a3be019f8d',1,'glfw3.h']]], + ['glfwsetmonitorcallback_498',['glfwSetMonitorCallback',['../group__monitor.html#gab39df645587c8518192aa746c2fb06c3',1,'glfw3.h']]], + ['glfwsetmonitoruserpointer_499',['glfwSetMonitorUserPointer',['../group__monitor.html#ga702750e24313a686d3637297b6e85fda',1,'glfw3.h']]], + ['glfwsetmousebuttoncallback_500',['glfwSetMouseButtonCallback',['../group__input.html#ga6ab84420974d812bee700e45284a723c',1,'glfw3.h']]], + ['glfwsetscrollcallback_501',['glfwSetScrollCallback',['../group__input.html#ga571e45a030ae4061f746ed56cb76aede',1,'glfw3.h']]], + ['glfwsettime_502',['glfwSetTime',['../group__input.html#gaf59589ef6e8b8c8b5ad184b25afd4dc0',1,'glfw3.h']]], + ['glfwsetwindowaspectratio_503',['glfwSetWindowAspectRatio',['../group__window.html#ga72ac8cb1ee2e312a878b55153d81b937',1,'glfw3.h']]], + ['glfwsetwindowattrib_504',['glfwSetWindowAttrib',['../group__window.html#gace2afda29b4116ec012e410a6819033e',1,'glfw3.h']]], + ['glfwsetwindowclosecallback_505',['glfwSetWindowCloseCallback',['../group__window.html#gada646d775a7776a95ac000cfc1885331',1,'glfw3.h']]], + ['glfwsetwindowcontentscalecallback_506',['glfwSetWindowContentScaleCallback',['../group__window.html#gaf2832ebb5aa6c252a2d261de002c92d6',1,'glfw3.h']]], + ['glfwsetwindowfocuscallback_507',['glfwSetWindowFocusCallback',['../group__window.html#gac2d83c4a10f071baf841f6730528e66c',1,'glfw3.h']]], + ['glfwsetwindowicon_508',['glfwSetWindowIcon',['../group__window.html#gadd7ccd39fe7a7d1f0904666ae5932dc5',1,'glfw3.h']]], + ['glfwsetwindowiconifycallback_509',['glfwSetWindowIconifyCallback',['../group__window.html#gac793e9efd255567b5fb8b445052cfd3e',1,'glfw3.h']]], + ['glfwsetwindowmaximizecallback_510',['glfwSetWindowMaximizeCallback',['../group__window.html#gacbe64c339fbd94885e62145563b6dc93',1,'glfw3.h']]], + ['glfwsetwindowmonitor_511',['glfwSetWindowMonitor',['../group__window.html#ga81c76c418af80a1cce7055bccb0ae0a7',1,'glfw3.h']]], + ['glfwsetwindowopacity_512',['glfwSetWindowOpacity',['../group__window.html#gac31caeb3d1088831b13d2c8a156802e9',1,'glfw3.h']]], + ['glfwsetwindowpos_513',['glfwSetWindowPos',['../group__window.html#ga1abb6d690e8c88e0c8cd1751356dbca8',1,'glfw3.h']]], + ['glfwsetwindowposcallback_514',['glfwSetWindowPosCallback',['../group__window.html#ga08bdfbba88934f9c4f92fd757979ac74',1,'glfw3.h']]], + ['glfwsetwindowrefreshcallback_515',['glfwSetWindowRefreshCallback',['../group__window.html#ga1c5c7eb889c33c7f4d10dd35b327654e',1,'glfw3.h']]], + ['glfwsetwindowshouldclose_516',['glfwSetWindowShouldClose',['../group__window.html#ga49c449dde2a6f87d996f4daaa09d6708',1,'glfw3.h']]], + ['glfwsetwindowsize_517',['glfwSetWindowSize',['../group__window.html#ga371911f12c74c504dd8d47d832d095cb',1,'glfw3.h']]], + ['glfwsetwindowsizecallback_518',['glfwSetWindowSizeCallback',['../group__window.html#gad91b8b047a0c4c6033c38853864c34f8',1,'glfw3.h']]], + ['glfwsetwindowsizelimits_519',['glfwSetWindowSizeLimits',['../group__window.html#gac314fa6cec7d2d307be9963e2709cc90',1,'glfw3.h']]], + ['glfwsetwindowtitle_520',['glfwSetWindowTitle',['../group__window.html#ga5d877f09e968cef7a360b513306f17ff',1,'glfw3.h']]], + ['glfwsetwindowuserpointer_521',['glfwSetWindowUserPointer',['../group__window.html#ga3d2fc6026e690ab31a13f78bc9fd3651',1,'glfw3.h']]], + ['glfwsetx11selectionstring_522',['glfwSetX11SelectionString',['../group__native.html#ga55f879ab02d93367f966186b6f0133f7',1,'glfw3native.h']]], + ['glfwshowwindow_523',['glfwShowWindow',['../group__window.html#ga61be47917b72536a148300f46494fc66',1,'glfw3.h']]], + ['glfwswapbuffers_524',['glfwSwapBuffers',['../group__window.html#ga15a5a1ee5b3c2ca6b15ca209a12efd14',1,'glfw3.h']]], + ['glfwswapinterval_525',['glfwSwapInterval',['../group__context.html#ga6d4e0cdf151b5e579bd67f13202994ed',1,'glfw3.h']]], + ['glfwterminate_526',['glfwTerminate',['../group__init.html#gaaae48c0a18607ea4a4ba951d939f0901',1,'glfw3.h']]], + ['glfwupdategamepadmappings_527',['glfwUpdateGamepadMappings',['../group__input.html#gaed5104612f2fa8e66aa6e846652ad00f',1,'glfw3.h']]], + ['glfwvidmode_528',['glfwvidmode',['../struct_g_l_f_wvidmode.html',1,'GLFWvidmode'],['../group__monitor.html#ga902c2816ac9b34b757282daab59b2565',1,'GLFWvidmode: glfw3.h']]], + ['glfwvkproc_529',['GLFWvkproc',['../group__vulkan.html#ga70c01918dc9d233a4fbe0681a43018af',1,'glfw3.h']]], + ['glfwvulkansupported_530',['glfwVulkanSupported',['../group__vulkan.html#ga2e7f30931e02464b5bc8d0d4b6f9fe2b',1,'glfw3.h']]], + ['glfwwaitevents_531',['glfwWaitEvents',['../group__window.html#ga554e37d781f0a997656c26b2c56c835e',1,'glfw3.h']]], + ['glfwwaiteventstimeout_532',['glfwWaitEventsTimeout',['../group__window.html#ga605a178db92f1a7f1a925563ef3ea2cf',1,'glfw3.h']]], + ['glfwwindow_533',['GLFWwindow',['../group__window.html#ga3c96d80d363e67d13a41b5d1821f3242',1,'glfw3.h']]], + ['glfwwindowclosefun_534',['GLFWwindowclosefun',['../group__window.html#gabf859b936d80961b7d39013a9694cc3e',1,'glfw3.h']]], + ['glfwwindowcontentscalefun_535',['GLFWwindowcontentscalefun',['../group__window.html#ga77f288a2d04bb3c77c7d9615d08cf70e',1,'glfw3.h']]], + ['glfwwindowfocusfun_536',['GLFWwindowfocusfun',['../group__window.html#gabc58c47e9d93f6eb1862d615c3680f46',1,'glfw3.h']]], + ['glfwwindowhint_537',['glfwWindowHint',['../group__window.html#ga7d9c8c62384b1e2821c4dc48952d2033',1,'glfw3.h']]], + ['glfwwindowhintstring_538',['glfwWindowHintString',['../group__window.html#ga8cb2782861c9d997bcf2dea97f363e5f',1,'glfw3.h']]], + ['glfwwindowiconifyfun_539',['GLFWwindowiconifyfun',['../group__window.html#ga35c658cccba236f26e7adee0e25f6a4f',1,'glfw3.h']]], + ['glfwwindowmaximizefun_540',['GLFWwindowmaximizefun',['../group__window.html#ga3017196fdaec33ac3e095765176c2a90',1,'glfw3.h']]], + ['glfwwindowposfun_541',['GLFWwindowposfun',['../group__window.html#gabe287973a21a8f927cde4db06b8dcbe9',1,'glfw3.h']]], + ['glfwwindowrefreshfun_542',['GLFWwindowrefreshfun',['../group__window.html#ga431663a1427d2eb3a273bc398b6737b5',1,'glfw3.h']]], + ['glfwwindowshouldclose_543',['glfwWindowShouldClose',['../group__window.html#ga24e02fbfefbb81fc45320989f8140ab5',1,'glfw3.h']]], + ['glfwwindowsizefun_544',['GLFWwindowsizefun',['../group__window.html#gaec0282944bb810f6f3163ec02da90350',1,'glfw3.h']]], + ['glu_20header_20inclusion_545',['GLU header inclusion',['../moving_guide.html#moving_glu',1,'']]], + ['glx_20extensions_546',['GLX extensions',['../compat_guide.html#compat_glx',1,'']]], + ['green_547',['green',['../struct_g_l_f_wgammaramp.html#affccc6f5df47820b6562d709da3a5a3a',1,'GLFWgammaramp']]], + ['greenbits_548',['greenBits',['../struct_g_l_f_wvidmode.html#a292fdd281f3485fb3ff102a5bda43faa',1,'GLFWvidmode']]], + ['guarantees_20and_20limitations_549',['Guarantees and limitations',['../intro_guide.html#guarantees_limitations',1,'']]], + ['gui_550',['Generating with the CMake GUI',['../compile_guide.html#compile_generate_gui',1,'']]], + ['guide_551',['guide',['../context_guide.html',1,'Context guide'],['../input_guide.html',1,'Input guide'],['../monitor_guide.html',1,'Monitor guide'],['../vulkan_guide.html',1,'Vulkan guide'],['../window_guide.html',1,'Window guide']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_e.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_e.js new file mode 100644 index 0000000..17045f5 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_e.js @@ -0,0 +1,23 @@ +var searchData= +[ + ['h_20header_0',['The glext.h header',['../context_guide.html#context_glext_header',1,'']]], + ['handle_20parameters_1',['Window handle parameters',['../moving_guide.html#moving_window_handles',1,'']]], + ['handling_2',['Error handling',['../intro_guide.html#error_handling',1,'']]], + ['hard_20and_20soft_20constraints_3',['Hard and soft constraints',['../window_guide.html#window_hints_hard',1,'']]], + ['has_20been_20changed_4',['Version string format has been changed',['../news.html#version_string_caveat',1,'']]], + ['has_20been_20removed_5',['has been removed',['../news.html#use_osmesa_removed',1,'GLFW_USE_OSMESA CMake option has been removed'],['../news.html#use_wayland_removed',1,'GLFW_USE_WAYLAND CMake option has been removed'],['../news.html#vulkan_static_removed',1,'GLFW_VULKAN_STATIC CMake option has been removed'],['../news.html#corevideo_caveat',1,'macOS CoreVideo dependency has been removed'],['../news.html#wl_shell_removed',1,'wl_shell protocol support has been removed']]], + ['hat_20states_6',['hat states',['../group__hat__state.html',1,'Joystick hat states'],['../input_guide.html#joystick_hat',1,'Joystick hat states']]], + ['header_7',['header',['../quick_guide.html#quick_include',1,'Including the GLFW header'],['../context_guide.html#context_glext_header',1,'The glext.h header']]], + ['header_20file_8',['header file',['../build_guide.html#build_include',1,'Including the GLFW header file'],['../vulkan_guide.html#vulkan_include',1,'Including the Vulkan header file'],['../moving_guide.html#moving_renamed_files',1,'Renamed library and header file']]], + ['header_20inclusion_9',['GLU header inclusion',['../moving_guide.html#moving_glu',1,'']]], + ['header_20is_20no_20longer_20generated_10',['Configuration header is no longer generated',['../news.html#config_header_caveat',1,'']]], + ['header_20option_20macros_11',['GLFW header option macros',['../build_guide.html#build_macros',1,'']]], + ['heap_20memory_20allocator_12',['heap memory allocator',['../intro_guide.html#init_allocator',1,'Custom heap memory allocator'],['../news.html#custom_heap_allocator',1,'Support for custom heap memory allocator']]], + ['height_13',['height',['../struct_g_l_f_wimage.html#a0b7d95368f0c80d5e5c9875057c7dbec',1,'GLFWimage::height'],['../struct_g_l_f_wvidmode.html#ac65942a5f6981695517437a9d571d03c',1,'GLFWvidmode::height']]], + ['hint_14',['hint',['../news.html#angle_renderer_hint',1,'ANGLE rendering backend hint'],['../news.html#wayland_app_id_hint',1,'Wayland surface app_id hint'],['../news.html#win32_showdefault_hint',1,'Windows STARTUPINFO show command hint'],['../news.html#win32_keymenu_hint',1,'Windows window menu keyboard access hint'],['../news.html#x11_xcb_vulkan_surface',1,'X11 Vulkan window surface hint']]], + ['hint_20for_20framebuffer_20scaling_15',['Window hint for framebuffer scaling',['../news.html#scale_framebuffer_hint',1,'']]], + ['hints_16',['hints',['../context_guide.html#context_hints',1,'Context creation hints'],['../window_guide.html#window_hints_ctx',1,'Context related hints'],['../window_guide.html#window_hints_fb',1,'Framebuffer related hints'],['../intro_guide.html#init_hints',1,'Initialization hints'],['../window_guide.html#window_hints_osx',1,'macOS specific hints'],['../intro_guide.html#init_hints_osx',1,'macOS specific init hints'],['../window_guide.html#window_hints_mtr',1,'Monitor related hints'],['../moving_guide.html#moving_hints',1,'Persistent window hints'],['../intro_guide.html#init_hints_shared',1,'Shared init hints'],['../intro_guide.html#init_hints_wayland',1,'Wayland specific init hints'],['../window_guide.html#window_hints_wayland',1,'Wayland specific window hints'],['../window_guide.html#window_hints_win32',1,'Win32 specific hints'],['../window_guide.html#window_hints',1,'Window creation hints'],['../window_guide.html#window_hints_wnd',1,'Window related hints'],['../intro_guide.html#init_hints_x11',1,'X11 specific init hints'],['../window_guide.html#window_hints_x11',1,'X11 specific window hints']]], + ['hints_20for_20initial_20window_20position_17',['Window hints for initial window position',['../news.html#window_position_hint',1,'']]], + ['hotkeys_18',['Capture of system-wide hotkeys',['../moving_guide.html#moving_syskeys',1,'']]], + ['human_20readable_20name_19',['Human-readable name',['../monitor_guide.html#monitor_name',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/all_f.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_f.js new file mode 100644 index 0000000..2d711cf --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/all_f.js @@ -0,0 +1,40 @@ +var searchData= +[ + ['icon_0',['Window icon',['../window_guide.html#window_icon',1,'']]], + ['iconification_1',['Window iconification',['../window_guide.html#window_iconify',1,'']]], + ['image_20and_20texture_20loading_2',['Removal of image and texture loading',['../moving_guide.html#moving_image',1,'']]], + ['including_20the_20glfw_20header_3',['Including the GLFW header',['../quick_guide.html#quick_include',1,'']]], + ['including_20the_20glfw_20header_20file_4',['Including the GLFW header file',['../build_guide.html#build_include',1,'']]], + ['including_20the_20vulkan_20header_20file_5',['Including the Vulkan header file',['../vulkan_guide.html#vulkan_include',1,'']]], + ['inclusion_6',['GLU header inclusion',['../moving_guide.html#moving_glu',1,'']]], + ['init_20hints_7',['init hints',['../intro_guide.html#init_hints_osx',1,'macOS specific init hints'],['../intro_guide.html#init_hints_shared',1,'Shared init hints'],['../intro_guide.html#init_hints_wayland',1,'Wayland specific init hints'],['../intro_guide.html#init_hints_x11',1,'X11 specific init hints']]], + ['initial_20window_20position_8',['Window hints for initial window position',['../news.html#window_position_hint',1,'']]], + ['initialization_9',['macOS main menu now created at initialization',['../news.html#macos_menu_caveat',1,'']]], + ['initialization_20and_20termination_10',['Initialization and termination',['../intro_guide.html#intro_init',1,'']]], + ['initialization_20hints_11',['Initialization hints',['../intro_guide.html#init_hints',1,'']]], + ['initialization_20version_20and_20error_20reference_12',['Initialization, version and error reference',['../group__init.html',1,'']]], + ['initialized_20on_20demand_13',['Joystick support is initialized on demand',['../news.html#joystick_init_caveat',1,'']]], + ['initializing_20and_20terminating_20glfw_14',['Initializing and terminating GLFW',['../quick_guide.html#quick_init_term',1,'']]], + ['initializing_20glfw_15',['Initializing GLFW',['../intro_guide.html#intro_init_init',1,'']]], + ['input_16',['input',['../input_guide.html#gamepad',1,'Gamepad input'],['../input_guide.html#joystick',1,'Joystick input'],['../input_guide.html#input_key',1,'Key input'],['../input_guide.html#input_keyboard',1,'Keyboard input'],['../input_guide.html#input_mouse_button',1,'Mouse button input'],['../input_guide.html#input_mouse',1,'Mouse input'],['../input_guide.html#path_drop',1,'Path drop input'],['../moving_guide.html#moving_keys',1,'Physical key input'],['../input_guide.html#scrolling',1,'Scroll input'],['../input_guide.html#input_char',1,'Text input'],['../input_guide.html#time',1,'Time input']]], + ['input_20and_20output_17',['Clipboard input and output',['../input_guide.html#clipboard',1,'']]], + ['input_20events_18',['Receiving input events',['../quick_guide.html#quick_key_input',1,'']]], + ['input_20focus_19',['Window input focus',['../window_guide.html#window_focus',1,'']]], + ['input_20guide_20',['Input guide',['../input_guide.html',1,'']]], + ['input_20reference_21',['Input reference',['../group__input.html',1,'']]], + ['input_2emd_22',['input.md',['../input_8md.html',1,'']]], + ['installed_20glfw_20binaries_23',['With CMake and installed GLFW binaries',['../build_guide.html#build_link_cmake_package',1,'']]], + ['installing_20dependencies_24',['Installing dependencies',['../compile_guide.html#compile_deps',1,'']]], + ['interface_25',['interface',['../internals_guide.html#internals_event',1,'Event interface'],['../internals_guide.html#internals_internal',1,'Internal interface'],['../internals_guide.html#internals_native',1,'Native interface'],['../internals_guide.html#internals_platform',1,'Platform interface'],['../internals_guide.html#internals_public',1,'Public interface']]], + ['internal_20interface_26',['Internal interface',['../internals_guide.html#internals_internal',1,'']]], + ['internal_20structure_27',['Internal structure',['../internals_guide.html',1,'']]], + ['internal_2emd_28',['internal.md',['../internal_8md.html',1,'']]], + ['intro_2emd_29',['intro.md',['../intro_8md.html',1,'']]], + ['introduction_30',['Introduction',['../index.html',1,'']]], + ['introduction_20to_20the_20api_31',['Introduction to the API',['../intro_guide.html',1,'']]], + ['ipc_20standards_32',['ipc standards',['../compat_guide.html#compat_wayland',1,'Wayland protocols and IPC standards'],['../compat_guide.html#compat_x11',1,'X11 extensions, protocols and IPC standards']]], + ['is_20deprecated_33',['is deprecated',['../news.html#mingw_deprecated',1,'Original MinGW support is deprecated'],['../news.html#yosemite_deprecated',1,'OS X Yosemite support is deprecated'],['../news.html#winxp_deprecated',1,'Windows XP and Vista support is deprecated']]], + ['is_20initialized_20on_20demand_34',['Joystick support is initialized on demand',['../news.html#joystick_init_caveat',1,'']]], + ['is_20no_20longer_20generated_35',['Configuration header is no longer generated',['../news.html#config_header_caveat',1,'']]], + ['it_20together_36',['Putting it together',['../quick_guide.html#quick_example',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/classes_0.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/classes_0.js new file mode 100644 index 0000000..4f9428c --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/classes_0.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['glfwallocator_0',['GLFWallocator',['../struct_g_l_f_wallocator.html',1,'']]], + ['glfwgamepadstate_1',['GLFWgamepadstate',['../struct_g_l_f_wgamepadstate.html',1,'']]], + ['glfwgammaramp_2',['GLFWgammaramp',['../struct_g_l_f_wgammaramp.html',1,'']]], + ['glfwimage_3',['GLFWimage',['../struct_g_l_f_wimage.html',1,'']]], + ['glfwvidmode_4',['GLFWvidmode',['../struct_g_l_f_wvidmode.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/search/close.svg b/src/lib/src/vendor/glfw-3.4/docs/html/search/close.svg similarity index 62% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/search/close.svg rename to src/lib/src/vendor/glfw-3.4/docs/html/search/close.svg index a933eea..337d6cc 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/search/close.svg +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/close.svg @@ -1,27 +1,14 @@ + - - - - image/svg+xml - - - - - + + + + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/mag_d.svg b/src/lib/src/vendor/glfw-3.4/docs/html/search/mag_d.svg new file mode 100644 index 0000000..4122773 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/mag_d.svg @@ -0,0 +1,24 @@ + + + + + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/mag_sel.svg b/src/lib/src/vendor/glfw-3.4/docs/html/search/mag_sel.svg new file mode 100644 index 0000000..553dba8 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/mag_sel.svg @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/mag_seld.svg b/src/lib/src/vendor/glfw-3.4/docs/html/search/mag_seld.svg new file mode 100644 index 0000000..c906f84 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/mag_seld.svg @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_0.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_0.js new file mode 100644 index 0000000..ccae2b5 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['2_20to_203_0',['Moving from GLFW 2 to 3',['../moving_guide.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_1.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_1.js new file mode 100644 index 0000000..162a517 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['3_0',['Moving from GLFW 2 to 3',['../moving_guide.html',1,'']]], + ['3_204_1',['Release notes for version 3.4',['../news.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_10.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_10.js new file mode 100644 index 0000000..3bfc205 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_10.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['version_203_204_0',['Release notes for version 3.4',['../news.html',1,'']]], + ['vulkan_20guide_1',['Vulkan guide',['../vulkan_guide.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_a.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_11.js similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_a.js rename to src/lib/src/vendor/glfw-3.4/docs/html/search/pages_11.js diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_2.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_2.js new file mode 100644 index 0000000..090f8b6 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['4_0',['Release notes for version 3.4',['../news.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_3.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_3.js new file mode 100644 index 0000000..9485b20 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['api_0',['Introduction to the API',['../intro_guide.html',1,'']]], + ['applications_1',['Building applications',['../build_guide.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_0.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_4.js similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_0.js rename to src/lib/src/vendor/glfw-3.4/docs/html/search/pages_4.js diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_5.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_5.js new file mode 100644 index 0000000..330a8a0 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_5.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['compiling_20glfw_0',['Compiling GLFW',['../compile_guide.html',1,'']]], + ['conformance_1',['Standards conformance',['../compat_guide.html',1,'']]], + ['context_20guide_2',['Context guide',['../context_guide.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_3.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_6.js similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/search/all_3.js rename to src/lib/src/vendor/glfw-3.4/docs/html/search/pages_6.js diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_7.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_7.js new file mode 100644 index 0000000..988a598 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_7.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['for_20version_203_204_0',['Release notes for version 3.4',['../news.html',1,'']]], + ['from_20glfw_202_20to_203_1',['Moving from GLFW 2 to 3',['../moving_guide.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_8.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_8.js new file mode 100644 index 0000000..ed2bd32 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_8.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['getting_20started_0',['Getting started',['../quick_guide.html',1,'']]], + ['glfw_1',['Compiling GLFW',['../compile_guide.html',1,'']]], + ['glfw_202_20to_203_2',['Moving from GLFW 2 to 3',['../moving_guide.html',1,'']]], + ['guide_3',['guide',['../context_guide.html',1,'Context guide'],['../input_guide.html',1,'Input guide'],['../monitor_guide.html',1,'Monitor guide'],['../vulkan_guide.html',1,'Vulkan guide'],['../window_guide.html',1,'Window guide']]] +]; diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_4.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_9.js similarity index 62% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_4.js rename to src/lib/src/vendor/glfw-3.4/docs/html/search/pages_9.js index f6548e8..66b7f9d 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_4.js +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_9.js @@ -2,5 +2,6 @@ var searchData= [ ['input_20guide_0',['Input guide',['../input_guide.html',1,'']]], ['internal_20structure_1',['Internal structure',['../internals_guide.html',1,'']]], - ['introduction_20to_20the_20api_2',['Introduction to the API',['../intro_guide.html',1,'']]] + ['introduction_2',['Introduction',['../index.html',1,'']]], + ['introduction_20to_20the_20api_3',['Introduction to the API',['../intro_guide.html',1,'']]] ]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_a.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_a.js new file mode 100644 index 0000000..1ad91e3 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['list_0',['Deprecated List',['../deprecated.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_5.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_b.js similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/search/pages_5.js rename to src/lib/src/vendor/glfw-3.4/docs/html/search/pages_b.js diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_c.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_c.js new file mode 100644 index 0000000..50dbf6f --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_c.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['notes_20for_20version_203_204_0',['Release notes for version 3.4',['../news.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_d.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_d.js new file mode 100644 index 0000000..dae584b --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['release_20notes_20for_20version_203_204_0',['Release notes for version 3.4',['../news.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_e.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_e.js new file mode 100644 index 0000000..cc5f03b --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_e.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['standards_20conformance_0',['Standards conformance',['../compat_guide.html',1,'']]], + ['started_1',['Getting started',['../quick_guide.html',1,'']]], + ['structure_2',['Internal structure',['../internals_guide.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_f.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_f.js new file mode 100644 index 0000000..c66bc52 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/pages_f.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['the_20api_0',['Introduction to the API',['../intro_guide.html',1,'']]], + ['to_203_1',['Moving from GLFW 2 to 3',['../moving_guide.html',1,'']]], + ['to_20the_20api_2',['Introduction to the API',['../intro_guide.html',1,'']]] +]; diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/search/search.css b/src/lib/src/vendor/glfw-3.4/docs/html/search/search.css similarity index 77% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/search/search.css rename to src/lib/src/vendor/glfw-3.4/docs/html/search/search.css index 648a792..d7b0f90 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/search/search.css +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/search.css @@ -1,6 +1,29 @@ -/*---------------- Search Box */ +/*---------------- Search Box positioning */ + +#main-menu > li:last-child { + /* This
  • object is the parent of the search bar */ + display: flex; + justify-content: center; + align-items: center; + height: 36px; + margin-right: 1em; +} + +/*---------------- Search box styling */ + +.SRPage * { + font-weight: normal; + line-height: normal; +} + +dark-mode-toggle { + margin-left: 5px; + display: flex; + float: right; +} #MSearchBox { + display: inline-block; white-space : nowrap; background: white; border-radius: 0.65em; @@ -17,11 +40,24 @@ #MSearchSelect { display: inline-block; vertical-align: middle; + width: 20px; height: 19px; - padding: 0 0 0 0.3em; - margin: 0; + background-image: url('mag_sel.svg'); + margin: 0 0 0 0.3em; + padding: 0; } +#MSearchSelectExt { + display: inline-block; + vertical-align: middle; + width: 10px; + height: 19px; + background-image: url('mag.svg'); + margin: 0 0 0 0.5em; + padding: 0; +} + + #MSearchField { display: inline-block; vertical-align: middle; @@ -33,7 +69,7 @@ border:none; color: #909090; outline: none; - font-family: Arial, Verdana, sans-serif; + font-family: Arial,Verdana,sans-serif; -webkit-border-radius: 0px; border-radius: 0px; background: none; @@ -65,23 +101,15 @@ } #MSearchCloseImg { - height: 1.4em; padding: 0.3em; margin: 0; } .MSearchBoxActive #MSearchField { - color: #000000; + color: black; } -#main-menu > li:last-child { - /* This
  • object is the parent of the search bar */ - display: flex; - justify-content: center; - align-items: center; - height: 36px; - margin-right: 1em; -} + /*---------------- Search filter selection */ @@ -103,7 +131,7 @@ } .SelectItem { - font: 8pt Arial, Verdana, sans-serif; + font: 8pt Arial,Verdana,sans-serif; padding-left: 2px; padding-right: 12px; border: 0px; @@ -111,7 +139,7 @@ span.SelectionMark { margin-right: 4px; - font-family: monospace; + font-family: 'JetBrains Mono',Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace,fixed; outline-style: none; text-decoration: none; } @@ -119,7 +147,7 @@ span.SelectionMark { a.SelectItem { display: block; outline-style: none; - color: #000000; + color: black; text-decoration: none; padding-left: 6px; padding-right: 12px; @@ -127,13 +155,13 @@ a.SelectItem { a.SelectItem:focus, a.SelectItem:active { - color: #000000; + color: black; outline-style: none; text-decoration: none; } a.SelectItem:hover { - color: #FFFFFF; + color: white; background-color: #3D578C; outline-style: none; text-decoration: none; @@ -152,9 +180,12 @@ iframe#MSearchResults { display: none; position: absolute; left: 0; top: 0; - border: 1px solid #000; + border: 1px solid black; background-color: #EEF1F7; z-index:10000; + width: 300px; + height: 400px; + overflow: auto; } /* ----------------------------------- */ @@ -162,7 +193,6 @@ iframe#MSearchResults { #SRIndex { clear:both; - padding-bottom: 15px; } .SREntry { @@ -175,8 +205,9 @@ iframe#MSearchResults { padding: 1px 5px; } -body.SRPage { +div.SRPage { margin: 5px 2px; + background-color: #EEF1F7; } .SRChildren { @@ -188,17 +219,18 @@ body.SRPage { } .SRSymbol { - font-weight: bold; + font-weight: bold; color: #425E97; - font-family: Arial, Verdana, sans-serif; + font-family: Arial,Verdana,sans-serif; text-decoration: none; outline: none; } a.SRScope { display: block; - color: #425E97; - font-family: Arial, Verdana, sans-serif; + color: #425E97; + font-family: Arial,Verdana,sans-serif; + font-size: 8pt; text-decoration: none; outline: none; } @@ -210,14 +242,14 @@ a.SRScope:focus, a.SRScope:active { span.SRScope { padding-left: 4px; - font-family: Arial, Verdana, sans-serif; + font-family: Arial,Verdana,sans-serif; } .SRPage .SRStatus { padding: 2px 5px; font-size: 8pt; font-style: italic; - font-family: Arial, Verdana, sans-serif; + font-family: Arial,Verdana,sans-serif; } .SRResult { @@ -231,10 +263,6 @@ div.searchresults { /*---------------- External search page results */ -.searchresult { - background-color: #F0F3F8; -} - .pages b { color: white; padding: 5px 5px 3px 5px; diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/search/search.js b/src/lib/src/vendor/glfw-3.4/docs/html/search/search.js similarity index 84% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/search/search.js rename to src/lib/src/vendor/glfw-3.4/docs/html/search/search.js index 607f4e1..6fd40c6 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/search/search.js +++ b/src/lib/src/vendor/glfw-3.4/docs/html/search/search.js @@ -73,6 +73,8 @@ function getYPos(item) return y; } +var searchResults = new SearchResults("searchResults"); + /* A class handling everything associated with the search panel. Parameters: @@ -80,7 +82,7 @@ function getYPos(item) storing this instance. Is needed to be able to set timeouts. resultPath - path to use for external files */ -function SearchBox(name, resultsPath, label, extension) +function SearchBox(name, resultsPath, extension) { if (!name || !resultsPath) { alert("Missing parameters to SearchBox."); } if (!extension || extension == "") { extension = ".html"; } @@ -96,7 +98,6 @@ function SearchBox(name, resultsPath, label, extension) this.hideTimeout = 0; this.searchIndex = 0; this.searchActive = false; - this.searchLabel = label; this.extension = extension; // ----------- DOM Elements @@ -155,7 +156,7 @@ function SearchBox(name, resultsPath, label, extension) this.OnSearchSelectHide = function() { - this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()", + this.hideTimeout = setTimeout(this.CloseSelectionWindow.bind(this), this.closeSelectionTimeout); } @@ -188,11 +189,13 @@ function SearchBox(name, resultsPath, label, extension) } else { - window.frames.MSearchResults.postMessage("take_focus", "*"); + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); } } else if (e.keyCode==27) // Escape out of the search field { + e.stopPropagation(); this.DOMSearchField().blur(); this.DOMPopupSearchResultsWindow().style.display = 'none'; this.DOMSearchClose().style.display = 'none'; @@ -209,7 +212,7 @@ function SearchBox(name, resultsPath, label, extension) if (searchValue != "") // non-empty search { // set timer for search update - this.keyTimeout = setTimeout(this.name + '.Search()', + this.keyTimeout = setTimeout(this.Search.bind(this), this.keyTimeoutLength); } else // empty search field @@ -287,6 +290,7 @@ function SearchBox(name, resultsPath, label, extension) } else if (e.keyCode==13 || e.keyCode==27) { + e.stopPropagation(); this.OnSelectItem(this.searchIndex); this.CloseSelectionWindow(); this.DOMSearchField().focus(); @@ -324,48 +328,70 @@ function SearchBox(name, resultsPath, label, extension) idxChar = searchValue.substr(0, 2); } - var resultsPage; - var resultsPageWithSearch; - var hasResultsPage; + var jsFile; var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); if (idx!=-1) { var hexCode=idx.toString(16); - resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + this.extension; - resultsPageWithSearch = resultsPage+'?'+escape(searchValue); - hasResultsPage = true; - } - else // nothing available for this search term - { - resultsPage = this.resultsPath + '/nomatches' + this.extension; - resultsPageWithSearch = resultsPage; - hasResultsPage = false; + jsFile = this.resultsPath + indexSectionNames[this.searchIndex] + '_' + hexCode + '.js'; + } + + var loadJS = function(url, impl, loc){ + var scriptTag = document.createElement('script'); + scriptTag.src = url; + scriptTag.onload = impl; + scriptTag.onreadystatechange = impl; + loc.appendChild(scriptTag); } - window.frames.MSearchResults.location = resultsPageWithSearch; var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + var domSearchBox = this.DOMSearchBox(); + var domPopupSearchResults = this.DOMPopupSearchResults(); + var domSearchClose = this.DOMSearchClose(); + var resultsPath = this.resultsPath; - if (domPopupSearchResultsWindow.style.display!='block') - { - var domSearchBox = this.DOMSearchBox(); - this.DOMSearchClose().style.display = 'inline-block'; - var domPopupSearchResults = this.DOMPopupSearchResults(); - var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; - var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; - domPopupSearchResultsWindow.style.display = 'block'; - left -= domPopupSearchResults.offsetWidth; - var maxWidth = document.body.clientWidth; - var width = 400; - if (left<10) left=10; - if (width+left+8>maxWidth) width=maxWidth-left-8; - domPopupSearchResultsWindow.style.top = top + 'px'; - domPopupSearchResultsWindow.style.left = left + 'px'; - domPopupSearchResultsWindow.style.width = width + 'px'; + var handleResults = function() { + document.getElementById("Loading").style.display="none"; + if (typeof searchData !== 'undefined') { + createResults(resultsPath); + document.getElementById("NoMatches").style.display="none"; + } + + if (idx!=-1) { + searchResults.Search(searchValue); + } else { // no file with search results => force empty search results + searchResults.Search('===='); + } + + if (domPopupSearchResultsWindow.style.display!='block') + { + domSearchClose.style.display = 'inline-block'; + var left = getXPos(domSearchBox) + 150; + var top = getYPos(domSearchBox) + 20; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + var maxWidth = document.body.clientWidth; + var maxHeight = document.body.clientHeight; + var width = 300; + if (left<10) left=10; + if (width+left+8>maxWidth) width=maxWidth-left-8; + var height = 400; + if (height+top+8>maxHeight) height=maxHeight-top-8; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResultsWindow.style.height = height + 'px'; + } + } + + if (jsFile) { + loadJS(jsFile, handleResults, this.DOMPopupSearchResultsWindow()); + } else { + handleResults(); } this.lastSearchValue = searchValue; - this.lastResultsPage = resultsPage; } // -------- Activation Functions @@ -379,22 +405,15 @@ function SearchBox(name, resultsPath, label, extension) ) { this.DOMSearchBox().className = 'MSearchBoxActive'; - - var searchField = this.DOMSearchField(); - - if (searchField.value == this.searchLabel) // clear "Search" term upon entry - { - searchField.value = ''; - this.searchActive = true; - } + this.searchActive = true; } else if (!isActive) // directly remove the panel { this.DOMSearchBox().className = 'MSearchBoxInactive'; - this.DOMSearchField().value = this.searchLabel; this.searchActive = false; this.lastSearchValue = '' this.lastResultsPage = ''; + this.DOMSearchField().value = ''; } } } @@ -623,7 +642,7 @@ function SearchResults(name) } else // return focus to search field { - parent.document.getElementById("MSearchField").focus(); + document.getElementById("MSearchField").focus(); } } else if (this.lastKey==40) // Down @@ -653,8 +672,9 @@ function SearchResults(name) } else if (this.lastKey==27) // Escape { - parent.searchBox.CloseResultsWindow(); - parent.document.getElementById("MSearchField").focus(); + e.stopPropagation(); + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); } else if (this.lastKey==13) // Enter { @@ -696,8 +716,9 @@ function SearchResults(name) } else if (this.lastKey==27) // Escape { - parent.searchBox.CloseResultsWindow(); - parent.document.getElementById("MSearchField").focus(); + e.stopPropagation(); + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); } else if (this.lastKey==13) // Enter { @@ -720,9 +741,10 @@ function setClassAttr(elem,attr) elem.setAttribute('className',attr); } -function createResults() +function createResults(resultsPath) { var results = document.getElementById("SRResults"); + results.innerHTML = ''; for (var e=0; e-{AmhX=Jf@VhhFKy35^fiT zT~&lUj3=cDh^%3HDY9k5CEku}PHXNoNC(_$U3XPb&Q*ME25pT;2(*BOgAf<+R$lzakPG`kF31()Fx{L5Wrac|GQzjeE= zueY1`Ze{#x<8=S|`~MgGetGce)#vN&|J{Cd^tS%;tBYTo?+^d68<#n_Y_xx`J||4O V@QB{^CqU0Kc)I$ztaD0e0svEzbJzd? literal 0 HcmV?d00001 diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wallocator.html b/src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wallocator.html new file mode 100644 index 0000000..c37faab --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wallocator.html @@ -0,0 +1,168 @@ + + + + + + + +GLFW: GLFWallocator Struct Reference + + + + + + + + + + +
    + + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    + +
    GLFWallocator Struct Reference
    +
    +
    + +

    Custom heap memory allocator. + More...

    + + + + + + + + + + +

    +Data Fields

    GLFWallocatefun allocate
     
    GLFWreallocatefun reallocate
     
    GLFWdeallocatefun deallocate
     
    void * user
     
    +

    Detailed Description

    +

    This describes a custom heap memory allocator for GLFW. To set an allocator, pass it to glfwInitAllocator before initializing the library.

    +
    See also
    Custom heap memory allocator
    +
    +glfwInitAllocator
    +
    Since
    Added in version 3.4.
    +

    Field Documentation

    + +

    ◆ allocate

    + +
    +
    + + + + +
    GLFWallocatefun GLFWallocator::allocate
    +
    +

    The memory allocation function. See GLFWallocatefun for details about allocation function.

    + +
    +
    + +

    ◆ reallocate

    + +
    +
    + + + + +
    GLFWreallocatefun GLFWallocator::reallocate
    +
    +

    The memory reallocation function. See GLFWreallocatefun for details about reallocation function.

    + +
    +
    + +

    ◆ deallocate

    + +
    +
    + + + + +
    GLFWdeallocatefun GLFWallocator::deallocate
    +
    +

    The memory deallocation function. See GLFWdeallocatefun for details about deallocation function.

    + +
    +
    + +

    ◆ user

    + +
    +
    + + + + +
    void* GLFWallocator::user
    +
    +

    The user pointer for this custom allocator. This value will be passed to the allocator functions.

    + +
    +
    +
    The documentation for this struct was generated from the following file: +
    + + + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/structGLFWgamepadstate.html b/src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wgamepadstate.html similarity index 72% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/structGLFWgamepadstate.html rename to src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wgamepadstate.html index aa66b91..b5b4f28 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/structGLFWgamepadstate.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wgamepadstate.html @@ -4,7 +4,7 @@ - + GLFW: GLFWgamepadstate Struct Reference @@ -28,10 +28,10 @@ - + @@ -54,9 +54,16 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    @@ -68,26 +75,24 @@ $(function() {

    Gamepad input state. - More...

    - -

    #include <glfw3.h>

    + More...

    - + - +

    Data Fields

    unsigned char buttons [15]
    unsigned char buttons [15]
     
    float axes [6]
    float axes [6]
     

    Detailed Description

    -

    This describes the input state of a gamepad.

    +

    This describes the input state of a gamepad.

    See also
    Gamepad input
    glfwGetGamepadState
    Since
    Added in version 3.3.

    Field Documentation

    -

    ◆ buttons

    +

    ◆ buttons

    @@ -97,12 +102,12 @@ Data Fields
    -

    The states of each gamepad button, GLFW_PRESS or GLFW_RELEASE.

    +

    The states of each gamepad button, GLFW_PRESS or GLFW_RELEASE.

    -

    ◆ axes

    +

    ◆ axes

    @@ -112,7 +117,7 @@ Data Fields
    -

    The states of each gamepad axis, in the range -1.0 to 1.0 inclusive.

    +

    The states of each gamepad axis, in the range -1.0 to 1.0 inclusive.

    @@ -122,7 +127,7 @@ Data Fields
    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/structGLFWgammaramp.html b/src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wgammaramp.html similarity index 69% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/structGLFWgammaramp.html rename to src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wgammaramp.html index 310d1cc..778a222 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/structGLFWgammaramp.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wgammaramp.html @@ -4,7 +4,7 @@ - + GLFW: GLFWgammaramp Struct Reference @@ -28,10 +28,10 @@
    - + @@ -54,9 +54,16 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    @@ -68,23 +75,21 @@ $(function() {

    Gamma ramp. - More...

    - -

    #include <glfw3.h>

    + More...

    - + - + - + - +

    Data Fields

    unsigned short * red
    unsigned short * red
     
    unsigned short * green
    unsigned short * green
     
    unsigned short * blue
    unsigned short * blue
     
    unsigned int size
    unsigned int size
     

    Detailed Description

    -

    This describes the gamma ramp for a monitor.

    +

    This describes the gamma ramp for a monitor.

    See also
    Gamma ramp
    glfwGetGammaRamp
    @@ -93,7 +98,7 @@ Data Fields
    Since
    Added in version 3.0.

    Field Documentation

    -

    ◆ red

    +

    ◆ red

    @@ -103,12 +108,12 @@ Data Fields
    -

    An array of value describing the response of the red channel.

    +

    An array of value describing the response of the red channel.

    -

    ◆ green

    +

    ◆ green

    @@ -118,12 +123,12 @@ Data Fields
    -

    An array of value describing the response of the green channel.

    +

    An array of value describing the response of the green channel.

    -

    ◆ blue

    +

    ◆ blue

    @@ -133,12 +138,12 @@ Data Fields
    -

    An array of value describing the response of the blue channel.

    +

    An array of value describing the response of the blue channel.

    -

    ◆ size

    +

    ◆ size

    @@ -148,7 +153,7 @@ Data Fields
    -

    The number of elements in each array.

    +

    The number of elements in each array.

    @@ -158,7 +163,7 @@ Data Fields
    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/structGLFWimage.html b/src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wimage.html similarity index 71% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/structGLFWimage.html rename to src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wimage.html index 672209d..d3d3225 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/structGLFWimage.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wimage.html @@ -4,7 +4,7 @@ - + GLFW: GLFWimage Struct Reference @@ -28,10 +28,10 @@
    - + @@ -54,9 +54,16 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    @@ -68,28 +75,26 @@ $(function() {

    Image data. - More...

    - -

    #include <glfw3.h>

    + More...

    - + - + - +

    Data Fields

    int width
    int width
     
    int height
    int height
     
    unsigned char * pixels
    unsigned char * pixels
     

    Detailed Description

    -

    This describes a single 2D image. See the documentation for each related function what the expected pixel format is.

    +

    This describes a single 2D image. See the documentation for each related function what the expected pixel format is.

    See also
    Custom cursor creation
    Window icon
    Since
    Added in version 2.1. GLFW 3: Removed format and bytes-per-pixel members.

    Field Documentation

    -

    ◆ width

    +

    ◆ width

    @@ -99,12 +104,12 @@ Data Fields
    -

    The width, in pixels, of this image.

    +

    The width, in pixels, of this image.

    -

    ◆ height

    +

    ◆ height

    @@ -114,12 +119,12 @@ Data Fields
    -

    The height, in pixels, of this image.

    +

    The height, in pixels, of this image.

    -

    ◆ pixels

    +

    ◆ pixels

    @@ -129,7 +134,7 @@ Data Fields
    -

    The pixel data of this image, arranged left-to-right, top-to-bottom.

    +

    The pixel data of this image, arranged left-to-right, top-to-bottom.

    @@ -139,7 +144,7 @@ Data Fields
    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/structGLFWvidmode.html b/src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wvidmode.html similarity index 67% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/structGLFWvidmode.html rename to src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wvidmode.html index c367377..57fe5f8 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/structGLFWvidmode.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/struct_g_l_f_wvidmode.html @@ -4,7 +4,7 @@ - + GLFW: GLFWvidmode Struct Reference @@ -28,10 +28,10 @@
    - + @@ -54,9 +54,16 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    @@ -68,27 +75,25 @@ $(function() {

    Video mode type. - More...

    - -

    #include <glfw3.h>

    + More...

    - + - + - + - + - + - +

    Data Fields

    int width
    int width
     
    int height
    int height
     
    int redBits
    int redBits
     
    int greenBits
    int greenBits
     
    int blueBits
    int blueBits
     
    int refreshRate
    int refreshRate
     

    Detailed Description

    -

    This describes a single video mode.

    +

    This describes a single video mode.

    See also
    Video modes
    glfwGetVideoMode
    @@ -97,7 +102,7 @@ Data Fields
    Since
    Added in version 1.0. GLFW 3: Added refresh rate member.

    Field Documentation

    -

    ◆ width

    +

    ◆ width

    @@ -107,12 +112,12 @@ Data Fields
    -

    The width, in screen coordinates, of the video mode.

    +

    The width, in screen coordinates, of the video mode.

    -

    ◆ height

    +

    ◆ height

    @@ -122,12 +127,12 @@ Data Fields
    -

    The height, in screen coordinates, of the video mode.

    +

    The height, in screen coordinates, of the video mode.

    -

    ◆ redBits

    +

    ◆ redBits

    @@ -137,12 +142,12 @@ Data Fields
    -

    The bit depth of the red channel of the video mode.

    +

    The bit depth of the red channel of the video mode.

    -

    ◆ greenBits

    +

    ◆ greenBits

    @@ -152,12 +157,12 @@ Data Fields
    -

    The bit depth of the green channel of the video mode.

    +

    The bit depth of the green channel of the video mode.

    -

    ◆ blueBits

    +

    ◆ blueBits

    @@ -167,12 +172,12 @@ Data Fields
    -

    The bit depth of the blue channel of the video mode.

    +

    The bit depth of the blue channel of the video mode.

    -

    ◆ refreshRate

    +

    ◆ refreshRate

    @@ -182,7 +187,7 @@ Data Fields
    -

    The refresh rate, in Hz, of the video mode.

    +

    The refresh rate, in Hz, of the video mode.

    @@ -192,7 +197,7 @@ Data Fields
    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/sync_off.png b/src/lib/src/vendor/glfw-3.4/docs/html/sync_off.png similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/sync_off.png rename to src/lib/src/vendor/glfw-3.4/docs/html/sync_off.png diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/sync_on.png b/src/lib/src/vendor/glfw-3.4/docs/html/sync_on.png similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/sync_on.png rename to src/lib/src/vendor/glfw-3.4/docs/html/sync_on.png diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/tab_a.png b/src/lib/src/vendor/glfw-3.4/docs/html/tab_a.png similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/tab_a.png rename to src/lib/src/vendor/glfw-3.4/docs/html/tab_a.png diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/tab_ad.png b/src/lib/src/vendor/glfw-3.4/docs/html/tab_ad.png new file mode 100644 index 0000000000000000000000000000000000000000..e34850acfc24be58da6d2fd1ccc6b29cc84fe34d GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QhuH;jv*C{Z|5d*H3V=pKi{In zd2jxLclDRPylmD}^l7{QOtL{vUjO{-WqItb5sQp2h-99b8^^Scr-=2mblCdZuUm?4 jzOJvgvt3{(cjKLW5(A@0qPS@<&}0TrS3j3^P6y&q2{!U5bk+Tso_B!YCpDh>v z{CM*1U8YvQRyBUHt^Ju0W_sq-?;9@_4equ-bavTs=gk796zopr0EBT&m;e9( literal 0 HcmV?d00001 diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/tab_s.png b/src/lib/src/vendor/glfw-3.4/docs/html/tab_s.png similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/tab_s.png rename to src/lib/src/vendor/glfw-3.4/docs/html/tab_s.png diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/tab_sd.png b/src/lib/src/vendor/glfw-3.4/docs/html/tab_sd.png new file mode 100644 index 0000000000000000000000000000000000000000..757a565ced4730f85c833fb2547d8e199ae68f19 GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!Qq7(&jv*C{Z|_!fH5o7*c=%9% zcILh!EA=pAQKdx-Cdiev=v{eg{8Ht<{e8_NAN~b=)%W>-WDCE0PyDHGemi$BoXwcK z{>e9^za6*c1ilttWw&V+U;WCPlV9{LdC~Ey%_H(qj`xgfES(4Yz5jSTZfCt`4E$0YRsR*S^mTCR^;V&sxC8{l_Cp7w8-YPgg&ebxsLQ00$vXK>z>% literal 0 HcmV?d00001 diff --git a/src/lib/src/vendor/glfw-3.4/docs/html/tabs.css b/src/lib/src/vendor/glfw-3.4/docs/html/tabs.css new file mode 100644 index 0000000..8920117 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/html/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.main-menu-btn{position:relative;display:inline-block;width:36px;height:36px;text-indent:36px;margin-left:8px;white-space:nowrap;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.main-menu-btn-icon,.main-menu-btn-icon:before,.main-menu-btn-icon:after{position:absolute;top:50%;left:2px;height:2px;width:24px;background:#364D7C;-webkit-transition:all .25s;transition:all .25s}.main-menu-btn-icon:before{content:'';top:-7px;left:0}.main-menu-btn-icon:after{content:'';top:7px;left:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon{height:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:before{top:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:after{top:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}#main-menu-state{position:absolute;width:1px;height:1px;margin:-1px;border:0;padding:0;overflow:hidden;clip:rect(1px,1px,1px,1px)}#main-menu-state:not(:checked) ~ #main-menu{display:none}#main-menu-state:checked ~ #main-menu{display:block}@media(min-width:768px){.main-menu-btn{position:absolute;top:-99999px}#main-menu-state:not(:checked) ~ #main-menu{display:block}}.sm-dox{background-image:url('tab_b.png')}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0px 1px 1px rgba(255, 255, 255, 0.9);color:#283A5D;outline:0}.sm-dox a:hover{background-image:url('tab_a.png');background-repeat:repeat-x;color:white;text-shadow:0px 1px 1px rgba(0, 0, 0, 1.0)}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:rgba(255, 255, 255, 0.5);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a span.sub-arrow:before{display:block;content:'+'}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:white}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url('tab_a.png');background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url('tab_b.png');line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283A5D transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:url('tab_s.png');background-repeat:no-repeat;background-position:right;-moz-border-radius:0 !important;-webkit-border-radius:0;border-radius:0 !important}.sm-dox a:hover{background-image:url('tab_a.png');background-repeat:repeat-x;color:white;text-shadow:0px 1px 1px rgba(0, 0, 0, 1.0)}.sm-dox a:hover span.sub-arrow{border-color:white transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent white transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:white;-moz-border-radius:5px !important;-webkit-border-radius:5px;border-radius:5px !important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555555;background-image:none;border:0 !important;color:#555555;background-image:none}.sm-dox ul a:hover{background-image:url('tab_a.png');background-repeat:repeat-x;color:white;text-shadow:0px 1px 1px rgba(0, 0, 0, 1.0)}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent white}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:white;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url('tab_b.png')}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:white}} \ No newline at end of file diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/modules.html b/src/lib/src/vendor/glfw-3.4/docs/html/topics.html similarity index 61% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/modules.html rename to src/lib/src/vendor/glfw-3.4/docs/html/topics.html index 1ef55b0..da5f22f 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/modules.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/topics.html @@ -4,7 +4,7 @@ - + GLFW: Reference @@ -28,10 +28,10 @@
    - + @@ -55,39 +55,46 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    Reference
    -
    Here is a list of all modules:
    +
    Here is a list of all topics with brief descriptions:
    [detail level 12]
    - + - + - + - - - + + + - + - + - +
     Context referenceFunctions and types related to OpenGL and OpenGL ES contexts
     Initialization, version and error referenceFunctions and types related to initialization and error handling
     Initialization, version and error referenceFunctions and types related to initialization and error handling
     Error codesError codes
     Input referenceFunctions and types related to input handling
     Input referenceFunctions and types related to input handling
     Gamepad axesGamepad axes
     Gamepad buttonsGamepad buttons
     Gamepad buttonsGamepad buttons
     Joystick hat statesJoystick hat states
     JoysticksJoystick IDs
     Keyboard keysKeyboard key IDs
     Modifier key flagsModifier key flags
     JoysticksJoystick IDs
     Keyboard key tokensKeyboard key tokens
     Modifier key flagsModifier key flags
     Mouse buttonsMouse button IDs
     Standard cursor shapesStandard system cursor shapes
     Standard cursor shapesStandard system cursor shapes
     Monitor referenceFunctions and types related to monitors
     Native accessFunctions related to accessing native handles
     Native accessFunctions related to accessing native handles
     Vulkan support referenceFunctions and types related to Vulkan
     Window referenceFunctions and types related to windows
     Window referenceFunctions and types related to windows
    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/intro_8dox.html b/src/lib/src/vendor/glfw-3.4/docs/html/vulkan_8md.html similarity index 80% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/intro_8dox.html rename to src/lib/src/vendor/glfw-3.4/docs/html/vulkan_8md.html index 6bf836e..2088e13 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/intro_8dox.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/vulkan_8md.html @@ -4,8 +4,8 @@ - -GLFW: intro.dox File Reference + +GLFW: vulkan.md File Reference @@ -28,10 +28,10 @@
    - + @@ -54,20 +54,27 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    intro.dox File Reference
    +
    vulkan.md File Reference
    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/vulkan_guide.html b/src/lib/src/vendor/glfw-3.4/docs/html/vulkan_guide.html similarity index 52% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/vulkan_guide.html rename to src/lib/src/vendor/glfw-3.4/docs/html/vulkan_guide.html index 1159aa0..5da2d0f 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/vulkan_guide.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/vulkan_guide.html @@ -4,7 +4,7 @@ - + GLFW: Vulkan guide @@ -28,10 +28,10 @@ - + @@ -54,19 +54,26 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    Vulkan guide
    +
    Vulkan guide
    -

    This guide is intended to fill the gaps between the official Vulkan resources and the rest of the GLFW documentation and is not a replacement for either. It assumes some familiarity with Vulkan concepts like loaders, devices, queues and surfaces and leaves it to the Vulkan documentation to explain the details of Vulkan functions.

    -

    To develop for Vulkan you should download the LunarG Vulkan SDK for your platform. Apart from headers and link libraries, they also provide the validation layers necessary for development.

    -

    The Vulkan Tutorial has more information on how to use GLFW and Vulkan. The Khronos Vulkan Samples also use GLFW, although with a small framework in between.

    -

    For details on a specific Vulkan support function, see the Vulkan support reference. There are also guides for the other areas of the GLFW API.

    +

    This guide is intended to fill the gaps between the official Vulkan resources and the rest of the GLFW documentation and is not a replacement for either. It assumes some familiarity with Vulkan concepts like loaders, devices, queues and surfaces and leaves it to the Vulkan documentation to explain the details of Vulkan functions.

    +

    To develop for Vulkan you should download the LunarG Vulkan SDK for your platform. Apart from headers and link libraries, they also provide the validation layers necessary for development.

    +

    The Vulkan Tutorial has more information on how to use GLFW and Vulkan. The Khronos Vulkan Samples also use GLFW, although with a small framework in between.

    +

    For details on a specific Vulkan support function, see the Vulkan support reference. There are also guides for the other areas of the GLFW API.

    -Linking against the Vulkan loader

    -

    By default, GLFW will look for the Vulkan loader on demand at runtime via its standard name (vulkan-1.dll on Windows, libvulkan.so.1 on Linux and other Unix-like systems and libvulkan.1.dylib on macOS). This means that GLFW does not need to be linked against the loader. However, it also means that if you are using the static library form of the Vulkan loader GLFW will either fail to find it or (worse) use the wrong one.

    -

    The GLFW_VULKAN_STATIC CMake option makes GLFW call the Vulkan loader directly instead of dynamically loading it at runtime. Not linking against the Vulkan loader will then be a compile-time error.

    -

    macOS: To make your application be redistributable you will need to set up the application bundle according to the LunarG SDK documentation. This is explained in more detail in the SDK documentation for macOS.

    +Finding the Vulkan loader +

    GLFW itself does not ever need to be linked against the Vulkan loader.

    +

    By default, GLFW will load the Vulkan loader dynamically at runtime via its standard name: vulkan-1.dll on Windows, libvulkan.so.1 on Linux and other Unix-like systems and libvulkan.1.dylib on macOS.

    +

    macOS: GLFW will also look up and search the Frameworks subdirectory of your application bundle.

    +

    If your code is using a Vulkan loader with a different name or in a non-standard location you will need to direct GLFW to it. Pass your version of vkGetInstanceProcAddr to glfwInitVulkanLoader before initializing GLFW and it will use that function for all Vulkan entry point retrieval. This prevents GLFW from dynamically loading the Vulkan loader.

    +
    glfwInitVulkanLoader(vkGetInstanceProcAddr);
    +
    void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader)
    Sets the desired Vulkan vkGetInstanceProcAddr function.
    +

    macOS: To make your application be redistributable you will need to set up the application bundle according to the LunarG SDK documentation. This is explained in more detail in the SDK documentation for macOS.

    -Including the Vulkan and GLFW header files

    -

    To include the Vulkan header, define GLFW_INCLUDE_VULKAN before including the GLFW header.

    +Including the Vulkan header file +

    To have GLFW include the Vulkan header, define GLFW_INCLUDE_VULKAN before including the GLFW header.

    #define GLFW_INCLUDE_VULKAN
    #include <GLFW/glfw3.h>
    The header of the GLFW 3 API.
    -

    If you instead want to include the Vulkan header from a custom location or use your own custom Vulkan header then do this before the GLFW header.

    +

    If you instead want to include the Vulkan header from a custom location or use your own custom Vulkan header then do this before the GLFW header.

    #include <path/to/vulkan.h>
    #include <GLFW/glfw3.h>
    -

    Unless a Vulkan header is included, either by the GLFW header or above it, any GLFW functions that take or return Vulkan types will not be declared.

    -

    The VK_USE_PLATFORM_*_KHR macros do not need to be defined for the Vulkan part of GLFW to work. Define them only if you are using these extensions directly.

    +

    Unless a Vulkan header is included, either by the GLFW header or above it, the following GLFW functions will not be declared, as depend on Vulkan types.

    + +

    The VK_USE_PLATFORM_*_KHR macros do not need to be defined for the Vulkan part of GLFW to work. Define them only if you are using these extensions directly.

    Querying for Vulkan support

    -

    If you are linking directly against the Vulkan loader then you can skip this section. The canonical desktop loader library exports all Vulkan core and Khronos extension functions, allowing them to be called directly.

    -

    If you are loading the Vulkan loader dynamically instead of linking directly against it, you can check for the availability of a loader and ICD with glfwVulkanSupported.

    +

    If you are linking directly against the Vulkan loader then you can skip this section. The canonical desktop loader library exports all Vulkan core and Khronos extension functions, allowing them to be called directly.

    +

    If you are loading the Vulkan loader dynamically instead of linking directly against it, you can check for the availability of a loader and ICD with glfwVulkanSupported.

    {
    // Vulkan is available, at least for compute
    }
    int glfwVulkanSupported(void)
    Returns whether the Vulkan loader and an ICD have been found.
    -

    This function returns GLFW_TRUE if the Vulkan loader and any minimally functional ICD was found.

    -

    If one or both were not found, calling any other Vulkan related GLFW function will generate a GLFW_API_UNAVAILABLE error.

    +

    This function returns GLFW_TRUE if the Vulkan loader and any minimally functional ICD was found.

    +

    If one or both were not found, calling any other Vulkan related GLFW function will generate a GLFW_API_UNAVAILABLE error.

    Querying Vulkan function pointers

    -

    To load any Vulkan core or extension function from the found loader, call glfwGetInstanceProcAddress. To load functions needed for instance creation, pass NULL as the instance.

    +

    To load any Vulkan core or extension function from the found loader, call glfwGetInstanceProcAddress. To load functions needed for instance creation, pass NULL as the instance.

    PFN_vkCreateInstance pfnCreateInstance = (PFN_vkCreateInstance)
    glfwGetInstanceProcAddress(NULL, "vkCreateInstance");
    GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char *procname)
    Returns the address of the specified Vulkan instance function.
    -

    Once you have created an instance, you can load from it all other Vulkan core functions and functions from any instance extensions you enabled.

    +

    Once you have created an instance, you can load from it all other Vulkan core functions and functions from any instance extensions you enabled.

    PFN_vkCreateDevice pfnCreateDevice = (PFN_vkCreateDevice)
    glfwGetInstanceProcAddress(instance, "vkCreateDevice");
    -

    This function in turn calls vkGetInstanceProcAddr. If that fails, the function falls back to a platform-specific query of the Vulkan loader (i.e. dlsym or GetProcAddress). If that also fails, the function returns NULL. For more information about vkGetInstanceProcAddr, see the Vulkan documentation.

    -

    Vulkan also provides vkGetDeviceProcAddr for loading device-specific versions of Vulkan function. This function can be retrieved from an instance with glfwGetInstanceProcAddress.

    +

    This function in turn calls vkGetInstanceProcAddr. If that fails, the function falls back to a platform-specific query of the Vulkan loader (i.e. dlsym or GetProcAddress). If that also fails, the function returns NULL. For more information about vkGetInstanceProcAddr, see the Vulkan documentation.

    +

    Vulkan also provides vkGetDeviceProcAddr for loading device-specific versions of Vulkan function. This function can be retrieved from an instance with glfwGetInstanceProcAddress.

    PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)
    glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr");
    -

    Device-specific functions may execute a little bit faster, due to not having to dispatch internally based on the device passed to them. For more information about vkGetDeviceProcAddr, see the Vulkan documentation.

    +

    Device-specific functions may execute a little faster, due to not having to dispatch internally based on the device passed to them. For more information about vkGetDeviceProcAddr, see the Vulkan documentation.

    Querying required Vulkan extensions

    -

    To do anything useful with Vulkan you need to create an instance. If you want to use Vulkan to render to a window, you must enable the instance extensions GLFW requires to create Vulkan surfaces.

    -

    To query the instance extensions required, call glfwGetRequiredInstanceExtensions.

    +

    To do anything useful with Vulkan you need to create an instance. If you want to use Vulkan to render to a window, you must enable the instance extensions GLFW requires to create Vulkan surfaces.

    +

    To query the instance extensions required, call glfwGetRequiredInstanceExtensions.

    uint32_t count;
    const char** extensions = glfwGetRequiredInstanceExtensions(&count);
    const char ** glfwGetRequiredInstanceExtensions(uint32_t *count)
    Returns the Vulkan instance extensions required by GLFW.
    -

    These extensions must all be enabled when creating instances that are going to be passed to glfwGetPhysicalDevicePresentationSupport and glfwCreateWindowSurface. The set of extensions will vary depending on platform and may also vary depending on graphics drivers and other factors.

    -

    If it fails it will return NULL and GLFW will not be able to create Vulkan window surfaces. You can still use Vulkan for off-screen rendering and compute work.

    -

    If successful the returned array will always include VK_KHR_surface, so if you don't require any additional extensions you can pass this list directly to the VkInstanceCreateInfo struct.

    +

    These extensions must all be enabled when creating instances that are going to be passed to glfwGetPhysicalDevicePresentationSupport and glfwCreateWindowSurface. The set of extensions will vary depending on platform and may also vary depending on graphics drivers and other factors.

    +

    If it fails it will return NULL and GLFW will not be able to create Vulkan window surfaces. You can still use Vulkan for off-screen rendering and compute work.

    +

    If successful the returned array will always include VK_KHR_surface, so if you don't require any additional extensions you can pass this list directly to the VkInstanceCreateInfo struct.

    VkInstanceCreateInfo ici;
    memset(&ici, 0, sizeof(ici));
    ici.enabledExtensionCount = count;
    ici.ppEnabledExtensionNames = extensions;
    ...
    -

    Additional extensions may be required by future versions of GLFW. You should check whether any extensions you wish to enable are already in the returned array, as it is an error to specify an extension more than once in the VkInstanceCreateInfo struct.

    -

    macOS: MoltenVK is (as of July 2022) not yet a fully conformant implementation of Vulkan. As of Vulkan SDK 1.3.216.0, this means you must also enable the VK_KHR_portability_enumeration instance extension and set the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit in the instance creation info flags for MoltenVK to show up in the list of physical devices. For more information, see the Vulkan and MoltenVK documentation.

    +

    Additional extensions may be required by future versions of GLFW. You should check whether any extensions you wish to enable are already in the returned array, as it is an error to specify an extension more than once in the VkInstanceCreateInfo struct.

    +

    macOS: MoltenVK is (as of July 2022) not yet a fully conformant implementation of Vulkan. As of Vulkan SDK 1.3.216.0, this means you must also enable the VK_KHR_portability_enumeration instance extension and set the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit in the instance creation info flags for MoltenVK to show up in the list of physical devices. For more information, see the Vulkan and MoltenVK documentation.

    Querying for Vulkan presentation support

    -

    Not every queue family of every Vulkan device can present images to surfaces. To check whether a specific queue family of a physical device supports image presentation without first having to create a window and surface, call glfwGetPhysicalDevicePresentationSupport.

    +

    Not every queue family of every Vulkan device can present images to surfaces. To check whether a specific queue family of a physical device supports image presentation without first having to create a window and surface, call glfwGetPhysicalDevicePresentationSupport.

    if (glfwGetPhysicalDevicePresentationSupport(instance, physical_device, queue_family_index))
    {
    // Queue family supports image presentation
    }
    int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily)
    Returns whether the specified queue family can present images.
    -

    The VK_KHR_surface extension additionally provides the vkGetPhysicalDeviceSurfaceSupportKHR function, which performs the same test on an existing Vulkan surface.

    +

    The VK_KHR_surface extension additionally provides the vkGetPhysicalDeviceSurfaceSupportKHR function, which performs the same test on an existing Vulkan surface.

    Creating the window

    -

    Unless you will be using OpenGL or OpenGL ES with the same window as Vulkan, there is no need to create a context. You can disable context creation with the GLFW_CLIENT_API hint.

    +

    Unless you will be using OpenGL or OpenGL ES with the same window as Vulkan, there is no need to create a context. You can disable context creation with the GLFW_CLIENT_API hint.

    GLFWwindow* window = glfwCreateWindow(640, 480, "Window Title", NULL, NULL);
    -
    #define GLFW_NO_API
    Definition: glfw3.h:1036
    +
    #define GLFW_NO_API
    Definition glfw3.h:1140
    GLFWwindow * glfwCreateWindow(int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
    Creates a window and its associated context.
    -
    struct GLFWwindow GLFWwindow
    Opaque window object.
    Definition: glfw3.h:1185
    -
    #define GLFW_CLIENT_API
    Context client API hint and attribute.
    Definition: glfw3.h:949
    +
    struct GLFWwindow GLFWwindow
    Opaque window object.
    Definition glfw3.h:1403
    +
    #define GLFW_CLIENT_API
    Context client API hint and attribute.
    Definition glfw3.h:1031
    void glfwWindowHint(int hint, int value)
    Sets the specified window hint to the desired value.
    -

    See Windows without contexts for more information.

    +

    See Windows without contexts for more information.

    Creating a Vulkan window surface

    -

    You can create a Vulkan surface (as defined by the VK_KHR_surface extension) for a GLFW window with glfwCreateWindowSurface.

    +

    You can create a Vulkan surface (as defined by the VK_KHR_surface extension) for a GLFW window with glfwCreateWindowSurface.

    VkSurfaceKHR surface;
    VkResult err = glfwCreateWindowSurface(instance, window, NULL, &surface);
    if (err)
    @@ -176,13 +193,13 @@ Creating a Vulkan window surface
    // Window surface creation failed
    }
    VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow *window, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
    Creates a Vulkan surface for the specified window.
    -

    If an OpenGL or OpenGL ES context was created on the window, the context has ownership of the presentation on the window and a Vulkan surface cannot be created.

    -

    It is your responsibility to destroy the surface. GLFW does not destroy it for you. Call vkDestroySurfaceKHR function from the same extension to destroy it.

    +

    If an OpenGL or OpenGL ES context was created on the window, the context has ownership of the presentation on the window and a Vulkan surface cannot be created.

    +

    It is your responsibility to destroy the surface. GLFW does not destroy it for you. Call vkDestroySurfaceKHR function from the same extension to destroy it.

    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/quick_8dox.html b/src/lib/src/vendor/glfw-3.4/docs/html/window_8md.html similarity index 80% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/quick_8dox.html rename to src/lib/src/vendor/glfw-3.4/docs/html/window_8md.html index f65bd4c..da40f2d 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/quick_8dox.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/window_8md.html @@ -4,8 +4,8 @@ - -GLFW: quick.dox File Reference + +GLFW: window.md File Reference @@ -28,10 +28,10 @@ - + @@ -54,20 +54,27 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    quick.dox File Reference
    +
    window.md File Reference
    diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/html/window_guide.html b/src/lib/src/vendor/glfw-3.4/docs/html/window_guide.html similarity index 50% rename from src/lib/src/vendor/glfw-3.3.8/docs/html/window_guide.html rename to src/lib/src/vendor/glfw-3.4/docs/html/window_guide.html index f7d0c2c..d94d9df 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/html/window_guide.html +++ b/src/lib/src/vendor/glfw-3.4/docs/html/window_guide.html @@ -4,7 +4,7 @@ - + GLFW: Window guide @@ -28,10 +28,10 @@ - + @@ -54,14 +54,21 @@ $(function() {
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    Window guide
    +
    Window guide

    Table of Contents

    @@ -75,7 +82,9 @@ $(function() {
  • Framebuffer related hints
  • Monitor related hints
  • Context related hints
  • -
  • macOS specific window hints
  • +
  • Win32 specific hints
  • +
  • macOS specific hints
  • +
  • Wayland specific window hints
  • X11 specific window hints
  • Supported and default values
  • @@ -110,7 +119,7 @@ $(function() {
  • Buffer swapping
  • -

    This guide introduces the window related functions of GLFW. For details on a specific function in this category, see the Window reference. There are also guides for the other areas of GLFW.

    +

    This guide introduces the window related functions of GLFW. For details on a specific function in this category, see the Window reference. There are also guides for the other areas of GLFW.

    Window objects

    -

    The GLFWwindow object encapsulates both a window and a context. They are created with glfwCreateWindow and destroyed with glfwDestroyWindow, or glfwTerminate, if any remain. As the window and context are inseparably linked, the object pointer is used as both a context and window handle.

    -

    To see the event stream provided to the various window related callbacks, run the events test program.

    +

    The GLFWwindow object encapsulates both a window and a context. They are created with glfwCreateWindow and destroyed with glfwDestroyWindow, or glfwTerminate, if any remain. As the window and context are inseparably linked, the object pointer is used as both a context and window handle.

    +

    To see the event stream provided to the various window related callbacks, run the events test program.

    Window creation

    -

    A window and its OpenGL or OpenGL ES context are created with glfwCreateWindow, which returns a handle to the created window object. For example, this creates a 640 by 480 windowed mode window:

    +

    A window and its OpenGL or OpenGL ES context are created with glfwCreateWindow, which returns a handle to the created window object. For example, this creates a 640 by 480 windowed mode window:

    GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
    GLFWwindow * glfwCreateWindow(int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
    Creates a window and its associated context.
    -
    struct GLFWwindow GLFWwindow
    Opaque window object.
    Definition: glfw3.h:1185
    -

    If window creation fails, NULL will be returned, so it is necessary to check the return value.

    -

    The window handle is passed to all window related functions and is provided to along with all input events, so event handlers can tell which window received the event.

    +
    struct GLFWwindow GLFWwindow
    Opaque window object.
    Definition glfw3.h:1403
    +

    If window creation fails, NULL will be returned, so it is necessary to check the return value.

    +

    The window handle is passed to all window related functions and is provided to along with all input events, so event handlers can tell which window received the event.

    Full screen windows

    -

    To create a full screen window, you need to specify which monitor the window should use. In most cases, the user's primary monitor is a good choice. For more information about retrieving monitors, see Retrieving monitors.

    +

    To create a full screen window, you need to specify which monitor the window should use. In most cases, the user's primary monitor is a good choice. For more information about retrieving monitors, see Retrieving monitors.

    GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", glfwGetPrimaryMonitor(), NULL);
    GLFWmonitor * glfwGetPrimaryMonitor(void)
    Returns the primary monitor.
    -

    Full screen windows cover the entire display area of a monitor, have no border or decorations.

    -

    Windowed mode windows can be made full screen by setting a monitor with glfwSetWindowMonitor, and full screen ones can be made windowed by unsetting it with the same function.

    -

    Each field of the GLFWvidmode structure corresponds to a function parameter or window hint and combine to form the desired video mode for that window. The supported video mode most closely matching the desired video mode will be set for the chosen monitor as long as the window has input focus. For more information about retrieving video modes, see Video modes.

    +

    Full screen windows cover the entire display area of a monitor, have no border or decorations.

    +

    Windowed mode windows can be made full screen by setting a monitor with glfwSetWindowMonitor, and full screen ones can be made windowed by unsetting it with the same function.

    +

    Each field of the GLFWvidmode structure corresponds to a function parameter or window hint and combine to form the desired video mode for that window. The supported video mode most closely matching the desired video mode will be set for the chosen monitor as long as the window has input focus. For more information about retrieving video modes, see Video modes.

    - + - + - + - + - + - +
    Video mode field Corresponds to
    GLFWvidmode.width width parameter of glfwCreateWindow
    GLFWvidmode.width width parameter of glfwCreateWindow
    GLFWvidmode.height height parameter of glfwCreateWindow
    GLFWvidmode.height height parameter of glfwCreateWindow
    GLFWvidmode.redBits GLFW_RED_BITS hint
    GLFWvidmode.redBits GLFW_RED_BITS hint
    GLFWvidmode.greenBits GLFW_GREEN_BITS hint
    GLFWvidmode.greenBits GLFW_GREEN_BITS hint
    GLFWvidmode.blueBits GLFW_BLUE_BITS hint
    GLFWvidmode.blueBits GLFW_BLUE_BITS hint
    GLFWvidmode.refreshRate GLFW_REFRESH_RATE hint
    GLFWvidmode.refreshRate GLFW_REFRESH_RATE hint
    -

    Once you have a full screen window, you can change its resolution, refresh rate and monitor with glfwSetWindowMonitor. If you only need change its resolution you can also call glfwSetWindowSize. In all cases, the new video mode will be selected the same way as the video mode chosen by glfwCreateWindow. If the window has an OpenGL or OpenGL ES context, it will be unaffected.

    -

    By default, the original video mode of the monitor will be restored and the window iconified if it loses input focus, to allow the user to switch back to the desktop. This behavior can be disabled with the GLFW_AUTO_ICONIFY window hint, for example if you wish to simultaneously cover multiple monitors with full screen windows.

    -

    If a monitor is disconnected, all windows that are full screen on that monitor will be switched to windowed mode. See Monitor configuration changes for more information.

    +

    Once you have a full screen window, you can change its resolution, refresh rate and monitor with glfwSetWindowMonitor. If you only need change its resolution you can also call glfwSetWindowSize. In all cases, the new video mode will be selected the same way as the video mode chosen by glfwCreateWindow. If the window has an OpenGL or OpenGL ES context, it will be unaffected.

    +

    By default, the original video mode of the monitor will be restored and the window iconified if it loses input focus, to allow the user to switch back to the desktop. This behavior can be disabled with the GLFW_AUTO_ICONIFY window hint, for example if you wish to simultaneously cover multiple monitors with full screen windows.

    +

    If a monitor is disconnected, all windows that are full screen on that monitor will be switched to windowed mode. See Monitor configuration changes for more information.

    "Windowed full screen" windows

    -

    If the closest match for the desired video mode is the current one, the video mode will not be changed, making window creation faster and application switching much smoother. This is sometimes called windowed full screen or borderless full screen window and counts as a full screen window. To create such a window, request the current video mode.

    -
    const GLFWvidmode* mode = glfwGetVideoMode(monitor);
    +

    If the closest match for the desired video mode is the current one, the video mode will not be changed, making window creation faster and application switching much smoother. This is sometimes called windowed full screen or borderless full screen window and counts as a full screen window. To create such a window, request the current video mode.

    +
    const GLFWvidmode* mode = glfwGetVideoMode(monitor);
    - - - - + + + +
    -
    GLFWwindow* window = glfwCreateWindow(mode->width, mode->height, "My Title", monitor, NULL);
    +
    GLFWwindow* window = glfwCreateWindow(mode->width, mode->height, "My Title", monitor, NULL);
    const GLFWvidmode * glfwGetVideoMode(GLFWmonitor *monitor)
    Returns the current mode of the specified monitor.
    -
    #define GLFW_REFRESH_RATE
    Monitor refresh rate hint.
    Definition: glfw3.h:937
    +
    #define GLFW_REFRESH_RATE
    Monitor refresh rate hint.
    Definition glfw3.h:1018
    void glfwWindowHint(int hint, int value)
    Sets the specified window hint to the desired value.
    -
    #define GLFW_BLUE_BITS
    Framebuffer bit depth hint.
    Definition: glfw3.h:877
    -
    #define GLFW_RED_BITS
    Framebuffer bit depth hint.
    Definition: glfw3.h:867
    -
    #define GLFW_GREEN_BITS
    Framebuffer bit depth hint.
    Definition: glfw3.h:872
    -
    Video mode type.
    Definition: glfw3.h:1658
    -
    int greenBits
    Definition: glfw3.h:1670
    -
    int redBits
    Definition: glfw3.h:1667
    -
    int width
    Definition: glfw3.h:1661
    -
    int refreshRate
    Definition: glfw3.h:1676
    -
    int height
    Definition: glfw3.h:1664
    -
    int blueBits
    Definition: glfw3.h:1673
    -

    This also works for windowed mode windows that are made full screen.

    -
    const GLFWvidmode* mode = glfwGetVideoMode(monitor);
    +
    #define GLFW_BLUE_BITS
    Framebuffer bit depth hint.
    Definition glfw3.h:958
    +
    #define GLFW_RED_BITS
    Framebuffer bit depth hint.
    Definition glfw3.h:948
    +
    #define GLFW_GREEN_BITS
    Framebuffer bit depth hint.
    Definition glfw3.h:953
    +
    Video mode type.
    Definition glfw3.h:2027
    +
    int greenBits
    Definition glfw3.h:2039
    +
    int redBits
    Definition glfw3.h:2036
    +
    int width
    Definition glfw3.h:2030
    +
    int refreshRate
    Definition glfw3.h:2045
    +
    int height
    Definition glfw3.h:2033
    +
    int blueBits
    Definition glfw3.h:2042
    +

    This also works for windowed mode windows that are made full screen.

    +
    const GLFWvidmode* mode = glfwGetVideoMode(monitor);
    -
    glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
    +
    glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
    void glfwSetWindowMonitor(GLFWwindow *window, GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)
    Sets the mode, monitor, video mode and placement of a window.
    -

    Note that glfwGetVideoMode returns the current video mode of a monitor, so if you already have a full screen window on that monitor that you want to make windowed full screen, you need to have saved the desktop resolution before.

    +

    Note that glfwGetVideoMode returns the current video mode of a monitor, so if you already have a full screen window on that monitor that you want to make windowed full screen, you need to have saved the desktop resolution before.

    Window destruction

    -

    When a window is no longer needed, destroy it with glfwDestroyWindow.

    +

    When a window is no longer needed, destroy it with glfwDestroyWindow.

    void glfwDestroyWindow(GLFWwindow *window)
    Destroys the specified window and its context.
    -

    Window destruction always succeeds. Before the actual destruction, all callbacks are removed so no further events will be delivered for the window. All windows remaining when glfwTerminate is called are destroyed as well.

    -

    When a full screen window is destroyed, the original video mode of its monitor is restored, but the gamma ramp is left untouched.

    +

    Window destruction always succeeds. Before the actual destruction, all callbacks are removed so no further events will be delivered for the window. All windows remaining when glfwTerminate is called are destroyed as well.

    +

    When a full screen window is destroyed, the original video mode of its monitor is restored, but the gamma ramp is left untouched.

    Window creation hints

    -

    There are a number of hints that can be set before the creation of a window and context. Some affect the window itself, others affect the framebuffer or context. These hints are set to their default values each time the library is initialized with glfwInit. Integer value hints can be set individually with glfwWindowHint and string value hints with glfwWindowHintString. You can reset all at once to their defaults with glfwDefaultWindowHints.

    -

    Some hints are platform specific. These are always valid to set on any platform but they will only affect their specific platform. Other platforms will ignore them. Setting these hints requires no platform specific headers or calls.

    +

    There are a number of hints that can be set before the creation of a window and context. Some affect the window itself, others affect the framebuffer or context. These hints are set to their default values each time the library is initialized with glfwInit. Integer value hints can be set individually with glfwWindowHint and string value hints with glfwWindowHintString. You can reset all at once to their defaults with glfwDefaultWindowHints.

    +

    Some hints are platform specific. These are always valid to set on any platform but they will only affect their specific platform. Other platforms will ignore them. Setting these hints requires no platform specific headers or calls.

    Note
    Window hints need to be set before the creation of the window and context you wish to have the specified attributes. They function as additional arguments to glfwCreateWindow.

    Hard and soft constraints

    -

    Some window hints are hard constraints. These must match the available capabilities exactly for window and context creation to succeed. Hints that are not hard constraints are matched as closely as possible, but the resulting context and framebuffer may differ from what these hints requested.

    -

    The following hints are always hard constraints:

      +

      Some window hints are hard constraints. These must match the available capabilities exactly for window and context creation to succeed. Hints that are not hard constraints are matched as closely as possible, but the resulting context and framebuffer may differ from what these hints requested.

      +

      The following hints are always hard constraints:

      -

      The following additional hints are hard constraints when requesting an OpenGL context, but are ignored when requesting an OpenGL ES context:

        +

        The following additional hints are hard constraints when requesting an OpenGL context, but are ignored when requesting an OpenGL ES context:

        Window related hints

        -

        GLFW_RESIZABLE specifies whether the windowed mode window will be resizable by the user. The window will still be resizable using the glfwSetWindowSize function. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for full screen and undecorated windows.

        -

        GLFW_VISIBLE specifies whether the windowed mode window will be initially visible. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for full screen windows.

        -

        GLFW_DECORATED specifies whether the windowed mode window will have window decorations such as a border, a close widget, etc. An undecorated window will not be resizable by the user but will still allow the user to generate close events on some platforms. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for full screen windows.

        -

        GLFW_FOCUSED specifies whether the windowed mode window will be given input focus when created. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for full screen and initially hidden windows.

        -

        GLFW_AUTO_ICONIFY specifies whether the full screen window will automatically iconify and restore the previous video mode on input focus loss. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for windowed mode windows.

        -

        GLFW_FLOATING specifies whether the windowed mode window will be floating above other regular windows, also called topmost or always-on-top. This is intended primarily for debugging purposes and cannot be used to implement proper full screen windows. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for full screen windows.

        -

        GLFW_MAXIMIZED specifies whether the windowed mode window will be maximized when created. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for full screen windows.

        -

        GLFW_CENTER_CURSOR specifies whether the cursor should be centered over newly created full screen windows. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for windowed mode windows.

        -

        GLFW_TRANSPARENT_FRAMEBUFFER specifies whether the window framebuffer will be transparent. If enabled and supported by the system, the window framebuffer alpha channel will be used to combine the framebuffer with the background. This does not affect window decorations. Possible values are GLFW_TRUE and GLFW_FALSE.

        -

        GLFW_FOCUS_ON_SHOW specifies whether the window will be given input focus when glfwShowWindow is called. Possible values are GLFW_TRUE and GLFW_FALSE.

        -

        GLFW_SCALE_TO_MONITOR specified whether the window content area should be resized based on the monitor content scale of any monitor it is placed on. This includes the initial placement when the window is created. Possible values are GLFW_TRUE and GLFW_FALSE.

        -

        This hint only has an effect on platforms where screen coordinates and pixels always map 1:1 such as Windows and X11. On platforms like macOS the resolution of the framebuffer is changed independently of the window size.

        +

        GLFW_RESIZABLE specifies whether the windowed mode window will be resizable by the user. The window will still be resizable using the glfwSetWindowSize function. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for full screen and undecorated windows.

        +

        GLFW_VISIBLE specifies whether the windowed mode window will be initially visible. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for full screen windows.

        +

        GLFW_DECORATED specifies whether the windowed mode window will have window decorations such as a border, a close widget, etc. An undecorated window will not be resizable by the user but will still allow the user to generate close events on some platforms. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for full screen windows.

        +

        GLFW_FOCUSED specifies whether the windowed mode window will be given input focus when created. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for full screen and initially hidden windows.

        +

        GLFW_AUTO_ICONIFY specifies whether the full screen window will automatically iconify and restore the previous video mode on input focus loss. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for windowed mode windows.

        +

        GLFW_FLOATING specifies whether the windowed mode window will be floating above other regular windows, also called topmost or always-on-top. This is intended primarily for debugging purposes and cannot be used to implement proper full screen windows. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for full screen windows.

        +

        GLFW_MAXIMIZED specifies whether the windowed mode window will be maximized when created. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for full screen windows.

        +

        GLFW_CENTER_CURSOR specifies whether the cursor should be centered over newly created full screen windows. Possible values are GLFW_TRUE and GLFW_FALSE. This hint is ignored for windowed mode windows.

        +

        GLFW_TRANSPARENT_FRAMEBUFFER specifies whether the window framebuffer will be transparent. If enabled and supported by the system, the window framebuffer alpha channel will be used to combine the framebuffer with the background. This does not affect window decorations. Possible values are GLFW_TRUE and GLFW_FALSE.

        +

        GLFW_FOCUS_ON_SHOW specifies whether the window will be given input focus when glfwShowWindow is called. Possible values are GLFW_TRUE and GLFW_FALSE.

        +

        GLFW_SCALE_TO_MONITOR specified whether the window content area should be resized based on content scale changes. This can be because of a global user settings change or because the window was moved to a monitor with different scale settings.

        +

        This hint only has an effect on platforms where screen coordinates and pixels always map 1:1, such as Windows and X11. On platforms like macOS the resolution of the framebuffer can change independently of the window size.

        +

        GLFW_SCALE_FRAMEBUFFER specifies whether the framebuffer should be resized based on content scale changes. This can be because of a global user settings change or because the window was moved to a monitor with different scale settings.

        +

        This hint only has an effect on platforms where screen coordinates can be scaled relative to pixel coordinates, such as macOS and Wayland. On platforms like Windows and X11 the framebuffer and window content area sizes always map 1:1.

        +

        This is the new name, introduced in GLFW 3.4. The older GLFW_COCOA_RETINA_FRAMEBUFFER name is also available for compatibility. Both names modify the same hint value.

        +

        GLFW_MOUSE_PASSTHROUGH specifies whether the window is transparent to mouse input, letting any mouse events pass through to whatever window is behind it. This is only supported for undecorated windows. Decorated windows with this enabled will behave differently between platforms. Possible values are GLFW_TRUE and GLFW_FALSE.

        +

        GLFW_POSITION_X and GLFW_POSITION_Y specify the desired initial position of the window. The window manager may modify or ignore these coordinates. If either or both of these hints are set to GLFW_ANY_POSITION then the window manager will position the window where it thinks the user will prefer it. Possible values are any valid screen coordinates and GLFW_ANY_POSITION.

        Framebuffer related hints

        -

        GLFW_RED_BITS, GLFW_GREEN_BITS, GLFW_BLUE_BITS, GLFW_ALPHA_BITS, GLFW_DEPTH_BITS and GLFW_STENCIL_BITS specify the desired bit depths of the various components of the default framebuffer. A value of GLFW_DONT_CARE means the application has no preference.

        -

        GLFW_ACCUM_RED_BITS, GLFW_ACCUM_GREEN_BITS, GLFW_ACCUM_BLUE_BITS and GLFW_ACCUM_ALPHA_BITS specify the desired bit depths of the various components of the accumulation buffer. A value of GLFW_DONT_CARE means the application has no preference.

        -

        Accumulation buffers are a legacy OpenGL feature and should not be used in new code.

        -

        GLFW_AUX_BUFFERS specifies the desired number of auxiliary buffers. A value of GLFW_DONT_CARE means the application has no preference.

        -

        Auxiliary buffers are a legacy OpenGL feature and should not be used in new code.

        -

        GLFW_STEREO specifies whether to use OpenGL stereoscopic rendering. Possible values are GLFW_TRUE and GLFW_FALSE. This is a hard constraint.

        -

        GLFW_SAMPLES specifies the desired number of samples to use for multisampling. Zero disables multisampling. A value of GLFW_DONT_CARE means the application has no preference.

        -

        GLFW_SRGB_CAPABLE specifies whether the framebuffer should be sRGB capable. Possible values are GLFW_TRUE and GLFW_FALSE.

        +

        GLFW_RED_BITS, GLFW_GREEN_BITS, GLFW_BLUE_BITS, GLFW_ALPHA_BITS, GLFW_DEPTH_BITS and GLFW_STENCIL_BITS specify the desired bit depths of the various components of the default framebuffer. A value of GLFW_DONT_CARE means the application has no preference.

        +

        GLFW_ACCUM_RED_BITS, GLFW_ACCUM_GREEN_BITS, GLFW_ACCUM_BLUE_BITS and GLFW_ACCUM_ALPHA_BITS specify the desired bit depths of the various components of the accumulation buffer. A value of GLFW_DONT_CARE means the application has no preference.

        +

        Accumulation buffers are a legacy OpenGL feature and should not be used in new code.

        +

        GLFW_AUX_BUFFERS specifies the desired number of auxiliary buffers. A value of GLFW_DONT_CARE means the application has no preference.

        +

        Auxiliary buffers are a legacy OpenGL feature and should not be used in new code.

        +

        GLFW_STEREO specifies whether to use OpenGL stereoscopic rendering. Possible values are GLFW_TRUE and GLFW_FALSE. This is a hard constraint.

        +

        GLFW_SAMPLES specifies the desired number of samples to use for multisampling. Zero disables multisampling. A value of GLFW_DONT_CARE means the application has no preference.

        +

        GLFW_SRGB_CAPABLE specifies whether the framebuffer should be sRGB capable. Possible values are GLFW_TRUE and GLFW_FALSE.

        Note
        OpenGL: If enabled and supported by the system, the GL_FRAMEBUFFER_SRGB enable will control sRGB rendering. By default, sRGB rendering will be disabled.
        OpenGL ES: If enabled and supported by the system, the context will always have sRGB rendering enabled.
        -

        GLFW_DOUBLEBUFFER specifies whether the framebuffer should be double buffered. You nearly always want to use double buffering. This is a hard constraint. Possible values are GLFW_TRUE and GLFW_FALSE.

        +

        GLFW_DOUBLEBUFFER specifies whether the framebuffer should be double buffered. You nearly always want to use double buffering. This is a hard constraint. Possible values are GLFW_TRUE and GLFW_FALSE.

        Monitor related hints

        -

        GLFW_REFRESH_RATE specifies the desired refresh rate for full screen windows. A value of GLFW_DONT_CARE means the highest available refresh rate will be used. This hint is ignored for windowed mode windows.

        +

        GLFW_REFRESH_RATE specifies the desired refresh rate for full screen windows. A value of GLFW_DONT_CARE means the highest available refresh rate will be used. This hint is ignored for windowed mode windows.

        Context related hints

        -

        GLFW_CLIENT_API specifies which client API to create the context for. Possible values are GLFW_OPENGL_API, GLFW_OPENGL_ES_API and GLFW_NO_API. This is a hard constraint.

        -

        GLFW_CONTEXT_CREATION_API specifies which context creation API to use to create the context. Possible values are GLFW_NATIVE_CONTEXT_API, GLFW_EGL_CONTEXT_API and GLFW_OSMESA_CONTEXT_API. This is a hard constraint. If no client API is requested, this hint is ignored.

        -

        An extension loader library that assumes it knows which API was used to create the current context may fail if you change this hint. This can be resolved by having it load functions via glfwGetProcAddress.

        +

        GLFW_CLIENT_API specifies which client API to create the context for. Possible values are GLFW_OPENGL_API, GLFW_OPENGL_ES_API and GLFW_NO_API. This is a hard constraint.

        +

        GLFW_CONTEXT_CREATION_API specifies which context creation API to use to create the context. Possible values are GLFW_NATIVE_CONTEXT_API, GLFW_EGL_CONTEXT_API and GLFW_OSMESA_CONTEXT_API. This is a hard constraint. If no client API is requested, this hint is ignored.

        +

        An extension loader library that assumes it knows which API was used to create the current context may fail if you change this hint. This can be resolved by having it load functions via glfwGetProcAddress.

        Note
        Wayland: The EGL API is the native context creation API, so this hint will have no effect.
        X11: On some Linux systems, creating contexts via both the native and EGL APIs in a single process will cause the application to segfault. Stick to one API or the other on Linux for now.
        OSMesa: As its name implies, an OpenGL context created with OSMesa does not update the window contents when its buffers are swapped. Use OpenGL functions or the OSMesa native access functions glfwGetOSMesaColorBuffer and glfwGetOSMesaDepthBuffer to retrieve the framebuffer contents.

        GLFW_CONTEXT_VERSION_MAJOR and GLFW_CONTEXT_VERSION_MINOR specify the client API version that the created context must be compatible with. The exact behavior of these hints depend on the requested client API.

        -

        While there is no way to ask the driver for a context of the highest supported version, GLFW will attempt to provide this when you ask for a version 1.0 context, which is the default for these hints.

        -

        Do not confuse these hints with GLFW_VERSION_MAJOR and GLFW_VERSION_MINOR, which provide the API version of the GLFW header.

        +

        While there is no way to ask the driver for a context of the highest supported version, GLFW will attempt to provide this when you ask for a version 1.0 context, which is the default for these hints.

        +

        Do not confuse these hints with GLFW_VERSION_MAJOR and GLFW_VERSION_MINOR, which provide the API version of the GLFW header.

        Note
        OpenGL: These hints are not hard constraints, but creation will fail if the OpenGL version of the created context is less than the one requested. It is therefore perfectly safe to use the default of version 1.0 for legacy code and you will still get backwards-compatible contexts of version 3.0 and above when available.
        OpenGL ES: These hints are not hard constraints, but creation will fail if the OpenGL ES version of the created context is less than the one requested. Additionally, OpenGL ES 1.x cannot be returned if 2.0 or later was requested, and vice versa. This is because OpenGL ES 3.x is backward compatible with 2.0, but OpenGL ES 2.0 is not backward compatible with 1.x.
        -macOS: The OS only supports forward-compatible core profile contexts for OpenGL versions 3.2 and later. Before creating an OpenGL context of version 3.2 or later you must set the GLFW_OPENGL_FORWARD_COMPAT and GLFW_OPENGL_PROFILE hints accordingly. OpenGL 3.0 and 3.1 contexts are not supported at all on macOS.
        +macOS: The OS only supports core profile contexts for OpenGL versions 3.2 and later. Before creating an OpenGL context of version 3.2 or later you must set the GLFW_OPENGL_PROFILE hint accordingly. OpenGL 3.0 and 3.1 contexts are not supported at all on macOS.

        GLFW_OPENGL_FORWARD_COMPAT specifies whether the OpenGL context should be forward-compatible, i.e. one where all functionality deprecated in the requested version of OpenGL is removed. This must only be used if the requested OpenGL version is 3.0 or above. If OpenGL ES is requested, this hint is ignored.

        -

        Forward-compatibility is described in detail in the OpenGL Reference Manual.

        -

        GLFW_OPENGL_DEBUG_CONTEXT specifies whether the context should be created in debug mode, which may provide additional error and diagnostic reporting functionality. Possible values are GLFW_TRUE and GLFW_FALSE.

        -

        Debug contexts for OpenGL and OpenGL ES are described in detail by the GL_KHR_debug extension.

        -

        GLFW_OPENGL_PROFILE specifies which OpenGL profile to create the context for. Possible values are one of GLFW_OPENGL_CORE_PROFILE or GLFW_OPENGL_COMPAT_PROFILE, or GLFW_OPENGL_ANY_PROFILE to not request a specific profile. If requesting an OpenGL version below 3.2, GLFW_OPENGL_ANY_PROFILE must be used. If OpenGL ES is requested, this hint is ignored.

        -

        OpenGL profiles are described in detail in the OpenGL Reference Manual.

        -

        GLFW_CONTEXT_ROBUSTNESS specifies the robustness strategy to be used by the context. This can be one of GLFW_NO_RESET_NOTIFICATION or GLFW_LOSE_CONTEXT_ON_RESET, or GLFW_NO_ROBUSTNESS to not request a robustness strategy.

        -

        GLFW_CONTEXT_RELEASE_BEHAVIOR specifies the release behavior to be used by the context. Possible values are one of GLFW_ANY_RELEASE_BEHAVIOR, GLFW_RELEASE_BEHAVIOR_FLUSH or GLFW_RELEASE_BEHAVIOR_NONE. If the behavior is GLFW_ANY_RELEASE_BEHAVIOR, the default behavior of the context creation API will be used. If the behavior is GLFW_RELEASE_BEHAVIOR_FLUSH, the pipeline will be flushed whenever the context is released from being the current one. If the behavior is GLFW_RELEASE_BEHAVIOR_NONE, the pipeline will not be flushed on release.

        -

        Context release behaviors are described in detail by the GL_KHR_context_flush_control extension.

        -

        GLFW_CONTEXT_NO_ERROR specifies whether errors should be generated by the context. Possible values are GLFW_TRUE and GLFW_FALSE. If enabled, situations that would have generated errors instead cause undefined behavior.

        -

        The no error mode for OpenGL and OpenGL ES is described in detail by the GL_KHR_no_error extension.

        +

        Forward-compatibility is described in detail in the OpenGL Reference Manual.

        +

        GLFW_CONTEXT_DEBUG specifies whether the context should be created in debug mode, which may provide additional error and diagnostic reporting functionality. Possible values are GLFW_TRUE and GLFW_FALSE.

        +

        Debug contexts for OpenGL and OpenGL ES are described in detail by the GL_KHR_debug extension.

        +
        Note
        GLFW_CONTEXT_DEBUG is the new name introduced in GLFW 3.4. The older GLFW_OPENGL_DEBUG_CONTEXT name is also available for compatibility.
        +

        GLFW_OPENGL_PROFILE specifies which OpenGL profile to create the context for. Possible values are one of GLFW_OPENGL_CORE_PROFILE or GLFW_OPENGL_COMPAT_PROFILE, or GLFW_OPENGL_ANY_PROFILE to not request a specific profile. If requesting an OpenGL version below 3.2, GLFW_OPENGL_ANY_PROFILE must be used. If OpenGL ES is requested, this hint is ignored.

        +

        OpenGL profiles are described in detail in the OpenGL Reference Manual.

        +

        GLFW_CONTEXT_ROBUSTNESS specifies the robustness strategy to be used by the context. This can be one of GLFW_NO_RESET_NOTIFICATION or GLFW_LOSE_CONTEXT_ON_RESET, or GLFW_NO_ROBUSTNESS to not request a robustness strategy.

        +

        GLFW_CONTEXT_RELEASE_BEHAVIOR specifies the release behavior to be used by the context. Possible values are one of GLFW_ANY_RELEASE_BEHAVIOR, GLFW_RELEASE_BEHAVIOR_FLUSH or GLFW_RELEASE_BEHAVIOR_NONE. If the behavior is GLFW_ANY_RELEASE_BEHAVIOR, the default behavior of the context creation API will be used. If the behavior is GLFW_RELEASE_BEHAVIOR_FLUSH, the pipeline will be flushed whenever the context is released from being the current one. If the behavior is GLFW_RELEASE_BEHAVIOR_NONE, the pipeline will not be flushed on release.

        +

        Context release behaviors are described in detail by the GL_KHR_context_flush_control extension.

        +

        GLFW_CONTEXT_NO_ERROR specifies whether errors should be generated by the context. Possible values are GLFW_TRUE and GLFW_FALSE. If enabled, situations that would have generated errors instead cause undefined behavior.

        +

        The no error mode for OpenGL and OpenGL ES is described in detail by the GL_KHR_no_error extension.

        +

        +Win32 specific hints

        +

        GLFW_WIN32_KEYBOARD_MENU specifies whether to allow access to the window menu via the Alt+Space and Alt-and-then-Space keyboard shortcuts. This is ignored on other platforms.

        +

        GLFW_WIN32_SHOWDEFAULT specifies whether to show the window the way specified in the program's STARTUPINFO when it is shown for the first time. This is the same information as the Run option in the shortcut properties window. If this information was not specified when the program was started, GLFW behaves as if this hint was set to GLFW_FALSE. Possible values are GLFW_TRUE and GLFW_FALSE. This is ignored on other platforms.

        -macOS specific window hints

        -

        GLFW_COCOA_RETINA_FRAMEBUFFER specifies whether to use full resolution framebuffers on Retina displays. Possible values are GLFW_TRUE and GLFW_FALSE. This is ignored on other platforms.

        -

        GLFW_COCOA_FRAME_NAME specifies the UTF-8 encoded name to use for autosaving the window frame, or if empty disables frame autosaving for the window. This is ignored on other platforms. This is set with glfwWindowHintString.

        -

        GLFW_COCOA_GRAPHICS_SWITCHING specifies whether to in Automatic Graphics Switching, i.e. to allow the system to choose the integrated GPU for the OpenGL context and move it between GPUs if necessary or whether to force it to always run on the discrete GPU. This only affects systems with both integrated and discrete GPUs. Possible values are GLFW_TRUE and GLFW_FALSE. This is ignored on other platforms.

        -

        Simpler programs and tools may want to enable this to save power, while games and other applications performing advanced rendering will want to leave it disabled.

        -

        A bundled application that wishes to participate in Automatic Graphics Switching should also declare this in its Info.plist by setting the NSSupportsAutomaticGraphicsSwitching key to true.

        +macOS specific hints +

        GLFW_COCOA_FRAME_NAME specifies the UTF-8 encoded name to use for autosaving the window frame, or if empty disables frame autosaving for the window. This is ignored on other platforms. This is set with glfwWindowHintString.

        +

        GLFW_COCOA_GRAPHICS_SWITCHING specifies whether to in Automatic Graphics Switching, i.e. to allow the system to choose the integrated GPU for the OpenGL context and move it between GPUs if necessary or whether to force it to always run on the discrete GPU. This only affects systems with both integrated and discrete GPUs. Possible values are GLFW_TRUE and GLFW_FALSE. This is ignored on other platforms.

        +

        Simpler programs and tools may want to enable this to save power, while games and other applications performing advanced rendering will want to leave it disabled.

        +

        A bundled application that wishes to participate in Automatic Graphics Switching should also declare this in its Info.plist by setting the NSSupportsAutomaticGraphicsSwitching key to true.

        +

        +Wayland specific window hints

        +

        GLFW_WAYLAND_APP_ID specifies the Wayland app_id for a window, used by window managers to identify types of windows. This is set with glfwWindowHintString.

        X11 specific window hints

        -

        GLFW_X11_CLASS_NAME and GLFW_X11_INSTANCE_NAME specifies the desired ASCII encoded class and instance parts of the ICCCM WM_CLASS window property. These are set with glfwWindowHintString.

        +

        GLFW_X11_CLASS_NAME and GLFW_X11_INSTANCE_NAME specifies the desired ASCII encoded class and instance parts of the ICCCM WM_CLASS window property. Both hints need to be set to something other than an empty string for them to take effect. These are set with glfwWindowHintString.

        Supported and default values

        @@ -310,6 +331,14 @@ Supported and default values + + + + + + + + @@ -356,15 +385,19 @@ Supported and default values - + - + - + + + + + @@ -372,17 +405,17 @@ Supported and default values
        GLFW_SCALE_TO_MONITOR GLFW_FALSE GLFW_TRUE or GLFW_FALSE
        GLFW_SCALE_FRAMEBUFFER GLFW_TRUE GLFW_TRUE or GLFW_FALSE
        GLFW_MOUSE_PASSTHROUGH GLFW_FALSE GLFW_TRUE or GLFW_FALSE
        GLFW_POSITION_X GLFW_ANY_POSITION Any valid screen x-coordinate or GLFW_ANY_POSITION
        GLFW_POSITION_Y GLFW_ANY_POSITION Any valid screen y-coordinate or GLFW_ANY_POSITION
        GLFW_RED_BITS 8 0 to INT_MAX or GLFW_DONT_CARE
        GLFW_GREEN_BITS 8 0 to INT_MAX or GLFW_DONT_CARE
        GLFW_OPENGL_FORWARD_COMPAT GLFW_FALSE GLFW_TRUE or GLFW_FALSE
        GLFW_OPENGL_DEBUG_CONTEXT GLFW_FALSE GLFW_TRUE or GLFW_FALSE
        GLFW_CONTEXT_DEBUG GLFW_FALSE GLFW_TRUE or GLFW_FALSE
        GLFW_OPENGL_PROFILE GLFW_OPENGL_ANY_PROFILE GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE or GLFW_OPENGL_CORE_PROFILE
        GLFW_COCOA_RETINA_FRAMEBUFFER GLFW_TRUE GLFW_TRUE or GLFW_FALSE
        GLFW_WIN32_KEYBOARD_MENU GLFW_FALSE GLFW_TRUE or GLFW_FALSE
        GLFW_COCOA_FRAME_NAME "" A UTF-8 encoded frame autosave name
        GLFW_WIN32_SHOWDEFAULT GLFW_FALSE GLFW_TRUE or GLFW_FALSE
        GLFW_COCOA_FRAME_NAME "" A UTF-8 encoded frame autosave name
        GLFW_COCOA_GRAPHICS_SWITCHING GLFW_FALSE GLFW_TRUE or GLFW_FALSE
        GLFW_WAYLAND_APP_ID "" An ASCII encoded Wayland app_id name
        GLFW_X11_CLASS_NAME "" An ASCII encoded WM_CLASS class name

        Window event processing

        -

        See Event processing.

        +

        See Event processing.

        Window properties and events

        User pointer

        -

        Each window has a user pointer that can be set with glfwSetWindowUserPointer and queried with glfwGetWindowUserPointer. This can be used for any purpose you need and will not be modified by GLFW throughout the life-time of the window.

        -

        The initial value of the pointer is NULL.

        +

        Each window has a user pointer that can be set with glfwSetWindowUserPointer and queried with glfwGetWindowUserPointer. This can be used for any purpose you need and will not be modified by GLFW throughout the life-time of the window.

        +

        The initial value of the pointer is NULL.

        Window closing and close flag

        -

        When the user attempts to close the window, for example by clicking the close widget or using a key chord like Alt+F4, the close flag of the window is set. The window is however not actually destroyed and, unless you watch for this state change, nothing further happens.

        -

        The current state of the close flag is returned by glfwWindowShouldClose and can be set or cleared directly with glfwSetWindowShouldClose. A common pattern is to use the close flag as a main loop condition.

        +

        When the user attempts to close the window, for example by clicking the close widget or using a key chord like Alt+F4, the close flag of the window is set. The window is however not actually destroyed and, unless you watch for this state change, nothing further happens.

        +

        The current state of the close flag is returned by glfwWindowShouldClose and can be set or cleared directly with glfwSetWindowShouldClose. A common pattern is to use the close flag as a main loop condition.

        while (!glfwWindowShouldClose(window))
        {
        render(window);
        @@ -393,31 +426,31 @@ Window closing and close flag
        void glfwSwapBuffers(GLFWwindow *window)
        Swaps the front and back buffers of the specified window.
        int glfwWindowShouldClose(GLFWwindow *window)
        Checks the close flag of the specified window.
        void glfwPollEvents(void)
        Processes all pending events.
        -

        If you wish to be notified when the user attempts to close a window, set a close callback.

        +

        If you wish to be notified when the user attempts to close a window, set a close callback.

        glfwSetWindowCloseCallback(window, window_close_callback);
        GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow *window, GLFWwindowclosefun callback)
        Sets the close callback for the specified window.
        -

        The callback function is called directly after the close flag has been set. It can be used for example to filter close requests and clear the close flag again unless certain conditions are met.

        +

        The callback function is called directly after the close flag has been set. It can be used for example to filter close requests and clear the close flag again unless certain conditions are met.

        void window_close_callback(GLFWwindow* window)
        {
        if (!time_to_close)
        }
        -
        #define GLFW_FALSE
        Zero.
        Definition: glfw3.h:321
        +
        #define GLFW_FALSE
        Zero.
        Definition glfw3.h:321
        void glfwSetWindowShouldClose(GLFWwindow *window, int value)
        Sets the close flag of the specified window.

        Window size

        -

        The size of a window can be changed with glfwSetWindowSize. For windowed mode windows, this sets the size, in screen coordinates of the content area or content area of the window. The window system may impose limits on window size.

        +

        The size of a window can be changed with glfwSetWindowSize. For windowed mode windows, this sets the size, in screen coordinates of the content area or content area of the window. The window system may impose limits on window size.

        glfwSetWindowSize(window, 640, 480);
        void glfwSetWindowSize(GLFWwindow *window, int width, int height)
        Sets the size of the content area of the specified window.
        -

        For full screen windows, the specified size becomes the new resolution of the window's desired video mode. The video mode most closely matching the new desired video mode is set immediately. The window is resized to fit the resolution of the set video mode.

        -

        If you wish to be notified when a window is resized, whether by the user, the system or your own code, set a size callback.

        +

        For full screen windows, the specified size becomes the new resolution of the window's desired video mode. The video mode most closely matching the new desired video mode is set immediately. The window is resized to fit the resolution of the set video mode.

        +

        If you wish to be notified when a window is resized, whether by the user, the system or your own code, set a size callback.

        glfwSetWindowSizeCallback(window, window_size_callback);
        GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow *window, GLFWwindowsizefun callback)
        Sets the size callback for the specified window.
        -

        The callback function receives the new size, in screen coordinates, of the content area of the window when the window is resized.

        +

        The callback function receives the new size, in screen coordinates, of the content area of the window when the window is resized.

        void window_size_callback(GLFWwindow* window, int width, int height)
        {
        }
        -

        There is also glfwGetWindowSize for directly retrieving the current size of a window.

        +

        There is also glfwGetWindowSize for directly retrieving the current size of a window.

        int width, height;
        glfwGetWindowSize(window, &width, &height);
        void glfwGetWindowSize(GLFWwindow *window, int *width, int *height)
        Retrieves the size of the content area of the specified window.
        @@ -426,127 +459,140 @@ Window size
        int left, top, right, bottom;
        glfwGetWindowFrameSize(window, &left, &top, &right, &bottom);
        void glfwGetWindowFrameSize(GLFWwindow *window, int *left, int *top, int *right, int *bottom)
        Retrieves the size of the frame of the window.
        -

        The returned values are the distances, in screen coordinates, from the edges of the content area to the corresponding edges of the full window. As they are distances and not coordinates, they are always zero or positive.

        +

        The returned values are the distances, in screen coordinates, from the edges of the content area to the corresponding edges of the full window. As they are distances and not coordinates, they are always zero or positive.

        Framebuffer size

        -

        While the size of a window is measured in screen coordinates, OpenGL works with pixels. The size you pass into glViewport, for example, should be in pixels. On some machines screen coordinates and pixels are the same, but on others they will not be. There is a second set of functions to retrieve the size, in pixels, of the framebuffer of a window.

        -

        If you wish to be notified when the framebuffer of a window is resized, whether by the user or the system, set a size callback.

        +

        While the size of a window is measured in screen coordinates, OpenGL works with pixels. The size you pass into glViewport, for example, should be in pixels. On some machines screen coordinates and pixels are the same, but on others they will not be. There is a second set of functions to retrieve the size, in pixels, of the framebuffer of a window.

        +

        If you wish to be notified when the framebuffer of a window is resized, whether by the user or the system, set a size callback.

        glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
        GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow *window, GLFWframebuffersizefun callback)
        Sets the framebuffer resize callback for the specified window.
        -

        The callback function receives the new size of the framebuffer when it is resized, which can for example be used to update the OpenGL viewport.

        +

        The callback function receives the new size of the framebuffer when it is resized, which can for example be used to update the OpenGL viewport.

        void framebuffer_size_callback(GLFWwindow* window, int width, int height)
        {
        glViewport(0, 0, width, height);
        }
        -

        There is also glfwGetFramebufferSize for directly retrieving the current size of the framebuffer of a window.

        +

        There is also glfwGetFramebufferSize for directly retrieving the current size of the framebuffer of a window.

        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        glViewport(0, 0, width, height);
        void glfwGetFramebufferSize(GLFWwindow *window, int *width, int *height)
        Retrieves the size of the framebuffer of the specified window.
        -

        The size of a framebuffer may change independently of the size of a window, for example if the window is dragged between a regular monitor and a high-DPI one.

        +

        The size of a framebuffer may change independently of the size of a window, for example if the window is dragged between a regular monitor and a high-DPI one.

        Window content scale

        -

        The content scale for a window can be retrieved with glfwGetWindowContentScale.

        +

        The content scale for a window can be retrieved with glfwGetWindowContentScale.

        float xscale, yscale;
        glfwGetWindowContentScale(window, &xscale, &yscale);
        void glfwGetWindowContentScale(GLFWwindow *window, float *xscale, float *yscale)
        Retrieves the content scale for the specified window.
        -

        The content scale is the ratio between the current DPI and the platform's default DPI. This is especially important for text and any UI elements. If the pixel dimensions of your UI scaled by this look appropriate on your machine then it should appear at a reasonable size on other machines regardless of their DPI and scaling settings. This relies on the system DPI and scaling settings being somewhat correct.

        -

        On systems where each monitors can have its own content scale, the window content scale will depend on which monitor the system considers the window to be on.

        -

        If you wish to be notified when the content scale of a window changes, whether because of a system setting change or because it was moved to a monitor with a different scale, set a content scale callback.

        +

        The content scale can be thought of as the ratio between the current DPI and the platform's default DPI. It is intended to be a scaling factor to apply to the pixel dimensions of text and other UI elements. If the dimensions scaled by this factor looks appropriate on your machine then it should appear at a reasonable size on other machines with different DPI and scaling settings.

        +

        This relies on the DPI and scaling settings on both machines being appropriate.

        +

        The content scale may depend on both the monitor resolution and pixel density and on user settings like DPI or a scaling percentage. It may be very different from the raw DPI calculated from the physical size and current resolution.

        +

        On systems where each monitors can have its own content scale, the window content scale will depend on which monitor or monitors the system considers the window to be "on".

        +

        If you wish to be notified when the content scale of a window changes, whether because of a system setting change or because it was moved to a monitor with a different scale, set a content scale callback.

        glfwSetWindowContentScaleCallback(window, window_content_scale_callback);
        GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow *window, GLFWwindowcontentscalefun callback)
        Sets the window content scale callback for the specified window.
        -

        The callback function receives the new content scale of the window.

        +

        The callback function receives the new content scale of the window.

        void window_content_scale_callback(GLFWwindow* window, float xscale, float yscale)
        {
        set_interface_scale(xscale, yscale);
        }
        -

        On platforms where pixels and screen coordinates always map 1:1, the window will need to be resized to appear the same size when it is moved to a monitor with a different content scale. To have this done automatically both when the window is created and when its content scale later changes, set the GLFW_SCALE_TO_MONITOR window hint.

        +

        On platforms where pixels and screen coordinates always map 1:1, the window will need to be resized to appear the same size when it is moved to a monitor with a different content scale. To have this done automatically both when the window is created and when its content scale later changes, set the GLFW_SCALE_TO_MONITOR window hint.

        +

        On platforms where pixels do not necessarily equal screen coordinates, the framebuffer will instead need to be sized to provide a full resolution image for the window. When the window moves between monitors with different content scales, the window size will remain the same but the framebuffer size will change. This is done automatically by default. To disable this resizing, set the GLFW_SCALE_FRAMEBUFFER window hint.

        +

        Both of these hints also apply when the window is created. Every window starts out with a content scale of one. A window with one or both of these hints set will adapt to the appropriate scale in the process of being created, set up and shown.

        Window size limits

        -

        The minimum and maximum size of the content area of a windowed mode window can be enforced with glfwSetWindowSizeLimits. The user may resize the window to any size and aspect ratio within the specified limits, unless the aspect ratio is also set.

        +

        The minimum and maximum size of the content area of a windowed mode window can be enforced with glfwSetWindowSizeLimits. The user may resize the window to any size and aspect ratio within the specified limits, unless the aspect ratio is also set.

        glfwSetWindowSizeLimits(window, 200, 200, 400, 400);
        void glfwSetWindowSizeLimits(GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)
        Sets the size limits of the specified window.
        -

        To specify only a minimum size or only a maximum one, set the other pair to GLFW_DONT_CARE.

        +

        To specify only a minimum size or only a maximum one, set the other pair to GLFW_DONT_CARE.

        -
        #define GLFW_DONT_CARE
        Definition: glfw3.h:1128
        -

        To disable size limits for a window, set them all to GLFW_DONT_CARE.

        -

        The aspect ratio of the content area of a windowed mode window can be enforced with glfwSetWindowAspectRatio. The user may resize the window freely unless size limits are also set, but the size will be constrained to maintain the aspect ratio.

        +
        #define GLFW_DONT_CARE
        Definition glfw3.h:1346
        +

        To disable size limits for a window, set them all to GLFW_DONT_CARE.

        +

        The aspect ratio of the content area of a windowed mode window can be enforced with glfwSetWindowAspectRatio. The user may resize the window freely unless size limits are also set, but the size will be constrained to maintain the aspect ratio.

        glfwSetWindowAspectRatio(window, 16, 9);
        void glfwSetWindowAspectRatio(GLFWwindow *window, int numer, int denom)
        Sets the aspect ratio of the specified window.
        -

        The aspect ratio is specified as a numerator and denominator, corresponding to the width and height, respectively. If you want a window to maintain its current aspect ratio, use its current size as the ratio.

        +

        The aspect ratio is specified as a numerator and denominator, corresponding to the width and height, respectively. If you want a window to maintain its current aspect ratio, use its current size as the ratio.

        int width, height;
        glfwGetWindowSize(window, &width, &height);
        glfwSetWindowAspectRatio(window, width, height);
        -

        To disable the aspect ratio limit for a window, set both terms to GLFW_DONT_CARE.

        -

        You can have both size limits and aspect ratio set for a window, but the results are undefined if they conflict.

        +

        To disable the aspect ratio limit for a window, set both terms to GLFW_DONT_CARE.

        +

        You can have both size limits and aspect ratio set for a window, but the results are undefined if they conflict.

        Window position

        -

        The position of a windowed-mode window can be changed with glfwSetWindowPos. This moves the window so that the upper-left corner of its content area has the specified screen coordinates. The window system may put limitations on window placement.

        +

        By default, the window manager chooses the position of new windowed mode windows, based on its size and which monitor the user appears to be working on. This is most often the right choice. If you need to create a window at a specific position, you can set the desired position with the GLFW_POSITION_X and GLFW_POSITION_Y window hints.

        +
        + +
        #define GLFW_POSITION_Y
        Initial position y-coordinate window hint.
        Definition glfw3.h:942
        +
        #define GLFW_POSITION_X
        Initial position x-coordinate window hint.
        Definition glfw3.h:936
        +

        To restore the previous behavior, set these hints to GLFW_ANY_POSITION.

        +

        The position of a windowed mode window can be changed with glfwSetWindowPos. This moves the window so that the upper-left corner of its content area has the specified screen coordinates. The window system may put limitations on window placement.

        glfwSetWindowPos(window, 100, 100);
        void glfwSetWindowPos(GLFWwindow *window, int xpos, int ypos)
        Sets the position of the content area of the specified window.
        -

        If you wish to be notified when a window is moved, whether by the user, the system or your own code, set a position callback.

        +

        If you wish to be notified when a window is moved, whether by the user, the system or your own code, set a position callback.

        glfwSetWindowPosCallback(window, window_pos_callback);
        GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow *window, GLFWwindowposfun callback)
        Sets the position callback for the specified window.
        -

        The callback function receives the new position, in screen coordinates, of the upper-left corner of the content area when the window is moved.

        +

        The callback function receives the new position, in screen coordinates, of the upper-left corner of the content area when the window is moved.

        void window_pos_callback(GLFWwindow* window, int xpos, int ypos)
        {
        }
        -

        There is also glfwGetWindowPos for directly retrieving the current position of the content area of the window.

        +

        There is also glfwGetWindowPos for directly retrieving the current position of the content area of the window.

        int xpos, ypos;
        glfwGetWindowPos(window, &xpos, &ypos);
        void glfwGetWindowPos(GLFWwindow *window, int *xpos, int *ypos)
        Retrieves the position of the content area of the specified window.

        Window title

        -

        All GLFW windows have a title, although undecorated or full screen windows may not display it or only display it in a task bar or similar interface. You can set a UTF-8 encoded window title with glfwSetWindowTitle.

        +

        All GLFW windows have a title, although undecorated or full screen windows may not display it or only display it in a task bar or similar interface. You can set a new UTF-8 encoded window title with glfwSetWindowTitle.

        glfwSetWindowTitle(window, "My Window");
        void glfwSetWindowTitle(GLFWwindow *window, const char *title)
        Sets the title of the specified window.
        -

        The specified string is copied before the function returns, so there is no need to keep it around.

        -

        As long as your source file is encoded as UTF-8, you can use any Unicode characters directly in the source.

        +

        The specified string is copied before the function returns, so there is no need to keep it around.

        +

        As long as your source file is encoded as UTF-8, you can use any Unicode characters directly in the source.

        glfwSetWindowTitle(window, "ラストエグザイル");
        -

        If you are using C++11 or C11, you can use a UTF-8 string literal.

        +

        If you are using C++11 or C11, you can use a UTF-8 string literal.

        glfwSetWindowTitle(window, u8"This is always a UTF-8 string");
        +

        The current window title can be queried with glfwGetWindowTitle.

        +
        const char* title = glfwGetWindowTitle(window);
        +
        const char * glfwGetWindowTitle(GLFWwindow *window)
        Returns the title of the specified window.

        Window icon

        -

        Decorated windows have icons on some platforms. You can set this icon by specifying a list of candidate images with glfwSetWindowIcon.

        -
        GLFWimage images[2];
        +

        Decorated windows have icons on some platforms. You can set this icon by specifying a list of candidate images with glfwSetWindowIcon.

        +
        GLFWimage images[2];
        images[0] = load_icon("my_icon.png");
        images[1] = load_icon("my_icon_small.png");
        glfwSetWindowIcon(window, 2, images);
        void glfwSetWindowIcon(GLFWwindow *window, int count, const GLFWimage *images)
        Sets the icon for the specified window.
        -
        Image data.
        Definition: glfw3.h:1721
        -

        The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits per channel with the red channel first. The pixels are arranged canonically as sequential rows, starting from the top-left corner.

        -

        To revert to the default window icon, pass in an empty image array.

        +
        Image data.
        Definition glfw3.h:2090
        +

        The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits per channel with the red channel first. The pixels are arranged canonically as sequential rows, starting from the top-left corner.

        +

        To revert to the default window icon, pass in an empty image array.

        glfwSetWindowIcon(window, 0, NULL);

        Window monitor

        -

        Full screen windows are associated with a specific monitor. You can get the handle for this monitor with glfwGetWindowMonitor.

        +

        Full screen windows are associated with a specific monitor. You can get the handle for this monitor with glfwGetWindowMonitor.

        GLFWmonitor* monitor = glfwGetWindowMonitor(window);
        -
        struct GLFWmonitor GLFWmonitor
        Opaque monitor object.
        Definition: glfw3.h:1173
        +
        struct GLFWmonitor GLFWmonitor
        Opaque monitor object.
        Definition glfw3.h:1391
        GLFWmonitor * glfwGetWindowMonitor(GLFWwindow *window)
        Returns the monitor that the window uses for full screen mode.
        -

        This monitor handle is one of those returned by glfwGetMonitors.

        -

        For windowed mode windows, this function returns NULL. This is how to tell full screen windows from windowed mode windows.

        -

        You can move windows between monitors or between full screen and windowed mode with glfwSetWindowMonitor. When making a window full screen on the same or on a different monitor, specify the desired monitor, resolution and refresh rate. The position arguments are ignored.

        -
        const GLFWvidmode* mode = glfwGetVideoMode(monitor);
        +

        This monitor handle is one of those returned by glfwGetMonitors.

        +

        For windowed mode windows, this function returns NULL. This is how to tell full screen windows from windowed mode windows.

        +

        You can move windows between monitors or between full screen and windowed mode with glfwSetWindowMonitor. When making a window full screen on the same or on a different monitor, specify the desired monitor, resolution and refresh rate. The position arguments are ignored.

        +
        const GLFWvidmode* mode = glfwGetVideoMode(monitor);
        -
        glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
        -

        When making the window windowed, specify the desired position and size. The refresh rate argument is ignored.

        +
        glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
        +

        When making the window windowed, specify the desired position and size. The refresh rate argument is ignored.

        glfwSetWindowMonitor(window, NULL, xpos, ypos, width, height, 0);
        -

        This restores any previous window settings such as whether it is decorated, floating, resizable, has size or aspect ratio limits, etc.. To restore a window that was originally windowed to its original size and position, save these before making it full screen and then pass them in as above.

        +

        This restores any previous window settings such as whether it is decorated, floating, resizable, has size or aspect ratio limits, etc.. To restore a window that was originally windowed to its original size and position, save these before making it full screen and then pass them in as above.

        Window iconification

        -

        Windows can be iconified (i.e. minimized) with glfwIconifyWindow.

        +

        Windows can be iconified (i.e. minimized) with glfwIconifyWindow.

        void glfwIconifyWindow(GLFWwindow *window)
        Iconifies the specified window.
        -

        When a full screen window is iconified, the original video mode of its monitor is restored until the user or application restores the window.

        -

        Iconified windows can be restored with glfwRestoreWindow. This function also restores windows from maximization.

        +

        When a full screen window is iconified, the original video mode of its monitor is restored until the user or application restores the window.

        +

        Iconified windows can be restored with glfwRestoreWindow. This function also restores windows from maximization.

        void glfwRestoreWindow(GLFWwindow *window)
        Restores the specified window.
        -

        When a full screen window is restored, the desired video mode is restored to its monitor as well.

        -

        If you wish to be notified when a window is iconified or restored, whether by the user, system or your own code, set an iconify callback.

        +

        When a full screen window is restored, the desired video mode is restored to its monitor as well.

        +

        If you wish to be notified when a window is iconified or restored, whether by the user, system or your own code, set an iconify callback.

        glfwSetWindowIconifyCallback(window, window_iconify_callback);
        GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow *window, GLFWwindowiconifyfun callback)
        Sets the iconify callback for the specified window.
        -

        The callback function receives changes in the iconification state of the window.

        +

        The callback function receives changes in the iconification state of the window.

        void window_iconify_callback(GLFWwindow* window, int iconified)
        {
        if (iconified)
        @@ -558,22 +604,22 @@ Window iconification
        // The window was restored
        }
        }
        -

        You can also get the current iconification state with glfwGetWindowAttrib.

        +

        You can also get the current iconification state with glfwGetWindowAttrib.

        int iconified = glfwGetWindowAttrib(window, GLFW_ICONIFIED);
        -
        #define GLFW_ICONIFIED
        Window iconification window attribute.
        Definition: glfw3.h:802
        +
        #define GLFW_ICONIFIED
        Window iconification window attribute.
        Definition glfw3.h:864
        int glfwGetWindowAttrib(GLFWwindow *window, int attrib)
        Returns an attribute of the specified window.

        Window maximization

        -

        Windows can be maximized (i.e. zoomed) with glfwMaximizeWindow.

        +

        Windows can be maximized (i.e. zoomed) with glfwMaximizeWindow.

        void glfwMaximizeWindow(GLFWwindow *window)
        Maximizes the specified window.
        -

        Full screen windows cannot be maximized and passing a full screen window to this function does nothing.

        -

        Maximized windows can be restored with glfwRestoreWindow. This function also restores windows from iconification.

        +

        Full screen windows cannot be maximized and passing a full screen window to this function does nothing.

        +

        Maximized windows can be restored with glfwRestoreWindow. This function also restores windows from iconification.

        If you wish to be notified when a window is maximized or restored, whether by the user, system or your own code, set a maximize callback.

        +

        If you wish to be notified when a window is maximized or restored, whether by the user, system or your own code, set a maximize callback.

        glfwSetWindowMaximizeCallback(window, window_maximize_callback);
        GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow *window, GLFWwindowmaximizefun callback)
        Sets the maximize callback for the specified window.
        -

        The callback function receives changes in the maximization state of the window.

        +

        The callback function receives changes in the maximization state of the window.

        void window_maximize_callback(GLFWwindow* window, int maximized)
        {
        if (maximized)
        @@ -585,38 +631,38 @@ Window maximization
        // The window was restored
        }
        }
        -

        You can also get the current maximization state with glfwGetWindowAttrib.

        +

        You can also get the current maximization state with glfwGetWindowAttrib.

        int maximized = glfwGetWindowAttrib(window, GLFW_MAXIMIZED);
        -
        #define GLFW_MAXIMIZED
        Window maximization window hint and attribute.
        Definition: glfw3.h:838
        -

        By default, newly created windows are not maximized. You can change this behavior by setting the GLFW_MAXIMIZED window hint before creating the window.

        +
        #define GLFW_MAXIMIZED
        Window maximization window hint and attribute.
        Definition glfw3.h:900
        +

        By default, newly created windows are not maximized. You can change this behavior by setting the GLFW_MAXIMIZED window hint before creating the window.

        -
        #define GLFW_TRUE
        One.
        Definition: glfw3.h:312
        +
        #define GLFW_TRUE
        One.
        Definition glfw3.h:312

        Window visibility

        -

        Windowed mode windows can be hidden with glfwHideWindow.

        +

        Windowed mode windows can be hidden with glfwHideWindow.

        void glfwHideWindow(GLFWwindow *window)
        Hides the specified window.
        -

        This makes the window completely invisible to the user, including removing it from the task bar, dock or window list. Full screen windows cannot be hidden and calling glfwHideWindow on a full screen window does nothing.

        -

        Hidden windows can be shown with glfwShowWindow.

        +

        This makes the window completely invisible to the user, including removing it from the task bar, dock or window list. Full screen windows cannot be hidden and calling glfwHideWindow on a full screen window does nothing.

        +

        Hidden windows can be shown with glfwShowWindow.

        void glfwShowWindow(GLFWwindow *window)
        Makes the specified window visible.
        -

        By default, this function will also set the input focus to that window. Set the GLFW_FOCUS_ON_SHOW window hint to change this behavior for all newly created windows, or change the behavior for an existing window with glfwSetWindowAttrib.

        -

        You can also get the current visibility state with glfwGetWindowAttrib.

        +

        By default, this function will also set the input focus to that window. Set the GLFW_FOCUS_ON_SHOW window hint to change this behavior for all newly created windows, or change the behavior for an existing window with glfwSetWindowAttrib.

        +

        You can also get the current visibility state with glfwGetWindowAttrib.

        int visible = glfwGetWindowAttrib(window, GLFW_VISIBLE);
        -
        #define GLFW_VISIBLE
        Window visibility window hint and attribute.
        Definition: glfw3.h:814
        -

        By default, newly created windows are visible. You can change this behavior by setting the GLFW_VISIBLE window hint before creating the window.

        +
        #define GLFW_VISIBLE
        Window visibility window hint and attribute.
        Definition glfw3.h:876
        +

        By default, newly created windows are visible. You can change this behavior by setting the GLFW_VISIBLE window hint before creating the window.

        Windows created hidden are completely invisible to the user until shown. This can be useful if you need to set up your window further before showing it, for example moving it to a specific location.

        +

        Windows created hidden are completely invisible to the user until shown. This can be useful if you need to set up your window further before showing it, for example moving it to a specific location.

        Window input focus

        -

        Windows can be given input focus and brought to the front with glfwFocusWindow.

        +

        Windows can be given input focus and brought to the front with glfwFocusWindow.

        void glfwFocusWindow(GLFWwindow *window)
        Brings the specified window to front and sets input focus.
        -

        Keep in mind that it can be very disruptive to the user when a window is forced to the top. For a less disruptive way of getting the user's attention, see attention requests.

        -

        If you wish to be notified when a window gains or loses input focus, whether by the user, system or your own code, set a focus callback.

        +

        Keep in mind that it can be very disruptive to the user when a window is forced to the top. For a less disruptive way of getting the user's attention, see attention requests.

        +

        If you wish to be notified when a window gains or loses input focus, whether by the user, system or your own code, set a focus callback.

        glfwSetWindowFocusCallback(window, window_focus_callback);
        GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow *window, GLFWwindowfocusfun callback)
        Sets the focus callback for the specified window.
        -

        The callback function receives changes in the input focus state of the window.

        +

        The callback function receives changes in the input focus state of the window.

        void window_focus_callback(GLFWwindow* window, int focused)
        {
        if (focused)
        @@ -628,23 +674,23 @@ Window input focus
        // The window lost input focus
        }
        }
        -

        You can also get the current input focus state with glfwGetWindowAttrib.

        +

        You can also get the current input focus state with glfwGetWindowAttrib.

        int focused = glfwGetWindowAttrib(window, GLFW_FOCUSED);
        -
        #define GLFW_FOCUSED
        Input focus window hint and attribute.
        Definition: glfw3.h:797
        -

        By default, newly created windows are given input focus. You can change this behavior by setting the GLFW_FOCUSED window hint before creating the window.

        +
        #define GLFW_FOCUSED
        Input focus window hint and attribute.
        Definition glfw3.h:859
        +

        By default, newly created windows are given input focus. You can change this behavior by setting the GLFW_FOCUSED window hint before creating the window.

        Window attention request

        -

        If you wish to notify the user of an event without interrupting, you can request attention with glfwRequestWindowAttention.

        +

        If you wish to notify the user of an event without interrupting, you can request attention with glfwRequestWindowAttention.

        void glfwRequestWindowAttention(GLFWwindow *window)
        Requests user attention to the specified window.
        -

        The system will highlight the specified window, or on platforms where this is not supported, the application as a whole. Once the user has given it attention, the system will automatically end the request.

        +

        The system will highlight the specified window, or on platforms where this is not supported, the application as a whole. Once the user has given it attention, the system will automatically end the request.

        Window damage and refresh

        -

        If you wish to be notified when the contents of a window is damaged and needs to be refreshed, set a window refresh callback.

        +

        If you wish to be notified when the contents of a window is damaged and needs to be refreshed, set a window refresh callback.

        glfwSetWindowRefreshCallback(m_handle, window_refresh_callback);
        GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow *window, GLFWwindowrefreshfun callback)
        Sets the refresh callback for the specified window.
        -

        The callback function is called when the contents of the window needs to be refreshed.

        +

        The callback function is called when the contents of the window needs to be refreshed.

        void window_refresh_callback(GLFWwindow* window)
        {
        draw_editor_ui(window);
        @@ -653,68 +699,71 @@ Window damage and refresh
        Note
        On compositing window systems such as Aero, Compiz or Aqua, where the window contents are saved off-screen, this callback might only be called when the window or framebuffer is resized.

        Window transparency

        -

        GLFW supports two kinds of transparency for windows; framebuffer transparency and whole window transparency. A single window may not use both methods. The results of doing this are undefined.

        -

        Both methods require the platform to support it and not every version of every platform GLFW supports does this, so there are mechanisms to check whether the window really is transparent.

        -

        Window framebuffers can be made transparent on a per-pixel per-frame basis with the GLFW_TRANSPARENT_FRAMEBUFFER window hint.

        +

        GLFW supports two kinds of transparency for windows; framebuffer transparency and whole window transparency. A single window may not use both methods. The results of doing this are undefined.

        +

        Both methods require the platform to support it and not every version of every platform GLFW supports does this, so there are mechanisms to check whether the window really is transparent.

        +

        Window framebuffers can be made transparent on a per-pixel per-frame basis with the GLFW_TRANSPARENT_FRAMEBUFFER window hint.

        -
        #define GLFW_TRANSPARENT_FRAMEBUFFER
        Window framebuffer transparency hint and attribute.
        Definition: glfw3.h:850
        -

        If supported by the system, the window content area will be composited with the background using the framebuffer per-pixel alpha channel. This requires desktop compositing to be enabled on the system. It does not affect window decorations.

        -

        You can check whether the window framebuffer was successfully made transparent with the GLFW_TRANSPARENT_FRAMEBUFFER window attribute.

        +
        #define GLFW_TRANSPARENT_FRAMEBUFFER
        Window framebuffer transparency hint and attribute.
        Definition glfw3.h:912
        +

        If supported by the system, the window content area will be composited with the background using the framebuffer per-pixel alpha channel. This requires desktop compositing to be enabled on the system. It does not affect window decorations.

        +

        You can check whether the window framebuffer was successfully made transparent with the GLFW_TRANSPARENT_FRAMEBUFFER window attribute.

        {
        // window framebuffer is currently transparent
        }
        -

        GLFW comes with an example that enabled framebuffer transparency called gears.

        -

        The opacity of the whole window, including any decorations, can be set with glfwSetWindowOpacity.

        +

        GLFW comes with an example that enabled framebuffer transparency called gears.

        +

        The opacity of the whole window, including any decorations, can be set with glfwSetWindowOpacity.

        glfwSetWindowOpacity(window, 0.5f);
        void glfwSetWindowOpacity(GLFWwindow *window, float opacity)
        Sets the opacity of the whole window.
        -

        The opacity (or alpha) value is a positive finite number between zero and one, where 0 (zero) is fully transparent and 1 (one) is fully opaque. The initial opacity value for newly created windows is 1.

        -

        The current opacity of a window can be queried with glfwGetWindowOpacity.

        +

        The opacity (or alpha) value is a positive finite number between zero and one, where 0 (zero) is fully transparent and 1 (one) is fully opaque. The initial opacity value for newly created windows is 1.

        +

        The current opacity of a window can be queried with glfwGetWindowOpacity.

        float opacity = glfwGetWindowOpacity(window);
        float glfwGetWindowOpacity(GLFWwindow *window)
        Returns the opacity of the whole window.
        -

        If the system does not support whole window transparency, this function always returns one.

        -

        GLFW comes with a test program that lets you control whole window transparency at run-time called opacity.

        +

        If the system does not support whole window transparency, this function always returns one.

        +

        GLFW comes with a test program that lets you control whole window transparency at run-time called window.

        +

        If you want to use either of these transparency methods to display a temporary overlay like for example a notification, the GLFW_FLOATING and GLFW_MOUSE_PASSTHROUGH window hints and attributes may be useful.

        Window attributes

        -

        Windows have a number of attributes that can be returned using glfwGetWindowAttrib. Some reflect state that may change as a result of user interaction, (e.g. whether it has input focus), while others reflect inherent properties of the window (e.g. what kind of border it has). Some are related to the window and others to its OpenGL or OpenGL ES context.

        +

        Windows have a number of attributes that can be returned using glfwGetWindowAttrib. Some reflect state that may change as a result of user interaction, (e.g. whether it has input focus), while others reflect inherent properties of the window (e.g. what kind of border it has). Some are related to the window and others to its OpenGL or OpenGL ES context.

        {
        // window has input focus
        }
        -

        The GLFW_DECORATED, GLFW_RESIZABLE, GLFW_FLOATING, GLFW_AUTO_ICONIFY and GLFW_FOCUS_ON_SHOW window attributes can be changed with glfwSetWindowAttrib.

        +

        The GLFW_DECORATED, GLFW_RESIZABLE, GLFW_FLOATING, GLFW_AUTO_ICONIFY and GLFW_FOCUS_ON_SHOW window attributes can be changed with glfwSetWindowAttrib.

        void glfwSetWindowAttrib(GLFWwindow *window, int attrib, int value)
        Sets an attribute of the specified window.
        -
        #define GLFW_RESIZABLE
        Window resize-ability window hint and attribute.
        Definition: glfw3.h:808
        +
        #define GLFW_RESIZABLE
        Window resize-ability window hint and attribute.
        Definition glfw3.h:870

        Window related attributes

        -

        GLFW_FOCUSED indicates whether the specified window has input focus. See Window input focus for details.

        -

        GLFW_ICONIFIED indicates whether the specified window is iconified. See Window iconification for details.

        -

        GLFW_MAXIMIZED indicates whether the specified window is maximized. See Window maximization for details.

        -

        GLFW_HOVERED indicates whether the cursor is currently directly over the content area of the window, with no other windows between. See Cursor enter/leave events for details.

        -

        GLFW_VISIBLE indicates whether the specified window is visible. See Window visibility for details.

        -

        GLFW_RESIZABLE indicates whether the specified window is resizable by the user. This can be set before creation with the GLFW_RESIZABLE window hint or after with glfwSetWindowAttrib.

        -

        GLFW_DECORATED indicates whether the specified window has decorations such as a border, a close widget, etc. This can be set before creation with the GLFW_DECORATED window hint or after with glfwSetWindowAttrib.

        -

        GLFW_AUTO_ICONIFY indicates whether the specified full screen window is iconified on focus loss, a close widget, etc. This can be set before creation with the GLFW_AUTO_ICONIFY window hint or after with glfwSetWindowAttrib.

        -

        GLFW_FLOATING indicates whether the specified window is floating, also called topmost or always-on-top. This can be set before creation with the GLFW_FLOATING window hint or after with glfwSetWindowAttrib.

        -

        GLFW_TRANSPARENT_FRAMEBUFFER indicates whether the specified window has a transparent framebuffer, i.e. the window contents is composited with the background using the window framebuffer alpha channel. See Window transparency for details.

        -

        GLFW_FOCUS_ON_SHOW specifies whether the window will be given input focus when glfwShowWindow is called. This can be set before creation with the GLFW_FOCUS_ON_SHOW window hint or after with glfwSetWindowAttrib.

        +

        GLFW_FOCUSED indicates whether the specified window has input focus. See Window input focus for details.

        +

        GLFW_ICONIFIED indicates whether the specified window is iconified. See Window iconification for details.

        +

        GLFW_MAXIMIZED indicates whether the specified window is maximized. See Window maximization for details.

        +

        GLFW_HOVERED indicates whether the cursor is currently directly over the content area of the window, with no other windows between. See Cursor enter/leave events for details.

        +

        GLFW_VISIBLE indicates whether the specified window is visible. See Window visibility for details.

        +

        GLFW_RESIZABLE indicates whether the specified window is resizable by the user. This can be set before creation with the GLFW_RESIZABLE window hint or after with glfwSetWindowAttrib.

        +

        GLFW_DECORATED indicates whether the specified window has decorations such as a border, a close widget, etc. This can be set before creation with the GLFW_DECORATED window hint or after with glfwSetWindowAttrib.

        +

        GLFW_AUTO_ICONIFY indicates whether the specified full screen window is iconified on focus loss, a close widget, etc. This can be set before creation with the GLFW_AUTO_ICONIFY window hint or after with glfwSetWindowAttrib.

        +

        GLFW_FLOATING indicates whether the specified window is floating, also called topmost or always-on-top. This can be set before creation with the GLFW_FLOATING window hint or after with glfwSetWindowAttrib.

        +

        GLFW_TRANSPARENT_FRAMEBUFFER indicates whether the specified window has a transparent framebuffer, i.e. the window contents is composited with the background using the window framebuffer alpha channel. See Window transparency for details.

        +

        GLFW_FOCUS_ON_SHOW specifies whether the window will be given input focus when glfwShowWindow is called. This can be set before creation with the GLFW_FOCUS_ON_SHOW window hint or after with glfwSetWindowAttrib.

        +

        GLFW_MOUSE_PASSTHROUGH specifies whether the window is transparent to mouse input, letting any mouse events pass through to whatever window is behind it. This can be set before creation with the GLFW_MOUSE_PASSTHROUGH window hint or after with glfwSetWindowAttrib. This is only supported for undecorated windows. Decorated windows with this enabled will behave differently between platforms.

        Context related attributes

        -

        GLFW_CLIENT_API indicates the client API provided by the window's context; either GLFW_OPENGL_API, GLFW_OPENGL_ES_API or GLFW_NO_API.

        -

        GLFW_CONTEXT_CREATION_API indicates the context creation API used to create the window's context; either GLFW_NATIVE_CONTEXT_API, GLFW_EGL_CONTEXT_API or GLFW_OSMESA_CONTEXT_API.

        -

        GLFW_CONTEXT_VERSION_MAJOR, GLFW_CONTEXT_VERSION_MINOR and GLFW_CONTEXT_REVISION indicate the client API version of the window's context.

        +

        GLFW_CLIENT_API indicates the client API provided by the window's context; either GLFW_OPENGL_API, GLFW_OPENGL_ES_API or GLFW_NO_API.

        +

        GLFW_CONTEXT_CREATION_API indicates the context creation API used to create the window's context; either GLFW_NATIVE_CONTEXT_API, GLFW_EGL_CONTEXT_API or GLFW_OSMESA_CONTEXT_API.

        +

        GLFW_CONTEXT_VERSION_MAJOR, GLFW_CONTEXT_VERSION_MINOR and GLFW_CONTEXT_REVISION indicate the client API version of the window's context.

        Note
        Do not confuse these attributes with GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR and GLFW_VERSION_REVISION which provide the API version of the GLFW header.

        GLFW_OPENGL_FORWARD_COMPAT is GLFW_TRUE if the window's context is an OpenGL forward-compatible one, or GLFW_FALSE otherwise.

        -

        GLFW_OPENGL_DEBUG_CONTEXT is GLFW_TRUE if the window's context is in debug mode, or GLFW_FALSE otherwise.

        -

        GLFW_OPENGL_PROFILE indicates the OpenGL profile used by the context. This is GLFW_OPENGL_CORE_PROFILE or GLFW_OPENGL_COMPAT_PROFILE if the context uses a known profile, or GLFW_OPENGL_ANY_PROFILE if the OpenGL profile is unknown or the context is an OpenGL ES context. Note that the returned profile may not match the profile bits of the context flags, as GLFW will try other means of detecting the profile when no bits are set.

        -

        GLFW_CONTEXT_RELEASE_BEHAVIOR indicates the release used by the context. Possible values are one of GLFW_ANY_RELEASE_BEHAVIOR, GLFW_RELEASE_BEHAVIOR_FLUSH or GLFW_RELEASE_BEHAVIOR_NONE. If the behavior is GLFW_ANY_RELEASE_BEHAVIOR, the default behavior of the context creation API will be used. If the behavior is GLFW_RELEASE_BEHAVIOR_FLUSH, the pipeline will be flushed whenever the context is released from being the current one. If the behavior is GLFW_RELEASE_BEHAVIOR_NONE, the pipeline will not be flushed on release.

        -

        GLFW_CONTEXT_NO_ERROR indicates whether errors are generated by the context. Possible values are GLFW_TRUE and GLFW_FALSE. If enabled, situations that would have generated errors instead cause undefined behavior.

        -

        GLFW_CONTEXT_ROBUSTNESS indicates the robustness strategy used by the context. This is GLFW_LOSE_CONTEXT_ON_RESET or GLFW_NO_RESET_NOTIFICATION if the window's context supports robustness, or GLFW_NO_ROBUSTNESS otherwise.

        +

        GLFW_CONTEXT_DEBUG is GLFW_TRUE if the window's context is in debug mode, or GLFW_FALSE otherwise.

        +

        This is the new name, introduced in GLFW 3.4. The older GLFW_OPENGL_DEBUG_CONTEXT name is also available for compatibility.

        +

        GLFW_OPENGL_PROFILE indicates the OpenGL profile used by the context. This is GLFW_OPENGL_CORE_PROFILE or GLFW_OPENGL_COMPAT_PROFILE if the context uses a known profile, or GLFW_OPENGL_ANY_PROFILE if the OpenGL profile is unknown or the context is an OpenGL ES context. Note that the returned profile may not match the profile bits of the context flags, as GLFW will try other means of detecting the profile when no bits are set.

        +

        GLFW_CONTEXT_RELEASE_BEHAVIOR indicates the release used by the context. Possible values are one of GLFW_ANY_RELEASE_BEHAVIOR, GLFW_RELEASE_BEHAVIOR_FLUSH or GLFW_RELEASE_BEHAVIOR_NONE. If the behavior is GLFW_ANY_RELEASE_BEHAVIOR, the default behavior of the context creation API will be used. If the behavior is GLFW_RELEASE_BEHAVIOR_FLUSH, the pipeline will be flushed whenever the context is released from being the current one. If the behavior is GLFW_RELEASE_BEHAVIOR_NONE, the pipeline will not be flushed on release.

        +

        GLFW_CONTEXT_NO_ERROR indicates whether errors are generated by the context. Possible values are GLFW_TRUE and GLFW_FALSE. If enabled, situations that would have generated errors instead cause undefined behavior.

        +

        GLFW_CONTEXT_ROBUSTNESS indicates the robustness strategy used by the context. This is GLFW_LOSE_CONTEXT_ON_RESET or GLFW_NO_RESET_NOTIFICATION if the window's context supports robustness, or GLFW_NO_ROBUSTNESS otherwise.

        Framebuffer related attributes

        -

        GLFW does not expose attributes of the default framebuffer (i.e. the framebuffer attached to the window) as these can be queried directly with either OpenGL, OpenGL ES or Vulkan.

        -

        If you are using version 3.0 or later of OpenGL or OpenGL ES, the glGetFramebufferAttachmentParameteriv function can be used to retrieve the number of bits for the red, green, blue, alpha, depth and stencil buffer channels. Otherwise, the glGetIntegerv function can be used.

        -

        The number of MSAA samples are always retrieved with glGetIntegerv. For contexts supporting framebuffer objects, the number of samples of the currently bound framebuffer is returned.

        +

        GLFW does not expose most attributes of the default framebuffer (i.e. the framebuffer attached to the window) as these can be queried directly with either OpenGL, OpenGL ES or Vulkan. The one exception is GLFW_DOUBLEBUFFER, as this is not provided by OpenGL ES.

        +

        If you are using version 3.0 or later of OpenGL or OpenGL ES, the glGetFramebufferAttachmentParameteriv function can be used to retrieve the number of bits for the red, green, blue, alpha, depth and stencil buffer channels. Otherwise, the glGetIntegerv function can be used.

        +

        The number of MSAA samples are always retrieved with glGetIntegerv. For contexts supporting framebuffer objects, the number of samples of the currently bound framebuffer is returned.

        @@ -733,23 +782,24 @@ Framebuffer related attributes
        Attribute glGetIntegerv glGetFramebufferAttachmentParameteriv
        MSAA samples GL_SAMPLES Not provided by this function
        -

        When calling glGetFramebufferAttachmentParameteriv, the red, green, blue and alpha sizes are queried from the GL_BACK_LEFT, while the depth and stencil sizes are queried from the GL_DEPTH and GL_STENCIL attachments, respectively.

        +

        When calling glGetFramebufferAttachmentParameteriv, the red, green, blue and alpha sizes are queried from the GL_BACK_LEFT, while the depth and stencil sizes are queried from the GL_DEPTH and GL_STENCIL attachments, respectively.

        +

        GLFW_DOUBLEBUFFER indicates whether the specified window is double-buffered when rendering with OpenGL or OpenGL ES. This can be set before creation with the GLFW_DOUBLEBUFFER window hint.

        Buffer swapping

        -

        GLFW windows are by default double buffered. That means that you have two rendering buffers; a front buffer and a back buffer. The front buffer is the one being displayed and the back buffer the one you render to.

        -

        When the entire frame has been rendered, it is time to swap the back and the front buffers in order to display what has been rendered and begin rendering a new frame. This is done with glfwSwapBuffers.

        +

        GLFW windows are by default double buffered. That means that you have two rendering buffers; a front buffer and a back buffer. The front buffer is the one being displayed and the back buffer the one you render to.

        +

        When the entire frame has been rendered, it is time to swap the back and the front buffers in order to display what has been rendered and begin rendering a new frame. This is done with glfwSwapBuffers.

        -

        Sometimes it can be useful to select when the buffer swap will occur. With the function glfwSwapInterval it is possible to select the minimum number of monitor refreshes the driver should wait from the time glfwSwapBuffers was called before swapping the buffers:

        +

        Sometimes it can be useful to select when the buffer swap will occur. With the function glfwSwapInterval it is possible to select the minimum number of monitor refreshes the driver should wait from the time glfwSwapBuffers was called before swapping the buffers:

        void glfwSwapInterval(int interval)
        Sets the swap interval for the current context.
        -

        If the interval is zero, the swap will take place immediately when glfwSwapBuffers is called without waiting for a refresh. Otherwise at least interval retraces will pass between each buffer swap. Using a swap interval of zero can be useful for benchmarking purposes, when it is not desirable to measure the time it takes to wait for the vertical retrace. However, a swap interval of one lets you avoid tearing.

        -

        Note that this may not work on all machines, as some drivers have user-controlled settings that override any swap interval the application requests.

        -

        A context that supports either the WGL_EXT_swap_control_tear or the GLX_EXT_swap_control_tear extension also accepts negative swap intervals, which allows the driver to swap immediately even if a frame arrives a little bit late. This trades the risk of visible tears for greater framerate stability. You can check for these extensions with glfwExtensionSupported.

        +

        If the interval is zero, the swap will take place immediately when glfwSwapBuffers is called without waiting for a refresh. Otherwise at least interval retraces will pass between each buffer swap. Using a swap interval of zero can be useful for benchmarking purposes, when it is not desirable to measure the time it takes to wait for the vertical retrace. However, a swap interval of one lets you avoid tearing.

        +

        Note that this may not work on all machines, as some drivers have user-controlled settings that override any swap interval the application requests.

        +

        A context that supports either the WGL_EXT_swap_control_tear or the GLX_EXT_swap_control_tear extension also accepts negative swap intervals, which allows the driver to swap immediately even if a frame arrives a little bit late. This trades the risk of visible tears for greater framerate stability. You can check for these extensions with glfwExtensionSupported.

        diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/input.dox b/src/lib/src/vendor/glfw-3.4/docs/input.md similarity index 88% rename from src/lib/src/vendor/glfw-3.3.8/docs/input.dox rename to src/lib/src/vendor/glfw-3.4/docs/input.md index 1d61e5b..56983b0 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/input.dox +++ b/src/lib/src/vendor/glfw-3.4/docs/input.md @@ -1,8 +1,6 @@ -/*! +# Input guide {#input_guide} -@page input_guide Input guide - -@tableofcontents +[TOC] This guide introduces the input related functions of GLFW. For details on a specific function in this category, see the @ref input. There are also guides @@ -24,12 +22,12 @@ All input callbacks receive a window handle. By using the or objects from your callbacks. To get a better feel for how the various events callbacks behave, run the -`events` test program. It register every callback supported by GLFW and prints +`events` test program. It registers every callback supported by GLFW and prints out all arguments provided for every event, along with time and sequence information. -@section events Event processing +## Event processing {#events} GLFW needs to poll the window system for events both to provide input to the application and to prove to the window system that the application hasn't locked @@ -42,18 +40,18 @@ There are three functions for processing pending events. @ref glfwPollEvents, processes only those events that have already been received and then returns immediately. -@code +```c glfwPollEvents(); -@endcode +``` This is the best choice when rendering continuously, like most games do. If you only need to update the contents of the window when you receive new input, @ref glfwWaitEvents is a better choice. -@code +```c glfwWaitEvents(); -@endcode +``` It puts the thread to sleep until at least one event has been received and then processes all received events. This saves a great deal of CPU cycles and is @@ -62,9 +60,9 @@ useful for, for example, editing tools. If you want to wait for events but have UI elements or other tasks that need periodic updates, @ref glfwWaitEventsTimeout lets you specify a timeout. -@code +```c glfwWaitEventsTimeout(0.7); -@endcode +``` It puts the thread to sleep until at least one event has been received, or until the specified number of seconds have elapsed. It then processes any received @@ -74,9 +72,9 @@ If the main thread is sleeping in @ref glfwWaitEvents, you can wake it from another thread by posting an empty event to the event queue with @ref glfwPostEmptyEvent. -@code +```c glfwPostEmptyEvent(); -@endcode +``` Do not assume that callbacks will _only_ be called in response to the above functions. While it is necessary to process events in one or more of the ways @@ -91,11 +89,11 @@ a [window size callback](@ref window_size) GLFW will call it in turn with the new size before everything returns back out of the @ref glfwSetWindowSize call. -@section input_keyboard Keyboard input +## Keyboard input {#input_keyboard} GLFW divides keyboard input into two categories; key events and character events. Key events relate to actual physical keyboard keys, whereas character -events relate to the Unicode code points generated by pressing some of them. +events relate to the text that is generated by pressing some of them. Keys and characters do not map 1:1. A single key press may produce several characters, and a single character may require several keys to produce. This @@ -103,30 +101,34 @@ may not be the case on your machine, but your users are likely not all using the same keyboard layout, input method or even operating system as you. -@subsection input_key Key input +### Key input {#input_key} If you wish to be notified when a physical key is pressed or released or when it repeats, set a key callback. -@code +```c glfwSetKeyCallback(window, key_callback); -@endcode +``` The callback function receives the [keyboard key](@ref keys), platform-specific scancode, key action and [modifier bits](@ref mods). -@code +```c void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { if (key == GLFW_KEY_E && action == GLFW_PRESS) activate_airship(); } -@endcode +``` The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. Events with `GLFW_PRESS` and `GLFW_RELEASE` actions are emitted for every key press. Most keys will also emit events with `GLFW_REPEAT` actions while a key is held down. +Note that many keyboards have a limit on how many keys being simultaneous held +down that they can detect. This limit is called +[key rollover](https://en.wikipedia.org/wiki/Key_rollover). + Key events with `GLFW_REPEAT` actions are intended for text input. They are emitted at the rate set in the user's keyboard settings. At most one key is repeated even if several keys are held down. `GLFW_REPEAT` actions should not @@ -142,29 +144,30 @@ keys. The scancode is unique for every key, regardless of whether it has a key token. Scancodes are platform-specific but consistent over time, so keys will have different scancodes depending on the platform but they are safe to save to disk. -You can query the scancode for any [named key](@ref keys) on the current -platform with @ref glfwGetKeyScancode. +You can query the scancode for any [key token](@ref keys) supported on the +current platform with @ref glfwGetKeyScancode. -@code +```c const int scancode = glfwGetKeyScancode(GLFW_KEY_X); set_key_mapping(scancode, swap_weapons); -@endcode +``` -The last reported state for every [named key](@ref keys) is also saved in -per-window state arrays that can be polled with @ref glfwGetKey. +The last reported state for every physical key with a [key token](@ref keys) is +also saved in per-window state arrays that can be polled with @ref glfwGetKey. -@code +```c int state = glfwGetKey(window, GLFW_KEY_E); if (state == GLFW_PRESS) { activate_airship(); } -@endcode +``` The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`. This function only returns cached key event state. It does not poll the -system for the current physical state of the key. +system for the current state of the physical key. It also does not provide any +key repeat information. @anchor GLFW_STICKY_KEYS Whenever you poll state, you risk missing the state change you are looking for. @@ -172,9 +175,9 @@ If a pressed key is released again before you poll its state, you will have missed the key press. The recommended solution for this is to use a key callback, but there is also the `GLFW_STICKY_KEYS` input mode. -@code +```c glfwSetInputMode(window, GLFW_STICKY_KEYS, GLFW_TRUE); -@endcode +``` When sticky keys mode is enabled, the pollable state of a key will remain `GLFW_PRESS` until the state of that key is polled with @ref glfwGetKey. Once @@ -185,9 +188,9 @@ the state will reset to `GLFW_RELEASE`, otherwise it will remain `GLFW_PRESS`. If you wish to know what the state of the Caps Lock and Num Lock keys was when input events were generated, set the `GLFW_LOCK_KEY_MODS` input mode. -@code +```c glfwSetInputMode(window, GLFW_LOCK_KEY_MODS, GLFW_TRUE); -@endcode +``` When this input mode is enabled, any callback that receives [modifier bits](@ref mods) will have the @ref GLFW_MOD_CAPS_LOCK bit set if Caps @@ -195,15 +198,15 @@ Lock was on when the event occurred and the @ref GLFW_MOD_NUM_LOCK bit set if Num Lock was on. The `GLFW_KEY_LAST` constant holds the highest value of any -[named key](@ref keys). +[key token](@ref keys). -@subsection input_char Text input +### Text input {#input_char} GLFW supports text input in the form of a stream of [Unicode code points](https://en.wikipedia.org/wiki/Unicode), as produced by the -operating system text input system. Unlike key input, text input obeys keyboard -layouts and modifier keys and supports composing characters using +operating system text input system. Unlike key input, text input is affected by +keyboard layouts and modifier keys and supports composing characters using [dead keys](https://en.wikipedia.org/wiki/Dead_key). Once received, you can encode the code points into UTF-8 or any other encoding you prefer. @@ -212,30 +215,30 @@ you can treat the code point argument as native endian UTF-32. If you wish to offer regular text input, set a character callback. -@code +```c glfwSetCharCallback(window, character_callback); -@endcode +``` The callback function receives Unicode code points for key events that would have led to regular text input and generally behaves as a standard text field on that platform. -@code +```c void character_callback(GLFWwindow* window, unsigned int codepoint) { } -@endcode +``` -@subsection input_key_name Key names +### Key names {#input_key_name} If you wish to refer to keys by name, you can query the keyboard layout dependent name of printable keys with @ref glfwGetKeyName. -@code +```c const char* key_name = glfwGetKeyName(GLFW_KEY_W, 0); show_tutorial_hint("Press %s to move forward", key_name); -@endcode +``` This function can handle both [keys and scancodes](@ref input_key). If the specified key is `GLFW_KEY_UNKNOWN` then the scancode is used, otherwise it is @@ -243,42 +246,42 @@ ignored. This matches the behavior of the key callback, meaning the callback arguments can always be passed unmodified to this function. -@section input_mouse Mouse input +## Mouse input {#input_mouse} Mouse input comes in many forms, including mouse motion, button presses and scrolling offsets. The cursor appearance can also be changed, either to a custom image or a standard cursor shape from the system theme. -@subsection cursor_pos Cursor position +### Cursor position {#cursor_pos} If you wish to be notified when the cursor moves over the window, set a cursor position callback. -@code +```c glfwSetCursorPosCallback(window, cursor_position_callback); -@endcode +``` The callback functions receives the cursor position, measured in screen coordinates but relative to the top-left corner of the window content area. On platforms that provide it, the full sub-pixel cursor position is passed on. -@code +```c static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos) { } -@endcode +``` The cursor position is also saved per-window and can be polled with @ref glfwGetCursorPos. -@code +```c double xpos, ypos; glfwGetCursorPos(window, &xpos, &ypos); -@endcode +``` -@subsection cursor_mode Cursor mode +### Cursor mode {#cursor_mode} @anchor GLFW_CURSOR The `GLFW_CURSOR` input mode provides several cursor modes for special forms of @@ -290,9 +293,9 @@ If you wish to implement mouse motion based camera controls or other input schemes that require unlimited mouse movement, set the cursor mode to `GLFW_CURSOR_DISABLED`. -@code +```c glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); -@endcode +``` This will hide the cursor and lock it to the specified window. GLFW will then take care of all the details of cursor re-centering and offset calculation and @@ -306,22 +309,34 @@ other features of GLFW. It is not supported and will not work as robustly as If you only wish the cursor to become hidden when it is over a window but still want it to behave normally, set the cursor mode to `GLFW_CURSOR_HIDDEN`. -@code +```c glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); -@endcode +``` This mode puts no limit on the motion of the cursor. +If you wish the cursor to be visible but confined to the content area of the +window, set the cursor mode to `GLFW_CURSOR_CAPTURED`. + +```c +glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_CAPTURED); +``` + +The cursor will behave normally inside the content area but will not be able to +leave unless the window loses focus. + To exit out of either of these special modes, restore the `GLFW_CURSOR_NORMAL` cursor mode. -@code +```c glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); -@endcode +``` + +If the cursor was disabled, this will move it back to its last visible position. @anchor GLFW_RAW_MOUSE_MOTION -@subsection raw_mouse_motion Raw mouse motion +### Raw mouse motion {#raw_mouse_motion} When the cursor is disabled, raw (unscaled and unaccelerated) mouse motion can be enabled if available. @@ -336,16 +351,16 @@ Call @ref glfwRawMouseMotionSupported to check if the current machine provides raw motion and set the `GLFW_RAW_MOUSE_MOTION` input mode to enable it. It is disabled by default. -@code +```c if (glfwRawMouseMotionSupported()) glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); -@endcode +``` If supported, raw mouse motion can be enabled or disabled per-window and at any time but it will only be provided when the cursor is disabled. -@subsection cursor_object Cursor objects +### Cursor objects {#cursor_object} GLFW supports creating both custom and system theme cursor images, encapsulated as @ref GLFWcursor objects. They are created with @ref glfwCreateCursor or @ref @@ -353,13 +368,13 @@ glfwCreateStandardCursor and destroyed with @ref glfwDestroyCursor, or @ref glfwTerminate, if any remain. -@subsubsection cursor_custom Custom cursor creation +#### Custom cursor creation {#cursor_custom} A custom cursor is created with @ref glfwCreateCursor, which returns a handle to the created cursor object. For example, this creates a 16x16 white square cursor with the hot-spot in the upper-left corner: -@code +```c unsigned char pixels[16 * 16 * 4]; memset(pixels, 0xff, sizeof(pixels)); @@ -369,7 +384,7 @@ image.height = 16; image.pixels = pixels; GLFWcursor* cursor = glfwCreateCursor(&image, 0, 0); -@endcode +``` If cursor creation fails, `NULL` will be returned, so it is necessary to check the return value. @@ -379,39 +394,42 @@ per channel with the red channel first. The pixels are arranged canonically as sequential rows, starting from the top-left corner. -@subsubsection cursor_standard Standard cursor creation +#### Standard cursor creation {#cursor_standard} A cursor with a [standard shape](@ref shapes) from the current system cursor -theme can be can be created with @ref glfwCreateStandardCursor. +theme can be created with @ref glfwCreateStandardCursor. -@code -GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); -@endcode +```c +GLFWcursor* url_cursor = glfwCreateStandardCursor(GLFW_POINTING_HAND_CURSOR); +``` These cursor objects behave in the exact same way as those created with @ref glfwCreateCursor except that the system cursor theme provides the actual image. +A few of these shapes are not available everywhere. If a shape is unavailable, +`NULL` is returned. See @ref glfwCreateStandardCursor for details. -@subsubsection cursor_destruction Cursor destruction + +#### Cursor destruction {#cursor_destruction} When a cursor is no longer needed, destroy it with @ref glfwDestroyCursor. -@code +```c glfwDestroyCursor(cursor); -@endcode +``` Cursor destruction always succeeds. If the cursor is current for any window, that window will revert to the default cursor. This does not affect the cursor mode. All remaining cursors are destroyed when @ref glfwTerminate is called. -@subsubsection cursor_set Cursor setting +#### Cursor setting {#cursor_set} A cursor can be set as current for a window with @ref glfwSetCursor. -@code +```c glfwSetCursor(window, cursor); -@endcode +``` Once set, the cursor image will be used as long as the system cursor is over the content area of the window and the [cursor mode](@ref cursor_mode) is set @@ -421,26 +439,26 @@ A single cursor may be set for any number of windows. To revert to the default cursor, set the cursor of that window to `NULL`. -@code +```c glfwSetCursor(window, NULL); -@endcode +``` When a cursor is destroyed, any window that has it set will revert to the default cursor. This does not affect the cursor mode. -@subsection cursor_enter Cursor enter/leave events +### Cursor enter/leave events {#cursor_enter} If you wish to be notified when the cursor enters or leaves the content area of a window, set a cursor enter/leave callback. -@code +```c glfwSetCursorEnterCallback(window, cursor_enter_callback); -@endcode +``` The callback function receives the new classification of the cursor. -@code +```c void cursor_enter_callback(GLFWwindow* window, int entered) { if (entered) @@ -452,51 +470,52 @@ void cursor_enter_callback(GLFWwindow* window, int entered) // The cursor left the content area of the window } } -@endcode +``` You can query whether the cursor is currently inside the content area of the window with the [GLFW_HOVERED](@ref GLFW_HOVERED_attrib) window attribute. -@code +```c if (glfwGetWindowAttrib(window, GLFW_HOVERED)) { highlight_interface(); } -@endcode +``` -@subsection input_mouse_button Mouse button input +### Mouse button input {#input_mouse_button} If you wish to be notified when a mouse button is pressed or released, set a mouse button callback. -@code +```c glfwSetMouseButtonCallback(window, mouse_button_callback); -@endcode +``` The callback function receives the [mouse button](@ref buttons), button action and [modifier bits](@ref mods). -@code +```c void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS) popup_menu(); } -@endcode +``` The action is one of `GLFW_PRESS` or `GLFW_RELEASE`. -Mouse button states for [named buttons](@ref buttons) are also saved in -per-window state arrays that can be polled with @ref glfwGetMouseButton. +The last reported state for every [supported mouse button](@ref buttons) is also +saved in per-window state arrays that can be polled with @ref +glfwGetMouseButton. -@code +```c int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); if (state == GLFW_PRESS) { upgrade_cow(); } -@endcode +``` The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`. @@ -510,9 +529,9 @@ missed the button press. The recommended solution for this is to use a mouse button callback, but there is also the `GLFW_STICKY_MOUSE_BUTTONS` input mode. -@code +```c glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, GLFW_TRUE); -@endcode +``` When sticky mouse buttons mode is enabled, the pollable state of a mouse button will remain `GLFW_PRESS` until the state of that button is polled with @ref @@ -521,30 +540,30 @@ had been processed in the meantime, the state will reset to `GLFW_RELEASE`, otherwise it will remain `GLFW_PRESS`. The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any -[named button](@ref buttons). +[supported mouse button](@ref buttons). -@subsection scrolling Scroll input +### Scroll input {#scrolling} If you wish to be notified when the user scrolls, whether with a mouse wheel or touchpad gesture, set a scroll callback. -@code +```c glfwSetScrollCallback(window, scroll_callback); -@endcode +``` The callback function receives two-dimensional scroll offsets. -@code +```c void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { } -@endcode +``` A normal mouse wheel, being vertical, provides offsets along the Y-axis. -@section joystick Joystick input +## Joystick input {#joystick} The joystick functions expose connected joysticks and controllers, with both referred to as joysticks. It supports up to sixteen joysticks, ranging from @@ -552,17 +571,17 @@ referred to as joysticks. It supports up to sixteen joysticks, ranging from `GLFW_JOYSTICK_LAST`. You can test whether a [joystick](@ref joysticks) is present with @ref glfwJoystickPresent. -@code +```c int present = glfwJoystickPresent(GLFW_JOYSTICK_1); -@endcode +``` Each joystick has zero or more axes, zero or more buttons, zero or more hats, a human-readable name, a user pointer and an SDL compatible GUID. -When GLFW is initialized, detected joysticks are added to the beginning of -the array. Once a joystick is detected, it keeps its assigned ID until it is -disconnected or the library is terminated, so as joysticks are connected and -disconnected, there may appear gaps in the IDs. +Detected joysticks are added to the beginning of the array. Once a joystick is +detected, it keeps its assigned ID until it is disconnected or the library is +terminated, so as joysticks are connected and disconnected, there may appear +gaps in the IDs. Joystick axis, button and hat state is updated when polled and does not require a window to be created or events to be processed. However, if you want joystick @@ -574,30 +593,30 @@ To see all the properties of all connected joysticks in real-time, run the `joysticks` test program. -@subsection joystick_axis Joystick axis states +### Joystick axis states {#joystick_axis} The positions of all axes of a joystick are returned by @ref glfwGetJoystickAxes. See the reference documentation for the lifetime of the returned array. -@code +```c int count; const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_5, &count); -@endcode +``` Each element in the returned array is a value between -1.0 and 1.0. -@subsection joystick_button Joystick button states +### Joystick button states {#joystick_button} The states of all buttons of a joystick are returned by @ref glfwGetJoystickButtons. See the reference documentation for the lifetime of the returned array. -@code +```c int count; const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_3, &count); -@endcode +``` Each element in the returned array is either `GLFW_PRESS` or `GLFW_RELEASE`. @@ -606,15 +625,15 @@ glfwGetJoystickHats, the button array by default also includes all hats. See the reference documentation for @ref glfwGetJoystickButtons for details. -@subsection joystick_hat Joystick hat states +### Joystick hat states {#joystick_hat} The states of all hats are returned by @ref glfwGetJoystickHats. See the reference documentation for the lifetime of the returned array. -@code +```c int count; const unsigned char* hats = glfwGetJoystickHats(GLFW_JOYSTICK_7, &count); -@endcode +``` Each element in the returned array is one of the following: @@ -634,34 +653,34 @@ The diagonal directions are bitwise combinations of the primary (up, right, down and left) directions and you can test for these individually by ANDing it with the corresponding direction. -@code +```c if (hats[2] & GLFW_HAT_RIGHT) { // State of hat 2 could be right-up, right or right-down } -@endcode +``` For backward compatibility with earlier versions that did not have @ref glfwGetJoystickHats, all hats are by default also included in the button array. See the reference documentation for @ref glfwGetJoystickButtons for details. -@subsection joystick_name Joystick name +### Joystick name {#joystick_name} The human-readable, UTF-8 encoded name of a joystick is returned by @ref glfwGetJoystickName. See the reference documentation for the lifetime of the returned string. -@code +```c const char* name = glfwGetJoystickName(GLFW_JOYSTICK_4); -@endcode +``` Joystick names are not guaranteed to be unique. Two joysticks of the same model and make may have the same name. Only the [joystick ID](@ref joysticks) is guaranteed to be unique, and only until that joystick is disconnected. -@subsection joystick_userptr Joystick user pointer +### Joystick user pointer {#joystick_userptr} Each joystick has a user pointer that can be set with @ref glfwSetJoystickUserPointer and queried with @ref glfwGetJoystickUserPointer. @@ -672,19 +691,19 @@ terminated. The initial value of the pointer is `NULL`. -@subsection joystick_event Joystick configuration changes +### Joystick configuration changes {#joystick_event} If you wish to be notified when a joystick is connected or disconnected, set a joystick callback. -@code +```c glfwSetJoystickCallback(joystick_callback); -@endcode +``` The callback function receives the ID of the joystick that has been connected and disconnected and the event that occurred. -@code +```c void joystick_callback(int jid, int event) { if (event == GLFW_CONNECTED) @@ -696,7 +715,7 @@ void joystick_callback(int jid, int event) // The joystick was disconnected } } -@endcode +``` For joystick connection and disconnection events to be delivered on all platforms, you need to call one of the [event processing](@ref events) @@ -709,15 +728,17 @@ useful values for a disconnected joystick and only before the monitor callback returns. -@subsection gamepad Gamepad input +### Gamepad input {#gamepad} The joystick functions provide unlabeled axes, buttons and hats, with no indication of where they are located on the device. Their order may also vary between platforms even with the same device. To solve this problem the SDL community crowdsourced the -[SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) project, -a database of mappings from many different devices to an Xbox-like gamepad. +[SDL_GameControllerDB][] project, a database of mappings from many different +devices to an Xbox-like gamepad. + +[SDL_GameControllerDB]: https://github.com/gabomdq/SDL_GameControllerDB GLFW supports this mapping format and contains a copy of the mappings available at the time of release. See @ref gamepad_mapping for how to update @@ -727,12 +748,12 @@ a joystick is connected or the mappings are updated. You can check whether a joystick is both present and has a gamepad mapping with @ref glfwJoystickIsGamepad. -@code +```c if (glfwJoystickIsGamepad(GLFW_JOYSTICK_2)) { // Use as gamepad } -@endcode +``` If you are only interested in gamepad input you can use this function instead of @ref glfwJoystickPresent. @@ -741,13 +762,13 @@ You can query the human-readable name provided by the gamepad mapping with @ref glfwGetGamepadName. This may or may not be the same as the [joystick name](@ref joystick_name). -@code +```c const char* name = glfwGetGamepadName(GLFW_JOYSTICK_7); -@endcode +``` To retrieve the gamepad state of a joystick, call @ref glfwGetGamepadState. -@code +```c GLFWgamepadstate state; if (glfwGetGamepadState(GLFW_JOYSTICK_3, &state)) @@ -759,7 +780,7 @@ if (glfwGetGamepadState(GLFW_JOYSTICK_3, &state)) input_speed(state.axes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER]); } -@endcode +``` The @ref GLFWgamepadstate struct has two arrays; one for button states and one for axis states. The values for each button and axis are the same as for the @@ -790,18 +811,17 @@ The `GLFW_GAMEPAD_BUTTON_LAST` and `GLFW_GAMEPAD_AXIS_LAST` constants equal the largest available index for each array. -@subsection gamepad_mapping Gamepad mappings +### Gamepad mappings {#gamepad_mapping} -GLFW contains a copy of the mappings available in -[SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) at the -time of release. Newer ones can be added at runtime with @ref +GLFW contains a copy of the mappings available in [SDL_GameControllerDB][] at +the time of release. Newer ones can be added at runtime with @ref glfwUpdateGamepadMappings. -@code +```c const char* mappings = load_file_contents("game/data/gamecontrollerdb.txt"); glfwUpdateGamepadMappings(mappings); -@endcode +``` This function supports everything from single lines up to and including the unmodified contents of the whole `gamecontrollerdb.txt` file. @@ -861,25 +881,25 @@ one built into GLFW for Xbox controllers accessed via the XInput API on Windows. This example has been broken into several lines to fit on the page, but real gamepad mappings must be a single line. -@code{.unparsed} +``` 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, -@endcode +``` @note GLFW does not yet support the output range and modifiers `+` and `-` that were recently added to SDL. The input modifiers `+`, `-` and `~` are supported and described above. -@section time Time input +## Time input {#time} GLFW provides high-resolution time input, in seconds, with @ref glfwGetTime. -@code +```c double seconds = glfwGetTime(); -@endcode +``` It returns the number of seconds since the library was initialized with @ref glfwInit. The platform-specific time sources used typically have micro- or @@ -887,9 +907,9 @@ nanosecond resolution. You can modify the base time with @ref glfwSetTime. -@code +```c glfwSetTime(4.0); -@endcode +``` This sets the time to the specified time, in seconds, and it continues to count from there. @@ -897,32 +917,32 @@ from there. You can also access the raw timer used to implement the functions above, with @ref glfwGetTimerValue. -@code +```c uint64_t value = glfwGetTimerValue(); -@endcode +``` This value is in 1 / frequency seconds. The frequency of the raw timer varies depending on the operating system and hardware. You can query the frequency, in Hz, with @ref glfwGetTimerFrequency. -@code +```c uint64_t frequency = glfwGetTimerFrequency(); -@endcode +``` -@section clipboard Clipboard input and output +## Clipboard input and output {#clipboard} If the system clipboard contains a UTF-8 encoded string or if it can be converted to one, you can retrieve it with @ref glfwGetClipboardString. See the reference documentation for the lifetime of the returned string. -@code +```c const char* text = glfwGetClipboardString(NULL); if (text) { insert_text(text); } -@endcode +``` If the clipboard is empty or if its contents could not be converted, `NULL` is returned. @@ -930,33 +950,32 @@ returned. The contents of the system clipboard can be set to a UTF-8 encoded string with @ref glfwSetClipboardString. -@code +```c glfwSetClipboardString(NULL, "A string with words in it"); -@endcode +``` -@section path_drop Path drop input +## Path drop input {#path_drop} If you wish to receive the paths of files and/or directories dropped on a window, set a file drop callback. -@code +```c glfwSetDropCallback(window, drop_callback); -@endcode +``` The callback function receives an array of paths encoded as UTF-8. -@code +```c void drop_callback(GLFWwindow* window, int count, const char** paths) { int i; for (i = 0; i < count; i++) handle_dropped_file(paths[i]); } -@endcode +``` The path array and its strings are only valid until the file drop callback returns, as they may have been generated specifically for that event. You need to make a deep copy of the array if you want to keep the paths. -*/ diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/internal.dox b/src/lib/src/vendor/glfw-3.4/docs/internal.md similarity index 75% rename from src/lib/src/vendor/glfw-3.3.8/docs/internal.dox rename to src/lib/src/vendor/glfw-3.4/docs/internal.md index 685c6d1..b658d77 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/internal.dox +++ b/src/lib/src/vendor/glfw-3.4/docs/internal.md @@ -1,14 +1,12 @@ -/*! +# Internal structure {#internals_guide} -@page internals_guide Internal structure - -@tableofcontents +[TOC] There are several interfaces inside GLFW. Each interface has its own area of responsibility and its own naming conventions. -@section internals_public Public interface +## Public interface {#internals_public} The most well-known is the public interface, described in the glfw3.h header file. This is implemented in source files shared by all platforms and these @@ -22,7 +20,7 @@ it use headless camel case. Examples: `glfwCreateWindow`, `GLFWwindow`, `GLFW_RED_BITS` -@section internals_native Native interface +## Native interface {#internals_native} The [native interface](@ref native) is a small set of publicly available but platform-specific functions, described in the glfw3native.h header file and @@ -36,7 +34,7 @@ from. Examples: `glfwGetX11Window`, `glfwGetWGLContext` -@section internals_internal Internal interface +## Internal interface {#internals_internal} The internal interface consists of utility functions used by all other interfaces. It is shared code implemented in the same shared source files as @@ -52,7 +50,7 @@ global names have a leading underscore. Examples: `_glfwIsValidContextConfig`, `_GLFWwindow`, `_glfw.monitorCount` -@section internals_platform Platform interface +## Platform interface {#internals_platform} The platform interface implements all platform-specific operations as a service to the public interface. This includes event processing. The platform @@ -61,12 +59,21 @@ application-provided callbacks. It is also prohibited from modifying the platform-independent part of the internal structs. Instead, it calls the event interface when events interesting to GLFW are received. -The platform interface mirrors those parts of the public interface that needs to -perform platform-specific operations on some or all platforms. The are also -named the same except that the glfw function prefix is replaced by -_glfwPlatform. +The platform interface mostly mirrors those parts of the public interface that needs to +perform platform-specific operations on some or all platforms. -Examples: `_glfwPlatformCreateWindow` +The window system bits of the platform API is called through the `_GLFWplatform` struct of +function pointers, to allow runtime selection of platform. This includes the window and +context creation, input and event processing, monitor and Vulkan surface creation parts of +GLFW. This is located in the global `_glfw` struct. + +Examples: `_glfw.platform.createWindow` + +The timer, threading and module loading bits of the platform API are plain functions with +a `_glfwPlatform` prefix, as these things are independent of what window system is being +used. + +Examples: `_glfwPlatformGetTimerValue` The platform interface also defines structs that contain platform-specific global and per-object state. Their names mirror those of the internal @@ -81,7 +88,7 @@ prevents shared code from accidentally using these members. Examples: `window->win32.handle`, `_glfw.x11.display` -@section internals_event Event interface +## Event interface {#internals_event} The event interface is implemented in the same shared source files as the public interface and is responsible for delivering the events it receives to the @@ -93,7 +100,7 @@ ObjectEvent pattern. Examples: `_glfwInputWindowFocus`, `_glfwInputCursorPos` -@section internals_static Static functions +## Static functions {#internals_static} Static functions may be used by any interface and have no prefixes or suffixes. These use headless camel case. @@ -101,15 +108,13 @@ These use headless camel case. Examples: `isValidElementForJoystick` -@section internals_config Configuration macros +## Configuration macros {#internals_config} GLFW uses a number of configuration macros to select at compile time which -interfaces and code paths to use. They are defined in the glfw_config.h header file, -which is generated from the `glfw_config.h.in` file by CMake. +interfaces and code paths to use. They are defined in the GLFW CMake target. Configuration macros the same style as tokens in the public interface, except with a leading underscore. Examples: `_GLFW_WIN32`, `_GLFW_BUILD_DLL` -*/ diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/intro.dox b/src/lib/src/vendor/glfw-3.4/docs/intro.md similarity index 59% rename from src/lib/src/vendor/glfw-3.3.8/docs/intro.dox rename to src/lib/src/vendor/glfw-3.4/docs/intro.md index e563b50..0610202 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/intro.dox +++ b/src/lib/src/vendor/glfw-3.4/docs/intro.md @@ -1,8 +1,6 @@ -/*! +# Introduction to the API {#intro_guide} -@page intro_guide Introduction to the API - -@tableofcontents +[TOC] This guide introduces the basic concepts of GLFW and describes initialization, error handling and API guarantees and limitations. For a broad but shallow @@ -18,21 +16,24 @@ There are also guides for the other areas of GLFW. - @ref input_guide -@section intro_init Initialization and termination +## Initialization and termination {#intro_init} Before most GLFW functions may be called, the library must be initialized. This initialization checks what features are available on the machine, -enumerates monitors and joysticks, initializes the timer and performs any -required platform-specific initialization. +enumerates monitors, initializes the timer and performs any required +platform-specific initialization. Only the following functions may be called before the library has been successfully initialized, and only from the main thread. - @ref glfwGetVersion - @ref glfwGetVersionString + - @ref glfwPlatformSupported - @ref glfwGetError - @ref glfwSetErrorCallback - @ref glfwInitHint + - @ref glfwInitAllocator + - @ref glfwInitVulkanLoader - @ref glfwInit - @ref glfwTerminate @@ -40,17 +41,17 @@ Calling any other function before successful initialization will cause a @ref GLFW_NOT_INITIALIZED error. -@subsection intro_init_init Initializing GLFW +### Initializing GLFW {#intro_init_init} The library is initialized with @ref glfwInit, which returns `GLFW_FALSE` if an error occurred. -@code +```c if (!glfwInit()) { // Handle initialization failure } -@endcode +``` If any part of initialization fails, any parts that succeeded are terminated as if @ref glfwTerminate had been called. The library only needs to be initialized @@ -62,15 +63,20 @@ before the application exits. Modern systems are very good at freeing resources allocated by programs that exit, but GLFW sometimes has to change global system settings and these might not be restored without termination. +@macos When the library is initialized the main menu and dock icon are created. +These are not desirable for a command-line only program. The creation of the +main menu and dock icon can be disabled with the @ref GLFW_COCOA_MENUBAR init +hint. -@subsection init_hints Initialization hints + +### Initialization hints {#init_hints} Initialization hints are set before @ref glfwInit and affect how the library behaves until termination. Hints are set with @ref glfwInitHint. -@code +```c glfwInitHint(GLFW_JOYSTICK_HAT_BUTTONS, GLFW_FALSE); -@endcode +``` The values you set hints to are never reset by GLFW, but they only take effect during initialization. Once GLFW has been initialized, any values you set will @@ -81,56 +87,214 @@ will only affect their specific platform. Other platforms will ignore them. Setting these hints requires no platform specific headers or functions. -@subsubsection init_hints_shared Shared init hints +#### Shared init hints {#init_hints_shared} + +@anchor GLFW_PLATFORM +__GLFW_PLATFORM__ specifies the platform to use for windowing and input. +Possible values are `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`, +`GLFW_PLATFORM_COCOA`, `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` and +`GLFW_PLATFORM_NULL`. The default value is `GLFW_ANY_PLATFORM`, which will +choose any platform the library includes support for except for the Null +backend. + @anchor GLFW_JOYSTICK_HAT_BUTTONS __GLFW_JOYSTICK_HAT_BUTTONS__ specifies whether to also expose joystick hats as buttons, for compatibility with earlier versions of GLFW that did not have @ref glfwGetJoystickHats. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. +@anchor GLFW_ANGLE_PLATFORM_TYPE_hint +__GLFW_ANGLE_PLATFORM_TYPE__ specifies the platform type (rendering backend) to +request when using OpenGL ES and EGL via [ANGLE][]. If the requested platform +type is unavailable, ANGLE will use its default. Possible values are one of +`GLFW_ANGLE_PLATFORM_TYPE_NONE`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGL`, +`GLFW_ANGLE_PLATFORM_TYPE_OPENGLES`, `GLFW_ANGLE_PLATFORM_TYPE_D3D9`, +`GLFW_ANGLE_PLATFORM_TYPE_D3D11`, `GLFW_ANGLE_PLATFORM_TYPE_VULKAN` and +`GLFW_ANGLE_PLATFORM_TYPE_METAL`. -@subsubsection init_hints_osx macOS specific init hints +[ANGLE]: https://chromium.googlesource.com/angle/angle/ + +The ANGLE platform type is specified via the `EGL_ANGLE_platform_angle` +extension. This extension is not used if this hint is +`GLFW_ANGLE_PLATFORM_TYPE_NONE`, which is the default value. + + +#### macOS specific init hints {#init_hints_osx} @anchor GLFW_COCOA_CHDIR_RESOURCES_hint __GLFW_COCOA_CHDIR_RESOURCES__ specifies whether to set the current directory to the application to the `Contents/Resources` subdirectory of the application's -bundle, if present. Set this with @ref glfwInitHint. +bundle, if present. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This is +ignored on other platforms. @anchor GLFW_COCOA_MENUBAR_hint -__GLFW_COCOA_MENUBAR__ specifies whether to create a basic menu bar, either from -a nib or manually, when the first window is created, which is when AppKit is -initialized. Set this with @ref glfwInitHint. +__GLFW_COCOA_MENUBAR__ specifies whether to create the menu bar and dock icon +when GLFW is initialized. This applies whether the menu bar is created from +a nib or manually by GLFW. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. +This is ignored on other platforms. -@subsubsection init_hints_values Supported and default values +#### Wayland specific init hints {#init_hints_wayland} -Initialization hint | Default value | Supported values -------------------------------- | ------------- | ---------------- -@ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` -@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` -@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +@anchor GLFW_WAYLAND_LIBDECOR_hint +__GLFW_WAYLAND_LIBDECOR__ specifies whether to use [libdecor][] for window +decorations where available. Possible values are `GLFW_WAYLAND_PREFER_LIBDECOR` +and `GLFW_WAYLAND_DISABLE_LIBDECOR`. This is ignored on other platforms. + +[libdecor]: https://gitlab.freedesktop.org/libdecor/libdecor -@subsection intro_init_terminate Terminating GLFW +#### X11 specific init hints {#init_hints_x11} + +@anchor GLFW_X11_XCB_VULKAN_SURFACE_hint +__GLFW_X11_XCB_VULKAN_SURFACE__ specifies whether to prefer the +`VK_KHR_xcb_surface` extension for creating Vulkan surfaces, or whether to use +the `VK_KHR_xlib_surface` extension. Possible values are `GLFW_TRUE` and +`GLFW_FALSE`. This is ignored on other platforms. + + +#### Supported and default values {#init_hints_values} + +Initialization hint | Default value | Supported values +-------------------------------- | ------------------------------- | ---------------- +@ref GLFW_PLATFORM | `GLFW_ANY_PLATFORM` | `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`, `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` or `GLFW_PLATFORM_NULL` +@ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +@ref GLFW_ANGLE_PLATFORM_TYPE | `GLFW_ANGLE_PLATFORM_TYPE_NONE` | `GLFW_ANGLE_PLATFORM_TYPE_NONE`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGL`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGLES`, `GLFW_ANGLE_PLATFORM_TYPE_D3D9`, `GLFW_ANGLE_PLATFORM_TYPE_D3D11`, `GLFW_ANGLE_PLATFORM_TYPE_VULKAN` or `GLFW_ANGLE_PLATFORM_TYPE_METAL` +@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +@ref GLFW_WAYLAND_LIBDECOR | `GLFW_WAYLAND_PREFER_LIBDECOR` | `GLFW_WAYLAND_PREFER_LIBDECOR` or `GLFW_WAYLAND_DISABLE_LIBDECOR` +@ref GLFW_X11_XCB_VULKAN_SURFACE | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` + + +### Runtime platform selection {#platform} + +GLFW can be compiled for more than one platform (window system) at once. This lets +a single library binary support both Wayland and X11 on Linux and other Unix-like systems. + +You can control platform selection via the @ref GLFW_PLATFORM initialization hint. By +default, this is set to @ref GLFW_ANY_PLATFORM, which will look for supported window +systems in order of priority and select the first one it finds. It can also be set to any +specific platform to have GLFW only look for that one. + +```c +glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11); +``` + +This mechanism also provides the Null platform, which is always supported but needs to be +explicitly requested. This platform is effectively a stub, emulating a window system on +a single 1080p monitor, but will not interact with any actual window system. + +```c +glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_NULL); +``` + +You can test whether a library binary was compiled with support for a specific platform +with @ref glfwPlatformSupported. + +```c +if (glfwPlatformSupported(GLFW_PLATFORM_WAYLAND)) + glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND); +``` + +Once GLFW has been initialized, you can query which platform was selected with @ref +glfwGetPlatform. + +```c +int platform = glfwGetPlatform(); +``` + +If you are using any [native access functions](@ref native), especially on Linux and other +Unix-like systems, then you may need to check that you are calling the ones matching the +selected platform. + + +### Custom heap memory allocator {#init_allocator} + +The heap memory allocator can be customized before initialization with @ref +glfwInitAllocator. + +```c +GLFWallocator allocator; +allocator.allocate = my_malloc; +allocator.reallocate = my_realloc; +allocator.deallocate = my_free; +allocator.user = NULL; + +glfwInitAllocator(&allocator); +``` + +The allocator will be made active at the beginning of initialization and will be used by +GLFW until the library has been fully terminated. Any allocator set after initialization +will be picked up only at the next initialization. + +The allocator will only be used for allocations that would have been made with +the C standard library. Memory allocations that must be made with platform +specific APIs will still use those. + +The allocation function must have a signature matching @ref GLFWallocatefun. It receives +the desired size, in bytes, and the user pointer passed to @ref glfwInitAllocator and +returns the address to the allocated memory block. + +```c +void* my_malloc(size_t size, void* user) +{ + ... +} +``` + +The documentation for @ref GLFWallocatefun also lists the requirements and limitations for +an allocation function. If the active one does not meet all of these, GLFW may fail. + +The reallocation function must have a function signature matching @ref GLFWreallocatefun. +It receives the memory block to be reallocated, the new desired size, in bytes, and the user +pointer passed to @ref glfwInitAllocator and returns the address to the resized memory +block. + +```c +void* my_realloc(void* block, size_t size, void* user) +{ + ... +} +``` + +The documentation for @ref GLFWreallocatefun also lists the requirements and limitations +for a reallocation function. If the active one does not meet all of these, GLFW may fail. + +The deallocation function must have a function signature matching @ref GLFWdeallocatefun. +It receives the memory block to be deallocated and the user pointer passed to @ref +glfwInitAllocator. + +```c +void my_free(void* block, void* user) +{ + ... +} +``` + +The documentation for @ref GLFWdeallocatefun also lists the requirements and limitations +for a deallocation function. If the active one does not meet all of these, GLFW may fail. + + +### Terminating GLFW {#intro_init_terminate} Before your application exits, you should terminate the GLFW library if it has been initialized. This is done with @ref glfwTerminate. -@code +```c glfwTerminate(); -@endcode +``` This will destroy any remaining window, monitor and cursor objects, restore any modified gamma ramps, re-enable the screensaver if it had been disabled and free any other resources allocated by GLFW. -Once the library is terminated, it is as if it had never been initialized and +Once the library is terminated, it is as if it had never been initialized, therefore you will need to initialize it again before being able to use GLFW. If the -library was not initialized or had already been terminated, it return +library was not initialized or had already been terminated, it returns immediately. -@section error_handling Error handling +## Error handling {#error_handling} Some GLFW functions have return values that indicate an error, but this is often not very helpful when trying to figure out what happened or why it occurred. @@ -141,12 +305,12 @@ values. The last [error code](@ref errors) for the calling thread can be queried at any time with @ref glfwGetError. -@code +```c int code = glfwGetError(NULL); if (code != GLFW_NO_ERROR) handle_error(code); -@endcode +``` If no error has occurred since the last call, @ref GLFW_NO_ERROR (zero) is returned. The error is cleared before the function returns. @@ -160,13 +324,13 @@ can retrieve a UTF-8 encoded human-readable description along with the error code. If no error has occurred since the last call, the description is set to `NULL`. -@code +```c const char* description; int code = glfwGetError(&description); if (description) display_error_message(code, description); -@endcode +``` The retrieved description string is only valid until the next error occurs. This means you must make a copy of it if you want to keep it. @@ -174,19 +338,19 @@ This means you must make a copy of it if you want to keep it. You can also set an error callback, which will be called each time an error occurs. It is set with @ref glfwSetErrorCallback. -@code +```c glfwSetErrorCallback(error_callback); -@endcode +``` The error callback receives the same error code and human-readable description returned by @ref glfwGetError. -@code +```c void error_callback(int code, const char* description) { display_error_message(code, description); } -@endcode +``` The error callback is called after the error is stored, so calling @ref glfwGetError from within the error callback returns the same values as the @@ -205,7 +369,7 @@ Do not rely on a currently invalid call to generate a specific error, as in the future that same call may generate a different error or become valid. -@section coordinate_systems Coordinate systems +## Coordinate systems {#coordinate_systems} GLFW has two primary coordinate systems: the _virtual screen_ and the window _content area_ or _content area_. Both use the same unit: _virtual screen @@ -242,18 +406,18 @@ between screen coordinates and pixels may also change at run-time depending on which monitor the window is currently considered to be on. -@section guarantees_limitations Guarantees and limitations +## Guarantees and limitations {#guarantees_limitations} This section describes the conditions under which GLFW can be expected to function, barring bugs in the operating system or drivers. Use of GLFW outside -of these limits may work on some platforms, or on some machines, or some of the +these limits may work on some platforms, or on some machines, or some of the time, or on some versions of GLFW, but it may break at any time and this will not be considered a bug. -@subsection lifetime Pointer lifetimes +### Pointer lifetimes {#lifetime} -GLFW will never free any pointer you provide to it and you must never free any +GLFW will never free any pointer you provide to it, and you must never free any pointer it provides to you. Many GLFW functions return pointers to dynamically allocated structures, strings @@ -271,7 +435,7 @@ Pointer lifetimes are guaranteed not to be shortened in future minor or patch releases. -@subsection reentrancy Reentrancy +### Reentrancy {#reentrancy} GLFW event processing and object destruction are not reentrant. This means that the following functions must not be called from any callback function: @@ -287,7 +451,7 @@ These functions may be made reentrant in future minor or patch releases, but functions not on this list will not be made non-reentrant. -@subsection thread_safety Thread safety +### Thread safety {#thread_safety} Most GLFW functions must only be called from the main thread (the thread that calls main), but some may be called from any thread once the library has been @@ -346,6 +510,11 @@ Library version information may be queried from any thread. - @ref glfwGetVersion - @ref glfwGetVersionString +Platform information may be queried from any thread. + + - @ref glfwPlatformSupported + - @ref glfwGetPlatform + All Vulkan related functions may be called from any thread. - @ref glfwVulkanSupported @@ -363,7 +532,7 @@ but functions that are currently limited to the main thread may be updated to allow calls from any thread in future releases. -@subsection compatibility Version compatibility +### Version compatibility {#compatibility} GLFW uses [Semantic Versioning](https://semver.org/). This guarantees source and binary backward compatibility with earlier minor versions of the API. This @@ -383,14 +552,14 @@ fixed in the next release. The reference documentation will also take precedence over anything stated in a guide. -@subsection event_order Event order +### Event order {#event_order} The order of arrival of related events is not guaranteed to be consistent across platforms. The exception is synthetic key and mouse button release events, which are always delivered after the window defocus event. -@section intro_version Version management +## Version management {#intro_version} GLFW provides mechanisms for identifying what version of GLFW your application was compiled against as well as what version it is currently running against. @@ -398,33 +567,33 @@ If you are loading GLFW dynamically (not just linking dynamically), you can use this to verify that the library binary is compatible with your application. -@subsection intro_version_compile Compile-time version +### Compile-time version {#intro_version_compile} The compile-time version of GLFW is provided by the GLFW header with the `GLFW_VERSION_MAJOR`, `GLFW_VERSION_MINOR` and `GLFW_VERSION_REVISION` macros. -@code +```c printf("Compiled against GLFW %i.%i.%i\n", GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, GLFW_VERSION_REVISION); -@endcode +``` -@subsection intro_version_runtime Run-time version +### Run-time version {#intro_version_runtime} The run-time version can be retrieved with @ref glfwGetVersion, a function that may be called regardless of whether GLFW is initialized. -@code +```c int major, minor, revision; glfwGetVersion(&major, &minor, &revision); printf("Running against GLFW %i.%i.%i\n", major, minor, revision); -@endcode +``` -@subsection intro_version_string Version string +### Version string {#intro_version_string} GLFW 3 also provides a compile-time generated version string that describes the version, platform, compiler and any platform-specific compile-time options. @@ -438,17 +607,31 @@ __Do not use the version string__ to parse the GLFW library version. The @ref glfwGetVersion function already provides the version of the running library binary. +__Do not use the version string__ to parse what platforms are supported. The @ref +glfwPlatformSupported function lets you query platform support. + +__GLFW 3.4:__ The format of this string was changed to support the addition of +[runtime platform selection](@ref platform). + The format of the string is as follows: - The version of GLFW - - The name of the window system API - - The name of the context creation API - - Any additional options or APIs + - For each supported platform: + - The name of the window system API + - The name of the window system specific context creation API, if applicable + - The names of the always supported context creation APIs EGL and OSMesa + - Any additional compile-time options, APIs and (on Windows) what compiler was used -For example, when compiling GLFW 3.0 with MinGW using the Win32 and WGL -back ends, the version string may look something like this: +For example, compiling GLFW 3.4 with MinGW as a DLL for Windows, may result in a version string +like this: -@code -3.0.0 Win32 WGL MinGW -@endcode +```c +3.4.0 Win32 WGL Null EGL OSMesa MinGW DLL +``` + +Compiling GLFW as a static library for Linux, with both Wayland and X11 enabled, may +result in a version string like this: + +```c +3.4.0 Wayland X11 GLX Null EGL OSMesa monotonic +``` -*/ diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/main.dox b/src/lib/src/vendor/glfw-3.4/docs/main.md similarity index 87% rename from src/lib/src/vendor/glfw-3.3.8/docs/main.dox rename to src/lib/src/vendor/glfw-3.4/docs/main.md index bd563d9..c70f735 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/main.dox +++ b/src/lib/src/vendor/glfw-3.4/docs/main.md @@ -1,14 +1,10 @@ -/*! - -@mainpage notitle - -@section main_intro Introduction +# Introduction {#mainpage} GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan application development. It provides a simple, platform-independent API for creating windows, contexts and surfaces, reading input, handling events, etc. -@ref news_33 list new features, caveats and deprecations. +@ref news list new features, caveats and deprecations. @ref quick_guide is a guide for users new to GLFW. It takes you through how to write a small but complete program. @@ -33,9 +29,6 @@ use the new API. There is a section on @ref guarantees_limitations for pointer lifetimes, reentrancy, thread safety, event order and backward and forward compatibility. -The [FAQ](https://www.glfw.org/faq.html) answers many common questions about the -design, implementation and use of GLFW. - Finally, @ref compat_guide explains what APIs, standards and protocols GLFW uses and what happens when they are not present on a given machine. @@ -43,4 +36,3 @@ This documentation was generated with Doxygen. The sources for it are available in both the [source distribution](https://www.glfw.org/download.html) and [GitHub repository](https://github.com/glfw/glfw). -*/ diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/monitor.dox b/src/lib/src/vendor/glfw-3.4/docs/monitor.md similarity index 81% rename from src/lib/src/vendor/glfw-3.3.8/docs/monitor.dox rename to src/lib/src/vendor/glfw-3.4/docs/monitor.md index 86eb454..12d9854 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/monitor.dox +++ b/src/lib/src/vendor/glfw-3.4/docs/monitor.md @@ -1,8 +1,6 @@ -/*! +# Monitor guide {#monitor_guide} -@page monitor_guide Monitor guide - -@tableofcontents +[TOC] This guide introduces the monitor related functions of GLFW. For details on a specific function in this category, see the @ref monitor. There are also @@ -15,7 +13,7 @@ guides for the other areas of GLFW. - @ref input_guide -@section monitor_object Monitor objects +## Monitor objects {#monitor_object} A monitor object represents a currently connected monitor and is represented as a pointer to the [opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type @@ -36,42 +34,42 @@ To see how GLFW views your monitor setup and its available video modes, run the `monitors` test program. -@subsection monitor_monitors Retrieving monitors +### Retrieving monitors {#monitor_monitors} The primary monitor is returned by @ref glfwGetPrimaryMonitor. It is the user's preferred monitor and is usually the one with global UI elements like task bar or menu bar. -@code +```c GLFWmonitor* primary = glfwGetPrimaryMonitor(); -@endcode +``` You can retrieve all currently connected monitors with @ref glfwGetMonitors. See the reference documentation for the lifetime of the returned array. -@code +```c int count; GLFWmonitor** monitors = glfwGetMonitors(&count); -@endcode +``` The primary monitor is always the first monitor in the returned array, but other monitors may be moved to a different index when a monitor is connected or disconnected. -@subsection monitor_event Monitor configuration changes +### Monitor configuration changes {#monitor_event} If you wish to be notified when a monitor is connected or disconnected, set a monitor callback. -@code +```c glfwSetMonitorCallback(monitor_callback); -@endcode +``` The callback function receives the handle for the monitor that has been connected or disconnected and the event that occurred. -@code +```c void monitor_callback(GLFWmonitor* monitor, int event) { if (event == GLFW_CONNECTED) @@ -83,7 +81,7 @@ void monitor_callback(GLFWmonitor* monitor, int event) // The monitor was disconnected } } -@endcode +``` If a monitor is disconnected, all windows that are full screen on it will be switched to windowed mode before the callback is called. Only @ref @@ -91,14 +89,14 @@ glfwGetMonitorName and @ref glfwGetMonitorUserPointer will return useful values for a disconnected monitor and only before the monitor callback returns. -@section monitor_properties Monitor properties +## Monitor properties {#monitor_properties} Each monitor has a current video mode, a list of supported video modes, a virtual position, a content scale, a human-readable name, a user pointer, an estimated physical size and a gamma ramp. -@subsection monitor_modes Video modes +### Video modes {#monitor_modes} GLFW generally does a good job selecting a suitable video mode when you create a full screen window, change its video mode or make a windowed one full @@ -109,101 +107,93 @@ Video modes are represented as @ref GLFWvidmode structures. You can get an array of the video modes supported by a monitor with @ref glfwGetVideoModes. See the reference documentation for the lifetime of the returned array. -@code +```c int count; GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); -@endcode +``` To get the current video mode of a monitor call @ref glfwGetVideoMode. See the reference documentation for the lifetime of the returned pointer. -@code +```c const GLFWvidmode* mode = glfwGetVideoMode(monitor); -@endcode +``` The resolution of a video mode is specified in [screen coordinates](@ref coordinate_systems), not pixels. -@subsection monitor_size Physical size +### Physical size {#monitor_size} The physical size of a monitor in millimetres, or an estimation of it, can be retrieved with @ref glfwGetMonitorPhysicalSize. This has no relation to its current _resolution_, i.e. the width and height of its current [video mode](@ref monitor_modes). -@code +```c int width_mm, height_mm; glfwGetMonitorPhysicalSize(monitor, &width_mm, &height_mm); -@endcode +``` While this can be used to calculate the raw DPI of a monitor, this is often not -useful. Instead use the [monitor content scale](@ref monitor_scale) and +useful. Instead, use the [monitor content scale](@ref monitor_scale) and [window content scale](@ref window_scale) to scale your content. -@subsection monitor_scale Content scale +### Content scale {#monitor_scale} The content scale for a monitor can be retrieved with @ref glfwGetMonitorContentScale. -@code +```c float xscale, yscale; glfwGetMonitorContentScale(monitor, &xscale, &yscale); -@endcode +``` -The content scale is the ratio between the current DPI and the platform's -default DPI. This is especially important for text and any UI elements. If the -pixel dimensions of your UI scaled by this look appropriate on your machine then -it should appear at a reasonable size on other machines regardless of their DPI -and scaling settings. This relies on the system DPI and scaling settings being -somewhat correct. - -The content scale may depend on both the monitor resolution and pixel density -and on user settings. It may be very different from the raw DPI calculated from -the physical size and current resolution. +For more information on what the content scale is and how to use it, see +[window content scale](@ref window_scale). -@subsection monitor_pos Virtual position +### Virtual position {#monitor_pos} The position of the monitor on the virtual desktop, in [screen coordinates](@ref coordinate_systems), can be retrieved with @ref glfwGetMonitorPos. -@code +```c int xpos, ypos; glfwGetMonitorPos(monitor, &xpos, &ypos); -@endcode +``` -@subsection monitor_workarea Work area +### Work area {#monitor_workarea} The area of a monitor not occupied by global task bars or menu bars is the work area. This is specified in [screen coordinates](@ref coordinate_systems) and can be retrieved with @ref glfwGetMonitorWorkarea. -@code +```c int xpos, ypos, width, height; glfwGetMonitorWorkarea(monitor, &xpos, &ypos, &width, &height); -@endcode +``` -@subsection monitor_name Human-readable name +### Human-readable name {#monitor_name} The human-readable, UTF-8 encoded name of a monitor is returned by @ref glfwGetMonitorName. See the reference documentation for the lifetime of the returned string. -@code +```c const char* name = glfwGetMonitorName(monitor); -@endcode +``` Monitor names are not guaranteed to be unique. Two monitors of the same model and make may have the same name. Only the monitor handle is guaranteed to be unique, and only until that monitor is disconnected. -@subsection monitor_userptr User pointer +### User pointer {#monitor_userptr} Each monitor has a user pointer that can be set with @ref glfwSetMonitorUserPointer and queried with @ref glfwGetMonitorUserPointer. This @@ -214,12 +204,12 @@ terminated. The initial value of the pointer is `NULL`. -@subsection monitor_gamma Gamma ramp +### Gamma ramp {#monitor_gamma} The gamma ramp of a monitor can be set with @ref glfwSetGammaRamp, which accepts a monitor handle and a pointer to a @ref GLFWgammaramp structure. -@code +```c GLFWgammaramp ramp; unsigned short red[256], green[256], blue[256]; @@ -234,7 +224,7 @@ for (i = 0; i < ramp.size; i++) } glfwSetGammaRamp(monitor, &ramp); -@endcode +``` The gamma ramp data is copied before the function returns, so there is no need to keep it around once the ramp has been set. @@ -245,24 +235,23 @@ ramp for that monitor. The current gamma ramp for a monitor is returned by @ref glfwGetGammaRamp. See the reference documentation for the lifetime of the returned structure. -@code +```c const GLFWgammaramp* ramp = glfwGetGammaRamp(monitor); -@endcode +``` If you wish to set a regular gamma ramp, you can have GLFW calculate it for you from the desired exponent with @ref glfwSetGamma, which in turn calls @ref glfwSetGammaRamp with the resulting ramp. -@code +```c glfwSetGamma(monitor, 1.0); -@endcode +``` To experiment with gamma correction via the @ref glfwSetGamma function, run the `gamma` test program. @note The software controlled gamma ramp is applied _in addition_ to the -hardware gamma correction, which today is usually an approximation of sRGB +hardware gamma correction, which today is typically an approximation of sRGB gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will produce the default (usually sRGB-like) behavior. -*/ diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/moving.dox b/src/lib/src/vendor/glfw-3.4/docs/moving.md similarity index 76% rename from src/lib/src/vendor/glfw-3.3.8/docs/moving.dox rename to src/lib/src/vendor/glfw-3.4/docs/moving.md index b80d84a..7c1e2f5 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/moving.dox +++ b/src/lib/src/vendor/glfw-3.4/docs/moving.md @@ -1,8 +1,6 @@ -/*! +# Moving from GLFW 2 to 3 {#moving_guide} -@page moving_guide Moving from GLFW 2 to 3 - -@tableofcontents +[TOC] This is a transition guide for moving from GLFW 2 to 3. It describes what has changed or been removed, but does _not_ include @@ -11,61 +9,64 @@ base onto the new API. For example, the new multi-monitor functions are required to create full screen windows with GLFW 3. -@section moving_removed Changed and removed features +## Changed and removed features {#moving_removed} -@subsection moving_renamed_files Renamed library and header file +### Renamed library and header file {#moving_renamed_files} The GLFW 3 header is named @ref glfw3.h and moved to the `GLFW` directory, to avoid collisions with the headers of other major versions. Similarly, the GLFW 3 library is named `glfw3,` except when it's installed as a shared library on -Unix-like systems, where it uses the -[soname](https://en.wikipedia.org/wiki/soname) `libglfw.so.3`. +Unix-like systems, where it uses the [soname][] `libglfw.so.3`. -@par Old syntax -@code +[soname]: https://en.wikipedia.org/wiki/soname + +__Old syntax__ +```c #include -@endcode +``` -@par New syntax -@code +__New syntax__ +```c #include -@endcode +``` -@subsection moving_threads Removal of threading functions +### Removal of threading functions {#moving_threads} The threading functions have been removed, including the per-thread sleep function. They were fairly primitive, under-used, poorly integrated and took time away from the focus of GLFW (i.e. context, input and window). There are better threading libraries available and native threading support is available -in both [C++11](https://en.cppreference.com/w/cpp/thread) and -[C11](https://en.cppreference.com/w/c/thread), both of which are gaining -traction. +in both [C++11][] and [C11][], both of which are gaining traction. + +[C++11]: https://en.cppreference.com/w/cpp/thread +[C11]: https://en.cppreference.com/w/c/thread If you wish to use the C++11 or C11 facilities but your compiler doesn't yet -support them, see the -[TinyThread++](https://gitorious.org/tinythread/tinythreadpp) and -[TinyCThread](https://github.com/tinycthread/tinycthread) projects created by +support them, see the [TinyThread++][] and [TinyCThread][] projects created by the original author of GLFW. These libraries implement a usable subset of the threading APIs in C++11 and C11, and in fact some GLFW 3 test programs use TinyCThread. +[TinyThread++]: https://gitorious.org/tinythread/tinythreadpp +[TinyCThread]: https://github.com/tinycthread/tinycthread + However, GLFW 3 has better support for _use from multiple threads_ than GLFW 2 had. Contexts can be made current on any thread, although only a single thread at a time, and the documentation explicitly states which functions may be used from any thread and which must only be used from the main thread. -@par Removed functions -`glfwSleep`, `glfwCreateThread`, `glfwDestroyThread`, `glfwWaitThread`, -`glfwGetThreadID`, `glfwCreateMutex`, `glfwDestroyMutex`, `glfwLockMutex`, -`glfwUnlockMutex`, `glfwCreateCond`, `glfwDestroyCond`, `glfwWaitCond`, -`glfwSignalCond`, `glfwBroadcastCond` and `glfwGetNumberOfProcessors`. +__Removed functions__ +> `glfwSleep`, `glfwCreateThread`, `glfwDestroyThread`, `glfwWaitThread`, +> `glfwGetThreadID`, `glfwCreateMutex`, `glfwDestroyMutex`, `glfwLockMutex`, +> `glfwUnlockMutex`, `glfwCreateCond`, `glfwDestroyCond`, `glfwWaitCond`, +> `glfwSignalCond`, `glfwBroadcastCond` and `glfwGetNumberOfProcessors`. -@par Removed types -`GLFWthreadfun` +__Removed types__ +> `GLFWthreadfun` -@subsection moving_image Removal of image and texture loading +### Removal of image and texture loading {#moving_image} The image and texture loading functions have been removed. They only supported the Targa image format, making them mostly useful for beginner level examples. @@ -79,94 +80,97 @@ As there already are libraries doing this, it is unnecessary both to duplicate the work and to tie the duplicate to GLFW. The resulting library would also be platform-independent, as both OpenGL and stdio are available wherever GLFW is. -@par Removed functions -`glfwReadImage`, `glfwReadMemoryImage`, `glfwFreeImage`, `glfwLoadTexture2D`, -`glfwLoadMemoryTexture2D` and `glfwLoadTextureImage2D`. +__Removed functions__ +> `glfwReadImage`, `glfwReadMemoryImage`, `glfwFreeImage`, `glfwLoadTexture2D`, +> `glfwLoadMemoryTexture2D` and `glfwLoadTextureImage2D`. -@subsection moving_stdcall Removal of GLFWCALL macro +### Removal of GLFWCALL macro {#moving_stdcall} -The `GLFWCALL` macro, which made callback functions use -[__stdcall](https://msdn.microsoft.com/en-us/library/zxk0tw93.aspx) on Windows, -has been removed. GLFW is written in C, not Pascal. Removing this macro means -there's one less thing for application programmers to remember, i.e. the -requirement to mark all callback functions with `GLFWCALL`. It also simplifies -the creation of DLLs and DLL link libraries, as there's no need to explicitly -disable `@n` entry point suffixes. +The `GLFWCALL` macro, which made callback functions use [\_\_stdcall][stdcall] +on Windows, has been removed. GLFW is written in C, not Pascal. Removing this +macro means there's one less thing for application programmers to remember, i.e. +the requirement to mark all callback functions with `GLFWCALL`. It also +simplifies the creation of DLLs and DLL link libraries, as there's no need to +explicitly disable `@n` entry point suffixes. -@par Old syntax -@code +[stdcall]: https://msdn.microsoft.com/en-us/library/zxk0tw93.aspx + +__Old syntax__ +```c void GLFWCALL callback_function(...); -@endcode +``` -@par New syntax -@code +__New syntax__ +```c void callback_function(...); -@endcode +``` -@subsection moving_window_handles Window handle parameters +### Window handle parameters {#moving_window_handles} Because GLFW 3 supports multiple windows, window handle parameters have been added to all window-related GLFW functions and callbacks. The handle of a newly created window is returned by @ref glfwCreateWindow (formerly `glfwOpenWindow`). Window handles are pointers to the -[opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type @ref GLFWwindow. +[opaque][opaque-type] type @ref GLFWwindow. -@par Old syntax -@code +[opaque-type]: https://en.wikipedia.org/wiki/Opaque_data_type + +__Old syntax__ +```c glfwSetWindowTitle("New Window Title"); -@endcode +``` -@par New syntax -@code +__New syntax__ +```c glfwSetWindowTitle(window, "New Window Title"); -@endcode +``` -@subsection moving_monitor Explicit monitor selection +### Explicit monitor selection {#moving_monitor} GLFW 3 provides support for multiple monitors. To request a full screen mode window, instead of passing `GLFW_FULLSCREEN` you specify which monitor you wish the window to use. The @ref glfwGetPrimaryMonitor function returns the monitor that GLFW 2 would have selected, but there are many other [monitor functions](@ref monitor_guide). Monitor handles are pointers to the -[opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type @ref GLFWmonitor. +[opaque][opaque-type] type @ref GLFWmonitor. -@par Old basic full screen -@code +__Old basic full screen__ +```c glfwOpenWindow(640, 480, 8, 8, 8, 0, 24, 0, GLFW_FULLSCREEN); -@endcode +``` -@par New basic full screen -@code +__New basic full screen__ +```c window = glfwCreateWindow(640, 480, "My Window", glfwGetPrimaryMonitor(), NULL); -@endcode +``` @note The framebuffer bit depth parameters of `glfwOpenWindow` have been turned into [window hints](@ref window_hints), but as they have been given [sane defaults](@ref window_hints_values) you rarely need to set these hints. -@subsection moving_autopoll Removal of automatic event polling +### Removal of automatic event polling {#moving_autopoll} GLFW 3 does not automatically poll for events in @ref glfwSwapBuffers, meaning you need to call @ref glfwPollEvents or @ref glfwWaitEvents yourself. Unlike buffer swap, which acts on a single window, the event processing functions act on all windows at once. -@par Old basic main loop -@code +__Old basic main loop__ +```c while (...) { // Process input // Render output glfwSwapBuffers(); } -@endcode +``` -@par New basic main loop -@code +__New basic main loop__ +```c while (...) { // Process input @@ -174,10 +178,10 @@ while (...) glfwSwapBuffers(window); glfwPollEvents(); } -@endcode +``` -@subsection moving_context Explicit context management +### Explicit context management {#moving_context} Each GLFW 3 window has its own OpenGL context and only you, the application programmer, can know which context should be current on which thread at any @@ -187,7 +191,7 @@ This means that you need to call @ref glfwMakeContextCurrent after creating a window before you can call any OpenGL functions. -@subsection moving_hidpi Separation of window and framebuffer sizes +### Separation of window and framebuffer sizes {#moving_hidpi} Window positions and sizes now use screen coordinates, which may not be the same as pixels on machines with high-DPI monitors. This is important as OpenGL uses @@ -197,20 +201,20 @@ been added. You can retrieve the size of the framebuffer of a window with @ref glfwGetFramebufferSize function. A framebuffer size callback has also been added, which can be set with @ref glfwSetFramebufferSizeCallback. -@par Old basic viewport setup -@code +__Old basic viewport setup__ +```c glfwGetWindowSize(&width, &height); glViewport(0, 0, width, height); -@endcode +``` -@par New basic viewport setup -@code +__New basic viewport setup__ +```c glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); -@endcode +``` -@subsection moving_window_close Window closing changes +### Window closing changes {#moving_window_close} The `GLFW_OPENED` window parameter has been removed. As long as the window has not been destroyed, whether through @ref glfwDestroyWindow or @ref @@ -226,43 +230,43 @@ the window, take some other action or ignore the request. You can query the close flag at any time with @ref glfwWindowShouldClose and set it at any time with @ref glfwSetWindowShouldClose. -@par Old basic main loop -@code +__Old basic main loop__ +```c while (glfwGetWindowParam(GLFW_OPENED)) { ... } -@endcode +``` -@par New basic main loop -@code +__New basic main loop__ +```c while (!glfwWindowShouldClose(window)) { ... } -@endcode +``` The close callback no longer returns a value. Instead, it is called after the -close flag has been set so it can override its value, if it chooses to, before +close flag has been set, so it can optionally override its value, before event processing completes. You may however not call @ref glfwDestroyWindow from the close callback (or any other window related callback). -@par Old syntax -@code +__Old syntax__ +```c int GLFWCALL window_close_callback(void); -@endcode +``` -@par New syntax -@code +__New syntax__ +```c void window_close_callback(GLFWwindow* window); -@endcode +``` @note GLFW never clears the close flag to `GLFW_FALSE`, meaning you can use it for other reasons to close the window as well, for example the user choosing Quit from an in-game menu. -@subsection moving_hints Persistent window hints +### Persistent window hints {#moving_hints} The `glfwOpenWindowHint` function has been renamed to @ref glfwWindowHint. @@ -271,7 +275,7 @@ instead retain their values until modified by @ref glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is terminated and re-initialized. -@subsection moving_video_modes Video mode enumeration +### Video mode enumeration {#moving_video_modes} Video mode enumeration is now per-monitor. The @ref glfwGetVideoModes function now returns all available modes for a specific monitor instead of requiring you @@ -280,7 +284,7 @@ had poorly defined behavior, has been replaced by @ref glfwGetVideoMode, which returns the current mode of a monitor. -@subsection moving_char_up Removal of character actions +### Removal of character actions {#moving_char_up} The action parameter of the [character callback](@ref GLFWcharfun) has been removed. This was an artefact of the origin of GLFW, i.e. being developed in @@ -288,18 +292,18 @@ English by a Swede. However, many keyboard layouts require more than one key to produce characters with diacritical marks. Even the Swedish keyboard layout requires this for uncommon cases like ü. -@par Old syntax -@code +__Old syntax__ +```c void GLFWCALL character_callback(int character, int action); -@endcode +``` -@par New syntax -@code +__New syntax__ +```c void character_callback(GLFWwindow* window, int character); -@endcode +``` -@subsection moving_cursorpos Cursor position changes +### Cursor position changes {#moving_cursorpos} The `glfwGetMousePos` function has been renamed to @ref glfwGetCursorPos, `glfwSetMousePos` to @ref glfwSetCursorPos and `glfwSetMousePosCallback` to @ref @@ -315,7 +319,7 @@ glfwSetCursorPos (formerly `glfwSetMousePos`) when that window is active. Unless the window is active, the function fails silently. -@subsection moving_wheel Wheel position replaced by scroll offsets +### Wheel position replaced by scroll offsets {#moving_wheel} The `glfwGetMouseWheel` function has been removed. Scrolling is the input of offsets and has no absolute position. The mouse wheel callback has been @@ -323,21 +327,21 @@ replaced by a [scroll callback](@ref GLFWscrollfun) that receives two-dimensional floating point scroll offsets. This allows you to receive precise scroll data from for example modern touchpads. -@par Old syntax -@code +__Old syntax__ +```c void GLFWCALL mouse_wheel_callback(int position); -@endcode +``` -@par New syntax -@code +__New syntax__ +```c void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); -@endcode +``` -@par Removed functions -`glfwGetMouseWheel` +__Removed functions__ +> `glfwGetMouseWheel` -@subsection moving_repeat Key repeat action +### Key repeat action {#moving_repeat} The `GLFW_KEY_REPEAT` enable has been removed and key repeat is always enabled for both keys and characters. A new key action, `GLFW_REPEAT`, has been added @@ -346,15 +350,15 @@ from a repeat. Note that @ref glfwGetKey still returns only `GLFW_PRESS` or `GLFW_RELEASE`. -@subsection moving_keys Physical key input +### Physical key input {#moving_keys} GLFW 3 key tokens map to physical keys, unlike in GLFW 2 where they mapped to the values generated by the current keyboard layout. The tokens are named -according to the values they would have using the standard US layout, but this +according to the values they would have in the standard US layout, but this is only a convenience, as most programmers are assumed to know that layout. This means that (for example) `GLFW_KEY_LEFT_BRACKET` is always a single key and is the same key in the same place regardless of what keyboard layouts the users -of your program has. +of your program have. The key input facility was never meant for text input, although using it that way worked slightly better in GLFW 2. If you were using it to input text, you @@ -366,7 +370,7 @@ having to remember whether to check for `a` or `A`, you now check for @ref GLFW_KEY_A. -@subsection moving_joystick Joystick function changes +### Joystick function changes {#moving_joystick} The `glfwGetJoystickPos` function has been renamed to @ref glfwGetJoystickAxes. @@ -376,18 +380,19 @@ function as well as axis and button counts returned by the @ref glfwGetJoystickAxes and @ref glfwGetJoystickButtons functions. -@subsection moving_mbcs Win32 MBCS support +### Win32 MBCS support {#moving_mbcs} -The Win32 port of GLFW 3 will not compile in -[MBCS mode](https://msdn.microsoft.com/en-us/library/5z097dxa.aspx). -However, because the use of the Unicode version of the Win32 API doesn't affect -the process as a whole, but only those windows created using it, it's perfectly +The Win32 port of GLFW 3 will not compile in [MBCS mode][MBCS]. However, +because the use of the Unicode version of the Win32 API doesn't affect the +process as a whole, but only those windows created using it, it's perfectly possible to call MBCS functions from other parts of the same application. Therefore, even if an application using GLFW has MBCS mode code, there's no need for GLFW itself to support it. +[MBCS]: https://msdn.microsoft.com/en-us/library/5z097dxa.aspx -@subsection moving_windows Support for versions of Windows older than XP + +### Support for versions of Windows older than XP {#moving_windows} All explicit support for version of Windows older than XP has been removed. There is no code that actively prevents GLFW 3 from running on these earlier @@ -407,7 +412,7 @@ runtime checking for a number of functions that are present only on modern version of Windows. -@subsection moving_syskeys Capture of system-wide hotkeys +### Capture of system-wide hotkeys {#moving_syskeys} The ability to disable and capture system-wide hotkeys like Alt+Tab has been removed. Modern applications, whether they're games, scientific visualisations @@ -415,7 +420,7 @@ or something else, are nowadays expected to be good desktop citizens and allow these hotkeys to function even when running in full screen mode. -@subsection moving_terminate Automatic termination +### Automatic termination {#moving_terminate} GLFW 3 does not register @ref glfwTerminate with `atexit` at initialization, because `exit` calls registered functions from the calling thread and while it @@ -428,37 +433,41 @@ destroys all windows not already destroyed with @ref glfwDestroyWindow, invalidating any window handles you may still have. -@subsection moving_glu GLU header inclusion +### GLU header inclusion {#moving_glu} GLFW 3 does not by default include the GLU header and GLU itself has been -deprecated by [Khronos](https://en.wikipedia.org/wiki/Khronos_Group). __New -projects should not use GLU__, but if you need it for legacy code that -has been moved to GLFW 3, you can request that the GLFW header includes it by -defining @ref GLFW_INCLUDE_GLU before the inclusion of the GLFW header. +deprecated by [Khronos][]. __New projects should not use GLU__, but if you need +it for legacy code that has been moved to GLFW 3, you can request that the GLFW +header includes it by defining @ref GLFW_INCLUDE_GLU before the inclusion of the +GLFW header. -@par Old syntax -@code +[Khronos]: https://en.wikipedia.org/wiki/Khronos_Group + +__Old syntax__ +```c #include -@endcode +``` -@par New syntax -@code +__New syntax__ +```c #define GLFW_INCLUDE_GLU #include -@endcode +``` There are many libraries that offer replacements for the functionality offered -by GLU. For the matrix helper functions, see math libraries like -[GLM](https://github.com/g-truc/glm) (for C++), -[linmath.h](https://github.com/datenwolf/linmath.h) (for C) and others. For the -tessellation functions, see for example -[libtess2](https://github.com/memononen/libtess2). +by GLU. For the matrix helper functions, see math libraries like [GLM][] (for +C++), [linmath.h][] (for C) and others. For the tessellation functions, see for +example [libtess2][]. + +[GLM]: https://github.com/g-truc/glm +[linmath.h]: https://github.com/datenwolf/linmath.h +[libtess2]: https://github.com/memononen/libtess2 -@section moving_tables Name change tables +## Name change tables {#moving_tables} -@subsection moving_renamed_functions Renamed functions +### Renamed functions {#moving_renamed_functions} | GLFW 2 | GLFW 3 | Notes | | --------------------------- | ----------------------------- | ----- | @@ -478,7 +487,7 @@ tessellation functions, see for example | `glfwGetJoystickParam` | @ref glfwJoystickPresent | The axis and button counts are provided by @ref glfwGetJoystickAxes and @ref glfwGetJoystickButtons | -@subsection moving_renamed_types Renamed types +### Renamed types {#moving_renamed_types} | GLFW 2 | GLFW 3 | Notes | | ------------------- | --------------------- | | @@ -486,7 +495,7 @@ tessellation functions, see for example | `GLFWmouseposfun` | @ref GLFWcursorposfun | | -@subsection moving_renamed_tokens Renamed tokens +### Renamed tokens {#moving_renamed_tokens} | GLFW 2 | GLFW 3 | Notes | | --------------------------- | ---------------------------- | ----- | @@ -510,4 +519,3 @@ tessellation functions, see for example | `GLFW_KEY_RALT` | `GLFW_KEY_RIGHT_ALT` | | | `GLFW_KEY_RSUPER` | `GLFW_KEY_RIGHT_SUPER` | | -*/ diff --git a/src/lib/src/vendor/glfw-3.4/docs/news.md b/src/lib/src/vendor/glfw-3.4/docs/news.md new file mode 100644 index 0000000..3be9548 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/docs/news.md @@ -0,0 +1,402 @@ +# Release notes for version 3.4 {#news} + +[TOC] + + +## New features {#features} + +### Runtime platform selection {#runtime_platform_selection} + +GLFW now supports being compiled for multiple backends and selecting between +them at runtime with the @ref GLFW_PLATFORM init hint. After initialization the +selected platform can be queried with @ref glfwGetPlatform. You can check if +support for a given platform is compiled in with @ref glfwPlatformSupported. + +For more information see @ref platform. + + +### More standard cursor shapes {#more_cursor_shapes} + +GLFW now provides the standard cursor shapes @ref GLFW_RESIZE_NWSE_CURSOR and +@ref GLFW_RESIZE_NESW_CURSOR for diagonal resizing, @ref GLFW_RESIZE_ALL_CURSOR +for omnidirectional resizing and @ref GLFW_NOT_ALLOWED_CURSOR for showing an +action is not allowed. + +Unlike the original set, these shapes may not be available everywhere and +creation will then fail with the new @ref GLFW_CURSOR_UNAVAILABLE error. + +The cursors for horizontal and vertical resizing are now referred to as @ref +GLFW_RESIZE_EW_CURSOR and @ref GLFW_RESIZE_NS_CURSOR, and the pointing hand +cursor is now referred to as @ref GLFW_POINTING_HAND_CURSOR. The older names +are still available. + +For more information see @ref cursor_standard. + + +### Mouse event passthrough {#mouse_input_passthrough} + +GLFW now provides the [GLFW_MOUSE_PASSTHROUGH](@ref GLFW_MOUSE_PASSTHROUGH_hint) +window hint for making a window transparent to mouse input, lettings events pass +to whatever window is behind it. This can also be changed after window +creation with the matching [window attribute](@ref GLFW_MOUSE_PASSTHROUGH_attrib). + + +### Ability to get window title {#window_title_function} + +GLFW now supports querying the title of a window with the @ref glfwGetWindowTitle +function. + +For more information see @ref window_title. + + +### Captured cursor mode {#captured_cursor_mode} + +GLFW now supports confining the cursor to the window content area with the @ref +GLFW_CURSOR_CAPTURED cursor mode. + +For more information see @ref cursor_mode. + + +### Support for custom heap memory allocator {#custom_heap_allocator} + +GLFW now supports plugging a custom heap memory allocator at initialization with +@ref glfwInitAllocator. The allocator is a struct of type @ref GLFWallocator +with function pointers corresponding to the standard library functions `malloc`, +`realloc` and `free`. + +For more information see @ref init_allocator. + + +### Window hint for framebuffer scaling {#scale_framebuffer_hint} + +GLFW now allows provides the +[GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) window hint for +controlling framebuffer scaling on platforms that handle scaling by keeping the +window size the same while resizing the framebuffer. The default value is to +allow framebuffer scaling. + +This was already possible on macOS via the +[GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint) window +hint. This is now another name for the same hint value. + +For more information see @ref window_scale. + + +### Window hints for initial window position {#window_position_hint} + +GLFW now provides the @ref GLFW_POSITION_X and @ref GLFW_POSITION_Y window hints for +specifying the initial position of the window. This removes the need to create a hidden +window, move it and then show it. The default value of these hints is +`GLFW_ANY_POSITION`, which selects the previous behavior. + +For more information see @ref window_pos. + + +### ANGLE rendering backend hint {#angle_renderer_hint} + +GLFW now provides the +[GLFW_ANGLE_PLATFORM_TYPE](@ref GLFW_ANGLE_PLATFORM_TYPE_hint) init hint for +requesting a specific rendering backend when using [ANGLE][] to create OpenGL ES +contexts. + +[ANGLE]: https://chromium.googlesource.com/angle/angle/ + + +### Windows window menu keyboard access hint {#win32_keymenu_hint} + +GLFW now provides the +[GLFW_WIN32_KEYBOARD_MENU](@ref GLFW_WIN32_KEYBOARD_MENU_hint) window hint for +enabling keyboard access to the window menu via the Alt+Space and +Alt-and-then-Space shortcuts. This may be useful for more GUI-oriented +applications. + + +### Windows STARTUPINFO show command hint {#win32_showdefault_hint} + +GLFW now provides the [GLFW_WIN32_SHOWDEFAULT](@ref GLFW_WIN32_SHOWDEFAULT_hint) window +hint for applying the show command in the program's `STARTUPINFO` when showing the window +for the first time. This may be useful for the main window of a windowed-mode tool. + + +### Cocoa NSView native access function {#cocoa_nsview_function} + +GLFW now provides the @ref glfwGetCocoaView native access function +for returning the Cocoa NSView. + + +### Wayland libdecor decorations {#wayland_libdecor_decorations} + +GLFW now supports improved client-side window decorations via +[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor). This provides +fully featured window decorations on desktop environments like GNOME. + +Support for libdecor can be toggled before GLFW is initialized with the +[GLFW_WAYLAND_LIBDECOR](@ref GLFW_WAYLAND_LIBDECOR_hint) init hint. It is +enabled by default. + +This feature has also been available in GLFW 3.3 since 3.3.9. + + +### Wayland surface app_id hint {#wayland_app_id_hint} + +GLFW now supports specifying the app_id for a Wayland window using the +[GLFW_WAYLAND_APP_ID](@ref GLFW_WAYLAND_APP_ID_hint) window hint string. + + +### X11 Vulkan window surface hint {#x11_xcb_vulkan_surface} + +GLFW now supports disabling the use of `VK_KHR_xcb_surface` over +`VK_KHR_xlib_surface` where available, with the +[GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init hint. +This affects @ref glfwGetRequiredInstanceExtensions and @ref +glfwCreateWindowSurface. + + +## Caveats {#caveats} + +### Multiple sets of native access functions {#multiplatform_caveat} + +Because GLFW now supports runtime selection of platform (window system), a library binary +may export native access functions for multiple platforms. Starting with version 3.4 you +must not assume that GLFW is running on a platform just because it exports native access +functions for it. After initialization, you can query the selected platform with @ref +glfwGetPlatform. + + +### Version string format has been changed {#version_string_caveat} + +Because GLFW now supports runtime selection of platform (window system), the version +string returned by @ref glfwGetVersionString has been expanded. It now contains the names +of all APIs for all the platforms that the library binary supports. + +The version string is intended for bug reporting and should not be parsed. See +@ref glfwGetVersion and @ref glfwPlatformSupported instead. + + +### Joystick support is initialized on demand {#joystick_init_caveat} + +The joystick part of GLFW is now initialized when first used, primarily to work +around faulty Windows drivers that cause DirectInput to take up to several +seconds to enumerate devices. + +This change is mostly not observable. However, if your application waits for +events without having first called any joystick function or created any visible +windows, the wait may never unblock as GLFW may not yet have subscribed to +joystick related OS events. + +To work around this, call any joystick function before waiting for events, for +example by setting a [joystick callback](@ref joystick_event). + + +### Tests and examples are disabled when built as a subproject {#standalone_caveat} + +GLFW now by default does not build the tests or examples when it is added as +a subdirectory of another CMake project. If you were setting @ref +GLFW_BUILD_TESTS or @ref GLFW_BUILD_EXAMPLES to false in your CMake files, you +can now remove this. + +If you do want these to be built, set @ref GLFW_BUILD_TESTS and @ref +GLFW_BUILD_EXAMPLES in your CMake files before adding the GLFW subdirectory. + +```cmake +set(GLFW_BUILD_EXAMPLES ON CACHE BOOL "" FORCE) +set(GLFW_BUILD_TESTS ON CACHE BOOL "" FORCE) +add_subdirectory(path/to/glfw) +``` + + +### Configuration header is no longer generated {#config_header_caveat} + +The `glfw_config.h` configuration header is no longer generated by CMake and the +platform selection macros are now part of the GLFW CMake target. The +`_GLFW_USE_CONFIG_H` macro is still supported in case you are generating +a configuration header in a custom build setup. + + +### Documentation generation requires Doxygen 1.9.8 or later {#docs_target_caveat} + +Doxygen 1.9.8 or later is now required for the `docs` CMake target to be +generated. This is because the documentation now uses more of the Markdown +support in Doxygen and this support has until recently been relatively unstable. + + +### Windows 7 framebuffer transparency requires DWM transparency {#win7_framebuffer_caveat} + +GLFW no longer supports per-pixel framebuffer transparency via @ref +GLFW_TRANSPARENT_FRAMEBUFFER on Windows 7 if DWM transparency is off +(the Transparency setting under Personalization > Window Color). + + +### macOS main menu now created at initialization {#macos_menu_caveat} + +GLFW now creates the main menu and completes the initialization of NSApplication +during initialization. Programs that do not want a main menu can disable it +with the [GLFW_COCOA_MENUBAR](@ref GLFW_COCOA_MENUBAR_hint) init hint. + + +### macOS CoreVideo dependency has been removed {#corevideo_caveat} + +GLFW no longer depends on the CoreVideo framework on macOS and it no longer +needs to be specified during compilation or linking. + + +### Wayland framebuffer may lack alpha channel on older systems {#wayland_alpha_caveat} + +On Wayland, when creating an EGL context on a machine lacking the new +`EGL_EXT_present_opaque` extension, the @ref GLFW_ALPHA_BITS window hint will be +ignored and the framebuffer will not have an alpha channel. This is because +some Wayland compositors treat any buffer with an alpha channel as per-pixel +transparent. + +If you want a per-pixel transparent window, see the +[GLFW_TRANSPARENT_FRAMEBUFFER](@ref GLFW_TRANSPARENT_FRAMEBUFFER_hint) window +hint. + + +### X11 empty events no longer round-trip to server {#x11_emptyevent_caveat} + +Events posted with @ref glfwPostEmptyEvent now use a separate unnamed pipe +instead of sending an X11 client event to the helper window. + + +## Deprecations {#deprecations} + +### Windows XP and Vista support is deprecated {#winxp_deprecated} + +Support for Windows XP and Vista has been deprecated and will be removed in +a future release. Windows XP has been out of extended support since 2014. + + +### Original MinGW support is deprecated {#mingw_deprecated} + +Support for the now unmaintained original MinGW distribution has been deprecated +and will be removed in a future release. + +This does not apply to the much more capable MinGW-w64, which remains fully +supported, actively maintained and available on many platforms. + + +### OS X Yosemite support is deprecated {#yosemite_deprecated} + +Support for OS X 10.10 Yosemite and earlier has been deprecated and will be +removed in a future release. OS X 10.10 has been out of support since 2017. + + +## Removals {#removals} + +### GLFW_VULKAN_STATIC CMake option has been removed {#vulkan_static_removed} + +This option was used to compile GLFW directly linked with the Vulkan loader, instead of +using dynamic loading to get hold of `vkGetInstanceProcAddr` at initialization. This is +now done by calling the @ref glfwInitVulkanLoader function before initialization. + +If you need backward compatibility, this macro can still be defined for GLFW 3.4 and will +have no effect. The call to @ref glfwInitVulkanLoader can be conditionally enabled in +your code by checking the @ref GLFW_VERSION_MAJOR and @ref GLFW_VERSION_MINOR macros. + + +### GLFW_USE_WAYLAND CMake option has been removed {#use_wayland_removed} + +This option was used to compile GLFW for Wayland instead of X11. GLFW now +supports selecting the platform at run-time. By default GLFW is compiled for +both Wayland and X11 on Linux and other Unix-like systems. + +To disable Wayland or X11 or both, set the @ref GLFW_BUILD_WAYLAND and @ref +GLFW_BUILD_X11 CMake options. + +The `GLFW_USE_WAYLAND` CMake variable must not be present in the CMake cache at +all, or GLFW will fail to configure. If you are getting this error, delete the +CMake cache for GLFW and configure again. + + +### GLFW_USE_OSMESA CMake option has been removed {#use_osmesa_removed} + +This option was used to compile GLFW for the Null platform. The Null platform +is now always available. To produce a library binary that only supports this +platform, the way this CMake option used to do, you will instead need to disable +the default platforms for the target OS. This means setting the @ref +GLFW_BUILD_WIN32, @ref GLFW_BUILD_COCOA or @ref GLFW_BUILD_WAYLAND and @ref +GLFW_BUILD_X11 CMake options to false. + +You can set all of them to false and the ones that don't apply for the target OS +will be ignored. + + +### wl_shell protocol support has been removed {#wl_shell_removed} + +Support for the deprecated wl_shell protocol has been removed and GLFW now only +supports the XDG-Shell protocol. If your Wayland compositor does not support +XDG-Shell then GLFW will fail to initialize. + + +## New symbols {#new_symbols} + +### New functions {#new_functions} + + - @ref glfwInitAllocator + - @ref glfwGetPlatform + - @ref glfwPlatformSupported + - @ref glfwInitVulkanLoader + - @ref glfwGetWindowTitle + - @ref glfwGetCocoaView + + +### New types {#new_types} + + - @ref GLFWallocator + - @ref GLFWallocatefun + - @ref GLFWreallocatefun + - @ref GLFWdeallocatefun + + +### New constants {#new_constants} + + - @ref GLFW_PLATFORM + - @ref GLFW_ANY_PLATFORM + - @ref GLFW_PLATFORM_WIN32 + - @ref GLFW_PLATFORM_COCOA + - @ref GLFW_PLATFORM_WAYLAND + - @ref GLFW_PLATFORM_X11 + - @ref GLFW_PLATFORM_NULL + - @ref GLFW_PLATFORM_UNAVAILABLE + - @ref GLFW_POINTING_HAND_CURSOR + - @ref GLFW_RESIZE_EW_CURSOR + - @ref GLFW_RESIZE_NS_CURSOR + - @ref GLFW_RESIZE_NWSE_CURSOR + - @ref GLFW_RESIZE_NESW_CURSOR + - @ref GLFW_RESIZE_ALL_CURSOR + - @ref GLFW_MOUSE_PASSTHROUGH + - @ref GLFW_NOT_ALLOWED_CURSOR + - @ref GLFW_CURSOR_UNAVAILABLE + - @ref GLFW_WIN32_KEYBOARD_MENU + - @ref GLFW_WIN32_SHOWDEFAULT + - @ref GLFW_CONTEXT_DEBUG + - @ref GLFW_FEATURE_UNAVAILABLE + - @ref GLFW_FEATURE_UNIMPLEMENTED + - @ref GLFW_ANGLE_PLATFORM_TYPE + - @ref GLFW_ANGLE_PLATFORM_TYPE_NONE + - @ref GLFW_ANGLE_PLATFORM_TYPE_OPENGL + - @ref GLFW_ANGLE_PLATFORM_TYPE_OPENGLES + - @ref GLFW_ANGLE_PLATFORM_TYPE_D3D9 + - @ref GLFW_ANGLE_PLATFORM_TYPE_D3D11 + - @ref GLFW_ANGLE_PLATFORM_TYPE_VULKAN + - @ref GLFW_ANGLE_PLATFORM_TYPE_METAL + - @ref GLFW_X11_XCB_VULKAN_SURFACE + - @ref GLFW_CURSOR_CAPTURED + - @ref GLFW_POSITION_X + - @ref GLFW_POSITION_Y + - @ref GLFW_ANY_POSITION + - @ref GLFW_WAYLAND_APP_ID + - @ref GLFW_WAYLAND_LIBDECOR + - @ref GLFW_WAYLAND_PREFER_LIBDECOR + - @ref GLFW_WAYLAND_DISABLE_LIBDECOR + - @ref GLFW_SCALE_FRAMEBUFFER + + +## Release notes for earlier versions {#news_archive} + +- [Release notes for 3.3](https://www.glfw.org/docs/3.3/news.html) +- [Release notes for 3.2](https://www.glfw.org/docs/3.2/news.html) +- [Release notes for 3.1](https://www.glfw.org/docs/3.1/news.html) +- [Release notes for 3.0](https://www.glfw.org/docs/3.0/news.html) + diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/quick.dox b/src/lib/src/vendor/glfw-3.4/docs/quick.md similarity index 85% rename from src/lib/src/vendor/glfw-3.3.8/docs/quick.dox rename to src/lib/src/vendor/glfw-3.4/docs/quick.md index 3645fc0..6f487fc 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/quick.dox +++ b/src/lib/src/vendor/glfw-3.4/docs/quick.md @@ -1,10 +1,8 @@ -/*! +# Getting started {#quick_guide} -@page quick_guide Getting started +[TOC] -@tableofcontents - -This guide takes you through writing a simple application using GLFW 3. The +This guide takes you through writing a small application using GLFW 3. The application will create a window and OpenGL context, render a rotating triangle and exit when the user closes the window or presses _Escape_. This guide will introduce a few of the most commonly used functions, but there are many more. @@ -14,16 +12,16 @@ have used GLFW 2 in the past, read @ref moving_guide, as some functions behave differently in GLFW 3. -@section quick_steps Step by step +## Step by step {#quick_steps} -@subsection quick_include Including the GLFW header +### Including the GLFW header {#quick_include} In the source files of your application where you use GLFW, you need to include its header file. -@code +```c #include -@endcode +``` This header provides all the constants, types and function prototypes of the GLFW API. @@ -38,51 +36,51 @@ This example uses files generated by [glad](https://gen.glad.sh/). The GLFW header can detect most such headers if they are included first and will then not include the one from your development environment. -@code +```c #include #include -@endcode +``` To make sure there will be no header conflicts, you can define @ref GLFW_INCLUDE_NONE before the GLFW header to explicitly disable inclusion of the development environment header. This also allows the two headers to be included in any order. -@code +```c #define GLFW_INCLUDE_NONE #include #include -@endcode +``` -@subsection quick_init_term Initializing and terminating GLFW +### Initializing and terminating GLFW {#quick_init_term} Before you can use most GLFW functions, the library must be initialized. On successful initialization, `GLFW_TRUE` is returned. If an error occurred, `GLFW_FALSE` is returned. -@code +```c if (!glfwInit()) { // Initialization failed } -@endcode +``` Note that `GLFW_TRUE` and `GLFW_FALSE` are and will always be one and zero. When you are done using GLFW, typically just before the application exits, you need to terminate GLFW. -@code +```c glfwTerminate(); -@endcode +``` This destroys any remaining windows and releases any other resources allocated by GLFW. After this call, you must initialize GLFW again before using any GLFW functions that require it. -@subsection quick_capture_error Setting an error callback +### Setting an error callback {#quick_capture_error} Most events are reported through callbacks, whether it's a key being pressed, a GLFW window being moved, or an error occurring. Callbacks are C functions (or @@ -92,36 +90,36 @@ In case a GLFW function fails, an error is reported to the GLFW error callback. You can receive these reports with an error callback. This function must have the signature below but may do anything permitted in other callbacks. -@code +```c void error_callback(int error, const char* description) { fprintf(stderr, "Error: %s\n", description); } -@endcode +``` Callback functions must be set, so GLFW knows to call them. The function to set the error callback is one of the few GLFW functions that may be called before initialization, which lets you be notified of errors both during and after initialization. -@code +```c glfwSetErrorCallback(error_callback); -@endcode +``` -@subsection quick_create_window Creating a window and context +### Creating a window and context {#quick_create_window} The window and its OpenGL context are created with a single call to @ref glfwCreateWindow, which returns a handle to the created combined window and context object -@code +```c GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); if (!window) { // Window or OpenGL context creation failed } -@endcode +``` This creates a 640 by 480 windowed mode window with an OpenGL context. If window or OpenGL context creation fails, `NULL` will be returned. You should @@ -134,37 +132,38 @@ require a minimum OpenGL version by setting the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` hints _before_ creation. If the required minimum version is not supported on the machine, context (and window) creation fails. -@code -glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); -glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); +You can select the OpenGL profile by setting the `GLFW_OPENGL_PROFILE` hint. +This program uses the core profile as that is the only profile macOS supports +for OpenGL 3.x and 4.x. + +```c +glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); +glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); +glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); if (!window) { // Window or context creation failed } -@endcode - -The window handle is passed to all window related functions and is provided to -along to all window related callbacks, so they can tell which window received -the event. +``` When a window and context is no longer needed, destroy it. -@code +```c glfwDestroyWindow(window); -@endcode +``` Once this function is called, no more events will be delivered for that window and its handle becomes invalid. -@subsection quick_context_current Making the OpenGL context current +### Making the OpenGL context current {#quick_context_current} Before you can use the OpenGL API, you must have a current OpenGL context. -@code +```c glfwMakeContextCurrent(window); -@endcode +``` The context will remain current until you make another context current or until the window owning the current context is destroyed. @@ -175,12 +174,12 @@ a current context to load from. This example uses [glad](https://github.com/Dav1dde/glad), but the same rule applies to all such libraries. -@code +```c gladLoadGL(glfwGetProcAddress); -@endcode +``` -@subsection quick_window_close Checking the window close flag +### Checking the window close flag {#quick_window_close} Each window has a flag indicating whether the window should be closed. @@ -190,12 +189,12 @@ Note that __the window isn't actually closed__, so you are expected to monitor this flag and either destroy the window or give some kind of feedback to the user. -@code +```c while (!glfwWindowShouldClose(window)) { // Keep running } -@endcode +``` You can be notified when the user is attempting to close the window by setting a close callback with @ref glfwSetWindowCloseCallback. The callback will be @@ -206,41 +205,41 @@ useful if you want to interpret other kinds of input as closing the window, like for example pressing the _Escape_ key. -@subsection quick_key_input Receiving input events +### Receiving input events {#quick_key_input} Each window has a large number of callbacks that can be set to receive all the various kinds of events. To receive key press and release events, create a key callback function. -@code +```c static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GLFW_TRUE); } -@endcode +``` The key callback, like other window related callbacks, are set per-window. -@code +```c glfwSetKeyCallback(window, key_callback); -@endcode +``` In order for event callbacks to be called when events occur, you need to process events as described below. -@subsection quick_render Rendering with OpenGL +### Rendering with OpenGL {#quick_render} Once you have a current OpenGL context, you can use OpenGL normally. In this -tutorial, a multi-colored rotating triangle will be rendered. The framebuffer +tutorial, a multicolored rotating triangle will be rendered. The framebuffer size needs to be retrieved for `glViewport`. -@code +```c int width, height; glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); -@endcode +``` You can also set a framebuffer size callback using @ref glfwSetFramebufferSizeCallback and be notified when the size changes. @@ -257,19 +256,19 @@ These all happen to use GLFW, but OpenGL itself works the same whatever API you use to create the window and context. -@subsection quick_timer Reading the timer +### Reading the timer {#quick_timer} To create smooth animation, a time source is needed. GLFW provides a timer that returns the number of seconds since initialization. The time source used is the most accurate on each platform and generally has micro- or nanosecond resolution. -@code +```c double time = glfwGetTime(); -@endcode +``` -@subsection quick_swap_buffers Swapping buffers +### Swapping buffers {#quick_swap_buffers} GLFW windows by default use double buffering. That means that each window has two rendering buffers; a front buffer and a back buffer. The front buffer is @@ -278,9 +277,9 @@ the one being displayed and the back buffer the one you render to. When the entire frame has been rendered, the buffers need to be swapped with one another, so the back buffer becomes the front buffer and vice versa. -@code +```c glfwSwapBuffers(window); -@endcode +``` The swap interval indicates how many frames to wait until swapping the buffers, commonly known as _vsync_. By default, the swap interval is zero, meaning @@ -295,15 +294,15 @@ For these reasons, applications will typically want to set the swap interval to one. It can be set to higher values, but this is usually not recommended, because of the input latency it leads to. -@code +```c glfwSwapInterval(1); -@endcode +``` This function acts on the current context and will fail unless a context is current. -@subsection quick_process_events Processing events +### Processing events {#quick_process_events} GLFW needs to communicate regularly with the window system both in order to receive events and to show that the application hasn't locked up. Event @@ -314,9 +313,9 @@ There are two methods for processing pending events; polling and waiting. This example will use event polling, which processes only those events that have already been received and then returns immediately. -@code +```c glfwPollEvents(); -@endcode +``` This is the best choice when rendering continually, like most games do. If instead you only need to update your rendering once you have received new input, @@ -326,22 +325,24 @@ all received events. This saves a great deal of CPU cycles and is useful for, for example, many kinds of editing tools. -@section quick_example Putting it together +## Putting it together {#quick_example} Now that you know how to initialize GLFW, create a window and poll for -keyboard input, it's possible to create a simple program. +keyboard input, it's possible to create a small program. This program creates a 640 by 480 windowed mode window and starts a loop that clears the screen, renders a triangle and processes events until the user either presses _Escape_ or closes the window. -@snippet simple.c code +@snippet triangle-opengl.c code -The program above can be found in the -[source package](https://www.glfw.org/download.html) as `examples/simple.c` -and is compiled along with all other examples when you build GLFW. If you -built GLFW from the source package then you already have this as `simple.exe` on -Windows, `simple` on Linux or `simple.app` on macOS. +The program above can be found in the [source package][download] as +`examples/triangle-opengl.c` and is compiled along with all other examples when +you build GLFW. If you built GLFW from the source package then you already have +this as `triangle-opengl.exe` on Windows, `triangle-opengl` on Linux or +`triangle-opengl.app` on macOS. + +[download]: https://www.glfw.org/download.html This tutorial used only a few of the many functions GLFW provides. There are guides for each of the areas covered by GLFW. Each guide will introduce all the @@ -362,4 +363,3 @@ environment you are using and is best explained by the documentation for that environment. To learn about the details that are specific to GLFW, see @ref build_guide. -*/ diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/spaces.svg b/src/lib/src/vendor/glfw-3.4/docs/spaces.svg similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/docs/spaces.svg rename to src/lib/src/vendor/glfw-3.4/docs/spaces.svg diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/vulkan.dox b/src/lib/src/vendor/glfw-3.4/docs/vulkan.md similarity index 79% rename from src/lib/src/vendor/glfw-3.3.8/docs/vulkan.dox rename to src/lib/src/vendor/glfw-3.4/docs/vulkan.md index f34366f..cb67302 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/vulkan.dox +++ b/src/lib/src/vendor/glfw-3.4/docs/vulkan.md @@ -1,8 +1,6 @@ -/*! +# Vulkan guide {#vulkan_guide} -@page vulkan_guide Vulkan guide - -@tableofcontents +[TOC] This guide is intended to fill the gaps between the official [Vulkan resources](https://www.khronos.org/vulkan/) and the rest of the GLFW @@ -29,51 +27,62 @@ are also guides for the other areas of the GLFW API. - @ref input_guide -@section vulkan_loader Linking against the Vulkan loader +## Finding the Vulkan loader {#vulkan_loader} -By default, GLFW will look for the Vulkan loader on demand at runtime via its -standard name (`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other -Unix-like systems and `libvulkan.1.dylib` on macOS). This means that GLFW does -not need to be linked against the loader. However, it also means that if you -are using the static library form of the Vulkan loader GLFW will either fail to -find it or (worse) use the wrong one. +GLFW itself does not ever need to be linked against the Vulkan loader. -The @ref GLFW_VULKAN_STATIC CMake option makes GLFW call the Vulkan loader -directly instead of dynamically loading it at runtime. Not linking against the -Vulkan loader will then be a compile-time error. +By default, GLFW will load the Vulkan loader dynamically at runtime via its standard name: +`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other Unix-like systems and +`libvulkan.1.dylib` on macOS. -@macos To make your application be redistributable you will need to set up the -application bundle according to the LunarG SDK documentation. This is explained -in more detail in the +@macos GLFW will also look up and search the `Frameworks` subdirectory of your +application bundle. + +If your code is using a Vulkan loader with a different name or in a non-standard location +you will need to direct GLFW to it. Pass your version of `vkGetInstanceProcAddr` to @ref +glfwInitVulkanLoader before initializing GLFW and it will use that function for all Vulkan +entry point retrieval. This prevents GLFW from dynamically loading the Vulkan loader. + +```c +glfwInitVulkanLoader(vkGetInstanceProcAddr); +``` + +@macos To make your application be redistributable you will need to set up the application +bundle according to the LunarG SDK documentation. This is explained in more detail in the [SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html). -@section vulkan_include Including the Vulkan and GLFW header files +## Including the Vulkan header file {#vulkan_include} -To include the Vulkan header, define @ref GLFW_INCLUDE_VULKAN before including +To have GLFW include the Vulkan header, define @ref GLFW_INCLUDE_VULKAN before including the GLFW header. -@code +```c #define GLFW_INCLUDE_VULKAN #include -@endcode +``` If you instead want to include the Vulkan header from a custom location or use your own custom Vulkan header then do this before the GLFW header. -@code +```c #include #include -@endcode +``` -Unless a Vulkan header is included, either by the GLFW header or above it, any -GLFW functions that take or return Vulkan types will not be declared. +Unless a Vulkan header is included, either by the GLFW header or above it, the following +GLFW functions will not be declared, as depend on Vulkan types. + + - @ref glfwInitVulkanLoader + - @ref glfwGetInstanceProcAddress + - @ref glfwGetPhysicalDevicePresentationSupport + - @ref glfwCreateWindowSurface The `VK_USE_PLATFORM_*_KHR` macros do not need to be defined for the Vulkan part of GLFW to work. Define them only if you are using these extensions directly. -@section vulkan_support Querying for Vulkan support +## Querying for Vulkan support {#vulkan_support} If you are linking directly against the Vulkan loader then you can skip this section. The canonical desktop loader library exports all Vulkan core and @@ -83,12 +92,12 @@ If you are loading the Vulkan loader dynamically instead of linking directly against it, you can check for the availability of a loader and ICD with @ref glfwVulkanSupported. -@code +```c if (glfwVulkanSupported()) { // Vulkan is available, at least for compute } -@endcode +``` This function returns `GLFW_TRUE` if the Vulkan loader and any minimally functional ICD was found. @@ -97,24 +106,24 @@ If one or both were not found, calling any other Vulkan related GLFW function will generate a @ref GLFW_API_UNAVAILABLE error. -@subsection vulkan_proc Querying Vulkan function pointers +### Querying Vulkan function pointers {#vulkan_proc} To load any Vulkan core or extension function from the found loader, call @ref glfwGetInstanceProcAddress. To load functions needed for instance creation, pass `NULL` as the instance. -@code +```c PFN_vkCreateInstance pfnCreateInstance = (PFN_vkCreateInstance) glfwGetInstanceProcAddress(NULL, "vkCreateInstance"); -@endcode +``` Once you have created an instance, you can load from it all other Vulkan core functions and functions from any instance extensions you enabled. -@code +```c PFN_vkCreateDevice pfnCreateDevice = (PFN_vkCreateDevice) glfwGetInstanceProcAddress(instance, "vkCreateDevice"); -@endcode +``` This function in turn calls `vkGetInstanceProcAddr`. If that fails, the function falls back to a platform-specific query of the Vulkan loader (i.e. @@ -126,17 +135,17 @@ Vulkan also provides `vkGetDeviceProcAddr` for loading device-specific versions of Vulkan function. This function can be retrieved from an instance with @ref glfwGetInstanceProcAddress. -@code +```c PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr"); -@endcode +``` -Device-specific functions may execute a little bit faster, due to not having to +Device-specific functions may execute a little faster, due to not having to dispatch internally based on the device passed to them. For more information about `vkGetDeviceProcAddr`, see the Vulkan documentation. -@section vulkan_ext Querying required Vulkan extensions +## Querying required Vulkan extensions {#vulkan_ext} To do anything useful with Vulkan you need to create an instance. If you want to use Vulkan to render to a window, you must enable the instance extensions @@ -145,10 +154,10 @@ GLFW requires to create Vulkan surfaces. To query the instance extensions required, call @ref glfwGetRequiredInstanceExtensions. -@code +```c uint32_t count; const char** extensions = glfwGetRequiredInstanceExtensions(&count); -@endcode +``` These extensions must all be enabled when creating instances that are going to be passed to @ref glfwGetPhysicalDevicePresentationSupport and @ref @@ -163,14 +172,14 @@ If successful the returned array will always include `VK_KHR_surface`, so if you don't require any additional extensions you can pass this list directly to the `VkInstanceCreateInfo` struct. -@code +```c VkInstanceCreateInfo ici; memset(&ici, 0, sizeof(ici)); ici.enabledExtensionCount = count; ici.ppEnabledExtensionNames = extensions; ... -@endcode +``` Additional extensions may be required by future versions of GLFW. You should check whether any extensions you wish to enable are already in the returned @@ -185,52 +194,52 @@ info flags for MoltenVK to show up in the list of physical devices. For more information, see the Vulkan and MoltenVK documentation. -@section vulkan_present Querying for Vulkan presentation support +## Querying for Vulkan presentation support {#vulkan_present} Not every queue family of every Vulkan device can present images to surfaces. To check whether a specific queue family of a physical device supports image presentation without first having to create a window and surface, call @ref glfwGetPhysicalDevicePresentationSupport. -@code +```c if (glfwGetPhysicalDevicePresentationSupport(instance, physical_device, queue_family_index)) { // Queue family supports image presentation } -@endcode +``` The `VK_KHR_surface` extension additionally provides the `vkGetPhysicalDeviceSurfaceSupportKHR` function, which performs the same test on an existing Vulkan surface. -@section vulkan_window Creating the window +## Creating the window {#vulkan_window} Unless you will be using OpenGL or OpenGL ES with the same window as Vulkan, there is no need to create a context. You can disable context creation with the [GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint. -@code +```c glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* window = glfwCreateWindow(640, 480, "Window Title", NULL, NULL); -@endcode +``` See @ref context_less for more information. -@section vulkan_surface Creating a Vulkan window surface +## Creating a Vulkan window surface {#vulkan_surface} You can create a Vulkan surface (as defined by the `VK_KHR_surface` extension) for a GLFW window with @ref glfwCreateWindowSurface. -@code +```c VkSurfaceKHR surface; VkResult err = glfwCreateWindowSurface(instance, window, NULL, &surface); if (err) { // Window surface creation failed } -@endcode +``` If an OpenGL or OpenGL ES context was created on the window, the context has ownership of the presentation on the window and a Vulkan surface cannot be @@ -239,4 +248,3 @@ created. It is your responsibility to destroy the surface. GLFW does not destroy it for you. Call `vkDestroySurfaceKHR` function from the same extension to destroy it. -*/ diff --git a/src/lib/src/vendor/glfw-3.3.8/docs/window.dox b/src/lib/src/vendor/glfw-3.4/docs/window.md similarity index 82% rename from src/lib/src/vendor/glfw-3.3.8/docs/window.dox rename to src/lib/src/vendor/glfw-3.4/docs/window.md index 2fcf11f..371baa5 100644 --- a/src/lib/src/vendor/glfw-3.3.8/docs/window.dox +++ b/src/lib/src/vendor/glfw-3.4/docs/window.md @@ -1,8 +1,6 @@ -/*! +# Window guide {#window_guide} -@page window_guide Window guide - -@tableofcontents +[TOC] This guide introduces the window related functions of GLFW. For details on a specific function in this category, see the @ref window. There are also @@ -15,7 +13,7 @@ guides for the other areas of GLFW. - @ref input_guide -@section window_object Window objects +## Window objects {#window_object} The @ref GLFWwindow object encapsulates both a window and a context. They are created with @ref glfwCreateWindow and destroyed with @ref glfwDestroyWindow, or @@ -26,15 +24,15 @@ To see the event stream provided to the various window related callbacks, run the `events` test program. -@subsection window_creation Window creation +### Window creation {#window_creation} A window and its OpenGL or OpenGL ES context are created with @ref glfwCreateWindow, which returns a handle to the created window object. For example, this creates a 640 by 480 windowed mode window: -@code +```c GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); -@endcode +``` If window creation fails, `NULL` will be returned, so it is necessary to check the return value. @@ -44,15 +42,15 @@ along with all input events, so event handlers can tell which window received the event. -@subsubsection window_full_screen Full screen windows +#### Full screen windows {#window_full_screen} To create a full screen window, you need to specify which monitor the window should use. In most cases, the user's primary monitor is a good choice. For more information about retrieving monitors, see @ref monitor_monitors. -@code +```c GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", glfwGetPrimaryMonitor(), NULL); -@endcode +``` Full screen windows cover the entire display area of a monitor, have no border or decorations. @@ -93,7 +91,7 @@ If a monitor is disconnected, all windows that are full screen on that monitor will be switched to windowed mode. See @ref monitor_event for more information. -@subsubsection window_windowed_full_screen "Windowed full screen" windows +#### "Windowed full screen" windows {#window_windowed_full_screen} If the closest match for the desired video mode is the current one, the video mode will not be changed, making window creation faster and application @@ -101,7 +99,7 @@ switching much smoother. This is sometimes called _windowed full screen_ or _borderless full screen_ window and counts as a full screen window. To create such a window, request the current video mode. -@code +```c const GLFWvidmode* mode = glfwGetVideoMode(monitor); glfwWindowHint(GLFW_RED_BITS, mode->redBits); @@ -110,28 +108,28 @@ glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); GLFWwindow* window = glfwCreateWindow(mode->width, mode->height, "My Title", monitor, NULL); -@endcode +``` This also works for windowed mode windows that are made full screen. -@code +```c const GLFWvidmode* mode = glfwGetVideoMode(monitor); glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); -@endcode +``` Note that @ref glfwGetVideoMode returns the _current_ video mode of a monitor, so if you already have a full screen window on that monitor that you want to make windowed full screen, you need to have saved the desktop resolution before. -@subsection window_destruction Window destruction +### Window destruction {#window_destruction} When a window is no longer needed, destroy it with @ref glfwDestroyWindow. -@code +```c glfwDestroyWindow(window); -@endcode +``` Window destruction always succeeds. Before the actual destruction, all callbacks are removed so no further events will be delivered for the window. @@ -141,7 +139,7 @@ When a full screen window is destroyed, the original video mode of its monitor is restored, but the gamma ramp is left untouched. -@subsection window_hints Window creation hints +### Window creation hints {#window_hints} There are a number of hints that can be set before the creation of a window and context. Some affect the window itself, others affect the framebuffer or @@ -160,7 +158,7 @@ you wish to have the specified attributes. They function as additional arguments to @ref glfwCreateWindow. -@subsubsection window_hints_hard Hard and soft constraints +#### Hard and soft constraints {#window_hints_hard} Some window hints are hard constraints. These must match the available capabilities _exactly_ for window and context creation to succeed. Hints @@ -179,7 +177,7 @@ context, but are ignored when requesting an OpenGL ES context: - [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) -@subsubsection window_hints_wnd Window related hints +#### Window related hints {#window_hints_wnd} @anchor GLFW_RESIZABLE_hint __GLFW_RESIZABLE__ specifies whether the windowed mode window will be resizable @@ -241,16 +239,46 @@ focus when @ref glfwShowWindow is called. Possible values are `GLFW_TRUE` and @anchor GLFW_SCALE_TO_MONITOR __GLFW_SCALE_TO_MONITOR__ specified whether the window content area should be -resized based on the [monitor content scale](@ref monitor_scale) of any monitor -it is placed on. This includes the initial placement when the window is -created. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. +resized based on [content scale](@ref window_scale) changes. This can be +because of a global user settings change or because the window was moved to +a monitor with different scale settings. This hint only has an effect on platforms where screen coordinates and pixels -always map 1:1 such as Windows and X11. On platforms like macOS the resolution -of the framebuffer is changed independently of the window size. +always map 1:1, such as Windows and X11. On platforms like macOS the resolution +of the framebuffer can change independently of the window size. + +@anchor GLFW_SCALE_FRAMEBUFFER_hint +@anchor GLFW_COCOA_RETINA_FRAMEBUFFER_hint +__GLFW_SCALE_FRAMEBUFFER__ specifies whether the framebuffer should be resized +based on [content scale](@ref window_scale) changes. This can be +because of a global user settings change or because the window was moved to +a monitor with different scale settings. + +This hint only has an effect on platforms where screen coordinates can be scaled +relative to pixel coordinates, such as macOS and Wayland. On platforms like +Windows and X11 the framebuffer and window content area sizes always map 1:1. + +This is the new name, introduced in GLFW 3.4. The older +`GLFW_COCOA_RETINA_FRAMEBUFFER` name is also available for compatibility. Both +names modify the same hint value. + +@anchor GLFW_MOUSE_PASSTHROUGH_hint +__GLFW_MOUSE_PASSTHROUGH__ specifies whether the window is transparent to mouse +input, letting any mouse events pass through to whatever window is behind it. +This is only supported for undecorated windows. Decorated windows with this +enabled will behave differently between platforms. Possible values are +`GLFW_TRUE` and `GLFW_FALSE`. + +@anchor GLFW_POSITION_X +@anchor GLFW_POSITION_Y +__GLFW_POSITION_X__ and __GLFW_POSITION_Y__ specify the desired initial position +of the window. The window manager may modify or ignore these coordinates. If +either or both of these hints are set to `GLFW_ANY_POSITION` then the window +manager will position the window where it thinks the user will prefer it. +Possible values are any valid screen coordinates and `GLFW_ANY_POSITION`. -@subsubsection window_hints_fb Framebuffer related hints +#### Framebuffer related hints {#window_hints_fb} @anchor GLFW_RED_BITS @anchor GLFW_GREEN_BITS @@ -303,12 +331,13 @@ rendering will be disabled. always have sRGB rendering enabled. @anchor GLFW_DOUBLEBUFFER +@anchor GLFW_DOUBLEBUFFER_hint __GLFW_DOUBLEBUFFER__ specifies whether the framebuffer should be double buffered. You nearly always want to use double buffering. This is a hard constraint. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. -@subsubsection window_hints_mtr Monitor related hints +#### Monitor related hints {#window_hints_mtr} @anchor GLFW_REFRESH_RATE __GLFW_REFRESH_RATE__ specifies the desired refresh rate for full screen @@ -316,7 +345,7 @@ windows. A value of `GLFW_DONT_CARE` means the highest available refresh rate will be used. This hint is ignored for windowed mode windows. -@subsubsection window_hints_ctx Context related hints +#### Context related hints {#window_hints_ctx} @anchor GLFW_CLIENT_API_hint __GLFW_CLIENT_API__ specifies which client API to create the context for. @@ -371,12 +400,10 @@ requested. Additionally, OpenGL ES 1.x cannot be returned if 2.0 or later was requested, and vice versa. This is because OpenGL ES 3.x is backward compatible with 2.0, but OpenGL ES 2.0 is not backward compatible with 1.x. -@note @macos The OS only supports forward-compatible core profile contexts for -OpenGL versions 3.2 and later. Before creating an OpenGL context of version -3.2 or later you must set the -[GLFW_OPENGL_FORWARD_COMPAT](@ref GLFW_OPENGL_FORWARD_COMPAT_hint) and -[GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) hints accordingly. OpenGL -3.0 and 3.1 contexts are not supported at all on macOS. +@note @macos The OS only supports core profile contexts for OpenGL versions 3.2 +and later. Before creating an OpenGL context of version 3.2 or later you must +set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) hint accordingly. +OpenGL 3.0 and 3.1 contexts are not supported at all on macOS. @anchor GLFW_OPENGL_FORWARD_COMPAT_hint __GLFW_OPENGL_FORWARD_COMPAT__ specifies whether the OpenGL context should be @@ -387,14 +414,19 @@ version is 3.0 or above. If OpenGL ES is requested, this hint is ignored. Forward-compatibility is described in detail in the [OpenGL Reference Manual](https://www.opengl.org/registry/). +@anchor GLFW_CONTEXT_DEBUG_hint @anchor GLFW_OPENGL_DEBUG_CONTEXT_hint -__GLFW_OPENGL_DEBUG_CONTEXT__ specifies whether the context should be created -in debug mode, which may provide additional error and diagnostic reporting -functionality. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. +__GLFW_CONTEXT_DEBUG__ specifies whether the context should be created in debug +mode, which may provide additional error and diagnostic reporting functionality. +Possible values are `GLFW_TRUE` and `GLFW_FALSE`. Debug contexts for OpenGL and OpenGL ES are described in detail by the -[GL_KHR_debug](https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_debug.txt) -extension. +[GL_KHR_debug][] extension. + +[GL_KHR_debug]: https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_debug.txt + +@note `GLFW_CONTEXT_DEBUG` is the new name introduced in GLFW 3.4. The older +`GLFW_OPENGL_DEBUG_CONTEXT` name is also available for compatibility. @anchor GLFW_OPENGL_PROFILE_hint __GLFW_OPENGL_PROFILE__ specifies which OpenGL profile to create the context @@ -424,8 +456,9 @@ current one. If the behavior is `GLFW_RELEASE_BEHAVIOR_NONE`, the pipeline will not be flushed on release. Context release behaviors are described in detail by the -[GL_KHR_context_flush_control](https://www.opengl.org/registry/specs/KHR/context_flush_control.txt) -extension. +[GL_KHR_context_flush_control][] extension. + +[GL_KHR_context_flush_control]: https://www.opengl.org/registry/specs/KHR/context_flush_control.txt @anchor GLFW_CONTEXT_NO_ERROR_hint __GLFW_CONTEXT_NO_ERROR__ specifies whether errors should be generated by the @@ -433,16 +466,28 @@ context. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. If enabled, situations that would have generated errors instead cause undefined behavior. The no error mode for OpenGL and OpenGL ES is described in detail by the -[GL_KHR_no_error](https://www.opengl.org/registry/specs/KHR/no_error.txt) -extension. +[GL_KHR_no_error][] extension. + +[GL_KHR_no_error]: https://www.opengl.org/registry/specs/KHR/no_error.txt -@subsubsection window_hints_osx macOS specific window hints +#### Win32 specific hints {#window_hints_win32} -@anchor GLFW_COCOA_RETINA_FRAMEBUFFER_hint -__GLFW_COCOA_RETINA_FRAMEBUFFER__ specifies whether to use full resolution -framebuffers on Retina displays. Possible values are `GLFW_TRUE` and -`GLFW_FALSE`. This is ignored on other platforms. +@anchor GLFW_WIN32_KEYBOARD_MENU_hint +__GLFW_WIN32_KEYBOARD_MENU__ specifies whether to allow access to the window +menu via the Alt+Space and Alt-and-then-Space keyboard shortcuts. This is +ignored on other platforms. + +@anchor GLFW_WIN32_SHOWDEFAULT_hint +__GLFW_WIN32_SHOWDEFAULT__ specifies whether to show the window the way +specified in the program's `STARTUPINFO` when it is shown for the first time. +This is the same information as the `Run` option in the shortcut properties +window. If this information was not specified when the program was started, +GLFW behaves as if this hint was set to `GLFW_FALSE`. Possible values are +`GLFW_TRUE` and `GLFW_FALSE`. This is ignored on other platforms. + + +#### macOS specific hints {#window_hints_osx} @anchor GLFW_COCOA_FRAME_NAME_hint __GLFW_COCOA_FRAME_NAME__ specifies the UTF-8 encoded name to use for autosaving @@ -466,16 +511,25 @@ should also declare this in its `Info.plist` by setting the `NSSupportsAutomaticGraphicsSwitching` key to `true`. -@subsubsection window_hints_x11 X11 specific window hints +#### Wayland specific window hints {#window_hints_wayland} + +@anchor GLFW_WAYLAND_APP_ID_hint +__GLFW_WAYLAND_APP_ID__ specifies the Wayland app_id for a window, used +by window managers to identify types of windows. This is set with +@ref glfwWindowHintString. + + +#### X11 specific window hints {#window_hints_x11} @anchor GLFW_X11_CLASS_NAME_hint @anchor GLFW_X11_INSTANCE_NAME_hint __GLFW_X11_CLASS_NAME__ and __GLFW_X11_INSTANCE_NAME__ specifies the desired -ASCII encoded class and instance parts of the ICCCM `WM_CLASS` window property. +ASCII encoded class and instance parts of the ICCCM `WM_CLASS` window property. Both +hints need to be set to something other than an empty string for them to take effect. These are set with @ref glfwWindowHintString. -@subsubsection window_hints_values Supported and default values +#### Supported and default values {#window_hints_values} Window hint | Default value | Supported values ----------------------------- | --------------------------- | ---------------- @@ -490,6 +544,10 @@ GLFW_CENTER_CURSOR | `GLFW_TRUE` | `GLFW_TRUE` or `GL GLFW_TRANSPARENT_FRAMEBUFFER | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` GLFW_FOCUS_ON_SHOW | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` GLFW_SCALE_TO_MONITOR | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_SCALE_FRAMEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_MOUSE_PASSTHROUGH | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_POSITION_X | `GLFW_ANY_POSITION` | Any valid screen x-coordinate or `GLFW_ANY_POSITION` +GLFW_POSITION_Y | `GLFW_ANY_POSITION` | Any valid screen y-coordinate or `GLFW_ANY_POSITION` GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` @@ -513,23 +571,25 @@ GLFW_CONTEXT_VERSION_MINOR | 0 | Any valid minor ve GLFW_CONTEXT_ROBUSTNESS | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET` GLFW_CONTEXT_RELEASE_BEHAVIOR | `GLFW_ANY_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE` GLFW_OPENGL_FORWARD_COMPAT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_OPENGL_DEBUG_CONTEXT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_CONTEXT_DEBUG | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` GLFW_OPENGL_PROFILE | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE` -GLFW_COCOA_RETINA_FRAMEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_WIN32_KEYBOARD_MENU | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_WIN32_SHOWDEFAULT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` GLFW_COCOA_FRAME_NAME | `""` | A UTF-8 encoded frame autosave name GLFW_COCOA_GRAPHICS_SWITCHING | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_WAYLAND_APP_ID | `""` | An ASCII encoded Wayland `app_id` name GLFW_X11_CLASS_NAME | `""` | An ASCII encoded `WM_CLASS` class name GLFW_X11_INSTANCE_NAME | `""` | An ASCII encoded `WM_CLASS` instance name -@section window_events Window event processing +## Window event processing {#window_events} See @ref events. -@section window_properties Window properties and events +## Window properties and events {#window_properties} -@subsection window_userptr User pointer +### User pointer {#window_userptr} Each window has a user pointer that can be set with @ref glfwSetWindowUserPointer and queried with @ref glfwGetWindowUserPointer. This @@ -539,7 +599,7 @@ the life-time of the window. The initial value of the pointer is `NULL`. -@subsection window_close Window closing and close flag +### Window closing and close flag {#window_close} When the user attempts to close the window, for example by clicking the close widget or using a key chord like Alt+F4, the _close flag_ of the window is set. @@ -550,7 +610,7 @@ The current state of the close flag is returned by @ref glfwWindowShouldClose and can be set or cleared directly with @ref glfwSetWindowShouldClose. A common pattern is to use the close flag as a main loop condition. -@code +```c while (!glfwWindowShouldClose(window)) { render(window); @@ -558,38 +618,38 @@ while (!glfwWindowShouldClose(window)) glfwSwapBuffers(window); glfwPollEvents(); } -@endcode +``` If you wish to be notified when the user attempts to close a window, set a close callback. -@code +```c glfwSetWindowCloseCallback(window, window_close_callback); -@endcode +``` The callback function is called directly _after_ the close flag has been set. It can be used for example to filter close requests and clear the close flag again unless certain conditions are met. -@code +```c void window_close_callback(GLFWwindow* window) { if (!time_to_close) glfwSetWindowShouldClose(window, GLFW_FALSE); } -@endcode +``` -@subsection window_size Window size +### Window size {#window_size} The size of a window can be changed with @ref glfwSetWindowSize. For windowed mode windows, this sets the size, in [screen coordinates](@ref coordinate_systems) of the _content area_ or _content area_ of the window. The window system may impose limits on window size. -@code +```c glfwSetWindowSize(window, 640, 480); -@endcode +``` For full screen windows, the specified size becomes the new resolution of the window's desired video mode. The video mode most closely matching the new @@ -599,26 +659,26 @@ resolution of the set video mode. If you wish to be notified when a window is resized, whether by the user, the system or your own code, set a size callback. -@code +```c glfwSetWindowSizeCallback(window, window_size_callback); -@endcode +``` The callback function receives the new size, in screen coordinates, of the content area of the window when the window is resized. -@code +```c void window_size_callback(GLFWwindow* window, int width, int height) { } -@endcode +``` There is also @ref glfwGetWindowSize for directly retrieving the current size of a window. -@code +```c int width, height; glfwGetWindowSize(window, &width, &height); -@endcode +``` @note Do not pass the window size to `glViewport` or other pixel-based OpenGL calls. The window size is in screen coordinates, not pixels. Use the @@ -629,17 +689,17 @@ The above functions work with the size of the content area, but decorated windows typically have title bars and window frames around this rectangle. You can retrieve the extents of these with @ref glfwGetWindowFrameSize. -@code +```c int left, top, right, bottom; glfwGetWindowFrameSize(window, &left, &top, &right, &bottom); -@endcode +``` The returned values are the distances, in screen coordinates, from the edges of the content area to the corresponding edges of the full window. As they are distances and not coordinates, they are always zero or positive. -@subsection window_fbsize Framebuffer size +### Framebuffer size {#window_fbsize} While the size of a window is measured in screen coordinates, OpenGL works with pixels. The size you pass into `glViewport`, for example, should be in pixels. @@ -650,70 +710,75 @@ pixels, of the framebuffer of a window. If you wish to be notified when the framebuffer of a window is resized, whether by the user or the system, set a size callback. -@code +```c glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); -@endcode +``` The callback function receives the new size of the framebuffer when it is resized, which can for example be used to update the OpenGL viewport. -@code +```c void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } -@endcode +``` There is also @ref glfwGetFramebufferSize for directly retrieving the current size of the framebuffer of a window. -@code +```c int width, height; glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); -@endcode +``` The size of a framebuffer may change independently of the size of a window, for example if the window is dragged between a regular monitor and a high-DPI one. -@subsection window_scale Window content scale +### Window content scale {#window_scale} The content scale for a window can be retrieved with @ref glfwGetWindowContentScale. -@code +```c float xscale, yscale; glfwGetWindowContentScale(window, &xscale, &yscale); -@endcode +``` -The content scale is the ratio between the current DPI and the platform's -default DPI. This is especially important for text and any UI elements. If the -pixel dimensions of your UI scaled by this look appropriate on your machine then -it should appear at a reasonable size on other machines regardless of their DPI -and scaling settings. This relies on the system DPI and scaling settings being -somewhat correct. +The content scale can be thought of as the ratio between the current DPI and the +platform's default DPI. It is intended to be a scaling factor to apply to the +pixel dimensions of text and other UI elements. If the dimensions scaled by +this factor looks appropriate on your machine then it should appear at +a reasonable size on other machines with different DPI and scaling settings. + +This relies on the DPI and scaling settings on both machines being appropriate. + +The content scale may depend on both the monitor resolution and pixel density +and on user settings like DPI or a scaling percentage. It may be very different +from the raw DPI calculated from the physical size and current resolution. On systems where each monitors can have its own content scale, the window -content scale will depend on which monitor the system considers the window to be -on. +content scale will depend on which monitor or monitors the system considers the +window to be "on". If you wish to be notified when the content scale of a window changes, whether because of a system setting change or because it was moved to a monitor with a different scale, set a content scale callback. -@code +```c glfwSetWindowContentScaleCallback(window, window_content_scale_callback); -@endcode +``` The callback function receives the new content scale of the window. -@code +```c void window_content_scale_callback(GLFWwindow* window, float xscale, float yscale) { set_interface_scale(xscale, yscale); } -@endcode +``` On platforms where pixels and screen coordinates always map 1:1, the window will need to be resized to appear the same size when it is moved to a monitor @@ -721,24 +786,36 @@ with a different content scale. To have this done automatically both when the window is created and when its content scale later changes, set the @ref GLFW_SCALE_TO_MONITOR window hint. +On platforms where pixels do not necessarily equal screen coordinates, the +framebuffer will instead need to be sized to provide a full resolution image +for the window. When the window moves between monitors with different content +scales, the window size will remain the same but the framebuffer size will +change. This is done automatically by default. To disable this resizing, set +the @ref GLFW_SCALE_FRAMEBUFFER window hint. -@subsection window_sizelimits Window size limits +Both of these hints also apply when the window is created. Every window starts +out with a content scale of one. A window with one or both of these hints set +will adapt to the appropriate scale in the process of being created, set up and +shown. + + +### Window size limits {#window_sizelimits} The minimum and maximum size of the content area of a windowed mode window can be enforced with @ref glfwSetWindowSizeLimits. The user may resize the window to any size and aspect ratio within the specified limits, unless the aspect ratio is also set. -@code +```c glfwSetWindowSizeLimits(window, 200, 200, 400, 400); -@endcode +``` To specify only a minimum size or only a maximum one, set the other pair to `GLFW_DONT_CARE`. -@code +```c glfwSetWindowSizeLimits(window, 640, 480, GLFW_DONT_CARE, GLFW_DONT_CARE); -@endcode +``` To disable size limits for a window, set them all to `GLFW_DONT_CARE`. @@ -747,19 +824,19 @@ with @ref glfwSetWindowAspectRatio. The user may resize the window freely unless size limits are also set, but the size will be constrained to maintain the aspect ratio. -@code +```c glfwSetWindowAspectRatio(window, 16, 9); -@endcode +``` The aspect ratio is specified as a numerator and denominator, corresponding to the width and height, respectively. If you want a window to maintain its current aspect ratio, use its current size as the ratio. -@code +```c int width, height; glfwGetWindowSize(window, &width, &height); glfwSetWindowAspectRatio(window, width, height); -@endcode +``` To disable the aspect ratio limit for a window, set both terms to `GLFW_DONT_CARE`. @@ -768,51 +845,64 @@ You can have both size limits and aspect ratio set for a window, but the results are undefined if they conflict. -@subsection window_pos Window position +### Window position {#window_pos} -The position of a windowed-mode window can be changed with @ref +By default, the window manager chooses the position of new windowed mode +windows, based on its size and which monitor the user appears to be working on. +This is most often the right choice. If you need to create a window at +a specific position, you can set the desired position with the @ref +GLFW_POSITION_X and @ref GLFW_POSITION_Y window hints. + +```c +glfwWindowHint(GLFW_POSITION_X, 70); +glfwWindowHint(GLFW_POSITION_Y, 83); +``` + +To restore the previous behavior, set these hints to `GLFW_ANY_POSITION`. + +The position of a windowed mode window can be changed with @ref glfwSetWindowPos. This moves the window so that the upper-left corner of its content area has the specified [screen coordinates](@ref coordinate_systems). The window system may put limitations on window placement. -@code +```c glfwSetWindowPos(window, 100, 100); -@endcode +``` If you wish to be notified when a window is moved, whether by the user, the system or your own code, set a position callback. -@code +```c glfwSetWindowPosCallback(window, window_pos_callback); -@endcode +``` The callback function receives the new position, in screen coordinates, of the upper-left corner of the content area when the window is moved. -@code +```c void window_pos_callback(GLFWwindow* window, int xpos, int ypos) { } -@endcode +``` There is also @ref glfwGetWindowPos for directly retrieving the current position of the content area of the window. -@code +```c int xpos, ypos; glfwGetWindowPos(window, &xpos, &ypos); -@endcode +``` -@subsection window_title Window title +### Window title {#window_title} All GLFW windows have a title, although undecorated or full screen windows may not display it or only display it in a task bar or similar interface. You can -set a UTF-8 encoded window title with @ref glfwSetWindowTitle. +set a new UTF-8 encoded window title with @ref glfwSetWindowTitle. -@code +```c glfwSetWindowTitle(window, "My Window"); -@endcode +``` The specified string is copied before the function returns, so there is no need to keep it around. @@ -820,29 +910,34 @@ to keep it around. As long as your source file is encoded as UTF-8, you can use any Unicode characters directly in the source. -@code +```c glfwSetWindowTitle(window, "ラストエグザイル"); -@endcode +``` If you are using C++11 or C11, you can use a UTF-8 string literal. -@code +```c glfwSetWindowTitle(window, u8"This is always a UTF-8 string"); -@endcode +``` +The current window title can be queried with @ref glfwGetWindowTitle. -@subsection window_icon Window icon +```c +const char* title = glfwGetWindowTitle(window); +``` + +### Window icon {#window_icon} Decorated windows have icons on some platforms. You can set this icon by specifying a list of candidate images with @ref glfwSetWindowIcon. -@code +```c GLFWimage images[2]; images[0] = load_icon("my_icon.png"); images[1] = load_icon("my_icon_small.png"); glfwSetWindowIcon(window, 2, images); -@endcode +``` The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits per channel with the red channel first. The pixels are arranged canonically as @@ -850,19 +945,19 @@ sequential rows, starting from the top-left corner. To revert to the default window icon, pass in an empty image array. -@code +```c glfwSetWindowIcon(window, 0, NULL); -@endcode +``` -@subsection window_monitor Window monitor +### Window monitor {#window_monitor} Full screen windows are associated with a specific monitor. You can get the handle for this monitor with @ref glfwGetWindowMonitor. -@code +```c GLFWmonitor* monitor = glfwGetWindowMonitor(window); -@endcode +``` This monitor handle is one of those returned by @ref glfwGetMonitors. @@ -874,18 +969,18 @@ with @ref glfwSetWindowMonitor. When making a window full screen on the same or on a different monitor, specify the desired monitor, resolution and refresh rate. The position arguments are ignored. -@code +```c const GLFWvidmode* mode = glfwGetVideoMode(monitor); glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); -@endcode +``` When making the window windowed, specify the desired position and size. The refresh rate argument is ignored. -@code +```c glfwSetWindowMonitor(window, NULL, xpos, ypos, width, height, 0); -@endcode +``` This restores any previous window settings such as whether it is decorated, floating, resizable, has size or aspect ratio limits, etc.. To restore a window @@ -893,13 +988,13 @@ that was originally windowed to its original size and position, save these before making it full screen and then pass them in as above. -@subsection window_iconify Window iconification +### Window iconification {#window_iconify} Windows can be iconified (i.e. minimized) with @ref glfwIconifyWindow. -@code +```c glfwIconifyWindow(window); -@endcode +``` When a full screen window is iconified, the original video mode of its monitor is restored until the user or application restores the window. @@ -907,9 +1002,9 @@ is restored until the user or application restores the window. Iconified windows can be restored with @ref glfwRestoreWindow. This function also restores windows from maximization. -@code +```c glfwRestoreWindow(window); -@endcode +``` When a full screen window is restored, the desired video mode is restored to its monitor as well. @@ -917,13 +1012,13 @@ monitor as well. If you wish to be notified when a window is iconified or restored, whether by the user, system or your own code, set an iconify callback. -@code +```c glfwSetWindowIconifyCallback(window, window_iconify_callback); -@endcode +``` The callback function receives changes in the iconification state of the window. -@code +```c void window_iconify_callback(GLFWwindow* window, int iconified) { if (iconified) @@ -935,22 +1030,22 @@ void window_iconify_callback(GLFWwindow* window, int iconified) // The window was restored } } -@endcode +``` You can also get the current iconification state with @ref glfwGetWindowAttrib. -@code +```c int iconified = glfwGetWindowAttrib(window, GLFW_ICONIFIED); -@endcode +``` -@subsection window_maximize Window maximization +### Window maximization {#window_maximize} Windows can be maximized (i.e. zoomed) with @ref glfwMaximizeWindow. -@code +```c glfwMaximizeWindow(window); -@endcode +``` Full screen windows cannot be maximized and passing a full screen window to this function does nothing. @@ -958,20 +1053,20 @@ function does nothing. Maximized windows can be restored with @ref glfwRestoreWindow. This function also restores windows from iconification. -@code +```c glfwRestoreWindow(window); -@endcode +``` If you wish to be notified when a window is maximized or restored, whether by the user, system or your own code, set a maximize callback. -@code +```c glfwSetWindowMaximizeCallback(window, window_maximize_callback); -@endcode +``` The callback function receives changes in the maximization state of the window. -@code +```c void window_maximize_callback(GLFWwindow* window, int maximized) { if (maximized) @@ -983,30 +1078,30 @@ void window_maximize_callback(GLFWwindow* window, int maximized) // The window was restored } } -@endcode +``` You can also get the current maximization state with @ref glfwGetWindowAttrib. -@code +```c int maximized = glfwGetWindowAttrib(window, GLFW_MAXIMIZED); -@endcode +``` By default, newly created windows are not maximized. You can change this behavior by setting the [GLFW_MAXIMIZED](@ref GLFW_MAXIMIZED_hint) window hint before creating the window. -@code +```c glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE); -@endcode +``` -@subsection window_hide Window visibility +### Window visibility {#window_hide} Windowed mode windows can be hidden with @ref glfwHideWindow. -@code +```c glfwHideWindow(window); -@endcode +``` This makes the window completely invisible to the user, including removing it from the task bar, dock or window list. Full screen windows cannot be hidden @@ -1014,9 +1109,9 @@ and calling @ref glfwHideWindow on a full screen window does nothing. Hidden windows can be shown with @ref glfwShowWindow. -@code +```c glfwShowWindow(window); -@endcode +``` By default, this function will also set the input focus to that window. Set the [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) window hint to change @@ -1025,31 +1120,31 @@ existing window with @ref glfwSetWindowAttrib. You can also get the current visibility state with @ref glfwGetWindowAttrib. -@code +```c int visible = glfwGetWindowAttrib(window, GLFW_VISIBLE); -@endcode +``` By default, newly created windows are visible. You can change this behavior by setting the [GLFW_VISIBLE](@ref GLFW_VISIBLE_hint) window hint before creating the window. -@code +```c glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); -@endcode +``` Windows created hidden are completely invisible to the user until shown. This can be useful if you need to set up your window further before showing it, for example moving it to a specific location. -@subsection window_focus Window input focus +### Window input focus {#window_focus} Windows can be given input focus and brought to the front with @ref glfwFocusWindow. -@code +```c glfwFocusWindow(window); -@endcode +``` Keep in mind that it can be very disruptive to the user when a window is forced to the top. For a less disruptive way of getting the user's attention, see @@ -1058,13 +1153,13 @@ to the top. For a less disruptive way of getting the user's attention, see If you wish to be notified when a window gains or loses input focus, whether by the user, system or your own code, set a focus callback. -@code +```c glfwSetWindowFocusCallback(window, window_focus_callback); -@endcode +``` The callback function receives changes in the input focus state of the window. -@code +```c void window_focus_callback(GLFWwindow* window, int focused) { if (focused) @@ -1076,63 +1171,63 @@ void window_focus_callback(GLFWwindow* window, int focused) // The window lost input focus } } -@endcode +``` You can also get the current input focus state with @ref glfwGetWindowAttrib. -@code +```c int focused = glfwGetWindowAttrib(window, GLFW_FOCUSED); -@endcode +``` By default, newly created windows are given input focus. You can change this behavior by setting the [GLFW_FOCUSED](@ref GLFW_FOCUSED_hint) window hint before creating the window. -@code +```c glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE); -@endcode +``` -@subsection window_attention Window attention request +### Window attention request {#window_attention} If you wish to notify the user of an event without interrupting, you can request attention with @ref glfwRequestWindowAttention. -@code +```c glfwRequestWindowAttention(window); -@endcode +``` The system will highlight the specified window, or on platforms where this is not supported, the application as a whole. Once the user has given it attention, the system will automatically end the request. -@subsection window_refresh Window damage and refresh +### Window damage and refresh {#window_refresh} If you wish to be notified when the contents of a window is damaged and needs to be refreshed, set a window refresh callback. -@code +```c glfwSetWindowRefreshCallback(m_handle, window_refresh_callback); -@endcode +``` The callback function is called when the contents of the window needs to be refreshed. -@code +```c void window_refresh_callback(GLFWwindow* window) { draw_editor_ui(window); glfwSwapBuffers(window); } -@endcode +``` @note On compositing window systems such as Aero, Compiz or Aqua, where the window contents are saved off-screen, this callback might only be called when the window or framebuffer is resized. -@subsection window_transparency Window transparency +### Window transparency {#window_transparency} GLFW supports two kinds of transparency for windows; framebuffer transparency and whole window transparency. A single window may not use both methods. The @@ -1146,9 +1241,9 @@ Window framebuffers can be made transparent on a per-pixel per-frame basis with the [GLFW_TRANSPARENT_FRAMEBUFFER](@ref GLFW_TRANSPARENT_FRAMEBUFFER_hint) window hint. -@code +```c glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); -@endcode +``` If supported by the system, the window content area will be composited with the background using the framebuffer per-pixel alpha channel. This requires desktop @@ -1159,21 +1254,21 @@ with the [GLFW_TRANSPARENT_FRAMEBUFFER](@ref GLFW_TRANSPARENT_FRAMEBUFFER_attrib) window attribute. -@code +```c if (glfwGetWindowAttrib(window, GLFW_TRANSPARENT_FRAMEBUFFER)) { // window framebuffer is currently transparent } -@endcode +``` GLFW comes with an example that enabled framebuffer transparency called `gears`. The opacity of the whole window, including any decorations, can be set with @ref glfwSetWindowOpacity. -@code +```c glfwSetWindowOpacity(window, 0.5f); -@endcode +``` The opacity (or alpha) value is a positive finite number between zero and one, where 0 (zero) is fully transparent and 1 (one) is fully opaque. The initial @@ -1181,18 +1276,22 @@ opacity value for newly created windows is 1. The current opacity of a window can be queried with @ref glfwGetWindowOpacity. -@code +```c float opacity = glfwGetWindowOpacity(window); -@endcode +``` If the system does not support whole window transparency, this function always returns one. GLFW comes with a test program that lets you control whole window transparency -at run-time called `opacity`. +at run-time called `window`. + +If you want to use either of these transparency methods to display a temporary +overlay like for example a notification, the @ref GLFW_FLOATING and @ref +GLFW_MOUSE_PASSTHROUGH window hints and attributes may be useful. -@subsection window_attribs Window attributes +### Window attributes {#window_attribs} Windows have a number of attributes that can be returned using @ref glfwGetWindowAttrib. Some reflect state that may change as a result of user @@ -1200,12 +1299,12 @@ interaction, (e.g. whether it has input focus), while others reflect inherent properties of the window (e.g. what kind of border it has). Some are related to the window and others to its OpenGL or OpenGL ES context. -@code +```c if (glfwGetWindowAttrib(window, GLFW_FOCUSED)) { // window has input focus } -@endcode +``` The [GLFW_DECORATED](@ref GLFW_DECORATED_attrib), [GLFW_RESIZABLE](@ref GLFW_RESIZABLE_attrib), @@ -1214,13 +1313,13 @@ The [GLFW_DECORATED](@ref GLFW_DECORATED_attrib), [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_attrib) window attributes can be changed with @ref glfwSetWindowAttrib. -@code +```c glfwSetWindowAttrib(window, GLFW_RESIZABLE, GLFW_FALSE); -@endcode +``` -@subsubsection window_attribs_wnd Window related attributes +#### Window related attributes {#window_attribs_wnd} @anchor GLFW_FOCUSED_attrib __GLFW_FOCUSED__ indicates whether the specified window has input focus. See @@ -1279,7 +1378,16 @@ focus when @ref glfwShowWindow is called. This can be set before creation with the [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) window hint or after with @ref glfwSetWindowAttrib. -@subsubsection window_attribs_ctx Context related attributes +@anchor GLFW_MOUSE_PASSTHROUGH_attrib +__GLFW_MOUSE_PASSTHROUGH__ specifies whether the window is transparent to mouse +input, letting any mouse events pass through to whatever window is behind it. +This can be set before creation with the +[GLFW_MOUSE_PASSTHROUGH](@ref GLFW_MOUSE_PASSTHROUGH_hint) window hint or after +with @ref glfwSetWindowAttrib. This is only supported for undecorated windows. +Decorated windows with this enabled will behave differently between platforms. + + +#### Context related attributes {#window_attribs_ctx} @anchor GLFW_CLIENT_API_attrib __GLFW_CLIENT_API__ indicates the client API provided by the window's context; @@ -1305,10 +1413,14 @@ of the GLFW header. __GLFW_OPENGL_FORWARD_COMPAT__ is `GLFW_TRUE` if the window's context is an OpenGL forward-compatible one, or `GLFW_FALSE` otherwise. +@anchor GLFW_CONTEXT_DEBUG_attrib @anchor GLFW_OPENGL_DEBUG_CONTEXT_attrib -__GLFW_OPENGL_DEBUG_CONTEXT__ is `GLFW_TRUE` if the window's context is in debug +__GLFW_CONTEXT_DEBUG__ is `GLFW_TRUE` if the window's context is in debug mode, or `GLFW_FALSE` otherwise. +This is the new name, introduced in GLFW 3.4. The older +`GLFW_OPENGL_DEBUG_CONTEXT` name is also available for compatibility. + @anchor GLFW_OPENGL_PROFILE_attrib __GLFW_OPENGL_PROFILE__ indicates the OpenGL profile used by the context. This is `GLFW_OPENGL_CORE_PROFILE` or `GLFW_OPENGL_COMPAT_PROFILE` if the context @@ -1338,11 +1450,13 @@ context. This is `GLFW_LOSE_CONTEXT_ON_RESET` or `GLFW_NO_RESET_NOTIFICATION` if the window's context supports robustness, or `GLFW_NO_ROBUSTNESS` otherwise. -@subsubsection window_attribs_fb Framebuffer related attributes +#### Framebuffer related attributes {#window_attribs_fb} -GLFW does not expose attributes of the default framebuffer (i.e. the framebuffer -attached to the window) as these can be queried directly with either OpenGL, -OpenGL ES or Vulkan. +GLFW does not expose most attributes of the default framebuffer (i.e. the +framebuffer attached to the window) as these can be queried directly with either +OpenGL, OpenGL ES or Vulkan. The one exception is +[GLFW_DOUBLEBUFFER](@ref GLFW_DOUBLEBUFFER_attrib), as this is not provided by +OpenGL ES. If you are using version 3.0 or later of OpenGL or OpenGL ES, the `glGetFramebufferAttachmentParameteriv` function can be used to retrieve the @@ -1368,8 +1482,13 @@ alpha sizes are queried from the `GL_BACK_LEFT`, while the depth and stencil sizes are queried from the `GL_DEPTH` and `GL_STENCIL` attachments, respectively. +@anchor GLFW_DOUBLEBUFFER_attrib +__GLFW_DOUBLEBUFFER__ indicates whether the specified window is double-buffered +when rendering with OpenGL or OpenGL ES. This can be set before creation with +the [GLFW_DOUBLEBUFFER](@ref GLFW_DOUBLEBUFFER_hint) window hint. -@section buffer_swap Buffer swapping + +## Buffer swapping {#buffer_swap} GLFW windows are by default double buffered. That means that you have two rendering buffers; a front buffer and a back buffer. The front buffer is @@ -1379,18 +1498,18 @@ When the entire frame has been rendered, it is time to swap the back and the front buffers in order to display what has been rendered and begin rendering a new frame. This is done with @ref glfwSwapBuffers. -@code +```c glfwSwapBuffers(window); -@endcode +``` Sometimes it can be useful to select when the buffer swap will occur. With the function @ref glfwSwapInterval it is possible to select the minimum number of monitor refreshes the driver should wait from the time @ref glfwSwapBuffers was called before swapping the buffers: -@code +```c glfwSwapInterval(1); -@endcode +``` If the interval is zero, the swap will take place immediately when @ref glfwSwapBuffers is called without waiting for a refresh. Otherwise at least @@ -1409,4 +1528,3 @@ which allows the driver to swap immediately even if a frame arrives a little bit late. This trades the risk of visible tears for greater framerate stability. You can check for these extensions with @ref glfwExtensionSupported. -*/ diff --git a/src/lib/src/vendor/glfw-3.3.8/examples/CMakeLists.txt b/src/lib/src/vendor/glfw-3.4/examples/CMakeLists.txt similarity index 75% rename from src/lib/src/vendor/glfw-3.3.8/examples/CMakeLists.txt rename to src/lib/src/vendor/glfw-3.4/examples/CMakeLists.txt index 0eba4e6..e7a0379 100644 --- a/src/lib/src/vendor/glfw-3.3.8/examples/CMakeLists.txt +++ b/src/lib/src/vendor/glfw-3.4/examples/CMakeLists.txt @@ -18,19 +18,8 @@ elseif (APPLE) set(ICON glfw.icns) endif() -if (${CMAKE_VERSION} VERSION_EQUAL "3.1.0" OR - ${CMAKE_VERSION} VERSION_GREATER "3.1.0") - set(CMAKE_C_STANDARD 99) -else() - # Remove this fallback when removing support for CMake version less than 3.1 - add_compile_options("$<$:-std=c99>" - "$<$:-std=c99>" - "$<$:-std=c99>") - -endif() - -set(GLAD_GL "${GLFW_SOURCE_DIR}/deps/glad/gl.h" - "${GLFW_SOURCE_DIR}/deps/glad_gl.c") +set(GLAD_GL "${GLFW_SOURCE_DIR}/deps/glad/gl.h") +set(GLAD_GLES2 "${GLFW_SOURCE_DIR}/deps/glad/gles2.h") set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h" "${GLFW_SOURCE_DIR}/deps/getopt.c") set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h" @@ -42,26 +31,25 @@ add_executable(heightmap WIN32 MACOSX_BUNDLE heightmap.c ${ICON} ${GLAD_GL}) add_executable(offscreen offscreen.c ${ICON} ${GLAD_GL}) add_executable(particles WIN32 MACOSX_BUNDLE particles.c ${ICON} ${TINYCTHREAD} ${GETOPT} ${GLAD_GL}) add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c ${ICON} ${GLAD_GL}) -add_executable(simple WIN32 MACOSX_BUNDLE simple.c ${ICON} ${GLAD_GL}) add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD_GL}) +add_executable(triangle-opengl WIN32 MACOSX_BUNDLE triangle-opengl.c ${ICON} ${GLAD_GL}) +add_executable(triangle-opengles WIN32 MACOSX_BUNDLE triangle-opengles.c ${ICON} ${GLAD_GLES2}) add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL}) +add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${ICON} ${GLAD_GL}) -target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}") +target_link_libraries(particles Threads::Threads) if (RT_LIBRARY) target_link_libraries(particles "${RT_LIBRARY}") endif() -set(GUI_ONLY_BINARIES boing gears heightmap particles sharing simple splitview - wave) +set(GUI_ONLY_BINARIES boing gears heightmap particles sharing splitview + triangle-opengl triangle-opengles wave windows) set(CONSOLE_BINARIES offscreen) set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES + C_STANDARD 99 FOLDER "GLFW3/Examples") -if (GLFW_USE_OSMESA) - target_compile_definitions(offscreen PRIVATE USE_NATIVE_OSMESA) -endif() - if (MSVC) # Tell MSVC to use main instead of WinMain set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES @@ -78,9 +66,11 @@ if (APPLE) set_target_properties(heightmap PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Heightmap") set_target_properties(particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles") set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing") - set_target_properties(simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple") + set_target_properties(triangle-opengl PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "OpenGL Triangle") + set_target_properties(triangle-opengles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "OpenGL ES Triangle") set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView") set_target_properties(wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave") + set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows") set_source_files_properties(glfw.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") @@ -88,6 +78,6 @@ if (APPLE) MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION} MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION} MACOSX_BUNDLE_ICON_FILE glfw.icns - MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/MacOSXBundleInfo.plist.in") + MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/Info.plist.in") endif() diff --git a/src/lib/src/vendor/glfw-3.3.8/examples/boing.c b/src/lib/src/vendor/glfw-3.4/examples/boing.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/examples/boing.c rename to src/lib/src/vendor/glfw-3.4/examples/boing.c index ca38908..ec118a3 100644 --- a/src/lib/src/vendor/glfw-3.3.8/examples/boing.c +++ b/src/lib/src/vendor/glfw-3.4/examples/boing.c @@ -36,6 +36,7 @@ #include #include +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/examples/gears.c b/src/lib/src/vendor/glfw-3.4/examples/gears.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/examples/gears.c rename to src/lib/src/vendor/glfw-3.4/examples/gears.c index 292f44b..3d63013 100644 --- a/src/lib/src/vendor/glfw-3.3.8/examples/gears.c +++ b/src/lib/src/vendor/glfw-3.4/examples/gears.c @@ -31,6 +31,7 @@ #include #include +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/examples/glfw.icns b/src/lib/src/vendor/glfw-3.4/examples/glfw.icns similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/examples/glfw.icns rename to src/lib/src/vendor/glfw-3.4/examples/glfw.icns diff --git a/src/lib/src/vendor/glfw-3.3.8/examples/glfw.ico b/src/lib/src/vendor/glfw-3.4/examples/glfw.ico similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/examples/glfw.ico rename to src/lib/src/vendor/glfw-3.4/examples/glfw.ico diff --git a/src/lib/src/vendor/glfw-3.3.8/examples/glfw.rc b/src/lib/src/vendor/glfw-3.4/examples/glfw.rc similarity index 100% rename from src/lib/src/vendor/glfw-3.3.8/examples/glfw.rc rename to src/lib/src/vendor/glfw-3.4/examples/glfw.rc diff --git a/src/lib/src/vendor/glfw-3.3.8/examples/heightmap.c b/src/lib/src/vendor/glfw-3.4/examples/heightmap.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/examples/heightmap.c rename to src/lib/src/vendor/glfw-3.4/examples/heightmap.c index 988dd0b..ad5d47c 100644 --- a/src/lib/src/vendor/glfw-3.3.8/examples/heightmap.c +++ b/src/lib/src/vendor/glfw-3.4/examples/heightmap.c @@ -29,6 +29,7 @@ #include #include +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/examples/offscreen.c b/src/lib/src/vendor/glfw-3.4/examples/offscreen.c similarity index 94% rename from src/lib/src/vendor/glfw-3.3.8/examples/offscreen.c rename to src/lib/src/vendor/glfw-3.4/examples/offscreen.c index 16b8f3c..e285286 100644 --- a/src/lib/src/vendor/glfw-3.3.8/examples/offscreen.c +++ b/src/lib/src/vendor/glfw-3.4/examples/offscreen.c @@ -23,15 +23,11 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include -#if USE_NATIVE_OSMESA - #define GLFW_EXPOSE_NATIVE_OSMESA - #include -#endif - #include "linmath.h" #include @@ -150,12 +146,8 @@ int main(void) glDrawArrays(GL_TRIANGLES, 0, 3); glFinish(); -#if USE_NATIVE_OSMESA - glfwGetOSMesaColorBuffer(window, &width, &height, NULL, (void**) &buffer); -#else buffer = calloc(4, width * height); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); -#endif // Write image Y-flipped because OpenGL stbi_write_png("offscreen.png", @@ -163,11 +155,7 @@ int main(void) buffer + (width * 4 * (height - 1)), -width * 4); -#if USE_NATIVE_OSMESA - // Here is where there's nothing -#else free(buffer); -#endif glfwDestroyWindow(window); diff --git a/src/lib/src/vendor/glfw-3.3.8/examples/particles.c b/src/lib/src/vendor/glfw-3.4/examples/particles.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/examples/particles.c rename to src/lib/src/vendor/glfw-3.4/examples/particles.c index 9556cca..baafe82 100644 --- a/src/lib/src/vendor/glfw-3.3.8/examples/particles.c +++ b/src/lib/src/vendor/glfw-3.4/examples/particles.c @@ -39,6 +39,7 @@ #include #include +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/examples/sharing.c b/src/lib/src/vendor/glfw-3.4/examples/sharing.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/examples/sharing.c rename to src/lib/src/vendor/glfw-3.4/examples/sharing.c index 4a1a232..502f9ee 100644 --- a/src/lib/src/vendor/glfw-3.3.8/examples/sharing.c +++ b/src/lib/src/vendor/glfw-3.4/examples/sharing.c @@ -23,6 +23,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include @@ -30,7 +31,6 @@ #include #include -#include "getopt.h" #include "linmath.h" static const char* vertex_shader_text = diff --git a/src/lib/src/vendor/glfw-3.3.8/examples/splitview.c b/src/lib/src/vendor/glfw-3.4/examples/splitview.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/examples/splitview.c rename to src/lib/src/vendor/glfw-3.4/examples/splitview.c index 079c2cb..990df12 100644 --- a/src/lib/src/vendor/glfw-3.3.8/examples/splitview.c +++ b/src/lib/src/vendor/glfw-3.4/examples/splitview.c @@ -10,6 +10,7 @@ // because I am not a friend of orthogonal projections) //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/examples/simple.c b/src/lib/src/vendor/glfw-3.4/examples/triangle-opengl.c similarity index 70% rename from src/lib/src/vendor/glfw-3.3.8/examples/simple.c rename to src/lib/src/vendor/glfw-3.4/examples/triangle-opengl.c index 95d8fe6..ff9e7d3 100644 --- a/src/lib/src/vendor/glfw-3.3.8/examples/simple.c +++ b/src/lib/src/vendor/glfw-3.4/examples/triangle-opengl.c @@ -1,5 +1,5 @@ //======================================================================== -// Simple GLFW example +// OpenGL triangle example // Copyright (c) Camilla Löwy // // This software is provided 'as-is', without any express or implied @@ -24,6 +24,7 @@ //======================================================================== //! [code] +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include @@ -31,25 +32,28 @@ #include "linmath.h" #include +#include #include -static const struct +typedef struct Vertex { - float x, y; - float r, g, b; -} vertices[3] = + vec2 pos; + vec3 col; +} Vertex; + +static const Vertex vertices[3] = { - { -0.6f, -0.4f, 1.f, 0.f, 0.f }, - { 0.6f, -0.4f, 0.f, 1.f, 0.f }, - { 0.f, 0.6f, 0.f, 0.f, 1.f } + { { -0.6f, -0.4f }, { 1.f, 0.f, 0.f } }, + { { 0.6f, -0.4f }, { 0.f, 1.f, 0.f } }, + { { 0.f, 0.6f }, { 0.f, 0.f, 1.f } } }; static const char* vertex_shader_text = -"#version 110\n" +"#version 330\n" "uniform mat4 MVP;\n" -"attribute vec3 vCol;\n" -"attribute vec2 vPos;\n" -"varying vec3 color;\n" +"in vec3 vCol;\n" +"in vec2 vPos;\n" +"out vec3 color;\n" "void main()\n" "{\n" " gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n" @@ -57,11 +61,12 @@ static const char* vertex_shader_text = "}\n"; static const char* fragment_shader_text = -"#version 110\n" -"varying vec3 color;\n" +"#version 330\n" +"in vec3 color;\n" +"out vec4 fragment;\n" "void main()\n" "{\n" -" gl_FragColor = vec4(color, 1.0);\n" +" fragment = vec4(color, 1.0);\n" "}\n"; static void error_callback(int error, const char* description) @@ -77,19 +82,16 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action, int main(void) { - GLFWwindow* window; - GLuint vertex_buffer, vertex_shader, fragment_shader, program; - GLint mvp_location, vpos_location, vcol_location; - glfwSetErrorCallback(error_callback); if (!glfwInit()) exit(EXIT_FAILURE); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL); + GLFWwindow* window = glfwCreateWindow(640, 480, "OpenGL Triangle", NULL, NULL); if (!window) { glfwTerminate(); @@ -104,53 +106,56 @@ int main(void) // NOTE: OpenGL error checks have been omitted for brevity + GLuint vertex_buffer; glGenBuffers(1, &vertex_buffer); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - vertex_shader = glCreateShader(GL_VERTEX_SHADER); + const GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL); glCompileShader(vertex_shader); - fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + const GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL); glCompileShader(fragment_shader); - program = glCreateProgram(); + const GLuint program = glCreateProgram(); glAttachShader(program, vertex_shader); glAttachShader(program, fragment_shader); glLinkProgram(program); - mvp_location = glGetUniformLocation(program, "MVP"); - vpos_location = glGetAttribLocation(program, "vPos"); - vcol_location = glGetAttribLocation(program, "vCol"); + const GLint mvp_location = glGetUniformLocation(program, "MVP"); + const GLint vpos_location = glGetAttribLocation(program, "vPos"); + const GLint vcol_location = glGetAttribLocation(program, "vCol"); + GLuint vertex_array; + glGenVertexArrays(1, &vertex_array); + glBindVertexArray(vertex_array); glEnableVertexAttribArray(vpos_location); glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE, - sizeof(vertices[0]), (void*) 0); + sizeof(Vertex), (void*) offsetof(Vertex, pos)); glEnableVertexAttribArray(vcol_location); glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE, - sizeof(vertices[0]), (void*) (sizeof(float) * 2)); + sizeof(Vertex), (void*) offsetof(Vertex, col)); while (!glfwWindowShouldClose(window)) { - float ratio; int width, height; - mat4x4 m, p, mvp; - glfwGetFramebufferSize(window, &width, &height); - ratio = width / (float) height; + const float ratio = width / (float) height; glViewport(0, 0, width, height); glClear(GL_COLOR_BUFFER_BIT); + mat4x4 m, p, mvp; mat4x4_identity(m); mat4x4_rotate_Z(m, m, (float) glfwGetTime()); mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f); mat4x4_mul(mvp, p, m); glUseProgram(program); - glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp); + glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) &mvp); + glBindVertexArray(vertex_array); glDrawArrays(GL_TRIANGLES, 0, 3); glfwSwapBuffers(window); diff --git a/src/lib/src/vendor/glfw-3.4/examples/triangle-opengles.c b/src/lib/src/vendor/glfw-3.4/examples/triangle-opengles.c new file mode 100644 index 0000000..03eb026 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/examples/triangle-opengles.c @@ -0,0 +1,170 @@ +//======================================================================== +// OpenGL ES 2.0 triangle example +// Copyright (c) Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as 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 GLAD_GLES2_IMPLEMENTATION +#include +#define GLFW_INCLUDE_NONE +#include + +#include "linmath.h" + +#include +#include +#include + +typedef struct Vertex +{ + vec2 pos; + vec3 col; +} Vertex; + +static const Vertex vertices[3] = +{ + { { -0.6f, -0.4f }, { 1.f, 0.f, 0.f } }, + { { 0.6f, -0.4f }, { 0.f, 1.f, 0.f } }, + { { 0.f, 0.6f }, { 0.f, 0.f, 1.f } } +}; + +static const char* vertex_shader_text = +"#version 100\n" +"precision mediump float;\n" +"uniform mat4 MVP;\n" +"attribute vec3 vCol;\n" +"attribute vec2 vPos;\n" +"varying vec3 color;\n" +"void main()\n" +"{\n" +" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n" +" color = vCol;\n" +"}\n"; + +static const char* fragment_shader_text = +"#version 100\n" +"precision mediump float;\n" +"varying vec3 color;\n" +"void main()\n" +"{\n" +" gl_FragColor = vec4(color, 1.0);\n" +"}\n"; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "GLFW Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GLFW_TRUE); +} + +int main(void) +{ + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API); + + GLFWwindow* window = glfwCreateWindow(640, 480, "OpenGL ES 2.0 Triangle (EGL)", NULL, NULL); + if (!window) + { + glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API); + window = glfwCreateWindow(640, 480, "OpenGL ES 2.0 Triangle", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + } + + glfwSetKeyCallback(window, key_callback); + + glfwMakeContextCurrent(window); + gladLoadGLES2(glfwGetProcAddress); + glfwSwapInterval(1); + + GLuint vertex_buffer; + glGenBuffers(1, &vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + const GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL); + glCompileShader(vertex_shader); + + const GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL); + glCompileShader(fragment_shader); + + const GLuint program = glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + + const GLint mvp_location = glGetUniformLocation(program, "MVP"); + const GLint vpos_location = glGetAttribLocation(program, "vPos"); + const GLint vcol_location = glGetAttribLocation(program, "vCol"); + + glEnableVertexAttribArray(vpos_location); + glEnableVertexAttribArray(vcol_location); + glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE, + sizeof(Vertex), (void*) offsetof(Vertex, pos)); + glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE, + sizeof(Vertex), (void*) offsetof(Vertex, col)); + + while (!glfwWindowShouldClose(window)) + { + int width, height; + glfwGetFramebufferSize(window, &width, &height); + const float ratio = width / (float) height; + + glViewport(0, 0, width, height); + glClear(GL_COLOR_BUFFER_BIT); + + mat4x4 m, p, mvp; + mat4x4_identity(m); + mat4x4_rotate_Z(m, m, (float) glfwGetTime()); + mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f); + mat4x4_mul(mvp, p, m); + + glUseProgram(program); + glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) &mvp); + glDrawArrays(GL_TRIANGLES, 0, 3); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwDestroyWindow(window); + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/src/lib/src/vendor/glfw-3.3.8/examples/wave.c b/src/lib/src/vendor/glfw-3.4/examples/wave.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/examples/wave.c rename to src/lib/src/vendor/glfw-3.4/examples/wave.c index 7acb8b9..d7ead49 100644 --- a/src/lib/src/vendor/glfw-3.3.8/examples/wave.c +++ b/src/lib/src/vendor/glfw-3.4/examples/wave.c @@ -17,6 +17,7 @@ #include #include +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.4/examples/windows.c b/src/lib/src/vendor/glfw-3.4/examples/windows.c new file mode 100644 index 0000000..1589ffb --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/examples/windows.c @@ -0,0 +1,106 @@ +//======================================================================== +// Simple multi-window example +// Copyright (c) Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as 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 GLAD_GL_IMPLEMENTATION +#include +#define GLFW_INCLUDE_NONE +#include + +#include +#include + +int main(int argc, char** argv) +{ + int xpos, ypos, height; + const char* description; + GLFWwindow* windows[4]; + + if (!glfwInit()) + { + glfwGetError(&description); + printf("Error: %s\n", description); + exit(EXIT_FAILURE); + } + + glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); + + glfwGetMonitorWorkarea(glfwGetPrimaryMonitor(), &xpos, &ypos, NULL, &height); + + for (int i = 0; i < 4; i++) + { + const int size = height / 5; + const struct + { + float r, g, b; + } colors[] = + { + { 0.95f, 0.32f, 0.11f }, + { 0.50f, 0.80f, 0.16f }, + { 0.f, 0.68f, 0.94f }, + { 0.98f, 0.74f, 0.04f } + }; + + if (i > 0) + glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_FALSE); + + glfwWindowHint(GLFW_POSITION_X, xpos + size * (1 + (i & 1))); + glfwWindowHint(GLFW_POSITION_Y, ypos + size * (1 + (i >> 1))); + + windows[i] = glfwCreateWindow(size, size, "Multi-Window Example", NULL, NULL); + if (!windows[i]) + { + glfwGetError(&description); + printf("Error: %s\n", description); + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetInputMode(windows[i], GLFW_STICKY_KEYS, GLFW_TRUE); + + glfwMakeContextCurrent(windows[i]); + gladLoadGL(glfwGetProcAddress); + glClearColor(colors[i].r, colors[i].g, colors[i].b, 1.f); + } + + for (;;) + { + for (int i = 0; i < 4; i++) + { + glfwMakeContextCurrent(windows[i]); + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(windows[i]); + + if (glfwWindowShouldClose(windows[i]) || + glfwGetKey(windows[i], GLFW_KEY_ESCAPE)) + { + glfwTerminate(); + exit(EXIT_SUCCESS); + } + } + + glfwWaitEvents(); + } +} + diff --git a/src/lib/src/vendor/glfw-3.3.8/include/GLFW/glfw3.h b/src/lib/src/vendor/glfw-3.4/include/GLFW/glfw3.h similarity index 86% rename from src/lib/src/vendor/glfw-3.3.8/include/GLFW/glfw3.h rename to src/lib/src/vendor/glfw-3.4/include/GLFW/glfw3.h index 31b201a..9c55ac9 100644 --- a/src/lib/src/vendor/glfw-3.3.8/include/GLFW/glfw3.h +++ b/src/lib/src/vendor/glfw-3.4/include/GLFW/glfw3.h @@ -1,5 +1,5 @@ /************************************************************************* - * GLFW 3.3 - www.glfw.org + * GLFW 3.4 - www.glfw.org * A library for OpenGL, window and input *------------------------------------------------------------------------ * Copyright (c) 2002-2006 Marcus Geelnard @@ -291,14 +291,14 @@ extern "C" { * features are added to the API but it remains backward-compatible. * @ingroup init */ -#define GLFW_VERSION_MINOR 3 +#define GLFW_VERSION_MINOR 4 /*! @brief The revision number of the GLFW header. * * The revision number of the GLFW header. This is incremented when a bug fix * release is made that does not contain any API changes. * @ingroup init */ -#define GLFW_VERSION_REVISION 8 +#define GLFW_VERSION_REVISION 0 /*! @} */ /*! @brief One. @@ -361,10 +361,15 @@ extern "C" { #define GLFW_HAT_RIGHT_DOWN (GLFW_HAT_RIGHT | GLFW_HAT_DOWN) #define GLFW_HAT_LEFT_UP (GLFW_HAT_LEFT | GLFW_HAT_UP) #define GLFW_HAT_LEFT_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN) + +/*! @ingroup input + */ +#define GLFW_KEY_UNKNOWN -1 + /*! @} */ -/*! @defgroup keys Keyboard keys - * @brief Keyboard key IDs. +/*! @defgroup keys Keyboard key tokens + * @brief Keyboard key tokens. * * See [key input](@ref input_key) for how these are used. * @@ -374,7 +379,7 @@ extern "C" { * * The naming of the key codes follow these rules: * - The US keyboard layout is used - * - Names of printable alpha-numeric characters are used (e.g. "A", "R", + * - Names of printable alphanumeric characters are used (e.g. "A", "R", * "3", etc.) * - For non-alphanumeric characters, Unicode:ish names are used (e.g. * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not @@ -387,9 +392,6 @@ extern "C" { * @{ */ -/* The unknown key */ -#define GLFW_KEY_UNKNOWN -1 - /* Printable keys */ #define GLFW_KEY_SPACE 32 #define GLFW_KEY_APOSTROPHE 39 /* ' */ @@ -719,7 +721,7 @@ extern "C" { * GLFW could not find support for the requested API on the system. * * @analysis The installed graphics driver does not support the requested - * API, or does not support it via the chosen context creation backend. + * API, or does not support it via the chosen context creation API. * Below are a few examples. * * @par @@ -785,6 +787,66 @@ extern "C" { * @analysis Application programmer error. Fix the offending call. */ #define GLFW_NO_WINDOW_CONTEXT 0x0001000A +/*! @brief The specified cursor shape is not available. + * + * The specified standard cursor shape is not available, either because the + * current platform cursor theme does not provide it or because it is not + * available on the platform. + * + * @analysis Platform or system settings limitation. Pick another + * [standard cursor shape](@ref shapes) or create a + * [custom cursor](@ref cursor_custom). + */ +#define GLFW_CURSOR_UNAVAILABLE 0x0001000B +/*! @brief The requested feature is not provided by the platform. + * + * The requested feature is not provided by the platform, so GLFW is unable to + * implement it. The documentation for each function notes if it could emit + * this error. + * + * @analysis Platform or platform version limitation. The error can be ignored + * unless the feature is critical to the application. + * + * @par + * A function call that emits this error has no effect other than the error and + * updating any existing out parameters. + */ +#define GLFW_FEATURE_UNAVAILABLE 0x0001000C +/*! @brief The requested feature is not implemented for the platform. + * + * The requested feature has not yet been implemented in GLFW for this platform. + * + * @analysis An incomplete implementation of GLFW for this platform, hopefully + * fixed in a future release. The error can be ignored unless the feature is + * critical to the application. + * + * @par + * A function call that emits this error has no effect other than the error and + * updating any existing out parameters. + */ +#define GLFW_FEATURE_UNIMPLEMENTED 0x0001000D +/*! @brief Platform unavailable or no matching platform was found. + * + * If emitted during initialization, no matching platform was found. If the @ref + * GLFW_PLATFORM init hint was set to `GLFW_ANY_PLATFORM`, GLFW could not detect any of + * the platforms supported by this library binary, except for the Null platform. If the + * init hint was set to a specific platform, it is either not supported by this library + * binary or GLFW was not able to detect it. + * + * If emitted by a native access function, GLFW was initialized for a different platform + * than the function is for. + * + * @analysis Failure to detect any platform usually only happens on non-macOS Unix + * systems, either when no window system is running or the program was run from + * a terminal that does not have the necessary environment variables. Fall back to + * a different platform if possible or notify the user that no usable platform was + * detected. + * + * Failure to detect a specific platform may have the same cause as above or be because + * support for that platform was not compiled in. Call @ref glfwPlatformSupported to + * check whether a specific platform is supported by a library binary. + */ +#define GLFW_PLATFORM_UNAVAILABLE 0x0001000E /*! @} */ /*! @addtogroup window @@ -860,6 +922,25 @@ extern "C" { */ #define GLFW_FOCUS_ON_SHOW 0x0002000C +/*! @brief Mouse input transparency window hint and attribute + * + * Mouse input transparency [window hint](@ref GLFW_MOUSE_PASSTHROUGH_hint) or + * [window attribute](@ref GLFW_MOUSE_PASSTHROUGH_attrib). + */ +#define GLFW_MOUSE_PASSTHROUGH 0x0002000D + +/*! @brief Initial position x-coordinate window hint. + * + * Initial position x-coordinate [window hint](@ref GLFW_POSITION_X). + */ +#define GLFW_POSITION_X 0x0002000E + +/*! @brief Initial position y-coordinate window hint. + * + * Initial position y-coordinate [window hint](@ref GLFW_POSITION_Y). + */ +#define GLFW_POSITION_Y 0x0002000F + /*! @brief Framebuffer bit depth hint. * * Framebuffer bit depth [hint](@ref GLFW_RED_BITS). @@ -935,9 +1016,10 @@ extern "C" { * Monitor refresh rate [hint](@ref GLFW_REFRESH_RATE). */ #define GLFW_REFRESH_RATE 0x0002100F -/*! @brief Framebuffer double buffering hint. +/*! @brief Framebuffer double buffering hint and attribute. * - * Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER). + * Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER_hint) and + * [attribute](@ref GLFW_DOUBLEBUFFER_attrib). */ #define GLFW_DOUBLEBUFFER 0x00021010 @@ -979,10 +1061,15 @@ extern "C" { #define GLFW_OPENGL_FORWARD_COMPAT 0x00022006 /*! @brief Debug mode context hint and attribute. * - * Debug mode context [hint](@ref GLFW_OPENGL_DEBUG_CONTEXT_hint) and - * [attribute](@ref GLFW_OPENGL_DEBUG_CONTEXT_attrib). + * Debug mode context [hint](@ref GLFW_CONTEXT_DEBUG_hint) and + * [attribute](@ref GLFW_CONTEXT_DEBUG_attrib). */ -#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007 +#define GLFW_CONTEXT_DEBUG 0x00022007 +/*! @brief Legacy name for compatibility. + * + * This is an alias for compatibility with earlier versions. + */ +#define GLFW_OPENGL_DEBUG_CONTEXT GLFW_CONTEXT_DEBUG /*! @brief OpenGL profile hint and attribute. * * OpenGL profile [hint](@ref GLFW_OPENGL_PROFILE_hint) and @@ -1011,8 +1098,15 @@ extern "C" { * [window hint](@ref GLFW_SCALE_TO_MONITOR). */ #define GLFW_SCALE_TO_MONITOR 0x0002200C -/*! @brief macOS specific - * [window hint](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint). +/*! @brief Window framebuffer scaling + * [window hint](@ref GLFW_SCALE_FRAMEBUFFER_hint). + */ +#define GLFW_SCALE_FRAMEBUFFER 0x0002200D +/*! @brief Legacy name for compatibility. + * + * This is an alias for the + * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) window hint for + * compatibility with earlier versions. */ #define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001 /*! @brief macOS specific @@ -1031,6 +1125,16 @@ extern "C" { * [window hint](@ref GLFW_X11_CLASS_NAME_hint). */ #define GLFW_X11_INSTANCE_NAME 0x00024002 +#define GLFW_WIN32_KEYBOARD_MENU 0x00025001 +/*! @brief Win32 specific [window hint](@ref GLFW_WIN32_SHOWDEFAULT_hint). + */ +#define GLFW_WIN32_SHOWDEFAULT 0x00025002 +/*! @brief Wayland specific + * [window hint](@ref GLFW_WAYLAND_APP_ID_hint). + * + * Allows specification of the Wayland app_id. + */ +#define GLFW_WAYLAND_APP_ID 0x00026001 /*! @} */ #define GLFW_NO_API 0 @@ -1054,6 +1158,7 @@ extern "C" { #define GLFW_CURSOR_NORMAL 0x00034001 #define GLFW_CURSOR_HIDDEN 0x00034002 #define GLFW_CURSOR_DISABLED 0x00034003 +#define GLFW_CURSOR_CAPTURED 0x00034004 #define GLFW_ANY_RELEASE_BEHAVIOR 0 #define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001 @@ -1063,17 +1168,31 @@ extern "C" { #define GLFW_EGL_CONTEXT_API 0x00036002 #define GLFW_OSMESA_CONTEXT_API 0x00036003 +#define GLFW_ANGLE_PLATFORM_TYPE_NONE 0x00037001 +#define GLFW_ANGLE_PLATFORM_TYPE_OPENGL 0x00037002 +#define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES 0x00037003 +#define GLFW_ANGLE_PLATFORM_TYPE_D3D9 0x00037004 +#define GLFW_ANGLE_PLATFORM_TYPE_D3D11 0x00037005 +#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007 +#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008 + +#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001 +#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002 + +#define GLFW_ANY_POSITION 0x80000000 + /*! @defgroup shapes Standard cursor shapes * @brief Standard system cursor shapes. * - * See [standard cursor creation](@ref cursor_standard) for how these are used. + * These are the [standard cursor shapes](@ref cursor_standard) that can be + * requested from the platform (window system). * * @ingroup input * @{ */ /*! @brief The regular arrow cursor shape. * - * The regular arrow cursor. + * The regular arrow cursor shape. */ #define GLFW_ARROW_CURSOR 0x00036001 /*! @brief The text input I-beam cursor shape. @@ -1081,26 +1200,91 @@ extern "C" { * The text input I-beam cursor shape. */ #define GLFW_IBEAM_CURSOR 0x00036002 -/*! @brief The crosshair shape. +/*! @brief The crosshair cursor shape. * - * The crosshair shape. + * The crosshair cursor shape. */ #define GLFW_CROSSHAIR_CURSOR 0x00036003 -/*! @brief The hand shape. +/*! @brief The pointing hand cursor shape. * - * The hand shape. + * The pointing hand cursor shape. */ -#define GLFW_HAND_CURSOR 0x00036004 -/*! @brief The horizontal resize arrow shape. +#define GLFW_POINTING_HAND_CURSOR 0x00036004 +/*! @brief The horizontal resize/move arrow shape. * - * The horizontal resize arrow shape. + * The horizontal resize/move arrow shape. This is usually a horizontal + * double-headed arrow. */ -#define GLFW_HRESIZE_CURSOR 0x00036005 -/*! @brief The vertical resize arrow shape. +#define GLFW_RESIZE_EW_CURSOR 0x00036005 +/*! @brief The vertical resize/move arrow shape. * - * The vertical resize arrow shape. + * The vertical resize/move shape. This is usually a vertical double-headed + * arrow. */ -#define GLFW_VRESIZE_CURSOR 0x00036006 +#define GLFW_RESIZE_NS_CURSOR 0x00036006 +/*! @brief The top-left to bottom-right diagonal resize/move arrow shape. + * + * The top-left to bottom-right diagonal resize/move shape. This is usually + * a diagonal double-headed arrow. + * + * @note @macos This shape is provided by a private system API and may fail + * with @ref GLFW_CURSOR_UNAVAILABLE in the future. + * + * @note @wayland This shape is provided by a newer standard not supported by + * all cursor themes. + * + * @note @x11 This shape is provided by a newer standard not supported by all + * cursor themes. + */ +#define GLFW_RESIZE_NWSE_CURSOR 0x00036007 +/*! @brief The top-right to bottom-left diagonal resize/move arrow shape. + * + * The top-right to bottom-left diagonal resize/move shape. This is usually + * a diagonal double-headed arrow. + * + * @note @macos This shape is provided by a private system API and may fail + * with @ref GLFW_CURSOR_UNAVAILABLE in the future. + * + * @note @wayland This shape is provided by a newer standard not supported by + * all cursor themes. + * + * @note @x11 This shape is provided by a newer standard not supported by all + * cursor themes. + */ +#define GLFW_RESIZE_NESW_CURSOR 0x00036008 +/*! @brief The omni-directional resize/move cursor shape. + * + * The omni-directional resize cursor/move shape. This is usually either + * a combined horizontal and vertical double-headed arrow or a grabbing hand. + */ +#define GLFW_RESIZE_ALL_CURSOR 0x00036009 +/*! @brief The operation-not-allowed shape. + * + * The operation-not-allowed shape. This is usually a circle with a diagonal + * line through it. + * + * @note @wayland This shape is provided by a newer standard not supported by + * all cursor themes. + * + * @note @x11 This shape is provided by a newer standard not supported by all + * cursor themes. + */ +#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A +/*! @brief Legacy name for compatibility. + * + * This is an alias for compatibility with earlier versions. + */ +#define GLFW_HRESIZE_CURSOR GLFW_RESIZE_EW_CURSOR +/*! @brief Legacy name for compatibility. + * + * This is an alias for compatibility with earlier versions. + */ +#define GLFW_VRESIZE_CURSOR GLFW_RESIZE_NS_CURSOR +/*! @brief Legacy name for compatibility. + * + * This is an alias for compatibility with earlier versions. + */ +#define GLFW_HAND_CURSOR GLFW_POINTING_HAND_CURSOR /*! @} */ #define GLFW_CONNECTED 0x00040001 @@ -1113,6 +1297,16 @@ extern "C" { * Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS). */ #define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001 +/*! @brief ANGLE rendering backend init hint. + * + * ANGLE rendering backend [init hint](@ref GLFW_ANGLE_PLATFORM_TYPE_hint). + */ +#define GLFW_ANGLE_PLATFORM_TYPE 0x00050002 +/*! @brief Platform selection init hint. + * + * Platform selection [init hint](@ref GLFW_PLATFORM). + */ +#define GLFW_PLATFORM 0x00050003 /*! @brief macOS specific init hint. * * macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint). @@ -1123,6 +1317,30 @@ extern "C" { * macOS specific [init hint](@ref GLFW_COCOA_MENUBAR_hint). */ #define GLFW_COCOA_MENUBAR 0x00051002 +/*! @brief X11 specific init hint. + * + * X11 specific [init hint](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint). + */ +#define GLFW_X11_XCB_VULKAN_SURFACE 0x00052001 +/*! @brief Wayland specific init hint. + * + * Wayland specific [init hint](@ref GLFW_WAYLAND_LIBDECOR_hint). + */ +#define GLFW_WAYLAND_LIBDECOR 0x00053001 +/*! @} */ + +/*! @addtogroup init + * @{ */ +/*! @brief Hint value that enables automatic platform selection. + * + * Hint value for @ref GLFW_PLATFORM that enables automatic platform selection. + */ +#define GLFW_ANY_PLATFORM 0x00060000 +#define GLFW_PLATFORM_WIN32 0x00060001 +#define GLFW_PLATFORM_COCOA 0x00060002 +#define GLFW_PLATFORM_WAYLAND 0x00060003 +#define GLFW_PLATFORM_X11 0x00060004 +#define GLFW_PLATFORM_NULL 0x00060005 /*! @} */ #define GLFW_DONT_CARE -1 @@ -1196,6 +1414,157 @@ typedef struct GLFWwindow GLFWwindow; */ typedef struct GLFWcursor GLFWcursor; +/*! @brief The function pointer type for memory allocation callbacks. + * + * This is the function pointer type for memory allocation callbacks. A memory + * allocation callback function has the following signature: + * @code + * void* function_name(size_t size, void* user) + * @endcode + * + * This function must return either a memory block at least `size` bytes long, + * or `NULL` if allocation failed. Note that not all parts of GLFW handle allocation + * failures gracefully yet. + * + * This function must support being called during @ref glfwInit but before the library is + * flagged as initialized, as well as during @ref glfwTerminate after the library is no + * longer flagged as initialized. + * + * Any memory allocated via this function will be deallocated via the same allocator + * during library termination or earlier. + * + * Any memory allocated via this function must be suitably aligned for any object type. + * If you are using C99 or earlier, this alignment is platform-dependent but will be the + * same as what `malloc` provides. If you are using C11 or later, this is the value of + * `alignof(max_align_t)`. + * + * The size will always be greater than zero. Allocations of size zero are filtered out + * before reaching the custom allocator. + * + * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY. + * + * This function must not call any GLFW function. + * + * @param[in] size The minimum size, in bytes, of the memory block. + * @param[in] user The user-defined pointer from the allocator. + * @return The address of the newly allocated memory block, or `NULL` if an + * error occurred. + * + * @pointer_lifetime The returned memory block must be valid at least until it + * is deallocated. + * + * @reentrancy This function should not call any GLFW function. + * + * @thread_safety This function must support being called from any thread that calls GLFW + * functions. + * + * @sa @ref init_allocator + * @sa @ref GLFWallocator + * + * @since Added in version 3.4. + * + * @ingroup init + */ +typedef void* (* GLFWallocatefun)(size_t size, void* user); + +/*! @brief The function pointer type for memory reallocation callbacks. + * + * This is the function pointer type for memory reallocation callbacks. + * A memory reallocation callback function has the following signature: + * @code + * void* function_name(void* block, size_t size, void* user) + * @endcode + * + * This function must return a memory block at least `size` bytes long, or + * `NULL` if allocation failed. Note that not all parts of GLFW handle allocation + * failures gracefully yet. + * + * This function must support being called during @ref glfwInit but before the library is + * flagged as initialized, as well as during @ref glfwTerminate after the library is no + * longer flagged as initialized. + * + * Any memory allocated via this function will be deallocated via the same allocator + * during library termination or earlier. + * + * Any memory allocated via this function must be suitably aligned for any object type. + * If you are using C99 or earlier, this alignment is platform-dependent but will be the + * same as what `realloc` provides. If you are using C11 or later, this is the value of + * `alignof(max_align_t)`. + * + * The block address will never be `NULL` and the size will always be greater than zero. + * Reallocations of a block to size zero are converted into deallocations before reaching + * the custom allocator. Reallocations of `NULL` to a non-zero size are converted into + * regular allocations before reaching the custom allocator. + * + * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY. + * + * This function must not call any GLFW function. + * + * @param[in] block The address of the memory block to reallocate. + * @param[in] size The new minimum size, in bytes, of the memory block. + * @param[in] user The user-defined pointer from the allocator. + * @return The address of the newly allocated or resized memory block, or + * `NULL` if an error occurred. + * + * @pointer_lifetime The returned memory block must be valid at least until it + * is deallocated. + * + * @reentrancy This function should not call any GLFW function. + * + * @thread_safety This function must support being called from any thread that calls GLFW + * functions. + * + * @sa @ref init_allocator + * @sa @ref GLFWallocator + * + * @since Added in version 3.4. + * + * @ingroup init + */ +typedef void* (* GLFWreallocatefun)(void* block, size_t size, void* user); + +/*! @brief The function pointer type for memory deallocation callbacks. + * + * This is the function pointer type for memory deallocation callbacks. + * A memory deallocation callback function has the following signature: + * @code + * void function_name(void* block, void* user) + * @endcode + * + * This function may deallocate the specified memory block. This memory block + * will have been allocated with the same allocator. + * + * This function must support being called during @ref glfwInit but before the library is + * flagged as initialized, as well as during @ref glfwTerminate after the library is no + * longer flagged as initialized. + * + * The block address will never be `NULL`. Deallocations of `NULL` are filtered out + * before reaching the custom allocator. + * + * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY. + * + * This function must not call any GLFW function. + * + * @param[in] block The address of the memory block to deallocate. + * @param[in] user The user-defined pointer from the allocator. + * + * @pointer_lifetime The specified memory block will not be accessed by GLFW + * after this function is called. + * + * @reentrancy This function should not call any GLFW function. + * + * @thread_safety This function must support being called from any thread that calls GLFW + * functions. + * + * @sa @ref init_allocator + * @sa @ref GLFWallocator + * + * @since Added in version 3.4. + * + * @ingroup init + */ +typedef void (* GLFWdeallocatefun)(void* block, void* user); + /*! @brief The function pointer type for error callbacks. * * This is the function pointer type for error callbacks. An error callback @@ -1511,7 +1880,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffse * * @param[in] window The window that received the event. * @param[in] key The [keyboard key](@ref keys) that was pressed or released. - * @param[in] scancode The system-specific scancode of the key. + * @param[in] scancode The platform-specific scancode of the key. * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`. Future * releases may add more actions. * @param[in] mods Bit field describing which [modifier keys](@ref mods) were @@ -1753,6 +2122,38 @@ typedef struct GLFWgamepadstate float axes[6]; } GLFWgamepadstate; +/*! @brief Custom heap memory allocator. + * + * This describes a custom heap memory allocator for GLFW. To set an allocator, pass it + * to @ref glfwInitAllocator before initializing the library. + * + * @sa @ref init_allocator + * @sa @ref glfwInitAllocator + * + * @since Added in version 3.4. + * + * @ingroup init + */ +typedef struct GLFWallocator +{ + /*! The memory allocation function. See @ref GLFWallocatefun for details about + * allocation function. + */ + GLFWallocatefun allocate; + /*! The memory reallocation function. See @ref GLFWreallocatefun for details about + * reallocation function. + */ + GLFWreallocatefun reallocate; + /*! The memory deallocation function. See @ref GLFWdeallocatefun for details about + * deallocation function. + */ + GLFWdeallocatefun deallocate; + /*! The user pointer for this custom allocator. This value will be passed to the + * allocator functions. + */ + void* user; +} GLFWallocator; + /************************************************************************* * GLFW API functions @@ -1771,16 +2172,36 @@ typedef struct GLFWgamepadstate * Additional calls to this function after successful initialization but before * termination will return `GLFW_TRUE` immediately. * + * The @ref GLFW_PLATFORM init hint controls which platforms are considered during + * initialization. This also depends on which platforms the library was compiled to + * support. + * * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_PLATFORM_UNAVAILABLE and @ref + * GLFW_PLATFORM_ERROR. * * @remark @macos This function will change the current directory of the * application to the `Contents/Resources` subdirectory of the application's * bundle, if present. This can be disabled with the @ref * GLFW_COCOA_CHDIR_RESOURCES init hint. * + * @remark @macos This function will create the main menu and dock icon for the + * application. If GLFW finds a `MainMenu.nib` it is loaded and assumed to + * contain a menu bar. Otherwise a minimal menu bar is created manually with + * common commands like Hide, Quit and About. The About entry opens a minimal + * about dialog with information from the application's bundle. The menu bar + * and dock icon can be disabled entirely with the @ref GLFW_COCOA_MENUBAR init + * hint. + * + * @remark __Wayland, X11:__ If the library was compiled with support for both + * Wayland and X11, and the @ref GLFW_PLATFORM init hint is set to + * `GLFW_ANY_PLATFORM`, the `XDG_SESSION_TYPE` environment variable affects + * which platform is picked. If the environment variable is not set, or is set + * to something other than `wayland` or `x11`, the regular detection mechanism + * will be used instead. + * * @remark @x11 This function will set the `LC_CTYPE` category of the * application locale according to the current environment if that category is * still "C". This is because the "C" locale breaks Unicode text input. @@ -1788,6 +2209,8 @@ typedef struct GLFWgamepadstate * @thread_safety This function must only be called from the main thread. * * @sa @ref intro_init + * @sa @ref glfwInitHint + * @sa @ref glfwInitAllocator * @sa @ref glfwTerminate * * @since Added in version 1.0. @@ -1862,6 +2285,85 @@ GLFWAPI void glfwTerminate(void); */ GLFWAPI void glfwInitHint(int hint, int value); +/*! @brief Sets the init allocator to the desired value. + * + * To use the default allocator, call this function with a `NULL` argument. + * + * If you specify an allocator struct, every member must be a valid function + * pointer. If any member is `NULL`, this function will emit @ref + * GLFW_INVALID_VALUE and the init allocator will be unchanged. + * + * The functions in the allocator must fulfil a number of requirements. See the + * documentation for @ref GLFWallocatefun, @ref GLFWreallocatefun and @ref + * GLFWdeallocatefun for details. + * + * @param[in] allocator The allocator to use at the next initialization, or + * `NULL` to use the default one. + * + * @errors Possible errors include @ref GLFW_INVALID_VALUE. + * + * @pointer_lifetime The specified allocator is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref init_allocator + * @sa @ref glfwInit + * + * @since Added in version 3.4. + * + * @ingroup init + */ +GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator); + +#if defined(VK_VERSION_1_0) + +/*! @brief Sets the desired Vulkan `vkGetInstanceProcAddr` function. + * + * This function sets the `vkGetInstanceProcAddr` function that GLFW will use for all + * Vulkan related entry point queries. + * + * This feature is mostly useful on macOS, if your copy of the Vulkan loader is in + * a location where GLFW cannot find it through dynamic loading, or if you are still + * using the static library version of the loader. + * + * If set to `NULL`, GLFW will try to load the Vulkan loader dynamically by its standard + * name and get this function from there. This is the default behavior. + * + * The standard name of the loader is `vulkan-1.dll` on Windows, `libvulkan.so.1` on + * Linux and other Unix-like systems and `libvulkan.1.dylib` on macOS. If your code is + * also loading it via these names then you probably don't need to use this function. + * + * The function address you set is never reset by GLFW, but it only takes effect during + * initialization. Once GLFW has been initialized, any updates will be ignored until the + * library is terminated and initialized again. + * + * @param[in] loader The address of the function to use, or `NULL`. + * + * @par Loader function signature + * @code + * PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance instance, const char* name) + * @endcode + * For more information about this function, see the + * [Vulkan Registry](https://www.khronos.org/registry/vulkan/). + * + * @errors None. + * + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref vulkan_loader + * @sa @ref glfwInit + * + * @since Added in version 3.4. + * + * @ingroup init + */ +GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader); + +#endif /*VK_VERSION_1_0*/ + /*! @brief Retrieves the version of the GLFW library. * * This function retrieves the major, minor and revision numbers of the GLFW @@ -1892,15 +2394,18 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); /*! @brief Returns a string describing the compile-time configuration. * * This function returns the compile-time generated - * [version string](@ref intro_version_string) of the GLFW library binary. It - * describes the version, platform, compiler and any platform-specific - * compile-time options. It should not be confused with the OpenGL or OpenGL - * ES version string, queried with `glGetString`. + * [version string](@ref intro_version_string) of the GLFW library binary. It describes + * the version, platforms, compiler and any platform or operating system specific + * compile-time options. It should not be confused with the OpenGL or OpenGL ES version + * string, queried with `glGetString`. * * __Do not use the version string__ to parse the GLFW library version. The * @ref glfwGetVersion function provides the version of the running library * binary in numerical format. * + * __Do not use the version string__ to parse what platforms are supported. The @ref + * glfwPlatformSupported function lets you query platform support. + * * @return The ASCII encoded GLFW version string. * * @errors None. @@ -1997,6 +2502,51 @@ GLFWAPI int glfwGetError(const char** description); */ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun callback); +/*! @brief Returns the currently selected platform. + * + * This function returns the platform that was selected during initialization. The + * returned value will be one of `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`, + * `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` or `GLFW_PLATFORM_NULL`. + * + * @return The currently selected platform, or zero if an error occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref platform + * @sa @ref glfwPlatformSupported + * + * @since Added in version 3.4. + * + * @ingroup init + */ +GLFWAPI int glfwGetPlatform(void); + +/*! @brief Returns whether the library includes support for the specified platform. + * + * This function returns whether the library was compiled with support for the specified + * platform. The platform must be one of `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`, + * `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` or `GLFW_PLATFORM_NULL`. + * + * @param[in] platform The platform to query. + * @return `GLFW_TRUE` if the platform is supported, or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_INVALID_ENUM. + * + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref platform + * @sa @ref glfwGetPlatform + * + * @since Added in version 3.4. + * + * @ingroup init + */ +GLFWAPI int glfwPlatformSupported(int platform); + /*! @brief Returns the currently connected monitors. * * This function returns an array of handles for all currently connected @@ -2080,7 +2630,7 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); * This function returns the position, in screen coordinates, of the upper-left * corner of the work area of the specified monitor along with the work area * size in screen coordinates. The work area is defined as the area of the - * monitor not occluded by the operating system task bar where present. If no + * monitor not occluded by the window system task bar where present. If no * task bar exists then the work area is the monitor resolution in screen * coordinates. * @@ -2111,10 +2661,11 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos, * This function returns the size, in millimetres, of the display area of the * specified monitor. * - * Some systems do not provide accurate monitor size information, either - * because the monitor - * [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data) - * data is incorrect or because the driver does not report it accurately. + * Some platforms do not provide accurate monitor size information, either + * because the monitor [EDID][] data is incorrect or because the driver does + * not report it accurately. + * + * [EDID]: https://en.wikipedia.org/wiki/Extended_display_identification_data * * Any or all of the size arguments may be `NULL`. If an error occurs, all * non-`NULL` size arguments will be set to zero. @@ -2161,6 +2712,9 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * + * @remark @wayland Fractional scaling information is not yet available for + * monitors, so this function only returns integer content scales. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_scale @@ -2357,11 +2911,11 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] gamma The desired exponent. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE, + * @ref GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark @wayland Gamma handling is a privileged protocol, this function - * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR. + * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE. * * @thread_safety This function must only be called from the main thread. * @@ -2381,11 +2935,11 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); * @return The current gamma ramp, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR + * and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark @wayland Gamma handling is a privileged protocol, this function - * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR while + * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while * returning `NULL`. * * @pointer_lifetime The returned structure and its arrays are allocated and @@ -2420,8 +2974,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] ramp The gamma ramp to use. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR + * and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark The size of the specified gamma ramp should match the size of the * current ramp for that monitor. @@ -2429,7 +2983,7 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); * @remark @win32 The gamma ramp size must be 256. * * @remark @wayland Gamma handling is a privileged protocol, this function - * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR. + * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE. * * @pointer_lifetime The specified gamma ramp is copied before this function * returns. @@ -2572,10 +3126,10 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value); * OpenGL or OpenGL ES context. * * By default, newly created windows use the placement recommended by the - * window system. To create the window at a specific position, make it - * initially invisible using the [GLFW_VISIBLE](@ref GLFW_VISIBLE_hint) window - * hint, set its [position](@ref window_pos) and then [show](@ref window_hide) - * it. + * window system. To create the window at a specific position, set the @ref + * GLFW_POSITION_X and @ref GLFW_POSITION_Y window hints before creation. To + * restore the default behavior, set either or both hints back to + * `GLFW_ANY_POSITION`. * * As long as at least one full screen window is not iconified, the screensaver * is prohibited from starting. @@ -2601,8 +3155,8 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value); * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref - * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref - * GLFW_PLATFORM_ERROR. + * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. * * @remark @win32 Window creation will fail if the Microsoft GDI software * OpenGL implementation is the only one available. @@ -2615,40 +3169,44 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value); * @remark @win32 The context to share resources with must not be current on * any other thread. * - * @remark @macos The OS only supports forward-compatible core profile contexts - * for OpenGL versions 3.2 and later. Before creating an OpenGL context of - * version 3.2 or later you must set the - * [GLFW_OPENGL_FORWARD_COMPAT](@ref GLFW_OPENGL_FORWARD_COMPAT_hint) and - * [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) hints accordingly. - * OpenGL 3.0 and 3.1 contexts are not supported at all on macOS. + * @remark @macos The OS only supports core profile contexts for OpenGL + * versions 3.2 and later. Before creating an OpenGL context of version 3.2 or + * later you must set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) + * hint accordingly. OpenGL 3.0 and 3.1 contexts are not supported at all + * on macOS. * * @remark @macos The GLFW window has no icon, as it is not a document * window, but the dock icon will be the same as the application bundle's icon. * For more information on bundles, see the - * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) - * in the Mac Developer Library. + * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library. * - * @remark @macos The first time a window is created the menu bar is created. - * If GLFW finds a `MainMenu.nib` it is loaded and assumed to contain a menu - * bar. Otherwise a minimal menu bar is created manually with common commands - * like Hide, Quit and About. The About entry opens a minimal about dialog - * with information from the application's bundle. Menu bar creation can be - * disabled entirely with the @ref GLFW_COCOA_MENUBAR init hint. + * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/ * * @remark @macos On OS X 10.10 and later the window frame will not be rendered * at full resolution on Retina displays unless the - * [GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint) + * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) * hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the * application bundle's `Info.plist`. For more information, see - * [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html) - * in the Mac Developer Library. The GLFW test and example programs use - * a custom `Info.plist` template for this, which can be found as - * `CMake/MacOSXBundleInfo.plist.in` in the source tree. + * [High Resolution Guidelines for OS X][hidpi-guide] in the Mac Developer + * Library. The GLFW test and example programs use a custom `Info.plist` + * template for this, which can be found as `CMake/Info.plist.in` in the source + * tree. + * + * [hidpi-guide]: https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html * * @remark @macos When activating frame autosaving with * [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified * window size and position may be overridden by previously saved values. * + * @remark @wayland GLFW uses [libdecor][] where available to create its window + * decorations. This in turn uses server-side XDG decorations where available + * and provides high quality client-side decorations on compositors like GNOME. + * If both XDG decorations and libdecor are unavailable, GLFW falls back to + * a very simple set of window decorations that only support moving, resizing + * and the window manager's right-click menu. + * + * [libdecor]: https://gitlab.freedesktop.org/libdecor/libdecor + * * @remark @x11 Some window managers will not respect the placement of * initially hidden windows. * @@ -2665,20 +3223,6 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value); * [GLFW_X11_INSTANCE_NAME](@ref GLFW_X11_INSTANCE_NAME_hint) window hints to * override this. * - * @remark @wayland Compositors should implement the xdg-decoration protocol - * for GLFW to decorate the window properly. If this protocol isn't - * supported, or if the compositor prefers client-side decorations, a very - * simple fallback frame will be drawn using the wp_viewporter protocol. A - * compositor can still emit close, maximize or fullscreen events, using for - * instance a keybind mechanism. If neither of these protocols is supported, - * the window won't be decorated. - * - * @remark @wayland A full screen window will not attempt to change the mode, - * no matter what the requested size or refresh rate. - * - * @remark @wayland Screensaver inhibition requires the idle-inhibit protocol - * to be implemented in the user's compositor. - * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_creation @@ -2761,6 +3305,38 @@ GLFWAPI int glfwWindowShouldClose(GLFWwindow* window); */ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); +/*! @brief Returns the title of the specified window. + * + * This function returns the window title, encoded as UTF-8, of the specified + * window. This is the title set previously by @ref glfwCreateWindow + * or @ref glfwSetWindowTitle. + * + * @param[in] window The window to query. + * @return The UTF-8 encoded window title, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark The returned title is currently a copy of the title last set by @ref + * glfwCreateWindow or @ref glfwSetWindowTitle. It does not include any + * additional text which may be appended by the platform or another program. + * + * @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 + * glfwGetWindowTitle or @ref glfwSetWindowTitle, or until the library is + * terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_title + * @sa @ref glfwSetWindowTitle + * + * @since Added in version 3.4. + * + * @ingroup window + */ +GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window); + /*! @brief Sets the title of the specified window. * * This function sets the window title, encoded as UTF-8, of the specified @@ -2778,6 +3354,7 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); * @thread_safety This function must only be called from the main thread. * * @sa @ref window_title + * @sa @ref glfwGetWindowTitle * * @since Added in version 1.0. * @glfw3 Added window handle parameter. @@ -2808,20 +3385,22 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); * count is zero. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR and @ref + * GLFW_FEATURE_UNAVAILABLE (see remarks). * * @pointer_lifetime The specified image data is copied before this function * returns. * - * @remark @macos The GLFW window has no icon, as it is not a document - * window, so this function does nothing. The dock icon will be the same as + * @remark @macos Regular windows do not have icons on macOS. This function + * will emit @ref GLFW_FEATURE_UNAVAILABLE. The dock icon will be the same as * the application bundle's icon. For more information on bundles, see the - * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) - * in the Mac Developer Library. + * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library. + * + * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/ * * @remark @wayland There is no existing protocol to change an icon, the * window will thus inherit the one defined in the application's desktop file. - * This function always emits @ref GLFW_PLATFORM_ERROR. + * This function will emit @ref GLFW_FEATURE_UNAVAILABLE. * * @thread_safety This function must only be called from the main thread. * @@ -2847,12 +3426,12 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* i * @param[out] ypos Where to store the y-coordinate of the upper-left corner of * the content area, or `NULL`. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark @wayland There is no way for an application to retrieve the global - * position of its windows, this function will always emit @ref - * GLFW_PLATFORM_ERROR. + * position of its windows. This function will emit @ref + * GLFW_FEATURE_UNAVAILABLE. * * @thread_safety This function must only be called from the main thread. * @@ -2881,12 +3460,12 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); * @param[in] xpos The x-coordinate of the upper-left corner of the content area. * @param[in] ypos The y-coordinate of the upper-left corner of the content area. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark @wayland There is no way for an application to set the global - * position of its windows, this function will always emit @ref - * GLFW_PLATFORM_ERROR. + * position of its windows. This function will emit @ref + * GLFW_FEATURE_UNAVAILABLE. * * @thread_safety This function must only be called from the main thread. * @@ -3041,9 +3620,6 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark @wayland A full screen window will not attempt to change the mode, - * no matter what the requested size. - * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size @@ -3133,7 +3709,7 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int * regardless of their DPI and scaling settings. This relies on the system DPI * and scaling settings being somewhat correct. * - * On systems where each monitors can have its own content scale, the window + * On platforms where each monitors can have its own content scale, the window * content scale will depend on which monitor the system considers the window * to be on. * @@ -3198,8 +3774,11 @@ GLFWAPI float glfwGetWindowOpacity(GLFWwindow* window); * @param[in] window The window to set the opacity for. * @param[in] opacity The desired opacity of the specified window. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). + * + * @remark @wayland There is no way to set an opacity factor for a window. + * This function will emit @ref GLFW_FEATURE_UNAVAILABLE. * * @thread_safety This function must only be called from the main thread. * @@ -3227,6 +3806,10 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * + * @remark @wayland Once a window is iconified, @ref glfwRestoreWindow won’t + * be able to restore it. This is a design decision of the xdg-shell + * protocol. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify @@ -3371,8 +3954,8 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark @wayland It is not possible for an application to bring its windows - * to front, this function will always emit @ref GLFW_PLATFORM_ERROR. + * @remark @wayland The compositor will likely ignore focus requests unless + * another window created by the same application already has input focus. * * @thread_safety This function must only be called from the main thread. * @@ -3477,9 +4060,6 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); * @remark @wayland The desired window position is ignored, as there is no way * for an application to set this property. * - * @remark @wayland Setting the window to full screen will not attempt to - * change the mode, no matter what the requested size or refresh rate. - * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_monitor @@ -3539,6 +4119,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); * [GLFW_FLOATING](@ref GLFW_FLOATING_attrib), * [GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) and * [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_attrib). + * [GLFW_MOUSE_PASSTHROUGH](@ref GLFW_MOUSE_PASSTHROUGH_attrib) * * Some of these attributes are ignored for full screen windows. The new * value will take effect if the window is later made windowed. @@ -3551,11 +4132,15 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); * @param[in] value `GLFW_TRUE` or `GLFW_FALSE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR and @ref + * GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark Calling @ref glfwGetWindowAttrib will always return the latest * value, even if that value is ignored by the current mode of the window. * + * @remark @wayland The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is + * not supported. Setting this will emit @ref GLFW_FEATURE_UNAVAILABLE. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_attribs @@ -3809,9 +4394,6 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @remark @wayland The XDG-shell protocol has no event for iconification, so - * this callback will never be called. - * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify @@ -4105,6 +4687,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual * and unlimited cursor movement. This is useful for implementing for * example 3D camera controls. + * - `GLFW_CURSOR_CAPTURED` makes the cursor visible and confines it to the + * content area of the window. * * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to * enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are @@ -4130,7 +4714,7 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * If the mode is `GLFW_RAW_MOUSE_MOTION`, the value must be either `GLFW_TRUE` * to enable raw (unscaled and unaccelerated) mouse motion when the cursor is * disabled, or `GLFW_FALSE` to disable it. If raw motion is not supported, - * attempting to set this will emit @ref GLFW_PLATFORM_ERROR. Call @ref + * attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE. Call @ref * glfwRawMouseMotionSupported to check for support. * * @param[in] window The window whose input mode to set. @@ -4140,7 +4724,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * @param[in] value The new value of the specified input mode. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * GLFW_INVALID_ENUM, @ref GLFW_PLATFORM_ERROR and @ref + * GLFW_FEATURE_UNAVAILABLE (see above). * * @thread_safety This function must only be called from the main thread. * @@ -4230,8 +4815,8 @@ GLFWAPI int glfwRawMouseMotionSupported(void); * @param[in] scancode The scancode of the key to query. * @return The UTF-8 encoded, layout-specific name of the key, or `NULL`. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE, @ref GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @remark The contents of the returned string may change when a keyboard * layout change event is received. @@ -4253,15 +4838,18 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode); * * This function returns the platform-specific scancode of the specified key. * - * If the key is `GLFW_KEY_UNKNOWN` or does not exist on the keyboard this - * method will return `-1`. + * If the specified [key token](@ref keys) corresponds to a physical key not + * supported on the current platform then this method will return `-1`. + * Calling this function with anything other than a key token will return `-1` + * and generate a @ref GLFW_INVALID_ENUM error. * - * @param[in] key Any [named key](@ref keys). - * @return The platform-specific scancode for the key, or `-1` if an - * [error](@ref error_handling) occurred. + * @param[in] key Any [key token](@ref keys). + * @return The platform-specific scancode for the key, or `-1` if the key is + * not supported on the current platform or an [error](@ref error_handling) + * occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. * * @thread_safety This function may be called from any thread. * @@ -4402,11 +4990,11 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); * @param[in] ypos The desired y-coordinate, relative to the top edge of the * content area. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark @wayland This function will only work when the cursor mode is - * `GLFW_CURSOR_DISABLED`, otherwise it will do nothing. + * `GLFW_CURSOR_DISABLED`, otherwise it will emit @ref GLFW_FEATURE_UNAVAILABLE. * * @thread_safety This function must only be called from the main thread. * @@ -4459,19 +5047,44 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) /*! @brief Creates a cursor with a standard shape. * - * Returns a cursor with a [standard shape](@ref shapes), that can be set for - * a window with @ref glfwSetCursor. + * Returns a cursor with a standard shape, that can be set for a window with + * @ref glfwSetCursor. The images for these cursors come from the system + * cursor theme and their exact appearance will vary between platforms. + * + * Most of these shapes are guaranteed to exist on every supported platform but + * a few may not be present. See the table below for details. + * + * Cursor shape | Windows | macOS | X11 | Wayland + * ------------------------------ | ------- | ----- | ------ | ------- + * @ref GLFW_ARROW_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_IBEAM_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_CROSSHAIR_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_POINTING_HAND_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_RESIZE_EW_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_RESIZE_NS_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_RESIZE_NWSE_CURSOR | Yes | Yes1 | Maybe2 | Maybe2 + * @ref GLFW_RESIZE_NESW_CURSOR | Yes | Yes1 | Maybe2 | Maybe2 + * @ref GLFW_RESIZE_ALL_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_NOT_ALLOWED_CURSOR | Yes | Yes | Maybe2 | Maybe2 + * + * 1) This uses a private system API and may fail in the future. + * + * 2) This uses a newer standard that not all cursor themes support. + * + * If the requested shape is not available, this function emits a @ref + * GLFW_CURSOR_UNAVAILABLE error and returns `NULL`. * * @param[in] shape One of the [standard shapes](@ref shapes). * @return A new cursor ready to use or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * GLFW_INVALID_ENUM, @ref GLFW_CURSOR_UNAVAILABLE and @ref + * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * - * @sa @ref cursor_object + * @sa @ref cursor_standard * @sa @ref glfwCreateCursor * * @since Added in version 3.1. @@ -4545,9 +5158,9 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); * [character callback](@ref glfwSetCharCallback) instead. * * When a window loses input focus, it will generate synthetic key release - * events for all pressed keys. You can tell these events from user-generated - * events by the fact that the synthetic ones are generated after the focus - * loss event has been processed, i.e. after the + * events for all pressed keys with associated key tokens. You can tell these + * events from user-generated events by the fact that the synthetic ones are + * generated after the focus loss event has been processed, i.e. after the * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. * * The scancode of a key is specific to that platform or sometimes even to that @@ -4828,8 +5441,6 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun ca * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @remark @wayland File drop is currently unimplemented. - * * @thread_safety This function must only be called from the main thread. * * @sa @ref path_drop @@ -5296,6 +5907,11 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * + * @remark @win32 The clipboard on Windows has a single global lock for reading and + * writing. GLFW tries to acquire it a few times, which is almost always enough. If it + * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns. + * It is safe to try this multiple times. + * * @pointer_lifetime The specified string is copied before this function * returns. * @@ -5324,6 +5940,11 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * + * @remark @win32 The clipboard on Windows has a single global lock for reading and + * writing. GLFW tries to acquire it a few times, which is almost always enough. If it + * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns. + * It is safe to try this multiple times. + * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the next call to @ref * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library @@ -5351,7 +5972,7 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); * * The resolution of the timer is system dependent, but is usually on the order * of a few micro- or nanoseconds. It uses the highest-resolution monotonic - * time source on each supported platform. + * time source on each operating system. * * @return The current time, in seconds, or zero if an * [error](@ref error_handling) occurred. @@ -5446,12 +6067,15 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void); * thread. * * This function makes the OpenGL or OpenGL ES context of the specified window - * current on the calling thread. A context must only be made current on - * a single thread at a time and each thread can have only a single current - * context at a time. + * current on the calling thread. It can also detach the current context from + * the calling thread without making a new one current by passing in `NULL`. * - * When moving a context between threads, you must make it non-current on the - * old thread before making it current on the new one. + * A context must only be made current on a single thread at a time and each + * thread can have only a single current context at a time. Making a context + * current detaches any previously current context on the calling thread. + * + * When moving a context between threads, you must detach it (make it + * non-current) on the old thread before making it current on the new one. * * By default, making a context non-current implicitly forces a pipeline flush. * On machines that support `GL_KHR_context_flush_control`, you can control @@ -5466,6 +6090,10 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void); * @param[in] window The window whose context to make current, or `NULL` to * detach the current context. * + * @remarks If the previously current context was created via a different + * context creation API than the one passed to this function, GLFW will still + * detach the previous one from its API before making the new one current. + * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. * @@ -5562,7 +6190,7 @@ GLFWAPI void glfwSwapBuffers(GLFWwindow* window); * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. * * @remark This function is not called during context creation, leaving the - * swap interval set to whatever is the default on that platform. This is done + * swap interval set to whatever is the default for that API. This is done * because some swap interval extensions used by GLFW do not allow the swap * interval to be reset to zero once it has been set to a non-zero value. * @@ -5862,6 +6490,13 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys * @remark @macos This function creates and sets a `CAMetalLayer` instance for * the window content view, which is required for MoltenVK to function. * + * @remark @x11 By default GLFW prefers the `VK_KHR_xcb_surface` extension, + * with the `VK_KHR_xlib_surface` extension as a fallback. You can make + * `VK_KHR_xlib_surface` the preferred extension by setting the + * [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init + * hint. The name of the selected extension, if any, is included in the array + * returned by @ref glfwGetRequiredInstanceExtensions. + * * @thread_safety This function may be called from any thread. For * synchronization details of Vulkan objects, see the Vulkan specification. * diff --git a/src/lib/src/vendor/glfw-3.3.8/include/GLFW/glfw3native.h b/src/lib/src/vendor/glfw-3.4/include/GLFW/glfw3native.h similarity index 85% rename from src/lib/src/vendor/glfw-3.3.8/include/GLFW/glfw3native.h rename to src/lib/src/vendor/glfw-3.4/include/GLFW/glfw3native.h index 7be0227..92f0d32 100644 --- a/src/lib/src/vendor/glfw-3.3.8/include/GLFW/glfw3native.h +++ b/src/lib/src/vendor/glfw-3.4/include/GLFW/glfw3native.h @@ -1,5 +1,5 @@ /************************************************************************* - * GLFW 3.3 - www.glfw.org + * GLFW 3.4 - www.glfw.org * A library for OpenGL, window and input *------------------------------------------------------------------------ * Copyright (c) 2002-2006 Marcus Geelnard @@ -103,17 +103,23 @@ extern "C" { #undef GLFW_APIENTRY_DEFINED #endif #include - #elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL) + #endif + + #if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL) #if defined(__OBJC__) #import #else #include #include #endif - #elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) + #endif + + #if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) #include #include - #elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) + #endif + + #if defined(GLFW_EXPOSE_NATIVE_WAYLAND) #include #endif @@ -163,7 +169,8 @@ extern "C" { * of the specified monitor, or `NULL` if an [error](@ref error_handling) * occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @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. @@ -180,7 +187,8 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor); * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @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. @@ -196,7 +204,8 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor); * @return The `HWND` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @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) @@ -222,8 +231,8 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); * @return The `HGLRC` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @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) @@ -249,7 +258,8 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window); * @return The `CGDirectDisplayID` of the specified monitor, or * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @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. @@ -265,7 +275,8 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); * @return The `NSWindow` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @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. @@ -275,6 +286,23 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); * @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) @@ -283,8 +311,8 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); * @return The `NSOpenGLContext` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @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. @@ -302,7 +330,8 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); * @return The `Display` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @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. @@ -318,7 +347,8 @@ GLFWAPI Display* glfwGetX11Display(void); * @return The `RRCrtc` of the specified monitor, or `None` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @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. @@ -334,7 +364,8 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* 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. + * @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. @@ -350,7 +381,8 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor); * @return The `Window` of the specified window, or `None` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * @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. @@ -365,8 +397,8 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* window); * * @param[in] string A UTF-8 encoded string. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @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. @@ -391,8 +423,8 @@ GLFWAPI void glfwSetX11SelectionString(const char* string); * @return The contents of the selection as a UTF-8 encoded string, or `NULL` * if an [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @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 @@ -418,8 +450,8 @@ GLFWAPI const char* glfwGetX11SelectionString(void); * @return The `GLXContext` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @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. @@ -435,8 +467,8 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); * @return The `GLXWindow` of the specified window, or `None` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @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. @@ -454,7 +486,8 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); * @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. + * @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. @@ -470,7 +503,8 @@ GLFWAPI struct wl_display* glfwGetWaylandDisplay(void); * @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. + * @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. @@ -486,7 +520,8 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); * @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. + * @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. @@ -523,8 +558,8 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void); * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @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. @@ -540,8 +575,8 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window); * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @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. @@ -566,8 +601,8 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window); * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @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. @@ -590,8 +625,8 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @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. @@ -607,8 +642,8 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height * @return The `OSMesaContext` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref - * GLFW_NOT_INITIALIZED. + * @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. diff --git a/src/lib/src/vendor/glfw-3.4/src/CMakeLists.txt b/src/lib/src/vendor/glfw-3.4/src/CMakeLists.txt new file mode 100644 index 0000000..1057a6f --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/CMakeLists.txt @@ -0,0 +1,368 @@ + +add_library(glfw ${GLFW_LIBRARY_TYPE} + "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" + "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h" + internal.h platform.h mappings.h + context.c init.c input.c monitor.c platform.c vulkan.c window.c + egl_context.c osmesa_context.c null_platform.h null_joystick.h + null_init.c null_monitor.c null_window.c null_joystick.c) + +# The time, thread and module code is shared between all backends on a given OS, +# including the null backend, which still needs those bits to be functional +if (APPLE) + target_sources(glfw PRIVATE cocoa_time.h cocoa_time.c posix_thread.h + posix_module.c posix_thread.c) +elseif (WIN32) + target_sources(glfw PRIVATE win32_time.h win32_thread.h win32_module.c + win32_time.c win32_thread.c) +else() + target_sources(glfw PRIVATE posix_time.h posix_thread.h posix_module.c + posix_time.c posix_thread.c) +endif() + +add_custom_target(update_mappings + COMMAND "${CMAKE_COMMAND}" -P "${GLFW_SOURCE_DIR}/CMake/GenerateMappings.cmake" mappings.h.in mappings.h + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Updating gamepad mappings from upstream repository" + SOURCES mappings.h.in "${GLFW_SOURCE_DIR}/CMake/GenerateMappings.cmake" + VERBATIM) + +set_target_properties(update_mappings PROPERTIES FOLDER "GLFW3") + +if (GLFW_BUILD_COCOA) + target_compile_definitions(glfw PRIVATE _GLFW_COCOA) + target_sources(glfw PRIVATE cocoa_platform.h cocoa_joystick.h cocoa_init.m + cocoa_joystick.m cocoa_monitor.m cocoa_window.m + nsgl_context.m) +endif() + +if (GLFW_BUILD_WIN32) + target_compile_definitions(glfw PRIVATE _GLFW_WIN32) + target_sources(glfw PRIVATE win32_platform.h win32_joystick.h win32_init.c + win32_joystick.c win32_monitor.c win32_window.c + wgl_context.c) +endif() + +if (GLFW_BUILD_X11) + target_compile_definitions(glfw PRIVATE _GLFW_X11) + target_sources(glfw PRIVATE x11_platform.h xkb_unicode.h x11_init.c + x11_monitor.c x11_window.c xkb_unicode.c + glx_context.c) +endif() + +if (GLFW_BUILD_WAYLAND) + target_compile_definitions(glfw PRIVATE _GLFW_WAYLAND) + target_sources(glfw PRIVATE wl_platform.h xkb_unicode.h wl_init.c + wl_monitor.c wl_window.c xkb_unicode.c) +endif() + +if (GLFW_BUILD_X11 OR GLFW_BUILD_WAYLAND) + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c) + endif() + target_sources(glfw PRIVATE posix_poll.h posix_poll.c) +endif() + +if (GLFW_BUILD_WAYLAND) + include(CheckIncludeFiles) + include(CheckFunctionExists) + check_function_exists(memfd_create HAVE_MEMFD_CREATE) + if (HAVE_MEMFD_CREATE) + target_compile_definitions(glfw PRIVATE HAVE_MEMFD_CREATE) + endif() + + find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner) + if (NOT WAYLAND_SCANNER_EXECUTABLE) + message(FATAL_ERROR "Failed to find wayland-scanner") + endif() + + macro(generate_wayland_protocol protocol_file) + set(protocol_path "${GLFW_SOURCE_DIR}/deps/wayland/${protocol_file}") + + string(REGEX REPLACE "\\.xml$" "-client-protocol.h" header_file ${protocol_file}) + string(REGEX REPLACE "\\.xml$" "-client-protocol-code.h" code_file ${protocol_file}) + + add_custom_command(OUTPUT ${header_file} + COMMAND "${WAYLAND_SCANNER_EXECUTABLE}" client-header "${protocol_path}" ${header_file} + DEPENDS "${protocol_path}" + VERBATIM) + + add_custom_command(OUTPUT ${code_file} + COMMAND "${WAYLAND_SCANNER_EXECUTABLE}" private-code "${protocol_path}" ${code_file} + DEPENDS "${protocol_path}" + VERBATIM) + + target_sources(glfw PRIVATE ${header_file} ${code_file}) + endmacro() + + generate_wayland_protocol("wayland.xml") + generate_wayland_protocol("viewporter.xml") + generate_wayland_protocol("xdg-shell.xml") + generate_wayland_protocol("idle-inhibit-unstable-v1.xml") + generate_wayland_protocol("pointer-constraints-unstable-v1.xml") + generate_wayland_protocol("relative-pointer-unstable-v1.xml") + generate_wayland_protocol("fractional-scale-v1.xml") + generate_wayland_protocol("xdg-activation-v1.xml") + generate_wayland_protocol("xdg-decoration-unstable-v1.xml") +endif() + +if (WIN32 AND GLFW_BUILD_SHARED_LIBRARY) + configure_file(glfw.rc.in glfw.rc @ONLY) + target_sources(glfw PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/glfw.rc") +endif() + +if (UNIX AND GLFW_BUILD_SHARED_LIBRARY) + # On Unix-like systems, shared libraries can use the soname system. + set(GLFW_LIB_NAME glfw) +else() + set(GLFW_LIB_NAME glfw3) +endif() +set(GLFW_LIB_NAME_SUFFIX "") + +set_target_properties(glfw PROPERTIES + OUTPUT_NAME ${GLFW_LIB_NAME} + VERSION ${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR} + SOVERSION ${GLFW_VERSION_MAJOR} + POSITION_INDEPENDENT_CODE ON + C_STANDARD 99 + C_EXTENSIONS OFF + DEFINE_SYMBOL _GLFW_BUILD_DLL + FOLDER "GLFW3") + +target_include_directories(glfw PUBLIC + "$" + "$") +target_include_directories(glfw PRIVATE + "${GLFW_SOURCE_DIR}/src" + "${GLFW_BINARY_DIR}/src") +target_link_libraries(glfw PRIVATE Threads::Threads) + +# Workaround for CMake not knowing about .m files before version 3.16 +if (CMAKE_VERSION VERSION_LESS "3.16" AND APPLE) + set_source_files_properties(cocoa_init.m cocoa_joystick.m cocoa_monitor.m + cocoa_window.m nsgl_context.m PROPERTIES + LANGUAGE C) +endif() + +if (GLFW_BUILD_WIN32) + list(APPEND glfw_PKG_LIBS "-lgdi32") +endif() + +if (GLFW_BUILD_COCOA) + target_link_libraries(glfw PRIVATE "-framework Cocoa" + "-framework IOKit" + "-framework CoreFoundation") + + set(glfw_PKG_DEPS "") + set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation") +endif() + +if (GLFW_BUILD_WAYLAND) + include(FindPkgConfig) + + pkg_check_modules(Wayland REQUIRED + wayland-client>=0.2.7 + wayland-cursor>=0.2.7 + wayland-egl>=0.2.7 + xkbcommon>=0.5.0) + + target_include_directories(glfw PRIVATE ${Wayland_INCLUDE_DIRS}) + + if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") + find_package(EpollShim) + if (EPOLLSHIM_FOUND) + target_include_directories(glfw PRIVATE ${EPOLLSHIM_INCLUDE_DIRS}) + target_link_libraries(glfw PRIVATE ${EPOLLSHIM_LIBRARIES}) + endif() + endif() +endif() + +if (GLFW_BUILD_X11) + find_package(X11 REQUIRED) + target_include_directories(glfw PRIVATE "${X11_X11_INCLUDE_PATH}") + + # Check for XRandR (modern resolution switching and gamma control) + if (NOT X11_Xrandr_INCLUDE_PATH) + message(FATAL_ERROR "RandR headers not found; install libxrandr development package") + endif() + target_include_directories(glfw PRIVATE "${X11_Xrandr_INCLUDE_PATH}") + + # Check for Xinerama (legacy multi-monitor support) + if (NOT X11_Xinerama_INCLUDE_PATH) + message(FATAL_ERROR "Xinerama headers not found; install libxinerama development package") + endif() + target_include_directories(glfw PRIVATE "${X11_Xinerama_INCLUDE_PATH}") + + # Check for Xkb (X keyboard extension) + if (NOT X11_Xkb_INCLUDE_PATH) + message(FATAL_ERROR "XKB headers not found; install X11 development package") + endif() + target_include_directories(glfw PRIVATE "${X11_Xkb_INCLUDE_PATH}") + + # Check for Xcursor (cursor creation from RGBA images) + if (NOT X11_Xcursor_INCLUDE_PATH) + message(FATAL_ERROR "Xcursor headers not found; install libxcursor development package") + endif() + target_include_directories(glfw PRIVATE "${X11_Xcursor_INCLUDE_PATH}") + + # Check for XInput (modern HID input) + if (NOT X11_Xi_INCLUDE_PATH) + message(FATAL_ERROR "XInput headers not found; install libxi development package") + endif() + target_include_directories(glfw PRIVATE "${X11_Xi_INCLUDE_PATH}") + + # Check for X Shape (custom window input shape) + if (NOT X11_Xshape_INCLUDE_PATH) + message(FATAL_ERROR "X Shape headers not found; install libxext development package") + endif() + target_include_directories(glfw PRIVATE "${X11_Xshape_INCLUDE_PATH}") +endif() + +if (UNIX AND NOT APPLE) + find_library(RT_LIBRARY rt) + mark_as_advanced(RT_LIBRARY) + if (RT_LIBRARY) + target_link_libraries(glfw PRIVATE "${RT_LIBRARY}") + list(APPEND glfw_PKG_LIBS "-lrt") + endif() + + find_library(MATH_LIBRARY m) + mark_as_advanced(MATH_LIBRARY) + if (MATH_LIBRARY) + target_link_libraries(glfw PRIVATE "${MATH_LIBRARY}") + list(APPEND glfw_PKG_LIBS "-lm") + endif() + + if (CMAKE_DL_LIBS) + target_link_libraries(glfw PRIVATE "${CMAKE_DL_LIBS}") + list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}") + endif() +endif() + +if (WIN32) + if (GLFW_USE_HYBRID_HPG) + target_compile_definitions(glfw PRIVATE _GLFW_USE_HYBRID_HPG) + endif() +endif() + +# Enable a reasonable set of warnings +# NOTE: The order matters here, Clang-CL matches both MSVC and Clang +if (MSVC) + target_compile_options(glfw PRIVATE "/W3") +elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR + CMAKE_C_COMPILER_ID STREQUAL "Clang" OR + CMAKE_C_COMPILER_ID STREQUAL "AppleClang") + + target_compile_options(glfw PRIVATE "-Wall") +endif() + +if (GLFW_BUILD_WIN32) + target_compile_definitions(glfw PRIVATE UNICODE _UNICODE) +endif() + +# HACK: When building on MinGW, WINVER and UNICODE need to be defined before +# the inclusion of stddef.h (by glfw3.h), which is itself included before +# win32_platform.h. We define them here until a saner solution can be found +# NOTE: MinGW-w64 and Visual C++ do /not/ need this hack. +if (MINGW) + target_compile_definitions(glfw PRIVATE WINVER=0x0501) +endif() + +# Workaround for legacy MinGW not providing XInput and DirectInput +if (MINGW) + include(CheckIncludeFile) + check_include_file(dinput.h DINPUT_H_FOUND) + check_include_file(xinput.h XINPUT_H_FOUND) + if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND) + target_include_directories(glfw PRIVATE "${GLFW_SOURCE_DIR}/deps/mingw") + endif() +endif() + +# Workaround for the MS CRT deprecating parts of the standard library +if (MSVC OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC") + target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS) +endif() + +# Workaround for -std=c99 on Linux disabling _DEFAULT_SOURCE (POSIX 2008 and more) +if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + target_compile_definitions(glfw PRIVATE _DEFAULT_SOURCE) +endif() + +if (GLFW_BUILD_SHARED_LIBRARY) + if (WIN32) + if (MINGW) + # Remove the dependency on the shared version of libgcc + # NOTE: MinGW-w64 has the correct default but MinGW needs this + target_link_libraries(glfw PRIVATE "-static-libgcc") + + # Remove the lib prefix on the DLL (but not the import library) + set_target_properties(glfw PROPERTIES PREFIX "") + + # Add a suffix to the import library to avoid naming conflicts + set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.a") + else() + # Add a suffix to the import library to avoid naming conflicts + set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib") + endif() + set (GLFW_LIB_NAME_SUFFIX "dll") + + target_compile_definitions(glfw INTERFACE GLFW_DLL) + endif() + + if (MINGW) + # Enable link-time exploit mitigation features enabled by default on MSVC + include(CheckCCompilerFlag) + + # Compatibility with data execution prevention (DEP) + set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat") + check_c_compiler_flag("" _GLFW_HAS_DEP) + if (_GLFW_HAS_DEP) + target_link_libraries(glfw PRIVATE "-Wl,--nxcompat") + endif() + + # Compatibility with address space layout randomization (ASLR) + set(CMAKE_REQUIRED_FLAGS "-Wl,--dynamicbase") + check_c_compiler_flag("" _GLFW_HAS_ASLR) + if (_GLFW_HAS_ASLR) + target_link_libraries(glfw PRIVATE "-Wl,--dynamicbase") + endif() + + # Compatibility with 64-bit address space layout randomization (ASLR) + set(CMAKE_REQUIRED_FLAGS "-Wl,--high-entropy-va") + check_c_compiler_flag("" _GLFW_HAS_64ASLR) + if (_GLFW_HAS_64ASLR) + target_link_libraries(glfw PRIVATE "-Wl,--high-entropy-va") + endif() + + # Clear flags again to avoid breaking later tests + set(CMAKE_REQUIRED_FLAGS) + endif() + + if (UNIX) + # Hide symbols not explicitly tagged for export from the shared library + target_compile_options(glfw PRIVATE "-fvisibility=hidden") + endif() +endif() + +foreach(arg ${glfw_PKG_DEPS}) + string(APPEND deps " ${arg}") +endforeach() +foreach(arg ${glfw_PKG_LIBS}) + string(APPEND libs " ${arg}") +endforeach() + +set(GLFW_PKG_CONFIG_REQUIRES_PRIVATE "${deps}" CACHE INTERNAL + "GLFW pkg-config Requires.private") +set(GLFW_PKG_CONFIG_LIBS_PRIVATE "${libs}" CACHE INTERNAL + "GLFW pkg-config Libs.private") + +configure_file("${GLFW_SOURCE_DIR}/CMake/glfw3.pc.in" glfw3.pc @ONLY) + +if (GLFW_INSTALL) + install(TARGETS glfw + EXPORT glfwTargets + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") +endif() + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_init.m b/src/lib/src/vendor/glfw-3.4/src/cocoa_init.m similarity index 79% rename from src/lib/src/vendor/glfw-3.3.8/src/cocoa_init.m rename to src/lib/src/vendor/glfw-3.4/src/cocoa_init.m index f527312..e75a551 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_init.m +++ b/src/lib/src/vendor/glfw-3.4/src/cocoa_init.m @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 macOS - www.glfw.org +// GLFW 3.4 macOS - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2009-2019 Camilla Löwy // @@ -23,10 +23,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" + +#if defined(_GLFW_COCOA) + #include // For MAXPATHLEN // Needed for _NSGetProgname @@ -75,7 +76,6 @@ static void changeToResourcesDirectory(void) // static void createMenuBar(void) { - size_t i; NSString* appName = nil; NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary]; NSString* nameKeys[] = @@ -87,7 +87,7 @@ static void createMenuBar(void) // Try to figure out what the calling application is called - for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++) + for (size_t i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++) { id name = bundleInfo[nameKeys[i]]; if (name && @@ -177,8 +177,6 @@ static void createMenuBar(void) // static void createKeyTables(void) { - int scancode; - memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes)); memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes)); @@ -251,7 +249,7 @@ static void createKeyTables(void) _glfw.ns.keycodes[0x6D] = GLFW_KEY_F10; _glfw.ns.keycodes[0x67] = GLFW_KEY_F11; _glfw.ns.keycodes[0x6F] = GLFW_KEY_F12; - _glfw.ns.keycodes[0x69] = GLFW_KEY_F13; + _glfw.ns.keycodes[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; @@ -297,7 +295,7 @@ static void createKeyTables(void) _glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY; _glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT; - for (scancode = 0; scancode < 256; scancode++) + for (int scancode = 0; scancode < 256; scancode++) { // Store the reverse translation for faster key name lookup if (_glfw.ns.keycodes[scancode] >= 0) @@ -307,7 +305,7 @@ static void createKeyTables(void) // Retrieve Unicode data for the current keyboard layout // -static GLFWbool updateUnicodeDataNS(void) +static GLFWbool updateUnicodeData(void) { if (_glfw.ns.inputSource) { @@ -377,7 +375,7 @@ static GLFWbool initializeTIS(void) _glfw.ns.tis.kPropertyUnicodeKeyLayoutData = *kPropertyUnicodeKeyLayoutData; - return updateUnicodeDataNS(); + return updateUnicodeData(); } @interface GLFWHelper : NSObject @@ -387,7 +385,7 @@ static GLFWbool initializeTIS(void) - (void)selectedKeyboardInputSourceChanged:(NSObject* )object { - updateUnicodeDataNS(); + updateUnicodeData(); } - (void)doNothing:(id)object @@ -403,9 +401,7 @@ static GLFWbool initializeTIS(void) - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { - _GLFWwindow* window; - - for (window = _glfw.windowListHead; window; window = window->next) + for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next) _glfwInputWindowCloseRequest(window); return NSTerminateCancel; @@ -413,15 +409,13 @@ static GLFWbool initializeTIS(void) - (void)applicationDidChangeScreenParameters:(NSNotification *) notification { - _GLFWwindow* window; - - for (window = _glfw.windowListHead; window; window = window->next) + for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next) { if (window->context.client != GLFW_NO_API) [window->context.nsgl.object update]; } - _glfwPollMonitorsNS(); + _glfwPollMonitorsCocoa(); } - (void)applicationWillFinishLaunching:(NSNotification *)notification @@ -444,22 +438,14 @@ static GLFWbool initializeTIS(void) - (void)applicationDidFinishLaunching:(NSNotification *)notification { - _glfw.ns.finishedLaunching = GLFW_TRUE; - _glfwPlatformPostEmptyEvent(); - - // In case we are unbundled, make us a proper UI application - if (_glfw.hints.init.ns.menubar) - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - + _glfwPostEmptyEventCocoa(); [NSApp stop:nil]; } - (void)applicationDidHide:(NSNotification *)notification { - int i; - - for (i = 0; i < _glfw.monitorCount; i++) - _glfwRestoreVideoModeNS(_glfw.monitors[i]); + for (int i = 0; i < _glfw.monitorCount; i++) + _glfwRestoreVideoModeCocoa(_glfw.monitors[i]); } @end // GLFWApplicationDelegate @@ -469,7 +455,7 @@ static GLFWbool initializeTIS(void) ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// -void* _glfwLoadLocalVulkanLoaderNS(void) +void* _glfwLoadLocalVulkanLoaderCocoa(void) { CFBundleRef bundle = CFBundleGetMainBundle(); if (!bundle) @@ -491,7 +477,7 @@ void* _glfwLoadLocalVulkanLoaderNS(void) void* handle = NULL; if (CFURLGetFileSystemRepresentation(loaderUrl, true, (UInt8*) path, sizeof(path) - 1)) - handle = _glfw_dlopen(path); + handle = _glfwPlatformLoadModule(path); CFRelease(loaderUrl); CFRelease(frameworksUrl); @@ -503,7 +489,89 @@ void* _glfwLoadLocalVulkanLoaderNS(void) ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -int _glfwPlatformInit(void) +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 { @@ -513,9 +581,6 @@ int _glfwPlatformInit(void) toTarget:_glfw.ns.helper withObject:nil]; - if (NSApp) - _glfw.ns.finishedLaunching = GLFW_TRUE; - [NSApplication sharedApplication]; _glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init]; @@ -564,16 +629,21 @@ int _glfwPlatformInit(void) if (!initializeTIS()) return GLFW_FALSE; - _glfwInitTimerNS(); - _glfwInitJoysticksNS(); + _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]; - _glfwPollMonitorsNS(); return GLFW_TRUE; } // autoreleasepool } -void _glfwPlatformTerminate(void) +void _glfwTerminateCocoa(void) { @autoreleasepool { @@ -612,22 +682,14 @@ void _glfwPlatformTerminate(void) if (_glfw.ns.keyUpMonitor) [NSEvent removeMonitor:_glfw.ns.keyUpMonitor]; - free(_glfw.ns.clipboardString); + _glfw_free(_glfw.ns.clipboardString); _glfwTerminateNSGL(); _glfwTerminateEGL(); _glfwTerminateOSMesa(); - _glfwTerminateJoysticksNS(); } // autoreleasepool } -const char* _glfwPlatformGetVersionString(void) -{ - return _GLFW_VERSION_NUMBER " Cocoa NSGL EGL OSMesa" -#if defined(_GLFW_BUILD_DLL) - " dynamic" -#endif - ; -} +#endif // _GLFW_COCOA diff --git a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_joystick.h b/src/lib/src/vendor/glfw-3.4/src/cocoa_joystick.h similarity index 79% rename from src/lib/src/vendor/glfw-3.3.8/src/cocoa_joystick.h rename to src/lib/src/vendor/glfw-3.4/src/cocoa_joystick.h index 0de8678..2f46dfc 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_joystick.h +++ b/src/lib/src/vendor/glfw-3.4/src/cocoa_joystick.h @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Cocoa - www.glfw.org +// GLFW 3.4 Cocoa - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2006-2017 Camilla Löwy // @@ -26,14 +26,10 @@ #include #include -#include #include -#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickNS ns -#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyJoystick; } - -#define _GLFW_PLATFORM_MAPPING_NAME "Mac OS X" -#define GLFW_BUILD_COCOA_MAPPINGS +#define GLFW_COCOA_JOYSTICK_STATE _GLFWjoystickNS ns; +#define GLFW_COCOA_LIBRARY_JOYSTICK_STATE // Cocoa-specific per-joystick data // @@ -45,7 +41,9 @@ typedef struct _GLFWjoystickNS CFMutableArrayRef hats; } _GLFWjoystickNS; - -void _glfwInitJoysticksNS(void); -void _glfwTerminateJoysticksNS(void); +GLFWbool _glfwInitJoysticksCocoa(void); +void _glfwTerminateJoysticksCocoa(void); +GLFWbool _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode); +const char* _glfwGetMappingNameCocoa(void); +void _glfwUpdateGamepadGUIDCocoa(char* guid); diff --git a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_joystick.m b/src/lib/src/vendor/glfw-3.4/src/cocoa_joystick.m similarity index 89% rename from src/lib/src/vendor/glfw-3.3.8/src/cocoa_joystick.m rename to src/lib/src/vendor/glfw-3.4/src/cocoa_joystick.m index 3d30677..d5de479 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_joystick.m +++ b/src/lib/src/vendor/glfw-3.4/src/cocoa_joystick.m @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Cocoa - www.glfw.org +// GLFW 3.4 Cocoa - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2009-2019 Camilla Löwy // Copyright (c) 2012 Torsten Walluhn @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_COCOA) + #include #include #include @@ -96,20 +96,18 @@ static CFComparisonResult compareElements(const void* fp, // static void closeJoystick(_GLFWjoystick* js) { - int i; - _glfwInputJoystick(js, GLFW_DISCONNECTED); - for (i = 0; i < CFArrayGetCount(js->ns.axes); i++) - free((void*) CFArrayGetValueAtIndex(js->ns.axes, i)); + for (int i = 0; i < CFArrayGetCount(js->ns.axes); i++) + _glfw_free((void*) CFArrayGetValueAtIndex(js->ns.axes, i)); CFRelease(js->ns.axes); - for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++) - free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i)); + for (int i = 0; i < CFArrayGetCount(js->ns.buttons); i++) + _glfw_free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i)); CFRelease(js->ns.buttons); - for (i = 0; i < CFArrayGetCount(js->ns.hats); i++) - free((void*) CFArrayGetValueAtIndex(js->ns.hats, i)); + for (int i = 0; i < CFArrayGetCount(js->ns.hats); i++) + _glfw_free((void*) CFArrayGetValueAtIndex(js->ns.hats, i)); CFRelease(js->ns.hats); _glfwFreeJoystick(js); @@ -125,7 +123,6 @@ static void matchCallback(void* context, int jid; char name[256]; char guid[33]; - CFIndex i; CFTypeRef property; uint32_t vendor = 0, product = 0, version = 0; _GLFWjoystick* js; @@ -137,6 +134,14 @@ static void matchCallback(void* context, 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); @@ -180,10 +185,7 @@ static void matchCallback(void* context, name[8], name[9], name[10]); } - CFArrayRef elements = - IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone); - - for (i = 0; i < CFArrayGetCount(elements); i++) + for (CFIndex i = 0; i < CFArrayGetCount(elements); i++) { IOHIDElementRef native = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, i); @@ -249,7 +251,7 @@ static void matchCallback(void* context, if (target) { - _GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS)); + _GLFWjoyelementNS* element = _glfw_calloc(1, sizeof(_GLFWjoyelementNS)); element->native = native; element->usage = usage; element->index = (int) CFArrayGetCount(target); @@ -288,9 +290,7 @@ static void removeCallback(void* context, void* sender, IOHIDDeviceRef device) { - int jid; - - for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) + for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { if (_glfw.joysticks[jid].connected && _glfw.joysticks[jid].ns.device == device) { @@ -302,12 +302,10 @@ static void removeCallback(void* context, ////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// +////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -// Initialize joystick interface -// -void _glfwInitJoysticksNS(void) +GLFWbool _glfwInitJoysticksCocoa(void) { CFMutableArrayRef matching; const long usages[] = @@ -326,7 +324,7 @@ void _glfwInitJoysticksNS(void) if (!matching) { _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array"); - return; + return GLFW_FALSE; } for (size_t i = 0; i < sizeof(usages) / sizeof(long); i++) @@ -381,36 +379,30 @@ void _glfwInitJoysticksNS(void) // Execute the run loop once in order to register any initially-attached // joysticks CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false); + return GLFW_TRUE; } -// Close all opened joystick handles -// -void _glfwTerminateJoysticksNS(void) +void _glfwTerminateJoysticksCocoa(void) { - int jid; - - for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) + for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { if (_glfw.joysticks[jid].connected) closeJoystick(&_glfw.joysticks[jid]); } - CFRelease(_glfw.ns.hidManager); - _glfw.ns.hidManager = NULL; + if (_glfw.ns.hidManager) + { + CFRelease(_glfw.ns.hidManager); + _glfw.ns.hidManager = NULL; + } } -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) +GLFWbool _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode) { if (mode & _GLFW_POLL_AXES) { - CFIndex i; - - for (i = 0; i < CFArrayGetCount(js->ns.axes); i++) + for (CFIndex i = 0; i < CFArrayGetCount(js->ns.axes); i++) { _GLFWjoyelementNS* axis = (_GLFWjoyelementNS*) CFArrayGetValueAtIndex(js->ns.axes, i); @@ -435,9 +427,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) if (mode & _GLFW_POLL_BUTTONS) { - CFIndex i; - - for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++) + for (CFIndex i = 0; i < CFArrayGetCount(js->ns.buttons); i++) { _GLFWjoyelementNS* button = (_GLFWjoyelementNS*) CFArrayGetValueAtIndex(js->ns.buttons, i); @@ -446,7 +436,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) _glfwInputJoystickButton(js, (int) i, state); } - for (i = 0; i < CFArrayGetCount(js->ns.hats); i++) + for (CFIndex i = 0; i < CFArrayGetCount(js->ns.hats); i++) { const int states[9] = { @@ -474,7 +464,12 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) return js->connected; } -void _glfwPlatformUpdateGamepadGUID(char* guid) +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)) @@ -486,3 +481,5 @@ void _glfwPlatformUpdateGamepadGUID(char* guid) } } +#endif // _GLFW_COCOA + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_monitor.m b/src/lib/src/vendor/glfw-3.4/src/cocoa_monitor.m similarity index 89% rename from src/lib/src/vendor/glfw-3.3.8/src/cocoa_monitor.m rename to src/lib/src/vendor/glfw-3.4/src/cocoa_monitor.m index 7769bb7..641d5f0 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_monitor.m +++ b/src/lib/src/vendor/glfw-3.4/src/cocoa_monitor.m @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 macOS - www.glfw.org +// GLFW 3.4 macOS - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_COCOA) + #include #include #include @@ -116,7 +116,7 @@ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen) const CFIndex size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef), kCFStringEncodingUTF8); - char* name = calloc(size + 1, 1); + char* name = _glfw_calloc(size + 1, 1); CFStringGetCString(nameRef, name, size, kCFStringEncodingUTF8); CFRelease(info); @@ -293,11 +293,11 @@ static double getFallbackRefreshRate(CGDirectDisplayID displayID) // Poll for changes in the set of connected monitors // -void _glfwPollMonitorsNS(void) +void _glfwPollMonitorsCocoa(void) { uint32_t displayCount; CGGetOnlineDisplayList(0, NULL, &displayCount); - CGDirectDisplayID* displays = calloc(displayCount, sizeof(CGDirectDisplayID)); + CGDirectDisplayID* displays = _glfw_calloc(displayCount, sizeof(CGDirectDisplayID)); CGGetOnlineDisplayList(displayCount, displays, &displayCount); for (int i = 0; i < _glfw.monitorCount; i++) @@ -307,7 +307,7 @@ void _glfwPollMonitorsNS(void) uint32_t disconnectedCount = _glfw.monitorCount; if (disconnectedCount) { - disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*)); + disconnected = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*)); memcpy(disconnected, _glfw.monitors, _glfw.monitorCount * sizeof(_GLFWmonitor*)); @@ -359,7 +359,7 @@ void _glfwPollMonitorsNS(void) monitor->ns.unitNumber = unitNumber; monitor->ns.screen = screen; - free(name); + _glfw_free(name); CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]); if (CGDisplayModeGetRefreshRate(mode) == 0.0) @@ -375,16 +375,16 @@ void _glfwPollMonitorsNS(void) _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0); } - free(disconnected); - free(displays); + _glfw_free(disconnected); + _glfw_free(displays); } // Change the current video mode // -void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired) +void _glfwSetVideoModeCocoa(_GLFWmonitor* monitor, const GLFWvidmode* desired) { GLFWvidmode current; - _glfwPlatformGetVideoMode(monitor, ¤t); + _glfwGetVideoModeCocoa(monitor, ¤t); const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired); if (_glfwCompareVideoModes(¤t, best) == 0) @@ -424,7 +424,7 @@ void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired) // Restore the previously saved (original) video mode // -void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor) +void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor) { if (monitor->ns.previousMode) { @@ -443,11 +443,11 @@ void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor) ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) +void _glfwFreeMonitorCocoa(_GLFWmonitor* monitor) { } -void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +void _glfwGetMonitorPosCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos) { @autoreleasepool { @@ -461,8 +461,8 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) } // autoreleasepool } -void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, - float* xscale, float* yscale) +void _glfwGetMonitorContentScaleCocoa(_GLFWmonitor* monitor, + float* xscale, float* yscale) { @autoreleasepool { @@ -483,9 +483,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, } // autoreleasepool } -void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, - int* xpos, int* ypos, - int* width, int* height) +void _glfwGetMonitorWorkareaCocoa(_GLFWmonitor* monitor, + int* xpos, int* ypos, + int* width, int* height) { @autoreleasepool { @@ -500,7 +500,7 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, if (xpos) *xpos = frameRect.origin.x; if (ypos) - *ypos = _glfwTransformYNS(frameRect.origin.y + frameRect.size.height - 1); + *ypos = _glfwTransformYCocoa(frameRect.origin.y + frameRect.size.height - 1); if (width) *width = frameRect.size.width; if (height) @@ -509,7 +509,7 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, } // autoreleasepool } -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) +GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count) { @autoreleasepool { @@ -517,7 +517,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); const CFIndex found = CFArrayGetCount(modes); - GLFWvidmode* result = calloc(found, sizeof(GLFWvidmode)); + GLFWvidmode* result = _glfw_calloc(found, sizeof(GLFWvidmode)); for (CFIndex i = 0; i < found; i++) { @@ -549,23 +549,30 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) } // autoreleasepool } -void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) +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 _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwGetGammaRampCocoa(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { @autoreleasepool { uint32_t size = CGDisplayGammaTableCapacity(monitor->ns.displayID); - CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue)); + CGGammaValue* values = _glfw_calloc(size * 3, sizeof(CGGammaValue)); CGGetDisplayTransferByTable(monitor->ns.displayID, size, @@ -583,17 +590,17 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535); } - free(values); + _glfw_free(values); return GLFW_TRUE; } // autoreleasepool } -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) { @autoreleasepool { - CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue)); + CGGammaValue* values = _glfw_calloc(ramp->size * 3, sizeof(CGGammaValue)); for (unsigned int i = 0; i < ramp->size; i++) { @@ -608,7 +615,7 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) values + ramp->size, values + ramp->size * 2); - free(values); + _glfw_free(values); } // autoreleasepool } @@ -622,6 +629,15 @@ 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 + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_platform.h b/src/lib/src/vendor/glfw-3.4/src/cocoa_platform.h similarity index 52% rename from src/lib/src/vendor/glfw-3.3.8/src/cocoa_platform.h rename to src/lib/src/vendor/glfw-3.4/src/cocoa_platform.h index bb67703..3991455 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_platform.h +++ b/src/lib/src/vendor/glfw-3.4/src/cocoa_platform.h @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 macOS - www.glfw.org +// GLFW 3.4 macOS - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2009-2019 Camilla Löwy // @@ -25,9 +25,9 @@ //======================================================================== #include -#include #include +#include // NOTE: All of NSGL was deprecated in the 10.14 SDK // This disables the pointless warnings for every symbol we use @@ -46,6 +46,11 @@ typedef void* id; // 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 @@ -95,24 +100,13 @@ typedef struct VkMetalSurfaceCreateInfoEXT typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*); typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance,const VkMetalSurfaceCreateInfoEXT*,const VkAllocationCallbacks*,VkSurfaceKHR*); -#include "posix_thread.h" -#include "cocoa_joystick.h" -#include "nsgl_context.h" -#include "egl_context.h" -#include "osmesa_context.h" +#define GLFW_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_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) -#define _glfw_dlclose(handle) dlclose(handle) -#define _glfw_dlsym(handle, name) dlsym(handle, name) - -#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->ns.layer) -#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY - -#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns -#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns -#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerNS ns -#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNS ns -#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorNS ns +#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 @@ -124,6 +118,22 @@ 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 @@ -135,7 +145,7 @@ typedef struct _GLFWwindowNS GLFWbool maximized; GLFWbool occluded; - GLFWbool retina; + GLFWbool scaleFramebuffer; // Cached window properties to filter out duplicate events int width, height; @@ -154,7 +164,6 @@ typedef struct _GLFWlibraryNS { CGEventSourceRef eventSource; id delegate; - GLFWbool finishedLaunching; GLFWbool cursorHidden; TISInputSourceRef inputSource; IOHIDManagerRef hidManager; @@ -200,21 +209,94 @@ typedef struct _GLFWcursorNS id object; } _GLFWcursorNS; -// Cocoa-specific global timer data -// -typedef struct _GLFWtimerNS -{ - uint64_t frequency; -} _GLFWtimerNS; +GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform); +int _glfwInitCocoa(void); +void _glfwTerminateCocoa(void); -void _glfwInitTimerNS(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 _glfwPollMonitorsNS(void); -void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired); -void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor); +void _glfwSetRawMouseMotionCocoa(_GLFWwindow *window, GLFWbool enabled); +GLFWbool _glfwRawMouseMotionSupportedCocoa(void); -float _glfwTransformYNS(float y); +void _glfwPollEventsCocoa(void); +void _glfwWaitEventsCocoa(void); +void _glfwWaitEventsTimeoutCocoa(double timeout); +void _glfwPostEmptyEventCocoa(void); -void* _glfwLoadLocalVulkanLoaderNS(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); diff --git a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_time.c b/src/lib/src/vendor/glfw-3.4/src/cocoa_time.c similarity index 79% rename from src/lib/src/vendor/glfw-3.3.8/src/cocoa_time.c rename to src/lib/src/vendor/glfw-3.4/src/cocoa_time.c index d390cdc..d56f145 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_time.c +++ b/src/lib/src/vendor/glfw-3.4/src/cocoa_time.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 macOS - www.glfw.org +// GLFW 3.4 macOS - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2009-2016 Camilla Löwy // @@ -23,21 +23,19 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_COCOA_TIMER) + #include ////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// +////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -// Initialise timer -// -void _glfwInitTimerNS(void) +void _glfwPlatformInitTimer(void) { mach_timebase_info_data_t info; mach_timebase_info(&info); @@ -45,11 +43,6 @@ void _glfwInitTimerNS(void) _glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer; } - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - uint64_t _glfwPlatformGetTimerValue(void) { return mach_absolute_time(); @@ -60,3 +53,5 @@ uint64_t _glfwPlatformGetTimerFrequency(void) return _glfw.timer.ns.frequency; } +#endif // GLFW_BUILD_COCOA_TIMER + diff --git a/src/lib/src/vendor/glfw-3.4/src/cocoa_time.h b/src/lib/src/vendor/glfw-3.4/src/cocoa_time.h new file mode 100644 index 0000000..3512e8b --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/cocoa_time.h @@ -0,0 +1,35 @@ +//======================================================================== +// GLFW 3.4 macOS - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2021 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as 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; + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_window.m b/src/lib/src/vendor/glfw-3.4/src/cocoa_window.m similarity index 79% rename from src/lib/src/vendor/glfw-3.3.8/src/cocoa_window.m rename to src/lib/src/vendor/glfw-3.4/src/cocoa_window.m index bbab6c4..0dcf0a3 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/cocoa_window.m +++ b/src/lib/src/vendor/glfw-3.4/src/cocoa_window.m @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 macOS - www.glfw.org +// GLFW 3.4 macOS - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2009-2019 Camilla Löwy // @@ -23,11 +23,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_COCOA) + #include #include @@ -89,20 +89,20 @@ static void updateCursorMode(_GLFWwindow* window) if (window->cursorMode == GLFW_CURSOR_DISABLED) { _glfw.ns.disabledCursorWindow = window; - _glfwPlatformGetCursorPos(window, - &_glfw.ns.restoreCursorPosX, - &_glfw.ns.restoreCursorPosY); + _glfwGetCursorPosCocoa(window, + &_glfw.ns.restoreCursorPosX, + &_glfw.ns.restoreCursorPosY); _glfwCenterCursorInContentArea(window); CGAssociateMouseAndMouseCursorPosition(false); } else if (_glfw.ns.disabledCursorWindow == window) { _glfw.ns.disabledCursorWindow = NULL; - _glfwPlatformSetCursorPos(window, - _glfw.ns.restoreCursorPosX, - _glfw.ns.restoreCursorPosY); + _glfwSetCursorPosCocoa(window, + _glfw.ns.restoreCursorPosX, + _glfw.ns.restoreCursorPosY); // NOTE: The matching CGAssociateMouseAndMouseCursorPosition call is - // made in _glfwPlatformSetCursorPos as part of a workaround + // made in _glfwSetCursorPosCocoa as part of a workaround } if (cursorInContentArea(window)) @@ -113,10 +113,10 @@ static void updateCursorMode(_GLFWwindow* window) // static void acquireMonitor(_GLFWwindow* window) { - _glfwSetVideoModeNS(window->monitor, &window->videoMode); + _glfwSetVideoModeCocoa(window->monitor, &window->videoMode); const CGRect bounds = CGDisplayBounds(window->monitor->ns.displayID); const NSRect frame = NSMakeRect(bounds.origin.x, - _glfwTransformYNS(bounds.origin.y + bounds.size.height - 1), + _glfwTransformYCocoa(bounds.origin.y + bounds.size.height - 1), bounds.size.width, bounds.size.height); @@ -133,7 +133,7 @@ static void releaseMonitor(_GLFWwindow* window) return; _glfwInputMonitorWindow(window->monitor, NULL); - _glfwRestoreVideoModeNS(window->monitor); + _glfwRestoreVideoModeCocoa(window->monitor); } // Translates macOS key modifiers into GLFW ones @@ -270,7 +270,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; _glfwCenterCursorInContentArea(window); int x, y; - _glfwPlatformGetWindowPos(window, &x, &y); + _glfwGetWindowPosCocoa(window, &x, &y); _glfwInputWindowPos(window, x, y); } @@ -302,17 +302,22 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (void)windowDidResignKey:(NSNotification *)notification { if (window->monitor && window->autoIconify) - _glfwPlatformIconifyWindow(window); + _glfwIconifyWindowCocoa(window); _glfwInputWindowFocus(window, GLFW_FALSE); } - (void)windowDidChangeOcclusionState:(NSNotification* )notification { - if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible) - window->ns.occluded = GLFW_FALSE; - else - window->ns.occluded = GLFW_TRUE; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 + if ([window->ns.object respondsToSelector:@selector(occlusionState)]) + { + if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible) + window->ns.occluded = GLFW_FALSE; + else + window->ns.occluded = GLFW_TRUE; + } +#endif } @end @@ -508,7 +513,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; if (xscale != window->ns.xscale || yscale != window->ns.yscale) { - if (window->ns.retina && window->ns.layer) + if (window->ns.scaleFramebuffer && window->ns.layer) [window->ns.layer setContentsScale:[window->ns.object backingScaleFactor]]; window->ns.xscale = xscale; @@ -629,7 +634,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; const NSUInteger count = [urls count]; if (count) { - char** paths = calloc(count, sizeof(char*)); + char** paths = _glfw_calloc(count, sizeof(char*)); for (NSUInteger i = 0; i < count; i++) paths[i] = _glfw_strdup([urls[i] fileSystemRepresentation]); @@ -637,8 +642,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; _glfwInputDrop(window, (int) count, (const char**) paths); for (NSUInteger i = 0; i < count; i++) - free(paths[i]); - free(paths); + _glfw_free(paths[i]); + _glfw_free(paths); } return YES; @@ -785,13 +790,25 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, GLFWvidmode mode; int xpos, ypos; - _glfwPlatformGetVideoMode(window->monitor, &mode); - _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); + _glfwGetVideoModeCocoa(window->monitor, &mode); + _glfwGetMonitorPosCocoa(window->monitor, &xpos, &ypos); contentRect = NSMakeRect(xpos, ypos, mode.width, mode.height); } else - contentRect = NSMakeRect(0, 0, wndconfig->width, wndconfig->height); + { + if (wndconfig->xpos == GLFW_ANY_POSITION || + wndconfig->ypos == GLFW_ANY_POSITION) + { + contentRect = NSMakeRect(0, 0, wndconfig->width, wndconfig->height); + } + else + { + const int xpos = wndconfig->xpos; + const int ypos = _glfwTransformYCocoa(wndconfig->ypos + wndconfig->height - 1); + contentRect = NSMakeRect(xpos, ypos, wndconfig->width, wndconfig->height); + } + } NSUInteger styleMask = NSWindowStyleMaskMiniaturizable; @@ -821,10 +838,14 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, [window->ns.object setLevel:NSMainMenuWindowLevel + 1]; else { - [(NSWindow*) window->ns.object center]; - _glfw.ns.cascadePoint = - NSPointToCGPoint([window->ns.object cascadeTopLeftFromPoint: - NSPointFromCGPoint(_glfw.ns.cascadePoint)]); + if (wndconfig->xpos == GLFW_ANY_POSITION || + wndconfig->ypos == GLFW_ANY_POSITION) + { + [(NSWindow*) window->ns.object center]; + _glfw.ns.cascadePoint = + NSPointToCGPoint([window->ns.object cascadeTopLeftFromPoint: + NSPointFromCGPoint(_glfw.ns.cascadePoint)]); + } if (wndconfig->resizable) { @@ -851,7 +872,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, [window->ns.object setFrameAutosaveName:@(wndconfig->ns.frameName)]; window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window]; - window->ns.retina = wndconfig->ns.retina; + window->ns.scaleFramebuffer = wndconfig->scaleFramebuffer; if (fbconfig->transparent) { @@ -872,8 +893,8 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, [window->ns.object setTabbingMode:NSWindowTabbingModeDisallowed]; #endif - _glfwPlatformGetWindowSize(window, &window->ns.width, &window->ns.height); - _glfwPlatformGetFramebufferSize(window, &window->ns.fbWidth, &window->ns.fbHeight); + _glfwGetWindowSizeCocoa(window, &window->ns.width, &window->ns.height); + _glfwGetFramebufferSizeCocoa(window, &window->ns.fbWidth, &window->ns.fbHeight); return GLFW_TRUE; } @@ -885,7 +906,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, // Transforms a y-coordinate between the CG display and NS screen spaces // -float _glfwTransformYNS(float y) +float _glfwTransformYCocoa(float y) { return CGDisplayBounds(CGMainDisplayID()).size.height - y - 1; } @@ -895,16 +916,13 @@ float _glfwTransformYNS(float y) ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -int _glfwPlatformCreateWindow(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) +GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) { @autoreleasepool { - if (!_glfw.ns.finishedLaunching) - [NSApp run]; - if (!createNativeWindow(window, wndconfig, fbconfig)) return GLFW_FALSE; @@ -941,10 +959,13 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, return GLFW_FALSE; } + if (wndconfig->mousePassthrough) + _glfwSetWindowMousePassthroughCocoa(window, GLFW_TRUE); + if (window->monitor) { - _glfwPlatformShowWindow(window); - _glfwPlatformFocusWindow(window); + _glfwShowWindowCocoa(window); + _glfwFocusWindowCocoa(window); acquireMonitor(window); if (wndconfig->centerCursor) @@ -954,9 +975,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, { if (wndconfig->visible) { - _glfwPlatformShowWindow(window); + _glfwShowWindowCocoa(window); if (wndconfig->focused) - _glfwPlatformFocusWindow(window); + _glfwFocusWindowCocoa(window); } } @@ -965,7 +986,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, } // autoreleasepool } -void _glfwPlatformDestroyWindow(_GLFWwindow* window) +void _glfwDestroyWindowCocoa(_GLFWwindow* window) { @autoreleasepool { @@ -991,12 +1012,12 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) window->ns.object = nil; // HACK: Allow Cocoa to catch up before returning - _glfwPlatformPollEvents(); + _glfwPollEventsCocoa(); } // autoreleasepool } -void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) +void _glfwSetWindowTitleCocoa(_GLFWwindow* window, const char* title) { @autoreleasepool { NSString* string = @(title); @@ -1007,13 +1028,14 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) } // autoreleasepool } -void _glfwPlatformSetWindowIcon(_GLFWwindow* window, - int count, const GLFWimage* images) +void _glfwSetWindowIconCocoa(_GLFWwindow* window, + int count, const GLFWimage* images) { - // Regular windows do not have icons + _glfwInputError(GLFW_FEATURE_UNAVAILABLE, + "Cocoa: Regular windows do not have icons on macOS"); } -void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) +void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos) { @autoreleasepool { @@ -1023,24 +1045,24 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) if (xpos) *xpos = contentRect.origin.x; if (ypos) - *ypos = _glfwTransformYNS(contentRect.origin.y + contentRect.size.height - 1); + *ypos = _glfwTransformYCocoa(contentRect.origin.y + contentRect.size.height - 1); } // autoreleasepool } -void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y) +void _glfwSetWindowPosCocoa(_GLFWwindow* window, int x, int y) { @autoreleasepool { const NSRect contentRect = [window->ns.view frame]; - const NSRect dummyRect = NSMakeRect(x, _glfwTransformYNS(y + contentRect.size.height - 1), 0, 0); + const NSRect dummyRect = NSMakeRect(x, _glfwTransformYCocoa(y + contentRect.size.height - 1), 0, 0); const NSRect frameRect = [window->ns.object frameRectForContentRect:dummyRect]; [window->ns.object setFrameOrigin:frameRect.origin]; } // autoreleasepool } -void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) +void _glfwGetWindowSizeCocoa(_GLFWwindow* window, int* width, int* height) { @autoreleasepool { @@ -1054,7 +1076,7 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) } // autoreleasepool } -void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) +void _glfwSetWindowSizeCocoa(_GLFWwindow* window, int width, int height) { @autoreleasepool { @@ -1076,9 +1098,9 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) } // autoreleasepool } -void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, - int minwidth, int minheight, - int maxwidth, int maxheight) +void _glfwSetWindowSizeLimitsCocoa(_GLFWwindow* window, + int minwidth, int minheight, + int maxwidth, int maxheight) { @autoreleasepool { @@ -1095,7 +1117,7 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, } // autoreleasepool } -void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom) +void _glfwSetWindowAspectRatioCocoa(_GLFWwindow* window, int numer, int denom) { @autoreleasepool { if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE) @@ -1105,7 +1127,7 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom } // autoreleasepool } -void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) +void _glfwGetFramebufferSizeCocoa(_GLFWwindow* window, int* width, int* height) { @autoreleasepool { @@ -1120,9 +1142,9 @@ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* heigh } // autoreleasepool } -void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, - int* left, int* top, - int* right, int* bottom) +void _glfwGetWindowFrameSizeCocoa(_GLFWwindow* window, + int* left, int* top, + int* right, int* bottom) { @autoreleasepool { @@ -1143,8 +1165,8 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, } // autoreleasepool } -void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, - float* xscale, float* yscale) +void _glfwGetWindowContentScaleCocoa(_GLFWwindow* window, + float* xscale, float* yscale) { @autoreleasepool { @@ -1159,14 +1181,14 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, } // autoreleasepool } -void _glfwPlatformIconifyWindow(_GLFWwindow* window) +void _glfwIconifyWindowCocoa(_GLFWwindow* window) { @autoreleasepool { [window->ns.object miniaturize:nil]; } // autoreleasepool } -void _glfwPlatformRestoreWindow(_GLFWwindow* window) +void _glfwRestoreWindowCocoa(_GLFWwindow* window) { @autoreleasepool { if ([window->ns.object isMiniaturized]) @@ -1176,7 +1198,7 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) } // autoreleasepool } -void _glfwPlatformMaximizeWindow(_GLFWwindow* window) +void _glfwMaximizeWindowCocoa(_GLFWwindow* window) { @autoreleasepool { if (![window->ns.object isZoomed]) @@ -1184,28 +1206,28 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window) } // autoreleasepool } -void _glfwPlatformShowWindow(_GLFWwindow* window) +void _glfwShowWindowCocoa(_GLFWwindow* window) { @autoreleasepool { [window->ns.object orderFront:nil]; } // autoreleasepool } -void _glfwPlatformHideWindow(_GLFWwindow* window) +void _glfwHideWindowCocoa(_GLFWwindow* window) { @autoreleasepool { [window->ns.object orderOut:nil]; } // autoreleasepool } -void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) +void _glfwRequestWindowAttentionCocoa(_GLFWwindow* window) { @autoreleasepool { [NSApp requestUserAttention:NSInformationalRequest]; } // autoreleasepool } -void _glfwPlatformFocusWindow(_GLFWwindow* window) +void _glfwFocusWindowCocoa(_GLFWwindow* window) { @autoreleasepool { // Make us the active application @@ -1217,11 +1239,11 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window) } // autoreleasepool } -void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, - _GLFWmonitor* monitor, - int xpos, int ypos, - int width, int height, - int refreshRate) +void _glfwSetWindowMonitorCocoa(_GLFWwindow* window, + _GLFWmonitor* monitor, + int xpos, int ypos, + int width, int height, + int refreshRate) { @autoreleasepool { @@ -1235,7 +1257,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, else { const NSRect contentRect = - NSMakeRect(xpos, _glfwTransformYNS(ypos + height - 1), width, height); + NSMakeRect(xpos, _glfwTransformYCocoa(ypos + height - 1), width, height); const NSUInteger styleMask = [window->ns.object styleMask]; const NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect @@ -1254,13 +1276,13 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, // HACK: Allow the state cached in Cocoa to catch up to reality // TODO: Solve this in a less terrible way - _glfwPlatformPollEvents(); + _glfwPollEventsCocoa(); NSUInteger styleMask = [window->ns.object styleMask]; if (window->monitor) { - styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable); + styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable); styleMask |= NSWindowStyleMaskBorderless; } else @@ -1290,7 +1312,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, } else { - NSRect contentRect = NSMakeRect(xpos, _glfwTransformYNS(ypos + height - 1), + NSRect contentRect = NSMakeRect(xpos, _glfwTransformYCocoa(ypos + height - 1), width, height); NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect styleMask:styleMask]; @@ -1345,28 +1367,28 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, } // autoreleasepool } -int _glfwPlatformWindowFocused(_GLFWwindow* window) +GLFWbool _glfwWindowFocusedCocoa(_GLFWwindow* window) { @autoreleasepool { return [window->ns.object isKeyWindow]; } // autoreleasepool } -int _glfwPlatformWindowIconified(_GLFWwindow* window) +GLFWbool _glfwWindowIconifiedCocoa(_GLFWwindow* window) { @autoreleasepool { return [window->ns.object isMiniaturized]; } // autoreleasepool } -int _glfwPlatformWindowVisible(_GLFWwindow* window) +GLFWbool _glfwWindowVisibleCocoa(_GLFWwindow* window) { @autoreleasepool { return [window->ns.object isVisible]; } // autoreleasepool } -int _glfwPlatformWindowMaximized(_GLFWwindow* window) +GLFWbool _glfwWindowMaximizedCocoa(_GLFWwindow* window) { @autoreleasepool { @@ -1378,7 +1400,7 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window) } // autoreleasepool } -int _glfwPlatformWindowHovered(_GLFWwindow* window) +GLFWbool _glfwWindowHoveredCocoa(_GLFWwindow* window) { @autoreleasepool { @@ -1396,14 +1418,14 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window) } // autoreleasepool } -int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) +GLFWbool _glfwFramebufferTransparentCocoa(_GLFWwindow* window) { @autoreleasepool { return ![window->ns.object isOpaque] && ![window->ns.view isOpaque]; } // autoreleasepool } -void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) +void _glfwSetWindowResizableCocoa(_GLFWwindow* window, GLFWbool enabled) { @autoreleasepool { @@ -1427,7 +1449,7 @@ void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) } // autoreleasepool } -void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) +void _glfwSetWindowDecoratedCocoa(_GLFWwindow* window, GLFWbool enabled) { @autoreleasepool { @@ -1449,7 +1471,7 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) } // autoreleasepool } -void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) +void _glfwSetWindowFloatingCocoa(_GLFWwindow* window, GLFWbool enabled) { @autoreleasepool { if (enabled) @@ -1459,36 +1481,42 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) } // autoreleasepool } -float _glfwPlatformGetWindowOpacity(_GLFWwindow* window) +void _glfwSetWindowMousePassthroughCocoa(_GLFWwindow* window, GLFWbool enabled) +{ + @autoreleasepool { + [window->ns.object setIgnoresMouseEvents:enabled]; + } +} + +float _glfwGetWindowOpacityCocoa(_GLFWwindow* window) { @autoreleasepool { return (float) [window->ns.object alphaValue]; } // autoreleasepool } -void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) +void _glfwSetWindowOpacityCocoa(_GLFWwindow* window, float opacity) { @autoreleasepool { [window->ns.object setAlphaValue:opacity]; } // autoreleasepool } -void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) +void _glfwSetRawMouseMotionCocoa(_GLFWwindow *window, GLFWbool enabled) { + _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, + "Cocoa: Raw mouse motion not yet implemented"); } -GLFWbool _glfwPlatformRawMouseMotionSupported(void) +GLFWbool _glfwRawMouseMotionSupportedCocoa(void) { return GLFW_FALSE; } -void _glfwPlatformPollEvents(void) +void _glfwPollEventsCocoa(void) { @autoreleasepool { - if (!_glfw.ns.finishedLaunching) - [NSApp run]; - for (;;) { NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny @@ -1504,13 +1532,10 @@ void _glfwPlatformPollEvents(void) } // autoreleasepool } -void _glfwPlatformWaitEvents(void) +void _glfwWaitEventsCocoa(void) { @autoreleasepool { - if (!_glfw.ns.finishedLaunching) - [NSApp run]; - // I wanted to pass NO to dequeue:, and rely on PollEvents to // dequeue and send. For reasons not at all clear to me, passing // NO to dequeue: causes this method never to return. @@ -1520,18 +1545,15 @@ void _glfwPlatformWaitEvents(void) dequeue:YES]; [NSApp sendEvent:event]; - _glfwPlatformPollEvents(); + _glfwPollEventsCocoa(); } // autoreleasepool } -void _glfwPlatformWaitEventsTimeout(double timeout) +void _glfwWaitEventsTimeoutCocoa(double timeout) { @autoreleasepool { - if (!_glfw.ns.finishedLaunching) - [NSApp run]; - NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout]; NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:date @@ -1540,18 +1562,15 @@ void _glfwPlatformWaitEventsTimeout(double timeout) if (event) [NSApp sendEvent:event]; - _glfwPlatformPollEvents(); + _glfwPollEventsCocoa(); } // autoreleasepool } -void _glfwPlatformPostEmptyEvent(void) +void _glfwPostEmptyEventCocoa(void) { @autoreleasepool { - if (!_glfw.ns.finishedLaunching) - [NSApp run]; - NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined location:NSMakePoint(0, 0) modifierFlags:0 @@ -1566,7 +1585,7 @@ void _glfwPlatformPostEmptyEvent(void) } // autoreleasepool } -void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) +void _glfwGetCursorPosCocoa(_GLFWwindow* window, double* xpos, double* ypos) { @autoreleasepool { @@ -1582,7 +1601,7 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) } // autoreleasepool } -void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) +void _glfwSetCursorPosCocoa(_GLFWwindow* window, double x, double y) { @autoreleasepool { @@ -1607,7 +1626,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) const NSPoint globalPoint = globalRect.origin; CGWarpMouseCursorPosition(CGPointMake(globalPoint.x, - _glfwTransformYNS(globalPoint.y))); + _glfwTransformYCocoa(globalPoint.y))); } // HACK: Calling this right after setting the cursor position prevents macOS @@ -1618,26 +1637,35 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) } // autoreleasepool } -void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) +void _glfwSetCursorModeCocoa(_GLFWwindow* window, int mode) { @autoreleasepool { - if (_glfwPlatformWindowFocused(window)) + + if (mode == GLFW_CURSOR_CAPTURED) + { + _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, + "Cocoa: Captured cursor mode not yet implemented"); + } + + if (_glfwWindowFocusedCocoa(window)) updateCursorMode(window); + } // autoreleasepool } -const char* _glfwPlatformGetScancodeName(int scancode) +const char* _glfwGetScancodeNameCocoa(int scancode) { @autoreleasepool { - if (scancode < 0 || scancode > 0xff || - _glfw.ns.keycodes[scancode] == GLFW_KEY_UNKNOWN) + if (scancode < 0 || scancode > 0xff) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode); return NULL; } const int key = _glfw.ns.keycodes[scancode]; + if (key == GLFW_KEY_UNKNOWN) + return NULL; UInt32 deadKeyState = 0; UniChar characters[4]; @@ -1675,14 +1703,14 @@ const char* _glfwPlatformGetScancodeName(int scancode) } // autoreleasepool } -int _glfwPlatformGetKeyScancode(int key) +int _glfwGetKeyScancodeCocoa(int key) { return _glfw.ns.scancodes[key]; } -int _glfwPlatformCreateCursor(_GLFWcursor* cursor, - const GLFWimage* image, - int xhot, int yhot) +GLFWbool _glfwCreateCursorCocoa(_GLFWcursor* cursor, + const GLFWimage* image, + int xhot, int yhot) { @autoreleasepool { @@ -1724,27 +1752,71 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, } // autoreleasepool } -int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) +GLFWbool _glfwCreateStandardCursorCocoa(_GLFWcursor* cursor, int shape) { @autoreleasepool { - if (shape == GLFW_ARROW_CURSOR) - cursor->ns.object = [NSCursor arrowCursor]; - else if (shape == GLFW_IBEAM_CURSOR) - cursor->ns.object = [NSCursor IBeamCursor]; - else if (shape == GLFW_CROSSHAIR_CURSOR) - cursor->ns.object = [NSCursor crosshairCursor]; - else if (shape == GLFW_HAND_CURSOR) - cursor->ns.object = [NSCursor pointingHandCursor]; - else if (shape == GLFW_HRESIZE_CURSOR) - cursor->ns.object = [NSCursor resizeLeftRightCursor]; - else if (shape == GLFW_VRESIZE_CURSOR) - cursor->ns.object = [NSCursor resizeUpDownCursor]; + SEL cursorSelector = NULL; + + // HACK: Try to use a private message + switch (shape) + { + case GLFW_RESIZE_EW_CURSOR: + cursorSelector = NSSelectorFromString(@"_windowResizeEastWestCursor"); + break; + case GLFW_RESIZE_NS_CURSOR: + cursorSelector = NSSelectorFromString(@"_windowResizeNorthSouthCursor"); + break; + case GLFW_RESIZE_NWSE_CURSOR: + cursorSelector = NSSelectorFromString(@"_windowResizeNorthWestSouthEastCursor"); + break; + case GLFW_RESIZE_NESW_CURSOR: + cursorSelector = NSSelectorFromString(@"_windowResizeNorthEastSouthWestCursor"); + break; + } + + if (cursorSelector && [NSCursor respondsToSelector:cursorSelector]) + { + id object = [NSCursor performSelector:cursorSelector]; + if ([object isKindOfClass:[NSCursor class]]) + cursor->ns.object = object; + } if (!cursor->ns.object) { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Cocoa: Failed to retrieve standard cursor"); + switch (shape) + { + case GLFW_ARROW_CURSOR: + cursor->ns.object = [NSCursor arrowCursor]; + break; + case GLFW_IBEAM_CURSOR: + cursor->ns.object = [NSCursor IBeamCursor]; + break; + case GLFW_CROSSHAIR_CURSOR: + cursor->ns.object = [NSCursor crosshairCursor]; + break; + case GLFW_POINTING_HAND_CURSOR: + cursor->ns.object = [NSCursor pointingHandCursor]; + break; + case GLFW_RESIZE_EW_CURSOR: + cursor->ns.object = [NSCursor resizeLeftRightCursor]; + break; + case GLFW_RESIZE_NS_CURSOR: + cursor->ns.object = [NSCursor resizeUpDownCursor]; + break; + case GLFW_RESIZE_ALL_CURSOR: + cursor->ns.object = [NSCursor closedHandCursor]; + break; + case GLFW_NOT_ALLOWED_CURSOR: + cursor->ns.object = [NSCursor operationNotAllowedCursor]; + break; + } + } + + if (!cursor->ns.object) + { + _glfwInputError(GLFW_CURSOR_UNAVAILABLE, + "Cocoa: Standard cursor shape unavailable"); return GLFW_FALSE; } @@ -1754,7 +1826,7 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) } // autoreleasepool } -void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) +void _glfwDestroyCursorCocoa(_GLFWcursor* cursor) { @autoreleasepool { if (cursor->ns.object) @@ -1762,7 +1834,7 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) } // autoreleasepool } -void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) +void _glfwSetCursorCocoa(_GLFWwindow* window, _GLFWcursor* cursor) { @autoreleasepool { if (cursorInContentArea(window)) @@ -1770,7 +1842,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) } // autoreleasepool } -void _glfwPlatformSetClipboardString(const char* string) +void _glfwSetClipboardStringCocoa(const char* string) { @autoreleasepool { NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; @@ -1779,7 +1851,7 @@ void _glfwPlatformSetClipboardString(const char* string) } // autoreleasepool } -const char* _glfwPlatformGetClipboardString(void) +const char* _glfwGetClipboardStringCocoa(void) { @autoreleasepool { @@ -1800,7 +1872,7 @@ const char* _glfwPlatformGetClipboardString(void) return NULL; } - free(_glfw.ns.clipboardString); + _glfw_free(_glfw.ns.clipboardString); _glfw.ns.clipboardString = _glfw_strdup([object UTF8String]); return _glfw.ns.clipboardString; @@ -1808,7 +1880,48 @@ const char* _glfwPlatformGetClipboardString(void) } // autoreleasepool } -void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) +EGLenum _glfwGetEGLPlatformCocoa(EGLint** attribs) +{ + if (_glfw.egl.ANGLE_platform_angle) + { + int type = 0; + + if (_glfw.egl.ANGLE_platform_angle_opengl) + { + if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGL) + type = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE; + } + + if (_glfw.egl.ANGLE_platform_angle_metal) + { + if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_METAL) + type = EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE; + } + + if (type) + { + *attribs = _glfw_calloc(3, sizeof(EGLint)); + (*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE; + (*attribs)[1] = type; + (*attribs)[2] = EGL_NONE; + return EGL_PLATFORM_ANGLE_ANGLE; + } + } + + return 0; +} + +EGLNativeDisplayType _glfwGetEGLNativeDisplayCocoa(void) +{ + return EGL_DEFAULT_DISPLAY; +} + +EGLNativeWindowType _glfwGetEGLNativeWindowCocoa(_GLFWwindow* window) +{ + return window->ns.layer; +} + +void _glfwGetRequiredInstanceExtensionsCocoa(char** extensions) { if (_glfw.vk.KHR_surface && _glfw.vk.EXT_metal_surface) { @@ -1822,17 +1935,17 @@ void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) } } -int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, - VkPhysicalDevice device, - uint32_t queuefamily) +GLFWbool _glfwGetPhysicalDevicePresentationSupportCocoa(VkInstance instance, + VkPhysicalDevice device, + uint32_t queuefamily) { return GLFW_TRUE; } -VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, - _GLFWwindow* window, - const VkAllocationCallbacks* allocator, - VkSurfaceKHR* surface) +VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, + _GLFWwindow* window, + const VkAllocationCallbacks* allocator, + VkSurfaceKHR* surface) { @autoreleasepool { @@ -1856,7 +1969,7 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, return VK_ERROR_EXTENSION_NOT_PRESENT; } - if (window->ns.retina) + if (window->ns.scaleFramebuffer) [window->ns.layer setContentsScale:[window->ns.object backingScaleFactor]]; [window->ns.view setLayer:window->ns.layer]; @@ -1929,6 +2042,31 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(nil); + + if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, + "Cocoa: Platform not initialized"); + return nil; + } + return window->ns.object; } +GLFWAPI id glfwGetCocoaView(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(nil); + + if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, + "Cocoa: Platform not initialized"); + return nil; + } + + return window->ns.view; +} + +#endif // _GLFW_COCOA + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/context.c b/src/lib/src/vendor/glfw-3.4/src/context.c similarity index 98% rename from src/lib/src/vendor/glfw-3.3.8/src/context.c rename to src/lib/src/vendor/glfw-3.4/src/context.c index d86e0fa..cc1fac4 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/context.c +++ b/src/lib/src/vendor/glfw-3.4/src/context.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 - www.glfw.org +// GLFW 3.4 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2016 Camilla Löwy @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" @@ -48,16 +46,6 @@ // GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig) { - if (ctxconfig->share) - { - if (ctxconfig->client == GLFW_NO_API || - ctxconfig->share->context.client == GLFW_NO_API) - { - _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); - return GLFW_FALSE; - } - } - if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API && ctxconfig->source != GLFW_EGL_CONTEXT_API && ctxconfig->source != GLFW_OSMESA_CONTEXT_API) @@ -78,6 +66,23 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig) 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) || @@ -356,6 +361,8 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window, previous = _glfwPlatformGetTls(&_glfw.contextSlot); glfwMakeContextCurrent((GLFWwindow*) window); + if (_glfwPlatformGetTls(&_glfw.contextSlot) != window) + return GLFW_FALSE; window->context.GetIntegerv = (PFNGLGETINTEGERVPROC) window->context.getProcAddress("glGetIntegerv"); diff --git a/src/lib/src/vendor/glfw-3.3.8/src/egl_context.c b/src/lib/src/vendor/glfw-3.4/src/egl_context.c similarity index 71% rename from src/lib/src/vendor/glfw-3.3.8/src/egl_context.c rename to src/lib/src/vendor/glfw-3.4/src/egl_context.c index 58d9557..ef65dd3 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/egl_context.c +++ b/src/lib/src/vendor/glfw-3.4/src/egl_context.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 EGL - www.glfw.org +// GLFW 3.4 EGL - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" @@ -88,13 +86,30 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib) // Return the EGLConfig most closely matching the specified hints // static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* desired, + const _GLFWfbconfig* fbconfig, EGLConfig* result) { EGLConfig* nativeConfigs; _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; - int i, nativeCount, usableCount; + 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) @@ -103,10 +118,10 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, return GLFW_FALSE; } - nativeConfigs = calloc(nativeCount, sizeof(EGLConfig)); + nativeConfigs = _glfw_calloc(nativeCount, sizeof(EGLConfig)); eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount); - usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); + usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig)); usableCount = 0; for (i = 0; i < nativeCount; i++) @@ -123,6 +138,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, continue; #if defined(_GLFW_X11) + if (_glfw.platform.platformID == GLFW_PLATFORM_X11) { XVisualInfo vi = {0}; @@ -131,7 +147,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, if (!vi.visualid) continue; - if (desired->transparent) + if (fbconfig->transparent) { int count; XVisualInfo* vis = @@ -145,23 +161,10 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, } #endif // _GLFW_X11 - if (ctxconfig->client == GLFW_OPENGL_ES_API) + if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & apiBit)) { - if (ctxconfig->major == 1) - { - if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT)) - continue; - } - else - { - if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT)) - continue; - } - } - else if (ctxconfig->client == GLFW_OPENGL_API) - { - if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT)) - continue; + wrongApiAvailable = GLFW_TRUE; + continue; } u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE); @@ -172,19 +175,63 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, 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 = desired->doublebuffer; + u->doublebuffer = fbconfig->doublebuffer; u->handle = (uintptr_t) n; usableCount++; } - closest = _glfwChooseFBConfig(desired, usableConfigs, 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"); + } + } - free(nativeConfigs); - free(usableConfigs); + _glfw_free(nativeConfigs); + _glfw_free(usableConfigs); return closest != NULL; } @@ -231,9 +278,12 @@ static void swapBuffersEGL(_GLFWwindow* window) } #if defined(_GLFW_WAYLAND) - // NOTE: Swapping buffers on a hidden window on Wayland makes it visible - if (!window->wl.visible) - return; + 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); @@ -259,11 +309,12 @@ static int extensionSupportedEGL(const char* extension) static GLFWglproc getProcAddressEGL(const char* procname) { _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); + assert(window != NULL); if (window->context.egl.client) { - GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client, - procname); + GLFWglproc proc = (GLFWglproc) + _glfwPlatformGetModuleSymbol(window->context.egl.client, procname); if (proc) return proc; } @@ -273,15 +324,14 @@ static GLFWglproc getProcAddressEGL(const char* procname) static void destroyContextEGL(_GLFWwindow* window) { -#if defined(_GLFW_X11) // NOTE: Do not unload libGL.so.1 while the X11 display is still open, // as it will make XCloseDisplay segfault - if (window->context.client != GLFW_OPENGL_API) -#endif // _GLFW_X11 + if (_glfw.platform.platformID != GLFW_PLATFORM_X11 || + window->context.client != GLFW_OPENGL_API) { if (window->context.egl.client) { - _glfw_dlclose(window->context.egl.client); + _glfwPlatformFreeModule(window->context.egl.client); window->context.egl.client = NULL; } } @@ -309,6 +359,8 @@ static void destroyContextEGL(_GLFWwindow* window) GLFWbool _glfwInitEGL(void) { int i; + EGLint* attribs = NULL; + const char* extensions; const char* sonames[] = { #if defined(_GLFW_EGL_LIBRARY) @@ -333,7 +385,7 @@ GLFWbool _glfwInitEGL(void) for (i = 0; sonames[i]; i++) { - _glfw.egl.handle = _glfw_dlopen(sonames[i]); + _glfw.egl.handle = _glfwPlatformLoadModule(sonames[i]); if (_glfw.egl.handle) break; } @@ -347,37 +399,37 @@ GLFWbool _glfwInitEGL(void) _glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0); _glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib) - _glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetConfigAttrib"); _glfw.egl.GetConfigs = (PFN_eglGetConfigs) - _glfw_dlsym(_glfw.egl.handle, "eglGetConfigs"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetConfigs"); _glfw.egl.GetDisplay = (PFN_eglGetDisplay) - _glfw_dlsym(_glfw.egl.handle, "eglGetDisplay"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetDisplay"); _glfw.egl.GetError = (PFN_eglGetError) - _glfw_dlsym(_glfw.egl.handle, "eglGetError"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetError"); _glfw.egl.Initialize = (PFN_eglInitialize) - _glfw_dlsym(_glfw.egl.handle, "eglInitialize"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglInitialize"); _glfw.egl.Terminate = (PFN_eglTerminate) - _glfw_dlsym(_glfw.egl.handle, "eglTerminate"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglTerminate"); _glfw.egl.BindAPI = (PFN_eglBindAPI) - _glfw_dlsym(_glfw.egl.handle, "eglBindAPI"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglBindAPI"); _glfw.egl.CreateContext = (PFN_eglCreateContext) - _glfw_dlsym(_glfw.egl.handle, "eglCreateContext"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateContext"); _glfw.egl.DestroySurface = (PFN_eglDestroySurface) - _glfw_dlsym(_glfw.egl.handle, "eglDestroySurface"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroySurface"); _glfw.egl.DestroyContext = (PFN_eglDestroyContext) - _glfw_dlsym(_glfw.egl.handle, "eglDestroyContext"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroyContext"); _glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface) - _glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateWindowSurface"); _glfw.egl.MakeCurrent = (PFN_eglMakeCurrent) - _glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglMakeCurrent"); _glfw.egl.SwapBuffers = (PFN_eglSwapBuffers) - _glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglSwapBuffers"); _glfw.egl.SwapInterval = (PFN_eglSwapInterval) - _glfw_dlsym(_glfw.egl.handle, "eglSwapInterval"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglSwapInterval"); _glfw.egl.QueryString = (PFN_eglQueryString) - _glfw_dlsym(_glfw.egl.handle, "eglQueryString"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglQueryString"); _glfw.egl.GetProcAddress = (PFN_eglGetProcAddress) - _glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress"); + _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetProcAddress"); if (!_glfw.egl.GetConfigAttrib || !_glfw.egl.GetConfigs || @@ -403,7 +455,51 @@ GLFWbool _glfwInitEGL(void) return GLFW_FALSE; } - _glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY); + 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, @@ -452,12 +548,12 @@ void _glfwTerminateEGL(void) if (_glfw.egl.handle) { - _glfw_dlclose(_glfw.egl.handle); + _glfwPlatformFreeModule(_glfw.egl.handle); _glfw.egl.handle = NULL; } } -#define setAttrib(a, v) \ +#define SET_ATTRIB(a, v) \ { \ assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ attribs[index++] = a; \ @@ -473,6 +569,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, EGLint attribs[40]; EGLConfig config; EGLContext share = NULL; + EGLNativeWindowType native; int index = 0; if (!_glfw.egl.display) @@ -485,11 +582,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, share = ctxconfig->share->context.egl.handle; if (!chooseEGLConfig(ctxconfig, fbconfig, &config)) - { - _glfwInputError(GLFW_FORMAT_UNAVAILABLE, - "EGL: Failed to find a suitable EGLConfig"); return GLFW_FALSE; - } if (ctxconfig->client == GLFW_OPENGL_ES_API) { @@ -534,57 +627,57 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, { if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) { - setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, - EGL_NO_RESET_NOTIFICATION_KHR); + SET_ATTRIB(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, + EGL_NO_RESET_NOTIFICATION_KHR); } else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) { - setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, - EGL_LOSE_CONTEXT_ON_RESET_KHR); + 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) - setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE); - } - - if (ctxconfig->major != 1 || ctxconfig->minor != 0) - { - setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major); - setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor); + SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE); } if (mask) - setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask); + SET_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask); if (flags) - setAttrib(EGL_CONTEXT_FLAGS_KHR, flags); + SET_ATTRIB(EGL_CONTEXT_FLAGS_KHR, flags); } else { if (ctxconfig->client == GLFW_OPENGL_ES_API) - setAttrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major); + SET_ATTRIB(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major); } if (_glfw.egl.KHR_context_flush_control) { if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) { - setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, - EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR); + SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, + EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR); } else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) { - setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, - EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR); + SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, + EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR); } } - setAttrib(EGL_NONE, EGL_NONE); + SET_ATTRIB(EGL_NONE, EGL_NONE); window->context.egl.handle = eglCreateContext(_glfw.egl.display, config, share, attribs); @@ -603,22 +696,34 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, if (fbconfig->sRGB) { if (_glfw.egl.KHR_gl_colorspace) - setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR); + SET_ATTRIB(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR); } if (!fbconfig->doublebuffer) - setAttrib(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER); + SET_ATTRIB(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER); - if (_glfw.egl.EXT_present_opaque) - setAttrib(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent); + if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND) + { + if (_glfw.egl.EXT_present_opaque) + SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent); + } - setAttrib(EGL_NONE, EGL_NONE); + 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); + } - window->context.egl.surface = - eglCreateWindowSurface(_glfw.egl.display, - config, - _GLFW_EGL_NATIVE_WINDOW, - attribs); if (window->context.egl.surface == EGL_NO_SURFACE) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -678,6 +783,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, #elif defined(__OpenBSD__) || defined(__NetBSD__) "libGL.so", #else + "libOpenGL.so.0", "libGL.so.1", #endif NULL @@ -700,7 +806,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0)) continue; - window->context.egl.client = _glfw_dlopen(sonames[i]); + window->context.egl.client = _glfwPlatformLoadModule(sonames[i]); if (window->context.egl.client) break; } @@ -723,7 +829,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, return GLFW_TRUE; } -#undef setAttrib +#undef SET_ATTRIB // Returns the Visual and depth of the chosen EGLConfig // @@ -740,11 +846,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, const long vimask = VisualScreenMask | VisualIDMask; if (!chooseEGLConfig(ctxconfig, fbconfig, &native)) - { - _glfwInputError(GLFW_FORMAT_UNAVAILABLE, - "EGL: Failed to find a suitable EGLConfig"); return GLFW_FALSE; - } eglGetConfigAttrib(_glfw.egl.display, native, EGL_NATIVE_VISUAL_ID, &visualID); diff --git a/src/lib/src/vendor/glfw-3.4/src/glfw.rc.in b/src/lib/src/vendor/glfw-3.4/src/glfw.rc.in new file mode 100644 index 0000000..ac3460a --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/glfw.rc.in @@ -0,0 +1,30 @@ + +#include + +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 + } +} + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/glx_context.c b/src/lib/src/vendor/glfw-3.4/src/glx_context.c similarity index 83% rename from src/lib/src/vendor/glfw-3.3.8/src/glx_context.c rename to src/lib/src/vendor/glfw-3.4/src/glx_context.c index 1b1b3f9..7082682 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/glx_context.c +++ b/src/lib/src/vendor/glfw-3.4/src/glx_context.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 GLX - www.glfw.org +// GLFW 3.4 GLX - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_X11) + #include #include #include @@ -55,7 +55,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* nativeConfigs; _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; - int i, nativeCount, usableCount; + int nativeCount, usableCount; const char* vendor; GLFWbool trustWindowBit = GLFW_TRUE; @@ -73,10 +73,10 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, return GLFW_FALSE; } - usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); + usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig)); usableCount = 0; - for (i = 0; i < nativeCount; i++) + for (int i = 0; i < nativeCount; i++) { const GLXFBConfig n = nativeConfigs[i]; _GLFWfbconfig* u = usableConfigs + usableCount; @@ -138,7 +138,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, *result = (GLXFBConfig) closest->handle; XFree(nativeConfigs); - free(usableConfigs); + _glfw_free(usableConfigs); return closest != NULL; } @@ -190,6 +190,7 @@ static void swapBuffersGLX(_GLFWwindow* window) static void swapIntervalGLX(int interval) { _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); + assert(window != NULL); if (_glfw.glx.EXT_swap_control) { @@ -226,7 +227,10 @@ static GLFWglproc getProcAddressGLX(const char* procname) else if (_glfw.glx.GetProcAddressARB) return _glfw.glx.GetProcAddressARB((const GLubyte*) procname); else - return _glfw_dlsym(_glfw.glx.handle, procname); + { + // NOTE: glvnd provides GLX 1.4, so this can only happen with libGL + return _glfwPlatformGetModuleSymbol(_glfw.glx.handle, procname); + } } static void destroyContextGLX(_GLFWwindow* window) @@ -253,7 +257,6 @@ static void destroyContextGLX(_GLFWwindow* window) // GLFWbool _glfwInitGLX(void) { - int i; const char* sonames[] = { #if defined(_GLFW_GLX_LIBRARY) @@ -263,6 +266,7 @@ GLFWbool _glfwInitGLX(void) #elif defined(__OpenBSD__) || defined(__NetBSD__) "libGL.so", #else + "libGLX.so.0", "libGL.so.1", "libGL.so", #endif @@ -272,9 +276,9 @@ GLFWbool _glfwInitGLX(void) if (_glfw.glx.handle) return GLFW_TRUE; - for (i = 0; sonames[i]; i++) + for (int i = 0; sonames[i]; i++) { - _glfw.glx.handle = _glfw_dlopen(sonames[i]); + _glfw.glx.handle = _glfwPlatformLoadModule(sonames[i]); if (_glfw.glx.handle) break; } @@ -285,32 +289,32 @@ GLFWbool _glfwInitGLX(void) return GLFW_FALSE; } - _glfw.glx.GetFBConfigs = - _glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigs"); - _glfw.glx.GetFBConfigAttrib = - _glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigAttrib"); - _glfw.glx.GetClientString = - _glfw_dlsym(_glfw.glx.handle, "glXGetClientString"); - _glfw.glx.QueryExtension = - _glfw_dlsym(_glfw.glx.handle, "glXQueryExtension"); - _glfw.glx.QueryVersion = - _glfw_dlsym(_glfw.glx.handle, "glXQueryVersion"); - _glfw.glx.DestroyContext = - _glfw_dlsym(_glfw.glx.handle, "glXDestroyContext"); - _glfw.glx.MakeCurrent = - _glfw_dlsym(_glfw.glx.handle, "glXMakeCurrent"); - _glfw.glx.SwapBuffers = - _glfw_dlsym(_glfw.glx.handle, "glXSwapBuffers"); - _glfw.glx.QueryExtensionsString = - _glfw_dlsym(_glfw.glx.handle, "glXQueryExtensionsString"); - _glfw.glx.CreateNewContext = - _glfw_dlsym(_glfw.glx.handle, "glXCreateNewContext"); - _glfw.glx.CreateWindow = - _glfw_dlsym(_glfw.glx.handle, "glXCreateWindow"); - _glfw.glx.DestroyWindow = - _glfw_dlsym(_glfw.glx.handle, "glXDestroyWindow"); - _glfw.glx.GetVisualFromFBConfig = - _glfw_dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig"); + _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 || @@ -333,9 +337,9 @@ GLFWbool _glfwInitGLX(void) // NOTE: Unlike GLX 1.3 entry points these are not required to be present _glfw.glx.GetProcAddress = (PFNGLXGETPROCADDRESSPROC) - _glfw_dlsym(_glfw.glx.handle, "glXGetProcAddress"); + _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddress"); _glfw.glx.GetProcAddressARB = (PFNGLXGETPROCADDRESSPROC) - _glfw_dlsym(_glfw.glx.handle, "glXGetProcAddressARB"); + _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddressARB"); if (!glXQueryExtension(_glfw.x11.display, &_glfw.glx.errorBase, @@ -427,16 +431,16 @@ GLFWbool _glfwInitGLX(void) void _glfwTerminateGLX(void) { // NOTE: This function must not call any X11 functions, as it is called - // after XCloseDisplay (see _glfwPlatformTerminate for details) + // after XCloseDisplay (see _glfwTerminateX11 for details) if (_glfw.glx.handle) { - _glfw_dlclose(_glfw.glx.handle); + _glfwPlatformFreeModule(_glfw.glx.handle); _glfw.glx.handle = NULL; } } -#define setAttrib(a, v) \ +#define SET_ATTRIB(a, v) \ { \ assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ attribs[index++] = a; \ @@ -524,13 +528,13 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, { if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) { - setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, - GLX_NO_RESET_NOTIFICATION_ARB); + SET_ATTRIB(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, + GLX_NO_RESET_NOTIFICATION_ARB); } else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) { - setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, - GLX_LOSE_CONTEXT_ON_RESET_ARB); + SET_ATTRIB(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, + GLX_LOSE_CONTEXT_ON_RESET_ARB); } flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB; @@ -543,13 +547,13 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, { if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) { - setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, - GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); + SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, + GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); } else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) { - setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, - GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); + SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, + GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); } } } @@ -557,7 +561,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, if (ctxconfig->noerror) { if (_glfw.glx.ARB_create_context_no_error) - setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE); + SET_ATTRIB(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE); } // NOTE: Only request an explicitly versioned context when necessary, as @@ -565,17 +569,17 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, // highest version supported by the driver if (ctxconfig->major != 1 || ctxconfig->minor != 0) { - setAttrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); - setAttrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); + SET_ATTRIB(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); + SET_ATTRIB(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); } if (mask) - setAttrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask); + SET_ATTRIB(GLX_CONTEXT_PROFILE_MASK_ARB, mask); if (flags) - setAttrib(GLX_CONTEXT_FLAGS_ARB, flags); + SET_ATTRIB(GLX_CONTEXT_FLAGS_ARB, flags); - setAttrib(None, None); + SET_ATTRIB(None, None); window->context.glx.handle = _glfw.glx.CreateContextAttribsARB(_glfw.x11.display, @@ -632,7 +636,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, return GLFW_TRUE; } -#undef setAttrib +#undef SET_ATTRIB // Returns the Visual and depth of the chosen GLXFBConfig // @@ -676,6 +680,12 @@ 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); @@ -690,6 +700,12 @@ 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); @@ -699,3 +715,5 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle) return window->context.glx.window; } +#endif // _GLFW_X11 + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/init.c b/src/lib/src/vendor/glfw-3.4/src/init.c similarity index 69% rename from src/lib/src/vendor/glfw-3.3.8/src/init.c rename to src/lib/src/vendor/glfw-3.4/src/init.c index cfdd512..532264e 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/init.c +++ b/src/lib/src/vendor/glfw-3.4/src/init.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 - www.glfw.org +// GLFW 3.4 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2018 Camilla Löwy @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" @@ -48,15 +46,49 @@ _GLFWlibrary _glfw = { GLFW_FALSE }; // static _GLFWerror _glfwMainThreadError; static GLFWerrorfun _glfwErrorCallback; +static GLFWallocator _glfwInitAllocator; static _GLFWinitconfig _glfwInitHints = { - GLFW_TRUE, // hat buttons + .hatButtons = GLFW_TRUE, + .angleType = GLFW_ANGLE_PLATFORM_TYPE_NONE, + .platformID = GLFW_ANY_PLATFORM, + .vulkanLoader = NULL, + .ns = { - GLFW_TRUE, // macOS menu bar - GLFW_TRUE // macOS bundle chdir - } + .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) @@ -75,20 +107,21 @@ static void terminate(void) { _GLFWmonitor* monitor = _glfw.monitors[i]; if (monitor->originalRamp.size) - _glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp); + _glfw.platform.setGammaRamp(monitor, &monitor->originalRamp); _glfwFreeMonitor(monitor); } - free(_glfw.monitors); + _glfw_free(_glfw.monitors); _glfw.monitors = NULL; _glfw.monitorCount = 0; - free(_glfw.mappings); + _glfw_free(_glfw.mappings); _glfw.mappings = NULL; _glfw.mappingCount = 0; _glfwTerminateVulkan(); - _glfwPlatformTerminate(); + _glfw.platform.terminateJoysticks(); + _glfw.platform.terminate(); _glfw.initialized = GLFW_FALSE; @@ -96,7 +129,7 @@ static void terminate(void) { _GLFWerror* error = _glfw.errorListHead; _glfw.errorListHead = error->next; - free(error); + _glfw_free(error); } _glfwPlatformDestroyTls(&_glfw.contextSlot); @@ -172,8 +205,8 @@ char** _glfwParseUriList(char* text, int* count) (*count)++; - path = calloc(strlen(line) + 1, 1); - paths = realloc(paths, *count * sizeof(char*)); + path = _glfw_calloc(strlen(line) + 1, 1); + paths = _glfw_realloc(paths, *count * sizeof(char*)); paths[*count - 1] = path; while (*line) @@ -198,7 +231,7 @@ char** _glfwParseUriList(char* text, int* count) char* _glfw_strdup(const char* source) { const size_t length = strlen(source); - char* result = calloc(length + 1, 1); + char* result = _glfw_calloc(length + 1, 1); strcpy(result, source); return result; } @@ -213,28 +246,57 @@ int _glfw_max(int a, int b) return a > b ? a : b; } -float _glfw_fminf(float a, float b) +void* _glfw_calloc(size_t count, size_t size) { - if (a != a) - return b; - else if (b != b) - return a; - else if (a < b) - return a; + 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 b; + return NULL; } -float _glfw_fmaxf(float a, float b) +void* _glfw_realloc(void* block, size_t size) { - if (a != a) - return b; - else if (b != b) - return a; - else if (a > b) - return a; + 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 b; + return _glfw_calloc(1, size); +} + +void _glfw_free(void* block) +{ + if (block) + _glfw.allocator.deallocate(block, _glfw.allocator.user); } @@ -281,6 +343,14 @@ void _glfwInputError(int code, const char* format, ...) 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"); } @@ -290,7 +360,7 @@ void _glfwInputError(int code, const char* format, ...) error = _glfwPlatformGetTls(&_glfw.errorSlot); if (!error) { - error = calloc(1, sizeof(_GLFWerror)); + error = _glfw_calloc(1, sizeof(_GLFWerror)); _glfwPlatformSetTls(&_glfw.errorSlot, error); _glfwPlatformLockMutex(&_glfw.errorLock); error->next = _glfw.errorListHead; @@ -321,7 +391,18 @@ GLFWAPI int glfwInit(void) memset(&_glfw, 0, sizeof(_glfw)); _glfw.hints.init = _glfwInitHints; - if (!_glfwPlatformInit()) + _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; @@ -339,9 +420,11 @@ GLFWAPI int glfwInit(void) _glfwInitGamepadMappings(); - _glfw.initialized = GLFW_TRUE; + _glfwPlatformInitTimer(); _glfw.timer.offset = _glfwPlatformGetTimerValue(); + _glfw.initialized = GLFW_TRUE; + glfwDefaultWindowHints(); return GLFW_TRUE; } @@ -361,18 +444,48 @@ GLFWAPI void glfwInitHint(int hint, int value) 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) @@ -383,11 +496,6 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev) *rev = GLFW_VERSION_REVISION; } -GLFWAPI const char* glfwGetVersionString(void) -{ - return _glfwPlatformGetVersionString(); -} - GLFWAPI int glfwGetError(const char** description) { _GLFWerror* error; @@ -414,7 +522,7 @@ GLFWAPI int glfwGetError(const char** description) GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun) { - _GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun); + _GLFW_SWAP(GLFWerrorfun, _glfwErrorCallback, cbfun); return cbfun; } diff --git a/src/lib/src/vendor/glfw-3.3.8/src/input.c b/src/lib/src/vendor/glfw-3.4/src/input.c similarity index 78% rename from src/lib/src/vendor/glfw-3.3.8/src/input.c rename to src/lib/src/vendor/glfw-3.4/src/input.c index 7ea1222..7b3b340 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/input.c +++ b/src/lib/src/vendor/glfw-3.4/src/input.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 - www.glfw.org +// GLFW 3.4 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" #include "mappings.h" @@ -44,6 +42,29 @@ #define _GLFW_JOYSTICK_BUTTON 2 #define _GLFW_JOYSTICK_HATBIT 3 +#define GLFW_MOD_MASK (GLFW_MOD_SHIFT | \ + GLFW_MOD_CONTROL | \ + GLFW_MOD_ALT | \ + GLFW_MOD_SUPER | \ + GLFW_MOD_CAPS_LOCK | \ + GLFW_MOD_NUM_LOCK) + +// Initializes the platform joystick API if it has not been already +// +static GLFWbool initJoysticks(void) +{ + if (!_glfw.joysticksInitialized) + { + if (!_glfw.platform.initJoysticks()) + { + _glfw.platform.terminateJoysticks(); + return GLFW_FALSE; + } + } + + return _glfw.joysticksInitialized = GLFW_TRUE; +} + // Finds a mapping based on joystick GUID // static _GLFWmapping* findMapping(const char* guid) @@ -218,8 +239,9 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string) } else { - length = strlen(_GLFW_PLATFORM_MAPPING_NAME); - if (strncmp(c, _GLFW_PLATFORM_MAPPING_NAME, length) != 0) + const char* name = _glfw.platform.getMappingName(); + length = strlen(name); + if (strncmp(c, name, length) != 0) return GLFW_FALSE; } @@ -236,7 +258,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string) mapping->guid[i] += 'a' - 'A'; } - _glfwPlatformUpdateGamepadGUID(mapping->guid); + _glfw.platform.updateGamepadGUID(mapping->guid); return GLFW_TRUE; } @@ -249,6 +271,12 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string) // void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods) { + assert(window != NULL); + assert(key >= 0 || key == GLFW_KEY_UNKNOWN); + assert(key <= GLFW_KEY_LAST); + assert(action == GLFW_PRESS || action == GLFW_RELEASE); + assert(mods == (mods & GLFW_MOD_MASK)); + if (key >= 0 && key <= GLFW_KEY_LAST) { GLFWbool repeated = GLFW_FALSE; @@ -280,6 +308,10 @@ void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int m // void _glfwInputChar(_GLFWwindow* window, uint32_t codepoint, int mods, GLFWbool plain) { + assert(window != NULL); + assert(mods == (mods & GLFW_MOD_MASK)); + assert(plain == GLFW_TRUE || plain == GLFW_FALSE); + if (codepoint < 32 || (codepoint > 126 && codepoint < 160)) return; @@ -300,6 +332,12 @@ void _glfwInputChar(_GLFWwindow* window, uint32_t codepoint, int mods, GLFWbool // void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset) { + assert(window != NULL); + assert(xoffset > -FLT_MAX); + assert(xoffset < FLT_MAX); + assert(yoffset > -FLT_MAX); + assert(yoffset < FLT_MAX); + if (window->callbacks.scroll) window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset); } @@ -308,6 +346,12 @@ void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset) // void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods) { + assert(window != NULL); + assert(button >= 0); + assert(button <= GLFW_MOUSE_BUTTON_LAST); + assert(action == GLFW_PRESS || action == GLFW_RELEASE); + assert(mods == (mods & GLFW_MOD_MASK)); + if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) return; @@ -328,6 +372,12 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods) // void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos) { + assert(window != NULL); + assert(xpos > -FLT_MAX); + assert(xpos < FLT_MAX); + assert(ypos > -FLT_MAX); + assert(ypos < FLT_MAX); + if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos) return; @@ -342,6 +392,9 @@ void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos) // void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered) { + assert(window != NULL); + assert(entered == GLFW_TRUE || entered == GLFW_FALSE); + if (window->callbacks.cursorEnter) window->callbacks.cursorEnter((GLFWwindow*) window, entered); } @@ -350,6 +403,10 @@ void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered) // void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths) { + assert(window != NULL); + assert(count > 0); + assert(paths != NULL); + if (window->callbacks.drop) window->callbacks.drop((GLFWwindow*) window, count, paths); } @@ -358,7 +415,8 @@ void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths) // void _glfwInputJoystick(_GLFWjoystick* js, int event) { - const int jid = (int) (js - _glfw.joysticks); + assert(js != NULL); + assert(event == GLFW_CONNECTED || event == GLFW_DISCONNECTED); if (event == GLFW_CONNECTED) js->connected = GLFW_TRUE; @@ -366,13 +424,17 @@ void _glfwInputJoystick(_GLFWjoystick* js, int event) js->connected = GLFW_FALSE; if (_glfw.callbacks.joystick) - _glfw.callbacks.joystick(jid, event); + _glfw.callbacks.joystick((int) (js - _glfw.joysticks), event); } // Notifies shared code of the new value of a joystick axis // void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value) { + assert(js != NULL); + assert(axis >= 0); + assert(axis < js->axisCount); + js->axes[axis] = value; } @@ -380,6 +442,11 @@ void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value) // void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value) { + assert(js != NULL); + assert(button >= 0); + assert(button < js->buttonCount); + assert(value == GLFW_PRESS || value == GLFW_RELEASE); + js->buttons[button] = value; } @@ -387,7 +454,19 @@ void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value) // void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value) { - const int base = js->buttonCount + hat * 4; + int base; + + assert(js != NULL); + assert(hat >= 0); + assert(hat < js->hatCount); + + // Valid hat values only use the least significant nibble + assert((value & 0xf0) == 0); + // Valid hat values do not have both bits of an axis set + assert((value & GLFW_HAT_LEFT) == 0 || (value & GLFW_HAT_RIGHT) == 0); + assert((value & GLFW_HAT_UP) == 0 || (value & GLFW_HAT_DOWN) == 0); + + base = js->buttonCount + hat * 4; js->buttons[base + 0] = (value & 0x01) ? GLFW_PRESS : GLFW_RELEASE; js->buttons[base + 1] = (value & 0x02) ? GLFW_PRESS : GLFW_RELEASE; @@ -406,23 +485,15 @@ void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value) // void _glfwInitGamepadMappings(void) { - int jid; size_t i; const size_t count = sizeof(_glfwDefaultMappings) / sizeof(char*); - _glfw.mappings = calloc(count, sizeof(_GLFWmapping)); + _glfw.mappings = _glfw_calloc(count, sizeof(_GLFWmapping)); for (i = 0; i < count; i++) { if (parseMapping(&_glfw.mappings[_glfw.mappingCount], _glfwDefaultMappings[i])) _glfw.mappingCount++; } - - for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) - { - _GLFWjoystick* js = _glfw.joysticks + jid; - if (js->connected) - js->mapping = findValidMapping(js); - } } // Returns an available joystick object with arrays and name allocated @@ -447,9 +518,9 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name, js = _glfw.joysticks + jid; js->allocated = GLFW_TRUE; - js->axes = calloc(axisCount, sizeof(float)); - js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1); - js->hats = calloc(hatCount, 1); + js->axes = _glfw_calloc(axisCount, sizeof(float)); + js->buttons = _glfw_calloc(buttonCount + (size_t) hatCount * 4, 1); + js->hats = _glfw_calloc(hatCount, 1); js->axisCount = axisCount; js->buttonCount = buttonCount; js->hatCount = hatCount; @@ -465,9 +536,9 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name, // void _glfwFreeJoystick(_GLFWjoystick* js) { - free(js->axes); - free(js->buttons); - free(js->hats); + _glfw_free(js->axes); + _glfw_free(js->buttons); + _glfw_free(js->hats); memset(js, 0, sizeof(_GLFWjoystick)); } @@ -477,8 +548,8 @@ void _glfwCenterCursorInContentArea(_GLFWwindow* window) { int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); - _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); + _glfw.platform.getWindowSize(window, &width, &height); + _glfw.platform.setCursorPos(window, width / 2.0, height / 2.0); } @@ -518,96 +589,109 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) _GLFW_REQUIRE_INIT(); - if (mode == GLFW_CURSOR) + switch (mode) { - if (value != GLFW_CURSOR_NORMAL && - value != GLFW_CURSOR_HIDDEN && - value != GLFW_CURSOR_DISABLED) + case GLFW_CURSOR: { - _glfwInputError(GLFW_INVALID_ENUM, - "Invalid cursor mode 0x%08X", - value); - return; - } - - if (window->cursorMode == value) - return; - - window->cursorMode = value; - - _glfwPlatformGetCursorPos(window, - &window->virtualCursorPosX, - &window->virtualCursorPosY); - _glfwPlatformSetCursorMode(window, value); - } - else if (mode == GLFW_STICKY_KEYS) - { - value = value ? GLFW_TRUE : GLFW_FALSE; - if (window->stickyKeys == value) - return; - - if (!value) - { - int i; - - // Release all sticky keys - for (i = 0; i <= GLFW_KEY_LAST; i++) + if (value != GLFW_CURSOR_NORMAL && + value != GLFW_CURSOR_HIDDEN && + value != GLFW_CURSOR_DISABLED && + value != GLFW_CURSOR_CAPTURED) { - if (window->keys[i] == _GLFW_STICK) - window->keys[i] = GLFW_RELEASE; + _glfwInputError(GLFW_INVALID_ENUM, + "Invalid cursor mode 0x%08X", + value); + return; } + + if (window->cursorMode == value) + return; + + window->cursorMode = value; + + _glfw.platform.getCursorPos(window, + &window->virtualCursorPosX, + &window->virtualCursorPosY); + _glfw.platform.setCursorMode(window, value); + return; } - window->stickyKeys = value; - } - else if (mode == GLFW_STICKY_MOUSE_BUTTONS) - { - value = value ? GLFW_TRUE : GLFW_FALSE; - if (window->stickyMouseButtons == value) - return; - - if (!value) + case GLFW_STICKY_KEYS: { - int i; + value = value ? GLFW_TRUE : GLFW_FALSE; + if (window->stickyKeys == value) + return; - // Release all sticky mouse buttons - for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) + if (!value) { - if (window->mouseButtons[i] == _GLFW_STICK) - window->mouseButtons[i] = GLFW_RELEASE; + int i; + + // Release all sticky keys + for (i = 0; i <= GLFW_KEY_LAST; i++) + { + if (window->keys[i] == _GLFW_STICK) + window->keys[i] = GLFW_RELEASE; + } } + + window->stickyKeys = value; + return; } - window->stickyMouseButtons = value; - } - else if (mode == GLFW_LOCK_KEY_MODS) - { - window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE; - } - else if (mode == GLFW_RAW_MOUSE_MOTION) - { - if (!_glfwPlatformRawMouseMotionSupported()) + case GLFW_STICKY_MOUSE_BUTTONS: { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Raw mouse motion is not supported on this system"); + value = value ? GLFW_TRUE : GLFW_FALSE; + if (window->stickyMouseButtons == value) + return; + + if (!value) + { + int i; + + // Release all sticky mouse buttons + for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) + { + if (window->mouseButtons[i] == _GLFW_STICK) + window->mouseButtons[i] = GLFW_RELEASE; + } + } + + window->stickyMouseButtons = value; return; } - value = value ? GLFW_TRUE : GLFW_FALSE; - if (window->rawMouseMotion == value) + case GLFW_LOCK_KEY_MODS: + { + window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE; return; + } - window->rawMouseMotion = value; - _glfwPlatformSetRawMouseMotion(window, value); + case GLFW_RAW_MOUSE_MOTION: + { + if (!_glfw.platform.rawMouseMotionSupported()) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Raw mouse motion is not supported on this system"); + return; + } + + value = value ? GLFW_TRUE : GLFW_FALSE; + if (window->rawMouseMotion == value) + return; + + window->rawMouseMotion = value; + _glfw.platform.setRawMouseMotion(window, value); + return; + } } - else - _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); + + _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); } GLFWAPI int glfwRawMouseMotionSupported(void) { _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); - return _glfwPlatformRawMouseMotionSupported(); + return _glfw.platform.rawMouseMotionSupported(); } GLFWAPI const char* glfwGetKeyName(int key, int scancode) @@ -616,6 +700,12 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode) if (key != GLFW_KEY_UNKNOWN) { + if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST) + { + _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key); + return NULL; + } + if (key != GLFW_KEY_KP_EQUAL && (key < GLFW_KEY_KP_0 || key > GLFW_KEY_KP_ADD) && (key < GLFW_KEY_APOSTROPHE || key > GLFW_KEY_WORLD_2)) @@ -623,23 +713,23 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode) return NULL; } - scancode = _glfwPlatformGetKeyScancode(key); + scancode = _glfw.platform.getKeyScancode(key); } - return _glfwPlatformGetScancodeName(scancode); + return _glfw.platform.getScancodeName(scancode); } GLFWAPI int glfwGetKeyScancode(int key) { - _GLFW_REQUIRE_INIT_OR_RETURN(-1); + _GLFW_REQUIRE_INIT_OR_RETURN(0); if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST) { _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key); - return GLFW_RELEASE; + return -1; } - return _glfwPlatformGetKeyScancode(key); + return _glfw.platform.getKeyScancode(key); } GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) @@ -708,7 +798,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos) *ypos = window->virtualCursorPosY; } else - _glfwPlatformGetCursorPos(window, xpos, ypos); + _glfw.platform.getCursorPos(window, xpos, ypos); } GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos) @@ -727,7 +817,7 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos) return; } - if (!_glfwPlatformWindowFocused(window)) + if (!_glfw.platform.windowFocused(window)) return; if (window->cursorMode == GLFW_CURSOR_DISABLED) @@ -739,7 +829,7 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos) else { // Update system cursor position - _glfwPlatformSetCursorPos(window, xpos, ypos); + _glfw.platform.setCursorPos(window, xpos, ypos); } } @@ -758,11 +848,11 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) return NULL; } - cursor = calloc(1, sizeof(_GLFWcursor)); + cursor = _glfw_calloc(1, sizeof(_GLFWcursor)); cursor->next = _glfw.cursorListHead; _glfw.cursorListHead = cursor; - if (!_glfwPlatformCreateCursor(cursor, image, xhot, yhot)) + if (!_glfw.platform.createCursor(cursor, image, xhot, yhot)) { glfwDestroyCursor((GLFWcursor*) cursor); return NULL; @@ -780,19 +870,23 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape) if (shape != GLFW_ARROW_CURSOR && shape != GLFW_IBEAM_CURSOR && shape != GLFW_CROSSHAIR_CURSOR && - shape != GLFW_HAND_CURSOR && - shape != GLFW_HRESIZE_CURSOR && - shape != GLFW_VRESIZE_CURSOR) + shape != GLFW_POINTING_HAND_CURSOR && + shape != GLFW_RESIZE_EW_CURSOR && + shape != GLFW_RESIZE_NS_CURSOR && + shape != GLFW_RESIZE_NWSE_CURSOR && + shape != GLFW_RESIZE_NESW_CURSOR && + shape != GLFW_RESIZE_ALL_CURSOR && + shape != GLFW_NOT_ALLOWED_CURSOR) { _glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor 0x%08X", shape); return NULL; } - cursor = calloc(1, sizeof(_GLFWcursor)); + cursor = _glfw_calloc(1, sizeof(_GLFWcursor)); cursor->next = _glfw.cursorListHead; _glfw.cursorListHead = cursor; - if (!_glfwPlatformCreateStandardCursor(cursor, shape)) + if (!_glfw.platform.createStandardCursor(cursor, shape)) { glfwDestroyCursor((GLFWcursor*) cursor); return NULL; @@ -821,7 +915,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* handle) } } - _glfwPlatformDestroyCursor(cursor); + _glfw.platform.destroyCursor(cursor); // Unlink cursor from global linked list { @@ -833,7 +927,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* handle) *prev = cursor->next; } - free(cursor); + _glfw_free(cursor); } GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle) @@ -846,7 +940,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle) window->cursor = cursor; - _glfwPlatformSetCursor(window, cursor); + _glfw.platform.setCursor(window, cursor); } GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) @@ -855,7 +949,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.key, cbfun); + _GLFW_SWAP(GLFWkeyfun, window->callbacks.key, cbfun); return cbfun; } @@ -865,7 +959,7 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun) assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.character, cbfun); + _GLFW_SWAP(GLFWcharfun, window->callbacks.character, cbfun); return cbfun; } @@ -875,7 +969,7 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmods assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun); + _GLFW_SWAP(GLFWcharmodsfun, window->callbacks.charmods, cbfun); return cbfun; } @@ -886,7 +980,7 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun); + _GLFW_SWAP(GLFWmousebuttonfun, window->callbacks.mouseButton, cbfun); return cbfun; } @@ -897,7 +991,7 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun); + _GLFW_SWAP(GLFWcursorposfun, window->callbacks.cursorPos, cbfun); return cbfun; } @@ -908,7 +1002,7 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun); + _GLFW_SWAP(GLFWcursorenterfun, window->callbacks.cursorEnter, cbfun); return cbfun; } @@ -919,7 +1013,7 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun); + _GLFW_SWAP(GLFWscrollfun, window->callbacks.scroll, cbfun); return cbfun; } @@ -929,7 +1023,7 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun) assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun); + _GLFW_SWAP(GLFWdropfun, window->callbacks.drop, cbfun); return cbfun; } @@ -948,11 +1042,14 @@ GLFWAPI int glfwJoystickPresent(int jid) return GLFW_FALSE; } + if (!initJoysticks()) + return GLFW_FALSE; + js = _glfw.joysticks + jid; if (!js->connected) return GLFW_FALSE; - return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE); + return _glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE); } GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count) @@ -973,11 +1070,14 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count) return NULL; } + if (!initJoysticks()) + return NULL; + js = _glfw.joysticks + jid; if (!js->connected) return NULL; - if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_AXES)) + if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_AXES)) return NULL; *count = js->axisCount; @@ -1002,11 +1102,14 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count) return NULL; } + if (!initJoysticks()) + return NULL; + js = _glfw.joysticks + jid; if (!js->connected) return NULL; - if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS)) + if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_BUTTONS)) return NULL; if (_glfw.hints.init.hatButtons) @@ -1035,11 +1138,14 @@ GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count) return NULL; } + if (!initJoysticks()) + return NULL; + js = _glfw.joysticks + jid; if (!js->connected) return NULL; - if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS)) + if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_BUTTONS)) return NULL; *count = js->hatCount; @@ -1061,11 +1167,14 @@ GLFWAPI const char* glfwGetJoystickName(int jid) return NULL; } + if (!initJoysticks()) + return NULL; + js = _glfw.joysticks + jid; if (!js->connected) return NULL; - if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) + if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE)) return NULL; return js->name; @@ -1086,11 +1195,14 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid) return NULL; } + if (!initJoysticks()) + return NULL; + js = _glfw.joysticks + jid; if (!js->connected) return NULL; - if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) + if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE)) return NULL; return js->guid; @@ -1131,7 +1243,11 @@ GLFWAPI void* glfwGetJoystickUserPointer(int jid) GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun) { _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(_glfw.callbacks.joystick, cbfun); + + if (!initJoysticks()) + return NULL; + + _GLFW_SWAP(GLFWjoystickfun, _glfw.callbacks.joystick, cbfun); return cbfun; } @@ -1169,8 +1285,8 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string) { _glfw.mappingCount++; _glfw.mappings = - realloc(_glfw.mappings, - sizeof(_GLFWmapping) * _glfw.mappingCount); + _glfw_realloc(_glfw.mappings, + sizeof(_GLFWmapping) * _glfw.mappingCount); _glfw.mappings[_glfw.mappingCount - 1] = mapping; } } @@ -1210,11 +1326,14 @@ GLFWAPI int glfwJoystickIsGamepad(int jid) return GLFW_FALSE; } + if (!initJoysticks()) + return GLFW_FALSE; + js = _glfw.joysticks + jid; if (!js->connected) return GLFW_FALSE; - if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) + if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE)) return GLFW_FALSE; return js->mapping != NULL; @@ -1235,11 +1354,14 @@ GLFWAPI const char* glfwGetGamepadName(int jid) return NULL; } + if (!initJoysticks()) + return NULL; + js = _glfw.joysticks + jid; if (!js->connected) return NULL; - if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) + if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE)) return NULL; if (!js->mapping) @@ -1267,11 +1389,14 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state) return GLFW_FALSE; } + if (!initJoysticks()) + return GLFW_FALSE; + js = _glfw.joysticks + jid; if (!js->connected) return GLFW_FALSE; - if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL)) + if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_ALL)) return GLFW_FALSE; if (!js->mapping) @@ -1313,7 +1438,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state) if (e->type == _GLFW_JOYSTICK_AXIS) { const float value = js->axes[e->index] * e->axisScale + e->axisOffset; - state->axes[i] = _glfw_fminf(_glfw_fmaxf(value, -1.f), 1.f); + state->axes[i] = fminf(fmaxf(value, -1.f), 1.f); } else if (e->type == _GLFW_JOYSTICK_HATBIT) { @@ -1336,13 +1461,13 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string) assert(string != NULL); _GLFW_REQUIRE_INIT(); - _glfwPlatformSetClipboardString(string); + _glfw.platform.setClipboardString(string); } GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle) { _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return _glfwPlatformGetClipboardString(); + return _glfw.platform.getClipboardString(); } GLFWAPI double glfwGetTime(void) diff --git a/src/lib/src/vendor/glfw-3.3.8/src/internal.h b/src/lib/src/vendor/glfw-3.4/src/internal.h similarity index 53% rename from src/lib/src/vendor/glfw-3.3.8/src/internal.h rename to src/lib/src/vendor/glfw-3.4/src/internal.h index 7734caa..8873359 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/internal.h +++ b/src/lib/src/vendor/glfw-3.4/src/internal.h @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 - www.glfw.org +// GLFW 3.4 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -59,6 +59,7 @@ #define _GLFW_MESSAGE_SIZE 1024 typedef int GLFWbool; +typedef void (*GLFWproc)(void); typedef struct _GLFWerror _GLFWerror; typedef struct _GLFWinitconfig _GLFWinitconfig; @@ -67,6 +68,7 @@ typedef struct _GLFWctxconfig _GLFWctxconfig; typedef struct _GLFWfbconfig _GLFWfbconfig; typedef struct _GLFWcontext _GLFWcontext; typedef struct _GLFWwindow _GLFWwindow; +typedef struct _GLFWplatform _GLFWplatform; typedef struct _GLFWlibrary _GLFWlibrary; typedef struct _GLFWmonitor _GLFWmonitor; typedef struct _GLFWcursor _GLFWcursor; @@ -76,13 +78,6 @@ typedef struct _GLFWjoystick _GLFWjoystick; typedef struct _GLFWtls _GLFWtls; typedef struct _GLFWmutex _GLFWmutex; -typedef void (* _GLFWmakecontextcurrentfun)(_GLFWwindow*); -typedef void (* _GLFWswapbuffersfun)(_GLFWwindow*); -typedef void (* _GLFWswapintervalfun)(int); -typedef int (* _GLFWextensionsupportedfun)(const char*); -typedef GLFWglproc (* _GLFWgetprocaddressfun)(const char*); -typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*); - #define GL_VERSION 0x1f02 #define GL_NONE 0 #define GL_COLOR_BUFFER_BIT 0x00004000 @@ -113,6 +108,159 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum); typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*); typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); +#define EGL_SUCCESS 0x3000 +#define EGL_NOT_INITIALIZED 0x3001 +#define EGL_BAD_ACCESS 0x3002 +#define EGL_BAD_ALLOC 0x3003 +#define EGL_BAD_ATTRIBUTE 0x3004 +#define EGL_BAD_CONFIG 0x3005 +#define EGL_BAD_CONTEXT 0x3006 +#define EGL_BAD_CURRENT_SURFACE 0x3007 +#define EGL_BAD_DISPLAY 0x3008 +#define EGL_BAD_MATCH 0x3009 +#define EGL_BAD_NATIVE_PIXMAP 0x300a +#define EGL_BAD_NATIVE_WINDOW 0x300b +#define EGL_BAD_PARAMETER 0x300c +#define EGL_BAD_SURFACE 0x300d +#define EGL_CONTEXT_LOST 0x300e +#define EGL_COLOR_BUFFER_TYPE 0x303f +#define EGL_RGB_BUFFER 0x308e +#define EGL_SURFACE_TYPE 0x3033 +#define EGL_WINDOW_BIT 0x0004 +#define EGL_RENDERABLE_TYPE 0x3040 +#define EGL_OPENGL_ES_BIT 0x0001 +#define EGL_OPENGL_ES2_BIT 0x0004 +#define EGL_OPENGL_BIT 0x0008 +#define EGL_ALPHA_SIZE 0x3021 +#define EGL_BLUE_SIZE 0x3022 +#define EGL_GREEN_SIZE 0x3023 +#define EGL_RED_SIZE 0x3024 +#define EGL_DEPTH_SIZE 0x3025 +#define EGL_STENCIL_SIZE 0x3026 +#define EGL_SAMPLES 0x3031 +#define EGL_OPENGL_ES_API 0x30a0 +#define EGL_OPENGL_API 0x30a2 +#define EGL_NONE 0x3038 +#define EGL_RENDER_BUFFER 0x3086 +#define EGL_SINGLE_BUFFER 0x3085 +#define EGL_EXTENSIONS 0x3055 +#define EGL_CONTEXT_CLIENT_VERSION 0x3098 +#define EGL_NATIVE_VISUAL_ID 0x302e +#define EGL_NO_SURFACE ((EGLSurface) 0) +#define EGL_NO_DISPLAY ((EGLDisplay) 0) +#define EGL_NO_CONTEXT ((EGLContext) 0) +#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0) + +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 +#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31bd +#define EGL_NO_RESET_NOTIFICATION_KHR 0x31be +#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31bf +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 +#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 +#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30fb +#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30fd +#define EGL_CONTEXT_FLAGS_KHR 0x30fc +#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3 +#define EGL_GL_COLORSPACE_KHR 0x309d +#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098 +#define EGL_PLATFORM_X11_EXT 0x31d5 +#define EGL_PLATFORM_WAYLAND_EXT 0x31d8 +#define EGL_PRESENT_OPAQUE_EXT 0x31df +#define EGL_PLATFORM_ANGLE_ANGLE 0x3202 +#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203 +#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320d +#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320e +#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207 +#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208 +#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450 +#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489 +#define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f + +typedef int EGLint; +typedef unsigned int EGLBoolean; +typedef unsigned int EGLenum; +typedef void* EGLConfig; +typedef void* EGLContext; +typedef void* EGLDisplay; +typedef void* EGLSurface; + +typedef void* EGLNativeDisplayType; +typedef void* EGLNativeWindowType; + +// EGL function pointer typedefs +typedef EGLBoolean (APIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*); +typedef EGLBoolean (APIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*); +typedef EGLDisplay (APIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType); +typedef EGLint (APIENTRY * PFN_eglGetError)(void); +typedef EGLBoolean (APIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*); +typedef EGLBoolean (APIENTRY * PFN_eglTerminate)(EGLDisplay); +typedef EGLBoolean (APIENTRY * PFN_eglBindAPI)(EGLenum); +typedef EGLContext (APIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLContext,const EGLint*); +typedef EGLBoolean (APIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface); +typedef EGLBoolean (APIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext); +typedef EGLSurface (APIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*); +typedef EGLBoolean (APIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext); +typedef EGLBoolean (APIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface); +typedef EGLBoolean (APIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint); +typedef const char* (APIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint); +typedef GLFWglproc (APIENTRY * PFN_eglGetProcAddress)(const char*); +#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib +#define eglGetConfigs _glfw.egl.GetConfigs +#define eglGetDisplay _glfw.egl.GetDisplay +#define eglGetError _glfw.egl.GetError +#define eglInitialize _glfw.egl.Initialize +#define eglTerminate _glfw.egl.Terminate +#define eglBindAPI _glfw.egl.BindAPI +#define eglCreateContext _glfw.egl.CreateContext +#define eglDestroySurface _glfw.egl.DestroySurface +#define eglDestroyContext _glfw.egl.DestroyContext +#define eglCreateWindowSurface _glfw.egl.CreateWindowSurface +#define eglMakeCurrent _glfw.egl.MakeCurrent +#define eglSwapBuffers _glfw.egl.SwapBuffers +#define eglSwapInterval _glfw.egl.SwapInterval +#define eglQueryString _glfw.egl.QueryString +#define eglGetProcAddress _glfw.egl.GetProcAddress + +typedef EGLDisplay (APIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*); +typedef EGLSurface (APIENTRY * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay,EGLConfig,void*,const EGLint*); +#define eglGetPlatformDisplayEXT _glfw.egl.GetPlatformDisplayEXT +#define eglCreatePlatformWindowSurfaceEXT _glfw.egl.CreatePlatformWindowSurfaceEXT + +#define OSMESA_RGBA 0x1908 +#define OSMESA_FORMAT 0x22 +#define OSMESA_DEPTH_BITS 0x30 +#define OSMESA_STENCIL_BITS 0x31 +#define OSMESA_ACCUM_BITS 0x32 +#define OSMESA_PROFILE 0x33 +#define OSMESA_CORE_PROFILE 0x34 +#define OSMESA_COMPAT_PROFILE 0x35 +#define OSMESA_CONTEXT_MAJOR_VERSION 0x36 +#define OSMESA_CONTEXT_MINOR_VERSION 0x37 + +typedef void* OSMesaContext; +typedef void (*OSMESAproc)(void); + +typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextExt)(GLenum,GLint,GLint,GLint,OSMesaContext); +typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextAttribs)(const int*,OSMesaContext); +typedef void (GLAPIENTRY * PFN_OSMesaDestroyContext)(OSMesaContext); +typedef int (GLAPIENTRY * PFN_OSMesaMakeCurrent)(OSMesaContext,void*,int,int,int); +typedef int (GLAPIENTRY * PFN_OSMesaGetColorBuffer)(OSMesaContext,int*,int*,int*,void**); +typedef int (GLAPIENTRY * PFN_OSMesaGetDepthBuffer)(OSMesaContext,int*,int*,int*,void**); +typedef GLFWglproc (GLAPIENTRY * PFN_OSMesaGetProcAddress)(const char*); +#define OSMesaCreateContextExt _glfw.osmesa.CreateContextExt +#define OSMesaCreateContextAttribs _glfw.osmesa.CreateContextAttribs +#define OSMesaDestroyContext _glfw.osmesa.DestroyContext +#define OSMesaMakeCurrent _glfw.osmesa.MakeCurrent +#define OSMesaGetColorBuffer _glfw.osmesa.GetColorBuffer +#define OSMesaGetDepthBuffer _glfw.osmesa.GetDepthBuffer +#define OSMesaGetProcAddress _glfw.osmesa.GetProcAddress + #define VK_NULL_HANDLE 0 typedef void* VkInstance; @@ -170,36 +318,14 @@ typedef struct VkExtensionProperties typedef void (APIENTRY * PFN_vkVoidFunction)(void); -#if defined(_GLFW_VULKAN_STATIC) - PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance,const char*); - VkResult vkEnumerateInstanceExtensionProperties(const char*,uint32_t*,VkExtensionProperties*); -#else - typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*); - typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*); - #define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties - #define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr -#endif +typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*); +typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*); +#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr -#if defined(_GLFW_COCOA) - #include "cocoa_platform.h" -#elif defined(_GLFW_WIN32) - #include "win32_platform.h" -#elif defined(_GLFW_X11) - #include "x11_platform.h" -#elif defined(_GLFW_WAYLAND) - #include "wl_platform.h" -#elif defined(_GLFW_OSMESA) - #include "null_platform.h" -#else - #error "No supported window creation API selected" -#endif +#include "platform.h" -// Constructs a version number string from the public header macros -#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r -#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r) -#define _GLFW_VERSION_NUMBER _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR, \ - GLFW_VERSION_MINOR, \ - GLFW_VERSION_REVISION) +#define GLFW_NATIVE_INCLUDE_NONE +#include "../include/GLFW/glfw3native.h" // Checks for whether the library has been initialized #define _GLFW_REQUIRE_INIT() \ @@ -216,12 +342,12 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void); } // Swaps the provided pointers -#define _GLFW_SWAP_POINTERS(x, y) \ - { \ - void* t; \ - t = x; \ - x = y; \ - y = t; \ +#define _GLFW_SWAP(type, x, y) \ + { \ + type t; \ + t = x; \ + x = y; \ + y = t; \ } // Per-thread error structure @@ -240,10 +366,19 @@ struct _GLFWerror struct _GLFWinitconfig { GLFWbool hatButtons; + int angleType; + int platformID; + PFN_vkGetInstanceProcAddr vulkanLoader; struct { GLFWbool menubar; GLFWbool chdir; } ns; + struct { + GLFWbool xcbVulkanSurface; + } x11; + struct { + int libdecorMode; + } wl; }; // Window configuration @@ -254,6 +389,8 @@ struct _GLFWinitconfig // struct _GLFWwndconfig { + int xpos; + int ypos; int width; int height; const char* title; @@ -266,15 +403,23 @@ struct _GLFWwndconfig GLFWbool maximized; GLFWbool centerCursor; GLFWbool focusOnShow; + GLFWbool mousePassthrough; GLFWbool scaleToMonitor; + GLFWbool scaleFramebuffer; struct { - GLFWbool retina; char frameName[256]; } ns; struct { char className[256]; char instanceName[256]; } x11; + struct { + GLFWbool keymenu; + GLFWbool showDefault; + } win32; + struct { + char appId[256]; + } wl; }; // Context configuration @@ -346,19 +491,29 @@ struct _GLFWcontext PFNGLGETINTEGERVPROC GetIntegerv; PFNGLGETSTRINGPROC GetString; - _GLFWmakecontextcurrentfun makeCurrent; - _GLFWswapbuffersfun swapBuffers; - _GLFWswapintervalfun swapInterval; - _GLFWextensionsupportedfun extensionSupported; - _GLFWgetprocaddressfun getProcAddress; - _GLFWdestroycontextfun destroy; + void (*makeCurrent)(_GLFWwindow*); + void (*swapBuffers)(_GLFWwindow*); + void (*swapInterval)(int); + int (*extensionSupported)(const char*); + GLFWglproc (*getProcAddress)(const char*); + void (*destroy)(_GLFWwindow*); - // This is defined in the context API's context.h - _GLFW_PLATFORM_CONTEXT_STATE; - // This is defined in egl_context.h - _GLFW_EGL_CONTEXT_STATE; - // This is defined in osmesa_context.h - _GLFW_OSMESA_CONTEXT_STATE; + struct { + EGLConfig config; + EGLContext handle; + EGLSurface surface; + void* client; + } egl; + + struct { + OSMesaContext handle; + int width; + int height; + void* buffer; + } osmesa; + + // This is defined in platform.h + GLFW_PLATFORM_CONTEXT_STATE }; // Window and context structure @@ -373,12 +528,14 @@ struct _GLFWwindow GLFWbool autoIconify; GLFWbool floating; GLFWbool focusOnShow; + GLFWbool mousePassthrough; GLFWbool shouldClose; void* userPointer; GLFWbool doublebuffer; GLFWvidmode videoMode; _GLFWmonitor* monitor; _GLFWcursor* cursor; + char* title; int minwidth, minheight; int maxwidth, maxheight; @@ -416,8 +573,8 @@ struct _GLFWwindow GLFWdropfun drop; } callbacks; - // This is defined in the window API's platform.h - _GLFW_PLATFORM_WINDOW_STATE; + // This is defined in platform.h + GLFW_PLATFORM_WINDOW_STATE }; // Monitor structure @@ -440,8 +597,8 @@ struct _GLFWmonitor GLFWgammaramp originalRamp; GLFWgammaramp currentRamp; - // This is defined in the window API's platform.h - _GLFW_PLATFORM_MONITOR_STATE; + // This is defined in platform.h + GLFW_PLATFORM_MONITOR_STATE }; // Cursor structure @@ -449,9 +606,8 @@ struct _GLFWmonitor struct _GLFWcursor { _GLFWcursor* next; - - // This is defined in the window API's platform.h - _GLFW_PLATFORM_CURSOR_STATE; + // This is defined in platform.h + GLFW_PLATFORM_CURSOR_STATE }; // Gamepad mapping element structure @@ -491,24 +647,108 @@ struct _GLFWjoystick char guid[33]; _GLFWmapping* mapping; - // This is defined in the joystick API's joystick.h - _GLFW_PLATFORM_JOYSTICK_STATE; + // This is defined in platform.h + GLFW_PLATFORM_JOYSTICK_STATE }; // Thread local storage structure // struct _GLFWtls { - // This is defined in the platform's thread.h - _GLFW_PLATFORM_TLS_STATE; + // This is defined in platform.h + GLFW_PLATFORM_TLS_STATE }; // Mutex structure // struct _GLFWmutex { - // This is defined in the platform's thread.h - _GLFW_PLATFORM_MUTEX_STATE; + // This is defined in platform.h + GLFW_PLATFORM_MUTEX_STATE +}; + +// Platform API structure +// +struct _GLFWplatform +{ + int platformID; + // init + GLFWbool (*init)(void); + void (*terminate)(void); + // input + void (*getCursorPos)(_GLFWwindow*,double*,double*); + void (*setCursorPos)(_GLFWwindow*,double,double); + void (*setCursorMode)(_GLFWwindow*,int); + void (*setRawMouseMotion)(_GLFWwindow*,GLFWbool); + GLFWbool (*rawMouseMotionSupported)(void); + GLFWbool (*createCursor)(_GLFWcursor*,const GLFWimage*,int,int); + GLFWbool (*createStandardCursor)(_GLFWcursor*,int); + void (*destroyCursor)(_GLFWcursor*); + void (*setCursor)(_GLFWwindow*,_GLFWcursor*); + const char* (*getScancodeName)(int); + int (*getKeyScancode)(int); + void (*setClipboardString)(const char*); + const char* (*getClipboardString)(void); + GLFWbool (*initJoysticks)(void); + void (*terminateJoysticks)(void); + GLFWbool (*pollJoystick)(_GLFWjoystick*,int); + const char* (*getMappingName)(void); + void (*updateGamepadGUID)(char*); + // monitor + void (*freeMonitor)(_GLFWmonitor*); + void (*getMonitorPos)(_GLFWmonitor*,int*,int*); + void (*getMonitorContentScale)(_GLFWmonitor*,float*,float*); + void (*getMonitorWorkarea)(_GLFWmonitor*,int*,int*,int*,int*); + GLFWvidmode* (*getVideoModes)(_GLFWmonitor*,int*); + GLFWbool (*getVideoMode)(_GLFWmonitor*,GLFWvidmode*); + GLFWbool (*getGammaRamp)(_GLFWmonitor*,GLFWgammaramp*); + void (*setGammaRamp)(_GLFWmonitor*,const GLFWgammaramp*); + // window + GLFWbool (*createWindow)(_GLFWwindow*,const _GLFWwndconfig*,const _GLFWctxconfig*,const _GLFWfbconfig*); + void (*destroyWindow)(_GLFWwindow*); + void (*setWindowTitle)(_GLFWwindow*,const char*); + void (*setWindowIcon)(_GLFWwindow*,int,const GLFWimage*); + void (*getWindowPos)(_GLFWwindow*,int*,int*); + void (*setWindowPos)(_GLFWwindow*,int,int); + void (*getWindowSize)(_GLFWwindow*,int*,int*); + void (*setWindowSize)(_GLFWwindow*,int,int); + void (*setWindowSizeLimits)(_GLFWwindow*,int,int,int,int); + void (*setWindowAspectRatio)(_GLFWwindow*,int,int); + void (*getFramebufferSize)(_GLFWwindow*,int*,int*); + void (*getWindowFrameSize)(_GLFWwindow*,int*,int*,int*,int*); + void (*getWindowContentScale)(_GLFWwindow*,float*,float*); + void (*iconifyWindow)(_GLFWwindow*); + void (*restoreWindow)(_GLFWwindow*); + void (*maximizeWindow)(_GLFWwindow*); + void (*showWindow)(_GLFWwindow*); + void (*hideWindow)(_GLFWwindow*); + void (*requestWindowAttention)(_GLFWwindow*); + void (*focusWindow)(_GLFWwindow*); + void (*setWindowMonitor)(_GLFWwindow*,_GLFWmonitor*,int,int,int,int,int); + GLFWbool (*windowFocused)(_GLFWwindow*); + GLFWbool (*windowIconified)(_GLFWwindow*); + GLFWbool (*windowVisible)(_GLFWwindow*); + GLFWbool (*windowMaximized)(_GLFWwindow*); + GLFWbool (*windowHovered)(_GLFWwindow*); + GLFWbool (*framebufferTransparent)(_GLFWwindow*); + float (*getWindowOpacity)(_GLFWwindow*); + void (*setWindowResizable)(_GLFWwindow*,GLFWbool); + void (*setWindowDecorated)(_GLFWwindow*,GLFWbool); + void (*setWindowFloating)(_GLFWwindow*,GLFWbool); + void (*setWindowOpacity)(_GLFWwindow*,float); + void (*setWindowMousePassthrough)(_GLFWwindow*,GLFWbool); + void (*pollEvents)(void); + void (*waitEvents)(void); + void (*waitEventsTimeout)(double); + void (*postEmptyEvent)(void); + // EGL + EGLenum (*getEGLPlatform)(EGLint**); + EGLNativeDisplayType (*getEGLNativeDisplay)(void); + EGLNativeWindowType (*getEGLNativeWindow)(_GLFWwindow*); + // vulkan + void (*getRequiredInstanceExtensions)(char**); + GLFWbool (*getPhysicalDevicePresentationSupport)(VkInstance,VkPhysicalDevice,uint32_t); + VkResult (*createWindowSurface)(VkInstance,_GLFWwindow*,const VkAllocationCallbacks*,VkSurfaceKHR*); }; // Library global data @@ -516,6 +756,9 @@ struct _GLFWmutex struct _GLFWlibrary { GLFWbool initialized; + GLFWallocator allocator; + + _GLFWplatform platform; struct { _GLFWinitconfig init; @@ -532,6 +775,7 @@ struct _GLFWlibrary _GLFWmonitor** monitors; int monitorCount; + GLFWbool joysticksInitialized; _GLFWjoystick joysticks[GLFW_JOYSTICK_LAST + 1]; _GLFWmapping* mappings; int mappingCount; @@ -542,30 +786,80 @@ struct _GLFWlibrary struct { uint64_t offset; - // This is defined in the platform's time.h - _GLFW_PLATFORM_LIBRARY_TIMER_STATE; + // This is defined in platform.h + GLFW_PLATFORM_LIBRARY_TIMER_STATE } timer; + struct { + EGLenum platform; + EGLDisplay display; + EGLint major, minor; + GLFWbool prefix; + + GLFWbool KHR_create_context; + GLFWbool KHR_create_context_no_error; + GLFWbool KHR_gl_colorspace; + GLFWbool KHR_get_all_proc_addresses; + GLFWbool KHR_context_flush_control; + GLFWbool EXT_client_extensions; + GLFWbool EXT_platform_base; + GLFWbool EXT_platform_x11; + GLFWbool EXT_platform_wayland; + GLFWbool EXT_present_opaque; + GLFWbool ANGLE_platform_angle; + GLFWbool ANGLE_platform_angle_opengl; + GLFWbool ANGLE_platform_angle_d3d; + GLFWbool ANGLE_platform_angle_vulkan; + GLFWbool ANGLE_platform_angle_metal; + + void* handle; + + PFN_eglGetConfigAttrib GetConfigAttrib; + PFN_eglGetConfigs GetConfigs; + PFN_eglGetDisplay GetDisplay; + PFN_eglGetError GetError; + PFN_eglInitialize Initialize; + PFN_eglTerminate Terminate; + PFN_eglBindAPI BindAPI; + PFN_eglCreateContext CreateContext; + PFN_eglDestroySurface DestroySurface; + PFN_eglDestroyContext DestroyContext; + PFN_eglCreateWindowSurface CreateWindowSurface; + PFN_eglMakeCurrent MakeCurrent; + PFN_eglSwapBuffers SwapBuffers; + PFN_eglSwapInterval SwapInterval; + PFN_eglQueryString QueryString; + PFN_eglGetProcAddress GetProcAddress; + + PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT; + PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC CreatePlatformWindowSurfaceEXT; + } egl; + + struct { + void* handle; + + PFN_OSMesaCreateContextExt CreateContextExt; + PFN_OSMesaCreateContextAttribs CreateContextAttribs; + PFN_OSMesaDestroyContext DestroyContext; + PFN_OSMesaMakeCurrent MakeCurrent; + PFN_OSMesaGetColorBuffer GetColorBuffer; + PFN_OSMesaGetDepthBuffer GetDepthBuffer; + PFN_OSMesaGetProcAddress GetProcAddress; + + } osmesa; + struct { GLFWbool available; void* handle; char* extensions[2]; -#if !defined(_GLFW_VULKAN_STATIC) - PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; PFN_vkGetInstanceProcAddr GetInstanceProcAddr; -#endif GLFWbool KHR_surface; -#if defined(_GLFW_WIN32) GLFWbool KHR_win32_surface; -#elif defined(_GLFW_COCOA) GLFWbool MVK_macos_surface; GLFWbool EXT_metal_surface; -#elif defined(_GLFW_X11) GLFWbool KHR_xlib_surface; GLFWbool KHR_xcb_surface; -#elif defined(_GLFW_WAYLAND) GLFWbool KHR_wayland_surface; -#endif } vk; struct { @@ -573,16 +867,10 @@ struct _GLFWlibrary GLFWjoystickfun joystick; } callbacks; - // This is defined in the window API's platform.h - _GLFW_PLATFORM_LIBRARY_WINDOW_STATE; - // This is defined in the context API's context.h - _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE; - // This is defined in the platform's joystick.h - _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE; - // This is defined in egl_context.h - _GLFW_EGL_LIBRARY_CONTEXT_STATE; - // This is defined in osmesa_context.h - _GLFW_OSMESA_LIBRARY_CONTEXT_STATE; + // These are defined in platform.h + GLFW_PLATFORM_LIBRARY_WINDOW_STATE + GLFW_PLATFORM_LIBRARY_CONTEXT_STATE + GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE }; // Global state shared between compilation units of GLFW @@ -594,101 +882,10 @@ extern _GLFWlibrary _glfw; ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -int _glfwPlatformInit(void); -void _glfwPlatformTerminate(void); -const char* _glfwPlatformGetVersionString(void); - -void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos); -void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos); -void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode); -void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled); -GLFWbool _glfwPlatformRawMouseMotionSupported(void); -int _glfwPlatformCreateCursor(_GLFWcursor* cursor, - const GLFWimage* image, int xhot, int yhot); -int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape); -void _glfwPlatformDestroyCursor(_GLFWcursor* cursor); -void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor); - -const char* _glfwPlatformGetScancodeName(int scancode); -int _glfwPlatformGetKeyScancode(int key); - -void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor); -void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos); -void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, - float* xscale, float* yscale); -void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height); -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count); -void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode); -GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp); -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); - -void _glfwPlatformSetClipboardString(const char* string); -const char* _glfwPlatformGetClipboardString(void); - -int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode); -void _glfwPlatformUpdateGamepadGUID(char* guid); - +void _glfwPlatformInitTimer(void); uint64_t _glfwPlatformGetTimerValue(void); uint64_t _glfwPlatformGetTimerFrequency(void); -int _glfwPlatformCreateWindow(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig); -void _glfwPlatformDestroyWindow(_GLFWwindow* window); -void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title); -void _glfwPlatformSetWindowIcon(_GLFWwindow* window, - int count, const GLFWimage* images); -void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos); -void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos); -void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height); -void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height); -void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, - int minwidth, int minheight, - int maxwidth, int maxheight); -void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom); -void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height); -void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, - int* left, int* top, - int* right, int* bottom); -void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, - float* xscale, float* yscale); -void _glfwPlatformIconifyWindow(_GLFWwindow* window); -void _glfwPlatformRestoreWindow(_GLFWwindow* window); -void _glfwPlatformMaximizeWindow(_GLFWwindow* window); -void _glfwPlatformShowWindow(_GLFWwindow* window); -void _glfwPlatformHideWindow(_GLFWwindow* window); -void _glfwPlatformRequestWindowAttention(_GLFWwindow* window); -void _glfwPlatformFocusWindow(_GLFWwindow* window); -void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor, - int xpos, int ypos, int width, int height, - int refreshRate); -int _glfwPlatformWindowFocused(_GLFWwindow* window); -int _glfwPlatformWindowIconified(_GLFWwindow* window); -int _glfwPlatformWindowVisible(_GLFWwindow* window); -int _glfwPlatformWindowMaximized(_GLFWwindow* window); -int _glfwPlatformWindowHovered(_GLFWwindow* window); -int _glfwPlatformFramebufferTransparent(_GLFWwindow* window); -float _glfwPlatformGetWindowOpacity(_GLFWwindow* window); -void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled); -void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled); -void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled); -void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity); - -void _glfwPlatformPollEvents(void); -void _glfwPlatformWaitEvents(void); -void _glfwPlatformWaitEventsTimeout(double timeout); -void _glfwPlatformPostEmptyEvent(void); - -void _glfwPlatformGetRequiredInstanceExtensions(char** extensions); -int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, - VkPhysicalDevice device, - uint32_t queuefamily); -VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, - _GLFWwindow* window, - const VkAllocationCallbacks* allocator, - VkSurfaceKHR* surface); - GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls); void _glfwPlatformDestroyTls(_GLFWtls* tls); void* _glfwPlatformGetTls(_GLFWtls* tls); @@ -699,6 +896,10 @@ void _glfwPlatformDestroyMutex(_GLFWmutex* mutex); void _glfwPlatformLockMutex(_GLFWmutex* mutex); void _glfwPlatformUnlockMutex(_GLFWmutex* mutex); +void* _glfwPlatformLoadModule(const char* path); +void _glfwPlatformFreeModule(void* module); +GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name); + ////////////////////////////////////////////////////////////////////////// ////// GLFW event API ////// @@ -745,6 +946,8 @@ void _glfwInputError(int code, const char* format, ...); ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// +GLFWbool _glfwSelectPlatform(int platformID, _GLFWplatform* platform); + GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions); const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, const _GLFWfbconfig* alternatives, @@ -771,6 +974,24 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name, void _glfwFreeJoystick(_GLFWjoystick* js); void _glfwCenterCursorInContentArea(_GLFWwindow* window); +GLFWbool _glfwInitEGL(void); +void _glfwTerminateEGL(void); +GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig); +#if defined(_GLFW_X11) +GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig, + Visual** visual, int* depth); +#endif /*_GLFW_X11*/ + +GLFWbool _glfwInitOSMesa(void); +void _glfwTerminateOSMesa(void); +GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig); + GLFWbool _glfwInitVulkan(int mode); void _glfwTerminateVulkan(void); const char* _glfwGetVulkanResultString(VkResult result); @@ -781,6 +1002,8 @@ char** _glfwParseUriList(char* text, int* count); char* _glfw_strdup(const char* source); int _glfw_min(int a, int b); int _glfw_max(int a, int b); -float _glfw_fminf(float a, float b); -float _glfw_fmaxf(float a, float b); + +void* _glfw_calloc(size_t count, size_t size); +void* _glfw_realloc(void* pointer, size_t size); +void _glfw_free(void* pointer); diff --git a/src/lib/src/vendor/glfw-3.3.8/src/linux_joystick.c b/src/lib/src/vendor/glfw-3.4/src/linux_joystick.c similarity index 94% rename from src/lib/src/vendor/glfw-3.3.8/src/linux_joystick.c rename to src/lib/src/vendor/glfw-3.4/src/linux_joystick.c index 0894a72..07d41d3 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/linux_joystick.c +++ b/src/lib/src/vendor/glfw-3.4/src/linux_joystick.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Linux - www.glfw.org +// GLFW 3.4 Linux - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2017 Camilla Löwy @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_LINUX_JOYSTICK) + #include #include #include @@ -135,7 +135,7 @@ static GLFWbool openJoystickDevice(const char* path) } _GLFWjoystickLinux linjs = {0}; - linjs.fd = open(path, O_RDONLY | O_NONBLOCK); + linjs.fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); if (linjs.fd == -1) return GLFW_FALSE; @@ -157,7 +157,7 @@ static GLFWbool openJoystickDevice(const char* path) } // Ensure this device supports the events expected of a joystick - if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits)) + if (!isBitSet(EV_ABS, evBits)) { close(linjs.fd); return GLFW_FALSE; @@ -264,86 +264,6 @@ static int compareJoysticks(const void* fp, const void* sp) ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// -// Initialize joystick interface -// -GLFWbool _glfwInitJoysticksLinux(void) -{ - const char* dirname = "/dev/input"; - - _glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); - if (_glfw.linjs.inotify > 0) - { - // HACK: Register for IN_ATTRIB to get notified when udev is done - // This works well in practice but the true way is libudev - - _glfw.linjs.watch = inotify_add_watch(_glfw.linjs.inotify, - dirname, - IN_CREATE | IN_ATTRIB | IN_DELETE); - } - - // Continue without device connection notifications if inotify fails - - if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex"); - return GLFW_FALSE; - } - - int count = 0; - - DIR* dir = opendir(dirname); - if (dir) - { - struct dirent* entry; - - while ((entry = readdir(dir))) - { - regmatch_t match; - - if (regexec(&_glfw.linjs.regex, entry->d_name, 1, &match, 0) != 0) - continue; - - char path[PATH_MAX]; - - snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name); - - if (openJoystickDevice(path)) - count++; - } - - closedir(dir); - } - - // Continue with no joysticks if enumeration fails - - qsort(_glfw.joysticks, count, sizeof(_GLFWjoystick), compareJoysticks); - return GLFW_TRUE; -} - -// Close all opened joystick handles -// -void _glfwTerminateJoysticksLinux(void) -{ - int jid; - - for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) - { - _GLFWjoystick* js = _glfw.joysticks + jid; - if (js->connected) - closeJoystick(js); - } - - regfree(&_glfw.linjs.regex); - - if (_glfw.linjs.inotify > 0) - { - if (_glfw.linjs.watch > 0) - inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch); - - close(_glfw.linjs.inotify); - } -} - void _glfwDetectJoystickConnectionLinux(void) { if (_glfw.linjs.inotify <= 0) @@ -387,7 +307,83 @@ void _glfwDetectJoystickConnectionLinux(void) ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) +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 (;;) @@ -427,7 +423,14 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) return js->connected; } -void _glfwPlatformUpdateGamepadGUID(char* guid) +const char* _glfwGetMappingNameLinux(void) +{ + return "Linux"; +} + +void _glfwUpdateGamepadGUIDLinux(char* guid) { } +#endif // GLFW_BUILD_LINUX_JOYSTICK + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/linux_joystick.h b/src/lib/src/vendor/glfw-3.4/src/linux_joystick.h similarity index 84% rename from src/lib/src/vendor/glfw-3.3.8/src/linux_joystick.h rename to src/lib/src/vendor/glfw-3.4/src/linux_joystick.h index 25a2a2e..64462b0 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/linux_joystick.h +++ b/src/lib/src/vendor/glfw-3.4/src/linux_joystick.h @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Linux - www.glfw.org +// GLFW 3.4 Linux - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2014 Jonas Ådahl // @@ -28,11 +28,8 @@ #include #include -#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs -#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs - -#define _GLFW_PLATFORM_MAPPING_NAME "Linux" -#define GLFW_BUILD_LINUX_MAPPINGS +#define GLFW_LINUX_JOYSTICK_STATE _GLFWjoystickLinux linjs; +#define GLFW_LINUX_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs; // Linux-specific joystick data // @@ -53,11 +50,15 @@ typedef struct _GLFWlibraryLinux int inotify; int watch; regex_t regex; + GLFWbool regexCompiled; GLFWbool dropped; } _GLFWlibraryLinux; +void _glfwDetectJoystickConnectionLinux(void); GLFWbool _glfwInitJoysticksLinux(void); void _glfwTerminateJoysticksLinux(void); -void _glfwDetectJoystickConnectionLinux(void); +GLFWbool _glfwPollJoystickLinux(_GLFWjoystick* js, int mode); +const char* _glfwGetMappingNameLinux(void); +void _glfwUpdateGamepadGUIDLinux(char* guid); diff --git a/src/lib/src/vendor/glfw-3.3.8/src/mappings.h b/src/lib/src/vendor/glfw-3.4/src/mappings.h similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/src/mappings.h rename to src/lib/src/vendor/glfw-3.4/src/mappings.h index 11853a0..270fa4c 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/mappings.h +++ b/src/lib/src/vendor/glfw-3.4/src/mappings.h @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 - www.glfw.org +// GLFW 3.4 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2006-2018 Camilla Löwy // @@ -60,7 +60,7 @@ const char* _glfwDefaultMappings[] = { -#if defined(GLFW_BUILD_WIN32_MAPPINGS) +#if defined(_GLFW_WIN32) "03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Windows,", "03000000c82d00002038000000000000,8bitdo,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,", "03000000c82d00000951000000000000,8BitDo Dogbone Modkit,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows,", @@ -426,9 +426,9 @@ const char* _glfwDefaultMappings[] = "78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", -#endif // GLFW_BUILD_WIN32_MAPPINGS +#endif // _GLFW_WIN32 -#if defined(GLFW_BUILD_COCOA_MAPPINGS) +#if defined(_GLFW_COCOA) "030000008f0e00000300000009010000,2In1 USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,", "03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", "03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,", @@ -598,9 +598,9 @@ const char* _glfwDefaultMappings[] = "03000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,", "03000000120c0000100e000000010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", "03000000120c0000101e000000010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,", -#endif // GLFW_BUILD_COCOA_MAPPINGS +#endif // _GLFW_COCOA -#if defined(GLFW_BUILD_LINUX_MAPPINGS) +#if defined(GLFW_BUILD_LINUX_JOYSTICK) "03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", "05000000c82d00001038000000010000,8Bitdo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,", "05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux,", @@ -996,6 +996,6 @@ const char* _glfwDefaultMappings[] = "03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,", "03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", "03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", -#endif // GLFW_BUILD_LINUX_MAPPINGS +#endif // GLFW_BUILD_LINUX_JOYSTICK }; diff --git a/src/lib/src/vendor/glfw-3.3.8/src/mappings.h.in b/src/lib/src/vendor/glfw-3.4/src/mappings.h.in similarity index 95% rename from src/lib/src/vendor/glfw-3.3.8/src/mappings.h.in rename to src/lib/src/vendor/glfw-3.4/src/mappings.h.in index 26b544b..ed62368 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/mappings.h.in +++ b/src/lib/src/vendor/glfw-3.4/src/mappings.h.in @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 - www.glfw.org +// GLFW 3.4 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2006-2018 Camilla Löwy // @@ -60,7 +60,7 @@ const char* _glfwDefaultMappings[] = { -#if defined(GLFW_BUILD_WIN32_MAPPINGS) +#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,", @@ -69,14 +69,14 @@ const char* _glfwDefaultMappings[] = "78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", -#endif // GLFW_BUILD_WIN32_MAPPINGS +#endif // _GLFW_WIN32 -#if defined(GLFW_BUILD_COCOA_MAPPINGS) +#if defined(_GLFW_COCOA) @GLFW_COCOA_MAPPINGS@ -#endif // GLFW_BUILD_COCOA_MAPPINGS +#endif // _GLFW_COCOA -#if defined(GLFW_BUILD_LINUX_MAPPINGS) +#if defined(GLFW_BUILD_LINUX_JOYSTICK) @GLFW_LINUX_MAPPINGS@ -#endif // GLFW_BUILD_LINUX_MAPPINGS +#endif // GLFW_BUILD_LINUX_JOYSTICK }; diff --git a/src/lib/src/vendor/glfw-3.3.8/src/monitor.c b/src/lib/src/vendor/glfw-3.4/src/monitor.c similarity index 88% rename from src/lib/src/vendor/glfw-3.3.8/src/monitor.c rename to src/lib/src/vendor/glfw-3.4/src/monitor.c index 2601d11..efc286d 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/monitor.c +++ b/src/lib/src/vendor/glfw-3.4/src/monitor.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 - www.glfw.org +// GLFW 3.4 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" @@ -74,13 +72,13 @@ static GLFWbool refreshVideoModes(_GLFWmonitor* monitor) if (monitor->modes) return GLFW_TRUE; - modes = _glfwPlatformGetVideoModes(monitor, &modeCount); + modes = _glfw.platform.getVideoModes(monitor, &modeCount); if (!modes) return GLFW_FALSE; qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes); - free(monitor->modes); + _glfw_free(monitor->modes); monitor->modes = modes; monitor->modeCount = modeCount; @@ -96,11 +94,16 @@ static GLFWbool refreshVideoModes(_GLFWmonitor* monitor) // 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 = - realloc(_glfw.monitors, sizeof(_GLFWmonitor*) * _glfw.monitorCount); + _glfw_realloc(_glfw.monitors, + sizeof(_GLFWmonitor*) * _glfw.monitorCount); if (placement == _GLFW_INSERT_FIRST) { @@ -122,10 +125,10 @@ void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement) if (window->monitor == monitor) { int width, height, xoff, yoff; - _glfwPlatformGetWindowSize(window, &width, &height); - _glfwPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0); - _glfwPlatformGetWindowFrameSize(window, &xoff, &yoff, NULL, NULL); - _glfwPlatformSetWindowPos(window, xoff, yoff); + _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); } } @@ -154,6 +157,7 @@ void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement) // void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window) { + assert(monitor != NULL); monitor->window = window; } @@ -166,7 +170,7 @@ void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window) // _GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM) { - _GLFWmonitor* monitor = calloc(1, sizeof(_GLFWmonitor)); + _GLFWmonitor* monitor = _glfw_calloc(1, sizeof(_GLFWmonitor)); monitor->widthMM = widthMM; monitor->heightMM = heightMM; @@ -182,22 +186,22 @@ void _glfwFreeMonitor(_GLFWmonitor* monitor) if (monitor == NULL) return; - _glfwPlatformFreeMonitor(monitor); + _glfw.platform.freeMonitor(monitor); _glfwFreeGammaArrays(&monitor->originalRamp); _glfwFreeGammaArrays(&monitor->currentRamp); - free(monitor->modes); - free(monitor); + _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 = calloc(size, sizeof(unsigned short)); - ramp->green = calloc(size, sizeof(unsigned short)); - ramp->blue = calloc(size, sizeof(unsigned short)); + 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; } @@ -205,9 +209,9 @@ void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size) // void _glfwFreeGammaArrays(GLFWgammaramp* ramp) { - free(ramp->red); - free(ramp->green); - free(ramp->blue); + _glfw_free(ramp->red); + _glfw_free(ramp->green); + _glfw_free(ramp->blue); memset(ramp, 0, sizeof(GLFWgammaramp)); } @@ -331,7 +335,7 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) _GLFW_REQUIRE_INIT(); - _glfwPlatformGetMonitorPos(monitor, xpos, ypos); + _glfw.platform.getMonitorPos(monitor, xpos, ypos); } GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle, @@ -352,7 +356,7 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle, _GLFW_REQUIRE_INIT(); - _glfwPlatformGetMonitorWorkarea(monitor, xpos, ypos, width, height); + _glfw.platform.getMonitorWorkarea(monitor, xpos, ypos, width, height); } GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) @@ -385,7 +389,7 @@ GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* handle, *yscale = 0.f; _GLFW_REQUIRE_INIT(); - _glfwPlatformGetMonitorContentScale(monitor, xscale, yscale); + _glfw.platform.getMonitorContentScale(monitor, xscale, yscale); } GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle) @@ -418,7 +422,7 @@ GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle) GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun) { _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(_glfw.callbacks.monitor, cbfun); + _GLFW_SWAP(GLFWmonitorfun, _glfw.callbacks.monitor, cbfun); return cbfun; } @@ -446,7 +450,9 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _glfwPlatformGetVideoMode(monitor, &monitor->currentMode); + if (!_glfw.platform.getVideoMode(monitor, &monitor->currentMode)) + return NULL; + return &monitor->currentMode; } @@ -472,7 +478,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) if (!original) return; - values = calloc(original->size, sizeof(unsigned short)); + values = _glfw_calloc(original->size, sizeof(unsigned short)); for (i = 0; i < original->size; i++) { @@ -483,7 +489,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) // Apply gamma curve value = powf(value, 1.f / gamma) * 65535.f + 0.5f; // Clamp to value range - value = _glfw_fminf(value, 65535.f); + value = fminf(value, 65535.f); values[i] = (unsigned short) value; } @@ -494,7 +500,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) ramp.size = original->size; glfwSetGammaRamp(handle, &ramp); - free(values); + _glfw_free(values); } GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) @@ -505,7 +511,7 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _glfwFreeGammaArrays(&monitor->currentRamp); - if (!_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp)) + if (!_glfw.platform.getGammaRamp(monitor, &monitor->currentRamp)) return NULL; return &monitor->currentRamp; @@ -533,10 +539,10 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) if (!monitor->originalRamp.size) { - if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp)) + if (!_glfw.platform.getGammaRamp(monitor, &monitor->originalRamp)) return; } - _glfwPlatformSetGammaRamp(monitor, ramp); + _glfw.platform.setGammaRamp(monitor, ramp); } diff --git a/src/lib/src/vendor/glfw-3.3.8/src/nsgl_context.m b/src/lib/src/vendor/glfw-3.4/src/nsgl_context.m similarity index 84% rename from src/lib/src/vendor/glfw-3.3.8/src/nsgl_context.m rename to src/lib/src/vendor/glfw-3.4/src/nsgl_context.m index 78d688c..daa8367 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/nsgl_context.m +++ b/src/lib/src/vendor/glfw-3.4/src/nsgl_context.m @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 macOS - www.glfw.org +// GLFW 3.4 macOS - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2009-2019 Camilla Löwy // @@ -23,11 +23,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_COCOA) + #include #include @@ -81,11 +81,10 @@ static void swapIntervalNSGL(int interval) @autoreleasepool { _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); - if (window) - { - [window->context.nsgl.object setValues:&interval - forParameter:NSOpenGLContextParameterSwapInterval]; - } + assert(window != NULL); + + [window->context.nsgl.object setValues:&interval + forParameter:NSOpenGLContextParameterSwapInterval]; } // autoreleasepool } @@ -162,7 +161,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, if (ctxconfig->client == GLFW_OPENGL_ES_API) { _glfwInputError(GLFW_API_UNAVAILABLE, - "NSGL: OpenGL ES is not available on macOS"); + "NSGL: OpenGL ES is not available via NSGL"); return GLFW_FALSE; } @@ -174,13 +173,13 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, "NSGL: The targeted version of macOS does not support OpenGL 3.0 or 3.1 but may support 3.2 and above"); return GLFW_FALSE; } + } - if (!ctxconfig->forward || ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "NSGL: The targeted version of macOS only supports forward-compatible core profile contexts for OpenGL 3.2 and above"); - return GLFW_FALSE; - } + 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 @@ -195,45 +194,45 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, // No-error contexts (GL_KHR_no_error) are not yet supported by macOS but // are not a hard constraint, so ignore and continue -#define addAttrib(a) \ +#define ADD_ATTRIB(a) \ { \ assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ attribs[index++] = a; \ } -#define setAttrib(a, v) { addAttrib(a); addAttrib(v); } +#define SET_ATTRIB(a, v) { ADD_ATTRIB(a); ADD_ATTRIB(v); } NSOpenGLPixelFormatAttribute attribs[40]; int index = 0; - addAttrib(NSOpenGLPFAAccelerated); - addAttrib(NSOpenGLPFAClosestPolicy); + ADD_ATTRIB(NSOpenGLPFAAccelerated); + ADD_ATTRIB(NSOpenGLPFAClosestPolicy); if (ctxconfig->nsgl.offline) { - addAttrib(NSOpenGLPFAAllowOfflineRenderers); + 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 - addAttrib(kCGLPFASupportsAutomaticGraphicsSwitching); + ADD_ATTRIB(kCGLPFASupportsAutomaticGraphicsSwitching); } #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 if (ctxconfig->major >= 4) { - setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core); + SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core); } else #endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ if (ctxconfig->major >= 3) { - setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); + SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); } if (ctxconfig->major <= 2) { if (fbconfig->auxBuffers != GLFW_DONT_CARE) - setAttrib(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); + SET_ATTRIB(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); if (fbconfig->accumRedBits != GLFW_DONT_CARE && fbconfig->accumGreenBits != GLFW_DONT_CARE && @@ -245,7 +244,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, fbconfig->accumBlueBits + fbconfig->accumAlphaBits; - setAttrib(NSOpenGLPFAAccumSize, accumBits); + SET_ATTRIB(NSOpenGLPFAAccumSize, accumBits); } } @@ -263,17 +262,17 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, else if (colorBits < 15) colorBits = 15; - setAttrib(NSOpenGLPFAColorSize, colorBits); + SET_ATTRIB(NSOpenGLPFAColorSize, colorBits); } if (fbconfig->alphaBits != GLFW_DONT_CARE) - setAttrib(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); + SET_ATTRIB(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); if (fbconfig->depthBits != GLFW_DONT_CARE) - setAttrib(NSOpenGLPFADepthSize, fbconfig->depthBits); + SET_ATTRIB(NSOpenGLPFADepthSize, fbconfig->depthBits); if (fbconfig->stencilBits != GLFW_DONT_CARE) - setAttrib(NSOpenGLPFAStencilSize, fbconfig->stencilBits); + SET_ATTRIB(NSOpenGLPFAStencilSize, fbconfig->stencilBits); if (fbconfig->stereo) { @@ -282,33 +281,33 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, "NSGL: Stereo rendering is deprecated"); return GLFW_FALSE; #else - addAttrib(NSOpenGLPFAStereo); + ADD_ATTRIB(NSOpenGLPFAStereo); #endif } if (fbconfig->doublebuffer) - addAttrib(NSOpenGLPFADoubleBuffer); + ADD_ATTRIB(NSOpenGLPFADoubleBuffer); if (fbconfig->samples != GLFW_DONT_CARE) { if (fbconfig->samples == 0) { - setAttrib(NSOpenGLPFASampleBuffers, 0); + SET_ATTRIB(NSOpenGLPFASampleBuffers, 0); } else { - setAttrib(NSOpenGLPFASampleBuffers, 1); - setAttrib(NSOpenGLPFASamples, fbconfig->samples); + 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 - addAttrib(0); + ADD_ATTRIB(0); -#undef addAttrib -#undef setAttrib +#undef ADD_ATTRIB +#undef SET_ATTRIB window->context.nsgl.pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; @@ -341,7 +340,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, forParameter:NSOpenGLContextParameterSurfaceOpacity]; } - [window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.retina]; + [window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.scaleFramebuffer]; [window->context.nsgl.object setView:window->ns.view]; @@ -365,6 +364,13 @@ 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); @@ -374,3 +380,5 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle) return window->context.nsgl.object; } +#endif // _GLFW_COCOA + diff --git a/src/lib/src/vendor/glfw-3.4/src/null_init.c b/src/lib/src/vendor/glfw-3.4/src/null_init.c new file mode 100644 index 0000000..88940fc --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/null_init.c @@ -0,0 +1,264 @@ +//======================================================================== +// GLFW 3.4 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2016 Google Inc. +// Copyright (c) 2016-2017 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include + + +////////////////////////////////////////////////////////////////////////// +////// GLFW 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(); +} + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/null_joystick.c b/src/lib/src/vendor/glfw-3.4/src/null_joystick.c similarity index 82% rename from src/lib/src/vendor/glfw-3.3.8/src/null_joystick.c rename to src/lib/src/vendor/glfw-3.4/src/null_joystick.c index 000faf2..ec1f6b5 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/null_joystick.c +++ b/src/lib/src/vendor/glfw-3.4/src/null_joystick.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 - www.glfw.org +// GLFW 3.4 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2016-2017 Camilla Löwy // @@ -23,8 +23,6 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" @@ -33,12 +31,26 @@ ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) +GLFWbool _glfwInitJoysticksNull(void) +{ + return GLFW_TRUE; +} + +void _glfwTerminateJoysticksNull(void) +{ +} + +GLFWbool _glfwPollJoystickNull(_GLFWjoystick* js, int mode) { return GLFW_FALSE; } -void _glfwPlatformUpdateGamepadGUID(char* guid) +const char* _glfwGetMappingNameNull(void) +{ + return ""; +} + +void _glfwUpdateGamepadGUIDNull(char* guid) { } diff --git a/src/lib/src/vendor/glfw-3.3.8/src/null_joystick.h b/src/lib/src/vendor/glfw-3.4/src/null_joystick.h similarity index 82% rename from src/lib/src/vendor/glfw-3.3.8/src/null_joystick.h rename to src/lib/src/vendor/glfw-3.4/src/null_joystick.h index 9307ae8..a2199c5 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/null_joystick.h +++ b/src/lib/src/vendor/glfw-3.4/src/null_joystick.h @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 - www.glfw.org +// GLFW 3.4 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2006-2017 Camilla Löwy // @@ -24,8 +24,9 @@ // //======================================================================== -#define _GLFW_PLATFORM_JOYSTICK_STATE struct { int dummyJoystick; } -#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyLibraryJoystick; } - -#define _GLFW_PLATFORM_MAPPING_NAME "" +GLFWbool _glfwInitJoysticksNull(void); +void _glfwTerminateJoysticksNull(void); +GLFWbool _glfwPollJoystickNull(_GLFWjoystick* js, int mode); +const char* _glfwGetMappingNameNull(void); +void _glfwUpdateGamepadGUIDNull(char* guid); diff --git a/src/lib/src/vendor/glfw-3.4/src/null_monitor.c b/src/lib/src/vendor/glfw-3.4/src/null_monitor.c new file mode 100644 index 0000000..d818f45 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/null_monitor.c @@ -0,0 +1,160 @@ +//======================================================================== +// GLFW 3.4 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2016 Google Inc. +// Copyright (c) 2016-2019 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include + +// 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); +} + diff --git a/src/lib/src/vendor/glfw-3.4/src/null_platform.h b/src/lib/src/vendor/glfw-3.4/src/null_platform.h new file mode 100644 index 0000000..4843a76 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/null_platform.h @@ -0,0 +1,271 @@ +//======================================================================== +// GLFW 3.4 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2016 Google Inc. +// Copyright (c) 2016-2017 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as 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); + diff --git a/src/lib/src/vendor/glfw-3.4/src/null_window.c b/src/lib/src/vendor/glfw-3.4/src/null_window.c new file mode 100644 index 0000000..1db0811 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/null_window.c @@ -0,0 +1,719 @@ +//======================================================================== +// GLFW 3.4 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2016 Google Inc. +// Copyright (c) 2016-2019 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as 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 + +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 acquireMonitor(_GLFWwindow* window) +{ + _glfwInputMonitorWindow(window->monitor, window); +} + +static void releaseMonitor(_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); + acquireMonitor(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) + releaseMonitor(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) + releaseMonitor(window); + + _glfwInputWindowMonitor(window, monitor); + + if (window->monitor) + { + window->null.visible = GLFW_TRUE; + acquireMonitor(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) + releaseMonitor(window); + } +} + +void _glfwRestoreWindowNull(_GLFWwindow* window) +{ + if (window->null.iconified) + { + window->null.iconified = GLFW_FALSE; + _glfwInputWindowIconify(window, GLFW_FALSE); + + if (window->monitor) + acquireMonitor(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; +} + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/osmesa_context.c b/src/lib/src/vendor/glfw-3.4/src/osmesa_context.c similarity index 86% rename from src/lib/src/vendor/glfw-3.3.8/src/osmesa_context.c rename to src/lib/src/vendor/glfw-3.4/src/osmesa_context.c index 4072728..2f12adf 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/osmesa_context.c +++ b/src/lib/src/vendor/glfw-3.4/src/osmesa_context.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 OSMesa - www.glfw.org +// GLFW 3.4 OSMesa - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2016 Google Inc. // Copyright (c) 2016-2017 Camilla Löwy @@ -24,32 +24,29 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== + +#include "internal.h" #include #include #include -#include "internal.h" - - static void makeContextCurrentOSMesa(_GLFWwindow* window) { if (window) { int width, height; - _glfwPlatformGetFramebufferSize(window, &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)) { - free(window->context.osmesa.buffer); + _glfw_free(window->context.osmesa.buffer); // Allocate the new buffer (width * height * 8-bit RGBA) - window->context.osmesa.buffer = calloc(4, (size_t) width * height); + window->context.osmesa.buffer = _glfw_calloc(4, (size_t) width * height); window->context.osmesa.width = width; window->context.osmesa.height = height; } @@ -83,7 +80,7 @@ static void destroyContextOSMesa(_GLFWwindow* window) if (window->context.osmesa.buffer) { - free(window->context.osmesa.buffer); + _glfw_free(window->context.osmesa.buffer); window->context.osmesa.width = 0; window->context.osmesa.height = 0; } @@ -138,7 +135,7 @@ GLFWbool _glfwInitOSMesa(void) for (i = 0; sonames[i]; i++) { - _glfw.osmesa.handle = _glfw_dlopen(sonames[i]); + _glfw.osmesa.handle = _glfwPlatformLoadModule(sonames[i]); if (_glfw.osmesa.handle) break; } @@ -150,19 +147,19 @@ GLFWbool _glfwInitOSMesa(void) } _glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt) - _glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextExt"); + _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextExt"); _glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs) - _glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextAttribs"); + _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextAttribs"); _glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext) - _glfw_dlsym(_glfw.osmesa.handle, "OSMesaDestroyContext"); + _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaDestroyContext"); _glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent) - _glfw_dlsym(_glfw.osmesa.handle, "OSMesaMakeCurrent"); + _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaMakeCurrent"); _glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer) - _glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetColorBuffer"); + _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetColorBuffer"); _glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer) - _glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetDepthBuffer"); + _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetDepthBuffer"); _glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress) - _glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetProcAddress"); + _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetProcAddress"); if (!_glfw.osmesa.CreateContextExt || !_glfw.osmesa.DestroyContext || @@ -185,12 +182,12 @@ void _glfwTerminateOSMesa(void) { if (_glfw.osmesa.handle) { - _glfw_dlclose(_glfw.osmesa.handle); + _glfwPlatformFreeModule(_glfw.osmesa.handle); _glfw.osmesa.handle = NULL; } } -#define setAttrib(a, v) \ +#define SET_ATTRIB(a, v) \ { \ assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ attribs[index++] = a; \ @@ -221,24 +218,24 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window, { int index = 0, attribs[40]; - setAttrib(OSMESA_FORMAT, OSMESA_RGBA); - setAttrib(OSMESA_DEPTH_BITS, fbconfig->depthBits); - setAttrib(OSMESA_STENCIL_BITS, fbconfig->stencilBits); - setAttrib(OSMESA_ACCUM_BITS, accumBits); + 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) { - setAttrib(OSMESA_PROFILE, OSMESA_CORE_PROFILE); + SET_ATTRIB(OSMESA_PROFILE, OSMESA_CORE_PROFILE); } else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) { - setAttrib(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE); + SET_ATTRIB(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE); } if (ctxconfig->major != 1 || ctxconfig->minor != 0) { - setAttrib(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major); - setAttrib(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor); + SET_ATTRIB(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major); + SET_ATTRIB(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor); } if (ctxconfig->forward) @@ -248,7 +245,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window, return GLFW_FALSE; } - setAttrib(0, 0); + SET_ATTRIB(0, 0); window->context.osmesa.handle = OSMesaCreateContextAttribs(attribs, share); @@ -287,7 +284,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window, return GLFW_TRUE; } -#undef setAttrib +#undef SET_ATTRIB ////////////////////////////////////////////////////////////////////////// diff --git a/src/lib/src/vendor/glfw-3.4/src/platform.c b/src/lib/src/vendor/glfw-3.4/src/platform.c new file mode 100644 index 0000000..af1b0f4 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/platform.c @@ -0,0 +1,212 @@ +//======================================================================== +// GLFW 3.4 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2018 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include + +// 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; + } + + // Only allow the Null platform if specifically requested + if (desiredID == GLFW_PLATFORM_NULL) + return _glfwConnectNull(desiredID, platform); + else if (count == 0) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "This binary only supports the Null platform"); + 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 + ; +} + diff --git a/src/lib/src/vendor/glfw-3.4/src/platform.h b/src/lib/src/vendor/glfw-3.4/src/platform.h new file mode 100644 index 0000000..75652dc --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/platform.h @@ -0,0 +1,212 @@ +//======================================================================== +// GLFW 3.4 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2018 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as 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_ 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 + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/null_init.c b/src/lib/src/vendor/glfw-3.4/src/posix_module.c similarity index 72% rename from src/lib/src/vendor/glfw-3.3.8/src/null_init.c rename to src/lib/src/vendor/glfw-3.4/src/posix_module.c index 569bc8c..7d81c67 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/null_init.c +++ b/src/lib/src/vendor/glfw-3.4/src/posix_module.c @@ -1,8 +1,7 @@ //======================================================================== -// GLFW 3.3 - www.glfw.org +// GLFW 3.4 POSIX - www.glfw.org //------------------------------------------------------------------------ -// Copyright (c) 2016 Google Inc. -// Copyright (c) 2016-2017 Camilla Löwy +// Copyright (c) 2021 Camilla Löwy // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages @@ -24,29 +23,31 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_POSIX_MODULE) + +#include ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -int _glfwPlatformInit(void) +void* _glfwPlatformLoadModule(const char* path) { - _glfwInitTimerPOSIX(); - return GLFW_TRUE; + return dlopen(path, RTLD_LAZY | RTLD_LOCAL); } -void _glfwPlatformTerminate(void) +void _glfwPlatformFreeModule(void* module) { - _glfwTerminateOSMesa(); + dlclose(module); } -const char* _glfwPlatformGetVersionString(void) +GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name) { - return _GLFW_VERSION_NUMBER " null OSMesa"; + return dlsym(module, name); } +#endif // GLFW_BUILD_POSIX_MODULE + diff --git a/src/lib/src/vendor/glfw-3.4/src/posix_poll.c b/src/lib/src/vendor/glfw-3.4/src/posix_poll.c new file mode 100644 index 0000000..b53e36e --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/posix_poll.c @@ -0,0 +1,83 @@ +//======================================================================== +// GLFW 3.4 POSIX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2022 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as 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 +#include +#include + +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 + diff --git a/src/lib/src/vendor/glfw-3.4/src/posix_poll.h b/src/lib/src/vendor/glfw-3.4/src/posix_poll.h new file mode 100644 index 0000000..4bdd244 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/posix_poll.h @@ -0,0 +1,30 @@ +//======================================================================== +// GLFW 3.4 POSIX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2022 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as 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 + +GLFWbool _glfwPollPOSIX(struct pollfd* fds, nfds_t count, double* timeout); + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/posix_thread.c b/src/lib/src/vendor/glfw-3.4/src/posix_thread.c similarity index 94% rename from src/lib/src/vendor/glfw-3.3.8/src/posix_thread.c rename to src/lib/src/vendor/glfw-3.4/src/posix_thread.c index f1697dc..3c355a5 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/posix_thread.c +++ b/src/lib/src/vendor/glfw-3.4/src/posix_thread.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 POSIX - www.glfw.org +// GLFW 3.4 POSIX - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2017 Camilla Löwy @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_POSIX_THREAD) + #include #include @@ -103,3 +103,5 @@ void _glfwPlatformUnlockMutex(_GLFWmutex* mutex) pthread_mutex_unlock(&mutex->posix.handle); } +#endif // GLFW_BUILD_POSIX_THREAD + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/posix_thread.h b/src/lib/src/vendor/glfw-3.4/src/posix_thread.h similarity index 91% rename from src/lib/src/vendor/glfw-3.3.8/src/posix_thread.h rename to src/lib/src/vendor/glfw-3.4/src/posix_thread.h index 1c6a5c4..5a5d7b7 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/posix_thread.h +++ b/src/lib/src/vendor/glfw-3.4/src/posix_thread.h @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 POSIX - www.glfw.org +// GLFW 3.4 POSIX - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2017 Camilla Löwy @@ -27,8 +27,8 @@ #include -#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsPOSIX posix -#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexPOSIX posix +#define GLFW_POSIX_TLS_STATE _GLFWtlsPOSIX posix; +#define GLFW_POSIX_MUTEX_STATE _GLFWmutexPOSIX posix; // POSIX-specific thread local storage data diff --git a/src/lib/src/vendor/glfw-3.3.8/src/posix_time.c b/src/lib/src/vendor/glfw-3.4/src/posix_time.c similarity index 59% rename from src/lib/src/vendor/glfw-3.3.8/src/posix_time.c rename to src/lib/src/vendor/glfw-3.4/src/posix_time.c index 040c8f1..a172408 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/posix_time.c +++ b/src/lib/src/vendor/glfw-3.4/src/posix_time.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 POSIX - www.glfw.org +// GLFW 3.4 POSIX - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2017 Camilla Löwy @@ -24,60 +24,36 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_POSIX_TIMER) + +#include #include -#include - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Initialise timer -// -void _glfwInitTimerPOSIX(void) -{ -#if defined(CLOCK_MONOTONIC) - struct timespec ts; - - if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) - { - _glfw.timer.posix.monotonic = GLFW_TRUE; - _glfw.timer.posix.frequency = 1000000000; - } - else -#endif - { - _glfw.timer.posix.monotonic = GLFW_FALSE; - _glfw.timer.posix.frequency = 1000000; - } -} ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// +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) { -#if defined(CLOCK_MONOTONIC) - if (_glfw.timer.posix.monotonic) - { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec; - } - else -#endif - { - struct timeval tv; - gettimeofday(&tv, NULL); - return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec; - } + 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) @@ -85,3 +61,5 @@ uint64_t _glfwPlatformGetTimerFrequency(void) return _glfw.timer.posix.frequency; } +#endif // GLFW_BUILD_POSIX_TIMER + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/posix_time.h b/src/lib/src/vendor/glfw-3.4/src/posix_time.h similarity index 89% rename from src/lib/src/vendor/glfw-3.3.8/src/posix_time.h rename to src/lib/src/vendor/glfw-3.4/src/posix_time.h index 911399e..94374ad 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/posix_time.h +++ b/src/lib/src/vendor/glfw-3.4/src/posix_time.h @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 POSIX - www.glfw.org +// GLFW 3.4 POSIX - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2017 Camilla Löwy @@ -25,19 +25,17 @@ // //======================================================================== -#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerPOSIX posix +#define GLFW_POSIX_LIBRARY_TIMER_STATE _GLFWtimerPOSIX posix; #include +#include // POSIX-specific global timer data // typedef struct _GLFWtimerPOSIX { - GLFWbool monotonic; + clockid_t clock; uint64_t frequency; } _GLFWtimerPOSIX; - -void _glfwInitTimerPOSIX(void); - diff --git a/src/lib/src/vendor/glfw-3.3.8/src/vulkan.c b/src/lib/src/vendor/glfw-3.4/src/vulkan.c similarity index 80% rename from src/lib/src/vendor/glfw-3.3.8/src/vulkan.c rename to src/lib/src/vendor/glfw-3.4/src/vulkan.c index 1b96579..d9fabde 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/vulkan.c +++ b/src/lib/src/vendor/glfw-3.4/src/vulkan.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 - www.glfw.org +// GLFW 3.4 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2018 Camilla Löwy @@ -24,8 +24,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" @@ -45,47 +43,52 @@ GLFWbool _glfwInitVulkan(int mode) { VkResult err; VkExtensionProperties* ep; + PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties; uint32_t i, count; if (_glfw.vk.available) return GLFW_TRUE; -#if !defined(_GLFW_VULKAN_STATIC) + if (_glfw.hints.init.vulkanLoader) + _glfw.vk.GetInstanceProcAddr = _glfw.hints.init.vulkanLoader; + else + { #if defined(_GLFW_VULKAN_LIBRARY) - _glfw.vk.handle = _glfw_dlopen(_GLFW_VULKAN_LIBRARY); + _glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY); #elif defined(_GLFW_WIN32) - _glfw.vk.handle = _glfw_dlopen("vulkan-1.dll"); + _glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll"); #elif defined(_GLFW_COCOA) - _glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib"); - if (!_glfw.vk.handle) - _glfw.vk.handle = _glfwLoadLocalVulkanLoaderNS(); + _glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib"); + if (!_glfw.vk.handle) + _glfw.vk.handle = _glfwLoadLocalVulkanLoaderCocoa(); #elif defined(__OpenBSD__) || defined(__NetBSD__) - _glfw.vk.handle = _glfw_dlopen("libvulkan.so"); + _glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so"); #else - _glfw.vk.handle = _glfw_dlopen("libvulkan.so.1"); + _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"); + if (!_glfw.vk.handle) + { + if (mode == _GLFW_REQUIRE_LOADER) + _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); - return GLFW_FALSE; + 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; + } } - _glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) - _glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr"); - if (!_glfw.vk.GetInstanceProcAddr) - { - _glfwInputError(GLFW_API_UNAVAILABLE, - "Vulkan: Loader does not export vkGetInstanceProcAddr"); - - _glfwTerminateVulkan(); - return GLFW_FALSE; - } - - _glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) + vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties"); - if (!_glfw.vk.EnumerateInstanceExtensionProperties) + if (!vkEnumerateInstanceExtensionProperties) { _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties"); @@ -93,7 +96,6 @@ GLFWbool _glfwInitVulkan(int mode) _glfwTerminateVulkan(); return GLFW_FALSE; } -#endif // _GLFW_VULKAN_STATIC err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL); if (err) @@ -110,7 +112,7 @@ GLFWbool _glfwInitVulkan(int mode) return GLFW_FALSE; } - ep = calloc(count, sizeof(VkExtensionProperties)); + ep = _glfw_calloc(count, sizeof(VkExtensionProperties)); err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep); if (err) @@ -119,7 +121,7 @@ GLFWbool _glfwInitVulkan(int mode) "Vulkan: Failed to query instance extensions: %s", _glfwGetVulkanResultString(err)); - free(ep); + _glfw_free(ep); _glfwTerminateVulkan(); return GLFW_FALSE; } @@ -128,40 +130,33 @@ GLFWbool _glfwInitVulkan(int mode) { if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0) _glfw.vk.KHR_surface = GLFW_TRUE; -#if defined(_GLFW_WIN32) else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0) _glfw.vk.KHR_win32_surface = GLFW_TRUE; -#elif defined(_GLFW_COCOA) else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0) _glfw.vk.MVK_macos_surface = GLFW_TRUE; else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0) _glfw.vk.EXT_metal_surface = GLFW_TRUE; -#elif defined(_GLFW_X11) else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0) _glfw.vk.KHR_xlib_surface = GLFW_TRUE; else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0) _glfw.vk.KHR_xcb_surface = GLFW_TRUE; -#elif defined(_GLFW_WAYLAND) else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0) _glfw.vk.KHR_wayland_surface = GLFW_TRUE; -#endif } - free(ep); + _glfw_free(ep); _glfw.vk.available = GLFW_TRUE; - _glfwPlatformGetRequiredInstanceExtensions(_glfw.vk.extensions); + _glfw.platform.getRequiredInstanceExtensions(_glfw.vk.extensions); return GLFW_TRUE; } void _glfwTerminateVulkan(void) { -#if !defined(_GLFW_VULKAN_STATIC) if (_glfw.vk.handle) - _glfw_dlclose(_glfw.vk.handle); -#endif + _glfwPlatformFreeModule(_glfw.vk.handle); } const char* _glfwGetVulkanResultString(VkResult result) @@ -259,17 +254,16 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, 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 defined(_GLFW_VULKAN_STATIC) if (!proc) { - if (strcmp(procname, "vkGetInstanceProcAddr") == 0) - return (GLFWvkproc) vkGetInstanceProcAddr; + if (_glfw.vk.handle) + proc = (GLFWvkproc) _glfwPlatformGetModuleSymbol(_glfw.vk.handle, procname); } -#else - if (!proc) - proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname); -#endif return proc; } @@ -293,9 +287,9 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, return GLFW_FALSE; } - return _glfwPlatformGetPhysicalDevicePresentationSupport(instance, - device, - queuefamily); + return _glfw.platform.getPhysicalDevicePresentationSupport(instance, + device, + queuefamily); } GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, @@ -329,6 +323,6 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR; } - return _glfwPlatformCreateWindowSurface(instance, window, allocator, surface); + return _glfw.platform.createWindowSurface(instance, window, allocator, surface); } diff --git a/src/lib/src/vendor/glfw-3.3.8/src/wgl_context.c b/src/lib/src/vendor/glfw-3.4/src/wgl_context.c similarity index 75% rename from src/lib/src/vendor/glfw-3.3.8/src/wgl_context.c rename to src/lib/src/vendor/glfw-3.4/src/wgl_context.c index 72ad11d..8a23ffc 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/wgl_context.c +++ b/src/lib/src/vendor/glfw-3.4/src/wgl_context.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 WGL - www.glfw.org +// GLFW 3.4 WGL - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -24,21 +24,20 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32) + #include -#include #include // Return the value corresponding to the specified attribute // -static int findPixelFormatAttribValue(const int* attribs, - int attribCount, - const int* values, - int attrib) +static int findPixelFormatAttribValueWGL(const int* attribs, + int attribCount, + const int* values, + int attrib) { int i; @@ -53,19 +52,19 @@ static int findPixelFormatAttribValue(const int* attribs, return 0; } -#define addAttrib(a) \ +#define ADD_ATTRIB(a) \ { \ assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \ attribs[attribCount++] = a; \ } -#define findAttribValue(a) \ - findPixelFormatAttribValue(attribs, attribCount, values, a) +#define FIND_ATTRIB_VALUE(a) \ + findPixelFormatAttribValueWGL(attribs, attribCount, values, a) // Return a list of available and usable framebuffer configs // -static int choosePixelFormat(_GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) +static int choosePixelFormatWGL(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) { _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; @@ -73,64 +72,69 @@ static int choosePixelFormat(_GLFWwindow* window, 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, &nativeCount)) + 1, 0, 1, &attrib, &extensionCount)) { _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, "WGL: Failed to retrieve pixel format attribute"); return 0; } - addAttrib(WGL_SUPPORT_OPENGL_ARB); - addAttrib(WGL_DRAW_TO_WINDOW_ARB); - addAttrib(WGL_PIXEL_TYPE_ARB); - addAttrib(WGL_ACCELERATION_ARB); - addAttrib(WGL_RED_BITS_ARB); - addAttrib(WGL_RED_SHIFT_ARB); - addAttrib(WGL_GREEN_BITS_ARB); - addAttrib(WGL_GREEN_SHIFT_ARB); - addAttrib(WGL_BLUE_BITS_ARB); - addAttrib(WGL_BLUE_SHIFT_ARB); - addAttrib(WGL_ALPHA_BITS_ARB); - addAttrib(WGL_ALPHA_SHIFT_ARB); - addAttrib(WGL_DEPTH_BITS_ARB); - addAttrib(WGL_STENCIL_BITS_ARB); - addAttrib(WGL_ACCUM_BITS_ARB); - addAttrib(WGL_ACCUM_RED_BITS_ARB); - addAttrib(WGL_ACCUM_GREEN_BITS_ARB); - addAttrib(WGL_ACCUM_BLUE_BITS_ARB); - addAttrib(WGL_ACCUM_ALPHA_BITS_ARB); - addAttrib(WGL_AUX_BUFFERS_ARB); - addAttrib(WGL_STEREO_ARB); - addAttrib(WGL_DOUBLE_BUFFER_ARB); - - if (_glfw.wgl.ARB_multisample) - addAttrib(WGL_SAMPLES_ARB); - - if (ctxconfig->client == GLFW_OPENGL_API) - { - if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB) - addAttrib(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); - } - else - { - if (_glfw.wgl.EXT_colorspace) - addAttrib(WGL_COLORSPACE_EXT); - } - } - else - { - nativeCount = DescribePixelFormat(window->context.wgl.dc, - 1, - sizeof(PIXELFORMATDESCRIPTOR), - NULL); + nativeCount = _glfw_min(nativeCount, extensionCount); } - usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); + usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig)); for (i = 0; i < nativeCount; i++) { @@ -149,52 +153,52 @@ static int choosePixelFormat(_GLFWwindow* window, _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, "WGL: Failed to retrieve pixel format attributes"); - free(usableConfigs); + _glfw_free(usableConfigs); return 0; } - if (!findAttribValue(WGL_SUPPORT_OPENGL_ARB) || - !findAttribValue(WGL_DRAW_TO_WINDOW_ARB)) + if (!FIND_ATTRIB_VALUE(WGL_SUPPORT_OPENGL_ARB) || + !FIND_ATTRIB_VALUE(WGL_DRAW_TO_WINDOW_ARB)) { continue; } - if (findAttribValue(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB) + if (FIND_ATTRIB_VALUE(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB) continue; - if (findAttribValue(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB) + if (FIND_ATTRIB_VALUE(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB) continue; - if (findAttribValue(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer) + if (FIND_ATTRIB_VALUE(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer) continue; - u->redBits = findAttribValue(WGL_RED_BITS_ARB); - u->greenBits = findAttribValue(WGL_GREEN_BITS_ARB); - u->blueBits = findAttribValue(WGL_BLUE_BITS_ARB); - u->alphaBits = findAttribValue(WGL_ALPHA_BITS_ARB); + u->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 = findAttribValue(WGL_DEPTH_BITS_ARB); - u->stencilBits = findAttribValue(WGL_STENCIL_BITS_ARB); + u->depthBits = FIND_ATTRIB_VALUE(WGL_DEPTH_BITS_ARB); + u->stencilBits = FIND_ATTRIB_VALUE(WGL_STENCIL_BITS_ARB); - u->accumRedBits = findAttribValue(WGL_ACCUM_RED_BITS_ARB); - u->accumGreenBits = findAttribValue(WGL_ACCUM_GREEN_BITS_ARB); - u->accumBlueBits = findAttribValue(WGL_ACCUM_BLUE_BITS_ARB); - u->accumAlphaBits = findAttribValue(WGL_ACCUM_ALPHA_BITS_ARB); + u->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 = findAttribValue(WGL_AUX_BUFFERS_ARB); + u->auxBuffers = FIND_ATTRIB_VALUE(WGL_AUX_BUFFERS_ARB); - if (findAttribValue(WGL_STEREO_ARB)) + if (FIND_ATTRIB_VALUE(WGL_STEREO_ARB)) u->stereo = GLFW_TRUE; if (_glfw.wgl.ARB_multisample) - u->samples = findAttribValue(WGL_SAMPLES_ARB); + 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 (findAttribValue(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) + if (FIND_ATTRIB_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) u->sRGB = GLFW_TRUE; } } @@ -202,7 +206,7 @@ static int choosePixelFormat(_GLFWwindow* window, { if (_glfw.wgl.EXT_colorspace) { - if (findAttribValue(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT) + if (FIND_ATTRIB_VALUE(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT) u->sRGB = GLFW_TRUE; } } @@ -221,7 +225,7 @@ static int choosePixelFormat(_GLFWwindow* window, _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, "WGL: Failed to describe pixel format"); - free(usableConfigs); + _glfw_free(usableConfigs); return 0; } @@ -271,7 +275,7 @@ static int choosePixelFormat(_GLFWwindow* window, _glfwInputError(GLFW_API_UNAVAILABLE, "WGL: The driver does not appear to support OpenGL"); - free(usableConfigs); + _glfw_free(usableConfigs); return 0; } @@ -281,18 +285,18 @@ static int choosePixelFormat(_GLFWwindow* window, _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "WGL: Failed to find a suitable pixel format"); - free(usableConfigs); + _glfw_free(usableConfigs); return 0; } pixelFormat = (int) closest->handle; - free(usableConfigs); + _glfw_free(usableConfigs); return pixelFormat; } -#undef addAttrib -#undef findAttribValue +#undef ADD_ATTRIB +#undef FIND_ATTRIB_VALUE static void makeContextCurrentWGL(_GLFWwindow* window) { @@ -323,14 +327,12 @@ static void swapBuffersWGL(_GLFWwindow* window) { if (!window->monitor) { - if (IsWindowsVistaOrGreater()) + // HACK: Use DwmFlush when desktop composition is enabled on Windows Vista and 7 + if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater()) { - // DWM Composition is always enabled on Win8+ - BOOL enabled = IsWindows8OrGreater(); + BOOL enabled = FALSE; - // HACK: Use DwmFlush when desktop composition is enabled - if (enabled || - (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)) + if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled) { int count = abs(window->context.wgl.interval); while (count--) @@ -345,20 +347,19 @@ static void swapBuffersWGL(_GLFWwindow* window) static void swapIntervalWGL(int interval) { _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); + assert(window != NULL); window->context.wgl.interval = interval; if (!window->monitor) { - if (IsWindowsVistaOrGreater()) + // HACK: Disable WGL swap interval when desktop composition is enabled on Windows + // Vista and 7 to avoid interfering with DWM vsync + if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater()) { - // DWM Composition is always enabled on Win8+ - BOOL enabled = IsWindows8OrGreater(); + BOOL enabled = FALSE; - // HACK: Disable WGL swap interval when desktop composition is enabled to - // avoid interfering with DWM vsync - if (enabled || - (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)) + if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled) interval = 0; } } @@ -388,7 +389,7 @@ static GLFWglproc getProcAddressWGL(const char* procname) if (proc) return proc; - return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname); + return (GLFWglproc) _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, procname); } static void destroyContextWGL(_GLFWwindow* window) @@ -400,11 +401,6 @@ static void destroyContextWGL(_GLFWwindow* window) } } - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - // Initialize WGL // GLFWbool _glfwInitWGL(void) @@ -416,7 +412,7 @@ GLFWbool _glfwInitWGL(void) if (_glfw.wgl.instance) return GLFW_TRUE; - _glfw.wgl.instance = LoadLibraryA("opengl32.dll"); + _glfw.wgl.instance = _glfwPlatformLoadModule("opengl32.dll"); if (!_glfw.wgl.instance) { _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, @@ -425,19 +421,19 @@ GLFWbool _glfwInitWGL(void) } _glfw.wgl.CreateContext = (PFN_wglCreateContext) - GetProcAddress(_glfw.wgl.instance, "wglCreateContext"); + _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglCreateContext"); _glfw.wgl.DeleteContext = (PFN_wglDeleteContext) - GetProcAddress(_glfw.wgl.instance, "wglDeleteContext"); + _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglDeleteContext"); _glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress) - GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress"); + _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetProcAddress"); _glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC) - GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC"); + _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetCurrentDC"); _glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext) - GetProcAddress(_glfw.wgl.instance, "wglGetCurrentContext"); + _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetCurrentContext"); _glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent) - GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent"); + _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglMakeCurrent"); _glfw.wgl.ShareLists = (PFN_wglShareLists) - GetProcAddress(_glfw.wgl.instance, "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 @@ -530,10 +526,10 @@ GLFWbool _glfwInitWGL(void) void _glfwTerminateWGL(void) { if (_glfw.wgl.instance) - FreeLibrary(_glfw.wgl.instance); + _glfwPlatformFreeModule(_glfw.wgl.instance); } -#define setAttrib(a, v) \ +#define SET_ATTRIB(a, v) \ { \ assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ attribs[index++] = a; \ @@ -562,7 +558,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, return GLFW_FALSE; } - pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig); + pixelFormat = choosePixelFormatWGL(window, ctxconfig, fbconfig); if (!pixelFormat) return GLFW_FALSE; @@ -641,13 +637,13 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, { if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) { - setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, - WGL_NO_RESET_NOTIFICATION_ARB); + SET_ATTRIB(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, + WGL_NO_RESET_NOTIFICATION_ARB); } else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) { - setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, - WGL_LOSE_CONTEXT_ON_RESET_ARB); + SET_ATTRIB(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, + WGL_LOSE_CONTEXT_ON_RESET_ARB); } flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; @@ -660,13 +656,13 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, { if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) { - setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, - WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); + SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, + WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); } else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) { - setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, - WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); + SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, + WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); } } } @@ -674,7 +670,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, if (ctxconfig->noerror) { if (_glfw.wgl.ARB_create_context_no_error) - setAttrib(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE); + SET_ATTRIB(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE); } // NOTE: Only request an explicitly versioned context when necessary, as @@ -682,17 +678,17 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, // highest version supported by the driver if (ctxconfig->major != 1 || ctxconfig->minor != 0) { - setAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); - setAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); + SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); + SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); } if (flags) - setAttrib(WGL_CONTEXT_FLAGS_ARB, flags); + SET_ATTRIB(WGL_CONTEXT_FLAGS_ARB, flags); if (mask) - setAttrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask); + SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, mask); - setAttrib(0, 0); + SET_ATTRIB(0, 0); window->context.wgl.handle = wglCreateContextAttribsARB(window->context.wgl.dc, share, attribs); @@ -775,18 +771,20 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, return GLFW_TRUE; } -#undef setAttrib - - -////////////////////////////////////////////////////////////////////////// -////// GLFW native API ////// -////////////////////////////////////////////////////////////////////////// +#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); @@ -796,3 +794,5 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle) return window->context.wgl.handle; } +#endif // _GLFW_WIN32 + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/win32_init.c b/src/lib/src/vendor/glfw-3.4/src/win32_init.c similarity index 69% rename from src/lib/src/vendor/glfw-3.3.8/src/win32_init.c rename to src/lib/src/vendor/glfw-3.4/src/win32_init.c index 885f32f..824e383 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/win32_init.c +++ b/src/lib/src/vendor/glfw-3.4/src/win32_init.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Win32 - www.glfw.org +// GLFW 3.4 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -24,13 +24,12 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32) + #include -#include static const GUID _glfw_GUID_DEVINTERFACE_HID = {0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}}; @@ -82,7 +81,7 @@ static GLFWbool loadLibraries(void) return GLFW_FALSE; } - _glfw.win32.user32.instance = LoadLibraryA("user32.dll"); + _glfw.win32.user32.instance = _glfwPlatformLoadModule("user32.dll"); if (!_glfw.win32.user32.instance) { _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, @@ -91,25 +90,25 @@ static GLFWbool loadLibraries(void) } _glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware) - GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware"); + _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "SetProcessDPIAware"); _glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx) - GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx"); + _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx"); _glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling) - GetProcAddress(_glfw.win32.user32.instance, "EnableNonClientDpiScaling"); + _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "EnableNonClientDpiScaling"); _glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext) - GetProcAddress(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext"); + _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext"); _glfw.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow) - GetProcAddress(_glfw.win32.user32.instance, "GetDpiForWindow"); + _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "GetDpiForWindow"); _glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi) - GetProcAddress(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi"); + _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi"); _glfw.win32.user32.GetSystemMetricsForDpi_ = (PFN_GetSystemMetricsForDpi) - GetProcAddress(_glfw.win32.user32.instance, "GetSystemMetricsForDpi"); + _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "GetSystemMetricsForDpi"); - _glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll"); + _glfw.win32.dinput8.instance = _glfwPlatformLoadModule("dinput8.dll"); if (_glfw.win32.dinput8.instance) { _glfw.win32.dinput8.Create = (PFN_DirectInput8Create) - GetProcAddress(_glfw.win32.dinput8.instance, "DirectInput8Create"); + _glfwPlatformGetModuleSymbol(_glfw.win32.dinput8.instance, "DirectInput8Create"); } { @@ -126,46 +125,46 @@ static GLFWbool loadLibraries(void) for (i = 0; names[i]; i++) { - _glfw.win32.xinput.instance = LoadLibraryA(names[i]); + _glfw.win32.xinput.instance = _glfwPlatformLoadModule(names[i]); if (_glfw.win32.xinput.instance) { _glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities) - GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities"); + _glfwPlatformGetModuleSymbol(_glfw.win32.xinput.instance, "XInputGetCapabilities"); _glfw.win32.xinput.GetState = (PFN_XInputGetState) - GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState"); + _glfwPlatformGetModuleSymbol(_glfw.win32.xinput.instance, "XInputGetState"); break; } } } - _glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll"); + _glfw.win32.dwmapi.instance = _glfwPlatformLoadModule("dwmapi.dll"); if (_glfw.win32.dwmapi.instance) { _glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled) - GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); + _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); _glfw.win32.dwmapi.Flush = (PFN_DwmFlush) - GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush"); + _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmFlush"); _glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow) - GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow"); + _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow"); _glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor) - GetProcAddress(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor"); + _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor"); } - _glfw.win32.shcore.instance = LoadLibraryA("shcore.dll"); + _glfw.win32.shcore.instance = _glfwPlatformLoadModule("shcore.dll"); if (_glfw.win32.shcore.instance) { _glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness) - GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness"); + _glfwPlatformGetModuleSymbol(_glfw.win32.shcore.instance, "SetProcessDpiAwareness"); _glfw.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor) - GetProcAddress(_glfw.win32.shcore.instance, "GetDpiForMonitor"); + _glfwPlatformGetModuleSymbol(_glfw.win32.shcore.instance, "GetDpiForMonitor"); } - _glfw.win32.ntdll.instance = LoadLibraryA("ntdll.dll"); + _glfw.win32.ntdll.instance = _glfwPlatformLoadModule("ntdll.dll"); if (_glfw.win32.ntdll.instance) { _glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo) - GetProcAddress(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo"); + _glfwPlatformGetModuleSymbol(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo"); } return GLFW_TRUE; @@ -176,22 +175,22 @@ static GLFWbool loadLibraries(void) static void freeLibraries(void) { if (_glfw.win32.xinput.instance) - FreeLibrary(_glfw.win32.xinput.instance); + _glfwPlatformFreeModule(_glfw.win32.xinput.instance); if (_glfw.win32.dinput8.instance) - FreeLibrary(_glfw.win32.dinput8.instance); + _glfwPlatformFreeModule(_glfw.win32.dinput8.instance); if (_glfw.win32.user32.instance) - FreeLibrary(_glfw.win32.user32.instance); + _glfwPlatformFreeModule(_glfw.win32.user32.instance); if (_glfw.win32.dwmapi.instance) - FreeLibrary(_glfw.win32.dwmapi.instance); + _glfwPlatformFreeModule(_glfw.win32.dwmapi.instance); if (_glfw.win32.shcore.instance) - FreeLibrary(_glfw.win32.shcore.instance); + _glfwPlatformFreeModule(_glfw.win32.shcore.instance); if (_glfw.win32.ntdll.instance) - FreeLibrary(_glfw.win32.ntdll.instance); + _glfwPlatformFreeModule(_glfw.win32.ntdll.instance); } // Create key code translation tables @@ -332,15 +331,64 @@ static void createKeyTables(void) } } +// 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, - _GLFW_WNDCLASSNAME, + MAKEINTATOM(_glfw.win32.helperWindowClass), L"GLFW message window", WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 1, 1, @@ -382,7 +430,6 @@ static GLFWbool createHelperWindow(void) return GLFW_TRUE; } - ////////////////////////////////////////////////////////////////////////// ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// @@ -402,13 +449,13 @@ WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source) return NULL; } - target = calloc(count, sizeof(WCHAR)); + 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"); - free(target); + _glfw_free(target); return NULL; } @@ -430,13 +477,13 @@ char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source) return NULL; } - target = calloc(size, 1); + 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"); - free(target); + _glfw_free(target); return NULL; } @@ -551,88 +598,134 @@ BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build) return RtlVerifyVersionInfo(&osvi, mask, cond) == 0; } - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformInit(void) +GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform) { - // To make SetForegroundWindow work as we want, we need to fiddle - // with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early - // as possible in the hope of still being the foreground process) - SystemParametersInfoW(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, - &_glfw.win32.foregroundLockTimeout, 0); - SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0), - SPIF_SENDCHANGE); + 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; createKeyTables(); _glfwUpdateKeyNamesWin32(); - if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32()) + if (_glfwIsWindows10Version1703OrGreaterWin32()) SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); else if (IsWindows8Point1OrGreater()) SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); else if (IsWindowsVistaOrGreater()) SetProcessDPIAware(); - if (!_glfwRegisterWindowClassWin32()) - return GLFW_FALSE; - if (!createHelperWindow()) return GLFW_FALSE; - _glfwInitTimerWin32(); - _glfwInitJoysticksWin32(); - _glfwPollMonitorsWin32(); return GLFW_TRUE; } -void _glfwPlatformTerminate(void) +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); - _glfwUnregisterWindowClassWin32(); - - // Restore previous foreground lock timeout system setting - SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, - UIntToPtr(_glfw.win32.foregroundLockTimeout), - SPIF_SENDCHANGE); - - free(_glfw.win32.clipboardString); - free(_glfw.win32.rawInput); + _glfw_free(_glfw.win32.clipboardString); + _glfw_free(_glfw.win32.rawInput); _glfwTerminateWGL(); _glfwTerminateEGL(); _glfwTerminateOSMesa(); - _glfwTerminateJoysticksWin32(); - freeLibraries(); } -const char* _glfwPlatformGetVersionString(void) -{ - return _GLFW_VERSION_NUMBER " Win32 WGL EGL OSMesa" -#if defined(__MINGW32__) - " MinGW" -#elif defined(_MSC_VER) - " VisualC" -#endif -#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG) - " hybrid-GPU" -#endif -#if defined(_GLFW_BUILD_DLL) - " DLL" -#endif - ; -} +#endif // _GLFW_WIN32 diff --git a/src/lib/src/vendor/glfw-3.3.8/src/win32_joystick.c b/src/lib/src/vendor/glfw-3.4/src/win32_joystick.c similarity index 95% rename from src/lib/src/vendor/glfw-3.3.8/src/win32_joystick.c rename to src/lib/src/vendor/glfw-3.4/src/win32_joystick.c index f471f0a..59389a9 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/win32_joystick.c +++ b/src/lib/src/vendor/glfw-3.4/src/win32_joystick.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Win32 - www.glfw.org +// GLFW 3.4 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32) + #include #include @@ -199,11 +199,11 @@ static GLFWbool supportsXInput(const GUID* guid) if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0) return GLFW_FALSE; - ridl = calloc(count, sizeof(RAWINPUTDEVICELIST)); + ridl = _glfw_calloc(count, sizeof(RAWINPUTDEVICELIST)); if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1) { - free(ridl); + _glfw_free(ridl); return GLFW_FALSE; } @@ -248,7 +248,7 @@ static GLFWbool supportsXInput(const GUID* guid) } } - free(ridl); + _glfw_free(ridl); return result; } @@ -264,7 +264,7 @@ static void closeJoystick(_GLFWjoystick* js) IDirectInputDevice8_Release(js->win32.device); } - free(js->win32.objects); + _glfw_free(js->win32.objects); _glfwFreeJoystick(js); } @@ -416,8 +416,8 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user) memset(&data, 0, sizeof(data)); data.device = device; - data.objects = calloc(dc.dwAxes + (size_t) dc.dwButtons + dc.dwPOVs, - sizeof(_GLFWjoyobjectWin32)); + data.objects = _glfw_calloc(dc.dwAxes + (size_t) dc.dwButtons + dc.dwPOVs, + sizeof(_GLFWjoyobjectWin32)); if (FAILED(IDirectInputDevice8_EnumObjects(device, deviceObjectCallback, @@ -428,7 +428,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user) "Win32: Failed to enumerate device objects"); IDirectInputDevice8_Release(device); - free(data.objects); + _glfw_free(data.objects); return DIENUM_CONTINUE; } @@ -445,7 +445,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user) "Win32: Failed to convert joystick name to UTF-8"); IDirectInputDevice8_Release(device); - free(data.objects); + _glfw_free(data.objects); return DIENUM_STOP; } @@ -473,7 +473,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user) if (!js) { IDirectInputDevice8_Release(device); - free(data.objects); + _glfw_free(data.objects); return DIENUM_STOP; } @@ -491,39 +491,6 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user) ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// -// Initialize joystick interface -// -void _glfwInitJoysticksWin32(void) -{ - if (_glfw.win32.dinput8.instance) - { - if (FAILED(DirectInput8Create(_glfw.win32.instance, - DIRECTINPUT_VERSION, - &IID_IDirectInput8W, - (void**) &_glfw.win32.dinput8.api, - NULL))) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to create interface"); - } - } - - _glfwDetectJoystickConnectionWin32(); -} - -// Close all opened joystick handles -// -void _glfwTerminateJoysticksWin32(void) -{ - int jid; - - for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++) - closeJoystick(_glfw.joysticks + jid); - - if (_glfw.win32.dinput8.api) - IDirectInput8_Release(_glfw.win32.dinput8.api); -} - // Checks for new joysticks after DBT_DEVICEARRIVAL // void _glfwDetectJoystickConnectionWin32(void) @@ -594,7 +561,7 @@ void _glfwDetectJoystickDisconnectionWin32(void) { _GLFWjoystick* js = _glfw.joysticks + jid; if (js->connected) - _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE); + _glfwPollJoystickWin32(js, _GLFW_POLL_PRESENCE); } } @@ -603,7 +570,38 @@ void _glfwDetectJoystickDisconnectionWin32(void) ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) +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) { @@ -736,13 +734,25 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) 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; } -void _glfwPlatformUpdateGamepadGUID(char* guid) +const char* _glfwGetMappingNameWin32(void) +{ + return "Windows"; +} + +void _glfwUpdateGamepadGUIDWin32(char* guid) { if (strcmp(guid + 20, "504944564944") == 0) { @@ -753,3 +763,5 @@ void _glfwPlatformUpdateGamepadGUID(char* guid) } } +#endif // _GLFW_WIN32 + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/win32_joystick.h b/src/lib/src/vendor/glfw-3.4/src/win32_joystick.h similarity index 83% rename from src/lib/src/vendor/glfw-3.3.8/src/win32_joystick.h rename to src/lib/src/vendor/glfw-3.4/src/win32_joystick.h index d591a82..9ab6438 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/win32_joystick.h +++ b/src/lib/src/vendor/glfw-3.4/src/win32_joystick.h @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Win32 - www.glfw.org +// GLFW 3.4 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2006-2017 Camilla Löwy // @@ -24,11 +24,8 @@ // //======================================================================== -#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickWin32 win32 -#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyLibraryJoystick; } - -#define _GLFW_PLATFORM_MAPPING_NAME "Windows" -#define GLFW_BUILD_WIN32_MAPPINGS +#define GLFW_WIN32_JOYSTICK_STATE _GLFWjoystickWin32 win32; +#define GLFW_WIN32_LIBRARY_JOYSTICK_STATE // Joystick element (axis, button or slider) // @@ -49,9 +46,6 @@ typedef struct _GLFWjoystickWin32 GUID guid; } _GLFWjoystickWin32; - -void _glfwInitJoysticksWin32(void); -void _glfwTerminateJoysticksWin32(void); void _glfwDetectJoystickConnectionWin32(void); void _glfwDetectJoystickDisconnectionWin32(void); diff --git a/src/lib/src/vendor/glfw-3.3.8/src/null_monitor.c b/src/lib/src/vendor/glfw-3.4/src/win32_module.c similarity index 53% rename from src/lib/src/vendor/glfw-3.3.8/src/null_monitor.c rename to src/lib/src/vendor/glfw-3.4/src/win32_module.c index 4514dae..47c8dff 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/null_monitor.c +++ b/src/lib/src/vendor/glfw-3.4/src/win32_module.c @@ -1,8 +1,7 @@ //======================================================================== -// GLFW 3.3 - www.glfw.org +// GLFW 3.4 Win32 - www.glfw.org //------------------------------------------------------------------------ -// Copyright (c) 2016 Google Inc. -// Copyright (c) 2016-2019 Camilla Löwy +// Copyright (c) 2021 Camilla Löwy // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages @@ -24,54 +23,29 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_WIN32_MODULE) ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) +void* _glfwPlatformLoadModule(const char* path) { + return LoadLibraryA(path); } -void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +void _glfwPlatformFreeModule(void* module) { + FreeLibrary((HMODULE) module); } -void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, - float* xscale, float* yscale) +GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name) { - if (xscale) - *xscale = 1.f; - if (yscale) - *yscale = 1.f; + return (GLFWproc) GetProcAddress((HMODULE) module, name); } -void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, - int* xpos, int* ypos, - int* width, int* height) -{ -} - -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) -{ - return NULL; -} - -void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) -{ -} - -GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) -{ - return GLFW_FALSE; -} - -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) -{ -} +#endif // GLFW_BUILD_WIN32_MODULE diff --git a/src/lib/src/vendor/glfw-3.3.8/src/win32_monitor.c b/src/lib/src/vendor/glfw-3.4/src/win32_monitor.c similarity index 88% rename from src/lib/src/vendor/glfw-3.3.8/src/win32_monitor.c rename to src/lib/src/vendor/glfw-3.4/src/win32_monitor.c index 67337fd..87c85b9 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/win32_monitor.c +++ b/src/lib/src/vendor/glfw-3.4/src/win32_monitor.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Win32 - www.glfw.org +// GLFW 3.4 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -24,15 +24,14 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32) + #include #include #include -#include #include @@ -96,7 +95,7 @@ static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter, DeleteDC(dc); monitor = _glfwAllocMonitor(name, widthMM, heightMM); - free(name); + _glfw_free(name); if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED) monitor->win32.modesPruned = GLFW_TRUE; @@ -145,7 +144,7 @@ void _glfwPollMonitorsWin32(void) disconnectedCount = _glfw.monitorCount; if (disconnectedCount) { - disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*)); + disconnected = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*)); memcpy(disconnected, _glfw.monitors, _glfw.monitorCount * sizeof(_GLFWmonitor*)); @@ -197,7 +196,7 @@ void _glfwPollMonitorsWin32(void) monitor = createMonitor(&adapter, &display); if (!monitor) { - free(disconnected); + _glfw_free(disconnected); return; } @@ -227,7 +226,7 @@ void _glfwPollMonitorsWin32(void) monitor = createMonitor(&adapter, NULL); if (!monitor) { - free(disconnected); + _glfw_free(disconnected); return; } @@ -241,7 +240,7 @@ void _glfwPollMonitorsWin32(void) _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0); } - free(disconnected); + _glfw_free(disconnected); } // Change the current video mode @@ -254,7 +253,7 @@ void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired) LONG result; best = _glfwChooseVideoMode(monitor, desired); - _glfwPlatformGetVideoMode(monitor, ¤t); + _glfwGetVideoModeWin32(monitor, ¤t); if (_glfwCompareVideoModes(¤t, best) == 0) return; @@ -314,7 +313,7 @@ void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor) } } -void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale) +void _glfwGetHMONITORContentScaleWin32(HMONITOR handle, float* xscale, float* yscale) { UINT xdpi, ydpi; @@ -350,11 +349,11 @@ void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* ysc ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) +void _glfwFreeMonitorWin32(_GLFWmonitor* monitor) { } -void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +void _glfwGetMonitorPosWin32(_GLFWmonitor* monitor, int* xpos, int* ypos) { DEVMODEW dm; ZeroMemory(&dm, sizeof(dm)); @@ -371,15 +370,15 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) *ypos = dm.dmPosition.y; } -void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, - float* xscale, float* yscale) +void _glfwGetMonitorContentScaleWin32(_GLFWmonitor* monitor, + float* xscale, float* yscale) { - _glfwGetMonitorContentScaleWin32(monitor->win32.handle, xscale, yscale); + _glfwGetHMONITORContentScaleWin32(monitor->win32.handle, xscale, yscale); } -void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, - int* xpos, int* ypos, - int* width, int* height) +void _glfwGetMonitorWorkareaWin32(_GLFWmonitor* monitor, + int* xpos, int* ypos, + int* width, int* height) { MONITORINFO mi = { sizeof(mi) }; GetMonitorInfoW(monitor->win32.handle, &mi); @@ -394,7 +393,7 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, *height = mi.rcWork.bottom - mi.rcWork.top; } -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) +GLFWvidmode* _glfwGetVideoModesWin32(_GLFWmonitor* monitor, int* count) { int modeIndex = 0, size = 0; GLFWvidmode* result = NULL; @@ -453,7 +452,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) if (*count == size) { size += 128; - result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode)); + result = (GLFWvidmode*) _glfw_realloc(result, size * sizeof(GLFWvidmode)); } (*count)++; @@ -463,21 +462,25 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) if (!*count) { // HACK: Report the current mode if no valid modes were found - result = calloc(1, sizeof(GLFWvidmode)); - _glfwPlatformGetVideoMode(monitor, result); + result = _glfw_calloc(1, sizeof(GLFWvidmode)); + _glfwGetVideoModeWin32(monitor, result); *count = 1; } return result; } -void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) +GLFWbool _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode) { DEVMODEW dm; ZeroMemory(&dm, sizeof(dm)); dm.dmSize = sizeof(dm); - EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &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; @@ -486,9 +489,11 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) &mode->redBits, &mode->greenBits, &mode->blueBits); + + return GLFW_TRUE; } -GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwGetGammaRampWin32(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { HDC dc; WORD values[3][256]; @@ -506,7 +511,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) return GLFW_TRUE; } -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +void _glfwSetGammaRampWin32(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) { HDC dc; WORD values[3][256]; @@ -536,6 +541,13 @@ 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; } @@ -543,6 +555,15 @@ 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 + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/win32_platform.h b/src/lib/src/vendor/glfw-3.4/src/win32_platform.h similarity index 54% rename from src/lib/src/vendor/glfw-3.3.8/src/win32_platform.h rename to src/lib/src/vendor/glfw-3.4/src/win32_platform.h index bf703d7..7e3d884 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/win32_platform.h +++ b/src/lib/src/vendor/glfw-3.4/src/win32_platform.h @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Win32 - www.glfw.org +// GLFW 3.4 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -165,9 +165,6 @@ typedef enum // Replacement for versionhelpers.h macros, as we cannot rely on the // application having a correct embedded manifest // -#define IsWindowsXPOrGreater() \ - _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINXP), \ - LOBYTE(_WIN32_WINNT_WINXP), 0) #define IsWindowsVistaOrGreater() \ _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \ LOBYTE(_WIN32_WINNT_VISTA), 0) @@ -181,9 +178,11 @@ typedef enum _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \ LOBYTE(_WIN32_WINNT_WINBLUE), 0) -#define _glfwIsWindows10AnniversaryUpdateOrGreaterWin32() \ +// Windows 10 Anniversary Update +#define _glfwIsWindows10Version1607OrGreaterWin32() \ _glfwIsWindows10BuildOrGreaterWin32(14393) -#define _glfwIsWindows10CreatorsUpdateOrGreaterWin32() \ +// Windows 10 Creators Update +#define _glfwIsWindows10Version1703OrGreaterWin32() \ _glfwIsWindows10BuildOrGreaterWin32(15063) // HACK: Define macros that some xinput.h variants don't @@ -220,6 +219,57 @@ typedef enum #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*); @@ -266,6 +316,34 @@ typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*, 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 @@ -280,30 +358,55 @@ typedef struct VkWin32SurfaceCreateInfoKHR typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t); -#include "win32_joystick.h" -#include "wgl_context.h" -#include "egl_context.h" -#include "osmesa_context.h" +#define GLFW_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; -#if !defined(_GLFW_WNDCLASSNAME) - #define _GLFW_WNDCLASSNAME L"GLFW30" -#endif +#define GLFW_WGL_CONTEXT_STATE _GLFWcontextWGL wgl; +#define GLFW_WGL_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl; -#define _glfw_dlopen(name) LoadLibraryA(name) -#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle) -#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name) -#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->win32.handle) -#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY +// WGL-specific per-context data +// +typedef struct _GLFWcontextWGL +{ + HDC dc; + HGLRC handle; + int interval; +} _GLFWcontextWGL; -#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32 -#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32 -#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32 -#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32 -#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32 -#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsWin32 win32 -#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexWin32 win32 +// 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 // @@ -320,13 +423,15 @@ typedef struct _GLFWwindowWin32 // 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 recevied high surrogate when decoding pairs of UTF-16 messages + // The last received high surrogate when decoding pairs of UTF-16 messages WCHAR highSurrogate; } _GLFWwindowWin32; @@ -336,8 +441,9 @@ typedef struct _GLFWlibraryWin32 { HINSTANCE instance; HWND helperWindowHandle; + ATOM helperWindowClass; + ATOM mainWindowClass; HDEVNOTIFY deviceNotificationHandle; - DWORD foregroundLockTimeout; int acquiredMonitorCount; char* clipboardString; short int keycodes[512]; @@ -347,9 +453,13 @@ typedef struct _GLFWlibraryWin32 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; @@ -415,32 +525,10 @@ typedef struct _GLFWcursorWin32 HCURSOR handle; } _GLFWcursorWin32; -// Win32-specific global timer data -// -typedef struct _GLFWtimerWin32 -{ - uint64_t frequency; -} _GLFWtimerWin32; -// Win32-specific thread local storage data -// -typedef struct _GLFWtlsWin32 -{ - GLFWbool allocated; - DWORD index; -} _GLFWtlsWin32; - -// Win32-specific mutex data -// -typedef struct _GLFWmutexWin32 -{ - GLFWbool allocated; - CRITICAL_SECTION section; -} _GLFWmutexWin32; - - -GLFWbool _glfwRegisterWindowClassWin32(void); -void _glfwUnregisterWindowClassWin32(void); +GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform); +int _glfwInitWin32(void); +void _glfwTerminateWin32(void); WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source); char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source); @@ -449,10 +537,91 @@ BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build); void _glfwInputErrorWin32(int error, const char* description); void _glfwUpdateKeyNamesWin32(void); -void _glfwInitTimerWin32(void); - void _glfwPollMonitorsWin32(void); void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired); void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor); -void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale); +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); diff --git a/src/lib/src/vendor/glfw-3.3.8/src/win32_thread.c b/src/lib/src/vendor/glfw-3.4/src/win32_thread.c similarity index 90% rename from src/lib/src/vendor/glfw-3.3.8/src/win32_thread.c rename to src/lib/src/vendor/glfw-3.4/src/win32_thread.c index ce0686d..212e666 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/win32_thread.c +++ b/src/lib/src/vendor/glfw-3.4/src/win32_thread.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Win32 - www.glfw.org +// GLFW 3.4 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2017 Camilla Löwy @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_WIN32_THREAD) + #include @@ -43,8 +43,7 @@ GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls) tls->win32.index = TlsAlloc(); if (tls->win32.index == TLS_OUT_OF_INDEXES) { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "Win32: Failed to allocate TLS index"); + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to allocate TLS index"); return GLFW_FALSE; } @@ -97,3 +96,5 @@ void _glfwPlatformUnlockMutex(_GLFWmutex* mutex) LeaveCriticalSection(&mutex->win32.section); } +#endif // GLFW_BUILD_WIN32_THREAD + diff --git a/src/lib/src/vendor/glfw-3.4/src/win32_thread.h b/src/lib/src/vendor/glfw-3.4/src/win32_thread.h new file mode 100644 index 0000000..dd5948f --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/win32_thread.h @@ -0,0 +1,53 @@ +//======================================================================== +// GLFW 3.4 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2017 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as 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 + +#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; + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/win32_time.c b/src/lib/src/vendor/glfw-3.4/src/win32_time.c similarity index 79% rename from src/lib/src/vendor/glfw-3.3.8/src/win32_time.c rename to src/lib/src/vendor/glfw-3.4/src/win32_time.c index b4e31ab..a38e15d 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/win32_time.c +++ b/src/lib/src/vendor/glfw-3.4/src/win32_time.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Win32 - www.glfw.org +// GLFW 3.4 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2017 Camilla Löwy @@ -24,28 +24,20 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Initialise timer -// -void _glfwInitTimerWin32(void) -{ - QueryPerformanceFrequency((LARGE_INTEGER*) &_glfw.timer.win32.frequency); -} - +#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; @@ -58,3 +50,5 @@ uint64_t _glfwPlatformGetTimerFrequency(void) return _glfw.timer.win32.frequency; } +#endif // GLFW_BUILD_WIN32_TIMER + diff --git a/src/lib/src/vendor/glfw-3.4/src/win32_time.h b/src/lib/src/vendor/glfw-3.4/src/win32_time.h new file mode 100644 index 0000000..ef57a5a --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/win32_time.h @@ -0,0 +1,43 @@ +//======================================================================== +// GLFW 3.4 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2017 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as 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 + +#define GLFW_WIN32_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32; + +// Win32-specific global timer data +// +typedef struct _GLFWtimerWin32 +{ + uint64_t frequency; +} _GLFWtimerWin32; + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/win32_window.c b/src/lib/src/vendor/glfw-3.4/src/win32_window.c similarity index 72% rename from src/lib/src/vendor/glfw-3.3.8/src/win32_window.c rename to src/lib/src/vendor/glfw-3.4/src/win32_window.c index 073ceee..e6a9496 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/win32_window.c +++ b/src/lib/src/vendor/glfw-3.4/src/win32_window.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Win32 - www.glfw.org +// GLFW 3.4 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -24,14 +24,13 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32) + #include #include -#include #include #include #include @@ -98,8 +97,7 @@ static const GLFWimage* chooseImage(int count, const GLFWimage* images, // Creates an RGBA icon or cursor // -static HICON createIcon(const GLFWimage* image, - int xhot, int yhot, GLFWbool icon) +static HICON createIcon(const GLFWimage* image, int xhot, int yhot, GLFWbool icon) { int i; HDC dc; @@ -186,53 +184,38 @@ static HICON createIcon(const GLFWimage* image, return handle; } -// Translate content area size to full window size according to styles and DPI -// -static void getFullWindowSize(DWORD style, DWORD exStyle, - int contentWidth, int contentHeight, - int* fullWidth, int* fullHeight, - UINT dpi) -{ - RECT rect = { 0, 0, contentWidth, contentHeight }; - - if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) - AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi); - else - AdjustWindowRectEx(&rect, style, FALSE, exStyle); - - *fullWidth = rect.right - rect.left; - *fullHeight = rect.bottom - rect.top; -} - // Enforce the content area aspect ratio based on which edge is being dragged // static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area) { - int xoff, yoff; - UINT dpi = USER_DEFAULT_SCREEN_DPI; + RECT frame = {0}; const float ratio = (float) window->numer / (float) window->denom; + const DWORD style = getWindowStyle(window); + const DWORD exStyle = getWindowExStyle(window); - if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) - dpi = GetDpiForWindow(window->win32.handle); - - getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), - 0, 0, &xoff, &yoff, dpi); + if (_glfwIsWindows10Version1607OrGreaterWin32()) + { + AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle, + GetDpiForWindow(window->win32.handle)); + } + else + AdjustWindowRectEx(&frame, style, FALSE, exStyle); if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT || edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT) { - area->bottom = area->top + yoff + - (int) ((area->right - area->left - xoff) / ratio); + area->bottom = area->top + (frame.bottom - frame.top) + + (int) (((area->right - area->left) - (frame.right - frame.left)) / ratio); } else if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT) { - area->top = area->bottom - yoff - - (int) ((area->right - area->left - xoff) / ratio); + area->top = area->bottom - (frame.bottom - frame.top) - + (int) (((area->right - area->left) - (frame.right - frame.left)) / ratio); } else if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM) { - area->right = area->left + xoff + - (int) ((area->bottom - area->top - yoff) * ratio); + area->right = area->left + (frame.right - frame.left) + + (int) (((area->bottom - area->top) - (frame.bottom - frame.top)) * ratio); } } @@ -240,7 +223,8 @@ static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area) // static void updateCursorImage(_GLFWwindow* window) { - if (window->cursorMode == GLFW_CURSOR_NORMAL) + if (window->cursorMode == GLFW_CURSOR_NORMAL || + window->cursorMode == GLFW_CURSOR_CAPTURED) { if (window->cursor) SetCursor(window->cursor->win32.handle); @@ -248,23 +232,32 @@ static void updateCursorImage(_GLFWwindow* window) SetCursor(LoadCursorW(NULL, IDC_ARROW)); } else - SetCursor(NULL); + { + // NOTE: Via Remote Desktop, setting the cursor to NULL does not hide it. + // HACK: When running locally, it is set to NULL, but when connected via Remote + // Desktop, this is a transparent cursor. + SetCursor(_glfw.win32.blankCursor); + } } -// Updates the cursor clip rect +// Sets the cursor clip rect to the window content area // -static void updateClipRect(_GLFWwindow* window) +static void captureCursor(_GLFWwindow* window) { - if (window) - { - RECT clipRect; - GetClientRect(window->win32.handle, &clipRect); - ClientToScreen(window->win32.handle, (POINT*) &clipRect.left); - ClientToScreen(window->win32.handle, (POINT*) &clipRect.right); - ClipCursor(&clipRect); - } - else - ClipCursor(NULL); + RECT clipRect; + GetClientRect(window->win32.handle, &clipRect); + ClientToScreen(window->win32.handle, (POINT*) &clipRect.left); + ClientToScreen(window->win32.handle, (POINT*) &clipRect.right); + ClipCursor(&clipRect); + _glfw.win32.capturedCursorWindow = window; +} + +// Disabled clip cursor +// +static void releaseCursor(void) +{ + ClipCursor(NULL); + _glfw.win32.capturedCursorWindow = NULL; } // Enables WM_INPUT messages for the mouse for the specified window @@ -298,12 +291,12 @@ static void disableRawMouseMotion(_GLFWwindow* window) static void disableCursor(_GLFWwindow* window) { _glfw.win32.disabledCursorWindow = window; - _glfwPlatformGetCursorPos(window, - &_glfw.win32.restoreCursorPosX, - &_glfw.win32.restoreCursorPosY); + _glfwGetCursorPosWin32(window, + &_glfw.win32.restoreCursorPosX, + &_glfw.win32.restoreCursorPosY); updateCursorImage(window); _glfwCenterCursorInContentArea(window); - updateClipRect(window); + captureCursor(window); if (window->rawMouseMotion) enableRawMouseMotion(window); @@ -317,10 +310,10 @@ static void enableCursor(_GLFWwindow* window) disableRawMouseMotion(window); _glfw.win32.disabledCursorWindow = NULL; - updateClipRect(NULL); - _glfwPlatformSetCursorPos(window, - _glfw.win32.restoreCursorPosX, - _glfw.win32.restoreCursorPosY); + releaseCursor(); + _glfwSetCursorPosWin32(window, + _glfw.win32.restoreCursorPosX, + _glfw.win32.restoreCursorPosY); updateCursorImage(window); } @@ -355,7 +348,7 @@ static void updateWindowStyles(const _GLFWwindow* window) GetClientRect(window->win32.handle, &rect); - if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) + if (_glfwIsWindows10Version1607OrGreaterWin32()) { AdjustWindowRectExForDpi(&rect, style, FALSE, getWindowExStyle(window), @@ -454,11 +447,8 @@ static void acquireMonitor(_GLFWwindow* window) // HACK: When mouse trails are enabled the cursor becomes invisible when // the OpenGL ICD switches to page flipping - if (IsWindowsXPOrGreater()) - { - SystemParametersInfoW(SPI_GETMOUSETRAILS, 0, &_glfw.win32.mouseTrailSize, 0); - SystemParametersInfoW(SPI_SETMOUSETRAILS, 0, 0, 0); - } + SystemParametersInfoW(SPI_GETMOUSETRAILS, 0, &_glfw.win32.mouseTrailSize, 0); + SystemParametersInfoW(SPI_SETMOUSETRAILS, 0, 0, 0); } if (!window->monitor->window) @@ -481,8 +471,7 @@ static void releaseMonitor(_GLFWwindow* window) SetThreadExecutionState(ES_CONTINUOUS); // HACK: Restore mouse trail length saved in acquireMonitor - if (IsWindowsXPOrGreater()) - SystemParametersInfoW(SPI_SETMOUSETRAILS, _glfw.win32.mouseTrailSize, 0, 0); + SystemParametersInfoW(SPI_SETMOUSETRAILS, _glfw.win32.mouseTrailSize, 0, 0); } _glfwInputMonitorWindow(window->monitor, NULL); @@ -516,7 +505,7 @@ static void maximizeWindowManually(_GLFWwindow* window) { const DWORD exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE); - if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) + if (_glfwIsWindows10Version1607OrGreaterWin32()) { const UINT dpi = GetDpiForWindow(window->win32.handle); AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi); @@ -539,57 +528,26 @@ static void maximizeWindowManually(_GLFWwindow* window) SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED); } -// Window callback function (handles window messages) +// Window procedure for user-created windows // -static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, - WPARAM wParam, LPARAM lParam) +static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { _GLFWwindow* window = GetPropW(hWnd, L"GLFW"); if (!window) { - // This is the message handling for the hidden helper window - // and for a regular window during its initial creation - - switch (uMsg) + if (uMsg == WM_NCCREATE) { - case WM_NCCREATE: + if (_glfwIsWindows10Version1607OrGreaterWin32()) { - if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) - { - const CREATESTRUCTW* cs = (const CREATESTRUCTW*) lParam; - const _GLFWwndconfig* wndconfig = cs->lpCreateParams; + const CREATESTRUCTW* cs = (const CREATESTRUCTW*) lParam; + const _GLFWwndconfig* wndconfig = cs->lpCreateParams; - // On per-monitor DPI aware V1 systems, only enable - // non-client scaling for windows that scale the client area - // We need WM_GETDPISCALEDSIZE from V2 to keep the client - // area static when the non-client area is scaled - if (wndconfig && wndconfig->scaleToMonitor) - EnableNonClientDpiScaling(hWnd); - } - - break; - } - - case WM_DISPLAYCHANGE: - _glfwPollMonitorsWin32(); - break; - - case WM_DEVICECHANGE: - { - if (wParam == DBT_DEVICEARRIVAL) - { - DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam; - if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) - _glfwDetectJoystickConnectionWin32(); - } - else if (wParam == DBT_DEVICEREMOVECOMPLETE) - { - DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam; - if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) - _glfwDetectJoystickDisconnectionWin32(); - } - - break; + // On per-monitor DPI aware V1 systems, only enable + // non-client scaling for windows that scale the client area + // We need WM_GETDPISCALEDSIZE from V2 to keep the client + // area static when the non-client area is scaled + if (wndconfig && wndconfig->scaleToMonitor) + EnableNonClientDpiScaling(hWnd); } } @@ -619,6 +577,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, { if (window->cursorMode == GLFW_CURSOR_DISABLED) disableCursor(window); + else if (window->cursorMode == GLFW_CURSOR_CAPTURED) + captureCursor(window); window->win32.frameAction = GLFW_FALSE; } @@ -637,6 +597,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, if (window->cursorMode == GLFW_CURSOR_DISABLED) disableCursor(window); + else if (window->cursorMode == GLFW_CURSOR_CAPTURED) + captureCursor(window); return 0; } @@ -645,9 +607,11 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, { if (window->cursorMode == GLFW_CURSOR_DISABLED) enableCursor(window); + else if (window->cursorMode == GLFW_CURSOR_CAPTURED) + releaseCursor(); if (window->monitor && window->autoIconify) - _glfwPlatformIconifyWindow(window); + _glfwIconifyWindowWin32(window); _glfwInputWindowFocus(window, GLFW_FALSE); return 0; @@ -672,7 +636,12 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // User trying to access application menu using ALT? case SC_KEYMENU: - return 0; + { + if (!window->win32.keymenu) + return 0; + + break; + } } break; } @@ -714,6 +683,9 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, _glfwInputChar(window, codepoint, getKeyMods(), uMsg != WM_SYSCHAR); } + if (uMsg == WM_SYSCHAR && window->win32.keymenu) + break; + return 0; } @@ -811,7 +783,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, { // HACK: Release both Shift keys on Shift up event, as when both // are pressed the first release does not emit any event - // NOTE: The other half of this is in _glfwPlatformPollEvents + // NOTE: The other half of this is in _glfwPollEventsWin32 _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, action, mods); _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, action, mods); } @@ -939,8 +911,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, GetRawInputData(ri, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); if (size > (UINT) _glfw.win32.rawInputSize) { - free(_glfw.win32.rawInput); - _glfw.win32.rawInput = calloc(size, 1); + _glfw_free(_glfw.win32.rawInput); + _glfw.win32.rawInput = _glfw_calloc(size, 1); _glfw.win32.rawInputSize = size; } @@ -957,8 +929,28 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, data = _glfw.win32.rawInput; if (data->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) { - dx = data->data.mouse.lLastX - window->win32.lastCursorPosX; - dy = data->data.mouse.lLastY - window->win32.lastCursorPosY; + POINT pos = {0}; + int width, height; + + if (data->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) + { + pos.x += GetSystemMetrics(SM_XVIRTUALSCREEN); + pos.y += GetSystemMetrics(SM_YVIRTUALSCREEN); + width = GetSystemMetrics(SM_CXVIRTUALSCREEN); + height = GetSystemMetrics(SM_CYVIRTUALSCREEN); + } + else + { + width = GetSystemMetrics(SM_CXSCREEN); + height = GetSystemMetrics(SM_CYSCREEN); + } + + pos.x += (int) ((data->data.mouse.lLastX / 65535.f) * width); + pos.y += (int) ((data->data.mouse.lLastY / 65535.f) * height); + ScreenToClient(window->win32.handle, &pos); + + dx = pos.x - window->win32.lastCursorPosX; + dy = pos.y - window->win32.lastCursorPosY; } else { @@ -1006,6 +998,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // resizing the window or using the window menu if (window->cursorMode == GLFW_CURSOR_DISABLED) enableCursor(window); + else if (window->cursorMode == GLFW_CURSOR_CAPTURED) + releaseCursor(); break; } @@ -1020,6 +1014,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // resizing the window or using the menu if (window->cursorMode == GLFW_CURSOR_DISABLED) disableCursor(window); + else if (window->cursorMode == GLFW_CURSOR_CAPTURED) + captureCursor(window); break; } @@ -1033,8 +1029,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, (window->win32.maximized && wParam != SIZE_RESTORED); - if (_glfw.win32.disabledCursorWindow == window) - updateClipRect(window); + if (_glfw.win32.capturedCursorWindow == window) + captureCursor(window); if (window->win32.iconified != iconified) _glfwInputWindowIconify(window, iconified); @@ -1069,8 +1065,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, case WM_MOVE: { - if (_glfw.win32.disabledCursorWindow == window) - updateClipRect(window); + if (_glfw.win32.capturedCursorWindow == window) + captureCursor(window); // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as // those macros do not handle negative window positions correctly @@ -1094,31 +1090,34 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, case WM_GETMINMAXINFO: { - int xoff, yoff; - UINT dpi = USER_DEFAULT_SCREEN_DPI; + RECT frame = {0}; MINMAXINFO* mmi = (MINMAXINFO*) lParam; + const DWORD style = getWindowStyle(window); + const DWORD exStyle = getWindowExStyle(window); if (window->monitor) break; - if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) - dpi = GetDpiForWindow(window->win32.handle); - - getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), - 0, 0, &xoff, &yoff, dpi); + if (_glfwIsWindows10Version1607OrGreaterWin32()) + { + AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle, + GetDpiForWindow(window->win32.handle)); + } + else + AdjustWindowRectEx(&frame, style, FALSE, exStyle); if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE) { - mmi->ptMinTrackSize.x = window->minwidth + xoff; - mmi->ptMinTrackSize.y = window->minheight + yoff; + mmi->ptMinTrackSize.x = window->minwidth + frame.right - frame.left; + mmi->ptMinTrackSize.y = window->minheight + frame.bottom - frame.top; } if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE) { - mmi->ptMaxTrackSize.x = window->maxwidth + xoff; - mmi->ptMaxTrackSize.y = window->maxheight + yoff; + mmi->ptMaxTrackSize.x = window->maxwidth + frame.right - frame.left; + mmi->ptMaxTrackSize.y = window->maxheight + frame.bottom - frame.top; } if (!window->decorated) @@ -1176,7 +1175,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, break; // Adjust the window size to keep the content area size constant - if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32()) + if (_glfwIsWindows10Version1703OrGreaterWin32()) { RECT source = {0}, target = {0}; SIZE* size = (SIZE*) lParam; @@ -1207,7 +1206,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // need it to compensate for non-client area scaling if (!window->monitor && (window->win32.scaleToMonitor || - _glfwIsWindows10CreatorsUpdateOrGreaterWin32())) + _glfwIsWindows10Version1703OrGreaterWin32())) { RECT* suggested = (RECT*) lParam; SetWindowPos(window->win32.handle, HWND_TOP, @@ -1240,7 +1239,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, int i; const int count = DragQueryFileW(drop, 0xffffffff, NULL, 0); - char** paths = calloc(count, sizeof(char*)); + char** paths = _glfw_calloc(count, sizeof(char*)); // Move the mouse to the position of the drop DragQueryPoint(drop, &pt); @@ -1249,19 +1248,19 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, for (i = 0; i < count; i++) { const UINT length = DragQueryFileW(drop, i, NULL, 0); - WCHAR* buffer = calloc((size_t) length + 1, sizeof(WCHAR)); + WCHAR* buffer = _glfw_calloc((size_t) length + 1, sizeof(WCHAR)); DragQueryFileW(drop, i, buffer, length + 1); paths[i] = _glfwCreateUTF8FromWideStringWin32(buffer); - free(buffer); + _glfw_free(buffer); } _glfwInputDrop(window, count, (const char**) paths); for (i = 0; i < count; i++) - free(paths[i]); - free(paths); + _glfw_free(paths[i]); + _glfw_free(paths); DragFinish(drop); return 0; @@ -1277,11 +1276,72 @@ static int createNativeWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWfbconfig* fbconfig) { - int xpos, ypos, fullWidth, fullHeight; + int frameX, frameY, frameWidth, frameHeight; WCHAR* wideTitle; DWORD style = getWindowStyle(window); DWORD exStyle = getWindowExStyle(window); + if (!_glfw.win32.mainWindowClass) + { + WNDCLASSEXW wc = { sizeof(wc) }; + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = windowProc; + wc.hInstance = _glfw.win32.instance; + wc.hCursor = LoadCursorW(NULL, IDC_ARROW); +#if defined(_GLFW_WNDCLASSNAME) + wc.lpszClassName = _GLFW_WNDCLASSNAME; +#else + wc.lpszClassName = L"GLFW30"; +#endif + // Load user-provided icon if available + wc.hIcon = LoadImageW(GetModuleHandleW(NULL), + L"GLFW_ICON", IMAGE_ICON, + 0, 0, LR_DEFAULTSIZE | LR_SHARED); + if (!wc.hIcon) + { + // No user-provided icon found, load default icon + wc.hIcon = LoadImageW(NULL, + IDI_APPLICATION, IMAGE_ICON, + 0, 0, LR_DEFAULTSIZE | LR_SHARED); + } + + _glfw.win32.mainWindowClass = RegisterClassExW(&wc); + if (!_glfw.win32.mainWindowClass) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "Win32: Failed to register window class"); + return GLFW_FALSE; + } + } + + if (GetSystemMetrics(SM_REMOTESESSION)) + { + // NOTE: On Remote Desktop, setting the cursor to NULL does not hide it + // HACK: Create a transparent cursor and always set that instead of NULL + // When not on Remote Desktop, this handle is NULL and normal hiding is used + if (!_glfw.win32.blankCursor) + { + const int cursorWidth = GetSystemMetrics(SM_CXCURSOR); + const int cursorHeight = GetSystemMetrics(SM_CYCURSOR); + + unsigned char* cursorPixels = _glfw_calloc(cursorWidth * cursorHeight, 4); + if (!cursorPixels) + return GLFW_FALSE; + + // NOTE: Windows checks whether the image is fully transparent and if so + // just ignores the alpha channel and makes the whole cursor opaque + // HACK: Make one pixel slightly less transparent + cursorPixels[3] = 1; + + const GLFWimage cursorImage = { cursorWidth, cursorHeight, cursorPixels }; + _glfw.win32.blankCursor = createIcon(&cursorImage, 0, 0, FALSE); + _glfw_free(cursorPixels); + + if (!_glfw.win32.blankCursor) + return GLFW_FALSE; + } + } + if (window->monitor) { MONITORINFO mi = { sizeof(mi) }; @@ -1290,24 +1350,34 @@ static int createNativeWindow(_GLFWwindow* window, // NOTE: This window placement is temporary and approximate, as the // correct position and size cannot be known until the monitor // video mode has been picked in _glfwSetVideoModeWin32 - xpos = mi.rcMonitor.left; - ypos = mi.rcMonitor.top; - fullWidth = mi.rcMonitor.right - mi.rcMonitor.left; - fullHeight = mi.rcMonitor.bottom - mi.rcMonitor.top; + frameX = mi.rcMonitor.left; + frameY = mi.rcMonitor.top; + frameWidth = mi.rcMonitor.right - mi.rcMonitor.left; + frameHeight = mi.rcMonitor.bottom - mi.rcMonitor.top; } else { - xpos = CW_USEDEFAULT; - ypos = CW_USEDEFAULT; + RECT rect = { 0, 0, wndconfig->width, wndconfig->height }; window->win32.maximized = wndconfig->maximized; if (wndconfig->maximized) style |= WS_MAXIMIZE; - getFullWindowSize(style, exStyle, - wndconfig->width, wndconfig->height, - &fullWidth, &fullHeight, - USER_DEFAULT_SCREEN_DPI); + AdjustWindowRectEx(&rect, style, FALSE, exStyle); + + if (wndconfig->xpos == GLFW_ANY_POSITION && wndconfig->ypos == GLFW_ANY_POSITION) + { + frameX = CW_USEDEFAULT; + frameY = CW_USEDEFAULT; + } + else + { + frameX = wndconfig->xpos + rect.left; + frameY = wndconfig->ypos + rect.top; + } + + frameWidth = rect.right - rect.left; + frameHeight = rect.bottom - rect.top; } wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title); @@ -1315,17 +1385,17 @@ static int createNativeWindow(_GLFWwindow* window, return GLFW_FALSE; window->win32.handle = CreateWindowExW(exStyle, - _GLFW_WNDCLASSNAME, + MAKEINTATOM(_glfw.win32.mainWindowClass), wideTitle, style, - xpos, ypos, - fullWidth, fullHeight, + frameX, frameY, + frameWidth, frameHeight, NULL, // No parent window NULL, // No window menu _glfw.win32.instance, (LPVOID) wndconfig); - free(wideTitle); + _glfw_free(wideTitle); if (!window->win32.handle) { @@ -1347,6 +1417,8 @@ static int createNativeWindow(_GLFWwindow* window, } window->win32.scaleToMonitor = wndconfig->scaleToMonitor; + window->win32.keymenu = wndconfig->win32.keymenu; + window->win32.showDefault = wndconfig->win32.showDefault; if (!window->monitor) { @@ -1363,7 +1435,7 @@ static int createNativeWindow(_GLFWwindow* window, if (wndconfig->scaleToMonitor) { float xscale, yscale; - _glfwGetMonitorContentScaleWin32(mh, &xscale, &yscale); + _glfwGetHMONITORContentScaleWin32(mh, &xscale, &yscale); if (xscale > 0.f && yscale > 0.f) { @@ -1372,7 +1444,7 @@ static int createNativeWindow(_GLFWwindow* window, } } - if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) + if (_glfwIsWindows10Version1607OrGreaterWin32()) { AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, GetDpiForWindow(window->win32.handle)); @@ -1414,68 +1486,15 @@ static int createNativeWindow(_GLFWwindow* window, window->win32.transparent = GLFW_TRUE; } - _glfwPlatformGetWindowSize(window, &window->win32.width, &window->win32.height); + _glfwGetWindowSizeWin32(window, &window->win32.width, &window->win32.height); return GLFW_TRUE; } - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Registers the GLFW window class -// -GLFWbool _glfwRegisterWindowClassWin32(void) -{ - WNDCLASSEXW wc; - - ZeroMemory(&wc, sizeof(wc)); - wc.cbSize = sizeof(wc); - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = windowProc; - wc.hInstance = _glfw.win32.instance; - wc.hCursor = LoadCursorW(NULL, IDC_ARROW); - wc.lpszClassName = _GLFW_WNDCLASSNAME; - - // Load user-provided icon if available - wc.hIcon = LoadImageW(GetModuleHandleW(NULL), - L"GLFW_ICON", IMAGE_ICON, - 0, 0, LR_DEFAULTSIZE | LR_SHARED); - if (!wc.hIcon) - { - // No user-provided icon found, load default icon - wc.hIcon = LoadImageW(NULL, - IDI_APPLICATION, IMAGE_ICON, - 0, 0, LR_DEFAULTSIZE | LR_SHARED); - } - - if (!RegisterClassExW(&wc)) - { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "Win32: Failed to register window class"); - return GLFW_FALSE; - } - - return GLFW_TRUE; -} - -// Unregisters the GLFW window class -// -void _glfwUnregisterWindowClassWin32(void) -{ - UnregisterClassW(_GLFW_WNDCLASSNAME, _glfw.win32.instance); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformCreateWindow(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) +GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) { if (!createNativeWindow(window, wndconfig, fbconfig)) return GLFW_FALSE; @@ -1508,10 +1527,13 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, return GLFW_FALSE; } + if (wndconfig->mousePassthrough) + _glfwSetWindowMousePassthroughWin32(window, GLFW_TRUE); + if (window->monitor) { - _glfwPlatformShowWindow(window); - _glfwPlatformFocusWindow(window); + _glfwShowWindowWin32(window); + _glfwFocusWindowWin32(window); acquireMonitor(window); fitToMonitor(window); @@ -1522,16 +1544,16 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, { if (wndconfig->visible) { - _glfwPlatformShowWindow(window); + _glfwShowWindowWin32(window); if (wndconfig->focused) - _glfwPlatformFocusWindow(window); + _glfwFocusWindowWin32(window); } } return GLFW_TRUE; } -void _glfwPlatformDestroyWindow(_GLFWwindow* window) +void _glfwDestroyWindowWin32(_GLFWwindow* window) { if (window->monitor) releaseMonitor(window); @@ -1540,7 +1562,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) window->context.destroy(window); if (_glfw.win32.disabledCursorWindow == window) - _glfw.win32.disabledCursorWindow = NULL; + enableCursor(window); + + if (_glfw.win32.capturedCursorWindow == window) + releaseCursor(); if (window->win32.handle) { @@ -1556,18 +1581,17 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) DestroyIcon(window->win32.smallIcon); } -void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) +void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title) { WCHAR* wideTitle = _glfwCreateWideStringFromUTF8Win32(title); if (!wideTitle) return; SetWindowTextW(window->win32.handle, wideTitle); - free(wideTitle); + _glfw_free(wideTitle); } -void _glfwPlatformSetWindowIcon(_GLFWwindow* window, - int count, const GLFWimage* images) +void _glfwSetWindowIconWin32(_GLFWwindow* window, int count, const GLFWimage* images) { HICON bigIcon = NULL, smallIcon = NULL; @@ -1605,7 +1629,7 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window, } } -void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) +void _glfwGetWindowPosWin32(_GLFWwindow* window, int* xpos, int* ypos) { POINT pos = { 0, 0 }; ClientToScreen(window->win32.handle, &pos); @@ -1616,11 +1640,11 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) *ypos = pos.y; } -void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) +void _glfwSetWindowPosWin32(_GLFWwindow* window, int xpos, int ypos) { RECT rect = { xpos, ypos, xpos, ypos }; - if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) + if (_glfwIsWindows10Version1607OrGreaterWin32()) { AdjustWindowRectExForDpi(&rect, getWindowStyle(window), FALSE, getWindowExStyle(window), @@ -1636,7 +1660,7 @@ void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE); } -void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) +void _glfwGetWindowSizeWin32(_GLFWwindow* window, int* width, int* height) { RECT area; GetClientRect(window->win32.handle, &area); @@ -1647,7 +1671,7 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) *height = area.bottom; } -void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) +void _glfwSetWindowSizeWin32(_GLFWwindow* window, int width, int height) { if (window->monitor) { @@ -1661,7 +1685,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) { RECT rect = { 0, 0, width, height }; - if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) + if (_glfwIsWindows10Version1607OrGreaterWin32()) { AdjustWindowRectExForDpi(&rect, getWindowStyle(window), FALSE, getWindowExStyle(window), @@ -1679,9 +1703,9 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) } } -void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, - int minwidth, int minheight, - int maxwidth, int maxheight) +void _glfwSetWindowSizeLimitsWin32(_GLFWwindow* window, + int minwidth, int minheight, + int maxwidth, int maxheight) { RECT area; @@ -1698,7 +1722,7 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, area.bottom - area.top, TRUE); } -void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom) +void _glfwSetWindowAspectRatioWin32(_GLFWwindow* window, int numer, int denom) { RECT area; @@ -1713,22 +1737,22 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom area.bottom - area.top, TRUE); } -void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) +void _glfwGetFramebufferSizeWin32(_GLFWwindow* window, int* width, int* height) { - _glfwPlatformGetWindowSize(window, width, height); + _glfwGetWindowSizeWin32(window, width, height); } -void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, - int* left, int* top, - int* right, int* bottom) +void _glfwGetWindowFrameSizeWin32(_GLFWwindow* window, + int* left, int* top, + int* right, int* bottom) { RECT rect; int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); + _glfwGetWindowSizeWin32(window, &width, &height); SetRect(&rect, 0, 0, width, height); - if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) + if (_glfwIsWindows10Version1607OrGreaterWin32()) { AdjustWindowRectExForDpi(&rect, getWindowStyle(window), FALSE, getWindowExStyle(window), @@ -1750,25 +1774,24 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, *bottom = rect.bottom - height; } -void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, - float* xscale, float* yscale) +void _glfwGetWindowContentScaleWin32(_GLFWwindow* window, float* xscale, float* yscale) { const HANDLE handle = MonitorFromWindow(window->win32.handle, MONITOR_DEFAULTTONEAREST); - _glfwGetMonitorContentScaleWin32(handle, xscale, yscale); + _glfwGetHMONITORContentScaleWin32(handle, xscale, yscale); } -void _glfwPlatformIconifyWindow(_GLFWwindow* window) +void _glfwIconifyWindowWin32(_GLFWwindow* window) { ShowWindow(window->win32.handle, SW_MINIMIZE); } -void _glfwPlatformRestoreWindow(_GLFWwindow* window) +void _glfwRestoreWindowWin32(_GLFWwindow* window) { ShowWindow(window->win32.handle, SW_RESTORE); } -void _glfwPlatformMaximizeWindow(_GLFWwindow* window) +void _glfwMaximizeWindowWin32(_GLFWwindow* window) { if (IsWindowVisible(window->win32.handle)) ShowWindow(window->win32.handle, SW_MAXIMIZE); @@ -1776,33 +1799,49 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window) maximizeWindowManually(window); } -void _glfwPlatformShowWindow(_GLFWwindow* window) +void _glfwShowWindowWin32(_GLFWwindow* window) { - ShowWindow(window->win32.handle, SW_SHOWNA); + int showCommand = SW_SHOWNA; + + if (window->win32.showDefault) + { + // NOTE: GLFW windows currently do not seem to match the Windows 10 definition of + // a main window, so even SW_SHOWDEFAULT does nothing + // This definition is undocumented and can change (source: Raymond Chen) + // HACK: Apply the STARTUPINFO show command manually if available + STARTUPINFOW si = { sizeof(si) }; + GetStartupInfoW(&si); + if (si.dwFlags & STARTF_USESHOWWINDOW) + showCommand = si.wShowWindow; + + window->win32.showDefault = GLFW_FALSE; + } + + ShowWindow(window->win32.handle, showCommand); } -void _glfwPlatformHideWindow(_GLFWwindow* window) +void _glfwHideWindowWin32(_GLFWwindow* window) { ShowWindow(window->win32.handle, SW_HIDE); } -void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) +void _glfwRequestWindowAttentionWin32(_GLFWwindow* window) { FlashWindow(window->win32.handle, TRUE); } -void _glfwPlatformFocusWindow(_GLFWwindow* window) +void _glfwFocusWindowWin32(_GLFWwindow* window) { BringWindowToTop(window->win32.handle); SetForegroundWindow(window->win32.handle); SetFocus(window->win32.handle); } -void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, - _GLFWmonitor* monitor, - int xpos, int ypos, - int width, int height, - int refreshRate) +void _glfwSetWindowMonitorWin32(_GLFWwindow* window, + _GLFWmonitor* monitor, + int xpos, int ypos, + int width, int height, + int refreshRate) { if (window->monitor == monitor) { @@ -1818,7 +1857,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, { RECT rect = { xpos, ypos, xpos + width, ypos + height }; - if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) + if (_glfwIsWindows10Version1607OrGreaterWin32()) { AdjustWindowRectExForDpi(&rect, getWindowStyle(window), FALSE, getWindowExStyle(window), @@ -1889,7 +1928,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, else after = HWND_NOTOPMOST; - if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) + if (_glfwIsWindows10Version1607OrGreaterWin32()) { AdjustWindowRectExForDpi(&rect, getWindowStyle(window), FALSE, getWindowExStyle(window), @@ -1908,32 +1947,32 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, } } -int _glfwPlatformWindowFocused(_GLFWwindow* window) +GLFWbool _glfwWindowFocusedWin32(_GLFWwindow* window) { return window->win32.handle == GetActiveWindow(); } -int _glfwPlatformWindowIconified(_GLFWwindow* window) +GLFWbool _glfwWindowIconifiedWin32(_GLFWwindow* window) { return IsIconic(window->win32.handle); } -int _glfwPlatformWindowVisible(_GLFWwindow* window) +GLFWbool _glfwWindowVisibleWin32(_GLFWwindow* window) { return IsWindowVisible(window->win32.handle); } -int _glfwPlatformWindowMaximized(_GLFWwindow* window) +GLFWbool _glfwWindowMaximizedWin32(_GLFWwindow* window) { return IsZoomed(window->win32.handle); } -int _glfwPlatformWindowHovered(_GLFWwindow* window) +GLFWbool _glfwWindowHoveredWin32(_GLFWwindow* window) { return cursorInContentArea(window); } -int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) +GLFWbool _glfwFramebufferTransparentWin32(_GLFWwindow* window) { BOOL composition, opaque; DWORD color; @@ -1960,24 +1999,54 @@ int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) return GLFW_TRUE; } -void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) +void _glfwSetWindowResizableWin32(_GLFWwindow* window, GLFWbool enabled) { updateWindowStyles(window); } -void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) +void _glfwSetWindowDecoratedWin32(_GLFWwindow* window, GLFWbool enabled) { updateWindowStyles(window); } -void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) +void _glfwSetWindowFloatingWin32(_GLFWwindow* window, GLFWbool enabled) { const HWND after = enabled ? HWND_TOPMOST : HWND_NOTOPMOST; SetWindowPos(window->win32.handle, after, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } -float _glfwPlatformGetWindowOpacity(_GLFWwindow* window) +void _glfwSetWindowMousePassthroughWin32(_GLFWwindow* window, GLFWbool enabled) +{ + COLORREF key = 0; + BYTE alpha = 0; + DWORD flags = 0; + DWORD exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE); + + if (exStyle & WS_EX_LAYERED) + GetLayeredWindowAttributes(window->win32.handle, &key, &alpha, &flags); + + if (enabled) + exStyle |= (WS_EX_TRANSPARENT | WS_EX_LAYERED); + else + { + exStyle &= ~WS_EX_TRANSPARENT; + // NOTE: Window opacity also needs the layered window style so do not + // remove it if the window is alpha blended + if (exStyle & WS_EX_LAYERED) + { + if (!(flags & LWA_ALPHA)) + exStyle &= ~WS_EX_LAYERED; + } + } + + SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle); + + if (enabled) + SetLayeredWindowAttributes(window->win32.handle, key, alpha, flags); +} + +float _glfwGetWindowOpacityWin32(_GLFWwindow* window) { BYTE alpha; DWORD flags; @@ -1992,25 +2061,28 @@ float _glfwPlatformGetWindowOpacity(_GLFWwindow* window) return 1.f; } -void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) +void _glfwSetWindowOpacityWin32(_GLFWwindow* window, float opacity) { - if (opacity < 1.f) + LONG exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE); + if (opacity < 1.f || (exStyle & WS_EX_TRANSPARENT)) { const BYTE alpha = (BYTE) (255 * opacity); - DWORD style = GetWindowLongW(window->win32.handle, GWL_EXSTYLE); - style |= WS_EX_LAYERED; - SetWindowLongW(window->win32.handle, GWL_EXSTYLE, style); + exStyle |= WS_EX_LAYERED; + SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle); SetLayeredWindowAttributes(window->win32.handle, 0, alpha, LWA_ALPHA); } + else if (exStyle & WS_EX_TRANSPARENT) + { + SetLayeredWindowAttributes(window->win32.handle, 0, 0, 0); + } else { - DWORD style = GetWindowLongW(window->win32.handle, GWL_EXSTYLE); - style &= ~WS_EX_LAYERED; - SetWindowLongW(window->win32.handle, GWL_EXSTYLE, style); + exStyle &= ~WS_EX_LAYERED; + SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle); } } -void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) +void _glfwSetRawMouseMotionWin32(_GLFWwindow *window, GLFWbool enabled) { if (_glfw.win32.disabledCursorWindow != window) return; @@ -2021,12 +2093,12 @@ void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) disableRawMouseMotion(window); } -GLFWbool _glfwPlatformRawMouseMotionSupported(void) +GLFWbool _glfwRawMouseMotionSupportedWin32(void) { return GLFW_TRUE; } -void _glfwPlatformPollEvents(void) +void _glfwPollEventsWin32(void) { MSG msg; HWND handle; @@ -2096,38 +2168,39 @@ void _glfwPlatformPollEvents(void) if (window) { int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); + _glfwGetWindowSizeWin32(window, &width, &height); // NOTE: Re-center the cursor only if it has moved since the last call, // to avoid breaking glfwWaitEvents with WM_MOUSEMOVE + // The re-center is required in order to prevent the mouse cursor stopping at the edges of the screen. if (window->win32.lastCursorPosX != width / 2 || window->win32.lastCursorPosY != height / 2) { - _glfwPlatformSetCursorPos(window, width / 2, height / 2); + _glfwSetCursorPosWin32(window, width / 2, height / 2); } } } -void _glfwPlatformWaitEvents(void) +void _glfwWaitEventsWin32(void) { WaitMessage(); - _glfwPlatformPollEvents(); + _glfwPollEventsWin32(); } -void _glfwPlatformWaitEventsTimeout(double timeout) +void _glfwWaitEventsTimeoutWin32(double timeout) { - MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLEVENTS); + MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLINPUT); - _glfwPlatformPollEvents(); + _glfwPollEventsWin32(); } -void _glfwPlatformPostEmptyEvent(void) +void _glfwPostEmptyEventWin32(void) { PostMessageW(_glfw.win32.helperWindowHandle, WM_NULL, 0, 0); } -void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) +void _glfwGetCursorPosWin32(_GLFWwindow* window, double* xpos, double* ypos) { POINT pos; @@ -2142,7 +2215,7 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) } } -void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos) +void _glfwSetCursorPosWin32(_GLFWwindow* window, double xpos, double ypos) { POINT pos = { (int) xpos, (int) ypos }; @@ -2154,39 +2227,68 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos) SetCursorPos(pos.x, pos.y); } -void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) +void _glfwSetCursorModeWin32(_GLFWwindow* window, int mode) { - if (mode == GLFW_CURSOR_DISABLED) + if (_glfwWindowFocusedWin32(window)) { - if (_glfwPlatformWindowFocused(window)) - disableCursor(window); + if (mode == GLFW_CURSOR_DISABLED) + { + _glfwGetCursorPosWin32(window, + &_glfw.win32.restoreCursorPosX, + &_glfw.win32.restoreCursorPosY); + _glfwCenterCursorInContentArea(window); + if (window->rawMouseMotion) + enableRawMouseMotion(window); + } + else if (_glfw.win32.disabledCursorWindow == window) + { + if (window->rawMouseMotion) + disableRawMouseMotion(window); + } + + if (mode == GLFW_CURSOR_DISABLED || mode == GLFW_CURSOR_CAPTURED) + captureCursor(window); + else + releaseCursor(); + + if (mode == GLFW_CURSOR_DISABLED) + _glfw.win32.disabledCursorWindow = window; + else if (_glfw.win32.disabledCursorWindow == window) + { + _glfw.win32.disabledCursorWindow = NULL; + _glfwSetCursorPosWin32(window, + _glfw.win32.restoreCursorPosX, + _glfw.win32.restoreCursorPosY); + } } - else if (_glfw.win32.disabledCursorWindow == window) - enableCursor(window); - else if (cursorInContentArea(window)) + + if (cursorInContentArea(window)) updateCursorImage(window); } -const char* _glfwPlatformGetScancodeName(int scancode) +const char* _glfwGetScancodeNameWin32(int scancode) { - if (scancode < 0 || scancode > (KF_EXTENDED | 0xff) || - _glfw.win32.keycodes[scancode] == GLFW_KEY_UNKNOWN) + if (scancode < 0 || scancode > (KF_EXTENDED | 0xff)) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode); return NULL; } - return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]]; + const int key = _glfw.win32.keycodes[scancode]; + if (key == GLFW_KEY_UNKNOWN) + return NULL; + + return _glfw.win32.keynames[key]; } -int _glfwPlatformGetKeyScancode(int key) +int _glfwGetKeyScancodeWin32(int key) { return _glfw.win32.scancodes[key]; } -int _glfwPlatformCreateCursor(_GLFWcursor* cursor, - const GLFWimage* image, - int xhot, int yhot) +GLFWbool _glfwCreateCursorWin32(_GLFWcursor* cursor, + const GLFWimage* image, + int xhot, int yhot) { cursor->win32.handle = (HCURSOR) createIcon(image, xhot, yhot, GLFW_FALSE); if (!cursor->win32.handle) @@ -2195,24 +2297,46 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, return GLFW_TRUE; } -int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) +GLFWbool _glfwCreateStandardCursorWin32(_GLFWcursor* cursor, int shape) { int id = 0; - if (shape == GLFW_ARROW_CURSOR) - id = OCR_NORMAL; - else if (shape == GLFW_IBEAM_CURSOR) - id = OCR_IBEAM; - else if (shape == GLFW_CROSSHAIR_CURSOR) - id = OCR_CROSS; - else if (shape == GLFW_HAND_CURSOR) - id = OCR_HAND; - else if (shape == GLFW_HRESIZE_CURSOR) - id = OCR_SIZEWE; - else if (shape == GLFW_VRESIZE_CURSOR) - id = OCR_SIZENS; - else - return GLFW_FALSE; + switch (shape) + { + case GLFW_ARROW_CURSOR: + id = OCR_NORMAL; + break; + case GLFW_IBEAM_CURSOR: + id = OCR_IBEAM; + break; + case GLFW_CROSSHAIR_CURSOR: + id = OCR_CROSS; + break; + case GLFW_POINTING_HAND_CURSOR: + id = OCR_HAND; + break; + case GLFW_RESIZE_EW_CURSOR: + id = OCR_SIZEWE; + break; + case GLFW_RESIZE_NS_CURSOR: + id = OCR_SIZENS; + break; + case GLFW_RESIZE_NWSE_CURSOR: + id = OCR_SIZENWSE; + break; + case GLFW_RESIZE_NESW_CURSOR: + id = OCR_SIZENESW; + break; + case GLFW_RESIZE_ALL_CURSOR: + id = OCR_SIZEALL; + break; + case GLFW_NOT_ALLOWED_CURSOR: + id = OCR_NO; + break; + default: + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Unknown standard cursor"); + return GLFW_FALSE; + } cursor->win32.handle = LoadImageW(NULL, MAKEINTRESOURCEW(id), IMAGE_CURSOR, 0, 0, @@ -2227,21 +2351,21 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) return GLFW_TRUE; } -void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) +void _glfwDestroyCursorWin32(_GLFWcursor* cursor) { if (cursor->win32.handle) DestroyIcon((HICON) cursor->win32.handle); } -void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) +void _glfwSetCursorWin32(_GLFWwindow* window, _GLFWcursor* cursor) { if (cursorInContentArea(window)) updateCursorImage(window); } -void _glfwPlatformSetClipboardString(const char* string) +void _glfwSetClipboardStringWin32(const char* string) { - int characterCount; + int characterCount, tries = 0; HANDLE object; WCHAR* buffer; @@ -2269,12 +2393,20 @@ void _glfwPlatformSetClipboardString(const char* string) MultiByteToWideChar(CP_UTF8, 0, string, -1, buffer, characterCount); GlobalUnlock(object); - if (!OpenClipboard(_glfw.win32.helperWindowHandle)) + // NOTE: Retry clipboard opening a few times as some other application may have it + // open and also the Windows Clipboard History reads it after each update + while (!OpenClipboard(_glfw.win32.helperWindowHandle)) { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "Win32: Failed to open clipboard"); - GlobalFree(object); - return; + Sleep(1); + tries++; + + if (tries == 3) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "Win32: Failed to open clipboard"); + GlobalFree(object); + return; + } } EmptyClipboard(); @@ -2282,16 +2414,25 @@ void _glfwPlatformSetClipboardString(const char* string) CloseClipboard(); } -const char* _glfwPlatformGetClipboardString(void) +const char* _glfwGetClipboardStringWin32(void) { HANDLE object; WCHAR* buffer; + int tries = 0; - if (!OpenClipboard(_glfw.win32.helperWindowHandle)) + // NOTE: Retry clipboard opening a few times as some other application may have it + // open and also the Windows Clipboard History reads it after each update + while (!OpenClipboard(_glfw.win32.helperWindowHandle)) { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "Win32: Failed to open clipboard"); - return NULL; + Sleep(1); + tries++; + + if (tries == 3) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "Win32: Failed to open clipboard"); + return NULL; + } } object = GetClipboardData(CF_UNICODETEXT); @@ -2312,7 +2453,7 @@ const char* _glfwPlatformGetClipboardString(void) return NULL; } - free(_glfw.win32.clipboardString); + _glfw_free(_glfw.win32.clipboardString); _glfw.win32.clipboardString = _glfwCreateUTF8FromWideStringWin32(buffer); GlobalUnlock(object); @@ -2321,7 +2462,58 @@ const char* _glfwPlatformGetClipboardString(void) return _glfw.win32.clipboardString; } -void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) +EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs) +{ + if (_glfw.egl.ANGLE_platform_angle) + { + int type = 0; + + if (_glfw.egl.ANGLE_platform_angle_opengl) + { + if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGL) + type = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE; + else if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGLES) + type = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE; + } + + if (_glfw.egl.ANGLE_platform_angle_d3d) + { + if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_D3D9) + type = EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE; + else if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_D3D11) + type = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE; + } + + if (_glfw.egl.ANGLE_platform_angle_vulkan) + { + if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_VULKAN) + type = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE; + } + + if (type) + { + *attribs = _glfw_calloc(3, sizeof(EGLint)); + (*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE; + (*attribs)[1] = type; + (*attribs)[2] = EGL_NONE; + return EGL_PLATFORM_ANGLE_ANGLE; + } + } + + return 0; +} + +EGLNativeDisplayType _glfwGetEGLNativeDisplayWin32(void) +{ + return GetDC(_glfw.win32.helperWindowHandle); +} + +EGLNativeWindowType _glfwGetEGLNativeWindowWin32(_GLFWwindow* window) +{ + return window->win32.handle; +} + +void _glfwGetRequiredInstanceExtensionsWin32(char** extensions) { if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_win32_surface) return; @@ -2330,9 +2522,9 @@ void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) extensions[1] = "VK_KHR_win32_surface"; } -int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, - VkPhysicalDevice device, - uint32_t queuefamily) +GLFWbool _glfwGetPhysicalDevicePresentationSupportWin32(VkInstance instance, + VkPhysicalDevice device, + uint32_t queuefamily) { PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR = @@ -2348,10 +2540,10 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, return vkGetPhysicalDeviceWin32PresentationSupportKHR(device, queuefamily); } -VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, - _GLFWwindow* window, - const VkAllocationCallbacks* allocator, - VkSurfaceKHR* surface) +VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance, + _GLFWwindow* window, + const VkAllocationCallbacks* allocator, + VkSurfaceKHR* surface) { VkResult err; VkWin32SurfaceCreateInfoKHR sci; @@ -2382,15 +2574,20 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, return err; } - -////////////////////////////////////////////////////////////////////////// -////// GLFW native API ////// -////////////////////////////////////////////////////////////////////////// - GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) 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 window->win32.handle; } +#endif // _GLFW_WIN32 + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/window.c b/src/lib/src/vendor/glfw-3.4/src/window.c similarity index 81% rename from src/lib/src/vendor/glfw-3.3.8/src/window.c rename to src/lib/src/vendor/glfw-3.4/src/window.c index 5d80e43..1463d16 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/window.c +++ b/src/lib/src/vendor/glfw-3.4/src/window.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 - www.glfw.org +// GLFW 3.4 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -25,8 +25,6 @@ // distribution. // //======================================================================== -// Please use C89 style variable declarations in this file because VS 2010 -//======================================================================== #include "internal.h" @@ -44,6 +42,9 @@ // void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused) { + assert(window != NULL); + assert(focused == GLFW_TRUE || focused == GLFW_FALSE); + if (window->callbacks.focus) window->callbacks.focus((GLFWwindow*) window, focused); @@ -55,7 +56,7 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused) { if (window->keys[key] == GLFW_PRESS) { - const int scancode = _glfwPlatformGetKeyScancode(key); + const int scancode = _glfw.platform.getKeyScancode(key); _glfwInputKey(window, key, scancode, GLFW_RELEASE, 0); } } @@ -73,6 +74,8 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused) // void _glfwInputWindowPos(_GLFWwindow* window, int x, int y) { + assert(window != NULL); + if (window->callbacks.pos) window->callbacks.pos((GLFWwindow*) window, x, y); } @@ -82,6 +85,10 @@ void _glfwInputWindowPos(_GLFWwindow* window, int x, int y) // void _glfwInputWindowSize(_GLFWwindow* window, int width, int height) { + assert(window != NULL); + assert(width >= 0); + assert(height >= 0); + if (window->callbacks.size) window->callbacks.size((GLFWwindow*) window, width, height); } @@ -90,6 +97,9 @@ void _glfwInputWindowSize(_GLFWwindow* window, int width, int height) // void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified) { + assert(window != NULL); + assert(iconified == GLFW_TRUE || iconified == GLFW_FALSE); + if (window->callbacks.iconify) window->callbacks.iconify((GLFWwindow*) window, iconified); } @@ -98,6 +108,9 @@ void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified) // void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized) { + assert(window != NULL); + assert(maximized == GLFW_TRUE || maximized == GLFW_FALSE); + if (window->callbacks.maximize) window->callbacks.maximize((GLFWwindow*) window, maximized); } @@ -107,6 +120,10 @@ void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized) // void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height) { + assert(window != NULL); + assert(width >= 0); + assert(height >= 0); + if (window->callbacks.fbsize) window->callbacks.fbsize((GLFWwindow*) window, width, height); } @@ -116,6 +133,12 @@ void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height) // void _glfwInputWindowContentScale(_GLFWwindow* window, float xscale, float yscale) { + assert(window != NULL); + assert(xscale > 0.f); + assert(xscale < FLT_MAX); + assert(yscale > 0.f); + assert(yscale < FLT_MAX); + if (window->callbacks.scale) window->callbacks.scale((GLFWwindow*) window, xscale, yscale); } @@ -124,6 +147,8 @@ void _glfwInputWindowContentScale(_GLFWwindow* window, float xscale, float yscal // void _glfwInputWindowDamage(_GLFWwindow* window) { + assert(window != NULL); + if (window->callbacks.refresh) window->callbacks.refresh((GLFWwindow*) window); } @@ -132,6 +157,8 @@ void _glfwInputWindowDamage(_GLFWwindow* window) // void _glfwInputWindowCloseRequest(_GLFWwindow* window) { + assert(window != NULL); + window->shouldClose = GLFW_TRUE; if (window->callbacks.close) @@ -142,6 +169,7 @@ void _glfwInputWindowCloseRequest(_GLFWwindow* window) // void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor) { + assert(window != NULL); window->monitor = monitor; } @@ -186,7 +214,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, if (!_glfwIsValidContextConfig(&ctxconfig)) return NULL; - window = calloc(1, sizeof(_GLFWwindow)); + window = _glfw_calloc(1, sizeof(_GLFWwindow)); window->next = _glfw.windowListHead; _glfw.windowListHead = window; @@ -197,13 +225,14 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->videoMode.blueBits = fbconfig.blueBits; window->videoMode.refreshRate = _glfw.hints.refreshRate; - window->monitor = (_GLFWmonitor*) monitor; - window->resizable = wndconfig.resizable; - window->decorated = wndconfig.decorated; - window->autoIconify = wndconfig.autoIconify; - window->floating = wndconfig.floating; - window->focusOnShow = wndconfig.focusOnShow; - window->cursorMode = GLFW_CURSOR_NORMAL; + window->monitor = (_GLFWmonitor*) monitor; + window->resizable = wndconfig.resizable; + window->decorated = wndconfig.decorated; + window->autoIconify = wndconfig.autoIconify; + window->floating = wndconfig.floating; + window->focusOnShow = wndconfig.focusOnShow; + window->mousePassthrough = wndconfig.mousePassthrough; + window->cursorMode = GLFW_CURSOR_NORMAL; window->doublebuffer = fbconfig.doublebuffer; @@ -213,9 +242,9 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->maxheight = GLFW_DONT_CARE; window->numer = GLFW_DONT_CARE; window->denom = GLFW_DONT_CARE; + window->title = _glfw_strdup(title); - // Open the actual window and create its context - if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig)) + if (!_glfw.platform.createWindow(window, &wndconfig, &ctxconfig, &fbconfig)) { glfwDestroyWindow((GLFWwindow*) window); return NULL; @@ -244,6 +273,9 @@ void glfwDefaultWindowHints(void) _glfw.hints.window.autoIconify = GLFW_TRUE; _glfw.hints.window.centerCursor = GLFW_TRUE; _glfw.hints.window.focusOnShow = GLFW_TRUE; + _glfw.hints.window.xpos = GLFW_ANY_POSITION; + _glfw.hints.window.ypos = GLFW_ANY_POSITION; + _glfw.hints.window.scaleFramebuffer = GLFW_TRUE; // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil, // double buffered @@ -258,9 +290,6 @@ void glfwDefaultWindowHints(void) // The default is to select the highest available refresh rate _glfw.hints.refreshRate = GLFW_DONT_CARE; - - // The default is to use full Retina resolution framebuffers - _glfw.hints.window.ns.retina = GLFW_TRUE; } GLFWAPI void glfwWindowHint(int hint, int value) @@ -338,8 +367,17 @@ GLFWAPI void glfwWindowHint(int hint, int value) case GLFW_VISIBLE: _glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE; return; - case GLFW_COCOA_RETINA_FRAMEBUFFER: - _glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE; + case GLFW_POSITION_X: + _glfw.hints.window.xpos = value; + return; + case GLFW_POSITION_Y: + _glfw.hints.window.ypos = value; + return; + case GLFW_WIN32_KEYBOARD_MENU: + _glfw.hints.window.win32.keymenu = value ? GLFW_TRUE : GLFW_FALSE; + return; + case GLFW_WIN32_SHOWDEFAULT: + _glfw.hints.window.win32.showDefault = value ? GLFW_TRUE : GLFW_FALSE; return; case GLFW_COCOA_GRAPHICS_SWITCHING: _glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE; @@ -347,12 +385,19 @@ GLFWAPI void glfwWindowHint(int hint, int value) case GLFW_SCALE_TO_MONITOR: _glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE; return; + case GLFW_SCALE_FRAMEBUFFER: + case GLFW_COCOA_RETINA_FRAMEBUFFER: + _glfw.hints.window.scaleFramebuffer = value ? GLFW_TRUE : GLFW_FALSE; + return; case GLFW_CENTER_CURSOR: _glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE; return; case GLFW_FOCUS_ON_SHOW: _glfw.hints.window.focusOnShow = value ? GLFW_TRUE : GLFW_FALSE; return; + case GLFW_MOUSE_PASSTHROUGH: + _glfw.hints.window.mousePassthrough = value ? GLFW_TRUE : GLFW_FALSE; + return; case GLFW_CLIENT_API: _glfw.hints.context.client = value; return; @@ -371,7 +416,7 @@ GLFWAPI void glfwWindowHint(int hint, int value) case GLFW_OPENGL_FORWARD_COMPAT: _glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE; return; - case GLFW_OPENGL_DEBUG_CONTEXT: + case GLFW_CONTEXT_DEBUG: _glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE; return; case GLFW_CONTEXT_NO_ERROR: @@ -411,6 +456,10 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value) strncpy(_glfw.hints.window.x11.instanceName, value, sizeof(_glfw.hints.window.x11.instanceName) - 1); return; + case GLFW_WAYLAND_APP_ID: + strncpy(_glfw.hints.window.wl.appId, value, + sizeof(_glfw.hints.window.wl.appId) - 1); + return; } _glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint string 0x%08X", hint); @@ -434,7 +483,7 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle) if (window == _glfwPlatformGetTls(&_glfw.contextSlot)) glfwMakeContextCurrent(NULL); - _glfwPlatformDestroyWindow(window); + _glfw.platform.destroyWindow(window); // Unlink window from global linked list { @@ -446,7 +495,8 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle) *prev = window->next; } - free(window); + _glfw_free(window->title); + _glfw_free(window); } GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle) @@ -467,6 +517,16 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value) window->shouldClose = value; } +GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + return window->title; +} + GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) { _GLFWwindow* window = (_GLFWwindow*) handle; @@ -474,7 +534,12 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) assert(title != NULL); _GLFW_REQUIRE_INIT(); - _glfwPlatformSetWindowTitle(window, title); + + char* prev = window->title; + window->title = _glfw_strdup(title); + + _glfw.platform.setWindowTitle(window, title); + _glfw_free(prev); } GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle, @@ -507,7 +572,7 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle, } } - _glfwPlatformSetWindowIcon(window, count, images); + _glfw.platform.setWindowIcon(window, count, images); } GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) @@ -521,7 +586,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) *ypos = 0; _GLFW_REQUIRE_INIT(); - _glfwPlatformGetWindowPos(window, xpos, ypos); + _glfw.platform.getWindowPos(window, xpos, ypos); } GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) @@ -534,7 +599,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) if (window->monitor) return; - _glfwPlatformSetWindowPos(window, xpos, ypos); + _glfw.platform.setWindowPos(window, xpos, ypos); } GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height) @@ -548,7 +613,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height) *height = 0; _GLFW_REQUIRE_INIT(); - _glfwPlatformGetWindowSize(window, width, height); + _glfw.platform.getWindowSize(window, width, height); } GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height) @@ -563,7 +628,7 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height) window->videoMode.width = width; window->videoMode.height = height; - _glfwPlatformSetWindowSize(window, width, height); + _glfw.platform.setWindowSize(window, width, height); } GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle, @@ -606,9 +671,9 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle, if (window->monitor || !window->resizable) return; - _glfwPlatformSetWindowSizeLimits(window, - minwidth, minheight, - maxwidth, maxheight); + _glfw.platform.setWindowSizeLimits(window, + minwidth, minheight, + maxwidth, maxheight); } GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom) @@ -637,7 +702,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom) if (window->monitor || !window->resizable) return; - _glfwPlatformSetWindowAspectRatio(window, numer, denom); + _glfw.platform.setWindowAspectRatio(window, numer, denom); } GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height) @@ -651,7 +716,7 @@ GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height) *height = 0; _GLFW_REQUIRE_INIT(); - _glfwPlatformGetFramebufferSize(window, width, height); + _glfw.platform.getFramebufferSize(window, width, height); } GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle, @@ -671,7 +736,7 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle, *bottom = 0; _GLFW_REQUIRE_INIT(); - _glfwPlatformGetWindowFrameSize(window, left, top, right, bottom); + _glfw.platform.getWindowFrameSize(window, left, top, right, bottom); } GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle, @@ -686,7 +751,7 @@ GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle, *yscale = 0.f; _GLFW_REQUIRE_INIT(); - _glfwPlatformGetWindowContentScale(window, xscale, yscale); + _glfw.platform.getWindowContentScale(window, xscale, yscale); } GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle) @@ -694,8 +759,8 @@ GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle) _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(1.f); - return _glfwPlatformGetWindowOpacity(window); + _GLFW_REQUIRE_INIT_OR_RETURN(0.f); + return _glfw.platform.getWindowOpacity(window); } GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity) @@ -714,7 +779,7 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity) return; } - _glfwPlatformSetWindowOpacity(window, opacity); + _glfw.platform.setWindowOpacity(window, opacity); } GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) @@ -723,7 +788,7 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) assert(window != NULL); _GLFW_REQUIRE_INIT(); - _glfwPlatformIconifyWindow(window); + _glfw.platform.iconifyWindow(window); } GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) @@ -732,7 +797,7 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) assert(window != NULL); _GLFW_REQUIRE_INIT(); - _glfwPlatformRestoreWindow(window); + _glfw.platform.restoreWindow(window); } GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle) @@ -745,7 +810,7 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle) if (window->monitor) return; - _glfwPlatformMaximizeWindow(window); + _glfw.platform.maximizeWindow(window); } GLFWAPI void glfwShowWindow(GLFWwindow* handle) @@ -758,10 +823,10 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle) if (window->monitor) return; - _glfwPlatformShowWindow(window); + _glfw.platform.showWindow(window); if (window->focusOnShow) - _glfwPlatformFocusWindow(window); + _glfw.platform.focusWindow(window); } GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle) @@ -771,7 +836,7 @@ GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle) _GLFW_REQUIRE_INIT(); - _glfwPlatformRequestWindowAttention(window); + _glfw.platform.requestWindowAttention(window); } GLFWAPI void glfwHideWindow(GLFWwindow* handle) @@ -784,7 +849,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* handle) if (window->monitor) return; - _glfwPlatformHideWindow(window); + _glfw.platform.hideWindow(window); } GLFWAPI void glfwFocusWindow(GLFWwindow* handle) @@ -794,7 +859,7 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* handle) _GLFW_REQUIRE_INIT(); - _glfwPlatformFocusWindow(window); + _glfw.platform.focusWindow(window); } GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) @@ -807,19 +872,21 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) switch (attrib) { case GLFW_FOCUSED: - return _glfwPlatformWindowFocused(window); + return _glfw.platform.windowFocused(window); case GLFW_ICONIFIED: - return _glfwPlatformWindowIconified(window); + return _glfw.platform.windowIconified(window); case GLFW_VISIBLE: - return _glfwPlatformWindowVisible(window); + return _glfw.platform.windowVisible(window); case GLFW_MAXIMIZED: - return _glfwPlatformWindowMaximized(window); + return _glfw.platform.windowMaximized(window); case GLFW_HOVERED: - return _glfwPlatformWindowHovered(window); + return _glfw.platform.windowHovered(window); case GLFW_FOCUS_ON_SHOW: return window->focusOnShow; + case GLFW_MOUSE_PASSTHROUGH: + return window->mousePassthrough; case GLFW_TRANSPARENT_FRAMEBUFFER: - return _glfwPlatformFramebufferTransparent(window); + return _glfw.platform.framebufferTransparent(window); case GLFW_RESIZABLE: return window->resizable; case GLFW_DECORATED: @@ -828,6 +895,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) return window->floating; case GLFW_AUTO_ICONIFY: return window->autoIconify; + case GLFW_DOUBLEBUFFER: + return window->doublebuffer; case GLFW_CLIENT_API: return window->context.client; case GLFW_CONTEXT_CREATION_API: @@ -842,7 +911,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) return window->context.robustness; case GLFW_OPENGL_FORWARD_COMPAT: return window->context.forward; - case GLFW_OPENGL_DEBUG_CONTEXT: + case GLFW_CONTEXT_DEBUG: return window->context.debug; case GLFW_OPENGL_PROFILE: return window->context.profile; @@ -865,39 +934,41 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value) value = value ? GLFW_TRUE : GLFW_FALSE; - if (attrib == GLFW_AUTO_ICONIFY) - window->autoIconify = value; - else if (attrib == GLFW_RESIZABLE) + switch (attrib) { - if (window->resizable == value) + case GLFW_AUTO_ICONIFY: + window->autoIconify = value; return; - window->resizable = value; - if (!window->monitor) - _glfwPlatformSetWindowResizable(window, value); - } - else if (attrib == GLFW_DECORATED) - { - if (window->decorated == value) + case GLFW_RESIZABLE: + window->resizable = value; + if (!window->monitor) + _glfw.platform.setWindowResizable(window, value); return; - window->decorated = value; - if (!window->monitor) - _glfwPlatformSetWindowDecorated(window, value); - } - else if (attrib == GLFW_FLOATING) - { - if (window->floating == value) + case GLFW_DECORATED: + window->decorated = value; + if (!window->monitor) + _glfw.platform.setWindowDecorated(window, value); return; - window->floating = value; - if (!window->monitor) - _glfwPlatformSetWindowFloating(window, value); + case GLFW_FLOATING: + window->floating = value; + if (!window->monitor) + _glfw.platform.setWindowFloating(window, value); + return; + + case GLFW_FOCUS_ON_SHOW: + window->focusOnShow = value; + return; + + case GLFW_MOUSE_PASSTHROUGH: + window->mousePassthrough = value; + _glfw.platform.setWindowMousePassthrough(window, value); + return; } - else if (attrib == GLFW_FOCUS_ON_SHOW) - window->focusOnShow = value; - else - _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib); + + _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib); } GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) @@ -943,9 +1014,9 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh, window->videoMode.height = height; window->videoMode.refreshRate = refreshRate; - _glfwPlatformSetWindowMonitor(window, monitor, - xpos, ypos, width, height, - refreshRate); + _glfw.platform.setWindowMonitor(window, monitor, + xpos, ypos, width, height, + refreshRate); } GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) @@ -973,7 +1044,7 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.pos, cbfun); + _GLFW_SWAP(GLFWwindowposfun, window->callbacks.pos, cbfun); return cbfun; } @@ -984,7 +1055,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.size, cbfun); + _GLFW_SWAP(GLFWwindowsizefun, window->callbacks.size, cbfun); return cbfun; } @@ -995,7 +1066,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.close, cbfun); + _GLFW_SWAP(GLFWwindowclosefun, window->callbacks.close, cbfun); return cbfun; } @@ -1006,7 +1077,7 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.refresh, cbfun); + _GLFW_SWAP(GLFWwindowrefreshfun, window->callbacks.refresh, cbfun); return cbfun; } @@ -1017,7 +1088,7 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.focus, cbfun); + _GLFW_SWAP(GLFWwindowfocusfun, window->callbacks.focus, cbfun); return cbfun; } @@ -1028,7 +1099,7 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.iconify, cbfun); + _GLFW_SWAP(GLFWwindowiconifyfun, window->callbacks.iconify, cbfun); return cbfun; } @@ -1039,7 +1110,7 @@ GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.maximize, cbfun); + _GLFW_SWAP(GLFWwindowmaximizefun, window->callbacks.maximize, cbfun); return cbfun; } @@ -1050,7 +1121,7 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.fbsize, cbfun); + _GLFW_SWAP(GLFWframebuffersizefun, window->callbacks.fbsize, cbfun); return cbfun; } @@ -1061,20 +1132,20 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.scale, cbfun); + _GLFW_SWAP(GLFWwindowcontentscalefun, window->callbacks.scale, cbfun); return cbfun; } GLFWAPI void glfwPollEvents(void) { _GLFW_REQUIRE_INIT(); - _glfwPlatformPollEvents(); + _glfw.platform.pollEvents(); } GLFWAPI void glfwWaitEvents(void) { _GLFW_REQUIRE_INIT(); - _glfwPlatformWaitEvents(); + _glfw.platform.waitEvents(); } GLFWAPI void glfwWaitEventsTimeout(double timeout) @@ -1090,12 +1161,12 @@ GLFWAPI void glfwWaitEventsTimeout(double timeout) return; } - _glfwPlatformWaitEventsTimeout(timeout); + _glfw.platform.waitEventsTimeout(timeout); } GLFWAPI void glfwPostEmptyEvent(void) { _GLFW_REQUIRE_INIT(); - _glfwPlatformPostEmptyEvent(); + _glfw.platform.postEmptyEvent(); } diff --git a/src/lib/src/vendor/glfw-3.4/src/wl_init.c b/src/lib/src/vendor/glfw-3.4/src/wl_init.c new file mode 100644 index 0000000..3aff476 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/wl_init.c @@ -0,0 +1,1003 @@ +//======================================================================== +// GLFW 3.4 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#if defined(_GLFW_WAYLAND) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wayland-client-protocol.h" +#include "xdg-shell-client-protocol.h" +#include "xdg-decoration-unstable-v1-client-protocol.h" +#include "viewporter-client-protocol.h" +#include "relative-pointer-unstable-v1-client-protocol.h" +#include "pointer-constraints-unstable-v1-client-protocol.h" +#include "fractional-scale-v1-client-protocol.h" +#include "xdg-activation-v1-client-protocol.h" +#include "idle-inhibit-unstable-v1-client-protocol.h" + +// NOTE: Versions of wayland-scanner prior to 1.17.91 named every global array of +// wl_interface pointers 'types', making it impossible to combine several unmodified +// private-code files into a single compilation unit +// HACK: We override this name with a macro for each file, allowing them to coexist + +#define types _glfw_wayland_types +#include "wayland-client-protocol-code.h" +#undef types + +#define types _glfw_xdg_shell_types +#include "xdg-shell-client-protocol-code.h" +#undef types + +#define types _glfw_xdg_decoration_types +#include "xdg-decoration-unstable-v1-client-protocol-code.h" +#undef types + +#define types _glfw_viewporter_types +#include "viewporter-client-protocol-code.h" +#undef types + +#define types _glfw_relative_pointer_types +#include "relative-pointer-unstable-v1-client-protocol-code.h" +#undef types + +#define types _glfw_pointer_constraints_types +#include "pointer-constraints-unstable-v1-client-protocol-code.h" +#undef types + +#define types _glfw_fractional_scale_types +#include "fractional-scale-v1-client-protocol-code.h" +#undef types + +#define types _glfw_xdg_activation_types +#include "xdg-activation-v1-client-protocol-code.h" +#undef types + +#define types _glfw_idle_inhibit_types +#include "idle-inhibit-unstable-v1-client-protocol-code.h" +#undef types + +static void wmBaseHandlePing(void* userData, + struct xdg_wm_base* wmBase, + uint32_t serial) +{ + xdg_wm_base_pong(wmBase, serial); +} + +static const struct xdg_wm_base_listener wmBaseListener = +{ + wmBaseHandlePing +}; + +static void registryHandleGlobal(void* userData, + struct wl_registry* registry, + uint32_t name, + const char* interface, + uint32_t version) +{ + if (strcmp(interface, "wl_compositor") == 0) + { + _glfw.wl.compositor = + wl_registry_bind(registry, name, &wl_compositor_interface, + _glfw_min(3, version)); + } + else if (strcmp(interface, "wl_subcompositor") == 0) + { + _glfw.wl.subcompositor = + wl_registry_bind(registry, name, &wl_subcompositor_interface, 1); + } + else if (strcmp(interface, "wl_shm") == 0) + { + _glfw.wl.shm = + wl_registry_bind(registry, name, &wl_shm_interface, 1); + } + else if (strcmp(interface, "wl_output") == 0) + { + _glfwAddOutputWayland(name, version); + } + else if (strcmp(interface, "wl_seat") == 0) + { + if (!_glfw.wl.seat) + { + _glfw.wl.seat = + wl_registry_bind(registry, name, &wl_seat_interface, + _glfw_min(4, version)); + _glfwAddSeatListenerWayland(_glfw.wl.seat); + } + } + else if (strcmp(interface, "wl_data_device_manager") == 0) + { + if (!_glfw.wl.dataDeviceManager) + { + _glfw.wl.dataDeviceManager = + wl_registry_bind(registry, name, + &wl_data_device_manager_interface, 1); + } + } + else if (strcmp(interface, "xdg_wm_base") == 0) + { + _glfw.wl.wmBase = + wl_registry_bind(registry, name, &xdg_wm_base_interface, 1); + xdg_wm_base_add_listener(_glfw.wl.wmBase, &wmBaseListener, NULL); + } + else if (strcmp(interface, "zxdg_decoration_manager_v1") == 0) + { + _glfw.wl.decorationManager = + wl_registry_bind(registry, name, + &zxdg_decoration_manager_v1_interface, + 1); + } + else if (strcmp(interface, "wp_viewporter") == 0) + { + _glfw.wl.viewporter = + wl_registry_bind(registry, name, &wp_viewporter_interface, 1); + } + else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) + { + _glfw.wl.relativePointerManager = + wl_registry_bind(registry, name, + &zwp_relative_pointer_manager_v1_interface, + 1); + } + else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) + { + _glfw.wl.pointerConstraints = + wl_registry_bind(registry, name, + &zwp_pointer_constraints_v1_interface, + 1); + } + else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0) + { + _glfw.wl.idleInhibitManager = + wl_registry_bind(registry, name, + &zwp_idle_inhibit_manager_v1_interface, + 1); + } + else if (strcmp(interface, "xdg_activation_v1") == 0) + { + _glfw.wl.activationManager = + wl_registry_bind(registry, name, + &xdg_activation_v1_interface, + 1); + } + else if (strcmp(interface, "wp_fractional_scale_manager_v1") == 0) + { + _glfw.wl.fractionalScaleManager = + wl_registry_bind(registry, name, + &wp_fractional_scale_manager_v1_interface, + 1); + } +} + +static void registryHandleGlobalRemove(void* userData, + struct wl_registry* registry, + uint32_t name) +{ + for (int i = 0; i < _glfw.monitorCount; ++i) + { + _GLFWmonitor* monitor = _glfw.monitors[i]; + if (monitor->wl.name == name) + { + _glfwInputMonitor(monitor, GLFW_DISCONNECTED, 0); + return; + } + } +} + + +static const struct wl_registry_listener registryListener = +{ + registryHandleGlobal, + registryHandleGlobalRemove +}; + +void libdecorHandleError(struct libdecor* context, + enum libdecor_error error, + const char* message) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: libdecor error %u: %s", + error, message); +} + +static const struct libdecor_interface libdecorInterface = +{ + libdecorHandleError +}; + +static void libdecorReadyCallback(void* userData, + struct wl_callback* callback, + uint32_t time) +{ + _glfw.wl.libdecor.ready = GLFW_TRUE; + + assert(_glfw.wl.libdecor.callback == callback); + wl_callback_destroy(_glfw.wl.libdecor.callback); + _glfw.wl.libdecor.callback = NULL; +} + +static const struct wl_callback_listener libdecorReadyListener = +{ + libdecorReadyCallback +}; + +// Create key code translation tables +// +static void createKeyTables(void) +{ + memset(_glfw.wl.keycodes, -1, sizeof(_glfw.wl.keycodes)); + memset(_glfw.wl.scancodes, -1, sizeof(_glfw.wl.scancodes)); + + _glfw.wl.keycodes[KEY_GRAVE] = GLFW_KEY_GRAVE_ACCENT; + _glfw.wl.keycodes[KEY_1] = GLFW_KEY_1; + _glfw.wl.keycodes[KEY_2] = GLFW_KEY_2; + _glfw.wl.keycodes[KEY_3] = GLFW_KEY_3; + _glfw.wl.keycodes[KEY_4] = GLFW_KEY_4; + _glfw.wl.keycodes[KEY_5] = GLFW_KEY_5; + _glfw.wl.keycodes[KEY_6] = GLFW_KEY_6; + _glfw.wl.keycodes[KEY_7] = GLFW_KEY_7; + _glfw.wl.keycodes[KEY_8] = GLFW_KEY_8; + _glfw.wl.keycodes[KEY_9] = GLFW_KEY_9; + _glfw.wl.keycodes[KEY_0] = GLFW_KEY_0; + _glfw.wl.keycodes[KEY_SPACE] = GLFW_KEY_SPACE; + _glfw.wl.keycodes[KEY_MINUS] = GLFW_KEY_MINUS; + _glfw.wl.keycodes[KEY_EQUAL] = GLFW_KEY_EQUAL; + _glfw.wl.keycodes[KEY_Q] = GLFW_KEY_Q; + _glfw.wl.keycodes[KEY_W] = GLFW_KEY_W; + _glfw.wl.keycodes[KEY_E] = GLFW_KEY_E; + _glfw.wl.keycodes[KEY_R] = GLFW_KEY_R; + _glfw.wl.keycodes[KEY_T] = GLFW_KEY_T; + _glfw.wl.keycodes[KEY_Y] = GLFW_KEY_Y; + _glfw.wl.keycodes[KEY_U] = GLFW_KEY_U; + _glfw.wl.keycodes[KEY_I] = GLFW_KEY_I; + _glfw.wl.keycodes[KEY_O] = GLFW_KEY_O; + _glfw.wl.keycodes[KEY_P] = GLFW_KEY_P; + _glfw.wl.keycodes[KEY_LEFTBRACE] = GLFW_KEY_LEFT_BRACKET; + _glfw.wl.keycodes[KEY_RIGHTBRACE] = GLFW_KEY_RIGHT_BRACKET; + _glfw.wl.keycodes[KEY_A] = GLFW_KEY_A; + _glfw.wl.keycodes[KEY_S] = GLFW_KEY_S; + _glfw.wl.keycodes[KEY_D] = GLFW_KEY_D; + _glfw.wl.keycodes[KEY_F] = GLFW_KEY_F; + _glfw.wl.keycodes[KEY_G] = GLFW_KEY_G; + _glfw.wl.keycodes[KEY_H] = GLFW_KEY_H; + _glfw.wl.keycodes[KEY_J] = GLFW_KEY_J; + _glfw.wl.keycodes[KEY_K] = GLFW_KEY_K; + _glfw.wl.keycodes[KEY_L] = GLFW_KEY_L; + _glfw.wl.keycodes[KEY_SEMICOLON] = GLFW_KEY_SEMICOLON; + _glfw.wl.keycodes[KEY_APOSTROPHE] = GLFW_KEY_APOSTROPHE; + _glfw.wl.keycodes[KEY_Z] = GLFW_KEY_Z; + _glfw.wl.keycodes[KEY_X] = GLFW_KEY_X; + _glfw.wl.keycodes[KEY_C] = GLFW_KEY_C; + _glfw.wl.keycodes[KEY_V] = GLFW_KEY_V; + _glfw.wl.keycodes[KEY_B] = GLFW_KEY_B; + _glfw.wl.keycodes[KEY_N] = GLFW_KEY_N; + _glfw.wl.keycodes[KEY_M] = GLFW_KEY_M; + _glfw.wl.keycodes[KEY_COMMA] = GLFW_KEY_COMMA; + _glfw.wl.keycodes[KEY_DOT] = GLFW_KEY_PERIOD; + _glfw.wl.keycodes[KEY_SLASH] = GLFW_KEY_SLASH; + _glfw.wl.keycodes[KEY_BACKSLASH] = GLFW_KEY_BACKSLASH; + _glfw.wl.keycodes[KEY_ESC] = GLFW_KEY_ESCAPE; + _glfw.wl.keycodes[KEY_TAB] = GLFW_KEY_TAB; + _glfw.wl.keycodes[KEY_LEFTSHIFT] = GLFW_KEY_LEFT_SHIFT; + _glfw.wl.keycodes[KEY_RIGHTSHIFT] = GLFW_KEY_RIGHT_SHIFT; + _glfw.wl.keycodes[KEY_LEFTCTRL] = GLFW_KEY_LEFT_CONTROL; + _glfw.wl.keycodes[KEY_RIGHTCTRL] = GLFW_KEY_RIGHT_CONTROL; + _glfw.wl.keycodes[KEY_LEFTALT] = GLFW_KEY_LEFT_ALT; + _glfw.wl.keycodes[KEY_RIGHTALT] = GLFW_KEY_RIGHT_ALT; + _glfw.wl.keycodes[KEY_LEFTMETA] = GLFW_KEY_LEFT_SUPER; + _glfw.wl.keycodes[KEY_RIGHTMETA] = GLFW_KEY_RIGHT_SUPER; + _glfw.wl.keycodes[KEY_COMPOSE] = GLFW_KEY_MENU; + _glfw.wl.keycodes[KEY_NUMLOCK] = GLFW_KEY_NUM_LOCK; + _glfw.wl.keycodes[KEY_CAPSLOCK] = GLFW_KEY_CAPS_LOCK; + _glfw.wl.keycodes[KEY_PRINT] = GLFW_KEY_PRINT_SCREEN; + _glfw.wl.keycodes[KEY_SCROLLLOCK] = GLFW_KEY_SCROLL_LOCK; + _glfw.wl.keycodes[KEY_PAUSE] = GLFW_KEY_PAUSE; + _glfw.wl.keycodes[KEY_DELETE] = GLFW_KEY_DELETE; + _glfw.wl.keycodes[KEY_BACKSPACE] = GLFW_KEY_BACKSPACE; + _glfw.wl.keycodes[KEY_ENTER] = GLFW_KEY_ENTER; + _glfw.wl.keycodes[KEY_HOME] = GLFW_KEY_HOME; + _glfw.wl.keycodes[KEY_END] = GLFW_KEY_END; + _glfw.wl.keycodes[KEY_PAGEUP] = GLFW_KEY_PAGE_UP; + _glfw.wl.keycodes[KEY_PAGEDOWN] = GLFW_KEY_PAGE_DOWN; + _glfw.wl.keycodes[KEY_INSERT] = GLFW_KEY_INSERT; + _glfw.wl.keycodes[KEY_LEFT] = GLFW_KEY_LEFT; + _glfw.wl.keycodes[KEY_RIGHT] = GLFW_KEY_RIGHT; + _glfw.wl.keycodes[KEY_DOWN] = GLFW_KEY_DOWN; + _glfw.wl.keycodes[KEY_UP] = GLFW_KEY_UP; + _glfw.wl.keycodes[KEY_F1] = GLFW_KEY_F1; + _glfw.wl.keycodes[KEY_F2] = GLFW_KEY_F2; + _glfw.wl.keycodes[KEY_F3] = GLFW_KEY_F3; + _glfw.wl.keycodes[KEY_F4] = GLFW_KEY_F4; + _glfw.wl.keycodes[KEY_F5] = GLFW_KEY_F5; + _glfw.wl.keycodes[KEY_F6] = GLFW_KEY_F6; + _glfw.wl.keycodes[KEY_F7] = GLFW_KEY_F7; + _glfw.wl.keycodes[KEY_F8] = GLFW_KEY_F8; + _glfw.wl.keycodes[KEY_F9] = GLFW_KEY_F9; + _glfw.wl.keycodes[KEY_F10] = GLFW_KEY_F10; + _glfw.wl.keycodes[KEY_F11] = GLFW_KEY_F11; + _glfw.wl.keycodes[KEY_F12] = GLFW_KEY_F12; + _glfw.wl.keycodes[KEY_F13] = GLFW_KEY_F13; + _glfw.wl.keycodes[KEY_F14] = GLFW_KEY_F14; + _glfw.wl.keycodes[KEY_F15] = GLFW_KEY_F15; + _glfw.wl.keycodes[KEY_F16] = GLFW_KEY_F16; + _glfw.wl.keycodes[KEY_F17] = GLFW_KEY_F17; + _glfw.wl.keycodes[KEY_F18] = GLFW_KEY_F18; + _glfw.wl.keycodes[KEY_F19] = GLFW_KEY_F19; + _glfw.wl.keycodes[KEY_F20] = GLFW_KEY_F20; + _glfw.wl.keycodes[KEY_F21] = GLFW_KEY_F21; + _glfw.wl.keycodes[KEY_F22] = GLFW_KEY_F22; + _glfw.wl.keycodes[KEY_F23] = GLFW_KEY_F23; + _glfw.wl.keycodes[KEY_F24] = GLFW_KEY_F24; + _glfw.wl.keycodes[KEY_KPSLASH] = GLFW_KEY_KP_DIVIDE; + _glfw.wl.keycodes[KEY_KPASTERISK] = GLFW_KEY_KP_MULTIPLY; + _glfw.wl.keycodes[KEY_KPMINUS] = GLFW_KEY_KP_SUBTRACT; + _glfw.wl.keycodes[KEY_KPPLUS] = GLFW_KEY_KP_ADD; + _glfw.wl.keycodes[KEY_KP0] = GLFW_KEY_KP_0; + _glfw.wl.keycodes[KEY_KP1] = GLFW_KEY_KP_1; + _glfw.wl.keycodes[KEY_KP2] = GLFW_KEY_KP_2; + _glfw.wl.keycodes[KEY_KP3] = GLFW_KEY_KP_3; + _glfw.wl.keycodes[KEY_KP4] = GLFW_KEY_KP_4; + _glfw.wl.keycodes[KEY_KP5] = GLFW_KEY_KP_5; + _glfw.wl.keycodes[KEY_KP6] = GLFW_KEY_KP_6; + _glfw.wl.keycodes[KEY_KP7] = GLFW_KEY_KP_7; + _glfw.wl.keycodes[KEY_KP8] = GLFW_KEY_KP_8; + _glfw.wl.keycodes[KEY_KP9] = GLFW_KEY_KP_9; + _glfw.wl.keycodes[KEY_KPDOT] = GLFW_KEY_KP_DECIMAL; + _glfw.wl.keycodes[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL; + _glfw.wl.keycodes[KEY_KPENTER] = GLFW_KEY_KP_ENTER; + _glfw.wl.keycodes[KEY_102ND] = GLFW_KEY_WORLD_2; + + for (int scancode = 0; scancode < 256; scancode++) + { + if (_glfw.wl.keycodes[scancode] > 0) + _glfw.wl.scancodes[_glfw.wl.keycodes[scancode]] = scancode; + } +} + +static GLFWbool loadCursorTheme(void) +{ + int cursorSize = 16; + + const char* sizeString = getenv("XCURSOR_SIZE"); + if (sizeString) + { + errno = 0; + const long cursorSizeLong = strtol(sizeString, NULL, 10); + if (errno == 0 && cursorSizeLong > 0 && cursorSizeLong < INT_MAX) + cursorSize = (int) cursorSizeLong; + } + + const char* themeName = getenv("XCURSOR_THEME"); + + _glfw.wl.cursorTheme = wl_cursor_theme_load(themeName, cursorSize, _glfw.wl.shm); + if (!_glfw.wl.cursorTheme) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to load default cursor theme"); + return GLFW_FALSE; + } + + // If this happens to be NULL, we just fallback to the scale=1 version. + _glfw.wl.cursorThemeHiDPI = + wl_cursor_theme_load(themeName, cursorSize * 2, _glfw.wl.shm); + + _glfw.wl.cursorSurface = wl_compositor_create_surface(_glfw.wl.compositor); + _glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); + return GLFW_TRUE; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform) +{ + const _GLFWplatform wayland = + { + .platformID = GLFW_PLATFORM_WAYLAND, + .init = _glfwInitWayland, + .terminate = _glfwTerminateWayland, + .getCursorPos = _glfwGetCursorPosWayland, + .setCursorPos = _glfwSetCursorPosWayland, + .setCursorMode = _glfwSetCursorModeWayland, + .setRawMouseMotion = _glfwSetRawMouseMotionWayland, + .rawMouseMotionSupported = _glfwRawMouseMotionSupportedWayland, + .createCursor = _glfwCreateCursorWayland, + .createStandardCursor = _glfwCreateStandardCursorWayland, + .destroyCursor = _glfwDestroyCursorWayland, + .setCursor = _glfwSetCursorWayland, + .getScancodeName = _glfwGetScancodeNameWayland, + .getKeyScancode = _glfwGetKeyScancodeWayland, + .setClipboardString = _glfwSetClipboardStringWayland, + .getClipboardString = _glfwGetClipboardStringWayland, +#if defined(GLFW_BUILD_LINUX_JOYSTICK) + .initJoysticks = _glfwInitJoysticksLinux, + .terminateJoysticks = _glfwTerminateJoysticksLinux, + .pollJoystick = _glfwPollJoystickLinux, + .getMappingName = _glfwGetMappingNameLinux, + .updateGamepadGUID = _glfwUpdateGamepadGUIDLinux, +#else + .initJoysticks = _glfwInitJoysticksNull, + .terminateJoysticks = _glfwTerminateJoysticksNull, + .pollJoystick = _glfwPollJoystickNull, + .getMappingName = _glfwGetMappingNameNull, + .updateGamepadGUID = _glfwUpdateGamepadGUIDNull, +#endif + .freeMonitor = _glfwFreeMonitorWayland, + .getMonitorPos = _glfwGetMonitorPosWayland, + .getMonitorContentScale = _glfwGetMonitorContentScaleWayland, + .getMonitorWorkarea = _glfwGetMonitorWorkareaWayland, + .getVideoModes = _glfwGetVideoModesWayland, + .getVideoMode = _glfwGetVideoModeWayland, + .getGammaRamp = _glfwGetGammaRampWayland, + .setGammaRamp = _glfwSetGammaRampWayland, + .createWindow = _glfwCreateWindowWayland, + .destroyWindow = _glfwDestroyWindowWayland, + .setWindowTitle = _glfwSetWindowTitleWayland, + .setWindowIcon = _glfwSetWindowIconWayland, + .getWindowPos = _glfwGetWindowPosWayland, + .setWindowPos = _glfwSetWindowPosWayland, + .getWindowSize = _glfwGetWindowSizeWayland, + .setWindowSize = _glfwSetWindowSizeWayland, + .setWindowSizeLimits = _glfwSetWindowSizeLimitsWayland, + .setWindowAspectRatio = _glfwSetWindowAspectRatioWayland, + .getFramebufferSize = _glfwGetFramebufferSizeWayland, + .getWindowFrameSize = _glfwGetWindowFrameSizeWayland, + .getWindowContentScale = _glfwGetWindowContentScaleWayland, + .iconifyWindow = _glfwIconifyWindowWayland, + .restoreWindow = _glfwRestoreWindowWayland, + .maximizeWindow = _glfwMaximizeWindowWayland, + .showWindow = _glfwShowWindowWayland, + .hideWindow = _glfwHideWindowWayland, + .requestWindowAttention = _glfwRequestWindowAttentionWayland, + .focusWindow = _glfwFocusWindowWayland, + .setWindowMonitor = _glfwSetWindowMonitorWayland, + .windowFocused = _glfwWindowFocusedWayland, + .windowIconified = _glfwWindowIconifiedWayland, + .windowVisible = _glfwWindowVisibleWayland, + .windowMaximized = _glfwWindowMaximizedWayland, + .windowHovered = _glfwWindowHoveredWayland, + .framebufferTransparent = _glfwFramebufferTransparentWayland, + .getWindowOpacity = _glfwGetWindowOpacityWayland, + .setWindowResizable = _glfwSetWindowResizableWayland, + .setWindowDecorated = _glfwSetWindowDecoratedWayland, + .setWindowFloating = _glfwSetWindowFloatingWayland, + .setWindowOpacity = _glfwSetWindowOpacityWayland, + .setWindowMousePassthrough = _glfwSetWindowMousePassthroughWayland, + .pollEvents = _glfwPollEventsWayland, + .waitEvents = _glfwWaitEventsWayland, + .waitEventsTimeout = _glfwWaitEventsTimeoutWayland, + .postEmptyEvent = _glfwPostEmptyEventWayland, + .getEGLPlatform = _glfwGetEGLPlatformWayland, + .getEGLNativeDisplay = _glfwGetEGLNativeDisplayWayland, + .getEGLNativeWindow = _glfwGetEGLNativeWindowWayland, + .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsWayland, + .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportWayland, + .createWindowSurface = _glfwCreateWindowSurfaceWayland + }; + + void* module = _glfwPlatformLoadModule("libwayland-client.so.0"); + if (!module) + { + if (platformID == GLFW_PLATFORM_WAYLAND) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to load libwayland-client"); + } + + return GLFW_FALSE; + } + + PFN_wl_display_connect wl_display_connect = (PFN_wl_display_connect) + _glfwPlatformGetModuleSymbol(module, "wl_display_connect"); + if (!wl_display_connect) + { + if (platformID == GLFW_PLATFORM_WAYLAND) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to load libwayland-client entry point"); + } + + _glfwPlatformFreeModule(module); + return GLFW_FALSE; + } + + struct wl_display* display = wl_display_connect(NULL); + if (!display) + { + if (platformID == GLFW_PLATFORM_WAYLAND) + _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to connect to display"); + + _glfwPlatformFreeModule(module); + return GLFW_FALSE; + } + + _glfw.wl.display = display; + _glfw.wl.client.handle = module; + + *platform = wayland; + return GLFW_TRUE; +} + +int _glfwInitWayland(void) +{ + // These must be set before any failure checks + _glfw.wl.keyRepeatTimerfd = -1; + _glfw.wl.cursorTimerfd = -1; + + _glfw.wl.tag = glfwGetVersionString(); + + _glfw.wl.client.display_flush = (PFN_wl_display_flush) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_flush"); + _glfw.wl.client.display_cancel_read = (PFN_wl_display_cancel_read) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_cancel_read"); + _glfw.wl.client.display_dispatch_pending = (PFN_wl_display_dispatch_pending) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_dispatch_pending"); + _glfw.wl.client.display_read_events = (PFN_wl_display_read_events) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_read_events"); + _glfw.wl.client.display_disconnect = (PFN_wl_display_disconnect) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_disconnect"); + _glfw.wl.client.display_roundtrip = (PFN_wl_display_roundtrip) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_roundtrip"); + _glfw.wl.client.display_get_fd = (PFN_wl_display_get_fd) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_get_fd"); + _glfw.wl.client.display_prepare_read = (PFN_wl_display_prepare_read) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_prepare_read"); + _glfw.wl.client.proxy_marshal = (PFN_wl_proxy_marshal) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal"); + _glfw.wl.client.proxy_add_listener = (PFN_wl_proxy_add_listener) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_add_listener"); + _glfw.wl.client.proxy_destroy = (PFN_wl_proxy_destroy) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_destroy"); + _glfw.wl.client.proxy_marshal_constructor = (PFN_wl_proxy_marshal_constructor) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_constructor"); + _glfw.wl.client.proxy_marshal_constructor_versioned = (PFN_wl_proxy_marshal_constructor_versioned) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_constructor_versioned"); + _glfw.wl.client.proxy_get_user_data = (PFN_wl_proxy_get_user_data) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_user_data"); + _glfw.wl.client.proxy_set_user_data = (PFN_wl_proxy_set_user_data) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_user_data"); + _glfw.wl.client.proxy_get_tag = (PFN_wl_proxy_get_tag) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_tag"); + _glfw.wl.client.proxy_set_tag = (PFN_wl_proxy_set_tag) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_tag"); + _glfw.wl.client.proxy_get_version = (PFN_wl_proxy_get_version) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_version"); + _glfw.wl.client.proxy_marshal_flags = (PFN_wl_proxy_marshal_flags) + _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_flags"); + + if (!_glfw.wl.client.display_flush || + !_glfw.wl.client.display_cancel_read || + !_glfw.wl.client.display_dispatch_pending || + !_glfw.wl.client.display_read_events || + !_glfw.wl.client.display_disconnect || + !_glfw.wl.client.display_roundtrip || + !_glfw.wl.client.display_get_fd || + !_glfw.wl.client.display_prepare_read || + !_glfw.wl.client.proxy_marshal || + !_glfw.wl.client.proxy_add_listener || + !_glfw.wl.client.proxy_destroy || + !_glfw.wl.client.proxy_marshal_constructor || + !_glfw.wl.client.proxy_marshal_constructor_versioned || + !_glfw.wl.client.proxy_get_user_data || + !_glfw.wl.client.proxy_set_user_data || + !_glfw.wl.client.proxy_get_tag || + !_glfw.wl.client.proxy_set_tag) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to load libwayland-client entry point"); + return GLFW_FALSE; + } + + _glfw.wl.cursor.handle = _glfwPlatformLoadModule("libwayland-cursor.so.0"); + if (!_glfw.wl.cursor.handle) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to load libwayland-cursor"); + return GLFW_FALSE; + } + + _glfw.wl.cursor.theme_load = (PFN_wl_cursor_theme_load) + _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_theme_load"); + _glfw.wl.cursor.theme_destroy = (PFN_wl_cursor_theme_destroy) + _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_theme_destroy"); + _glfw.wl.cursor.theme_get_cursor = (PFN_wl_cursor_theme_get_cursor) + _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor"); + _glfw.wl.cursor.image_get_buffer = (PFN_wl_cursor_image_get_buffer) + _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_image_get_buffer"); + + _glfw.wl.egl.handle = _glfwPlatformLoadModule("libwayland-egl.so.1"); + if (!_glfw.wl.egl.handle) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to load libwayland-egl"); + return GLFW_FALSE; + } + + _glfw.wl.egl.window_create = (PFN_wl_egl_window_create) + _glfwPlatformGetModuleSymbol(_glfw.wl.egl.handle, "wl_egl_window_create"); + _glfw.wl.egl.window_destroy = (PFN_wl_egl_window_destroy) + _glfwPlatformGetModuleSymbol(_glfw.wl.egl.handle, "wl_egl_window_destroy"); + _glfw.wl.egl.window_resize = (PFN_wl_egl_window_resize) + _glfwPlatformGetModuleSymbol(_glfw.wl.egl.handle, "wl_egl_window_resize"); + + _glfw.wl.xkb.handle = _glfwPlatformLoadModule("libxkbcommon.so.0"); + if (!_glfw.wl.xkb.handle) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to load libxkbcommon"); + return GLFW_FALSE; + } + + _glfw.wl.xkb.context_new = (PFN_xkb_context_new) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_context_new"); + _glfw.wl.xkb.context_unref = (PFN_xkb_context_unref) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_context_unref"); + _glfw.wl.xkb.keymap_new_from_string = (PFN_xkb_keymap_new_from_string) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_new_from_string"); + _glfw.wl.xkb.keymap_unref = (PFN_xkb_keymap_unref) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_unref"); + _glfw.wl.xkb.keymap_mod_get_index = (PFN_xkb_keymap_mod_get_index) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index"); + _glfw.wl.xkb.keymap_key_repeats = (PFN_xkb_keymap_key_repeats) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_repeats"); + _glfw.wl.xkb.keymap_key_get_syms_by_level = (PFN_xkb_keymap_key_get_syms_by_level) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_get_syms_by_level"); + _glfw.wl.xkb.state_new = (PFN_xkb_state_new) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_new"); + _glfw.wl.xkb.state_unref = (PFN_xkb_state_unref) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_unref"); + _glfw.wl.xkb.state_key_get_syms = (PFN_xkb_state_key_get_syms) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_key_get_syms"); + _glfw.wl.xkb.state_update_mask = (PFN_xkb_state_update_mask) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_update_mask"); + _glfw.wl.xkb.state_key_get_layout = (PFN_xkb_state_key_get_layout) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_key_get_layout"); + _glfw.wl.xkb.state_mod_index_is_active = (PFN_xkb_state_mod_index_is_active) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_mod_index_is_active"); + _glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale"); + _glfw.wl.xkb.compose_table_unref = (PFN_xkb_compose_table_unref) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_table_unref"); + _glfw.wl.xkb.compose_state_new = (PFN_xkb_compose_state_new) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_new"); + _glfw.wl.xkb.compose_state_unref = (PFN_xkb_compose_state_unref) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_unref"); + _glfw.wl.xkb.compose_state_feed = (PFN_xkb_compose_state_feed) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_feed"); + _glfw.wl.xkb.compose_state_get_status = (PFN_xkb_compose_state_get_status) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_status"); + _glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym"); + + if (!_glfw.wl.xkb.context_new || + !_glfw.wl.xkb.context_unref || + !_glfw.wl.xkb.keymap_new_from_string || + !_glfw.wl.xkb.keymap_unref || + !_glfw.wl.xkb.keymap_mod_get_index || + !_glfw.wl.xkb.keymap_key_repeats || + !_glfw.wl.xkb.keymap_key_get_syms_by_level || + !_glfw.wl.xkb.state_new || + !_glfw.wl.xkb.state_unref || + !_glfw.wl.xkb.state_key_get_syms || + !_glfw.wl.xkb.state_update_mask || + !_glfw.wl.xkb.state_key_get_layout || + !_glfw.wl.xkb.state_mod_index_is_active || + !_glfw.wl.xkb.compose_table_new_from_locale || + !_glfw.wl.xkb.compose_table_unref || + !_glfw.wl.xkb.compose_state_new || + !_glfw.wl.xkb.compose_state_unref || + !_glfw.wl.xkb.compose_state_feed || + !_glfw.wl.xkb.compose_state_get_status || + !_glfw.wl.xkb.compose_state_get_one_sym) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to load all entry points from libxkbcommon"); + return GLFW_FALSE; + } + + if (_glfw.hints.init.wl.libdecorMode == GLFW_WAYLAND_PREFER_LIBDECOR) + _glfw.wl.libdecor.handle = _glfwPlatformLoadModule("libdecor-0.so.0"); + + if (_glfw.wl.libdecor.handle) + { + _glfw.wl.libdecor.libdecor_new_ = (PFN_libdecor_new) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_new"); + _glfw.wl.libdecor.libdecor_unref_ = (PFN_libdecor_unref) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_unref"); + _glfw.wl.libdecor.libdecor_get_fd_ = (PFN_libdecor_get_fd) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_get_fd"); + _glfw.wl.libdecor.libdecor_dispatch_ = (PFN_libdecor_dispatch) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_dispatch"); + _glfw.wl.libdecor.libdecor_decorate_ = (PFN_libdecor_decorate) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_decorate"); + _glfw.wl.libdecor.libdecor_frame_unref_ = (PFN_libdecor_frame_unref) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unref"); + _glfw.wl.libdecor.libdecor_frame_set_app_id_ = (PFN_libdecor_frame_set_app_id) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_app_id"); + _glfw.wl.libdecor.libdecor_frame_set_title_ = (PFN_libdecor_frame_set_title) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_title"); + _glfw.wl.libdecor.libdecor_frame_set_minimized_ = (PFN_libdecor_frame_set_minimized) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_minimized"); + _glfw.wl.libdecor.libdecor_frame_set_fullscreen_ = (PFN_libdecor_frame_set_fullscreen) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_fullscreen"); + _glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ = (PFN_libdecor_frame_unset_fullscreen) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_fullscreen"); + _glfw.wl.libdecor.libdecor_frame_map_ = (PFN_libdecor_frame_map) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_map"); + _glfw.wl.libdecor.libdecor_frame_commit_ = (PFN_libdecor_frame_commit) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_commit"); + _glfw.wl.libdecor.libdecor_frame_set_min_content_size_ = (PFN_libdecor_frame_set_min_content_size) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_min_content_size"); + _glfw.wl.libdecor.libdecor_frame_set_max_content_size_ = (PFN_libdecor_frame_set_max_content_size) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_max_content_size"); + _glfw.wl.libdecor.libdecor_frame_set_maximized_ = (PFN_libdecor_frame_set_maximized) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_maximized"); + _glfw.wl.libdecor.libdecor_frame_unset_maximized_ = (PFN_libdecor_frame_unset_maximized) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_maximized"); + _glfw.wl.libdecor.libdecor_frame_set_capabilities_ = (PFN_libdecor_frame_set_capabilities) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_capabilities"); + _glfw.wl.libdecor.libdecor_frame_unset_capabilities_ = (PFN_libdecor_frame_unset_capabilities) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_capabilities"); + _glfw.wl.libdecor.libdecor_frame_set_visibility_ = (PFN_libdecor_frame_set_visibility) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_visibility"); + _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ = (PFN_libdecor_frame_get_xdg_toplevel) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_get_xdg_toplevel"); + _glfw.wl.libdecor.libdecor_configuration_get_content_size_ = (PFN_libdecor_configuration_get_content_size) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_configuration_get_content_size"); + _glfw.wl.libdecor.libdecor_configuration_get_window_state_ = (PFN_libdecor_configuration_get_window_state) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_configuration_get_window_state"); + _glfw.wl.libdecor.libdecor_state_new_ = (PFN_libdecor_state_new) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_state_new"); + _glfw.wl.libdecor.libdecor_state_free_ = (PFN_libdecor_state_free) + _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_state_free"); + + if (!_glfw.wl.libdecor.libdecor_new_ || + !_glfw.wl.libdecor.libdecor_unref_ || + !_glfw.wl.libdecor.libdecor_get_fd_ || + !_glfw.wl.libdecor.libdecor_dispatch_ || + !_glfw.wl.libdecor.libdecor_decorate_ || + !_glfw.wl.libdecor.libdecor_frame_unref_ || + !_glfw.wl.libdecor.libdecor_frame_set_app_id_ || + !_glfw.wl.libdecor.libdecor_frame_set_title_ || + !_glfw.wl.libdecor.libdecor_frame_set_minimized_ || + !_glfw.wl.libdecor.libdecor_frame_set_fullscreen_ || + !_glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ || + !_glfw.wl.libdecor.libdecor_frame_map_ || + !_glfw.wl.libdecor.libdecor_frame_commit_ || + !_glfw.wl.libdecor.libdecor_frame_set_min_content_size_ || + !_glfw.wl.libdecor.libdecor_frame_set_max_content_size_ || + !_glfw.wl.libdecor.libdecor_frame_set_maximized_ || + !_glfw.wl.libdecor.libdecor_frame_unset_maximized_ || + !_glfw.wl.libdecor.libdecor_frame_set_capabilities_ || + !_glfw.wl.libdecor.libdecor_frame_unset_capabilities_ || + !_glfw.wl.libdecor.libdecor_frame_set_visibility_ || + !_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ || + !_glfw.wl.libdecor.libdecor_configuration_get_content_size_ || + !_glfw.wl.libdecor.libdecor_configuration_get_window_state_ || + !_glfw.wl.libdecor.libdecor_state_new_ || + !_glfw.wl.libdecor.libdecor_state_free_) + { + _glfwPlatformFreeModule(_glfw.wl.libdecor.handle); + memset(&_glfw.wl.libdecor, 0, sizeof(_glfw.wl.libdecor)); + } + } + + _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display); + wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL); + + createKeyTables(); + + _glfw.wl.xkb.context = xkb_context_new(0); + if (!_glfw.wl.xkb.context) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to initialize xkb context"); + return GLFW_FALSE; + } + + // Sync so we got all registry objects + wl_display_roundtrip(_glfw.wl.display); + + // Sync so we got all initial output events + wl_display_roundtrip(_glfw.wl.display); + + if (_glfw.wl.libdecor.handle) + { + _glfw.wl.libdecor.context = libdecor_new(_glfw.wl.display, &libdecorInterface); + if (_glfw.wl.libdecor.context) + { + // Perform an initial dispatch and flush to get the init started + libdecor_dispatch(_glfw.wl.libdecor.context, 0); + + // Create sync point to "know" when libdecor is ready for use + _glfw.wl.libdecor.callback = wl_display_sync(_glfw.wl.display); + wl_callback_add_listener(_glfw.wl.libdecor.callback, + &libdecorReadyListener, + NULL); + } + } + + if (wl_seat_get_version(_glfw.wl.seat) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) + { + _glfw.wl.keyRepeatTimerfd = + timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); + } + + if (!_glfw.wl.wmBase) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to find xdg-shell in your compositor"); + return GLFW_FALSE; + } + + if (!_glfw.wl.shm) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to find wl_shm in your compositor"); + return GLFW_FALSE; + } + + if (!loadCursorTheme()) + return GLFW_FALSE; + + if (_glfw.wl.seat && _glfw.wl.dataDeviceManager) + { + _glfw.wl.dataDevice = + wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager, + _glfw.wl.seat); + _glfwAddDataDeviceListenerWayland(_glfw.wl.dataDevice); + } + + return GLFW_TRUE; +} + +void _glfwTerminateWayland(void) +{ + _glfwTerminateEGL(); + _glfwTerminateOSMesa(); + + if (_glfw.wl.libdecor.context) + { + // Allow libdecor to finish receiving all its requested globals + // and ensure the associated sync callback object is destroyed + while (!_glfw.wl.libdecor.ready) + _glfwWaitEventsWayland(); + + libdecor_unref(_glfw.wl.libdecor.context); + } + + if (_glfw.wl.libdecor.handle) + { + _glfwPlatformFreeModule(_glfw.wl.libdecor.handle); + _glfw.wl.libdecor.handle = NULL; + } + + if (_glfw.wl.egl.handle) + { + _glfwPlatformFreeModule(_glfw.wl.egl.handle); + _glfw.wl.egl.handle = NULL; + } + + if (_glfw.wl.xkb.composeState) + xkb_compose_state_unref(_glfw.wl.xkb.composeState); + if (_glfw.wl.xkb.keymap) + xkb_keymap_unref(_glfw.wl.xkb.keymap); + if (_glfw.wl.xkb.state) + xkb_state_unref(_glfw.wl.xkb.state); + if (_glfw.wl.xkb.context) + xkb_context_unref(_glfw.wl.xkb.context); + if (_glfw.wl.xkb.handle) + { + _glfwPlatformFreeModule(_glfw.wl.xkb.handle); + _glfw.wl.xkb.handle = NULL; + } + + if (_glfw.wl.cursorTheme) + wl_cursor_theme_destroy(_glfw.wl.cursorTheme); + if (_glfw.wl.cursorThemeHiDPI) + wl_cursor_theme_destroy(_glfw.wl.cursorThemeHiDPI); + if (_glfw.wl.cursor.handle) + { + _glfwPlatformFreeModule(_glfw.wl.cursor.handle); + _glfw.wl.cursor.handle = NULL; + } + + for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) + wl_data_offer_destroy(_glfw.wl.offers[i].offer); + + _glfw_free(_glfw.wl.offers); + + if (_glfw.wl.cursorSurface) + wl_surface_destroy(_glfw.wl.cursorSurface); + if (_glfw.wl.subcompositor) + wl_subcompositor_destroy(_glfw.wl.subcompositor); + if (_glfw.wl.compositor) + wl_compositor_destroy(_glfw.wl.compositor); + if (_glfw.wl.shm) + wl_shm_destroy(_glfw.wl.shm); + if (_glfw.wl.viewporter) + wp_viewporter_destroy(_glfw.wl.viewporter); + if (_glfw.wl.decorationManager) + zxdg_decoration_manager_v1_destroy(_glfw.wl.decorationManager); + if (_glfw.wl.wmBase) + xdg_wm_base_destroy(_glfw.wl.wmBase); + if (_glfw.wl.selectionOffer) + wl_data_offer_destroy(_glfw.wl.selectionOffer); + if (_glfw.wl.dragOffer) + wl_data_offer_destroy(_glfw.wl.dragOffer); + if (_glfw.wl.selectionSource) + wl_data_source_destroy(_glfw.wl.selectionSource); + if (_glfw.wl.dataDevice) + wl_data_device_destroy(_glfw.wl.dataDevice); + if (_glfw.wl.dataDeviceManager) + wl_data_device_manager_destroy(_glfw.wl.dataDeviceManager); + if (_glfw.wl.pointer) + wl_pointer_destroy(_glfw.wl.pointer); + if (_glfw.wl.keyboard) + wl_keyboard_destroy(_glfw.wl.keyboard); + if (_glfw.wl.seat) + wl_seat_destroy(_glfw.wl.seat); + if (_glfw.wl.relativePointerManager) + zwp_relative_pointer_manager_v1_destroy(_glfw.wl.relativePointerManager); + if (_glfw.wl.pointerConstraints) + zwp_pointer_constraints_v1_destroy(_glfw.wl.pointerConstraints); + if (_glfw.wl.idleInhibitManager) + zwp_idle_inhibit_manager_v1_destroy(_glfw.wl.idleInhibitManager); + if (_glfw.wl.activationManager) + xdg_activation_v1_destroy(_glfw.wl.activationManager); + if (_glfw.wl.fractionalScaleManager) + wp_fractional_scale_manager_v1_destroy(_glfw.wl.fractionalScaleManager); + if (_glfw.wl.registry) + wl_registry_destroy(_glfw.wl.registry); + if (_glfw.wl.display) + { + wl_display_flush(_glfw.wl.display); + wl_display_disconnect(_glfw.wl.display); + } + + if (_glfw.wl.keyRepeatTimerfd >= 0) + close(_glfw.wl.keyRepeatTimerfd); + if (_glfw.wl.cursorTimerfd >= 0) + close(_glfw.wl.cursorTimerfd); + + _glfw_free(_glfw.wl.clipboardString); +} + +#endif // _GLFW_WAYLAND + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/wl_monitor.c b/src/lib/src/vendor/glfw-3.4/src/wl_monitor.c similarity index 81% rename from src/lib/src/vendor/glfw-3.3.8/src/wl_monitor.c rename to src/lib/src/vendor/glfw-3.4/src/wl_monitor.c index 99de893..df30313 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/wl_monitor.c +++ b/src/lib/src/vendor/glfw-3.4/src/wl_monitor.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Wayland - www.glfw.org +// GLFW 3.4 Wayland - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2014 Jonas Ådahl // @@ -23,17 +23,19 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_WAYLAND) + #include #include #include #include #include +#include "wayland-client-protocol.h" + static void outputHandleGeometry(void* userData, struct wl_output* output, @@ -76,7 +78,7 @@ static void outputHandleMode(void* userData, monitor->modeCount++; monitor->modes = - realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode)); + _glfw_realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode)); monitor->modes[monitor->modeCount - 1] = mode; if (flags & WL_OUTPUT_MODE_CURRENT) @@ -114,19 +116,18 @@ static void outputHandleScale(void* userData, for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next) { - for (int i = 0; i < window->wl.monitorsCount; i++) + for (size_t i = 0; i < window->wl.outputScaleCount; i++) { - if (window->wl.monitors[i] == monitor) + if (window->wl.outputScales[i].output == monitor->wl.output) { - _glfwUpdateContentScaleWayland(window); + window->wl.outputScales[i].factor = monitor->wl.scale; + _glfwUpdateBufferScaleFromOutputsWayland(window); break; } } } } -#ifdef WL_OUTPUT_NAME_SINCE_VERSION - void outputHandleName(void* userData, struct wl_output* wl_output, const char* name) { struct _GLFWmonitor* monitor = userData; @@ -140,18 +141,14 @@ void outputHandleDescription(void* userData, { } -#endif // WL_OUTPUT_NAME_SINCE_VERSION - static const struct wl_output_listener outputListener = { outputHandleGeometry, outputHandleMode, outputHandleDone, outputHandleScale, -#ifdef WL_OUTPUT_NAME_SINCE_VERSION outputHandleName, outputHandleDescription, -#endif }; @@ -168,11 +165,7 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version) return; } -#ifdef WL_OUTPUT_NAME_SINCE_VERSION version = _glfw_min(version, WL_OUTPUT_NAME_SINCE_VERSION); -#else - version = 2; -#endif struct wl_output* output = wl_registry_bind(_glfw.wl.registry, name, @@ -187,6 +180,7 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version) monitor->wl.output = output; monitor->wl.name = name; + wl_proxy_set_tag((struct wl_proxy*) output, &_glfw.wl.tag); wl_output_add_listener(output, &outputListener, monitor); } @@ -195,13 +189,13 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version) ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) +void _glfwFreeMonitorWayland(_GLFWmonitor* monitor) { if (monitor->wl.output) wl_output_destroy(monitor->wl.output); } -void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +void _glfwGetMonitorPosWayland(_GLFWmonitor* monitor, int* xpos, int* ypos) { if (xpos) *xpos = monitor->wl.x; @@ -209,8 +203,8 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) *ypos = monitor->wl.y; } -void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, - float* xscale, float* yscale) +void _glfwGetMonitorContentScaleWayland(_GLFWmonitor* monitor, + float* xscale, float* yscale) { if (xscale) *xscale = (float) monitor->wl.scale; @@ -218,9 +212,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, *yscale = (float) monitor->wl.scale; } -void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, - int* xpos, int* ypos, - int* width, int* height) +void _glfwGetMonitorWorkareaWayland(_GLFWmonitor* monitor, + int* xpos, int* ypos, + int* width, int* height) { if (xpos) *xpos = monitor->wl.x; @@ -232,28 +226,28 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, *height = monitor->modes[monitor->wl.currentMode].height; } -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) +GLFWvidmode* _glfwGetVideoModesWayland(_GLFWmonitor* monitor, int* found) { *found = monitor->modeCount; return monitor->modes; } -void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) +GLFWbool _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode) { *mode = monitor->modes[monitor->wl.currentMode]; + return GLFW_TRUE; } -GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { - _glfwInputError(GLFW_PLATFORM_ERROR, + _glfwInputError(GLFW_FEATURE_UNAVAILABLE, "Wayland: Gamma ramp access is not available"); return GLFW_FALSE; } -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, - const GLFWgammaramp* ramp) +void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) { - _glfwInputError(GLFW_PLATFORM_ERROR, + _glfwInputError(GLFW_FEATURE_UNAVAILABLE, "Wayland: Gamma ramp access is not available"); } @@ -266,6 +260,15 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Wayland: Platform not initialized"); + return NULL; + } + return monitor->wl.output; } +#endif // _GLFW_WAYLAND + diff --git a/src/lib/src/vendor/glfw-3.4/src/wl_platform.h b/src/lib/src/vendor/glfw-3.4/src/wl_platform.h new file mode 100644 index 0000000..149cd24 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/wl_platform.h @@ -0,0 +1,691 @@ +//======================================================================== +// GLFW 3.4 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include +#include +#include + +#include + +typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; + +typedef struct VkWaylandSurfaceCreateInfoKHR +{ + VkStructureType sType; + const void* pNext; + VkWaylandSurfaceCreateFlagsKHR flags; + struct wl_display* display; + struct wl_surface* surface; +} VkWaylandSurfaceCreateInfoKHR; + +typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); +typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*); + +#include "xkb_unicode.h" +#include "posix_poll.h" + +typedef int (* PFN_wl_display_flush)(struct wl_display* display); +typedef void (* PFN_wl_display_cancel_read)(struct wl_display* display); +typedef int (* PFN_wl_display_dispatch_pending)(struct wl_display* display); +typedef int (* PFN_wl_display_read_events)(struct wl_display* display); +typedef struct wl_display* (* PFN_wl_display_connect)(const char*); +typedef void (* PFN_wl_display_disconnect)(struct wl_display*); +typedef int (* PFN_wl_display_roundtrip)(struct wl_display*); +typedef int (* PFN_wl_display_get_fd)(struct wl_display*); +typedef int (* PFN_wl_display_prepare_read)(struct wl_display*); +typedef void (* PFN_wl_proxy_marshal)(struct wl_proxy*,uint32_t,...); +typedef int (* PFN_wl_proxy_add_listener)(struct wl_proxy*,void(**)(void),void*); +typedef void (* PFN_wl_proxy_destroy)(struct wl_proxy*); +typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor)(struct wl_proxy*,uint32_t,const struct wl_interface*,...); +typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor_versioned)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,...); +typedef void* (* PFN_wl_proxy_get_user_data)(struct wl_proxy*); +typedef void (* PFN_wl_proxy_set_user_data)(struct wl_proxy*,void*); +typedef void (* PFN_wl_proxy_set_tag)(struct wl_proxy*,const char*const*); +typedef const char* const* (* PFN_wl_proxy_get_tag)(struct wl_proxy*); +typedef uint32_t (* PFN_wl_proxy_get_version)(struct wl_proxy*); +typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,uint32_t,...); +#define wl_display_flush _glfw.wl.client.display_flush +#define wl_display_cancel_read _glfw.wl.client.display_cancel_read +#define wl_display_dispatch_pending _glfw.wl.client.display_dispatch_pending +#define wl_display_read_events _glfw.wl.client.display_read_events +#define wl_display_disconnect _glfw.wl.client.display_disconnect +#define wl_display_roundtrip _glfw.wl.client.display_roundtrip +#define wl_display_get_fd _glfw.wl.client.display_get_fd +#define wl_display_prepare_read _glfw.wl.client.display_prepare_read +#define wl_proxy_marshal _glfw.wl.client.proxy_marshal +#define wl_proxy_add_listener _glfw.wl.client.proxy_add_listener +#define wl_proxy_destroy _glfw.wl.client.proxy_destroy +#define wl_proxy_marshal_constructor _glfw.wl.client.proxy_marshal_constructor +#define wl_proxy_marshal_constructor_versioned _glfw.wl.client.proxy_marshal_constructor_versioned +#define wl_proxy_get_user_data _glfw.wl.client.proxy_get_user_data +#define wl_proxy_set_user_data _glfw.wl.client.proxy_set_user_data +#define wl_proxy_get_tag _glfw.wl.client.proxy_get_tag +#define wl_proxy_set_tag _glfw.wl.client.proxy_set_tag +#define wl_proxy_get_version _glfw.wl.client.proxy_get_version +#define wl_proxy_marshal_flags _glfw.wl.client.proxy_marshal_flags + +struct wl_shm; +struct wl_output; + +#define wl_display_interface _glfw_wl_display_interface +#define wl_subcompositor_interface _glfw_wl_subcompositor_interface +#define wl_compositor_interface _glfw_wl_compositor_interface +#define wl_shm_interface _glfw_wl_shm_interface +#define wl_data_device_manager_interface _glfw_wl_data_device_manager_interface +#define wl_shell_interface _glfw_wl_shell_interface +#define wl_buffer_interface _glfw_wl_buffer_interface +#define wl_callback_interface _glfw_wl_callback_interface +#define wl_data_device_interface _glfw_wl_data_device_interface +#define wl_data_offer_interface _glfw_wl_data_offer_interface +#define wl_data_source_interface _glfw_wl_data_source_interface +#define wl_keyboard_interface _glfw_wl_keyboard_interface +#define wl_output_interface _glfw_wl_output_interface +#define wl_pointer_interface _glfw_wl_pointer_interface +#define wl_region_interface _glfw_wl_region_interface +#define wl_registry_interface _glfw_wl_registry_interface +#define wl_seat_interface _glfw_wl_seat_interface +#define wl_shell_surface_interface _glfw_wl_shell_surface_interface +#define wl_shm_pool_interface _glfw_wl_shm_pool_interface +#define wl_subsurface_interface _glfw_wl_subsurface_interface +#define wl_surface_interface _glfw_wl_surface_interface +#define wl_touch_interface _glfw_wl_touch_interface +#define zwp_idle_inhibitor_v1_interface _glfw_zwp_idle_inhibitor_v1_interface +#define zwp_idle_inhibit_manager_v1_interface _glfw_zwp_idle_inhibit_manager_v1_interface +#define zwp_confined_pointer_v1_interface _glfw_zwp_confined_pointer_v1_interface +#define zwp_locked_pointer_v1_interface _glfw_zwp_locked_pointer_v1_interface +#define zwp_pointer_constraints_v1_interface _glfw_zwp_pointer_constraints_v1_interface +#define zwp_relative_pointer_v1_interface _glfw_zwp_relative_pointer_v1_interface +#define zwp_relative_pointer_manager_v1_interface _glfw_zwp_relative_pointer_manager_v1_interface +#define wp_viewport_interface _glfw_wp_viewport_interface +#define wp_viewporter_interface _glfw_wp_viewporter_interface +#define xdg_toplevel_interface _glfw_xdg_toplevel_interface +#define zxdg_toplevel_decoration_v1_interface _glfw_zxdg_toplevel_decoration_v1_interface +#define zxdg_decoration_manager_v1_interface _glfw_zxdg_decoration_manager_v1_interface +#define xdg_popup_interface _glfw_xdg_popup_interface +#define xdg_positioner_interface _glfw_xdg_positioner_interface +#define xdg_surface_interface _glfw_xdg_surface_interface +#define xdg_toplevel_interface _glfw_xdg_toplevel_interface +#define xdg_wm_base_interface _glfw_xdg_wm_base_interface +#define xdg_activation_v1_interface _glfw_xdg_activation_v1_interface +#define xdg_activation_token_v1_interface _glfw_xdg_activation_token_v1_interface +#define wl_surface_interface _glfw_wl_surface_interface +#define wp_fractional_scale_v1_interface _glfw_wp_fractional_scale_v1_interface + +#define GLFW_WAYLAND_WINDOW_STATE _GLFWwindowWayland wl; +#define GLFW_WAYLAND_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl; +#define GLFW_WAYLAND_MONITOR_STATE _GLFWmonitorWayland wl; +#define GLFW_WAYLAND_CURSOR_STATE _GLFWcursorWayland wl; + +struct wl_cursor_image { + uint32_t width; + uint32_t height; + uint32_t hotspot_x; + uint32_t hotspot_y; + uint32_t delay; +}; +struct wl_cursor { + unsigned int image_count; + struct wl_cursor_image** images; + char* name; +}; +typedef struct wl_cursor_theme* (* PFN_wl_cursor_theme_load)(const char*, int, struct wl_shm*); +typedef void (* PFN_wl_cursor_theme_destroy)(struct wl_cursor_theme*); +typedef struct wl_cursor* (* PFN_wl_cursor_theme_get_cursor)(struct wl_cursor_theme*, const char*); +typedef struct wl_buffer* (* PFN_wl_cursor_image_get_buffer)(struct wl_cursor_image*); +#define wl_cursor_theme_load _glfw.wl.cursor.theme_load +#define wl_cursor_theme_destroy _glfw.wl.cursor.theme_destroy +#define wl_cursor_theme_get_cursor _glfw.wl.cursor.theme_get_cursor +#define wl_cursor_image_get_buffer _glfw.wl.cursor.image_get_buffer + +typedef struct wl_egl_window* (* PFN_wl_egl_window_create)(struct wl_surface*, int, int); +typedef void (* PFN_wl_egl_window_destroy)(struct wl_egl_window*); +typedef void (* PFN_wl_egl_window_resize)(struct wl_egl_window*, int, int, int, int); +#define wl_egl_window_create _glfw.wl.egl.window_create +#define wl_egl_window_destroy _glfw.wl.egl.window_destroy +#define wl_egl_window_resize _glfw.wl.egl.window_resize + +typedef struct xkb_context* (* PFN_xkb_context_new)(enum xkb_context_flags); +typedef void (* PFN_xkb_context_unref)(struct xkb_context*); +typedef struct xkb_keymap* (* PFN_xkb_keymap_new_from_string)(struct xkb_context*, const char*, enum xkb_keymap_format, enum xkb_keymap_compile_flags); +typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*); +typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*); +typedef int (* PFN_xkb_keymap_key_repeats)(struct xkb_keymap*, xkb_keycode_t); +typedef int (* PFN_xkb_keymap_key_get_syms_by_level)(struct xkb_keymap*,xkb_keycode_t,xkb_layout_index_t,xkb_level_index_t,const xkb_keysym_t**); +typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*); +typedef void (* PFN_xkb_state_unref)(struct xkb_state*); +typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**); +typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t); +typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t); +typedef int (* PFN_xkb_state_mod_index_is_active)(struct xkb_state*,xkb_mod_index_t,enum xkb_state_component); +#define xkb_context_new _glfw.wl.xkb.context_new +#define xkb_context_unref _glfw.wl.xkb.context_unref +#define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string +#define xkb_keymap_unref _glfw.wl.xkb.keymap_unref +#define xkb_keymap_mod_get_index _glfw.wl.xkb.keymap_mod_get_index +#define xkb_keymap_key_repeats _glfw.wl.xkb.keymap_key_repeats +#define xkb_keymap_key_get_syms_by_level _glfw.wl.xkb.keymap_key_get_syms_by_level +#define xkb_state_new _glfw.wl.xkb.state_new +#define xkb_state_unref _glfw.wl.xkb.state_unref +#define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms +#define xkb_state_update_mask _glfw.wl.xkb.state_update_mask +#define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout +#define xkb_state_mod_index_is_active _glfw.wl.xkb.state_mod_index_is_active + +typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags); +typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*); +typedef struct xkb_compose_state* (* PFN_xkb_compose_state_new)(struct xkb_compose_table*, enum xkb_compose_state_flags); +typedef void (* PFN_xkb_compose_state_unref)(struct xkb_compose_state*); +typedef enum xkb_compose_feed_result (* PFN_xkb_compose_state_feed)(struct xkb_compose_state*, xkb_keysym_t); +typedef enum xkb_compose_status (* PFN_xkb_compose_state_get_status)(struct xkb_compose_state*); +typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_state*); +#define xkb_compose_table_new_from_locale _glfw.wl.xkb.compose_table_new_from_locale +#define xkb_compose_table_unref _glfw.wl.xkb.compose_table_unref +#define xkb_compose_state_new _glfw.wl.xkb.compose_state_new +#define xkb_compose_state_unref _glfw.wl.xkb.compose_state_unref +#define xkb_compose_state_feed _glfw.wl.xkb.compose_state_feed +#define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status +#define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym + +struct libdecor; +struct libdecor_frame; +struct libdecor_state; +struct libdecor_configuration; + +enum libdecor_error +{ + LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE, + LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION, +}; + +enum libdecor_window_state +{ + LIBDECOR_WINDOW_STATE_NONE = 0, + LIBDECOR_WINDOW_STATE_ACTIVE = 1, + LIBDECOR_WINDOW_STATE_MAXIMIZED = 2, + LIBDECOR_WINDOW_STATE_FULLSCREEN = 4, + LIBDECOR_WINDOW_STATE_TILED_LEFT = 8, + LIBDECOR_WINDOW_STATE_TILED_RIGHT = 16, + LIBDECOR_WINDOW_STATE_TILED_TOP = 32, + LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 64 +}; + +enum libdecor_capabilities +{ + LIBDECOR_ACTION_MOVE = 1, + LIBDECOR_ACTION_RESIZE = 2, + LIBDECOR_ACTION_MINIMIZE = 4, + LIBDECOR_ACTION_FULLSCREEN = 8, + LIBDECOR_ACTION_CLOSE = 16 +}; + +struct libdecor_interface +{ + void (* error)(struct libdecor*,enum libdecor_error,const char*); + void (* reserved0)(void); + void (* reserved1)(void); + void (* reserved2)(void); + void (* reserved3)(void); + void (* reserved4)(void); + void (* reserved5)(void); + void (* reserved6)(void); + void (* reserved7)(void); + void (* reserved8)(void); + void (* reserved9)(void); +}; + +struct libdecor_frame_interface +{ + void (* configure)(struct libdecor_frame*,struct libdecor_configuration*,void*); + void (* close)(struct libdecor_frame*,void*); + void (* commit)(struct libdecor_frame*,void*); + void (* dismiss_popup)(struct libdecor_frame*,const char*,void*); + void (* reserved0)(void); + void (* reserved1)(void); + void (* reserved2)(void); + void (* reserved3)(void); + void (* reserved4)(void); + void (* reserved5)(void); + void (* reserved6)(void); + void (* reserved7)(void); + void (* reserved8)(void); + void (* reserved9)(void); +}; + +typedef struct libdecor* (* PFN_libdecor_new)(struct wl_display*,const struct libdecor_interface*); +typedef void (* PFN_libdecor_unref)(struct libdecor*); +typedef int (* PFN_libdecor_get_fd)(struct libdecor*); +typedef int (* PFN_libdecor_dispatch)(struct libdecor*,int); +typedef struct libdecor_frame* (* PFN_libdecor_decorate)(struct libdecor*,struct wl_surface*,const struct libdecor_frame_interface*,void*); +typedef void (* PFN_libdecor_frame_unref)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_set_app_id)(struct libdecor_frame*,const char*); +typedef void (* PFN_libdecor_frame_set_title)(struct libdecor_frame*,const char*); +typedef void (* PFN_libdecor_frame_set_minimized)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_set_fullscreen)(struct libdecor_frame*,struct wl_output*); +typedef void (* PFN_libdecor_frame_unset_fullscreen)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_map)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_commit)(struct libdecor_frame*,struct libdecor_state*,struct libdecor_configuration*); +typedef void (* PFN_libdecor_frame_set_min_content_size)(struct libdecor_frame*,int,int); +typedef void (* PFN_libdecor_frame_set_max_content_size)(struct libdecor_frame*,int,int); +typedef void (* PFN_libdecor_frame_set_maximized)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_unset_maximized)(struct libdecor_frame*); +typedef void (* PFN_libdecor_frame_set_capabilities)(struct libdecor_frame*,enum libdecor_capabilities); +typedef void (* PFN_libdecor_frame_unset_capabilities)(struct libdecor_frame*,enum libdecor_capabilities); +typedef void (* PFN_libdecor_frame_set_visibility)(struct libdecor_frame*,bool visible); +typedef struct xdg_toplevel* (* PFN_libdecor_frame_get_xdg_toplevel)(struct libdecor_frame*); +typedef bool (* PFN_libdecor_configuration_get_content_size)(struct libdecor_configuration*,struct libdecor_frame*,int*,int*); +typedef bool (* PFN_libdecor_configuration_get_window_state)(struct libdecor_configuration*,enum libdecor_window_state*); +typedef struct libdecor_state* (* PFN_libdecor_state_new)(int,int); +typedef void (* PFN_libdecor_state_free)(struct libdecor_state*); +#define libdecor_new _glfw.wl.libdecor.libdecor_new_ +#define libdecor_unref _glfw.wl.libdecor.libdecor_unref_ +#define libdecor_get_fd _glfw.wl.libdecor.libdecor_get_fd_ +#define libdecor_dispatch _glfw.wl.libdecor.libdecor_dispatch_ +#define libdecor_decorate _glfw.wl.libdecor.libdecor_decorate_ +#define libdecor_frame_unref _glfw.wl.libdecor.libdecor_frame_unref_ +#define libdecor_frame_set_app_id _glfw.wl.libdecor.libdecor_frame_set_app_id_ +#define libdecor_frame_set_title _glfw.wl.libdecor.libdecor_frame_set_title_ +#define libdecor_frame_set_minimized _glfw.wl.libdecor.libdecor_frame_set_minimized_ +#define libdecor_frame_set_fullscreen _glfw.wl.libdecor.libdecor_frame_set_fullscreen_ +#define libdecor_frame_unset_fullscreen _glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ +#define libdecor_frame_map _glfw.wl.libdecor.libdecor_frame_map_ +#define libdecor_frame_commit _glfw.wl.libdecor.libdecor_frame_commit_ +#define libdecor_frame_set_min_content_size _glfw.wl.libdecor.libdecor_frame_set_min_content_size_ +#define libdecor_frame_set_max_content_size _glfw.wl.libdecor.libdecor_frame_set_max_content_size_ +#define libdecor_frame_set_maximized _glfw.wl.libdecor.libdecor_frame_set_maximized_ +#define libdecor_frame_unset_maximized _glfw.wl.libdecor.libdecor_frame_unset_maximized_ +#define libdecor_frame_set_capabilities _glfw.wl.libdecor.libdecor_frame_set_capabilities_ +#define libdecor_frame_unset_capabilities _glfw.wl.libdecor.libdecor_frame_unset_capabilities_ +#define libdecor_frame_set_visibility _glfw.wl.libdecor.libdecor_frame_set_visibility_ +#define libdecor_frame_get_xdg_toplevel _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ +#define libdecor_configuration_get_content_size _glfw.wl.libdecor.libdecor_configuration_get_content_size_ +#define libdecor_configuration_get_window_state _glfw.wl.libdecor.libdecor_configuration_get_window_state_ +#define libdecor_state_new _glfw.wl.libdecor.libdecor_state_new_ +#define libdecor_state_free _glfw.wl.libdecor.libdecor_state_free_ + +typedef struct _GLFWfallbackEdgeWayland +{ + struct wl_surface* surface; + struct wl_subsurface* subsurface; + struct wp_viewport* viewport; +} _GLFWfallbackEdgeWayland; + +typedef struct _GLFWofferWayland +{ + struct wl_data_offer* offer; + GLFWbool text_plain_utf8; + GLFWbool text_uri_list; +} _GLFWofferWayland; + +typedef struct _GLFWscaleWayland +{ + struct wl_output* output; + int32_t factor; +} _GLFWscaleWayland; + +// Wayland-specific per-window data +// +typedef struct _GLFWwindowWayland +{ + int width, height; + int fbWidth, fbHeight; + GLFWbool visible; + GLFWbool maximized; + GLFWbool activated; + GLFWbool fullscreen; + GLFWbool hovered; + GLFWbool transparent; + GLFWbool scaleFramebuffer; + struct wl_surface* surface; + struct wl_callback* callback; + + struct { + struct wl_egl_window* window; + } egl; + + struct { + int width, height; + GLFWbool maximized; + GLFWbool iconified; + GLFWbool activated; + GLFWbool fullscreen; + } pending; + + struct { + struct xdg_surface* surface; + struct xdg_toplevel* toplevel; + struct zxdg_toplevel_decoration_v1* decoration; + uint32_t decorationMode; + } xdg; + + struct { + struct libdecor_frame* frame; + } libdecor; + + _GLFWcursor* currentCursor; + double cursorPosX, cursorPosY; + + char* appId; + + // We need to track the monitors the window spans on to calculate the + // optimal scaling factor. + int32_t bufferScale; + _GLFWscaleWayland* outputScales; + size_t outputScaleCount; + size_t outputScaleSize; + + struct wp_viewport* scalingViewport; + uint32_t scalingNumerator; + struct wp_fractional_scale_v1* fractionalScale; + + struct zwp_relative_pointer_v1* relativePointer; + struct zwp_locked_pointer_v1* lockedPointer; + struct zwp_confined_pointer_v1* confinedPointer; + + struct zwp_idle_inhibitor_v1* idleInhibitor; + struct xdg_activation_token_v1* activationToken; + + struct { + GLFWbool decorations; + struct wl_buffer* buffer; + _GLFWfallbackEdgeWayland top, left, right, bottom; + struct wl_surface* focus; + } fallback; +} _GLFWwindowWayland; + +// Wayland-specific global data +// +typedef struct _GLFWlibraryWayland +{ + struct wl_display* display; + struct wl_registry* registry; + struct wl_compositor* compositor; + struct wl_subcompositor* subcompositor; + struct wl_shm* shm; + struct wl_seat* seat; + struct wl_pointer* pointer; + struct wl_keyboard* keyboard; + struct wl_data_device_manager* dataDeviceManager; + struct wl_data_device* dataDevice; + struct xdg_wm_base* wmBase; + struct zxdg_decoration_manager_v1* decorationManager; + struct wp_viewporter* viewporter; + struct zwp_relative_pointer_manager_v1* relativePointerManager; + struct zwp_pointer_constraints_v1* pointerConstraints; + struct zwp_idle_inhibit_manager_v1* idleInhibitManager; + struct xdg_activation_v1* activationManager; + struct wp_fractional_scale_manager_v1* fractionalScaleManager; + + _GLFWofferWayland* offers; + unsigned int offerCount; + + struct wl_data_offer* selectionOffer; + struct wl_data_source* selectionSource; + + struct wl_data_offer* dragOffer; + _GLFWwindow* dragFocus; + uint32_t dragSerial; + + const char* tag; + + struct wl_cursor_theme* cursorTheme; + struct wl_cursor_theme* cursorThemeHiDPI; + struct wl_surface* cursorSurface; + const char* cursorPreviousName; + int cursorTimerfd; + uint32_t serial; + uint32_t pointerEnterSerial; + + int keyRepeatTimerfd; + int32_t keyRepeatRate; + int32_t keyRepeatDelay; + int keyRepeatScancode; + + char* clipboardString; + short int keycodes[256]; + short int scancodes[GLFW_KEY_LAST + 1]; + char keynames[GLFW_KEY_LAST + 1][5]; + + struct { + void* handle; + struct xkb_context* context; + struct xkb_keymap* keymap; + struct xkb_state* state; + + struct xkb_compose_state* composeState; + + xkb_mod_index_t controlIndex; + xkb_mod_index_t altIndex; + xkb_mod_index_t shiftIndex; + xkb_mod_index_t superIndex; + xkb_mod_index_t capsLockIndex; + xkb_mod_index_t numLockIndex; + unsigned int modifiers; + + PFN_xkb_context_new context_new; + PFN_xkb_context_unref context_unref; + PFN_xkb_keymap_new_from_string keymap_new_from_string; + PFN_xkb_keymap_unref keymap_unref; + PFN_xkb_keymap_mod_get_index keymap_mod_get_index; + PFN_xkb_keymap_key_repeats keymap_key_repeats; + PFN_xkb_keymap_key_get_syms_by_level keymap_key_get_syms_by_level; + PFN_xkb_state_new state_new; + PFN_xkb_state_unref state_unref; + PFN_xkb_state_key_get_syms state_key_get_syms; + PFN_xkb_state_update_mask state_update_mask; + PFN_xkb_state_key_get_layout state_key_get_layout; + PFN_xkb_state_mod_index_is_active state_mod_index_is_active; + + PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale; + PFN_xkb_compose_table_unref compose_table_unref; + PFN_xkb_compose_state_new compose_state_new; + PFN_xkb_compose_state_unref compose_state_unref; + PFN_xkb_compose_state_feed compose_state_feed; + PFN_xkb_compose_state_get_status compose_state_get_status; + PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym; + } xkb; + + _GLFWwindow* pointerFocus; + _GLFWwindow* keyboardFocus; + + struct { + void* handle; + PFN_wl_display_flush display_flush; + PFN_wl_display_cancel_read display_cancel_read; + PFN_wl_display_dispatch_pending display_dispatch_pending; + PFN_wl_display_read_events display_read_events; + PFN_wl_display_disconnect display_disconnect; + PFN_wl_display_roundtrip display_roundtrip; + PFN_wl_display_get_fd display_get_fd; + PFN_wl_display_prepare_read display_prepare_read; + PFN_wl_proxy_marshal proxy_marshal; + PFN_wl_proxy_add_listener proxy_add_listener; + PFN_wl_proxy_destroy proxy_destroy; + PFN_wl_proxy_marshal_constructor proxy_marshal_constructor; + PFN_wl_proxy_marshal_constructor_versioned proxy_marshal_constructor_versioned; + PFN_wl_proxy_get_user_data proxy_get_user_data; + PFN_wl_proxy_set_user_data proxy_set_user_data; + PFN_wl_proxy_get_tag proxy_get_tag; + PFN_wl_proxy_set_tag proxy_set_tag; + PFN_wl_proxy_get_version proxy_get_version; + PFN_wl_proxy_marshal_flags proxy_marshal_flags; + } client; + + struct { + void* handle; + + PFN_wl_cursor_theme_load theme_load; + PFN_wl_cursor_theme_destroy theme_destroy; + PFN_wl_cursor_theme_get_cursor theme_get_cursor; + PFN_wl_cursor_image_get_buffer image_get_buffer; + } cursor; + + struct { + void* handle; + + PFN_wl_egl_window_create window_create; + PFN_wl_egl_window_destroy window_destroy; + PFN_wl_egl_window_resize window_resize; + } egl; + + struct { + void* handle; + struct libdecor* context; + struct wl_callback* callback; + GLFWbool ready; + PFN_libdecor_new libdecor_new_; + PFN_libdecor_unref libdecor_unref_; + PFN_libdecor_get_fd libdecor_get_fd_; + PFN_libdecor_dispatch libdecor_dispatch_; + PFN_libdecor_decorate libdecor_decorate_; + PFN_libdecor_frame_unref libdecor_frame_unref_; + PFN_libdecor_frame_set_app_id libdecor_frame_set_app_id_; + PFN_libdecor_frame_set_title libdecor_frame_set_title_; + PFN_libdecor_frame_set_minimized libdecor_frame_set_minimized_; + PFN_libdecor_frame_set_fullscreen libdecor_frame_set_fullscreen_; + PFN_libdecor_frame_unset_fullscreen libdecor_frame_unset_fullscreen_; + PFN_libdecor_frame_map libdecor_frame_map_; + PFN_libdecor_frame_commit libdecor_frame_commit_; + PFN_libdecor_frame_set_min_content_size libdecor_frame_set_min_content_size_; + PFN_libdecor_frame_set_max_content_size libdecor_frame_set_max_content_size_; + PFN_libdecor_frame_set_maximized libdecor_frame_set_maximized_; + PFN_libdecor_frame_unset_maximized libdecor_frame_unset_maximized_; + PFN_libdecor_frame_set_capabilities libdecor_frame_set_capabilities_; + PFN_libdecor_frame_unset_capabilities libdecor_frame_unset_capabilities_; + PFN_libdecor_frame_set_visibility libdecor_frame_set_visibility_; + PFN_libdecor_frame_get_xdg_toplevel libdecor_frame_get_xdg_toplevel_; + PFN_libdecor_configuration_get_content_size libdecor_configuration_get_content_size_; + PFN_libdecor_configuration_get_window_state libdecor_configuration_get_window_state_; + PFN_libdecor_state_new libdecor_state_new_; + PFN_libdecor_state_free libdecor_state_free_; + } libdecor; +} _GLFWlibraryWayland; + +// Wayland-specific per-monitor data +// +typedef struct _GLFWmonitorWayland +{ + struct wl_output* output; + uint32_t name; + int currentMode; + + int x; + int y; + int32_t scale; +} _GLFWmonitorWayland; + +// Wayland-specific per-cursor data +// +typedef struct _GLFWcursorWayland +{ + struct wl_cursor* cursor; + struct wl_cursor* cursorHiDPI; + struct wl_buffer* buffer; + int width, height; + int xhot, yhot; + int currentImage; +} _GLFWcursorWayland; + +GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform); +int _glfwInitWayland(void); +void _glfwTerminateWayland(void); + +GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); +void _glfwDestroyWindowWayland(_GLFWwindow* window); +void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title); +void _glfwSetWindowIconWayland(_GLFWwindow* window, int count, const GLFWimage* images); +void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos); +void _glfwSetWindowPosWayland(_GLFWwindow* window, int xpos, int ypos); +void _glfwGetWindowSizeWayland(_GLFWwindow* window, int* width, int* height); +void _glfwSetWindowSizeWayland(_GLFWwindow* window, int width, int height); +void _glfwSetWindowSizeLimitsWayland(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight); +void _glfwSetWindowAspectRatioWayland(_GLFWwindow* window, int numer, int denom); +void _glfwGetFramebufferSizeWayland(_GLFWwindow* window, int* width, int* height); +void _glfwGetWindowFrameSizeWayland(_GLFWwindow* window, int* left, int* top, int* right, int* bottom); +void _glfwGetWindowContentScaleWayland(_GLFWwindow* window, float* xscale, float* yscale); +void _glfwIconifyWindowWayland(_GLFWwindow* window); +void _glfwRestoreWindowWayland(_GLFWwindow* window); +void _glfwMaximizeWindowWayland(_GLFWwindow* window); +void _glfwShowWindowWayland(_GLFWwindow* window); +void _glfwHideWindowWayland(_GLFWwindow* window); +void _glfwRequestWindowAttentionWayland(_GLFWwindow* window); +void _glfwFocusWindowWayland(_GLFWwindow* window); +void _glfwSetWindowMonitorWayland(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); +GLFWbool _glfwWindowFocusedWayland(_GLFWwindow* window); +GLFWbool _glfwWindowIconifiedWayland(_GLFWwindow* window); +GLFWbool _glfwWindowVisibleWayland(_GLFWwindow* window); +GLFWbool _glfwWindowMaximizedWayland(_GLFWwindow* window); +GLFWbool _glfwWindowHoveredWayland(_GLFWwindow* window); +GLFWbool _glfwFramebufferTransparentWayland(_GLFWwindow* window); +void _glfwSetWindowResizableWayland(_GLFWwindow* window, GLFWbool enabled); +void _glfwSetWindowDecoratedWayland(_GLFWwindow* window, GLFWbool enabled); +void _glfwSetWindowFloatingWayland(_GLFWwindow* window, GLFWbool enabled); +float _glfwGetWindowOpacityWayland(_GLFWwindow* window); +void _glfwSetWindowOpacityWayland(_GLFWwindow* window, float opacity); +void _glfwSetWindowMousePassthroughWayland(_GLFWwindow* window, GLFWbool enabled); + +void _glfwSetRawMouseMotionWayland(_GLFWwindow* window, GLFWbool enabled); +GLFWbool _glfwRawMouseMotionSupportedWayland(void); + +void _glfwPollEventsWayland(void); +void _glfwWaitEventsWayland(void); +void _glfwWaitEventsTimeoutWayland(double timeout); +void _glfwPostEmptyEventWayland(void); + +void _glfwGetCursorPosWayland(_GLFWwindow* window, double* xpos, double* ypos); +void _glfwSetCursorPosWayland(_GLFWwindow* window, double xpos, double ypos); +void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode); +const char* _glfwGetScancodeNameWayland(int scancode); +int _glfwGetKeyScancodeWayland(int key); +GLFWbool _glfwCreateCursorWayland(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot); +GLFWbool _glfwCreateStandardCursorWayland(_GLFWcursor* cursor, int shape); +void _glfwDestroyCursorWayland(_GLFWcursor* cursor); +void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor); +void _glfwSetClipboardStringWayland(const char* string); +const char* _glfwGetClipboardStringWayland(void); + +EGLenum _glfwGetEGLPlatformWayland(EGLint** attribs); +EGLNativeDisplayType _glfwGetEGLNativeDisplayWayland(void); +EGLNativeWindowType _glfwGetEGLNativeWindowWayland(_GLFWwindow* window); + +void _glfwGetRequiredInstanceExtensionsWayland(char** extensions); +GLFWbool _glfwGetPhysicalDevicePresentationSupportWayland(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily); +VkResult _glfwCreateWindowSurfaceWayland(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); + +void _glfwFreeMonitorWayland(_GLFWmonitor* monitor); +void _glfwGetMonitorPosWayland(_GLFWmonitor* monitor, int* xpos, int* ypos); +void _glfwGetMonitorContentScaleWayland(_GLFWmonitor* monitor, float* xscale, float* yscale); +void _glfwGetMonitorWorkareaWayland(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); +GLFWvidmode* _glfwGetVideoModesWayland(_GLFWmonitor* monitor, int* count); +GLFWbool _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode); +GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp); +void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); + +void _glfwAddOutputWayland(uint32_t name, uint32_t version); +void _glfwUpdateBufferScaleFromOutputsWayland(_GLFWwindow* window); + +void _glfwAddSeatListenerWayland(struct wl_seat* seat); +void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device); + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/wl_window.c b/src/lib/src/vendor/glfw-3.4/src/wl_window.c similarity index 55% rename from src/lib/src/vendor/glfw-3.3.8/src/wl_window.c rename to src/lib/src/vendor/glfw-3.4/src/wl_window.c index 53cbd33..5b491ff 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/wl_window.c +++ b/src/lib/src/vendor/glfw-3.4/src/wl_window.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Wayland - www.glfw.org +// GLFW 3.4 Wayland - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2014 Jonas Ådahl // @@ -23,13 +23,13 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #define _GNU_SOURCE #include "internal.h" +#if defined(_GLFW_WAYLAND) + #include #include #include @@ -40,8 +40,17 @@ #include #include #include -#include -#include +#include + +#include "wayland-client-protocol.h" +#include "xdg-shell-client-protocol.h" +#include "xdg-decoration-unstable-v1-client-protocol.h" +#include "viewporter-client-protocol.h" +#include "relative-pointer-unstable-v1-client-protocol.h" +#include "pointer-constraints-unstable-v1-client-protocol.h" +#include "xdg-activation-v1-client-protocol.h" +#include "idle-inhibit-unstable-v1-client-protocol.h" +#include "fractional-scale-v1-client-protocol.h" #define GLFW_BORDER_SIZE 4 #define GLFW_CAPTION_HEIGHT 24 @@ -109,12 +118,12 @@ static int createAnonymousFile(off_t size) return -1; } - name = calloc(strlen(path) + sizeof(template), 1); + name = _glfw_calloc(strlen(path) + sizeof(template), 1); strcpy(name, path); strcat(name, template); fd = createTmpfileCloexec(name); - free(name); + _glfw_free(name); if (fd < 0) return -1; } @@ -136,14 +145,10 @@ static int createAnonymousFile(off_t size) static struct wl_buffer* createShmBuffer(const GLFWimage* image) { - struct wl_shm_pool* pool; - struct wl_buffer* buffer; - int stride = image->width * 4; - int length = image->width * image->height * 4; - void* data; - int fd, i; + const int stride = image->width * 4; + const int length = image->width * image->height * 4; - fd = createAnonymousFile(length); + const int fd = createAnonymousFile(length); if (fd < 0) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -152,7 +157,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image) return NULL; } - data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + void* data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (data == MAP_FAILED) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -161,12 +166,13 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image) return NULL; } - pool = wl_shm_create_pool(_glfw.wl.shm, fd, length); + struct wl_shm_pool* pool = wl_shm_create_pool(_glfw.wl.shm, fd, length); close(fd); + unsigned char* source = (unsigned char*) image->pixels; unsigned char* target = data; - for (i = 0; i < image->width * image->height; i++, source += 4) + for (int i = 0; i < image->width * image->height; i++, source += 4) { unsigned int alpha = source[3]; @@ -176,7 +182,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image) *target++ = (unsigned char) alpha; } - buffer = + struct wl_buffer* buffer = wl_shm_pool_create_buffer(pool, 0, image->width, image->height, @@ -187,73 +193,28 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image) return buffer; } -// Wait for data to arrive on any of the specified file descriptors -// -static GLFWbool waitForData(struct pollfd* fds, nfds_t count, double* timeout) +static void createFallbackEdge(_GLFWwindow* window, + _GLFWfallbackEdgeWayland* edge, + struct wl_surface* parent, + struct wl_buffer* buffer, + int x, int y, + int width, int height) { - 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; - } - } -} - -static void createFallbackDecoration(_GLFWdecorationWayland* decoration, - struct wl_surface* parent, - struct wl_buffer* buffer, - int x, int y, - int width, int height) -{ - decoration->surface = wl_compositor_create_surface(_glfw.wl.compositor); - decoration->subsurface = - wl_subcompositor_get_subsurface(_glfw.wl.subcompositor, - decoration->surface, parent); - wl_subsurface_set_position(decoration->subsurface, x, y); - decoration->viewport = wp_viewporter_get_viewport(_glfw.wl.viewporter, - decoration->surface); - wp_viewport_set_destination(decoration->viewport, width, height); - wl_surface_attach(decoration->surface, buffer, 0, 0); + edge->surface = wl_compositor_create_surface(_glfw.wl.compositor); + wl_surface_set_user_data(edge->surface, window); + wl_proxy_set_tag((struct wl_proxy*) edge->surface, &_glfw.wl.tag); + edge->subsurface = wl_subcompositor_get_subsurface(_glfw.wl.subcompositor, + edge->surface, parent); + wl_subsurface_set_position(edge->subsurface, x, y); + edge->viewport = wp_viewporter_get_viewport(_glfw.wl.viewporter, + edge->surface); + wp_viewport_set_destination(edge->viewport, width, height); + wl_surface_attach(edge->surface, buffer, 0, 0); struct wl_region* region = wl_compositor_create_region(_glfw.wl.compositor); wl_region_add(region, 0, 0, width, height); - wl_surface_set_opaque_region(decoration->surface, region); - wl_surface_commit(decoration->surface); + wl_surface_set_opaque_region(edge->surface, region); + wl_surface_commit(edge->surface); wl_region_destroy(region); } @@ -265,48 +226,53 @@ static void createFallbackDecorations(_GLFWwindow* window) if (!_glfw.wl.viewporter) return; - if (!window->wl.decorations.buffer) - window->wl.decorations.buffer = createShmBuffer(&image); - if (!window->wl.decorations.buffer) + if (!window->wl.fallback.buffer) + window->wl.fallback.buffer = createShmBuffer(&image); + if (!window->wl.fallback.buffer) return; - createFallbackDecoration(&window->wl.decorations.top, window->wl.surface, - window->wl.decorations.buffer, - 0, -GLFW_CAPTION_HEIGHT, - window->wl.width, GLFW_CAPTION_HEIGHT); - createFallbackDecoration(&window->wl.decorations.left, window->wl.surface, - window->wl.decorations.buffer, - -GLFW_BORDER_SIZE, -GLFW_CAPTION_HEIGHT, - GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); - createFallbackDecoration(&window->wl.decorations.right, window->wl.surface, - window->wl.decorations.buffer, - window->wl.width, -GLFW_CAPTION_HEIGHT, - GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); - createFallbackDecoration(&window->wl.decorations.bottom, window->wl.surface, - window->wl.decorations.buffer, - -GLFW_BORDER_SIZE, window->wl.height, - window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE); + createFallbackEdge(window, &window->wl.fallback.top, window->wl.surface, + window->wl.fallback.buffer, + 0, -GLFW_CAPTION_HEIGHT, + window->wl.width, GLFW_CAPTION_HEIGHT); + createFallbackEdge(window, &window->wl.fallback.left, window->wl.surface, + window->wl.fallback.buffer, + -GLFW_BORDER_SIZE, -GLFW_CAPTION_HEIGHT, + GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); + createFallbackEdge(window, &window->wl.fallback.right, window->wl.surface, + window->wl.fallback.buffer, + window->wl.width, -GLFW_CAPTION_HEIGHT, + GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); + createFallbackEdge(window, &window->wl.fallback.bottom, window->wl.surface, + window->wl.fallback.buffer, + -GLFW_BORDER_SIZE, window->wl.height, + window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE); + + window->wl.fallback.decorations = GLFW_TRUE; } -static void destroyFallbackDecoration(_GLFWdecorationWayland* decoration) +static void destroyFallbackEdge(_GLFWfallbackEdgeWayland* edge) { - if (decoration->subsurface) - wl_subsurface_destroy(decoration->subsurface); - if (decoration->surface) - wl_surface_destroy(decoration->surface); - if (decoration->viewport) - wp_viewport_destroy(decoration->viewport); - decoration->surface = NULL; - decoration->subsurface = NULL; - decoration->viewport = NULL; + if (edge->subsurface) + wl_subsurface_destroy(edge->subsurface); + if (edge->surface) + wl_surface_destroy(edge->surface); + if (edge->viewport) + wp_viewport_destroy(edge->viewport); + + edge->surface = NULL; + edge->subsurface = NULL; + edge->viewport = NULL; } static void destroyFallbackDecorations(_GLFWwindow* window) { - destroyFallbackDecoration(&window->wl.decorations.top); - destroyFallbackDecoration(&window->wl.decorations.left); - destroyFallbackDecoration(&window->wl.decorations.right); - destroyFallbackDecoration(&window->wl.decorations.bottom); + window->wl.fallback.decorations = GLFW_FALSE; + + destroyFallbackEdge(&window->wl.fallback.top); + destroyFallbackEdge(&window->wl.fallback.left); + destroyFallbackEdge(&window->wl.fallback.right); + destroyFallbackEdge(&window->wl.fallback.bottom); } static void xdgDecorationHandleConfigure(void* userData, @@ -345,61 +311,114 @@ static void setContentAreaOpaque(_GLFWwindow* window) wl_region_destroy(region); } - -static void resizeWindow(_GLFWwindow* window) +static void resizeFramebuffer(_GLFWwindow* window) { - int scale = window->wl.scale; - int scaledWidth = window->wl.width * scale; - int scaledHeight = window->wl.height * scale; + if (window->wl.fractionalScale) + { + window->wl.fbWidth = (window->wl.width * window->wl.scalingNumerator) / 120; + window->wl.fbHeight = (window->wl.height * window->wl.scalingNumerator) / 120; + } + else + { + window->wl.fbWidth = window->wl.width * window->wl.bufferScale; + window->wl.fbHeight = window->wl.height * window->wl.bufferScale; + } if (window->wl.egl.window) - wl_egl_window_resize(window->wl.egl.window, scaledWidth, scaledHeight, 0, 0); + { + wl_egl_window_resize(window->wl.egl.window, + window->wl.fbWidth, + window->wl.fbHeight, + 0, 0); + } + if (!window->wl.transparent) setContentAreaOpaque(window); - _glfwInputFramebufferSize(window, scaledWidth, scaledHeight); - if (!window->wl.decorations.top.surface) - return; - - wp_viewport_set_destination(window->wl.decorations.top.viewport, - window->wl.width, GLFW_CAPTION_HEIGHT); - wl_surface_commit(window->wl.decorations.top.surface); - - wp_viewport_set_destination(window->wl.decorations.left.viewport, - GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); - wl_surface_commit(window->wl.decorations.left.surface); - - wl_subsurface_set_position(window->wl.decorations.right.subsurface, - window->wl.width, -GLFW_CAPTION_HEIGHT); - wp_viewport_set_destination(window->wl.decorations.right.viewport, - GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT); - wl_surface_commit(window->wl.decorations.right.surface); - - wl_subsurface_set_position(window->wl.decorations.bottom.subsurface, - -GLFW_BORDER_SIZE, window->wl.height); - wp_viewport_set_destination(window->wl.decorations.bottom.viewport, - window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE); - wl_surface_commit(window->wl.decorations.bottom.surface); + _glfwInputFramebufferSize(window, window->wl.fbWidth, window->wl.fbHeight); } -void _glfwUpdateContentScaleWayland(_GLFWwindow* window) +static GLFWbool resizeWindow(_GLFWwindow* window, int width, int height) { - if (_glfw.wl.compositorVersion < WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION) + width = _glfw_max(width, 1); + height = _glfw_max(height, 1); + + if (width == window->wl.width && height == window->wl.height) + return GLFW_FALSE; + + window->wl.width = width; + window->wl.height = height; + + resizeFramebuffer(window); + + if (window->wl.scalingViewport) + { + wp_viewport_set_destination(window->wl.scalingViewport, + window->wl.width, + window->wl.height); + } + + if (window->wl.fallback.decorations) + { + wp_viewport_set_destination(window->wl.fallback.top.viewport, + window->wl.width, + GLFW_CAPTION_HEIGHT); + wl_surface_commit(window->wl.fallback.top.surface); + + wp_viewport_set_destination(window->wl.fallback.left.viewport, + GLFW_BORDER_SIZE, + window->wl.height + GLFW_CAPTION_HEIGHT); + wl_surface_commit(window->wl.fallback.left.surface); + + wl_subsurface_set_position(window->wl.fallback.right.subsurface, + window->wl.width, -GLFW_CAPTION_HEIGHT); + wp_viewport_set_destination(window->wl.fallback.right.viewport, + GLFW_BORDER_SIZE, + window->wl.height + GLFW_CAPTION_HEIGHT); + wl_surface_commit(window->wl.fallback.right.surface); + + wl_subsurface_set_position(window->wl.fallback.bottom.subsurface, + -GLFW_BORDER_SIZE, window->wl.height); + wp_viewport_set_destination(window->wl.fallback.bottom.viewport, + window->wl.width + GLFW_BORDER_SIZE * 2, + GLFW_BORDER_SIZE); + wl_surface_commit(window->wl.fallback.bottom.surface); + } + + return GLFW_TRUE; +} + +void _glfwUpdateBufferScaleFromOutputsWayland(_GLFWwindow* window) +{ + if (wl_compositor_get_version(_glfw.wl.compositor) < + WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION) + { + return; + } + + if (!window->wl.scaleFramebuffer) + return; + + // When using fractional scaling, the buffer scale should remain at 1 + if (window->wl.fractionalScale) return; // Get the scale factor from the highest scale monitor. - int maxScale = 1; + int32_t maxScale = 1; - for (int i = 0; i < window->wl.monitorsCount; i++) - maxScale = _glfw_max(window->wl.monitors[i]->wl.scale, maxScale); + for (size_t i = 0; i < window->wl.outputScaleCount; i++) + maxScale = _glfw_max(window->wl.outputScales[i].factor, maxScale); // Only change the framebuffer size if the scale changed. - if (window->wl.scale != maxScale) + if (window->wl.bufferScale != maxScale) { - window->wl.scale = maxScale; + window->wl.bufferScale = maxScale; wl_surface_set_buffer_scale(window->wl.surface, maxScale); _glfwInputWindowContentScale(window, maxScale, maxScale); - resizeWindow(window); + resizeFramebuffer(window); + + if (window->wl.visible) + _glfwInputWindowDamage(window); } } @@ -407,41 +426,50 @@ static void surfaceHandleEnter(void* userData, struct wl_surface* surface, struct wl_output* output) { + if (wl_proxy_get_tag((struct wl_proxy*) output) != &_glfw.wl.tag) + return; + _GLFWwindow* window = userData; _GLFWmonitor* monitor = wl_output_get_user_data(output); + if (!window || !monitor) + return; - if (window->wl.monitorsCount + 1 > window->wl.monitorsSize) + if (window->wl.outputScaleCount + 1 > window->wl.outputScaleSize) { - ++window->wl.monitorsSize; - window->wl.monitors = - realloc(window->wl.monitors, - window->wl.monitorsSize * sizeof(_GLFWmonitor*)); + window->wl.outputScaleSize++; + window->wl.outputScales = + _glfw_realloc(window->wl.outputScales, + window->wl.outputScaleSize * sizeof(_GLFWscaleWayland)); } - window->wl.monitors[window->wl.monitorsCount++] = monitor; + window->wl.outputScaleCount++; + window->wl.outputScales[window->wl.outputScaleCount - 1] = + (_GLFWscaleWayland) { output, monitor->wl.scale }; - _glfwUpdateContentScaleWayland(window); + _glfwUpdateBufferScaleFromOutputsWayland(window); } static void surfaceHandleLeave(void* userData, struct wl_surface* surface, struct wl_output* output) { + if (wl_proxy_get_tag((struct wl_proxy*) output) != &_glfw.wl.tag) + return; + _GLFWwindow* window = userData; - _GLFWmonitor* monitor = wl_output_get_user_data(output); - GLFWbool found; - int i; - for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i) + for (size_t i = 0; i < window->wl.outputScaleCount; i++) { - if (monitor == window->wl.monitors[i]) - found = GLFW_TRUE; - if (found) - window->wl.monitors[i] = window->wl.monitors[i + 1]; + if (window->wl.outputScales[i].output == output) + { + window->wl.outputScales[i] = + window->wl.outputScales[window->wl.outputScaleCount - 1]; + window->wl.outputScaleCount--; + break; + } } - window->wl.monitors[--window->wl.monitorsCount] = NULL; - _glfwUpdateContentScaleWayland(window); + _glfwUpdateBufferScaleFromOutputsWayland(window); } static const struct wl_surface_listener surfaceListener = @@ -472,7 +500,12 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable) // static void acquireMonitor(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + { + libdecor_frame_set_fullscreen(window->wl.libdecor.frame, + window->monitor->wl.output); + } + else if (window->wl.xdg.toplevel) { xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel, window->monitor->wl.output); @@ -480,7 +513,7 @@ static void acquireMonitor(_GLFWwindow* window) setIdleInhibitor(window, GLFW_TRUE); - if (window->wl.decorations.top.surface) + if (window->wl.fallback.decorations) destroyFallbackDecorations(window); } @@ -488,18 +521,40 @@ static void acquireMonitor(_GLFWwindow* window) // static void releaseMonitor(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_unset_fullscreen(window->wl.libdecor.frame); + else if (window->wl.xdg.toplevel) xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel); setIdleInhibitor(window, GLFW_FALSE); - if (window->wl.xdg.decorationMode != ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) + if (!window->wl.libdecor.frame && + window->wl.xdg.decorationMode != ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) { if (window->decorated) createFallbackDecorations(window); } } +void fractionalScaleHandlePreferredScale(void* userData, + struct wp_fractional_scale_v1* fractionalScale, + uint32_t numerator) +{ + _GLFWwindow* window = userData; + + window->wl.scalingNumerator = numerator; + _glfwInputWindowContentScale(window, numerator / 120.f, numerator / 120.f); + resizeFramebuffer(window); + + if (window->wl.visible) + _glfwInputWindowDamage(window); +} + +const struct wp_fractional_scale_v1_listener fractionalScaleListener = +{ + fractionalScaleHandlePreferredScale, +}; + static void xdgToplevelHandleConfigure(void* userData, struct xdg_toplevel* toplevel, int32_t width, @@ -533,7 +588,7 @@ static void xdgToplevelHandleConfigure(void* userData, if (width && height) { - if (window->wl.decorations.top.surface) + if (window->wl.fallback.decorations) { window->wl.pending.width = _glfw_max(0, width - GLFW_BORDER_SIZE * 2); window->wl.pending.height = @@ -607,13 +662,9 @@ static void xdgSurfaceHandleConfigure(void* userData, } } - if (width != window->wl.width || height != window->wl.height) + if (resizeWindow(window, width, height)) { - window->wl.width = width; - window->wl.height = height; - resizeWindow(window); - - _glfwInputWindowSize(window, width, height); + _glfwInputWindowSize(window, window->wl.width, window->wl.height); if (window->wl.visible) _glfwInputWindowDamage(window); @@ -636,7 +687,232 @@ static const struct xdg_surface_listener xdgSurfaceListener = xdgSurfaceHandleConfigure }; -static GLFWbool createShellObjects(_GLFWwindow* window) +void libdecorFrameHandleConfigure(struct libdecor_frame* frame, + struct libdecor_configuration* config, + void* userData) +{ + _GLFWwindow* window = userData; + int width, height; + + enum libdecor_window_state windowState; + GLFWbool fullscreen, activated, maximized; + + if (libdecor_configuration_get_window_state(config, &windowState)) + { + fullscreen = (windowState & LIBDECOR_WINDOW_STATE_FULLSCREEN) != 0; + activated = (windowState & LIBDECOR_WINDOW_STATE_ACTIVE) != 0; + maximized = (windowState & LIBDECOR_WINDOW_STATE_MAXIMIZED) != 0; + } + else + { + fullscreen = window->wl.fullscreen; + activated = window->wl.activated; + maximized = window->wl.maximized; + } + + if (!libdecor_configuration_get_content_size(config, frame, &width, &height)) + { + width = window->wl.width; + height = window->wl.height; + } + + if (!maximized && !fullscreen) + { + if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE) + { + const float aspectRatio = (float) width / (float) height; + const float targetRatio = (float) window->numer / (float) window->denom; + if (aspectRatio < targetRatio) + height = width / targetRatio; + else if (aspectRatio > targetRatio) + width = height * targetRatio; + } + } + + struct libdecor_state* frameState = libdecor_state_new(width, height); + libdecor_frame_commit(frame, frameState, config); + libdecor_state_free(frameState); + + if (window->wl.activated != activated) + { + window->wl.activated = activated; + if (!window->wl.activated) + { + if (window->monitor && window->autoIconify) + libdecor_frame_set_minimized(window->wl.libdecor.frame); + } + } + + if (window->wl.maximized != maximized) + { + window->wl.maximized = maximized; + _glfwInputWindowMaximize(window, window->wl.maximized); + } + + window->wl.fullscreen = fullscreen; + + GLFWbool damaged = GLFW_FALSE; + + if (!window->wl.visible) + { + window->wl.visible = GLFW_TRUE; + damaged = GLFW_TRUE; + } + + if (resizeWindow(window, width, height)) + { + _glfwInputWindowSize(window, window->wl.width, window->wl.height); + damaged = GLFW_TRUE; + } + + if (damaged) + _glfwInputWindowDamage(window); + else + wl_surface_commit(window->wl.surface); +} + +void libdecorFrameHandleClose(struct libdecor_frame* frame, void* userData) +{ + _GLFWwindow* window = userData; + _glfwInputWindowCloseRequest(window); +} + +void libdecorFrameHandleCommit(struct libdecor_frame* frame, void* userData) +{ + _GLFWwindow* window = userData; + wl_surface_commit(window->wl.surface); +} + +void libdecorFrameHandleDismissPopup(struct libdecor_frame* frame, + const char* seatName, + void* userData) +{ +} + +static const struct libdecor_frame_interface libdecorFrameInterface = +{ + libdecorFrameHandleConfigure, + libdecorFrameHandleClose, + libdecorFrameHandleCommit, + libdecorFrameHandleDismissPopup +}; + +static GLFWbool createLibdecorFrame(_GLFWwindow* window) +{ + // Allow libdecor to finish initialization of itself and its plugin + while (!_glfw.wl.libdecor.ready) + _glfwWaitEventsWayland(); + + window->wl.libdecor.frame = libdecor_decorate(_glfw.wl.libdecor.context, + window->wl.surface, + &libdecorFrameInterface, + window); + if (!window->wl.libdecor.frame) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to create libdecor frame"); + return GLFW_FALSE; + } + + struct libdecor_state* frameState = + libdecor_state_new(window->wl.width, window->wl.height); + libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL); + libdecor_state_free(frameState); + + if (strlen(window->wl.appId)) + libdecor_frame_set_app_id(window->wl.libdecor.frame, window->wl.appId); + + libdecor_frame_set_title(window->wl.libdecor.frame, window->title); + + if (window->minwidth != GLFW_DONT_CARE && + window->minheight != GLFW_DONT_CARE) + { + libdecor_frame_set_min_content_size(window->wl.libdecor.frame, + window->minwidth, + window->minheight); + } + + if (window->maxwidth != GLFW_DONT_CARE && + window->maxheight != GLFW_DONT_CARE) + { + libdecor_frame_set_max_content_size(window->wl.libdecor.frame, + window->maxwidth, + window->maxheight); + } + + if (!window->resizable) + { + libdecor_frame_unset_capabilities(window->wl.libdecor.frame, + LIBDECOR_ACTION_RESIZE); + } + + if (window->monitor) + { + libdecor_frame_set_fullscreen(window->wl.libdecor.frame, + window->monitor->wl.output); + setIdleInhibitor(window, GLFW_TRUE); + } + else + { + if (window->wl.maximized) + libdecor_frame_set_maximized(window->wl.libdecor.frame); + + if (!window->decorated) + libdecor_frame_set_visibility(window->wl.libdecor.frame, false); + + setIdleInhibitor(window, GLFW_FALSE); + } + + libdecor_frame_map(window->wl.libdecor.frame); + wl_display_roundtrip(_glfw.wl.display); + return GLFW_TRUE; +} + +static void updateXdgSizeLimits(_GLFWwindow* window) +{ + int minwidth, minheight, maxwidth, maxheight; + + if (window->resizable) + { + if (window->minwidth == GLFW_DONT_CARE || window->minheight == GLFW_DONT_CARE) + minwidth = minheight = 0; + else + { + minwidth = window->minwidth; + minheight = window->minheight; + + if (window->wl.fallback.decorations) + { + minwidth += GLFW_BORDER_SIZE * 2; + minheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; + } + } + + if (window->maxwidth == GLFW_DONT_CARE || window->maxheight == GLFW_DONT_CARE) + maxwidth = maxheight = 0; + else + { + maxwidth = window->maxwidth; + maxheight = window->maxheight; + + if (window->wl.fallback.decorations) + { + maxwidth += GLFW_BORDER_SIZE * 2; + maxheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; + } + } + } + else + { + minwidth = maxwidth = window->wl.width; + minheight = maxheight = window->wl.height; + } + + xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight); + xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight); +} + +static GLFWbool createXdgShellObjects(_GLFWwindow* window) { window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase, window->wl.surface); @@ -659,8 +935,10 @@ static GLFWbool createShellObjects(_GLFWwindow* window) xdg_toplevel_add_listener(window->wl.xdg.toplevel, &xdgToplevelListener, window); - if (window->wl.title) - xdg_toplevel_set_title(window->wl.xdg.toplevel, window->wl.title); + if (window->wl.appId) + xdg_toplevel_set_app_id(window->wl.xdg.toplevel, window->wl.appId); + + xdg_toplevel_set_title(window->wl.xdg.toplevel, window->title); if (window->monitor) { @@ -673,70 +951,57 @@ static GLFWbool createShellObjects(_GLFWwindow* window) xdg_toplevel_set_maximized(window->wl.xdg.toplevel); setIdleInhibitor(window, GLFW_FALSE); + } - if (_glfw.wl.decorationManager) - { - window->wl.xdg.decoration = - zxdg_decoration_manager_v1_get_toplevel_decoration( - _glfw.wl.decorationManager, window->wl.xdg.toplevel); - zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration, - &xdgDecorationListener, - window); + if (_glfw.wl.decorationManager) + { + window->wl.xdg.decoration = + zxdg_decoration_manager_v1_get_toplevel_decoration( + _glfw.wl.decorationManager, window->wl.xdg.toplevel); + zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration, + &xdgDecorationListener, + window); - uint32_t mode; + uint32_t mode; - if (window->decorated) - mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; - else - mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; - - zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode); - } + if (window->decorated) + mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; else - { - if (window->decorated) - createFallbackDecorations(window); - } - } + mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; - if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE) + zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode); + } + else { - int minwidth = window->minwidth; - int minheight = window->minheight; - - if (window->wl.decorations.top.surface) - { - minwidth += GLFW_BORDER_SIZE * 2; - minheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; - } - - xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight); + if (window->decorated && !window->monitor) + createFallbackDecorations(window); } - if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE) - { - int maxwidth = window->maxwidth; - int maxheight = window->maxheight; - - if (window->wl.decorations.top.surface) - { - maxwidth += GLFW_BORDER_SIZE * 2; - maxheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; - } - - xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight); - } + updateXdgSizeLimits(window); wl_surface_commit(window->wl.surface); wl_display_roundtrip(_glfw.wl.display); - return GLFW_TRUE; } +static GLFWbool createShellObjects(_GLFWwindow* window) +{ + if (_glfw.wl.libdecor.context) + { + if (createLibdecorFrame(window)) + return GLFW_TRUE; + } + + return createXdgShellObjects(window); +} + static void destroyShellObjects(_GLFWwindow* window) { destroyFallbackDecorations(window); + if (window->wl.libdecor.frame) + libdecor_frame_unref(window->wl.libdecor.frame); + if (window->wl.xdg.decoration) zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration); @@ -746,6 +1011,7 @@ static void destroyShellObjects(_GLFWwindow* window) if (window->wl.xdg.surface) xdg_surface_destroy(window->wl.xdg.surface); + window->wl.libdecor.frame = NULL; window->wl.xdg.decoration = NULL; window->wl.xdg.decorationMode = 0; window->wl.xdg.toplevel = NULL; @@ -763,16 +1029,20 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, return GLFW_FALSE; } + wl_proxy_set_tag((struct wl_proxy*) window->wl.surface, &_glfw.wl.tag); wl_surface_add_listener(window->wl.surface, &surfaceListener, window); - wl_surface_set_user_data(window->wl.surface, window); - window->wl.width = wndconfig->width; window->wl.height = wndconfig->height; - window->wl.scale = 1; - window->wl.title = _glfw_strdup(wndconfig->title); + window->wl.fbWidth = wndconfig->width; + window->wl.fbHeight = wndconfig->height; + window->wl.appId = _glfw_strdup(wndconfig->wl.appId); + + window->wl.bufferScale = 1; + window->wl.scalingNumerator = 120; + window->wl.scaleFramebuffer = wndconfig->scaleFramebuffer; window->wl.maximized = wndconfig->maximized; @@ -780,13 +1050,35 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, if (!window->wl.transparent) setContentAreaOpaque(window); + if (_glfw.wl.fractionalScaleManager) + { + if (window->wl.scaleFramebuffer) + { + window->wl.scalingViewport = + wp_viewporter_get_viewport(_glfw.wl.viewporter, window->wl.surface); + + wp_viewport_set_destination(window->wl.scalingViewport, + window->wl.width, + window->wl.height); + + window->wl.fractionalScale = + wp_fractional_scale_manager_v1_get_fractional_scale( + _glfw.wl.fractionalScaleManager, + window->wl.surface); + + wp_fractional_scale_v1_add_listener(window->wl.fractionalScale, + &fractionalScaleListener, + window); + } + } + return GLFW_TRUE; } static void setCursorImage(_GLFWwindow* window, _GLFWcursorWayland* cursorWayland) { - struct itimerspec timer = {}; + struct itimerspec timer = {0}; struct wl_cursor* wlCursor = cursorWayland->cursor; struct wl_cursor_image* image; struct wl_buffer* buffer; @@ -797,7 +1089,7 @@ static void setCursorImage(_GLFWwindow* window, buffer = cursorWayland->buffer; else { - if (window->wl.scale > 1 && cursorWayland->cursorHiDPI) + if (window->wl.bufferScale > 1 && cursorWayland->cursorHiDPI) { wlCursor = cursorWayland->cursorHiDPI; scale = 2; @@ -833,7 +1125,7 @@ static void incrementCursorImage(_GLFWwindow* window) { _GLFWcursor* cursor; - if (!window || window->wl.decorations.focus != mainWindow) + if (!window || !window->wl.hovered) return; cursor = window->wl.currentCursor; @@ -864,20 +1156,79 @@ static GLFWbool flushDisplay(void) return GLFW_TRUE; } +static int translateKey(uint32_t scancode) +{ + if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0])) + return _glfw.wl.keycodes[scancode]; + + return GLFW_KEY_UNKNOWN; +} + +static xkb_keysym_t composeSymbol(xkb_keysym_t sym) +{ + if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState) + return sym; + if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym) + != XKB_COMPOSE_FEED_ACCEPTED) + return sym; + switch (xkb_compose_state_get_status(_glfw.wl.xkb.composeState)) + { + case XKB_COMPOSE_COMPOSED: + return xkb_compose_state_get_one_sym(_glfw.wl.xkb.composeState); + case XKB_COMPOSE_COMPOSING: + case XKB_COMPOSE_CANCELLED: + return XKB_KEY_NoSymbol; + case XKB_COMPOSE_NOTHING: + default: + return sym; + } +} + +static void inputText(_GLFWwindow* window, uint32_t scancode) +{ + const xkb_keysym_t* keysyms; + const xkb_keycode_t keycode = scancode + 8; + + if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1) + { + const xkb_keysym_t keysym = composeSymbol(keysyms[0]); + const uint32_t codepoint = _glfwKeySym2Unicode(keysym); + if (codepoint != GLFW_INVALID_CODEPOINT) + { + const int mods = _glfw.wl.xkb.modifiers; + const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); + _glfwInputChar(window, codepoint, mods, plain); + } + } +} + static void handleEvents(double* timeout) { +#if defined(GLFW_BUILD_LINUX_JOYSTICK) + if (_glfw.joysticksInitialized) + _glfwDetectJoystickConnectionLinux(); +#endif + GLFWbool event = GLFW_FALSE; + enum { DISPLAY_FD, KEYREPEAT_FD, CURSOR_FD, LIBDECOR_FD }; struct pollfd fds[] = { - { wl_display_get_fd(_glfw.wl.display), POLLIN }, - { _glfw.wl.timerfd, POLLIN }, - { _glfw.wl.cursorTimerfd, POLLIN }, + [DISPLAY_FD] = { wl_display_get_fd(_glfw.wl.display), POLLIN }, + [KEYREPEAT_FD] = { _glfw.wl.keyRepeatTimerfd, POLLIN }, + [CURSOR_FD] = { _glfw.wl.cursorTimerfd, POLLIN }, + [LIBDECOR_FD] = { -1, POLLIN } }; + if (_glfw.wl.libdecor.context) + fds[LIBDECOR_FD].fd = libdecor_get_fd(_glfw.wl.libdecor.context); + while (!event) { while (wl_display_prepare_read(_glfw.wl.display) != 0) - wl_display_dispatch_pending(_glfw.wl.display); + { + if (wl_display_dispatch_pending(_glfw.wl.display) > 0) + return; + } // If an error other than EAGAIN happens, we have likely been disconnected // from the Wayland session; try to handle that the best we can. @@ -895,13 +1246,13 @@ static void handleEvents(double* timeout) return; } - if (!waitForData(fds, 3, timeout)) + if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout)) { wl_display_cancel_read(_glfw.wl.display); return; } - if (fds[0].revents & POLLIN) + if (fds[DISPLAY_FD].revents & POLLIN) { wl_display_read_events(_glfw.wl.display); if (wl_display_dispatch_pending(_glfw.wl.display) > 0) @@ -910,36 +1261,38 @@ static void handleEvents(double* timeout) else wl_display_cancel_read(_glfw.wl.display); - if (fds[1].revents & POLLIN) + if (fds[KEYREPEAT_FD].revents & POLLIN) { uint64_t repeats; - if (read(_glfw.wl.timerfd, &repeats, sizeof(repeats)) == 8) + if (read(_glfw.wl.keyRepeatTimerfd, &repeats, sizeof(repeats)) == 8) { for (uint64_t i = 0; i < repeats; i++) { _glfwInputKey(_glfw.wl.keyboardFocus, - _glfw.wl.keyboardLastKey, - _glfw.wl.keyboardLastScancode, + translateKey(_glfw.wl.keyRepeatScancode), + _glfw.wl.keyRepeatScancode, GLFW_PRESS, _glfw.wl.xkb.modifiers); - _glfwInputTextWayland(_glfw.wl.keyboardFocus, - _glfw.wl.keyboardLastScancode); + inputText(_glfw.wl.keyboardFocus, _glfw.wl.keyRepeatScancode); } event = GLFW_TRUE; } } - if (fds[2].revents & POLLIN) + if (fds[CURSOR_FD].revents & POLLIN) { uint64_t repeats; if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8) - { incrementCursorImage(_glfw.wl.pointerFocus); + } + + if (fds[LIBDECOR_FD].revents & POLLIN) + { + if (libdecor_dispatch(_glfw.wl.libdecor.context, 0) > 0) event = GLFW_TRUE; - } } } } @@ -972,7 +1325,7 @@ static char* readDataOfferAsString(struct wl_data_offer* offer, const char* mime const size_t requiredSize = length + readSize + 1; if (requiredSize > size) { - char* longer = realloc(string, requiredSize); + char* longer = _glfw_realloc(string, requiredSize); if (!longer) { _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); @@ -1008,40 +1361,6 @@ static char* readDataOfferAsString(struct wl_data_offer* offer, const char* mime return string; } -static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, - _GLFWdecorationSideWayland* which) -{ - _GLFWdecorationSideWayland focus; - _GLFWwindow* window = _glfw.windowListHead; - if (!which) - which = &focus; - while (window) - { - if (surface == window->wl.decorations.top.surface) - { - *which = topDecoration; - break; - } - if (surface == window->wl.decorations.left.surface) - { - *which = leftDecoration; - break; - } - if (surface == window->wl.decorations.right.surface) - { - *which = rightDecoration; - break; - } - if (surface == window->wl.decorations.bottom.surface) - { - *which = bottomDecoration; - break; - } - window = window->next; - } - return window; -} - static void pointerHandleEnter(void* userData, struct wl_pointer* pointer, uint32_t serial, @@ -1053,24 +1372,26 @@ static void pointerHandleEnter(void* userData, if (!surface) return; - _GLFWdecorationSideWayland focus = mainWindow; - _GLFWwindow* window = wl_surface_get_user_data(surface); - if (!window) - { - window = findWindowFromDecorationSurface(surface, &focus); - if (!window) - return; - } + if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) + return; + + _GLFWwindow* window = wl_surface_get_user_data(surface); - window->wl.decorations.focus = focus; _glfw.wl.serial = serial; _glfw.wl.pointerEnterSerial = serial; _glfw.wl.pointerFocus = window; - window->wl.hovered = GLFW_TRUE; - - _glfwPlatformSetCursor(window, window->wl.currentCursor); - _glfwInputCursorEnter(window, GLFW_TRUE); + if (surface == window->wl.surface) + { + window->wl.hovered = GLFW_TRUE; + _glfwSetCursorWayland(window, window->wl.currentCursor); + _glfwInputCursorEnter(window, GLFW_TRUE); + } + else + { + if (window->wl.fallback.decorations) + window->wl.fallback.focus = surface; + } } static void pointerHandleLeave(void* userData, @@ -1078,62 +1399,30 @@ static void pointerHandleLeave(void* userData, uint32_t serial, struct wl_surface* surface) { - _GLFWwindow* window = _glfw.wl.pointerFocus; + if (!surface) + return; + if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) + return; + + _GLFWwindow* window = _glfw.wl.pointerFocus; if (!window) return; - window->wl.hovered = GLFW_FALSE; - _glfw.wl.serial = serial; _glfw.wl.pointerFocus = NULL; - _glfwInputCursorEnter(window, GLFW_FALSE); _glfw.wl.cursorPreviousName = NULL; -} -static void setCursor(_GLFWwindow* window, const char* name) -{ - struct wl_buffer* buffer; - struct wl_cursor* cursor; - struct wl_cursor_image* image; - struct wl_surface* surface = _glfw.wl.cursorSurface; - struct wl_cursor_theme* theme = _glfw.wl.cursorTheme; - int scale = 1; - - if (window->wl.scale > 1 && _glfw.wl.cursorThemeHiDPI) + if (window->wl.hovered) { - // We only support up to scale=2 for now, since libwayland-cursor - // requires us to load a different theme for each size. - scale = 2; - theme = _glfw.wl.cursorThemeHiDPI; + window->wl.hovered = GLFW_FALSE; + _glfwInputCursorEnter(window, GLFW_FALSE); } - - cursor = wl_cursor_theme_get_cursor(theme, name); - if (!cursor) + else { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Standard cursor shape unavailable"); - return; + if (window->wl.fallback.decorations) + window->wl.fallback.focus = NULL; } - // TODO: handle animated cursors too. - image = cursor->images[0]; - - if (!image) - return; - - buffer = wl_cursor_image_get_buffer(image); - if (!buffer) - return; - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, - surface, - image->hotspot_x / scale, - image->hotspot_y / scale); - wl_surface_set_buffer_scale(surface, scale); - wl_surface_attach(surface, buffer, 0, 0); - wl_surface_damage(surface, 0, 0, - image->width, image->height); - wl_surface_commit(surface); - _glfw.wl.cursorPreviousName = name; } static void pointerHandleMotion(void* userData, @@ -1143,56 +1432,99 @@ static void pointerHandleMotion(void* userData, wl_fixed_t sy) { _GLFWwindow* window = _glfw.wl.pointerFocus; - const char* cursorName = NULL; - double x, y; - if (!window) return; if (window->cursorMode == GLFW_CURSOR_DISABLED) return; - x = wl_fixed_to_double(sx); - y = wl_fixed_to_double(sy); - window->wl.cursorPosX = x; - window->wl.cursorPosY = y; - switch (window->wl.decorations.focus) + const double xpos = wl_fixed_to_double(sx); + const double ypos = wl_fixed_to_double(sy); + window->wl.cursorPosX = xpos; + window->wl.cursorPosY = ypos; + + if (window->wl.hovered) { - case mainWindow: - _glfwInputCursorPos(window, x, y); - _glfw.wl.cursorPreviousName = NULL; - return; - case topDecoration: - if (y < GLFW_BORDER_SIZE) - cursorName = "n-resize"; - else - cursorName = "left_ptr"; - break; - case leftDecoration: - if (y < GLFW_BORDER_SIZE) - cursorName = "nw-resize"; - else - cursorName = "w-resize"; - break; - case rightDecoration: - if (y < GLFW_BORDER_SIZE) - cursorName = "ne-resize"; - else - cursorName = "e-resize"; - break; - case bottomDecoration: - if (x < GLFW_BORDER_SIZE) - cursorName = "sw-resize"; - else if (x > window->wl.width + GLFW_BORDER_SIZE) - cursorName = "se-resize"; - else - cursorName = "s-resize"; - break; - default: - assert(0); + _glfw.wl.cursorPreviousName = NULL; + _glfwInputCursorPos(window, xpos, ypos); + return; + } + + if (window->wl.fallback.decorations) + { + const char* cursorName = "left_ptr"; + + if (window->resizable) + { + if (window->wl.fallback.focus == window->wl.fallback.top.surface) + { + if (ypos < GLFW_BORDER_SIZE) + cursorName = "n-resize"; + } + else if (window->wl.fallback.focus == window->wl.fallback.left.surface) + { + if (ypos < GLFW_BORDER_SIZE) + cursorName = "nw-resize"; + else + cursorName = "w-resize"; + } + else if (window->wl.fallback.focus == window->wl.fallback.right.surface) + { + if (ypos < GLFW_BORDER_SIZE) + cursorName = "ne-resize"; + else + cursorName = "e-resize"; + } + else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface) + { + if (xpos < GLFW_BORDER_SIZE) + cursorName = "sw-resize"; + else if (xpos > window->wl.width + GLFW_BORDER_SIZE) + cursorName = "se-resize"; + else + cursorName = "s-resize"; + } + } + + if (_glfw.wl.cursorPreviousName != cursorName) + { + struct wl_surface* surface = _glfw.wl.cursorSurface; + struct wl_cursor_theme* theme = _glfw.wl.cursorTheme; + int scale = 1; + + if (window->wl.bufferScale > 1 && _glfw.wl.cursorThemeHiDPI) + { + // We only support up to scale=2 for now, since libwayland-cursor + // requires us to load a different theme for each size. + scale = 2; + theme = _glfw.wl.cursorThemeHiDPI; + } + + struct wl_cursor* cursor = wl_cursor_theme_get_cursor(theme, cursorName); + if (!cursor) + return; + + // TODO: handle animated cursors too. + struct wl_cursor_image* image = cursor->images[0]; + if (!image) + return; + + struct wl_buffer* buffer = wl_cursor_image_get_buffer(image); + if (!buffer) + return; + + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, + surface, + image->hotspot_x / scale, + image->hotspot_y / scale); + wl_surface_set_buffer_scale(surface, scale); + wl_surface_attach(surface, buffer, 0, 0); + wl_surface_damage(surface, 0, 0, image->width, image->height); + wl_surface_commit(surface); + + _glfw.wl.cursorPreviousName = cursorName; + } } - if (_glfw.wl.cursorPreviousName != cursorName) - setCursor(window, cursorName); } static void pointerHandleButton(void* userData, @@ -1203,84 +1535,74 @@ static void pointerHandleButton(void* userData, uint32_t state) { _GLFWwindow* window = _glfw.wl.pointerFocus; - int glfwButton; - - uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE; - if (!window) return; - if (button == BTN_LEFT) + + if (window->wl.hovered) { - switch (window->wl.decorations.focus) + _glfw.wl.serial = serial; + + _glfwInputMouseClick(window, + button - BTN_LEFT, + state == WL_POINTER_BUTTON_STATE_PRESSED, + _glfw.wl.xkb.modifiers); + return; + } + + if (window->wl.fallback.decorations) + { + if (button == BTN_LEFT) { - case mainWindow: - break; - case topDecoration: + uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE; + + if (window->wl.fallback.focus == window->wl.fallback.top.surface) + { if (window->wl.cursorPosY < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP; else - { xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial); - } - break; - case leftDecoration: + } + else if (window->wl.fallback.focus == window->wl.fallback.left.surface) + { if (window->wl.cursorPosY < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT; else edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT; - break; - case rightDecoration: + } + else if (window->wl.fallback.focus == window->wl.fallback.right.surface) + { if (window->wl.cursorPosY < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT; else edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT; - break; - case bottomDecoration: + } + else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface) + { if (window->wl.cursorPosX < GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT; else if (window->wl.cursorPosX > window->wl.width + GLFW_BORDER_SIZE) edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT; else edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM; - break; - default: - assert(0); + } + + if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE) + { + xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat, + serial, edges); + } } - if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE) + else if (button == BTN_RIGHT) { - xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat, - serial, edges); - return; + if (window->wl.xdg.toplevel) + { + xdg_toplevel_show_window_menu(window->wl.xdg.toplevel, + _glfw.wl.seat, serial, + window->wl.cursorPosX, + window->wl.cursorPosY); + } } } - else if (button == BTN_RIGHT) - { - if (window->wl.decorations.focus != mainWindow && window->wl.xdg.toplevel) - { - xdg_toplevel_show_window_menu(window->wl.xdg.toplevel, - _glfw.wl.seat, serial, - window->wl.cursorPosX, - window->wl.cursorPosY); - return; - } - } - - // Don’t pass the button to the user if it was related to a decoration. - if (window->wl.decorations.focus != mainWindow) - return; - - _glfw.wl.serial = serial; - - /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev - * codes. */ - glfwButton = button - BTN_LEFT; - - _glfwInputMouseClick(window, - glfwButton, - state == WL_POINTER_BUTTON_STATE_PRESSED - ? GLFW_PRESS - : GLFW_RELEASE, - _glfw.wl.xkb.modifiers); } static void pointerHandleAxis(void* userData, @@ -1290,24 +1612,14 @@ static void pointerHandleAxis(void* userData, wl_fixed_t value) { _GLFWwindow* window = _glfw.wl.pointerFocus; - double x = 0.0, y = 0.0; - // Wayland scroll events are in pointer motion coordinate space (think two - // finger scroll). The factor 10 is commonly used to convert to "scroll - // step means 1.0. - const double scrollFactor = 1.0 / 10.0; - if (!window) return; - assert(axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL || - axis == WL_POINTER_AXIS_VERTICAL_SCROLL); - + // NOTE: 10 units of motion per mouse wheel step seems to be a common ratio if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) - x = -wl_fixed_to_double(value) * scrollFactor; + _glfwInputScroll(window, -wl_fixed_to_double(value) / 10.0, 0.0); else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) - y = -wl_fixed_to_double(value) * scrollFactor; - - _glfwInputScroll(window, x, y); + _glfwInputScroll(window, 0.0, -wl_fixed_to_double(value) / 10.0); } static const struct wl_pointer_listener pointerListener = @@ -1329,6 +1641,7 @@ static void keyboardHandleKeymap(void* userData, struct xkb_state* state; struct xkb_compose_table* composeTable; struct xkb_compose_state* composeState; + char* mapStr; const char* locale; @@ -1419,13 +1732,12 @@ static void keyboardHandleEnter(void* userData, if (!surface) return; + if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) + return; + _GLFWwindow* window = wl_surface_get_user_data(surface); - if (!window) - { - window = findWindowFromDecorationSurface(surface, NULL); - if (!window) - return; - } + if (surface != window->wl.surface) + return; _glfw.wl.serial = serial; _glfw.wl.keyboardFocus = window; @@ -1442,62 +1754,14 @@ static void keyboardHandleLeave(void* userData, if (!window) return; - struct itimerspec timer = {}; - timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); + struct itimerspec timer = {0}; + timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL); _glfw.wl.serial = serial; _glfw.wl.keyboardFocus = NULL; _glfwInputWindowFocus(window, GLFW_FALSE); } -static int translateKey(uint32_t scancode) -{ - if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0])) - return _glfw.wl.keycodes[scancode]; - - return GLFW_KEY_UNKNOWN; -} - -static xkb_keysym_t composeSymbol(xkb_keysym_t sym) -{ - if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState) - return sym; - if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym) - != XKB_COMPOSE_FEED_ACCEPTED) - return sym; - switch (xkb_compose_state_get_status(_glfw.wl.xkb.composeState)) - { - case XKB_COMPOSE_COMPOSED: - return xkb_compose_state_get_one_sym(_glfw.wl.xkb.composeState); - case XKB_COMPOSE_COMPOSING: - case XKB_COMPOSE_CANCELLED: - return XKB_KEY_NoSymbol; - case XKB_COMPOSE_NOTHING: - default: - return sym; - } -} - -GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode) -{ - const xkb_keysym_t* keysyms; - const xkb_keycode_t keycode = scancode + 8; - - if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1) - { - const xkb_keysym_t keysym = composeSymbol(keysyms[0]); - const uint32_t codepoint = _glfwKeySym2Unicode(keysym); - if (codepoint != GLFW_INVALID_CODEPOINT) - { - const int mods = _glfw.wl.xkb.modifiers; - const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); - _glfwInputChar(window, codepoint, mods, plain); - } - } - - return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode); -} - static void keyboardHandleKey(void* userData, struct wl_keyboard* keyboard, uint32_t serial, @@ -1514,29 +1778,33 @@ static void keyboardHandleKey(void* userData, state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE; _glfw.wl.serial = serial; - _glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers); - struct itimerspec timer = {}; + struct itimerspec timer = {0}; if (action == GLFW_PRESS) { - const GLFWbool shouldRepeat = _glfwInputTextWayland(window, scancode); + const xkb_keycode_t keycode = scancode + 8; - if (shouldRepeat && _glfw.wl.keyboardRepeatRate > 0) + if (xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode) && + _glfw.wl.keyRepeatRate > 0) { - _glfw.wl.keyboardLastKey = key; - _glfw.wl.keyboardLastScancode = scancode; - if (_glfw.wl.keyboardRepeatRate > 1) - timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyboardRepeatRate; + _glfw.wl.keyRepeatScancode = scancode; + if (_glfw.wl.keyRepeatRate > 1) + timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyRepeatRate; else timer.it_interval.tv_sec = 1; - timer.it_value.tv_sec = _glfw.wl.keyboardRepeatDelay / 1000; - timer.it_value.tv_nsec = (_glfw.wl.keyboardRepeatDelay % 1000) * 1000000; + timer.it_value.tv_sec = _glfw.wl.keyRepeatDelay / 1000; + timer.it_value.tv_nsec = (_glfw.wl.keyRepeatDelay % 1000) * 1000000; } } - timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); + timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL); + + _glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers); + + if (action == GLFW_PRESS) + inputText(window, scancode); } static void keyboardHandleModifiers(void* userData, @@ -1587,7 +1855,6 @@ static void keyboardHandleModifiers(void* userData, } } -#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION static void keyboardHandleRepeatInfo(void* userData, struct wl_keyboard* keyboard, int32_t rate, @@ -1596,10 +1863,9 @@ static void keyboardHandleRepeatInfo(void* userData, if (keyboard != _glfw.wl.keyboard) return; - _glfw.wl.keyboardRepeatRate = rate; - _glfw.wl.keyboardRepeatDelay = delay; + _glfw.wl.keyRepeatRate = rate; + _glfw.wl.keyRepeatDelay = delay; } -#endif static const struct wl_keyboard_listener keyboardListener = { @@ -1608,9 +1874,7 @@ static const struct wl_keyboard_listener keyboardListener = keyboardHandleLeave, keyboardHandleKey, keyboardHandleModifiers, -#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION keyboardHandleRepeatInfo, -#endif }; static void seatHandleCapabilities(void* userData, @@ -1680,7 +1944,8 @@ static void dataDeviceHandleDataOffer(void* userData, struct wl_data_offer* offer) { _GLFWofferWayland* offers = - realloc(_glfw.wl.offers, _glfw.wl.offerCount + 1); + _glfw_realloc(_glfw.wl.offers, + sizeof(_GLFWofferWayland) * (_glfw.wl.offerCount + 1)); if (!offers) { _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); @@ -1716,9 +1981,12 @@ static void dataDeviceHandleEnter(void* userData, _GLFWwindow* window = NULL; if (surface) - window = wl_surface_get_user_data(surface); + { + if (wl_proxy_get_tag((struct wl_proxy*) surface) == &_glfw.wl.tag) + window = wl_surface_get_user_data(surface); + } - if (window && _glfw.wl.offers[i].text_uri_list) + if (surface == window->wl.surface && _glfw.wl.offers[i].text_uri_list) { _glfw.wl.dragOffer = offer; _glfw.wl.dragFocus = window; @@ -1731,6 +1999,9 @@ static void dataDeviceHandleEnter(void* userData, } } + if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) + return; + if (_glfw.wl.dragOffer) wl_data_offer_accept(offer, serial, "text/uri-list"); else @@ -1774,12 +2045,12 @@ static void dataDeviceHandleDrop(void* userData, _glfwInputDrop(_glfw.wl.dragFocus, count, (const char**) paths); for (int i = 0; i < count; i++) - free(paths[i]); + _glfw_free(paths[i]); - free(paths); + _glfw_free(paths); } - free(string); + _glfw_free(string); } static void dataDeviceHandleSelection(void* userData, @@ -1818,28 +2089,25 @@ const struct wl_data_device_listener dataDeviceListener = dataDeviceHandleSelection, }; -// Translates a GLFW standard cursor to a theme cursor name -// -static char *translateCursorShape(int shape) +static void xdgActivationHandleDone(void* userData, + struct xdg_activation_token_v1* activationToken, + const char* token) { - switch (shape) - { - case GLFW_ARROW_CURSOR: - return "left_ptr"; - case GLFW_IBEAM_CURSOR: - return "xterm"; - case GLFW_CROSSHAIR_CURSOR: - return "crosshair"; - case GLFW_HAND_CURSOR: - return "hand2"; - case GLFW_HRESIZE_CURSOR: - return "sb_h_double_arrow"; - case GLFW_VRESIZE_CURSOR: - return "sb_v_double_arrow"; - } - return NULL; + _GLFWwindow* window = userData; + + if (activationToken != window->wl.activationToken) + return; + + xdg_activation_v1_activate(_glfw.wl.activationManager, token, window->wl.surface); + xdg_activation_token_v1_destroy(window->wl.activationToken); + window->wl.activationToken = NULL; } +static const struct xdg_activation_token_v1_listener xdgActivationListener = +{ + xdgActivationHandleDone +}; + void _glfwAddSeatListenerWayland(struct wl_seat* seat) { wl_seat_add_listener(seat, &seatListener, NULL); @@ -1855,10 +2123,10 @@ void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device) ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -int _glfwPlatformCreateWindow(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) +GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) { if (!createNativeSurface(window, wndconfig, fbconfig)) return GLFW_FALSE; @@ -1869,8 +2137,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, ctxconfig->source == GLFW_NATIVE_CONTEXT_API) { window->wl.egl.window = wl_egl_window_create(window->wl.surface, - wndconfig->width, - wndconfig->height); + window->wl.fbWidth, + window->wl.fbHeight); if (!window->wl.egl.window) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -1895,6 +2163,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, return GLFW_FALSE; } + if (wndconfig->mousePassthrough) + _glfwSetWindowMousePassthroughWayland(window, GLFW_TRUE); + if (window->monitor || wndconfig->visible) { if (!createShellObjects(window)) @@ -1904,29 +2175,36 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, return GLFW_TRUE; } -void _glfwPlatformDestroyWindow(_GLFWwindow* window) +void _glfwDestroyWindowWayland(_GLFWwindow* window) { if (window == _glfw.wl.pointerFocus) - { _glfw.wl.pointerFocus = NULL; - _glfwInputCursorEnter(window, GLFW_FALSE); - } + if (window == _glfw.wl.keyboardFocus) - { _glfw.wl.keyboardFocus = NULL; - _glfwInputWindowFocus(window, GLFW_FALSE); - } + + if (window->wl.activationToken) + xdg_activation_token_v1_destroy(window->wl.activationToken); if (window->wl.idleInhibitor) zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor); + if (window->wl.relativePointer) + zwp_relative_pointer_v1_destroy(window->wl.relativePointer); + + if (window->wl.lockedPointer) + zwp_locked_pointer_v1_destroy(window->wl.lockedPointer); + + if (window->wl.confinedPointer) + zwp_confined_pointer_v1_destroy(window->wl.confinedPointer); + if (window->context.destroy) window->context.destroy(window); destroyShellObjects(window); - if (window->wl.decorations.buffer) - wl_buffer_destroy(window->wl.decorations.buffer); + if (window->wl.fallback.buffer) + wl_buffer_destroy(window->wl.fallback.buffer); if (window->wl.egl.window) wl_egl_window_destroy(window->wl.egl.window); @@ -1934,44 +2212,43 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) if (window->wl.surface) wl_surface_destroy(window->wl.surface); - free(window->wl.title); - free(window->wl.monitors); + _glfw_free(window->wl.appId); + _glfw_free(window->wl.outputScales); } -void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) +void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title) { - if (window->wl.title) - free(window->wl.title); - window->wl.title = _glfw_strdup(title); - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_set_title(window->wl.libdecor.frame, title); + else if (window->wl.xdg.toplevel) xdg_toplevel_set_title(window->wl.xdg.toplevel, title); } -void _glfwPlatformSetWindowIcon(_GLFWwindow* window, - int count, const GLFWimage* images) +void _glfwSetWindowIconWayland(_GLFWwindow* window, + int count, const GLFWimage* images) { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Setting window icon not supported"); + _glfwInputError(GLFW_FEATURE_UNAVAILABLE, + "Wayland: The platform does not support setting the window icon"); } -void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) +void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos) { // A Wayland client is not aware of its position, so just warn and leave it // as (0, 0) - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Window position retrieval not supported"); + _glfwInputError(GLFW_FEATURE_UNAVAILABLE, + "Wayland: The platform does not provide the window position"); } -void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) +void _glfwSetWindowPosWayland(_GLFWwindow* window, int xpos, int ypos) { // A Wayland client can not set its position, so just warn - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Window position setting not supported"); + _glfwInputError(GLFW_FEATURE_UNAVAILABLE, + "Wayland: The platform does not support setting the window position"); } -void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) +void _glfwGetWindowSizeWayland(_GLFWwindow* window, int* width, int* height) { if (width) *width = window->wl.width; @@ -1979,7 +2256,7 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) *height = window->wl.height; } -void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) +void _glfwSetWindowSizeWayland(_GLFWwindow* window, int width, int height) { if (window->monitor) { @@ -1987,80 +2264,90 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) } else { - window->wl.width = width; - window->wl.height = height; - resizeWindow(window); + if (!resizeWindow(window, width, height)) + return; + + if (window->wl.libdecor.frame) + { + struct libdecor_state* frameState = + libdecor_state_new(window->wl.width, window->wl.height); + libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL); + libdecor_state_free(frameState); + } + + if (window->wl.visible) + _glfwInputWindowDamage(window); } } -void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, - int minwidth, int minheight, - int maxwidth, int maxheight) +void _glfwSetWindowSizeLimitsWayland(_GLFWwindow* window, + int minwidth, int minheight, + int maxwidth, int maxheight) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) { if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) minwidth = minheight = 0; - else - { - if (window->wl.decorations.top.surface) - { - minwidth += GLFW_BORDER_SIZE * 2; - minheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; - } - } if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE) maxwidth = maxheight = 0; - else - { - if (window->wl.decorations.top.surface) - { - maxwidth += GLFW_BORDER_SIZE * 2; - maxheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE; - } - } - xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight); - xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight); - wl_surface_commit(window->wl.surface); + libdecor_frame_set_min_content_size(window->wl.libdecor.frame, + minwidth, minheight); + libdecor_frame_set_max_content_size(window->wl.libdecor.frame, + maxwidth, maxheight); } + else if (window->wl.xdg.toplevel) + updateXdgSizeLimits(window); } -void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, - int numer, int denom) +void _glfwSetWindowAspectRatioWayland(_GLFWwindow* window, int numer, int denom) { if (window->wl.maximized || window->wl.fullscreen) return; + int width = window->wl.width, height = window->wl.height; + if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE) { - const float aspectRatio = (float) window->wl.width / (float) window->wl.height; + const float aspectRatio = (float) width / (float) height; const float targetRatio = (float) numer / (float) denom; if (aspectRatio < targetRatio) - window->wl.height = window->wl.width / targetRatio; + height /= targetRatio; else if (aspectRatio > targetRatio) - window->wl.width = window->wl.height * targetRatio; + width *= targetRatio; + } - resizeWindow(window); + if (resizeWindow(window, width, height)) + { + if (window->wl.libdecor.frame) + { + struct libdecor_state* frameState = + libdecor_state_new(window->wl.width, window->wl.height); + libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL); + libdecor_state_free(frameState); + } + + _glfwInputWindowSize(window, window->wl.width, window->wl.height); + + if (window->wl.visible) + _glfwInputWindowDamage(window); } } -void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, - int* width, int* height) +void _glfwGetFramebufferSizeWayland(_GLFWwindow* window, int* width, int* height) { - _glfwPlatformGetWindowSize(window, width, height); if (width) - *width *= window->wl.scale; + *width = window->wl.fbWidth; if (height) - *height *= window->wl.scale; + *height = window->wl.fbHeight; } -void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, - int* left, int* top, - int* right, int* bottom) +void _glfwGetWindowFrameSizeWayland(_GLFWwindow* window, + int* left, int* top, + int* right, int* bottom) { - if (window->decorated && !window->monitor && window->wl.decorations.top.surface) + if (window->wl.fallback.decorations) { if (top) *top = GLFW_CAPTION_HEIGHT; @@ -2073,27 +2360,39 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, } } -void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, - float* xscale, float* yscale) +void _glfwGetWindowContentScaleWayland(_GLFWwindow* window, + float* xscale, float* yscale) { - if (xscale) - *xscale = (float) window->wl.scale; - if (yscale) - *yscale = (float) window->wl.scale; + if (window->wl.fractionalScale) + { + if (xscale) + *xscale = (float) window->wl.scalingNumerator / 120.f; + if (yscale) + *yscale = (float) window->wl.scalingNumerator / 120.f; + } + else + { + if (xscale) + *xscale = (float) window->wl.bufferScale; + if (yscale) + *yscale = (float) window->wl.bufferScale; + } } -void _glfwPlatformIconifyWindow(_GLFWwindow* window) +void _glfwIconifyWindowWayland(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_set_minimized(window->wl.libdecor.frame); + else if (window->wl.xdg.toplevel) xdg_toplevel_set_minimized(window->wl.xdg.toplevel); } -void _glfwPlatformRestoreWindow(_GLFWwindow* window) +void _glfwRestoreWindowWayland(_GLFWwindow* window) { if (window->monitor) { // There is no way to unset minimized, or even to know if we are - // minimized, so there is nothing to do here. + // minimized, so there is nothing to do in this case. } else { @@ -2101,7 +2400,9 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) if (window->wl.maximized) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_unset_maximized(window->wl.libdecor.frame); + else if (window->wl.xdg.toplevel) xdg_toplevel_unset_maximized(window->wl.xdg.toplevel); else window->wl.maximized = GLFW_FALSE; @@ -2109,25 +2410,27 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) } } -void _glfwPlatformMaximizeWindow(_GLFWwindow* window) +void _glfwMaximizeWindowWayland(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->wl.libdecor.frame) + libdecor_frame_set_maximized(window->wl.libdecor.frame); + else if (window->wl.xdg.toplevel) xdg_toplevel_set_maximized(window->wl.xdg.toplevel); else window->wl.maximized = GLFW_TRUE; } -void _glfwPlatformShowWindow(_GLFWwindow* window) +void _glfwShowWindowWayland(_GLFWwindow* window) { - if (!window->wl.xdg.toplevel) + if (!window->wl.libdecor.frame && !window->wl.xdg.toplevel) { - // NOTE: The XDG/shell surface is created here so command-line applications + // NOTE: The XDG surface and role are created here so command-line applications // with off-screen windows do not appear in for example the Unity dock createShellObjects(window); } } -void _glfwPlatformHideWindow(_GLFWwindow* window) +void _glfwHideWindowWayland(_GLFWwindow* window) { if (window->wl.visible) { @@ -2139,29 +2442,68 @@ void _glfwPlatformHideWindow(_GLFWwindow* window) } } -void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) +void _glfwRequestWindowAttentionWayland(_GLFWwindow* window) { - // TODO - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Window attention request not implemented yet"); + if (!_glfw.wl.activationManager) + return; + + // We're about to overwrite this with a new request + if (window->wl.activationToken) + xdg_activation_token_v1_destroy(window->wl.activationToken); + + window->wl.activationToken = + xdg_activation_v1_get_activation_token(_glfw.wl.activationManager); + xdg_activation_token_v1_add_listener(window->wl.activationToken, + &xdgActivationListener, + window); + + xdg_activation_token_v1_commit(window->wl.activationToken); } -void _glfwPlatformFocusWindow(_GLFWwindow* window) +void _glfwFocusWindowWayland(_GLFWwindow* window) { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Focusing a window requires user interaction"); + if (!_glfw.wl.activationManager) + return; + + if (window->wl.activationToken) + xdg_activation_token_v1_destroy(window->wl.activationToken); + + window->wl.activationToken = + xdg_activation_v1_get_activation_token(_glfw.wl.activationManager); + xdg_activation_token_v1_add_listener(window->wl.activationToken, + &xdgActivationListener, + window); + + xdg_activation_token_v1_set_serial(window->wl.activationToken, + _glfw.wl.serial, + _glfw.wl.seat); + + _GLFWwindow* requester = _glfw.wl.keyboardFocus; + if (requester) + { + xdg_activation_token_v1_set_surface(window->wl.activationToken, + requester->wl.surface); + + if (requester->wl.appId) + { + xdg_activation_token_v1_set_app_id(window->wl.activationToken, + requester->wl.appId); + } + } + + xdg_activation_token_v1_commit(window->wl.activationToken); } -void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, - _GLFWmonitor* monitor, - int xpos, int ypos, - int width, int height, - int refreshRate) +void _glfwSetWindowMonitorWayland(_GLFWwindow* window, + _GLFWmonitor* monitor, + int xpos, int ypos, + int width, int height, + int refreshRate) { if (window->monitor == monitor) { if (!monitor) - _glfwPlatformSetWindowSize(window, width, height); + _glfwSetWindowSizeWayland(window, width, height); return; } @@ -2174,50 +2516,67 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, if (window->monitor) acquireMonitor(window); else - _glfwPlatformSetWindowSize(window, width, height); + _glfwSetWindowSizeWayland(window, width, height); } -int _glfwPlatformWindowFocused(_GLFWwindow* window) +GLFWbool _glfwWindowFocusedWayland(_GLFWwindow* window) { return _glfw.wl.keyboardFocus == window; } -int _glfwPlatformWindowIconified(_GLFWwindow* window) +GLFWbool _glfwWindowIconifiedWayland(_GLFWwindow* window) { - // xdg-shell doesn’t give any way to request whether a surface is iconified + // xdg-shell doesn’t give any way to request whether a surface is + // iconified. return GLFW_FALSE; } -int _glfwPlatformWindowVisible(_GLFWwindow* window) +GLFWbool _glfwWindowVisibleWayland(_GLFWwindow* window) { return window->wl.visible; } -int _glfwPlatformWindowMaximized(_GLFWwindow* window) +GLFWbool _glfwWindowMaximizedWayland(_GLFWwindow* window) { return window->wl.maximized; } -int _glfwPlatformWindowHovered(_GLFWwindow* window) +GLFWbool _glfwWindowHoveredWayland(_GLFWwindow* window) { return window->wl.hovered; } -int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) +GLFWbool _glfwFramebufferTransparentWayland(_GLFWwindow* window) { return window->wl.transparent; } -void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) +void _glfwSetWindowResizableWayland(_GLFWwindow* window, GLFWbool enabled) { - // TODO - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Window attribute setting not implemented yet"); + if (window->wl.libdecor.frame) + { + if (enabled) + { + libdecor_frame_set_capabilities(window->wl.libdecor.frame, + LIBDECOR_ACTION_RESIZE); + } + else + { + libdecor_frame_unset_capabilities(window->wl.libdecor.frame, + LIBDECOR_ACTION_RESIZE); + } + } + else if (window->wl.xdg.toplevel) + updateXdgSizeLimits(window); } -void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) +void _glfwSetWindowDecoratedWayland(_GLFWwindow* window, GLFWbool enabled) { - if (window->wl.xdg.decoration) + if (window->wl.libdecor.frame) + { + libdecor_frame_set_visibility(window->wl.libdecor.frame, enabled); + } + else if (window->wl.xdg.decoration) { uint32_t mode; @@ -2228,7 +2587,7 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode); } - else + else if (window->wl.xdg.toplevel) { if (enabled) createFallbackDecorations(window); @@ -2237,55 +2596,68 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) } } -void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) +void _glfwSetWindowFloatingWayland(_GLFWwindow* window, GLFWbool enabled) { - // TODO - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Window attribute setting not implemented yet"); + _glfwInputError(GLFW_FEATURE_UNAVAILABLE, + "Wayland: Platform does not support making a window floating"); } -float _glfwPlatformGetWindowOpacity(_GLFWwindow* window) +void _glfwSetWindowMousePassthroughWayland(_GLFWwindow* window, GLFWbool enabled) +{ + if (enabled) + { + struct wl_region* region = wl_compositor_create_region(_glfw.wl.compositor); + wl_surface_set_input_region(window->wl.surface, region); + wl_region_destroy(region); + } + else + wl_surface_set_input_region(window->wl.surface, NULL); +} + +float _glfwGetWindowOpacityWayland(_GLFWwindow* window) { return 1.f; } -void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) +void _glfwSetWindowOpacityWayland(_GLFWwindow* window, float opacity) { + _glfwInputError(GLFW_FEATURE_UNAVAILABLE, + "Wayland: The platform does not support setting the window opacity"); } -void _glfwPlatformSetRawMouseMotion(_GLFWwindow* window, GLFWbool enabled) +void _glfwSetRawMouseMotionWayland(_GLFWwindow* window, GLFWbool enabled) { // This is handled in relativePointerHandleRelativeMotion } -GLFWbool _glfwPlatformRawMouseMotionSupported(void) +GLFWbool _glfwRawMouseMotionSupportedWayland(void) { return GLFW_TRUE; } -void _glfwPlatformPollEvents(void) +void _glfwPollEventsWayland(void) { double timeout = 0.0; handleEvents(&timeout); } -void _glfwPlatformWaitEvents(void) +void _glfwWaitEventsWayland(void) { handleEvents(NULL); } -void _glfwPlatformWaitEventsTimeout(double timeout) +void _glfwWaitEventsTimeoutWayland(double timeout) { handleEvents(&timeout); } -void _glfwPlatformPostEmptyEvent(void) +void _glfwPostEmptyEventWayland(void) { wl_display_sync(_glfw.wl.display); flushDisplay(); } -void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) +void _glfwGetCursorPosWayland(_GLFWwindow* window, double* xpos, double* ypos) { if (xpos) *xpos = window->wl.cursorPosX; @@ -2293,27 +2665,20 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) *ypos = window->wl.cursorPosY; } -static GLFWbool isPointerLocked(_GLFWwindow* window); - -void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) +void _glfwSetCursorPosWayland(_GLFWwindow* window, double x, double y) { - if (isPointerLocked(window)) - { - zwp_locked_pointer_v1_set_cursor_position_hint( - window->wl.pointerLock.lockedPointer, - wl_fixed_from_double(x), wl_fixed_from_double(y)); - } + _glfwInputError(GLFW_FEATURE_UNAVAILABLE, + "Wayland: The platform does not support setting the cursor position"); } -void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) +void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode) { - _glfwPlatformSetCursor(window, window->wl.currentCursor); + _glfwSetCursorWayland(window, window->wl.currentCursor); } -const char* _glfwPlatformGetScancodeName(int scancode) +const char* _glfwGetScancodeNameWayland(int scancode) { - if (scancode < 0 || scancode > 255 || - _glfw.wl.keycodes[scancode] == GLFW_KEY_UNKNOWN) + if (scancode < 0 || scancode > 255) { _glfwInputError(GLFW_INVALID_VALUE, "Wayland: Invalid scancode %i", @@ -2322,6 +2687,9 @@ const char* _glfwPlatformGetScancodeName(int scancode) } const int key = _glfw.wl.keycodes[scancode]; + if (key == GLFW_KEY_UNKNOWN) + return NULL; + const xkb_keycode_t keycode = scancode + 8; const xkb_layout_index_t layout = xkb_state_key_get_layout(_glfw.wl.xkb.state, keycode); @@ -2365,14 +2733,14 @@ const char* _glfwPlatformGetScancodeName(int scancode) return _glfw.wl.keynames[key]; } -int _glfwPlatformGetKeyScancode(int key) +int _glfwGetKeyScancodeWayland(int key) { return _glfw.wl.scancodes[key]; } -int _glfwPlatformCreateCursor(_GLFWcursor* cursor, - const GLFWimage* image, - int xhot, int yhot) +GLFWbool _glfwCreateCursorWayland(_GLFWcursor* cursor, + const GLFWimage* image, + int xhot, int yhot) { cursor->wl.buffer = createShmBuffer(image); if (!cursor->wl.buffer) @@ -2385,34 +2753,108 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, return GLFW_TRUE; } -int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) +GLFWbool _glfwCreateStandardCursorWayland(_GLFWcursor* cursor, int shape) { - struct wl_cursor* standardCursor; + const char* name = NULL; - standardCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, - translateCursorShape(shape)); - if (!standardCursor) + // Try the XDG names first + switch (shape) { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Standard cursor \"%s\" not found", - translateCursorShape(shape)); - return GLFW_FALSE; + case GLFW_ARROW_CURSOR: + name = "default"; + break; + case GLFW_IBEAM_CURSOR: + name = "text"; + break; + case GLFW_CROSSHAIR_CURSOR: + name = "crosshair"; + break; + case GLFW_POINTING_HAND_CURSOR: + name = "pointer"; + break; + case GLFW_RESIZE_EW_CURSOR: + name = "ew-resize"; + break; + case GLFW_RESIZE_NS_CURSOR: + name = "ns-resize"; + break; + case GLFW_RESIZE_NWSE_CURSOR: + name = "nwse-resize"; + break; + case GLFW_RESIZE_NESW_CURSOR: + name = "nesw-resize"; + break; + case GLFW_RESIZE_ALL_CURSOR: + name = "all-scroll"; + break; + case GLFW_NOT_ALLOWED_CURSOR: + name = "not-allowed"; + break; } - cursor->wl.cursor = standardCursor; - cursor->wl.currentImage = 0; + cursor->wl.cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, name); if (_glfw.wl.cursorThemeHiDPI) { - standardCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, - translateCursorShape(shape)); - cursor->wl.cursorHiDPI = standardCursor; + cursor->wl.cursorHiDPI = + wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, name); + } + + if (!cursor->wl.cursor) + { + // Fall back to the core X11 names + switch (shape) + { + case GLFW_ARROW_CURSOR: + name = "left_ptr"; + break; + case GLFW_IBEAM_CURSOR: + name = "xterm"; + break; + case GLFW_CROSSHAIR_CURSOR: + name = "crosshair"; + break; + case GLFW_POINTING_HAND_CURSOR: + name = "hand2"; + break; + case GLFW_RESIZE_EW_CURSOR: + name = "sb_h_double_arrow"; + break; + case GLFW_RESIZE_NS_CURSOR: + name = "sb_v_double_arrow"; + break; + case GLFW_RESIZE_ALL_CURSOR: + name = "fleur"; + break; + default: + _glfwInputError(GLFW_CURSOR_UNAVAILABLE, + "Wayland: Standard cursor shape unavailable"); + return GLFW_FALSE; + } + + cursor->wl.cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, name); + if (!cursor->wl.cursor) + { + _glfwInputError(GLFW_CURSOR_UNAVAILABLE, + "Wayland: Failed to create standard cursor \"%s\"", + name); + return GLFW_FALSE; + } + + if (_glfw.wl.cursorThemeHiDPI) + { + if (!cursor->wl.cursorHiDPI) + { + cursor->wl.cursorHiDPI = + wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, name); + } + } } return GLFW_TRUE; } -void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) +void _glfwDestroyCursorWayland(_GLFWcursor* cursor) { // If it's a standard cursor we don't need to do anything here if (cursor->wl.cursor) @@ -2462,22 +2904,6 @@ static void lockedPointerHandleLocked(void* userData, { } -static void unlockPointer(_GLFWwindow* window) -{ - struct zwp_relative_pointer_v1* relativePointer = - window->wl.pointerLock.relativePointer; - struct zwp_locked_pointer_v1* lockedPointer = - window->wl.pointerLock.lockedPointer; - - zwp_relative_pointer_v1_destroy(relativePointer); - zwp_locked_pointer_v1_destroy(lockedPointer); - - window->wl.pointerLock.relativePointer = NULL; - window->wl.pointerLock.lockedPointer = NULL; -} - -static void lockPointer(_GLFWwindow* window); - static void lockedPointerHandleUnlocked(void* userData, struct zwp_locked_pointer_v1* lockedPointer) { @@ -2491,52 +2917,81 @@ static const struct zwp_locked_pointer_v1_listener lockedPointerListener = static void lockPointer(_GLFWwindow* window) { - struct zwp_relative_pointer_v1* relativePointer; - struct zwp_locked_pointer_v1* lockedPointer; - if (!_glfw.wl.relativePointerManager) { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: no relative pointer manager"); + _glfwInputError(GLFW_FEATURE_UNAVAILABLE, + "Wayland: The compositor does not support pointer locking"); return; } - relativePointer = + window->wl.relativePointer = zwp_relative_pointer_manager_v1_get_relative_pointer( _glfw.wl.relativePointerManager, _glfw.wl.pointer); - zwp_relative_pointer_v1_add_listener(relativePointer, + zwp_relative_pointer_v1_add_listener(window->wl.relativePointer, &relativePointerListener, window); - lockedPointer = + window->wl.lockedPointer = zwp_pointer_constraints_v1_lock_pointer( _glfw.wl.pointerConstraints, window->wl.surface, _glfw.wl.pointer, NULL, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); - zwp_locked_pointer_v1_add_listener(lockedPointer, + zwp_locked_pointer_v1_add_listener(window->wl.lockedPointer, &lockedPointerListener, window); - - window->wl.pointerLock.relativePointer = relativePointer; - window->wl.pointerLock.lockedPointer = lockedPointer; - - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, - NULL, 0, 0); } -static GLFWbool isPointerLocked(_GLFWwindow* window) +static void unlockPointer(_GLFWwindow* window) { - return window->wl.pointerLock.lockedPointer != NULL; + zwp_relative_pointer_v1_destroy(window->wl.relativePointer); + window->wl.relativePointer = NULL; + + zwp_locked_pointer_v1_destroy(window->wl.lockedPointer); + window->wl.lockedPointer = NULL; } -void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) +static void confinedPointerHandleConfined(void* userData, + struct zwp_confined_pointer_v1* confinedPointer) { - struct wl_cursor* defaultCursor; - struct wl_cursor* defaultCursorHiDPI = NULL; +} +static void confinedPointerHandleUnconfined(void* userData, + struct zwp_confined_pointer_v1* confinedPointer) +{ +} + +static const struct zwp_confined_pointer_v1_listener confinedPointerListener = +{ + confinedPointerHandleConfined, + confinedPointerHandleUnconfined +}; + +static void confinePointer(_GLFWwindow* window) +{ + window->wl.confinedPointer = + zwp_pointer_constraints_v1_confine_pointer( + _glfw.wl.pointerConstraints, + window->wl.surface, + _glfw.wl.pointer, + NULL, + ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); + + zwp_confined_pointer_v1_add_listener(window->wl.confinedPointer, + &confinedPointerListener, + window); +} + +static void unconfinePointer(_GLFWwindow* window) +{ + zwp_confined_pointer_v1_destroy(window->wl.confinedPointer); + window->wl.confinedPointer = NULL; +} + +void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor) +{ if (!_glfw.wl.pointer) return; @@ -2544,32 +2999,58 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) // If we're not in the correct window just save the cursor // the next time the pointer enters the window the cursor will change - if (window != _glfw.wl.pointerFocus || window->wl.decorations.focus != mainWindow) + if (!window->wl.hovered) return; - // Unlock possible pointer lock if no longer disabled. - if (window->cursorMode != GLFW_CURSOR_DISABLED && isPointerLocked(window)) - unlockPointer(window); + // Update pointer lock to match cursor mode + if (window->cursorMode == GLFW_CURSOR_DISABLED) + { + if (window->wl.confinedPointer) + unconfinePointer(window); + if (!window->wl.lockedPointer) + lockPointer(window); + } + else if (window->cursorMode == GLFW_CURSOR_CAPTURED) + { + if (window->wl.lockedPointer) + unlockPointer(window); + if (!window->wl.confinedPointer) + confinePointer(window); + } + else if (window->cursorMode == GLFW_CURSOR_NORMAL || + window->cursorMode == GLFW_CURSOR_HIDDEN) + { + if (window->wl.lockedPointer) + unlockPointer(window); + else if (window->wl.confinedPointer) + unconfinePointer(window); + } - if (window->cursorMode == GLFW_CURSOR_NORMAL) + if (window->cursorMode == GLFW_CURSOR_NORMAL || + window->cursorMode == GLFW_CURSOR_CAPTURED) { if (cursor) setCursorImage(window, &cursor->wl); else { - defaultCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, - "left_ptr"); + struct wl_cursor* defaultCursor = + wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, "left_ptr"); if (!defaultCursor) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Standard cursor not found"); return; } + + struct wl_cursor* defaultCursorHiDPI = NULL; if (_glfw.wl.cursorThemeHiDPI) + { defaultCursorHiDPI = - wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, - "left_ptr"); - _GLFWcursorWayland cursorWayland = { + wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, "left_ptr"); + } + + _GLFWcursorWayland cursorWayland = + { defaultCursor, defaultCursorHiDPI, NULL, @@ -2577,15 +3058,12 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) 0, 0, 0 }; + setCursorImage(window, &cursorWayland); } } - else if (window->cursorMode == GLFW_CURSOR_DISABLED) - { - if (!isPointerLocked(window)) - lockPointer(window); - } - else if (window->cursorMode == GLFW_CURSOR_HIDDEN) + else if (window->cursorMode == GLFW_CURSOR_HIDDEN || + window->cursorMode == GLFW_CURSOR_DISABLED) { wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, NULL, 0, 0); } @@ -2658,7 +3136,7 @@ static const struct wl_data_source_listener dataSourceListener = dataSourceHandleCancelled, }; -void _glfwPlatformSetClipboardString(const char* string) +void _glfwSetClipboardStringWayland(const char* string) { if (_glfw.wl.selectionSource) { @@ -2673,7 +3151,7 @@ void _glfwPlatformSetClipboardString(const char* string) return; } - free(_glfw.wl.clipboardString); + _glfw_free(_glfw.wl.clipboardString); _glfw.wl.clipboardString = copy; _glfw.wl.selectionSource = @@ -2693,7 +3171,7 @@ void _glfwPlatformSetClipboardString(const char* string) _glfw.wl.serial); } -const char* _glfwPlatformGetClipboardString(void) +const char* _glfwGetClipboardStringWayland(void) { if (!_glfw.wl.selectionOffer) { @@ -2705,13 +3183,31 @@ const char* _glfwPlatformGetClipboardString(void) if (_glfw.wl.selectionSource) return _glfw.wl.clipboardString; - free(_glfw.wl.clipboardString); + _glfw_free(_glfw.wl.clipboardString); _glfw.wl.clipboardString = readDataOfferAsString(_glfw.wl.selectionOffer, "text/plain;charset=utf-8"); return _glfw.wl.clipboardString; } -void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) +EGLenum _glfwGetEGLPlatformWayland(EGLint** attribs) +{ + if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_wayland) + return EGL_PLATFORM_WAYLAND_EXT; + else + return 0; +} + +EGLNativeDisplayType _glfwGetEGLNativeDisplayWayland(void) +{ + return _glfw.wl.display; +} + +EGLNativeWindowType _glfwGetEGLNativeWindowWayland(_GLFWwindow* window) +{ + return window->wl.egl.window; +} + +void _glfwGetRequiredInstanceExtensionsWayland(char** extensions) { if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_wayland_surface) return; @@ -2720,9 +3216,9 @@ void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) extensions[1] = "VK_KHR_wayland_surface"; } -int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, - VkPhysicalDevice device, - uint32_t queuefamily) +GLFWbool _glfwGetPhysicalDevicePresentationSupportWayland(VkInstance instance, + VkPhysicalDevice device, + uint32_t queuefamily) { PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR = @@ -2740,10 +3236,10 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, _glfw.wl.display); } -VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, - _GLFWwindow* window, - const VkAllocationCallbacks* allocator, - VkSurfaceKHR* surface) +VkResult _glfwCreateWindowSurfaceWayland(VkInstance instance, + _GLFWwindow* window, + const VkAllocationCallbacks* allocator, + VkSurfaceKHR* surface) { VkResult err; VkWaylandSurfaceCreateInfoKHR sci; @@ -2782,6 +3278,14 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, GLFWAPI struct wl_display* glfwGetWaylandDisplay(void) { _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, + "Wayland: Platform not initialized"); + return NULL; + } + return _glfw.wl.display; } @@ -2789,6 +3293,16 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, + "Wayland: Platform not initialized"); + return NULL; + } + return window->wl.surface; } +#endif // _GLFW_WAYLAND + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/x11_init.c b/src/lib/src/vendor/glfw-3.4/src/x11_init.c similarity index 59% rename from src/lib/src/vendor/glfw-3.3.8/src/x11_init.c rename to src/lib/src/vendor/glfw-3.4/src/x11_init.c index 6049904..e992f44 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/x11_init.c +++ b/src/lib/src/vendor/glfw-3.4/src/x11_init.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 X11 - www.glfw.org +// GLFW 3.4 X11 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -24,12 +24,10 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" -#include +#if defined(_GLFW_X11) #include #include @@ -214,7 +212,7 @@ static int translateKeySyms(const KeySym* keysyms, int width) // static void createKeyTables(void) { - int scancode, scancodeMin, scancodeMax; + int scancodeMin, scancodeMax; memset(_glfw.x11.keycodes, -1, sizeof(_glfw.x11.keycodes)); memset(_glfw.x11.scancodes, -1, sizeof(_glfw.x11.scancodes)); @@ -360,7 +358,7 @@ static void createKeyTables(void) }; // Find the X11 key code -> GLFW key code mapping - for (scancode = scancodeMin; scancode <= scancodeMax; scancode++) + for (int scancode = scancodeMin; scancode <= scancodeMax; scancode++) { int key = GLFW_KEY_UNKNOWN; @@ -419,7 +417,7 @@ static void createKeyTables(void) scancodeMax - scancodeMin + 1, &width); - for (scancode = scancodeMin; scancode <= scancodeMax; scancode++) + for (int scancode = scancodeMin; scancode <= scancodeMax; scancode++) { // Translate the un-translated key codes using traditional X11 KeySym // lookups @@ -460,7 +458,41 @@ static GLFWbool hasUsableInputMethodStyle(void) return found; } -// Check whether the specified atom is supported +static void inputMethodDestroyCallback(XIM im, XPointer clientData, XPointer callData) +{ + _glfw.x11.im = NULL; +} + +static void inputMethodInstantiateCallback(Display* display, + XPointer clientData, + XPointer callData) +{ + if (_glfw.x11.im) + return; + + _glfw.x11.im = XOpenIM(_glfw.x11.display, 0, NULL, NULL); + if (_glfw.x11.im) + { + if (!hasUsableInputMethodStyle()) + { + XCloseIM(_glfw.x11.im); + _glfw.x11.im = NULL; + } + } + + if (_glfw.x11.im) + { + XIMCallback callback; + callback.callback = (XIMProc) inputMethodDestroyCallback; + callback.client_data = NULL; + XSetIMValues(_glfw.x11.im, XNDestroyCallback, &callback, NULL); + + for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next) + _glfwCreateInputContextX11(window); + } +} + +// Return the atom ID only if it is listed in the specified array // static Atom getAtomIfSupported(Atom* supportedAtoms, unsigned long atomCount, @@ -573,20 +605,20 @@ static void detectEWMH(void) static GLFWbool initExtensions(void) { #if defined(__OpenBSD__) || defined(__NetBSD__) - _glfw.x11.vidmode.handle = _glfw_dlopen("libXxf86vm.so"); + _glfw.x11.vidmode.handle = _glfwPlatformLoadModule("libXxf86vm.so"); #else - _glfw.x11.vidmode.handle = _glfw_dlopen("libXxf86vm.so.1"); + _glfw.x11.vidmode.handle = _glfwPlatformLoadModule("libXxf86vm.so.1"); #endif if (_glfw.x11.vidmode.handle) { _glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension) - _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeQueryExtension"); + _glfwPlatformGetModuleSymbol(_glfw.x11.vidmode.handle, "XF86VidModeQueryExtension"); _glfw.x11.vidmode.GetGammaRamp = (PFN_XF86VidModeGetGammaRamp) - _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp"); + _glfwPlatformGetModuleSymbol(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp"); _glfw.x11.vidmode.SetGammaRamp = (PFN_XF86VidModeSetGammaRamp) - _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp"); + _glfwPlatformGetModuleSymbol(_glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp"); _glfw.x11.vidmode.GetGammaRampSize = (PFN_XF86VidModeGetGammaRampSize) - _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize"); + _glfwPlatformGetModuleSymbol(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize"); _glfw.x11.vidmode.available = XF86VidModeQueryExtension(_glfw.x11.display, @@ -595,18 +627,18 @@ static GLFWbool initExtensions(void) } #if defined(__CYGWIN__) - _glfw.x11.xi.handle = _glfw_dlopen("libXi-6.so"); + _glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi-6.so"); #elif defined(__OpenBSD__) || defined(__NetBSD__) - _glfw.x11.xi.handle = _glfw_dlopen("libXi.so"); + _glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi.so"); #else - _glfw.x11.xi.handle = _glfw_dlopen("libXi.so.6"); + _glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi.so.6"); #endif if (_glfw.x11.xi.handle) { _glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion) - _glfw_dlsym(_glfw.x11.xi.handle, "XIQueryVersion"); + _glfwPlatformGetModuleSymbol(_glfw.x11.xi.handle, "XIQueryVersion"); _glfw.x11.xi.SelectEvents = (PFN_XISelectEvents) - _glfw_dlsym(_glfw.x11.xi.handle, "XISelectEvents"); + _glfwPlatformGetModuleSymbol(_glfw.x11.xi.handle, "XISelectEvents"); if (XQueryExtension(_glfw.x11.display, "XInputExtension", @@ -627,50 +659,50 @@ static GLFWbool initExtensions(void) } #if defined(__CYGWIN__) - _glfw.x11.randr.handle = _glfw_dlopen("libXrandr-2.so"); + _glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr-2.so"); #elif defined(__OpenBSD__) || defined(__NetBSD__) - _glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so"); + _glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr.so"); #else - _glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so.2"); + _glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr.so.2"); #endif if (_glfw.x11.randr.handle) { _glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRAllocGamma"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRAllocGamma"); _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRFreeGamma"); _glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRFreeCrtcInfo"); _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRFreeGamma"); _glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRFreeOutputInfo"); _glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRFreeScreenResources"); _glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRGetCrtcGamma"); _glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize"); _glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRGetCrtcInfo"); _glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRGetOutputInfo"); _glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRGetOutputPrimary"); _glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent"); _glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryExtension"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRQueryExtension"); _glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryVersion"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRQueryVersion"); _glfw.x11.randr.SelectInput = (PFN_XRRSelectInput) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRSelectInput"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRSelectInput"); _glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRSetCrtcConfig"); _glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRSetCrtcGamma"); _glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration) - _glfw_dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration"); + _glfwPlatformGetModuleSymbol(_glfw.x11.randr.handle, "XRRUpdateConfiguration"); if (XRRQueryExtension(_glfw.x11.display, &_glfw.x11.randr.eventBase, @@ -721,37 +753,43 @@ static GLFWbool initExtensions(void) } #if defined(__CYGWIN__) - _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor-1.so"); + _glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor-1.so"); #elif defined(__OpenBSD__) || defined(__NetBSD__) - _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so"); + _glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor.so"); #else - _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so.1"); + _glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor.so.1"); #endif if (_glfw.x11.xcursor.handle) { _glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate) - _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageCreate"); + _glfwPlatformGetModuleSymbol(_glfw.x11.xcursor.handle, "XcursorImageCreate"); _glfw.x11.xcursor.ImageDestroy = (PFN_XcursorImageDestroy) - _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy"); + _glfwPlatformGetModuleSymbol(_glfw.x11.xcursor.handle, "XcursorImageDestroy"); _glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor) - _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor"); + _glfwPlatformGetModuleSymbol(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor"); + _glfw.x11.xcursor.GetTheme = (PFN_XcursorGetTheme) + _glfwPlatformGetModuleSymbol(_glfw.x11.xcursor.handle, "XcursorGetTheme"); + _glfw.x11.xcursor.GetDefaultSize = (PFN_XcursorGetDefaultSize) + _glfwPlatformGetModuleSymbol(_glfw.x11.xcursor.handle, "XcursorGetDefaultSize"); + _glfw.x11.xcursor.LibraryLoadImage = (PFN_XcursorLibraryLoadImage) + _glfwPlatformGetModuleSymbol(_glfw.x11.xcursor.handle, "XcursorLibraryLoadImage"); } #if defined(__CYGWIN__) - _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama-1.so"); + _glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama-1.so"); #elif defined(__OpenBSD__) || defined(__NetBSD__) - _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so"); + _glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama.so"); #else - _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so.1"); + _glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama.so.1"); #endif if (_glfw.x11.xinerama.handle) { _glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive) - _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaIsActive"); + _glfwPlatformGetModuleSymbol(_glfw.x11.xinerama.handle, "XineramaIsActive"); _glfw.x11.xinerama.QueryExtension = (PFN_XineramaQueryExtension) - _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryExtension"); + _glfwPlatformGetModuleSymbol(_glfw.x11.xinerama.handle, "XineramaQueryExtension"); _glfw.x11.xinerama.QueryScreens = (PFN_XineramaQueryScreens) - _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryScreens"); + _glfwPlatformGetModuleSymbol(_glfw.x11.xinerama.handle, "XineramaQueryScreens"); if (XineramaQueryExtension(_glfw.x11.display, &_glfw.x11.xinerama.major, @@ -790,34 +828,38 @@ static GLFWbool initExtensions(void) XkbGroupStateMask, XkbGroupStateMask); } + if (_glfw.hints.init.x11.xcbVulkanSurface) + { #if defined(__CYGWIN__) - _glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb-1.so"); + _glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb-1.so"); #elif defined(__OpenBSD__) || defined(__NetBSD__) - _glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so"); + _glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb.so"); #else - _glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so.1"); + _glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb.so.1"); #endif + } + if (_glfw.x11.x11xcb.handle) { _glfw.x11.x11xcb.GetXCBConnection = (PFN_XGetXCBConnection) - _glfw_dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection"); + _glfwPlatformGetModuleSymbol(_glfw.x11.x11xcb.handle, "XGetXCBConnection"); } #if defined(__CYGWIN__) - _glfw.x11.xrender.handle = _glfw_dlopen("libXrender-1.so"); + _glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender-1.so"); #elif defined(__OpenBSD__) || defined(__NetBSD__) - _glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so"); + _glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender.so"); #else - _glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so.1"); + _glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender.so.1"); #endif if (_glfw.x11.xrender.handle) { _glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension) - _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryExtension"); + _glfwPlatformGetModuleSymbol(_glfw.x11.xrender.handle, "XRenderQueryExtension"); _glfw.x11.xrender.QueryVersion = (PFN_XRenderQueryVersion) - _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryVersion"); + _glfwPlatformGetModuleSymbol(_glfw.x11.xrender.handle, "XRenderQueryVersion"); _glfw.x11.xrender.FindVisualFormat = (PFN_XRenderFindVisualFormat) - _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderFindVisualFormat"); + _glfwPlatformGetModuleSymbol(_glfw.x11.xrender.handle, "XRenderFindVisualFormat"); if (XRenderQueryExtension(_glfw.x11.display, &_glfw.x11.xrender.errorBase, @@ -832,6 +874,37 @@ static GLFWbool initExtensions(void) } } +#if defined(__CYGWIN__) + _glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext-6.so"); +#elif defined(__OpenBSD__) || defined(__NetBSD__) + _glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext.so"); +#else + _glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext.so.6"); +#endif + if (_glfw.x11.xshape.handle) + { + _glfw.x11.xshape.QueryExtension = (PFN_XShapeQueryExtension) + _glfwPlatformGetModuleSymbol(_glfw.x11.xshape.handle, "XShapeQueryExtension"); + _glfw.x11.xshape.ShapeCombineRegion = (PFN_XShapeCombineRegion) + _glfwPlatformGetModuleSymbol(_glfw.x11.xshape.handle, "XShapeCombineRegion"); + _glfw.x11.xshape.QueryVersion = (PFN_XShapeQueryVersion) + _glfwPlatformGetModuleSymbol(_glfw.x11.xshape.handle, "XShapeQueryVersion"); + _glfw.x11.xshape.ShapeCombineMask = (PFN_XShapeCombineMask) + _glfwPlatformGetModuleSymbol(_glfw.x11.xshape.handle, "XShapeCombineMask"); + + if (XShapeQueryExtension(_glfw.x11.display, + &_glfw.x11.xshape.errorBase, + &_glfw.x11.xshape.eventBase)) + { + if (XShapeQueryVersion(_glfw.x11.display, + &_glfw.x11.xshape.major, + &_glfw.x11.xshape.minor)) + { + _glfw.x11.xshape.available = GLFW_TRUE; + } + } + } + // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to // the keyboard mapping. @@ -955,7 +1028,7 @@ static Cursor createHiddenCursor(void) { unsigned char pixels[16 * 16 * 4] = { 0 }; GLFWimage image = { 16, 16, pixels }; - return _glfwCreateCursorX11(&image, 0, 0); + return _glfwCreateNativeCursorX11(&image, 0, 0); } // Create a helper window for IPC @@ -1051,9 +1124,8 @@ void _glfwInputErrorX11(int error, const char* message) // Creates a native cursor object from the specified image and hotspot // -Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot) +Cursor _glfwCreateNativeCursorX11(const GLFWimage* image, int xhot, int yhot) { - int i; Cursor cursor; if (!_glfw.x11.xcursor.handle) @@ -1069,7 +1141,7 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot) unsigned char* source = (unsigned char*) image->pixels; XcursorPixel* target = native->pixels; - for (i = 0; i < image->width * image->height; i++, target++, source += 4) + for (int i = 0; i < image->width * image->height; i++, target++, source += 4) { unsigned int alpha = source[3]; @@ -1090,8 +1162,92 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot) ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -int _glfwPlatformInit(void) +GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform) { + const _GLFWplatform x11 = + { + .platformID = GLFW_PLATFORM_X11, + .init = _glfwInitX11, + .terminate = _glfwTerminateX11, + .getCursorPos = _glfwGetCursorPosX11, + .setCursorPos = _glfwSetCursorPosX11, + .setCursorMode = _glfwSetCursorModeX11, + .setRawMouseMotion = _glfwSetRawMouseMotionX11, + .rawMouseMotionSupported = _glfwRawMouseMotionSupportedX11, + .createCursor = _glfwCreateCursorX11, + .createStandardCursor = _glfwCreateStandardCursorX11, + .destroyCursor = _glfwDestroyCursorX11, + .setCursor = _glfwSetCursorX11, + .getScancodeName = _glfwGetScancodeNameX11, + .getKeyScancode = _glfwGetKeyScancodeX11, + .setClipboardString = _glfwSetClipboardStringX11, + .getClipboardString = _glfwGetClipboardStringX11, +#if defined(GLFW_BUILD_LINUX_JOYSTICK) + .initJoysticks = _glfwInitJoysticksLinux, + .terminateJoysticks = _glfwTerminateJoysticksLinux, + .pollJoystick = _glfwPollJoystickLinux, + .getMappingName = _glfwGetMappingNameLinux, + .updateGamepadGUID = _glfwUpdateGamepadGUIDLinux, +#else + .initJoysticks = _glfwInitJoysticksNull, + .terminateJoysticks = _glfwTerminateJoysticksNull, + .pollJoystick = _glfwPollJoystickNull, + .getMappingName = _glfwGetMappingNameNull, + .updateGamepadGUID = _glfwUpdateGamepadGUIDNull, +#endif + .freeMonitor = _glfwFreeMonitorX11, + .getMonitorPos = _glfwGetMonitorPosX11, + .getMonitorContentScale = _glfwGetMonitorContentScaleX11, + .getMonitorWorkarea = _glfwGetMonitorWorkareaX11, + .getVideoModes = _glfwGetVideoModesX11, + .getVideoMode = _glfwGetVideoModeX11, + .getGammaRamp = _glfwGetGammaRampX11, + .setGammaRamp = _glfwSetGammaRampX11, + .createWindow = _glfwCreateWindowX11, + .destroyWindow = _glfwDestroyWindowX11, + .setWindowTitle = _glfwSetWindowTitleX11, + .setWindowIcon = _glfwSetWindowIconX11, + .getWindowPos = _glfwGetWindowPosX11, + .setWindowPos = _glfwSetWindowPosX11, + .getWindowSize = _glfwGetWindowSizeX11, + .setWindowSize = _glfwSetWindowSizeX11, + .setWindowSizeLimits = _glfwSetWindowSizeLimitsX11, + .setWindowAspectRatio = _glfwSetWindowAspectRatioX11, + .getFramebufferSize = _glfwGetFramebufferSizeX11, + .getWindowFrameSize = _glfwGetWindowFrameSizeX11, + .getWindowContentScale = _glfwGetWindowContentScaleX11, + .iconifyWindow = _glfwIconifyWindowX11, + .restoreWindow = _glfwRestoreWindowX11, + .maximizeWindow = _glfwMaximizeWindowX11, + .showWindow = _glfwShowWindowX11, + .hideWindow = _glfwHideWindowX11, + .requestWindowAttention = _glfwRequestWindowAttentionX11, + .focusWindow = _glfwFocusWindowX11, + .setWindowMonitor = _glfwSetWindowMonitorX11, + .windowFocused = _glfwWindowFocusedX11, + .windowIconified = _glfwWindowIconifiedX11, + .windowVisible = _glfwWindowVisibleX11, + .windowMaximized = _glfwWindowMaximizedX11, + .windowHovered = _glfwWindowHoveredX11, + .framebufferTransparent = _glfwFramebufferTransparentX11, + .getWindowOpacity = _glfwGetWindowOpacityX11, + .setWindowResizable = _glfwSetWindowResizableX11, + .setWindowDecorated = _glfwSetWindowDecoratedX11, + .setWindowFloating = _glfwSetWindowFloatingX11, + .setWindowOpacity = _glfwSetWindowOpacityX11, + .setWindowMousePassthrough = _glfwSetWindowMousePassthroughX11, + .pollEvents = _glfwPollEventsX11, + .waitEvents = _glfwWaitEventsX11, + .waitEventsTimeout = _glfwWaitEventsTimeoutX11, + .postEmptyEvent = _glfwPostEmptyEventX11, + .getEGLPlatform = _glfwGetEGLPlatformX11, + .getEGLNativeDisplay = _glfwGetEGLNativeDisplayX11, + .getEGLNativeWindow = _glfwGetEGLNativeWindowX11, + .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsX11, + .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportX11, + .createWindowSurface = _glfwCreateWindowSurfaceX11 + }; + // HACK: If the application has left the locale as "C" then both wide // character text input and explicit UTF-8 input via XIM will break // This sets the CTYPE part of the current locale from the environment @@ -1099,27 +1255,272 @@ int _glfwPlatformInit(void) if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0) setlocale(LC_CTYPE, ""); - XInitThreads(); - XrmInitialize(); - - _glfw.x11.display = XOpenDisplay(NULL); - if (!_glfw.x11.display) +#if defined(__CYGWIN__) + void* module = _glfwPlatformLoadModule("libX11-6.so"); +#elif defined(__OpenBSD__) || defined(__NetBSD__) + void* module = _glfwPlatformLoadModule("libX11.so"); +#else + void* module = _glfwPlatformLoadModule("libX11.so.6"); +#endif + if (!module) { - const char* display = getenv("DISPLAY"); - if (display) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "X11: Failed to open display %s", display); - } - else - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "X11: The DISPLAY environment variable is missing"); - } + if (platformID == GLFW_PLATFORM_X11) + _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to load Xlib"); return GLFW_FALSE; } + PFN_XInitThreads XInitThreads = (PFN_XInitThreads) + _glfwPlatformGetModuleSymbol(module, "XInitThreads"); + PFN_XrmInitialize XrmInitialize = (PFN_XrmInitialize) + _glfwPlatformGetModuleSymbol(module, "XrmInitialize"); + PFN_XOpenDisplay XOpenDisplay = (PFN_XOpenDisplay) + _glfwPlatformGetModuleSymbol(module, "XOpenDisplay"); + if (!XInitThreads || !XrmInitialize || !XOpenDisplay) + { + if (platformID == GLFW_PLATFORM_X11) + _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to load Xlib entry point"); + + _glfwPlatformFreeModule(module); + return GLFW_FALSE; + } + + XInitThreads(); + XrmInitialize(); + + Display* display = XOpenDisplay(NULL); + if (!display) + { + if (platformID == GLFW_PLATFORM_X11) + { + const char* name = getenv("DISPLAY"); + if (name) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, + "X11: Failed to open display %s", name); + } + else + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, + "X11: The DISPLAY environment variable is missing"); + } + } + + _glfwPlatformFreeModule(module); + return GLFW_FALSE; + } + + _glfw.x11.display = display; + _glfw.x11.xlib.handle = module; + + *platform = x11; + return GLFW_TRUE; +} + +int _glfwInitX11(void) +{ + _glfw.x11.xlib.AllocClassHint = (PFN_XAllocClassHint) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XAllocClassHint"); + _glfw.x11.xlib.AllocSizeHints = (PFN_XAllocSizeHints) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XAllocSizeHints"); + _glfw.x11.xlib.AllocWMHints = (PFN_XAllocWMHints) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XAllocWMHints"); + _glfw.x11.xlib.ChangeProperty = (PFN_XChangeProperty) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XChangeProperty"); + _glfw.x11.xlib.ChangeWindowAttributes = (PFN_XChangeWindowAttributes) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XChangeWindowAttributes"); + _glfw.x11.xlib.CheckIfEvent = (PFN_XCheckIfEvent) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XCheckIfEvent"); + _glfw.x11.xlib.CheckTypedWindowEvent = (PFN_XCheckTypedWindowEvent) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XCheckTypedWindowEvent"); + _glfw.x11.xlib.CloseDisplay = (PFN_XCloseDisplay) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XCloseDisplay"); + _glfw.x11.xlib.CloseIM = (PFN_XCloseIM) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XCloseIM"); + _glfw.x11.xlib.ConvertSelection = (PFN_XConvertSelection) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XConvertSelection"); + _glfw.x11.xlib.CreateColormap = (PFN_XCreateColormap) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XCreateColormap"); + _glfw.x11.xlib.CreateFontCursor = (PFN_XCreateFontCursor) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XCreateFontCursor"); + _glfw.x11.xlib.CreateIC = (PFN_XCreateIC) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XCreateIC"); + _glfw.x11.xlib.CreateRegion = (PFN_XCreateRegion) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XCreateRegion"); + _glfw.x11.xlib.CreateWindow = (PFN_XCreateWindow) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XCreateWindow"); + _glfw.x11.xlib.DefineCursor = (PFN_XDefineCursor) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XDefineCursor"); + _glfw.x11.xlib.DeleteContext = (PFN_XDeleteContext) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XDeleteContext"); + _glfw.x11.xlib.DeleteProperty = (PFN_XDeleteProperty) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XDeleteProperty"); + _glfw.x11.xlib.DestroyIC = (PFN_XDestroyIC) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XDestroyIC"); + _glfw.x11.xlib.DestroyRegion = (PFN_XDestroyRegion) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XDestroyRegion"); + _glfw.x11.xlib.DestroyWindow = (PFN_XDestroyWindow) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XDestroyWindow"); + _glfw.x11.xlib.DisplayKeycodes = (PFN_XDisplayKeycodes) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XDisplayKeycodes"); + _glfw.x11.xlib.EventsQueued = (PFN_XEventsQueued) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XEventsQueued"); + _glfw.x11.xlib.FilterEvent = (PFN_XFilterEvent) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XFilterEvent"); + _glfw.x11.xlib.FindContext = (PFN_XFindContext) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XFindContext"); + _glfw.x11.xlib.Flush = (PFN_XFlush) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XFlush"); + _glfw.x11.xlib.Free = (PFN_XFree) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XFree"); + _glfw.x11.xlib.FreeColormap = (PFN_XFreeColormap) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XFreeColormap"); + _glfw.x11.xlib.FreeCursor = (PFN_XFreeCursor) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XFreeCursor"); + _glfw.x11.xlib.FreeEventData = (PFN_XFreeEventData) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XFreeEventData"); + _glfw.x11.xlib.GetErrorText = (PFN_XGetErrorText) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XGetErrorText"); + _glfw.x11.xlib.GetEventData = (PFN_XGetEventData) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XGetEventData"); + _glfw.x11.xlib.GetICValues = (PFN_XGetICValues) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XGetICValues"); + _glfw.x11.xlib.GetIMValues = (PFN_XGetIMValues) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XGetIMValues"); + _glfw.x11.xlib.GetInputFocus = (PFN_XGetInputFocus) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XGetInputFocus"); + _glfw.x11.xlib.GetKeyboardMapping = (PFN_XGetKeyboardMapping) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XGetKeyboardMapping"); + _glfw.x11.xlib.GetScreenSaver = (PFN_XGetScreenSaver) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XGetScreenSaver"); + _glfw.x11.xlib.GetSelectionOwner = (PFN_XGetSelectionOwner) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XGetSelectionOwner"); + _glfw.x11.xlib.GetVisualInfo = (PFN_XGetVisualInfo) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XGetVisualInfo"); + _glfw.x11.xlib.GetWMNormalHints = (PFN_XGetWMNormalHints) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XGetWMNormalHints"); + _glfw.x11.xlib.GetWindowAttributes = (PFN_XGetWindowAttributes) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XGetWindowAttributes"); + _glfw.x11.xlib.GetWindowProperty = (PFN_XGetWindowProperty) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XGetWindowProperty"); + _glfw.x11.xlib.GrabPointer = (PFN_XGrabPointer) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XGrabPointer"); + _glfw.x11.xlib.IconifyWindow = (PFN_XIconifyWindow) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XIconifyWindow"); + _glfw.x11.xlib.InternAtom = (PFN_XInternAtom) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XInternAtom"); + _glfw.x11.xlib.LookupString = (PFN_XLookupString) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XLookupString"); + _glfw.x11.xlib.MapRaised = (PFN_XMapRaised) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XMapRaised"); + _glfw.x11.xlib.MapWindow = (PFN_XMapWindow) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XMapWindow"); + _glfw.x11.xlib.MoveResizeWindow = (PFN_XMoveResizeWindow) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XMoveResizeWindow"); + _glfw.x11.xlib.MoveWindow = (PFN_XMoveWindow) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XMoveWindow"); + _glfw.x11.xlib.NextEvent = (PFN_XNextEvent) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XNextEvent"); + _glfw.x11.xlib.OpenIM = (PFN_XOpenIM) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XOpenIM"); + _glfw.x11.xlib.PeekEvent = (PFN_XPeekEvent) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XPeekEvent"); + _glfw.x11.xlib.Pending = (PFN_XPending) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XPending"); + _glfw.x11.xlib.QueryExtension = (PFN_XQueryExtension) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XQueryExtension"); + _glfw.x11.xlib.QueryPointer = (PFN_XQueryPointer) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XQueryPointer"); + _glfw.x11.xlib.RaiseWindow = (PFN_XRaiseWindow) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XRaiseWindow"); + _glfw.x11.xlib.RegisterIMInstantiateCallback = (PFN_XRegisterIMInstantiateCallback) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XRegisterIMInstantiateCallback"); + _glfw.x11.xlib.ResizeWindow = (PFN_XResizeWindow) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XResizeWindow"); + _glfw.x11.xlib.ResourceManagerString = (PFN_XResourceManagerString) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XResourceManagerString"); + _glfw.x11.xlib.SaveContext = (PFN_XSaveContext) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSaveContext"); + _glfw.x11.xlib.SelectInput = (PFN_XSelectInput) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSelectInput"); + _glfw.x11.xlib.SendEvent = (PFN_XSendEvent) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSendEvent"); + _glfw.x11.xlib.SetClassHint = (PFN_XSetClassHint) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSetClassHint"); + _glfw.x11.xlib.SetErrorHandler = (PFN_XSetErrorHandler) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSetErrorHandler"); + _glfw.x11.xlib.SetICFocus = (PFN_XSetICFocus) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSetICFocus"); + _glfw.x11.xlib.SetIMValues = (PFN_XSetIMValues) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSetIMValues"); + _glfw.x11.xlib.SetInputFocus = (PFN_XSetInputFocus) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSetInputFocus"); + _glfw.x11.xlib.SetLocaleModifiers = (PFN_XSetLocaleModifiers) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSetLocaleModifiers"); + _glfw.x11.xlib.SetScreenSaver = (PFN_XSetScreenSaver) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSetScreenSaver"); + _glfw.x11.xlib.SetSelectionOwner = (PFN_XSetSelectionOwner) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSetSelectionOwner"); + _glfw.x11.xlib.SetWMHints = (PFN_XSetWMHints) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSetWMHints"); + _glfw.x11.xlib.SetWMNormalHints = (PFN_XSetWMNormalHints) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSetWMNormalHints"); + _glfw.x11.xlib.SetWMProtocols = (PFN_XSetWMProtocols) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSetWMProtocols"); + _glfw.x11.xlib.SupportsLocale = (PFN_XSupportsLocale) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSupportsLocale"); + _glfw.x11.xlib.Sync = (PFN_XSync) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XSync"); + _glfw.x11.xlib.TranslateCoordinates = (PFN_XTranslateCoordinates) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XTranslateCoordinates"); + _glfw.x11.xlib.UndefineCursor = (PFN_XUndefineCursor) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XUndefineCursor"); + _glfw.x11.xlib.UngrabPointer = (PFN_XUngrabPointer) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XUngrabPointer"); + _glfw.x11.xlib.UnmapWindow = (PFN_XUnmapWindow) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XUnmapWindow"); + _glfw.x11.xlib.UnsetICFocus = (PFN_XUnsetICFocus) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XUnsetICFocus"); + _glfw.x11.xlib.VisualIDFromVisual = (PFN_XVisualIDFromVisual) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XVisualIDFromVisual"); + _glfw.x11.xlib.WarpPointer = (PFN_XWarpPointer) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XWarpPointer"); + _glfw.x11.xkb.FreeKeyboard = (PFN_XkbFreeKeyboard) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XkbFreeKeyboard"); + _glfw.x11.xkb.FreeNames = (PFN_XkbFreeNames) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XkbFreeNames"); + _glfw.x11.xkb.GetMap = (PFN_XkbGetMap) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XkbGetMap"); + _glfw.x11.xkb.GetNames = (PFN_XkbGetNames) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XkbGetNames"); + _glfw.x11.xkb.GetState = (PFN_XkbGetState) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XkbGetState"); + _glfw.x11.xkb.KeycodeToKeysym = (PFN_XkbKeycodeToKeysym) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XkbKeycodeToKeysym"); + _glfw.x11.xkb.QueryExtension = (PFN_XkbQueryExtension) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XkbQueryExtension"); + _glfw.x11.xkb.SelectEventDetails = (PFN_XkbSelectEventDetails) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XkbSelectEventDetails"); + _glfw.x11.xkb.SetDetectableAutoRepeat = (PFN_XkbSetDetectableAutoRepeat) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XkbSetDetectableAutoRepeat"); + _glfw.x11.xrm.DestroyDatabase = (PFN_XrmDestroyDatabase) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XrmDestroyDatabase"); + _glfw.x11.xrm.GetResource = (PFN_XrmGetResource) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XrmGetResource"); + _glfw.x11.xrm.GetStringDatabase = (PFN_XrmGetStringDatabase) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XrmGetStringDatabase"); + _glfw.x11.xrm.UniqueQuark = (PFN_XrmUniqueQuark) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XrmUniqueQuark"); + _glfw.x11.xlib.UnregisterIMInstantiateCallback = (PFN_XUnregisterIMInstantiateCallback) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XUnregisterIMInstantiateCallback"); + _glfw.x11.xlib.utf8LookupString = (PFN_Xutf8LookupString) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "Xutf8LookupString"); + _glfw.x11.xlib.utf8SetWMProperties = (PFN_Xutf8SetWMProperties) + _glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "Xutf8SetWMProperties"); + + if (_glfw.x11.xlib.utf8LookupString && _glfw.x11.xlib.utf8SetWMProperties) + _glfw.x11.xlib.utf8 = GLFW_TRUE; + _glfw.x11.screen = DefaultScreen(_glfw.x11.display); _glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen); _glfw.x11.context = XUniqueContext(); @@ -1135,33 +1536,22 @@ int _glfwPlatformInit(void) _glfw.x11.helperWindowHandle = createHelperWindow(); _glfw.x11.hiddenCursorHandle = createHiddenCursor(); - if (XSupportsLocale()) + if (XSupportsLocale() && _glfw.x11.xlib.utf8) { XSetLocaleModifiers(""); - _glfw.x11.im = XOpenIM(_glfw.x11.display, 0, NULL, NULL); - if (_glfw.x11.im) - { - if (!hasUsableInputMethodStyle()) - { - XCloseIM(_glfw.x11.im); - _glfw.x11.im = NULL; - } - } + // If an IM is already present our callback will be called right away + XRegisterIMInstantiateCallback(_glfw.x11.display, + NULL, NULL, NULL, + inputMethodInstantiateCallback, + NULL); } -#if defined(__linux__) - if (!_glfwInitJoysticksLinux()) - return GLFW_FALSE; -#endif - - _glfwInitTimerPOSIX(); - _glfwPollMonitorsX11(); return GLFW_TRUE; } -void _glfwPlatformTerminate(void) +void _glfwTerminateX11(void) { if (_glfw.x11.helperWindowHandle) { @@ -1181,8 +1571,13 @@ void _glfwPlatformTerminate(void) _glfw.x11.hiddenCursorHandle = (Cursor) 0; } - free(_glfw.x11.primarySelectionString); - free(_glfw.x11.clipboardString); + _glfw_free(_glfw.x11.primarySelectionString); + _glfw_free(_glfw.x11.clipboardString); + + XUnregisterIMInstantiateCallback(_glfw.x11.display, + NULL, NULL, NULL, + inputMethodInstantiateCallback, + NULL); if (_glfw.x11.im) { @@ -1198,43 +1593,43 @@ void _glfwPlatformTerminate(void) if (_glfw.x11.x11xcb.handle) { - _glfw_dlclose(_glfw.x11.x11xcb.handle); + _glfwPlatformFreeModule(_glfw.x11.x11xcb.handle); _glfw.x11.x11xcb.handle = NULL; } if (_glfw.x11.xcursor.handle) { - _glfw_dlclose(_glfw.x11.xcursor.handle); + _glfwPlatformFreeModule(_glfw.x11.xcursor.handle); _glfw.x11.xcursor.handle = NULL; } if (_glfw.x11.randr.handle) { - _glfw_dlclose(_glfw.x11.randr.handle); + _glfwPlatformFreeModule(_glfw.x11.randr.handle); _glfw.x11.randr.handle = NULL; } if (_glfw.x11.xinerama.handle) { - _glfw_dlclose(_glfw.x11.xinerama.handle); + _glfwPlatformFreeModule(_glfw.x11.xinerama.handle); _glfw.x11.xinerama.handle = NULL; } if (_glfw.x11.xrender.handle) { - _glfw_dlclose(_glfw.x11.xrender.handle); + _glfwPlatformFreeModule(_glfw.x11.xrender.handle); _glfw.x11.xrender.handle = NULL; } if (_glfw.x11.vidmode.handle) { - _glfw_dlclose(_glfw.x11.vidmode.handle); + _glfwPlatformFreeModule(_glfw.x11.vidmode.handle); _glfw.x11.vidmode.handle = NULL; } if (_glfw.x11.xi.handle) { - _glfw_dlclose(_glfw.x11.xi.handle); + _glfwPlatformFreeModule(_glfw.x11.xi.handle); _glfw.x11.xi.handle = NULL; } @@ -1244,9 +1639,11 @@ void _glfwPlatformTerminate(void) _glfwTerminateEGL(); _glfwTerminateGLX(); -#if defined(__linux__) - _glfwTerminateJoysticksLinux(); -#endif + if (_glfw.x11.xlib.handle) + { + _glfwPlatformFreeModule(_glfw.x11.xlib.handle); + _glfw.x11.xlib.handle = NULL; + } if (_glfw.x11.emptyEventPipe[0] || _glfw.x11.emptyEventPipe[1]) { @@ -1255,20 +1652,5 @@ void _glfwPlatformTerminate(void) } } -const char* _glfwPlatformGetVersionString(void) -{ - return _GLFW_VERSION_NUMBER " X11 GLX EGL OSMesa" -#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) - " clock_gettime" -#else - " gettimeofday" -#endif -#if defined(__linux__) - " evdev" -#endif -#if defined(_GLFW_BUILD_DLL) - " shared" -#endif - ; -} +#endif // _GLFW_X11 diff --git a/src/lib/src/vendor/glfw-3.3.8/src/x11_monitor.c b/src/lib/src/vendor/glfw-3.4/src/x11_monitor.c similarity index 91% rename from src/lib/src/vendor/glfw-3.3.8/src/x11_monitor.c rename to src/lib/src/vendor/glfw-3.4/src/x11_monitor.c index fb3a67b..38af7e0 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/x11_monitor.c +++ b/src/lib/src/vendor/glfw-3.4/src/x11_monitor.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 X11 - www.glfw.org +// GLFW 3.4 X11 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -24,11 +24,11 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_X11) + #include #include #include @@ -116,7 +116,7 @@ void _glfwPollMonitorsX11(void) disconnectedCount = _glfw.monitorCount; if (disconnectedCount) { - disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*)); + disconnected = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*)); memcpy(disconnected, _glfw.monitors, _glfw.monitorCount * sizeof(_GLFWmonitor*)); @@ -209,7 +209,7 @@ void _glfwPollMonitorsX11(void) _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0); } - free(disconnected); + _glfw_free(disconnected); } else { @@ -232,7 +232,7 @@ void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired) RRMode native = None; const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired); - _glfwPlatformGetVideoMode(monitor, ¤t); + _glfwGetVideoModeX11(monitor, ¤t); if (_glfwCompareVideoModes(¤t, best) == 0) return; @@ -310,11 +310,11 @@ void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor) ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) +void _glfwFreeMonitorX11(_GLFWmonitor* monitor) { } -void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +void _glfwGetMonitorPosX11(_GLFWmonitor* monitor, int* xpos, int* ypos) { if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) { @@ -336,8 +336,8 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) } } -void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, - float* xscale, float* yscale) +void _glfwGetMonitorContentScaleX11(_GLFWmonitor* monitor, + float* xscale, float* yscale) { if (xscale) *xscale = _glfw.x11.contentScaleX; @@ -345,7 +345,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, *yscale = _glfw.x11.contentScaleY; } -void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height) +void _glfwGetMonitorWorkareaX11(_GLFWmonitor* monitor, + int* xpos, int* ypos, + int* width, int* height) { int areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0; @@ -437,7 +439,7 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos *height = areaHeight; } -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) +GLFWvidmode* _glfwGetVideoModesX11(_GLFWmonitor* monitor, int* count) { GLFWvidmode* result; @@ -450,7 +452,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output); - result = calloc(oi->nmode, sizeof(GLFWvidmode)); + result = _glfw_calloc(oi->nmode, sizeof(GLFWvidmode)); for (int i = 0; i < oi->nmode; i++) { @@ -482,31 +484,38 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) else { *count = 1; - result = calloc(1, sizeof(GLFWvidmode)); - _glfwPlatformGetVideoMode(monitor, result); + result = _glfw_calloc(1, sizeof(GLFWvidmode)); + _glfwGetVideoModeX11(monitor, result); } return result; } -void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) +GLFWbool _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode) { if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) { XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); - XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); + const XRRModeInfo* mi = NULL; + XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); if (ci) { - const XRRModeInfo* mi = getModeInfo(sr, ci->mode); - if (mi) // mi can be NULL if the monitor has been disconnected + mi = getModeInfo(sr, ci->mode); + if (mi) *mode = vidmodeFromModeInfo(mi, ci); XRRFreeCrtcInfo(ci); } XRRFreeScreenResources(sr); + + if (!mi) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to query video mode"); + return GLFW_FALSE; + } } else { @@ -517,9 +526,11 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) _glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen), &mode->redBits, &mode->greenBits, &mode->blueBits); } + + return GLFW_TRUE; } -GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwGetGammaRampX11(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) { @@ -557,7 +568,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) } } -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +void _glfwSetGammaRampX11(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) { if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) { @@ -602,6 +613,13 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(None); + + if (_glfw.platform.platformID != GLFW_PLATFORM_X11) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized"); + return None; + } + return monitor->x11.crtc; } @@ -609,6 +627,15 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(None); + + if (_glfw.platform.platformID != GLFW_PLATFORM_X11) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized"); + return None; + } + return monitor->x11.output; } +#endif // _GLFW_X11 + diff --git a/src/lib/src/vendor/glfw-3.4/src/x11_platform.h b/src/lib/src/vendor/glfw-3.4/src/x11_platform.h new file mode 100644 index 0000000..14e363d --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/src/x11_platform.h @@ -0,0 +1,1004 @@ +//======================================================================== +// GLFW 3.4 X11 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2019 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include +#include +#include + +#include +#include +#include +#include +#include + +// The XRandR extension provides mode setting and gamma control +#include + +// The Xkb extension provides improved keyboard support +#include + +// The Xinerama extension provides legacy monitor indices +#include + +// The XInput extension provides raw mouse motion input +#include + +// The Shape extension provides custom window shapes +#include + +#define GLX_VENDOR 1 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_DOUBLEBUFFER 5 +#define GLX_STEREO 6 +#define GLX_AUX_BUFFERS 7 +#define GLX_RED_SIZE 8 +#define GLX_GREEN_SIZE 9 +#define GLX_BLUE_SIZE 10 +#define GLX_ALPHA_SIZE 11 +#define GLX_DEPTH_SIZE 12 +#define GLX_STENCIL_SIZE 13 +#define GLX_ACCUM_RED_SIZE 14 +#define GLX_ACCUM_GREEN_SIZE 15 +#define GLX_ACCUM_BLUE_SIZE 16 +#define GLX_ACCUM_ALPHA_SIZE 17 +#define GLX_SAMPLES 0x186a1 +#define GLX_VISUAL_ID 0x800b + +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20b2 +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 +#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 +#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3 + +typedef XID GLXWindow; +typedef XID GLXDrawable; +typedef struct __GLXFBConfig* GLXFBConfig; +typedef struct __GLXcontext* GLXContext; +typedef void (*__GLXextproc)(void); + +typedef XClassHint* (* PFN_XAllocClassHint)(void); +typedef XSizeHints* (* PFN_XAllocSizeHints)(void); +typedef XWMHints* (* PFN_XAllocWMHints)(void); +typedef int (* PFN_XChangeProperty)(Display*,Window,Atom,Atom,int,int,const unsigned char*,int); +typedef int (* PFN_XChangeWindowAttributes)(Display*,Window,unsigned long,XSetWindowAttributes*); +typedef Bool (* PFN_XCheckIfEvent)(Display*,XEvent*,Bool(*)(Display*,XEvent*,XPointer),XPointer); +typedef Bool (* PFN_XCheckTypedWindowEvent)(Display*,Window,int,XEvent*); +typedef int (* PFN_XCloseDisplay)(Display*); +typedef Status (* PFN_XCloseIM)(XIM); +typedef int (* PFN_XConvertSelection)(Display*,Atom,Atom,Atom,Window,Time); +typedef Colormap (* PFN_XCreateColormap)(Display*,Window,Visual*,int); +typedef Cursor (* PFN_XCreateFontCursor)(Display*,unsigned int); +typedef XIC (* PFN_XCreateIC)(XIM,...); +typedef Region (* PFN_XCreateRegion)(void); +typedef Window (* PFN_XCreateWindow)(Display*,Window,int,int,unsigned int,unsigned int,unsigned int,int,unsigned int,Visual*,unsigned long,XSetWindowAttributes*); +typedef int (* PFN_XDefineCursor)(Display*,Window,Cursor); +typedef int (* PFN_XDeleteContext)(Display*,XID,XContext); +typedef int (* PFN_XDeleteProperty)(Display*,Window,Atom); +typedef void (* PFN_XDestroyIC)(XIC); +typedef int (* PFN_XDestroyRegion)(Region); +typedef int (* PFN_XDestroyWindow)(Display*,Window); +typedef int (* PFN_XDisplayKeycodes)(Display*,int*,int*); +typedef int (* PFN_XEventsQueued)(Display*,int); +typedef Bool (* PFN_XFilterEvent)(XEvent*,Window); +typedef int (* PFN_XFindContext)(Display*,XID,XContext,XPointer*); +typedef int (* PFN_XFlush)(Display*); +typedef int (* PFN_XFree)(void*); +typedef int (* PFN_XFreeColormap)(Display*,Colormap); +typedef int (* PFN_XFreeCursor)(Display*,Cursor); +typedef void (* PFN_XFreeEventData)(Display*,XGenericEventCookie*); +typedef int (* PFN_XGetErrorText)(Display*,int,char*,int); +typedef Bool (* PFN_XGetEventData)(Display*,XGenericEventCookie*); +typedef char* (* PFN_XGetICValues)(XIC,...); +typedef char* (* PFN_XGetIMValues)(XIM,...); +typedef int (* PFN_XGetInputFocus)(Display*,Window*,int*); +typedef KeySym* (* PFN_XGetKeyboardMapping)(Display*,KeyCode,int,int*); +typedef int (* PFN_XGetScreenSaver)(Display*,int*,int*,int*,int*); +typedef Window (* PFN_XGetSelectionOwner)(Display*,Atom); +typedef XVisualInfo* (* PFN_XGetVisualInfo)(Display*,long,XVisualInfo*,int*); +typedef Status (* PFN_XGetWMNormalHints)(Display*,Window,XSizeHints*,long*); +typedef Status (* PFN_XGetWindowAttributes)(Display*,Window,XWindowAttributes*); +typedef int (* PFN_XGetWindowProperty)(Display*,Window,Atom,long,long,Bool,Atom,Atom*,int*,unsigned long*,unsigned long*,unsigned char**); +typedef int (* PFN_XGrabPointer)(Display*,Window,Bool,unsigned int,int,int,Window,Cursor,Time); +typedef Status (* PFN_XIconifyWindow)(Display*,Window,int); +typedef Status (* PFN_XInitThreads)(void); +typedef Atom (* PFN_XInternAtom)(Display*,const char*,Bool); +typedef int (* PFN_XLookupString)(XKeyEvent*,char*,int,KeySym*,XComposeStatus*); +typedef int (* PFN_XMapRaised)(Display*,Window); +typedef int (* PFN_XMapWindow)(Display*,Window); +typedef int (* PFN_XMoveResizeWindow)(Display*,Window,int,int,unsigned int,unsigned int); +typedef int (* PFN_XMoveWindow)(Display*,Window,int,int); +typedef int (* PFN_XNextEvent)(Display*,XEvent*); +typedef Display* (* PFN_XOpenDisplay)(const char*); +typedef XIM (* PFN_XOpenIM)(Display*,XrmDatabase*,char*,char*); +typedef int (* PFN_XPeekEvent)(Display*,XEvent*); +typedef int (* PFN_XPending)(Display*); +typedef Bool (* PFN_XQueryExtension)(Display*,const char*,int*,int*,int*); +typedef Bool (* PFN_XQueryPointer)(Display*,Window,Window*,Window*,int*,int*,int*,int*,unsigned int*); +typedef int (* PFN_XRaiseWindow)(Display*,Window); +typedef Bool (* PFN_XRegisterIMInstantiateCallback)(Display*,void*,char*,char*,XIDProc,XPointer); +typedef int (* PFN_XResizeWindow)(Display*,Window,unsigned int,unsigned int); +typedef char* (* PFN_XResourceManagerString)(Display*); +typedef int (* PFN_XSaveContext)(Display*,XID,XContext,const char*); +typedef int (* PFN_XSelectInput)(Display*,Window,long); +typedef Status (* PFN_XSendEvent)(Display*,Window,Bool,long,XEvent*); +typedef int (* PFN_XSetClassHint)(Display*,Window,XClassHint*); +typedef XErrorHandler (* PFN_XSetErrorHandler)(XErrorHandler); +typedef void (* PFN_XSetICFocus)(XIC); +typedef char* (* PFN_XSetIMValues)(XIM,...); +typedef int (* PFN_XSetInputFocus)(Display*,Window,int,Time); +typedef char* (* PFN_XSetLocaleModifiers)(const char*); +typedef int (* PFN_XSetScreenSaver)(Display*,int,int,int,int); +typedef int (* PFN_XSetSelectionOwner)(Display*,Atom,Window,Time); +typedef int (* PFN_XSetWMHints)(Display*,Window,XWMHints*); +typedef void (* PFN_XSetWMNormalHints)(Display*,Window,XSizeHints*); +typedef Status (* PFN_XSetWMProtocols)(Display*,Window,Atom*,int); +typedef Bool (* PFN_XSupportsLocale)(void); +typedef int (* PFN_XSync)(Display*,Bool); +typedef Bool (* PFN_XTranslateCoordinates)(Display*,Window,Window,int,int,int*,int*,Window*); +typedef int (* PFN_XUndefineCursor)(Display*,Window); +typedef int (* PFN_XUngrabPointer)(Display*,Time); +typedef int (* PFN_XUnmapWindow)(Display*,Window); +typedef void (* PFN_XUnsetICFocus)(XIC); +typedef VisualID (* PFN_XVisualIDFromVisual)(Visual*); +typedef int (* PFN_XWarpPointer)(Display*,Window,Window,int,int,unsigned int,unsigned int,int,int); +typedef void (* PFN_XkbFreeKeyboard)(XkbDescPtr,unsigned int,Bool); +typedef void (* PFN_XkbFreeNames)(XkbDescPtr,unsigned int,Bool); +typedef XkbDescPtr (* PFN_XkbGetMap)(Display*,unsigned int,unsigned int); +typedef Status (* PFN_XkbGetNames)(Display*,unsigned int,XkbDescPtr); +typedef Status (* PFN_XkbGetState)(Display*,unsigned int,XkbStatePtr); +typedef KeySym (* PFN_XkbKeycodeToKeysym)(Display*,KeyCode,int,int); +typedef Bool (* PFN_XkbQueryExtension)(Display*,int*,int*,int*,int*,int*); +typedef Bool (* PFN_XkbSelectEventDetails)(Display*,unsigned int,unsigned int,unsigned long,unsigned long); +typedef Bool (* PFN_XkbSetDetectableAutoRepeat)(Display*,Bool,Bool*); +typedef void (* PFN_XrmDestroyDatabase)(XrmDatabase); +typedef Bool (* PFN_XrmGetResource)(XrmDatabase,const char*,const char*,char**,XrmValue*); +typedef XrmDatabase (* PFN_XrmGetStringDatabase)(const char*); +typedef void (* PFN_XrmInitialize)(void); +typedef XrmQuark (* PFN_XrmUniqueQuark)(void); +typedef Bool (* PFN_XUnregisterIMInstantiateCallback)(Display*,void*,char*,char*,XIDProc,XPointer); +typedef int (* PFN_Xutf8LookupString)(XIC,XKeyPressedEvent*,char*,int,KeySym*,Status*); +typedef void (* PFN_Xutf8SetWMProperties)(Display*,Window,const char*,const char*,char**,int,XSizeHints*,XWMHints*,XClassHint*); +#define XAllocClassHint _glfw.x11.xlib.AllocClassHint +#define XAllocSizeHints _glfw.x11.xlib.AllocSizeHints +#define XAllocWMHints _glfw.x11.xlib.AllocWMHints +#define XChangeProperty _glfw.x11.xlib.ChangeProperty +#define XChangeWindowAttributes _glfw.x11.xlib.ChangeWindowAttributes +#define XCheckIfEvent _glfw.x11.xlib.CheckIfEvent +#define XCheckTypedWindowEvent _glfw.x11.xlib.CheckTypedWindowEvent +#define XCloseDisplay _glfw.x11.xlib.CloseDisplay +#define XCloseIM _glfw.x11.xlib.CloseIM +#define XConvertSelection _glfw.x11.xlib.ConvertSelection +#define XCreateColormap _glfw.x11.xlib.CreateColormap +#define XCreateFontCursor _glfw.x11.xlib.CreateFontCursor +#define XCreateIC _glfw.x11.xlib.CreateIC +#define XCreateRegion _glfw.x11.xlib.CreateRegion +#define XCreateWindow _glfw.x11.xlib.CreateWindow +#define XDefineCursor _glfw.x11.xlib.DefineCursor +#define XDeleteContext _glfw.x11.xlib.DeleteContext +#define XDeleteProperty _glfw.x11.xlib.DeleteProperty +#define XDestroyIC _glfw.x11.xlib.DestroyIC +#define XDestroyRegion _glfw.x11.xlib.DestroyRegion +#define XDestroyWindow _glfw.x11.xlib.DestroyWindow +#define XDisplayKeycodes _glfw.x11.xlib.DisplayKeycodes +#define XEventsQueued _glfw.x11.xlib.EventsQueued +#define XFilterEvent _glfw.x11.xlib.FilterEvent +#define XFindContext _glfw.x11.xlib.FindContext +#define XFlush _glfw.x11.xlib.Flush +#define XFree _glfw.x11.xlib.Free +#define XFreeColormap _glfw.x11.xlib.FreeColormap +#define XFreeCursor _glfw.x11.xlib.FreeCursor +#define XFreeEventData _glfw.x11.xlib.FreeEventData +#define XGetErrorText _glfw.x11.xlib.GetErrorText +#define XGetEventData _glfw.x11.xlib.GetEventData +#define XGetICValues _glfw.x11.xlib.GetICValues +#define XGetIMValues _glfw.x11.xlib.GetIMValues +#define XGetInputFocus _glfw.x11.xlib.GetInputFocus +#define XGetKeyboardMapping _glfw.x11.xlib.GetKeyboardMapping +#define XGetScreenSaver _glfw.x11.xlib.GetScreenSaver +#define XGetSelectionOwner _glfw.x11.xlib.GetSelectionOwner +#define XGetVisualInfo _glfw.x11.xlib.GetVisualInfo +#define XGetWMNormalHints _glfw.x11.xlib.GetWMNormalHints +#define XGetWindowAttributes _glfw.x11.xlib.GetWindowAttributes +#define XGetWindowProperty _glfw.x11.xlib.GetWindowProperty +#define XGrabPointer _glfw.x11.xlib.GrabPointer +#define XIconifyWindow _glfw.x11.xlib.IconifyWindow +#define XInternAtom _glfw.x11.xlib.InternAtom +#define XLookupString _glfw.x11.xlib.LookupString +#define XMapRaised _glfw.x11.xlib.MapRaised +#define XMapWindow _glfw.x11.xlib.MapWindow +#define XMoveResizeWindow _glfw.x11.xlib.MoveResizeWindow +#define XMoveWindow _glfw.x11.xlib.MoveWindow +#define XNextEvent _glfw.x11.xlib.NextEvent +#define XOpenIM _glfw.x11.xlib.OpenIM +#define XPeekEvent _glfw.x11.xlib.PeekEvent +#define XPending _glfw.x11.xlib.Pending +#define XQueryExtension _glfw.x11.xlib.QueryExtension +#define XQueryPointer _glfw.x11.xlib.QueryPointer +#define XRaiseWindow _glfw.x11.xlib.RaiseWindow +#define XRegisterIMInstantiateCallback _glfw.x11.xlib.RegisterIMInstantiateCallback +#define XResizeWindow _glfw.x11.xlib.ResizeWindow +#define XResourceManagerString _glfw.x11.xlib.ResourceManagerString +#define XSaveContext _glfw.x11.xlib.SaveContext +#define XSelectInput _glfw.x11.xlib.SelectInput +#define XSendEvent _glfw.x11.xlib.SendEvent +#define XSetClassHint _glfw.x11.xlib.SetClassHint +#define XSetErrorHandler _glfw.x11.xlib.SetErrorHandler +#define XSetICFocus _glfw.x11.xlib.SetICFocus +#define XSetIMValues _glfw.x11.xlib.SetIMValues +#define XSetInputFocus _glfw.x11.xlib.SetInputFocus +#define XSetLocaleModifiers _glfw.x11.xlib.SetLocaleModifiers +#define XSetScreenSaver _glfw.x11.xlib.SetScreenSaver +#define XSetSelectionOwner _glfw.x11.xlib.SetSelectionOwner +#define XSetWMHints _glfw.x11.xlib.SetWMHints +#define XSetWMNormalHints _glfw.x11.xlib.SetWMNormalHints +#define XSetWMProtocols _glfw.x11.xlib.SetWMProtocols +#define XSupportsLocale _glfw.x11.xlib.SupportsLocale +#define XSync _glfw.x11.xlib.Sync +#define XTranslateCoordinates _glfw.x11.xlib.TranslateCoordinates +#define XUndefineCursor _glfw.x11.xlib.UndefineCursor +#define XUngrabPointer _glfw.x11.xlib.UngrabPointer +#define XUnmapWindow _glfw.x11.xlib.UnmapWindow +#define XUnsetICFocus _glfw.x11.xlib.UnsetICFocus +#define XVisualIDFromVisual _glfw.x11.xlib.VisualIDFromVisual +#define XWarpPointer _glfw.x11.xlib.WarpPointer +#define XkbFreeKeyboard _glfw.x11.xkb.FreeKeyboard +#define XkbFreeNames _glfw.x11.xkb.FreeNames +#define XkbGetMap _glfw.x11.xkb.GetMap +#define XkbGetNames _glfw.x11.xkb.GetNames +#define XkbGetState _glfw.x11.xkb.GetState +#define XkbKeycodeToKeysym _glfw.x11.xkb.KeycodeToKeysym +#define XkbQueryExtension _glfw.x11.xkb.QueryExtension +#define XkbSelectEventDetails _glfw.x11.xkb.SelectEventDetails +#define XkbSetDetectableAutoRepeat _glfw.x11.xkb.SetDetectableAutoRepeat +#define XrmDestroyDatabase _glfw.x11.xrm.DestroyDatabase +#define XrmGetResource _glfw.x11.xrm.GetResource +#define XrmGetStringDatabase _glfw.x11.xrm.GetStringDatabase +#define XrmUniqueQuark _glfw.x11.xrm.UniqueQuark +#define XUnregisterIMInstantiateCallback _glfw.x11.xlib.UnregisterIMInstantiateCallback +#define Xutf8LookupString _glfw.x11.xlib.utf8LookupString +#define Xutf8SetWMProperties _glfw.x11.xlib.utf8SetWMProperties + +typedef XRRCrtcGamma* (* PFN_XRRAllocGamma)(int); +typedef void (* PFN_XRRFreeCrtcInfo)(XRRCrtcInfo*); +typedef void (* PFN_XRRFreeGamma)(XRRCrtcGamma*); +typedef void (* PFN_XRRFreeOutputInfo)(XRROutputInfo*); +typedef void (* PFN_XRRFreeScreenResources)(XRRScreenResources*); +typedef XRRCrtcGamma* (* PFN_XRRGetCrtcGamma)(Display*,RRCrtc); +typedef int (* PFN_XRRGetCrtcGammaSize)(Display*,RRCrtc); +typedef XRRCrtcInfo* (* PFN_XRRGetCrtcInfo) (Display*,XRRScreenResources*,RRCrtc); +typedef XRROutputInfo* (* PFN_XRRGetOutputInfo)(Display*,XRRScreenResources*,RROutput); +typedef RROutput (* PFN_XRRGetOutputPrimary)(Display*,Window); +typedef XRRScreenResources* (* PFN_XRRGetScreenResourcesCurrent)(Display*,Window); +typedef Bool (* PFN_XRRQueryExtension)(Display*,int*,int*); +typedef Status (* PFN_XRRQueryVersion)(Display*,int*,int*); +typedef void (* PFN_XRRSelectInput)(Display*,Window,int); +typedef Status (* PFN_XRRSetCrtcConfig)(Display*,XRRScreenResources*,RRCrtc,Time,int,int,RRMode,Rotation,RROutput*,int); +typedef void (* PFN_XRRSetCrtcGamma)(Display*,RRCrtc,XRRCrtcGamma*); +typedef int (* PFN_XRRUpdateConfiguration)(XEvent*); +#define XRRAllocGamma _glfw.x11.randr.AllocGamma +#define XRRFreeCrtcInfo _glfw.x11.randr.FreeCrtcInfo +#define XRRFreeGamma _glfw.x11.randr.FreeGamma +#define XRRFreeOutputInfo _glfw.x11.randr.FreeOutputInfo +#define XRRFreeScreenResources _glfw.x11.randr.FreeScreenResources +#define XRRGetCrtcGamma _glfw.x11.randr.GetCrtcGamma +#define XRRGetCrtcGammaSize _glfw.x11.randr.GetCrtcGammaSize +#define XRRGetCrtcInfo _glfw.x11.randr.GetCrtcInfo +#define XRRGetOutputInfo _glfw.x11.randr.GetOutputInfo +#define XRRGetOutputPrimary _glfw.x11.randr.GetOutputPrimary +#define XRRGetScreenResourcesCurrent _glfw.x11.randr.GetScreenResourcesCurrent +#define XRRQueryExtension _glfw.x11.randr.QueryExtension +#define XRRQueryVersion _glfw.x11.randr.QueryVersion +#define XRRSelectInput _glfw.x11.randr.SelectInput +#define XRRSetCrtcConfig _glfw.x11.randr.SetCrtcConfig +#define XRRSetCrtcGamma _glfw.x11.randr.SetCrtcGamma +#define XRRUpdateConfiguration _glfw.x11.randr.UpdateConfiguration + +typedef XcursorImage* (* PFN_XcursorImageCreate)(int,int); +typedef void (* PFN_XcursorImageDestroy)(XcursorImage*); +typedef Cursor (* PFN_XcursorImageLoadCursor)(Display*,const XcursorImage*); +typedef char* (* PFN_XcursorGetTheme)(Display*); +typedef int (* PFN_XcursorGetDefaultSize)(Display*); +typedef XcursorImage* (* PFN_XcursorLibraryLoadImage)(const char*,const char*,int); +#define XcursorImageCreate _glfw.x11.xcursor.ImageCreate +#define XcursorImageDestroy _glfw.x11.xcursor.ImageDestroy +#define XcursorImageLoadCursor _glfw.x11.xcursor.ImageLoadCursor +#define XcursorGetTheme _glfw.x11.xcursor.GetTheme +#define XcursorGetDefaultSize _glfw.x11.xcursor.GetDefaultSize +#define XcursorLibraryLoadImage _glfw.x11.xcursor.LibraryLoadImage + +typedef Bool (* PFN_XineramaIsActive)(Display*); +typedef Bool (* PFN_XineramaQueryExtension)(Display*,int*,int*); +typedef XineramaScreenInfo* (* PFN_XineramaQueryScreens)(Display*,int*); +#define XineramaIsActive _glfw.x11.xinerama.IsActive +#define XineramaQueryExtension _glfw.x11.xinerama.QueryExtension +#define XineramaQueryScreens _glfw.x11.xinerama.QueryScreens + +typedef XID xcb_window_t; +typedef XID xcb_visualid_t; +typedef struct xcb_connection_t xcb_connection_t; +typedef xcb_connection_t* (* PFN_XGetXCBConnection)(Display*); +#define XGetXCBConnection _glfw.x11.x11xcb.GetXCBConnection + +typedef Bool (* PFN_XF86VidModeQueryExtension)(Display*,int*,int*); +typedef Bool (* PFN_XF86VidModeGetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*); +typedef Bool (* PFN_XF86VidModeSetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*); +typedef Bool (* PFN_XF86VidModeGetGammaRampSize)(Display*,int,int*); +#define XF86VidModeQueryExtension _glfw.x11.vidmode.QueryExtension +#define XF86VidModeGetGammaRamp _glfw.x11.vidmode.GetGammaRamp +#define XF86VidModeSetGammaRamp _glfw.x11.vidmode.SetGammaRamp +#define XF86VidModeGetGammaRampSize _glfw.x11.vidmode.GetGammaRampSize + +typedef Status (* PFN_XIQueryVersion)(Display*,int*,int*); +typedef int (* PFN_XISelectEvents)(Display*,Window,XIEventMask*,int); +#define XIQueryVersion _glfw.x11.xi.QueryVersion +#define XISelectEvents _glfw.x11.xi.SelectEvents + +typedef Bool (* PFN_XRenderQueryExtension)(Display*,int*,int*); +typedef Status (* PFN_XRenderQueryVersion)(Display*dpy,int*,int*); +typedef XRenderPictFormat* (* PFN_XRenderFindVisualFormat)(Display*,Visual const*); +#define XRenderQueryExtension _glfw.x11.xrender.QueryExtension +#define XRenderQueryVersion _glfw.x11.xrender.QueryVersion +#define XRenderFindVisualFormat _glfw.x11.xrender.FindVisualFormat + +typedef Bool (* PFN_XShapeQueryExtension)(Display*,int*,int*); +typedef Status (* PFN_XShapeQueryVersion)(Display*dpy,int*,int*); +typedef void (* PFN_XShapeCombineRegion)(Display*,Window,int,int,int,Region,int); +typedef void (* PFN_XShapeCombineMask)(Display*,Window,int,int,int,Pixmap,int); + +#define XShapeQueryExtension _glfw.x11.xshape.QueryExtension +#define XShapeQueryVersion _glfw.x11.xshape.QueryVersion +#define XShapeCombineRegion _glfw.x11.xshape.ShapeCombineRegion +#define XShapeCombineMask _glfw.x11.xshape.ShapeCombineMask + +typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*); +typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int); +typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*); +typedef Bool (*PFNGLXQUERYVERSIONPROC)(Display*,int*,int*); +typedef void (*PFNGLXDESTROYCONTEXTPROC)(Display*,GLXContext); +typedef Bool (*PFNGLXMAKECURRENTPROC)(Display*,GLXDrawable,GLXContext); +typedef void (*PFNGLXSWAPBUFFERSPROC)(Display*,GLXDrawable); +typedef const char* (*PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display*,int); +typedef GLXFBConfig* (*PFNGLXGETFBCONFIGSPROC)(Display*,int,int*); +typedef GLXContext (*PFNGLXCREATENEWCONTEXTPROC)(Display*,GLXFBConfig,int,GLXContext,Bool); +typedef __GLXextproc (* PFNGLXGETPROCADDRESSPROC)(const GLubyte *procName); +typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int); +typedef XVisualInfo* (*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display*,GLXFBConfig); +typedef GLXWindow (*PFNGLXCREATEWINDOWPROC)(Display*,GLXFBConfig,Window,const int*); +typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow); + +typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int); +typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int); +typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLXContext,Bool,const int*); + +// libGL.so function pointer typedefs +#define glXGetFBConfigs _glfw.glx.GetFBConfigs +#define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib +#define glXGetClientString _glfw.glx.GetClientString +#define glXQueryExtension _glfw.glx.QueryExtension +#define glXQueryVersion _glfw.glx.QueryVersion +#define glXDestroyContext _glfw.glx.DestroyContext +#define glXMakeCurrent _glfw.glx.MakeCurrent +#define glXSwapBuffers _glfw.glx.SwapBuffers +#define glXQueryExtensionsString _glfw.glx.QueryExtensionsString +#define glXCreateNewContext _glfw.glx.CreateNewContext +#define glXGetVisualFromFBConfig _glfw.glx.GetVisualFromFBConfig +#define glXCreateWindow _glfw.glx.CreateWindow +#define glXDestroyWindow _glfw.glx.DestroyWindow + +typedef VkFlags VkXlibSurfaceCreateFlagsKHR; +typedef VkFlags VkXcbSurfaceCreateFlagsKHR; + +typedef struct VkXlibSurfaceCreateInfoKHR +{ + VkStructureType sType; + const void* pNext; + VkXlibSurfaceCreateFlagsKHR flags; + Display* dpy; + Window window; +} VkXlibSurfaceCreateInfoKHR; + +typedef struct VkXcbSurfaceCreateInfoKHR +{ + VkStructureType sType; + const void* pNext; + VkXcbSurfaceCreateFlagsKHR flags; + xcb_connection_t* connection; + xcb_window_t window; +} VkXcbSurfaceCreateInfoKHR; + +typedef VkResult (APIENTRY *PFN_vkCreateXlibSurfaceKHR)(VkInstance,const VkXlibSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); +typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice,uint32_t,Display*,VisualID); +typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); +typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t); + +#include "xkb_unicode.h" +#include "posix_poll.h" + +#define GLFW_X11_WINDOW_STATE _GLFWwindowX11 x11; +#define GLFW_X11_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11; +#define GLFW_X11_MONITOR_STATE _GLFWmonitorX11 x11; +#define GLFW_X11_CURSOR_STATE _GLFWcursorX11 x11; + +#define GLFW_GLX_CONTEXT_STATE _GLFWcontextGLX glx; +#define GLFW_GLX_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx; + + +// GLX-specific per-context data +// +typedef struct _GLFWcontextGLX +{ + GLXContext handle; + GLXWindow window; +} _GLFWcontextGLX; + +// GLX-specific global data +// +typedef struct _GLFWlibraryGLX +{ + int major, minor; + int eventBase; + int errorBase; + + void* handle; + + // GLX 1.3 functions + PFNGLXGETFBCONFIGSPROC GetFBConfigs; + PFNGLXGETFBCONFIGATTRIBPROC GetFBConfigAttrib; + PFNGLXGETCLIENTSTRINGPROC GetClientString; + PFNGLXQUERYEXTENSIONPROC QueryExtension; + PFNGLXQUERYVERSIONPROC QueryVersion; + PFNGLXDESTROYCONTEXTPROC DestroyContext; + PFNGLXMAKECURRENTPROC MakeCurrent; + PFNGLXSWAPBUFFERSPROC SwapBuffers; + PFNGLXQUERYEXTENSIONSSTRINGPROC QueryExtensionsString; + PFNGLXCREATENEWCONTEXTPROC CreateNewContext; + PFNGLXGETVISUALFROMFBCONFIGPROC GetVisualFromFBConfig; + PFNGLXCREATEWINDOWPROC CreateWindow; + PFNGLXDESTROYWINDOWPROC DestroyWindow; + + // GLX 1.4 and extension functions + PFNGLXGETPROCADDRESSPROC GetProcAddress; + PFNGLXGETPROCADDRESSPROC GetProcAddressARB; + PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI; + PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT; + PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA; + PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB; + GLFWbool SGI_swap_control; + GLFWbool EXT_swap_control; + GLFWbool MESA_swap_control; + GLFWbool ARB_multisample; + GLFWbool ARB_framebuffer_sRGB; + GLFWbool EXT_framebuffer_sRGB; + GLFWbool ARB_create_context; + GLFWbool ARB_create_context_profile; + GLFWbool ARB_create_context_robustness; + GLFWbool EXT_create_context_es2_profile; + GLFWbool ARB_create_context_no_error; + GLFWbool ARB_context_flush_control; +} _GLFWlibraryGLX; + +// X11-specific per-window data +// +typedef struct _GLFWwindowX11 +{ + Colormap colormap; + Window handle; + Window parent; + XIC ic; + + GLFWbool overrideRedirect; + GLFWbool iconified; + GLFWbool maximized; + + // Whether the visual supports framebuffer transparency + GLFWbool transparent; + + // Cached position and size used to filter out duplicate events + int width, height; + int xpos, ypos; + + // The last received cursor position, regardless of source + int lastCursorPosX, lastCursorPosY; + // The last position the cursor was warped to by GLFW + int warpCursorPosX, warpCursorPosY; + + // The time of the last KeyPress event per keycode, for discarding + // duplicate key events generated for some keys by ibus + Time keyPressTimes[256]; +} _GLFWwindowX11; + +// X11-specific global data +// +typedef struct _GLFWlibraryX11 +{ + Display* display; + int screen; + Window root; + + // System content scale + float contentScaleX, contentScaleY; + // Helper window for IPC + Window helperWindowHandle; + // Invisible cursor for hidden cursor mode + Cursor hiddenCursorHandle; + // Context for mapping window XIDs to _GLFWwindow pointers + XContext context; + // XIM input method + XIM im; + // The previous X error handler, to be restored later + XErrorHandler errorHandler; + // Most recent error code received by X error handler + int errorCode; + // Primary selection string (while the primary selection is owned) + char* primarySelectionString; + // Clipboard string (while the selection is owned) + char* clipboardString; + // Key name string + char keynames[GLFW_KEY_LAST + 1][5]; + // X11 keycode to GLFW key LUT + short int keycodes[256]; + // GLFW key to X11 keycode LUT + short int scancodes[GLFW_KEY_LAST + 1]; + // Where to place the cursor when re-enabled + double restoreCursorPosX, restoreCursorPosY; + // The window whose disabled cursor mode is active + _GLFWwindow* disabledCursorWindow; + int emptyEventPipe[2]; + + // Window manager atoms + Atom NET_SUPPORTED; + Atom NET_SUPPORTING_WM_CHECK; + Atom WM_PROTOCOLS; + Atom WM_STATE; + Atom WM_DELETE_WINDOW; + Atom NET_WM_NAME; + Atom NET_WM_ICON_NAME; + Atom NET_WM_ICON; + Atom NET_WM_PID; + Atom NET_WM_PING; + Atom NET_WM_WINDOW_TYPE; + Atom NET_WM_WINDOW_TYPE_NORMAL; + Atom NET_WM_STATE; + Atom NET_WM_STATE_ABOVE; + Atom NET_WM_STATE_FULLSCREEN; + Atom NET_WM_STATE_MAXIMIZED_VERT; + Atom NET_WM_STATE_MAXIMIZED_HORZ; + Atom NET_WM_STATE_DEMANDS_ATTENTION; + Atom NET_WM_BYPASS_COMPOSITOR; + Atom NET_WM_FULLSCREEN_MONITORS; + Atom NET_WM_WINDOW_OPACITY; + Atom NET_WM_CM_Sx; + Atom NET_WORKAREA; + Atom NET_CURRENT_DESKTOP; + Atom NET_ACTIVE_WINDOW; + Atom NET_FRAME_EXTENTS; + Atom NET_REQUEST_FRAME_EXTENTS; + Atom MOTIF_WM_HINTS; + + // Xdnd (drag and drop) atoms + Atom XdndAware; + Atom XdndEnter; + Atom XdndPosition; + Atom XdndStatus; + Atom XdndActionCopy; + Atom XdndDrop; + Atom XdndFinished; + Atom XdndSelection; + Atom XdndTypeList; + Atom text_uri_list; + + // Selection (clipboard) atoms + Atom TARGETS; + Atom MULTIPLE; + Atom INCR; + Atom CLIPBOARD; + Atom PRIMARY; + Atom CLIPBOARD_MANAGER; + Atom SAVE_TARGETS; + Atom NULL_; + Atom UTF8_STRING; + Atom COMPOUND_STRING; + Atom ATOM_PAIR; + Atom GLFW_SELECTION; + + struct { + void* handle; + GLFWbool utf8; + PFN_XAllocClassHint AllocClassHint; + PFN_XAllocSizeHints AllocSizeHints; + PFN_XAllocWMHints AllocWMHints; + PFN_XChangeProperty ChangeProperty; + PFN_XChangeWindowAttributes ChangeWindowAttributes; + PFN_XCheckIfEvent CheckIfEvent; + PFN_XCheckTypedWindowEvent CheckTypedWindowEvent; + PFN_XCloseDisplay CloseDisplay; + PFN_XCloseIM CloseIM; + PFN_XConvertSelection ConvertSelection; + PFN_XCreateColormap CreateColormap; + PFN_XCreateFontCursor CreateFontCursor; + PFN_XCreateIC CreateIC; + PFN_XCreateRegion CreateRegion; + PFN_XCreateWindow CreateWindow; + PFN_XDefineCursor DefineCursor; + PFN_XDeleteContext DeleteContext; + PFN_XDeleteProperty DeleteProperty; + PFN_XDestroyIC DestroyIC; + PFN_XDestroyRegion DestroyRegion; + PFN_XDestroyWindow DestroyWindow; + PFN_XDisplayKeycodes DisplayKeycodes; + PFN_XEventsQueued EventsQueued; + PFN_XFilterEvent FilterEvent; + PFN_XFindContext FindContext; + PFN_XFlush Flush; + PFN_XFree Free; + PFN_XFreeColormap FreeColormap; + PFN_XFreeCursor FreeCursor; + PFN_XFreeEventData FreeEventData; + PFN_XGetErrorText GetErrorText; + PFN_XGetEventData GetEventData; + PFN_XGetICValues GetICValues; + PFN_XGetIMValues GetIMValues; + PFN_XGetInputFocus GetInputFocus; + PFN_XGetKeyboardMapping GetKeyboardMapping; + PFN_XGetScreenSaver GetScreenSaver; + PFN_XGetSelectionOwner GetSelectionOwner; + PFN_XGetVisualInfo GetVisualInfo; + PFN_XGetWMNormalHints GetWMNormalHints; + PFN_XGetWindowAttributes GetWindowAttributes; + PFN_XGetWindowProperty GetWindowProperty; + PFN_XGrabPointer GrabPointer; + PFN_XIconifyWindow IconifyWindow; + PFN_XInternAtom InternAtom; + PFN_XLookupString LookupString; + PFN_XMapRaised MapRaised; + PFN_XMapWindow MapWindow; + PFN_XMoveResizeWindow MoveResizeWindow; + PFN_XMoveWindow MoveWindow; + PFN_XNextEvent NextEvent; + PFN_XOpenIM OpenIM; + PFN_XPeekEvent PeekEvent; + PFN_XPending Pending; + PFN_XQueryExtension QueryExtension; + PFN_XQueryPointer QueryPointer; + PFN_XRaiseWindow RaiseWindow; + PFN_XRegisterIMInstantiateCallback RegisterIMInstantiateCallback; + PFN_XResizeWindow ResizeWindow; + PFN_XResourceManagerString ResourceManagerString; + PFN_XSaveContext SaveContext; + PFN_XSelectInput SelectInput; + PFN_XSendEvent SendEvent; + PFN_XSetClassHint SetClassHint; + PFN_XSetErrorHandler SetErrorHandler; + PFN_XSetICFocus SetICFocus; + PFN_XSetIMValues SetIMValues; + PFN_XSetInputFocus SetInputFocus; + PFN_XSetLocaleModifiers SetLocaleModifiers; + PFN_XSetScreenSaver SetScreenSaver; + PFN_XSetSelectionOwner SetSelectionOwner; + PFN_XSetWMHints SetWMHints; + PFN_XSetWMNormalHints SetWMNormalHints; + PFN_XSetWMProtocols SetWMProtocols; + PFN_XSupportsLocale SupportsLocale; + PFN_XSync Sync; + PFN_XTranslateCoordinates TranslateCoordinates; + PFN_XUndefineCursor UndefineCursor; + PFN_XUngrabPointer UngrabPointer; + PFN_XUnmapWindow UnmapWindow; + PFN_XUnsetICFocus UnsetICFocus; + PFN_XVisualIDFromVisual VisualIDFromVisual; + PFN_XWarpPointer WarpPointer; + PFN_XUnregisterIMInstantiateCallback UnregisterIMInstantiateCallback; + PFN_Xutf8LookupString utf8LookupString; + PFN_Xutf8SetWMProperties utf8SetWMProperties; + } xlib; + + struct { + PFN_XrmDestroyDatabase DestroyDatabase; + PFN_XrmGetResource GetResource; + PFN_XrmGetStringDatabase GetStringDatabase; + PFN_XrmUniqueQuark UniqueQuark; + } xrm; + + struct { + GLFWbool available; + void* handle; + int eventBase; + int errorBase; + int major; + int minor; + GLFWbool gammaBroken; + GLFWbool monitorBroken; + PFN_XRRAllocGamma AllocGamma; + PFN_XRRFreeCrtcInfo FreeCrtcInfo; + PFN_XRRFreeGamma FreeGamma; + PFN_XRRFreeOutputInfo FreeOutputInfo; + PFN_XRRFreeScreenResources FreeScreenResources; + PFN_XRRGetCrtcGamma GetCrtcGamma; + PFN_XRRGetCrtcGammaSize GetCrtcGammaSize; + PFN_XRRGetCrtcInfo GetCrtcInfo; + PFN_XRRGetOutputInfo GetOutputInfo; + PFN_XRRGetOutputPrimary GetOutputPrimary; + PFN_XRRGetScreenResourcesCurrent GetScreenResourcesCurrent; + PFN_XRRQueryExtension QueryExtension; + PFN_XRRQueryVersion QueryVersion; + PFN_XRRSelectInput SelectInput; + PFN_XRRSetCrtcConfig SetCrtcConfig; + PFN_XRRSetCrtcGamma SetCrtcGamma; + PFN_XRRUpdateConfiguration UpdateConfiguration; + } randr; + + struct { + GLFWbool available; + GLFWbool detectable; + int majorOpcode; + int eventBase; + int errorBase; + int major; + int minor; + unsigned int group; + PFN_XkbFreeKeyboard FreeKeyboard; + PFN_XkbFreeNames FreeNames; + PFN_XkbGetMap GetMap; + PFN_XkbGetNames GetNames; + PFN_XkbGetState GetState; + PFN_XkbKeycodeToKeysym KeycodeToKeysym; + PFN_XkbQueryExtension QueryExtension; + PFN_XkbSelectEventDetails SelectEventDetails; + PFN_XkbSetDetectableAutoRepeat SetDetectableAutoRepeat; + } xkb; + + struct { + int count; + int timeout; + int interval; + int blanking; + int exposure; + } saver; + + struct { + int version; + Window source; + Atom format; + } xdnd; + + struct { + void* handle; + PFN_XcursorImageCreate ImageCreate; + PFN_XcursorImageDestroy ImageDestroy; + PFN_XcursorImageLoadCursor ImageLoadCursor; + PFN_XcursorGetTheme GetTheme; + PFN_XcursorGetDefaultSize GetDefaultSize; + PFN_XcursorLibraryLoadImage LibraryLoadImage; + } xcursor; + + struct { + GLFWbool available; + void* handle; + int major; + int minor; + PFN_XineramaIsActive IsActive; + PFN_XineramaQueryExtension QueryExtension; + PFN_XineramaQueryScreens QueryScreens; + } xinerama; + + struct { + void* handle; + PFN_XGetXCBConnection GetXCBConnection; + } x11xcb; + + struct { + GLFWbool available; + void* handle; + int eventBase; + int errorBase; + PFN_XF86VidModeQueryExtension QueryExtension; + PFN_XF86VidModeGetGammaRamp GetGammaRamp; + PFN_XF86VidModeSetGammaRamp SetGammaRamp; + PFN_XF86VidModeGetGammaRampSize GetGammaRampSize; + } vidmode; + + struct { + GLFWbool available; + void* handle; + int majorOpcode; + int eventBase; + int errorBase; + int major; + int minor; + PFN_XIQueryVersion QueryVersion; + PFN_XISelectEvents SelectEvents; + } xi; + + struct { + GLFWbool available; + void* handle; + int major; + int minor; + int eventBase; + int errorBase; + PFN_XRenderQueryExtension QueryExtension; + PFN_XRenderQueryVersion QueryVersion; + PFN_XRenderFindVisualFormat FindVisualFormat; + } xrender; + + struct { + GLFWbool available; + void* handle; + int major; + int minor; + int eventBase; + int errorBase; + PFN_XShapeQueryExtension QueryExtension; + PFN_XShapeCombineRegion ShapeCombineRegion; + PFN_XShapeQueryVersion QueryVersion; + PFN_XShapeCombineMask ShapeCombineMask; + } xshape; +} _GLFWlibraryX11; + +// X11-specific per-monitor data +// +typedef struct _GLFWmonitorX11 +{ + RROutput output; + RRCrtc crtc; + RRMode oldMode; + + // Index of corresponding Xinerama screen, + // for EWMH full screen window placement + int index; +} _GLFWmonitorX11; + +// X11-specific per-cursor data +// +typedef struct _GLFWcursorX11 +{ + Cursor handle; +} _GLFWcursorX11; + + +GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform); +int _glfwInitX11(void); +void _glfwTerminateX11(void); + +GLFWbool _glfwCreateWindowX11(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); +void _glfwDestroyWindowX11(_GLFWwindow* window); +void _glfwSetWindowTitleX11(_GLFWwindow* window, const char* title); +void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* images); +void _glfwGetWindowPosX11(_GLFWwindow* window, int* xpos, int* ypos); +void _glfwSetWindowPosX11(_GLFWwindow* window, int xpos, int ypos); +void _glfwGetWindowSizeX11(_GLFWwindow* window, int* width, int* height); +void _glfwSetWindowSizeX11(_GLFWwindow* window, int width, int height); +void _glfwSetWindowSizeLimitsX11(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight); +void _glfwSetWindowAspectRatioX11(_GLFWwindow* window, int numer, int denom); +void _glfwGetFramebufferSizeX11(_GLFWwindow* window, int* width, int* height); +void _glfwGetWindowFrameSizeX11(_GLFWwindow* window, int* left, int* top, int* right, int* bottom); +void _glfwGetWindowContentScaleX11(_GLFWwindow* window, float* xscale, float* yscale); +void _glfwIconifyWindowX11(_GLFWwindow* window); +void _glfwRestoreWindowX11(_GLFWwindow* window); +void _glfwMaximizeWindowX11(_GLFWwindow* window); +void _glfwShowWindowX11(_GLFWwindow* window); +void _glfwHideWindowX11(_GLFWwindow* window); +void _glfwRequestWindowAttentionX11(_GLFWwindow* window); +void _glfwFocusWindowX11(_GLFWwindow* window); +void _glfwSetWindowMonitorX11(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); +GLFWbool _glfwWindowFocusedX11(_GLFWwindow* window); +GLFWbool _glfwWindowIconifiedX11(_GLFWwindow* window); +GLFWbool _glfwWindowVisibleX11(_GLFWwindow* window); +GLFWbool _glfwWindowMaximizedX11(_GLFWwindow* window); +GLFWbool _glfwWindowHoveredX11(_GLFWwindow* window); +GLFWbool _glfwFramebufferTransparentX11(_GLFWwindow* window); +void _glfwSetWindowResizableX11(_GLFWwindow* window, GLFWbool enabled); +void _glfwSetWindowDecoratedX11(_GLFWwindow* window, GLFWbool enabled); +void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled); +float _glfwGetWindowOpacityX11(_GLFWwindow* window); +void _glfwSetWindowOpacityX11(_GLFWwindow* window, float opacity); +void _glfwSetWindowMousePassthroughX11(_GLFWwindow* window, GLFWbool enabled); + +void _glfwSetRawMouseMotionX11(_GLFWwindow *window, GLFWbool enabled); +GLFWbool _glfwRawMouseMotionSupportedX11(void); + +void _glfwPollEventsX11(void); +void _glfwWaitEventsX11(void); +void _glfwWaitEventsTimeoutX11(double timeout); +void _glfwPostEmptyEventX11(void); + +void _glfwGetCursorPosX11(_GLFWwindow* window, double* xpos, double* ypos); +void _glfwSetCursorPosX11(_GLFWwindow* window, double xpos, double ypos); +void _glfwSetCursorModeX11(_GLFWwindow* window, int mode); +const char* _glfwGetScancodeNameX11(int scancode); +int _glfwGetKeyScancodeX11(int key); +GLFWbool _glfwCreateCursorX11(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot); +GLFWbool _glfwCreateStandardCursorX11(_GLFWcursor* cursor, int shape); +void _glfwDestroyCursorX11(_GLFWcursor* cursor); +void _glfwSetCursorX11(_GLFWwindow* window, _GLFWcursor* cursor); +void _glfwSetClipboardStringX11(const char* string); +const char* _glfwGetClipboardStringX11(void); + +EGLenum _glfwGetEGLPlatformX11(EGLint** attribs); +EGLNativeDisplayType _glfwGetEGLNativeDisplayX11(void); +EGLNativeWindowType _glfwGetEGLNativeWindowX11(_GLFWwindow* window); + +void _glfwGetRequiredInstanceExtensionsX11(char** extensions); +GLFWbool _glfwGetPhysicalDevicePresentationSupportX11(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily); +VkResult _glfwCreateWindowSurfaceX11(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); + +void _glfwFreeMonitorX11(_GLFWmonitor* monitor); +void _glfwGetMonitorPosX11(_GLFWmonitor* monitor, int* xpos, int* ypos); +void _glfwGetMonitorContentScaleX11(_GLFWmonitor* monitor, float* xscale, float* yscale); +void _glfwGetMonitorWorkareaX11(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); +GLFWvidmode* _glfwGetVideoModesX11(_GLFWmonitor* monitor, int* count); +GLFWbool _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode); +GLFWbool _glfwGetGammaRampX11(_GLFWmonitor* monitor, GLFWgammaramp* ramp); +void _glfwSetGammaRampX11(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); + +void _glfwPollMonitorsX11(void); +void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired); +void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor); + +Cursor _glfwCreateNativeCursorX11(const GLFWimage* image, int xhot, int yhot); + +unsigned long _glfwGetWindowPropertyX11(Window window, + Atom property, + Atom type, + unsigned char** value); +GLFWbool _glfwIsVisualTransparentX11(Visual* visual); + +void _glfwGrabErrorHandlerX11(void); +void _glfwReleaseErrorHandlerX11(void); +void _glfwInputErrorX11(int error, const char* message); + +void _glfwPushSelectionToManagerX11(void); +void _glfwCreateInputContextX11(_GLFWwindow* window); + +GLFWbool _glfwInitGLX(void); +void _glfwTerminateGLX(void); +GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig); +void _glfwDestroyContextGLX(_GLFWwindow* window); +GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig, + Visual** visual, int* depth); + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/x11_window.c b/src/lib/src/vendor/glfw-3.4/src/x11_window.c similarity index 82% rename from src/lib/src/vendor/glfw-3.3.8/src/x11_window.c rename to src/lib/src/vendor/glfw-3.4/src/x11_window.c index ddda48d..e029546 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/x11_window.c +++ b/src/lib/src/vendor/glfw-3.4/src/x11_window.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 X11 - www.glfw.org +// GLFW 3.4 X11 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy @@ -24,19 +24,15 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== - -#define _GNU_SOURCE #include "internal.h" +#if defined(_GLFW_X11) + #include #include #include -#include -#include #include #include @@ -60,53 +56,6 @@ #define _GLFW_XDND_VERSION 5 -// Wait for data to arrive on any of the specified file descriptors -// -static GLFWbool waitForData(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; - } - } -} - // Wait for event data to arrive on the X11 display socket // This avoids blocking other threads via the per-display Xlib lock that also // covers GLX functions @@ -117,7 +66,7 @@ static GLFWbool waitForX11Event(double* timeout) while (!XPending(_glfw.x11.display)) { - if (!waitForData(&fd, 1, timeout)) + if (!_glfwPollPOSIX(&fd, 1, timeout)) return GLFW_FALSE; } @@ -130,24 +79,25 @@ static GLFWbool waitForX11Event(double* timeout) // static GLFWbool waitForAnyEvent(double* timeout) { - nfds_t count = 2; - struct pollfd fds[3] = + enum { XLIB_FD, PIPE_FD, INOTIFY_FD }; + struct pollfd fds[] = { - { ConnectionNumber(_glfw.x11.display), POLLIN }, - { _glfw.x11.emptyEventPipe[0], POLLIN } + [XLIB_FD] = { ConnectionNumber(_glfw.x11.display), POLLIN }, + [PIPE_FD] = { _glfw.x11.emptyEventPipe[0], POLLIN }, + [INOTIFY_FD] = { -1, POLLIN } }; -#if defined(__linux__) - if (_glfw.linjs.inotify > 0) - fds[count++] = (struct pollfd) { _glfw.linjs.inotify, POLLIN }; +#if defined(GLFW_BUILD_LINUX_JOYSTICK) + if (_glfw.joysticksInitialized) + fds[INOTIFY_FD].fd = _glfw.linjs.inotify; #endif while (!XPending(_glfw.x11.display)) { - if (!waitForData(fds, count, timeout)) + if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout)) return GLFW_FALSE; - for (int i = 1; i < count; i++) + for (int i = 1; i < sizeof(fds) / sizeof(fds[0]); i++) { if (fds[i].revents & POLLIN) return GLFW_TRUE; @@ -321,6 +271,11 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height) { XSizeHints* hints = XAllocSizeHints(); + long supplied; + XGetWMNormalHints(_glfw.x11.display, window->x11.handle, hints, &supplied); + + hints->flags &= ~(PMinSize | PMaxSize | PAspect); + if (!window->monitor) { if (window->resizable) @@ -357,9 +312,6 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height) } } - hints->flags |= PWinGravity; - hints->win_gravity = StaticGravity; - XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); XFree(hints); } @@ -461,7 +413,6 @@ static void updateWindowMode(_GLFWwindow* window) // Decode a Unicode code point from a UTF-8 stream // Based on cutef8 by Jeff Bezanson (Public Domain) // -#if defined(X_HAVE_UTF8_STRING) static uint32_t decodeUTF8(const char** s) { uint32_t codepoint = 0, count = 0; @@ -481,7 +432,6 @@ static uint32_t decodeUTF8(const char** s) assert(count <= 6); return codepoint - offsets[count - 1]; } -#endif /*X_HAVE_UTF8_STRING*/ // Convert the specified Latin-1 string to UTF-8 // @@ -493,7 +443,7 @@ static char* convertLatin1toUTF8(const char* source) for (sp = source; *sp; sp++) size += (*sp & 0x80) ? 2 : 1; - char* target = calloc(size, 1); + char* target = _glfw_calloc(size, 1); char* tp = target; for (sp = source; *sp; sp++) @@ -506,7 +456,8 @@ static char* convertLatin1toUTF8(const char* source) // static void updateCursorImage(_GLFWwindow* window) { - if (window->cursorMode == GLFW_CURSOR_NORMAL) + if (window->cursorMode == GLFW_CURSOR_NORMAL || + window->cursorMode == GLFW_CURSOR_CAPTURED) { if (window->cursor) { @@ -523,6 +474,25 @@ static void updateCursorImage(_GLFWwindow* window) } } +// Grabs the cursor and confines it to the window +// +static void captureCursor(_GLFWwindow* window) +{ + XGrabPointer(_glfw.x11.display, window->x11.handle, True, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + GrabModeAsync, GrabModeAsync, + window->x11.handle, + None, + CurrentTime); +} + +// Ungrabs the cursor +// +static void releaseCursor(void) +{ + XUngrabPointer(_glfw.x11.display, CurrentTime); +} + // Enable XI2 raw mouse motion events // static void enableRawMouseMotion(_GLFWwindow* window) @@ -560,17 +530,12 @@ static void disableCursor(_GLFWwindow* window) enableRawMouseMotion(window); _glfw.x11.disabledCursorWindow = window; - _glfwPlatformGetCursorPos(window, - &_glfw.x11.restoreCursorPosX, - &_glfw.x11.restoreCursorPosY); + _glfwGetCursorPosX11(window, + &_glfw.x11.restoreCursorPosX, + &_glfw.x11.restoreCursorPosY); updateCursorImage(window); _glfwCenterCursorInContentArea(window); - XGrabPointer(_glfw.x11.display, window->x11.handle, True, - ButtonPressMask | ButtonReleaseMask | PointerMotionMask, - GrabModeAsync, GrabModeAsync, - window->x11.handle, - _glfw.x11.hiddenCursorHandle, - CurrentTime); + captureCursor(window); } // Exit disabled cursor mode for the specified window @@ -581,13 +546,21 @@ static void enableCursor(_GLFWwindow* window) disableRawMouseMotion(window); _glfw.x11.disabledCursorWindow = NULL; - XUngrabPointer(_glfw.x11.display, CurrentTime); - _glfwPlatformSetCursorPos(window, - _glfw.x11.restoreCursorPosX, - _glfw.x11.restoreCursorPosY); + releaseCursor(); + _glfwSetCursorPosX11(window, + _glfw.x11.restoreCursorPosX, + _glfw.x11.restoreCursorPosY); updateCursorImage(window); } +// Clear its handle when the input context has been destroyed +// +static void inputContextDestroyCallback(XIC ic, XPointer clientData, XPointer callData) +{ + _GLFWwindow* window = (_GLFWwindow*) clientData; + window->x11.ic = NULL; +} + // Create the X11 window (and its colormap) // static GLFWbool createNativeWindow(_GLFWwindow* window, @@ -603,6 +576,14 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, height *= _glfw.x11.contentScaleY; } + int xpos = 0, ypos = 0; + + if (wndconfig->xpos != GLFW_ANY_POSITION && wndconfig->ypos != GLFW_ANY_POSITION) + { + xpos = wndconfig->xpos; + ypos = wndconfig->ypos; + } + // Create a colormap based on the visual used by the current context window->x11.colormap = XCreateColormap(_glfw.x11.display, _glfw.x11.root, @@ -623,7 +604,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, window->x11.parent = _glfw.x11.root; window->x11.handle = XCreateWindow(_glfw.x11.display, _glfw.x11.root, - 0, 0, // Position + xpos, ypos, width, height, 0, // Border width depth, // Color depth @@ -647,7 +628,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, (XPointer) window); if (!wndconfig->decorated) - _glfwPlatformSetWindowDecorated(window, GLFW_FALSE); + _glfwSetWindowDecoratedX11(window, GLFW_FALSE); if (_glfw.x11.NET_WM_STATE && !window->monitor) { @@ -726,7 +707,37 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, XFree(hints); } - updateNormalHints(window, width, height); + // Set ICCCM WM_NORMAL_HINTS property + { + XSizeHints* hints = XAllocSizeHints(); + if (!hints) + { + _glfwInputError(GLFW_OUT_OF_MEMORY, "X11: Failed to allocate size hints"); + return GLFW_FALSE; + } + + if (!wndconfig->resizable) + { + hints->flags |= (PMinSize | PMaxSize); + hints->min_width = hints->max_width = width; + hints->min_height = hints->max_height = height; + } + + // HACK: Explicitly setting PPosition to any value causes some WMs, notably + // Compiz and Metacity, to honor the position of unmapped windows + if (wndconfig->xpos != GLFW_ANY_POSITION && wndconfig->ypos != GLFW_ANY_POSITION) + { + hints->flags |= PPosition; + hints->x = 0; + hints->y = 0; + } + + hints->flags |= PWinGravity; + hints->win_gravity = StaticGravity; + + XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); + XFree(hints); + } // Set ICCCM WM_CLASS property { @@ -766,29 +777,12 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, PropModeReplace, (unsigned char*) &version, 1); } - _glfwPlatformSetWindowTitle(window, wndconfig->title); - if (_glfw.x11.im) - { - window->x11.ic = XCreateIC(_glfw.x11.im, - XNInputStyle, - XIMPreeditNothing | XIMStatusNothing, - XNClientWindow, - window->x11.handle, - XNFocusWindow, - window->x11.handle, - NULL); - } + _glfwCreateInputContextX11(window); - if (window->x11.ic) - { - unsigned long filter = 0; - if (XGetICValues(window->x11.ic, XNFilterEvents, &filter, NULL) == NULL) - XSelectInput(_glfw.x11.display, window->x11.handle, wa.event_mask | filter); - } - - _glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos); - _glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height); + _glfwSetWindowTitleX11(window, wndconfig->title); + _glfwGetWindowPosX11(window, &window->x11.xpos, &window->x11.ypos); + _glfwGetWindowSizeX11(window, &window->x11.width, &window->x11.height); return GLFW_TRUE; } @@ -797,7 +791,6 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, // static Atom writeTargetToProperty(const XSelectionRequestEvent* request) { - int i; char* selectionString = NULL; const Atom formats[] = { _glfw.x11.UTF8_STRING, XA_STRING }; const int formatCount = sizeof(formats) / sizeof(formats[0]); @@ -840,14 +833,13 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request) // Multiple conversions were requested Atom* targets; - unsigned long i, count; + const unsigned long count = + _glfwGetWindowPropertyX11(request->requestor, + request->property, + _glfw.x11.ATOM_PAIR, + (unsigned char**) &targets); - count = _glfwGetWindowPropertyX11(request->requestor, - request->property, - _glfw.x11.ATOM_PAIR, - (unsigned char**) &targets); - - for (i = 0; i < count; i += 2) + for (unsigned long i = 0; i < count; i += 2) { int j; @@ -905,7 +897,7 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request) // Conversion to a data target was requested - for (i = 0; i < formatCount; i++) + for (int i = 0; i < formatCount; i++) { if (request->target == formats[i]) { @@ -963,7 +955,7 @@ static const char* getSelectionString(Atom selection) return *selectionString; } - free(*selectionString); + _glfw_free(*selectionString); *selectionString = NULL; for (size_t i = 0; i < targetCount; i++) @@ -1042,7 +1034,7 @@ static const char* getSelectionString(Atom selection) if (itemCount) { size += itemCount; - string = realloc(string, size); + string = _glfw_realloc(string, size); string[size - itemCount - 1] = '\0'; strcat(string, data); } @@ -1054,7 +1046,7 @@ static const char* getSelectionString(Atom selection) if (targets[i] == XA_STRING) { *selectionString = convertLatin1toUTF8(string); - free(string); + _glfw_free(string); } else *selectionString = string; @@ -1116,8 +1108,8 @@ static void acquireMonitor(_GLFWwindow* window) GLFWvidmode mode; // Manually position the window over its monitor - _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); - _glfwPlatformGetVideoMode(window->monitor, &mode); + _glfwGetMonitorPosX11(window->monitor, &xpos, &ypos); + _glfwGetVideoModeX11(window->monitor, &mode); XMoveResizeWindow(_glfw.x11.display, window->x11.handle, xpos, ypos, mode.width, mode.height); @@ -1160,8 +1152,7 @@ static void processEvent(XEvent *event) if (event->type == KeyPress || event->type == KeyRelease) keycode = event->xkey.keycode; - if (_glfw.x11.im) - filtered = XFilterEvent(event, None); + filtered = XFilterEvent(event, None); if (_glfw.x11.randr.available) { @@ -1277,7 +1268,6 @@ static void processEvent(XEvent *event) { int count; Status status; -#if defined(X_HAVE_UTF8_STRING) char buffer[100]; char* chars = buffer; @@ -1288,7 +1278,7 @@ static void processEvent(XEvent *event) if (status == XBufferOverflow) { - chars = calloc(count + 1, 1); + chars = _glfw_calloc(count + 1, 1); count = Xutf8LookupString(window->x11.ic, &event->xkey, chars, count, @@ -1302,36 +1292,9 @@ static void processEvent(XEvent *event) while (c - chars < count) _glfwInputChar(window, decodeUTF8(&c), mods, plain); } -#else /*X_HAVE_UTF8_STRING*/ - wchar_t buffer[16]; - wchar_t* chars = buffer; - - count = XwcLookupString(window->x11.ic, - &event->xkey, - buffer, - sizeof(buffer) / sizeof(wchar_t), - NULL, - &status); - - if (status == XBufferOverflow) - { - chars = calloc(count, sizeof(wchar_t)); - count = XwcLookupString(window->x11.ic, - &event->xkey, - chars, count, - NULL, &status); - } - - if (status == XLookupChars || status == XLookupBoth) - { - int i; - for (i = 0; i < count; i++) - _glfwInputChar(window, chars[i], mods, plain); - } -#endif /*X_HAVE_UTF8_STRING*/ if (chars != buffer) - free(chars); + _glfw_free(chars); } } else @@ -1525,6 +1488,9 @@ static void processEvent(XEvent *event) if (event->xconfigure.width != window->x11.width || event->xconfigure.height != window->x11.height) { + window->x11.width = event->xconfigure.width; + window->x11.height = event->xconfigure.height; + _glfwInputFramebufferSize(window, event->xconfigure.width, event->xconfigure.height); @@ -1532,9 +1498,6 @@ static void processEvent(XEvent *event) _glfwInputWindowSize(window, event->xconfigure.width, event->xconfigure.height); - - window->x11.width = event->xconfigure.width; - window->x11.height = event->xconfigure.height; } int xpos = event->xconfigure.x; @@ -1562,9 +1525,10 @@ static void processEvent(XEvent *event) if (xpos != window->x11.xpos || ypos != window->x11.ypos) { - _glfwInputWindowPos(window, xpos, ypos); window->x11.xpos = xpos; window->x11.ypos = ypos; + + _glfwInputWindowPos(window, xpos, ypos); } return; @@ -1610,7 +1574,7 @@ static void processEvent(XEvent *event) else if (event->xclient.message_type == _glfw.x11.XdndEnter) { // A drag operation has entered the window - unsigned long i, count; + unsigned long count; Atom* formats = NULL; const GLFWbool list = event->xclient.data.l[1] & 1; @@ -1634,7 +1598,7 @@ static void processEvent(XEvent *event) formats = (Atom*) event->xclient.data.l + 2; } - for (i = 0; i < count; i++) + for (unsigned int i = 0; i < count; i++) { if (formats[i] == _glfw.x11.text_uri_list) { @@ -1740,14 +1704,14 @@ static void processEvent(XEvent *event) if (result) { - int i, count; + int count; char** paths = _glfwParseUriList(data, &count); _glfwInputDrop(window, count, (const char**) paths); - for (i = 0; i < count; i++) - free(paths[i]); - free(paths); + for (int i = 0; i < count; i++) + _glfw_free(paths[i]); + _glfw_free(paths); } if (data) @@ -1784,6 +1748,8 @@ static void processEvent(XEvent *event) if (window->cursorMode == GLFW_CURSOR_DISABLED) disableCursor(window); + else if (window->cursorMode == GLFW_CURSOR_CAPTURED) + captureCursor(window); if (window->x11.ic) XSetICFocus(window->x11.ic); @@ -1804,12 +1770,14 @@ static void processEvent(XEvent *event) if (window->cursorMode == GLFW_CURSOR_DISABLED) enableCursor(window); + else if (window->cursorMode == GLFW_CURSOR_CAPTURED) + releaseCursor(); if (window->x11.ic) XUnsetICFocus(window->x11.ic); if (window->monitor && window->autoIconify) - _glfwPlatformIconifyWindow(window); + _glfwIconifyWindowX11(window); _glfwInputWindowFocus(window, GLFW_FALSE); return; @@ -1849,7 +1817,7 @@ static void processEvent(XEvent *event) } else if (event->xproperty.atom == _glfw.x11.NET_WM_STATE) { - const GLFWbool maximized = _glfwPlatformWindowMaximized(window); + const GLFWbool maximized = _glfwWindowMaximizedX11(window); if (window->x11.maximized != maximized) { window->x11.maximized = maximized; @@ -1951,12 +1919,44 @@ void _glfwPushSelectionToManagerX11(void) } } +void _glfwCreateInputContextX11(_GLFWwindow* window) +{ + XIMCallback callback; + callback.callback = (XIMProc) inputContextDestroyCallback; + callback.client_data = (XPointer) window; + + window->x11.ic = XCreateIC(_glfw.x11.im, + XNInputStyle, + XIMPreeditNothing | XIMStatusNothing, + XNClientWindow, + window->x11.handle, + XNFocusWindow, + window->x11.handle, + XNDestroyCallback, + &callback, + NULL); + + if (window->x11.ic) + { + XWindowAttributes attribs; + XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &attribs); + + unsigned long filter = 0; + if (XGetICValues(window->x11.ic, XNFilterEvents, &filter, NULL) == NULL) + { + XSelectInput(_glfw.x11.display, + window->x11.handle, + attribs.your_event_mask | filter); + } + } +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -int _glfwPlatformCreateWindow(_GLFWwindow* window, +GLFWbool _glfwCreateWindowX11(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig) @@ -2018,9 +2018,12 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, return GLFW_FALSE; } + if (wndconfig->mousePassthrough) + _glfwSetWindowMousePassthroughX11(window, GLFW_TRUE); + if (window->monitor) { - _glfwPlatformShowWindow(window); + _glfwShowWindowX11(window); updateWindowMode(window); acquireMonitor(window); @@ -2031,9 +2034,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, { if (wndconfig->visible) { - _glfwPlatformShowWindow(window); + _glfwShowWindowX11(window); if (wndconfig->focused) - _glfwPlatformFocusWindow(window); + _glfwFocusWindowX11(window); } } @@ -2041,10 +2044,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, return GLFW_TRUE; } -void _glfwPlatformDestroyWindow(_GLFWwindow* window) +void _glfwDestroyWindowX11(_GLFWwindow* window) { if (_glfw.x11.disabledCursorWindow == window) - _glfw.x11.disabledCursorWindow = NULL; + enableCursor(window); if (window->monitor) releaseMonitor(window); @@ -2075,23 +2078,16 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) XFlush(_glfw.x11.display); } -void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) +void _glfwSetWindowTitleX11(_GLFWwindow* window, const char* title) { -#if defined(X_HAVE_UTF8_STRING) - Xutf8SetWMProperties(_glfw.x11.display, - window->x11.handle, - title, title, - NULL, 0, - NULL, NULL, NULL); -#else - // This may be a slightly better fallback than using XStoreName and - // XSetIconName, which always store their arguments using STRING - XmbSetWMProperties(_glfw.x11.display, - window->x11.handle, - title, title, - NULL, 0, - NULL, NULL, NULL); -#endif + if (_glfw.x11.xlib.utf8) + { + Xutf8SetWMProperties(_glfw.x11.display, + window->x11.handle, + title, title, + NULL, 0, + NULL, NULL, NULL); + } XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_NAME, _glfw.x11.UTF8_STRING, 8, @@ -2106,25 +2102,24 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) XFlush(_glfw.x11.display); } -void _glfwPlatformSetWindowIcon(_GLFWwindow* window, - int count, const GLFWimage* images) +void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* images) { if (count) { - int i, j, longCount = 0; + int longCount = 0; - for (i = 0; i < count; i++) + for (int i = 0; i < count; i++) longCount += 2 + images[i].width * images[i].height; - unsigned long* icon = calloc(longCount, sizeof(unsigned long)); + unsigned long* icon = _glfw_calloc(longCount, sizeof(unsigned long)); unsigned long* target = icon; - for (i = 0; i < count; i++) + for (int i = 0; i < count; i++) { *target++ = images[i].width; *target++ = images[i].height; - for (j = 0; j < images[i].width * images[i].height; j++) + for (int j = 0; j < images[i].width * images[i].height; j++) { *target++ = (((unsigned long) images[i].pixels[j * 4 + 0]) << 16) | (((unsigned long) images[i].pixels[j * 4 + 1]) << 8) | @@ -2146,7 +2141,7 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window, (unsigned char*) icon, longCount); - free(icon); + _glfw_free(icon); } else { @@ -2157,7 +2152,7 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window, XFlush(_glfw.x11.display); } -void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) +void _glfwGetWindowPosX11(_GLFWwindow* window, int* xpos, int* ypos) { Window dummy; int x, y; @@ -2171,11 +2166,11 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) *ypos = y; } -void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) +void _glfwSetWindowPosX11(_GLFWwindow* window, int xpos, int ypos) { // HACK: Explicitly setting PPosition to any value causes some WMs, notably // Compiz and Metacity, to honor the position of unmapped windows - if (!_glfwPlatformWindowVisible(window)) + if (!_glfwWindowVisibleX11(window)) { long supplied; XSizeHints* hints = XAllocSizeHints(); @@ -2195,7 +2190,7 @@ void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) XFlush(_glfw.x11.display); } -void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) +void _glfwGetWindowSizeX11(_GLFWwindow* window, int* width, int* height) { XWindowAttributes attribs; XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &attribs); @@ -2206,7 +2201,7 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) *height = attribs.height; } -void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) +void _glfwSetWindowSizeX11(_GLFWwindow* window, int width, int height) { if (window->monitor) { @@ -2224,32 +2219,32 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) XFlush(_glfw.x11.display); } -void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, - int minwidth, int minheight, - int maxwidth, int maxheight) +void _glfwSetWindowSizeLimitsX11(_GLFWwindow* window, + int minwidth, int minheight, + int maxwidth, int maxheight) { int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); + _glfwGetWindowSizeX11(window, &width, &height); updateNormalHints(window, width, height); XFlush(_glfw.x11.display); } -void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom) +void _glfwSetWindowAspectRatioX11(_GLFWwindow* window, int numer, int denom) { int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); + _glfwGetWindowSizeX11(window, &width, &height); updateNormalHints(window, width, height); XFlush(_glfw.x11.display); } -void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) +void _glfwGetFramebufferSizeX11(_GLFWwindow* window, int* width, int* height) { - _glfwPlatformGetWindowSize(window, width, height); + _glfwGetWindowSizeX11(window, width, height); } -void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, - int* left, int* top, - int* right, int* bottom) +void _glfwGetWindowFrameSizeX11(_GLFWwindow* window, + int* left, int* top, + int* right, int* bottom) { long* extents = NULL; @@ -2259,7 +2254,7 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, if (_glfw.x11.NET_FRAME_EXTENTS == None) return; - if (!_glfwPlatformWindowVisible(window) && + if (!_glfwWindowVisibleX11(window) && _glfw.x11.NET_REQUEST_FRAME_EXTENTS) { XEvent event; @@ -2308,8 +2303,7 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, XFree(extents); } -void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, - float* xscale, float* yscale) +void _glfwGetWindowContentScaleX11(_GLFWwindow* window, float* xscale, float* yscale) { if (xscale) *xscale = _glfw.x11.contentScaleX; @@ -2317,7 +2311,7 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, *yscale = _glfw.x11.contentScaleY; } -void _glfwPlatformIconifyWindow(_GLFWwindow* window) +void _glfwIconifyWindowX11(_GLFWwindow* window) { if (window->x11.overrideRedirect) { @@ -2332,7 +2326,7 @@ void _glfwPlatformIconifyWindow(_GLFWwindow* window) XFlush(_glfw.x11.display); } -void _glfwPlatformRestoreWindow(_GLFWwindow* window) +void _glfwRestoreWindowX11(_GLFWwindow* window) { if (window->x11.overrideRedirect) { @@ -2343,12 +2337,12 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) return; } - if (_glfwPlatformWindowIconified(window)) + if (_glfwWindowIconifiedX11(window)) { XMapWindow(_glfw.x11.display, window->x11.handle); waitForVisibilityNotify(window); } - else if (_glfwPlatformWindowVisible(window)) + else if (_glfwWindowVisibleX11(window)) { if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT && @@ -2366,7 +2360,7 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) XFlush(_glfw.x11.display); } -void _glfwPlatformMaximizeWindow(_GLFWwindow* window) +void _glfwMaximizeWindowX11(_GLFWwindow* window) { if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT || @@ -2375,7 +2369,7 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window) return; } - if (_glfwPlatformWindowVisible(window)) + if (_glfwWindowVisibleX11(window)) { sendEventToWM(window, _glfw.x11.NET_WM_STATE, @@ -2431,22 +2425,22 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window) XFlush(_glfw.x11.display); } -void _glfwPlatformShowWindow(_GLFWwindow* window) +void _glfwShowWindowX11(_GLFWwindow* window) { - if (_glfwPlatformWindowVisible(window)) + if (_glfwWindowVisibleX11(window)) return; XMapWindow(_glfw.x11.display, window->x11.handle); waitForVisibilityNotify(window); } -void _glfwPlatformHideWindow(_GLFWwindow* window) +void _glfwHideWindowX11(_GLFWwindow* window) { XUnmapWindow(_glfw.x11.display, window->x11.handle); XFlush(_glfw.x11.display); } -void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) +void _glfwRequestWindowAttentionX11(_GLFWwindow* window) { if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION) return; @@ -2458,11 +2452,11 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) 0, 1, 0); } -void _glfwPlatformFocusWindow(_GLFWwindow* window) +void _glfwFocusWindowX11(_GLFWwindow* window) { if (_glfw.x11.NET_ACTIVE_WINDOW) sendEventToWM(window, _glfw.x11.NET_ACTIVE_WINDOW, 1, 0, 0, 0, 0); - else if (_glfwPlatformWindowVisible(window)) + else if (_glfwWindowVisibleX11(window)) { XRaiseWindow(_glfw.x11.display, window->x11.handle); XSetInputFocus(_glfw.x11.display, window->x11.handle, @@ -2472,11 +2466,11 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window) XFlush(_glfw.x11.display); } -void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, - _GLFWmonitor* monitor, - int xpos, int ypos, - int width, int height, - int refreshRate) +void _glfwSetWindowMonitorX11(_GLFWwindow* window, + _GLFWmonitor* monitor, + int xpos, int ypos, + int width, int height, + int refreshRate) { if (window->monitor == monitor) { @@ -2500,8 +2494,8 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, if (window->monitor) { - _glfwPlatformSetWindowDecorated(window, window->decorated); - _glfwPlatformSetWindowFloating(window, window->floating); + _glfwSetWindowDecoratedX11(window, window->decorated); + _glfwSetWindowFloatingX11(window, window->floating); releaseMonitor(window); } @@ -2510,7 +2504,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, if (window->monitor) { - if (!_glfwPlatformWindowVisible(window)) + if (!_glfwWindowVisibleX11(window)) { XMapRaised(_glfw.x11.display, window->x11.handle); waitForVisibilityNotify(window); @@ -2529,7 +2523,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, XFlush(_glfw.x11.display); } -int _glfwPlatformWindowFocused(_GLFWwindow* window) +GLFWbool _glfwWindowFocusedX11(_GLFWwindow* window) { Window focused; int state; @@ -2538,22 +2532,21 @@ int _glfwPlatformWindowFocused(_GLFWwindow* window) return window->x11.handle == focused; } -int _glfwPlatformWindowIconified(_GLFWwindow* window) +GLFWbool _glfwWindowIconifiedX11(_GLFWwindow* window) { return getWindowState(window) == IconicState; } -int _glfwPlatformWindowVisible(_GLFWwindow* window) +GLFWbool _glfwWindowVisibleX11(_GLFWwindow* window) { XWindowAttributes wa; XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &wa); return wa.map_state == IsViewable; } -int _glfwPlatformWindowMaximized(_GLFWwindow* window) +GLFWbool _glfwWindowMaximizedX11(_GLFWwindow* window) { Atom* states; - unsigned long i; GLFWbool maximized = GLFW_FALSE; if (!_glfw.x11.NET_WM_STATE || @@ -2569,7 +2562,7 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window) XA_ATOM, (unsigned char**) &states); - for (i = 0; i < count; i++) + for (unsigned long i = 0; i < count; i++) { if (states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT || states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ) @@ -2585,7 +2578,7 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window) return maximized; } -int _glfwPlatformWindowHovered(_GLFWwindow* window) +GLFWbool _glfwWindowHoveredX11(_GLFWwindow* window) { Window w = _glfw.x11.root; while (w) @@ -2613,7 +2606,7 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window) return GLFW_FALSE; } -int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) +GLFWbool _glfwFramebufferTransparentX11(_GLFWwindow* window) { if (!window->x11.transparent) return GLFW_FALSE; @@ -2621,14 +2614,14 @@ int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) return XGetSelectionOwner(_glfw.x11.display, _glfw.x11.NET_WM_CM_Sx) != None; } -void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) +void _glfwSetWindowResizableX11(_GLFWwindow* window, GLFWbool enabled) { int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); + _glfwGetWindowSizeX11(window, &width, &height); updateNormalHints(window, width, height); } -void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) +void _glfwSetWindowDecoratedX11(_GLFWwindow* window, GLFWbool enabled) { struct { @@ -2650,12 +2643,12 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) sizeof(hints) / sizeof(long)); } -void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) +void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled) { if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_ABOVE) return; - if (_glfwPlatformWindowVisible(window)) + if (_glfwWindowVisibleX11(window)) { const long action = enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; sendEventToWM(window, @@ -2667,18 +2660,19 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) else { Atom* states = NULL; - unsigned long i, count; - - count = _glfwGetWindowPropertyX11(window->x11.handle, - _glfw.x11.NET_WM_STATE, - XA_ATOM, - (unsigned char**) &states); + const unsigned long count = + _glfwGetWindowPropertyX11(window->x11.handle, + _glfw.x11.NET_WM_STATE, + XA_ATOM, + (unsigned char**) &states); // NOTE: We don't check for failure as this property may not exist yet // and that's fine (and we'll create it implicitly with append) if (enabled) { + unsigned long i; + for (i = 0; i < count; i++) { if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE) @@ -2696,20 +2690,16 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) } else if (states) { - for (i = 0; i < count; i++) + for (unsigned long i = 0; i < count; i++) { if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE) + { + states[i] = states[count - 1]; + XChangeProperty(_glfw.x11.display, window->x11.handle, + _glfw.x11.NET_WM_STATE, XA_ATOM, 32, + PropModeReplace, (unsigned char*) states, count - 1); break; - } - - if (i < count) - { - states[i] = states[count - 1]; - count--; - - XChangeProperty(_glfw.x11.display, window->x11.handle, - _glfw.x11.NET_WM_STATE, XA_ATOM, 32, - PropModeReplace, (unsigned char*) states, count); + } } } @@ -2720,7 +2710,26 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) XFlush(_glfw.x11.display); } -float _glfwPlatformGetWindowOpacity(_GLFWwindow* window) +void _glfwSetWindowMousePassthroughX11(_GLFWwindow* window, GLFWbool enabled) +{ + if (!_glfw.x11.xshape.available) + return; + + if (enabled) + { + Region region = XCreateRegion(); + XShapeCombineRegion(_glfw.x11.display, window->x11.handle, + ShapeInput, 0, 0, region, ShapeSet); + XDestroyRegion(region); + } + else + { + XShapeCombineMask(_glfw.x11.display, window->x11.handle, + ShapeInput, 0, 0, None, ShapeSet); + } +} + +float _glfwGetWindowOpacityX11(_GLFWwindow* window) { float opacity = 1.f; @@ -2743,7 +2752,7 @@ float _glfwPlatformGetWindowOpacity(_GLFWwindow* window) return opacity; } -void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) +void _glfwSetWindowOpacityX11(_GLFWwindow* window, float opacity) { const CARD32 value = (CARD32) (0xffffffffu * (double) opacity); XChangeProperty(_glfw.x11.display, window->x11.handle, @@ -2751,7 +2760,7 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) PropModeReplace, (unsigned char*) &value, 1); } -void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) +void _glfwSetRawMouseMotionX11(_GLFWwindow *window, GLFWbool enabled) { if (!_glfw.x11.xi.available) return; @@ -2765,21 +2774,22 @@ void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) disableRawMouseMotion(window); } -GLFWbool _glfwPlatformRawMouseMotionSupported(void) +GLFWbool _glfwRawMouseMotionSupportedX11(void) { return _glfw.x11.xi.available; } -void _glfwPlatformPollEvents(void) +void _glfwPollEventsX11(void) { drainEmptyEvents(); -#if defined(__linux__) - _glfwDetectJoystickConnectionLinux(); +#if defined(GLFW_BUILD_LINUX_JOYSTICK) + if (_glfw.joysticksInitialized) + _glfwDetectJoystickConnectionLinux(); #endif XPending(_glfw.x11.display); - while (XQLength(_glfw.x11.display)) + while (QLength(_glfw.x11.display)) { XEvent event; XNextEvent(_glfw.x11.display, &event); @@ -2790,38 +2800,38 @@ void _glfwPlatformPollEvents(void) if (window) { int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); + _glfwGetWindowSizeX11(window, &width, &height); // NOTE: Re-center the cursor only if it has moved since the last call, // to avoid breaking glfwWaitEvents with MotionNotify if (window->x11.lastCursorPosX != width / 2 || window->x11.lastCursorPosY != height / 2) { - _glfwPlatformSetCursorPos(window, width / 2, height / 2); + _glfwSetCursorPosX11(window, width / 2, height / 2); } } XFlush(_glfw.x11.display); } -void _glfwPlatformWaitEvents(void) +void _glfwWaitEventsX11(void) { waitForAnyEvent(NULL); - _glfwPlatformPollEvents(); + _glfwPollEventsX11(); } -void _glfwPlatformWaitEventsTimeout(double timeout) +void _glfwWaitEventsTimeoutX11(double timeout) { waitForAnyEvent(&timeout); - _glfwPlatformPollEvents(); + _glfwPollEventsX11(); } -void _glfwPlatformPostEmptyEvent(void) +void _glfwPostEmptyEventX11(void) { writeEmptyEvent(); } -void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) +void _glfwGetCursorPosX11(_GLFWwindow* window, double* xpos, double* ypos) { Window root, child; int rootX, rootY, childX, childY; @@ -2838,7 +2848,7 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) *ypos = childY; } -void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) +void _glfwSetCursorPosX11(_GLFWwindow* window, double x, double y) { // Store the new position so it can be recognized later window->x11.warpCursorPosX = (int) x; @@ -2849,34 +2859,60 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) XFlush(_glfw.x11.display); } -void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) +void _glfwSetCursorModeX11(_GLFWwindow* window, int mode) { - if (mode == GLFW_CURSOR_DISABLED) + if (_glfwWindowFocusedX11(window)) { - if (_glfwPlatformWindowFocused(window)) - disableCursor(window); - } - else if (_glfw.x11.disabledCursorWindow == window) - enableCursor(window); - else - updateCursorImage(window); + if (mode == GLFW_CURSOR_DISABLED) + { + _glfwGetCursorPosX11(window, + &_glfw.x11.restoreCursorPosX, + &_glfw.x11.restoreCursorPosY); + _glfwCenterCursorInContentArea(window); + if (window->rawMouseMotion) + enableRawMouseMotion(window); + } + else if (_glfw.x11.disabledCursorWindow == window) + { + if (window->rawMouseMotion) + disableRawMouseMotion(window); + } + if (mode == GLFW_CURSOR_DISABLED || mode == GLFW_CURSOR_CAPTURED) + captureCursor(window); + else + releaseCursor(); + + if (mode == GLFW_CURSOR_DISABLED) + _glfw.x11.disabledCursorWindow = window; + else if (_glfw.x11.disabledCursorWindow == window) + { + _glfw.x11.disabledCursorWindow = NULL; + _glfwSetCursorPosX11(window, + _glfw.x11.restoreCursorPosX, + _glfw.x11.restoreCursorPosY); + } + } + + updateCursorImage(window); XFlush(_glfw.x11.display); } -const char* _glfwPlatformGetScancodeName(int scancode) +const char* _glfwGetScancodeNameX11(int scancode) { if (!_glfw.x11.xkb.available) return NULL; - if (scancode < 0 || scancode > 0xff || - _glfw.x11.keycodes[scancode] == GLFW_KEY_UNKNOWN) + if (scancode < 0 || scancode > 0xff) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode); return NULL; } const int key = _glfw.x11.keycodes[scancode]; + if (key == GLFW_KEY_UNKNOWN) + return NULL; + const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 0); if (keysym == NoSymbol) @@ -2894,71 +2930,140 @@ const char* _glfwPlatformGetScancodeName(int scancode) return _glfw.x11.keynames[key]; } -int _glfwPlatformGetKeyScancode(int key) +int _glfwGetKeyScancodeX11(int key) { return _glfw.x11.scancodes[key]; } -int _glfwPlatformCreateCursor(_GLFWcursor* cursor, +GLFWbool _glfwCreateCursorX11(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot) { - cursor->x11.handle = _glfwCreateCursorX11(image, xhot, yhot); + cursor->x11.handle = _glfwCreateNativeCursorX11(image, xhot, yhot); if (!cursor->x11.handle) return GLFW_FALSE; return GLFW_TRUE; } -int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) +GLFWbool _glfwCreateStandardCursorX11(_GLFWcursor* cursor, int shape) { - int native = 0; + if (_glfw.x11.xcursor.handle) + { + char* theme = XcursorGetTheme(_glfw.x11.display); + if (theme) + { + const int size = XcursorGetDefaultSize(_glfw.x11.display); + const char* name = NULL; - if (shape == GLFW_ARROW_CURSOR) - native = XC_left_ptr; - else if (shape == GLFW_IBEAM_CURSOR) - native = XC_xterm; - else if (shape == GLFW_CROSSHAIR_CURSOR) - native = XC_crosshair; - else if (shape == GLFW_HAND_CURSOR) - native = XC_hand2; - else if (shape == GLFW_HRESIZE_CURSOR) - native = XC_sb_h_double_arrow; - else if (shape == GLFW_VRESIZE_CURSOR) - native = XC_sb_v_double_arrow; - else - return GLFW_FALSE; + switch (shape) + { + case GLFW_ARROW_CURSOR: + name = "default"; + break; + case GLFW_IBEAM_CURSOR: + name = "text"; + break; + case GLFW_CROSSHAIR_CURSOR: + name = "crosshair"; + break; + case GLFW_POINTING_HAND_CURSOR: + name = "pointer"; + break; + case GLFW_RESIZE_EW_CURSOR: + name = "ew-resize"; + break; + case GLFW_RESIZE_NS_CURSOR: + name = "ns-resize"; + break; + case GLFW_RESIZE_NWSE_CURSOR: + name = "nwse-resize"; + break; + case GLFW_RESIZE_NESW_CURSOR: + name = "nesw-resize"; + break; + case GLFW_RESIZE_ALL_CURSOR: + name = "all-scroll"; + break; + case GLFW_NOT_ALLOWED_CURSOR: + name = "not-allowed"; + break; + } + + XcursorImage* image = XcursorLibraryLoadImage(name, theme, size); + if (image) + { + cursor->x11.handle = XcursorImageLoadCursor(_glfw.x11.display, image); + XcursorImageDestroy(image); + } + } + } - cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native); if (!cursor->x11.handle) { - _glfwInputError(GLFW_PLATFORM_ERROR, - "X11: Failed to create standard cursor"); - return GLFW_FALSE; + unsigned int native = 0; + + switch (shape) + { + case GLFW_ARROW_CURSOR: + native = XC_left_ptr; + break; + case GLFW_IBEAM_CURSOR: + native = XC_xterm; + break; + case GLFW_CROSSHAIR_CURSOR: + native = XC_crosshair; + break; + case GLFW_POINTING_HAND_CURSOR: + native = XC_hand2; + break; + case GLFW_RESIZE_EW_CURSOR: + native = XC_sb_h_double_arrow; + break; + case GLFW_RESIZE_NS_CURSOR: + native = XC_sb_v_double_arrow; + break; + case GLFW_RESIZE_ALL_CURSOR: + native = XC_fleur; + break; + default: + _glfwInputError(GLFW_CURSOR_UNAVAILABLE, + "X11: Standard cursor shape unavailable"); + return GLFW_FALSE; + } + + cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native); + if (!cursor->x11.handle) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Failed to create standard cursor"); + return GLFW_FALSE; + } } return GLFW_TRUE; } -void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) +void _glfwDestroyCursorX11(_GLFWcursor* cursor) { if (cursor->x11.handle) XFreeCursor(_glfw.x11.display, cursor->x11.handle); } -void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) +void _glfwSetCursorX11(_GLFWwindow* window, _GLFWcursor* cursor) { - if (window->cursorMode == GLFW_CURSOR_NORMAL) + if (window->cursorMode == GLFW_CURSOR_NORMAL || + window->cursorMode == GLFW_CURSOR_CAPTURED) { updateCursorImage(window); XFlush(_glfw.x11.display); } } -void _glfwPlatformSetClipboardString(const char* string) +void _glfwSetClipboardStringX11(const char* string) { char* copy = _glfw_strdup(string); - free(_glfw.x11.clipboardString); + _glfw_free(_glfw.x11.clipboardString); _glfw.x11.clipboardString = copy; XSetSelectionOwner(_glfw.x11.display, @@ -2974,12 +3079,61 @@ void _glfwPlatformSetClipboardString(const char* string) } } -const char* _glfwPlatformGetClipboardString(void) +const char* _glfwGetClipboardStringX11(void) { return getSelectionString(_glfw.x11.CLIPBOARD); } -void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) +EGLenum _glfwGetEGLPlatformX11(EGLint** attribs) +{ + if (_glfw.egl.ANGLE_platform_angle) + { + int type = 0; + + if (_glfw.egl.ANGLE_platform_angle_opengl) + { + if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGL) + type = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE; + } + + if (_glfw.egl.ANGLE_platform_angle_vulkan) + { + if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_VULKAN) + type = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE; + } + + if (type) + { + *attribs = _glfw_calloc(5, sizeof(EGLint)); + (*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE; + (*attribs)[1] = type; + (*attribs)[2] = EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE; + (*attribs)[3] = EGL_PLATFORM_X11_EXT; + (*attribs)[4] = EGL_NONE; + return EGL_PLATFORM_ANGLE_ANGLE; + } + } + + if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_x11) + return EGL_PLATFORM_X11_EXT; + + return 0; +} + +EGLNativeDisplayType _glfwGetEGLNativeDisplayX11(void) +{ + return _glfw.x11.display; +} + +EGLNativeWindowType _glfwGetEGLNativeWindowX11(_GLFWwindow* window) +{ + if (_glfw.egl.platform) + return &window->x11.handle; + else + return (EGLNativeWindowType) window->x11.handle; +} + +void _glfwGetRequiredInstanceExtensionsX11(char** extensions) { if (!_glfw.vk.KHR_surface) return; @@ -3000,7 +3154,7 @@ void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) extensions[1] = "VK_KHR_xlib_surface"; } -int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, +GLFWbool _glfwGetPhysicalDevicePresentationSupportX11(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily) { @@ -3053,10 +3207,10 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, } } -VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, - _GLFWwindow* window, - const VkAllocationCallbacks* allocator, - VkSurfaceKHR* surface) +VkResult _glfwCreateWindowSurfaceX11(VkInstance instance, + _GLFWwindow* window, + const VkAllocationCallbacks* allocator, + VkSurfaceKHR* surface) { if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle) { @@ -3136,6 +3290,13 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, GLFWAPI Display* glfwGetX11Display(void) { _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (_glfw.platform.platformID != GLFW_PLATFORM_X11) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized"); + return NULL; + } + return _glfw.x11.display; } @@ -3143,6 +3304,13 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(None); + + if (_glfw.platform.platformID != GLFW_PLATFORM_X11) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized"); + return None; + } + return window->x11.handle; } @@ -3150,7 +3318,13 @@ GLFWAPI void glfwSetX11SelectionString(const char* string) { _GLFW_REQUIRE_INIT(); - free(_glfw.x11.primarySelectionString); + if (_glfw.platform.platformID != GLFW_PLATFORM_X11) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized"); + return; + } + + _glfw_free(_glfw.x11.primarySelectionString); _glfw.x11.primarySelectionString = _glfw_strdup(string); XSetSelectionOwner(_glfw.x11.display, @@ -3169,6 +3343,15 @@ GLFWAPI void glfwSetX11SelectionString(const char* string) GLFWAPI const char* glfwGetX11SelectionString(void) { _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (_glfw.platform.platformID != GLFW_PLATFORM_X11) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized"); + return NULL; + } + return getSelectionString(_glfw.x11.PRIMARY); } +#endif // _GLFW_X11 + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/xkb_unicode.c b/src/lib/src/vendor/glfw-3.4/src/xkb_unicode.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/src/xkb_unicode.c rename to src/lib/src/vendor/glfw-3.4/src/xkb_unicode.c index 859bedc..6b8dfca 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/xkb_unicode.c +++ b/src/lib/src/vendor/glfw-3.4/src/xkb_unicode.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 X11 - www.glfw.org +// GLFW 3.4 X11 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2017 Camilla Löwy @@ -24,11 +24,10 @@ // distribution. // //======================================================================== -// It is fine to use C99 in this file because it will not be built with VS -//======================================================================== #include "internal.h" +#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND) /* * Marcus: This code was originally written by Markus G. Kuhn. @@ -940,3 +939,5 @@ uint32_t _glfwKeySym2Unicode(unsigned int keysym) return GLFW_INVALID_CODEPOINT; } +#endif // _GLFW_WAYLAND or _GLFW_X11 + diff --git a/src/lib/src/vendor/glfw-3.3.8/src/xkb_unicode.h b/src/lib/src/vendor/glfw-3.4/src/xkb_unicode.h similarity index 97% rename from src/lib/src/vendor/glfw-3.3.8/src/xkb_unicode.h rename to src/lib/src/vendor/glfw-3.4/src/xkb_unicode.h index be97cdc..b07408f 100644 --- a/src/lib/src/vendor/glfw-3.3.8/src/xkb_unicode.h +++ b/src/lib/src/vendor/glfw-3.4/src/xkb_unicode.h @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.3 Linux - www.glfw.org +// GLFW 3.4 Linux - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2014 Jonas Ådahl // diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/CMakeLists.txt b/src/lib/src/vendor/glfw-3.4/tests/CMakeLists.txt similarity index 71% rename from src/lib/src/vendor/glfw-3.3.8/tests/CMakeLists.txt rename to src/lib/src/vendor/glfw-3.4/tests/CMakeLists.txt index 91374b2..f81cfeb 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/CMakeLists.txt +++ b/src/lib/src/vendor/glfw-3.4/tests/CMakeLists.txt @@ -12,26 +12,14 @@ if (MSVC OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC") add_definitions(-D_CRT_SECURE_NO_WARNINGS) endif() -set(GLAD_GL "${GLFW_SOURCE_DIR}/deps/glad/gl.h" - "${GLFW_SOURCE_DIR}/deps/glad_gl.c") -set(GLAD_VULKAN "${GLFW_SOURCE_DIR}/deps/glad/vulkan.h" - "${GLFW_SOURCE_DIR}/deps/glad_vulkan.c") +set(GLAD_GL "${GLFW_SOURCE_DIR}/deps/glad/gl.h") +set(GLAD_VULKAN "${GLFW_SOURCE_DIR}/deps/glad/vulkan.h") set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h" "${GLFW_SOURCE_DIR}/deps/getopt.c") set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h" "${GLFW_SOURCE_DIR}/deps/tinycthread.c") -if (${CMAKE_VERSION} VERSION_EQUAL "3.1.0" OR - ${CMAKE_VERSION} VERSION_GREATER "3.1.0") - set(CMAKE_C_STANDARD 99) -else() - # Remove this fallback when removing support for CMake version less than 3.1 - add_compile_options("$<$:-std=c99>" - "$<$:-std=c99>" - "$<$:-std=c99>") - -endif() - +add_executable(allocator allocator.c ${GLAD_GL}) add_executable(clipboard clipboard.c ${GETOPT} ${GLAD_GL}) add_executable(events events.c ${GETOPT} ${GLAD_GL}) add_executable(msaa msaa.c ${GETOPT} ${GLAD_GL}) @@ -46,27 +34,27 @@ add_executable(gamma WIN32 MACOSX_BUNDLE gamma.c ${GLAD_GL}) add_executable(icon WIN32 MACOSX_BUNDLE icon.c ${GLAD_GL}) add_executable(inputlag WIN32 MACOSX_BUNDLE inputlag.c ${GETOPT} ${GLAD_GL}) add_executable(joysticks WIN32 MACOSX_BUNDLE joysticks.c ${GLAD_GL}) -add_executable(opacity WIN32 MACOSX_BUNDLE opacity.c ${GLAD_GL}) add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c ${GLAD_GL}) add_executable(threads WIN32 MACOSX_BUNDLE threads.c ${TINYCTHREAD} ${GLAD_GL}) add_executable(timeout WIN32 MACOSX_BUNDLE timeout.c ${GLAD_GL}) add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD_GL}) add_executable(triangle-vulkan WIN32 triangle-vulkan.c ${GLAD_VULKAN}) -add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${GETOPT} ${GLAD_GL}) +add_executable(window WIN32 MACOSX_BUNDLE window.c ${GLAD_GL}) -target_link_libraries(empty "${CMAKE_THREAD_LIBS_INIT}") -target_link_libraries(threads "${CMAKE_THREAD_LIBS_INIT}") +target_link_libraries(empty Threads::Threads) +target_link_libraries(threads Threads::Threads) if (RT_LIBRARY) target_link_libraries(empty "${RT_LIBRARY}") target_link_libraries(threads "${RT_LIBRARY}") endif() -set(GUI_ONLY_BINARIES empty gamma icon inputlag joysticks opacity tearing - threads timeout title triangle-vulkan windows) -set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen - cursor) +set(GUI_ONLY_BINARIES empty gamma icon inputlag joysticks tearing threads + timeout title triangle-vulkan window) +set(CONSOLE_BINARIES allocator clipboard events msaa glfwinfo iconify monitors + reopen cursor) set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES + C_STANDARD 99 FOLDER "GLFW3/Tests") if (MSVC) @@ -84,16 +72,15 @@ if (APPLE) set_target_properties(gamma PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gamma") set_target_properties(inputlag PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Input Lag") set_target_properties(joysticks PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Joysticks") - set_target_properties(opacity PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Opacity") set_target_properties(tearing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Tearing") set_target_properties(threads PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Threads") set_target_properties(timeout PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Timeout") set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title") - set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows") + set_target_properties(window PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Window") set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION} MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION} - MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/MacOSXBundleInfo.plist.in") + MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/Info.plist.in") endif() diff --git a/src/lib/src/vendor/glfw-3.4/tests/allocator.c b/src/lib/src/vendor/glfw-3.4/tests/allocator.c new file mode 100644 index 0000000..3fb004d --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/tests/allocator.c @@ -0,0 +1,142 @@ +//======================================================================== +// Custom heap allocator test +// Copyright (c) Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as 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 GLAD_GL_IMPLEMENTATION +#include +#define GLFW_INCLUDE_NONE +#include + +#include +#include +#include + +#define CALL(x) (function_name = #x, x) +static const char* function_name = NULL; + +struct allocator_stats +{ + size_t total; + size_t current; + size_t maximum; +}; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void* allocate(size_t size, void* user) +{ + struct allocator_stats* stats = user; + assert(size > 0); + + stats->total += size; + stats->current += size; + if (stats->current > stats->maximum) + stats->maximum = stats->current; + + printf("%s: allocate %zu bytes (current %zu maximum %zu total %zu)\n", + function_name, size, stats->current, stats->maximum, stats->total); + + size_t* real_block = malloc(size + sizeof(size_t)); + assert(real_block != NULL); + *real_block = size; + return real_block + 1; +} + +static void deallocate(void* block, void* user) +{ + struct allocator_stats* stats = user; + assert(block != NULL); + + size_t* real_block = (size_t*) block - 1; + stats->current -= *real_block; + + printf("%s: deallocate %zu bytes (current %zu maximum %zu total %zu)\n", + function_name, *real_block, stats->current, stats->maximum, stats->total); + + free(real_block); +} + +static void* reallocate(void* block, size_t size, void* user) +{ + struct allocator_stats* stats = user; + assert(block != NULL); + assert(size > 0); + + size_t* real_block = (size_t*) block - 1; + stats->total += size; + stats->current += size - *real_block; + if (stats->current > stats->maximum) + stats->maximum = stats->current; + + printf("%s: reallocate %zu bytes to %zu bytes (current %zu maximum %zu total %zu)\n", + function_name, *real_block, size, stats->current, stats->maximum, stats->total); + + real_block = realloc(real_block, size + sizeof(size_t)); + assert(real_block != NULL); + *real_block = size; + return real_block + 1; +} + +int main(void) +{ + struct allocator_stats stats = {0}; + const GLFWallocator allocator = + { + .allocate = allocate, + .deallocate = deallocate, + .reallocate = reallocate, + .user = &stats + }; + + glfwSetErrorCallback(error_callback); + glfwInitAllocator(&allocator); + + if (!CALL(glfwInit)()) + exit(EXIT_FAILURE); + + GLFWwindow* window = CALL(glfwCreateWindow)(400, 400, "Custom allocator test", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + CALL(glfwMakeContextCurrent)(window); + gladLoadGL(glfwGetProcAddress); + CALL(glfwSwapInterval)(1); + + while (!CALL(glfwWindowShouldClose)(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + CALL(glfwSwapBuffers)(window); + CALL(glfwWaitEvents)(); + } + + CALL(glfwTerminate)(); + exit(EXIT_SUCCESS); +} + diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/clipboard.c b/src/lib/src/vendor/glfw-3.4/tests/clipboard.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/tests/clipboard.c rename to src/lib/src/vendor/glfw-3.4/tests/clipboard.c index 41454a3..eaad516 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/clipboard.c +++ b/src/lib/src/vendor/glfw-3.4/tests/clipboard.c @@ -27,6 +27,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/cursor.c b/src/lib/src/vendor/glfw-3.4/tests/cursor.c similarity index 93% rename from src/lib/src/vendor/glfw-3.3.8/tests/cursor.c rename to src/lib/src/vendor/glfw-3.4/tests/cursor.c index b6288f6..37f3299 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/cursor.c +++ b/src/lib/src/vendor/glfw-3.4/tests/cursor.c @@ -30,6 +30,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include @@ -69,7 +70,7 @@ static int swap_interval = 1; static int wait_events = GLFW_TRUE; static int animate_cursor = GLFW_FALSE; static int track_cursor = GLFW_FALSE; -static GLFWcursor* standard_cursors[6]; +static GLFWcursor* standard_cursors[10]; static GLFWcursor* tracking_cursor = NULL; static void error_callback(int error, const char* description) @@ -171,7 +172,8 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action, case GLFW_KEY_ESCAPE: { - if (glfwGetInputMode(window, GLFW_CURSOR) != GLFW_CURSOR_DISABLED) + const int mode = glfwGetInputMode(window, GLFW_CURSOR); + if (mode != GLFW_CURSOR_DISABLED && mode != GLFW_CURSOR_CAPTURED) { glfwSetWindowShouldClose(window, GLFW_TRUE); break; @@ -196,6 +198,11 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action, printf("(( cursor is hidden ))\n"); break; + case GLFW_KEY_C: + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_CAPTURED); + printf("(( cursor is captured ))\n"); + break; + case GLFW_KEY_R: if (!glfwRawMouseMotionSupported()) break; @@ -271,28 +278,24 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action, break; case GLFW_KEY_1: - glfwSetCursor(window, standard_cursors[0]); - break; - case GLFW_KEY_2: - glfwSetCursor(window, standard_cursors[1]); - break; - case GLFW_KEY_3: - glfwSetCursor(window, standard_cursors[2]); - break; - case GLFW_KEY_4: - glfwSetCursor(window, standard_cursors[3]); - break; - case GLFW_KEY_5: - glfwSetCursor(window, standard_cursors[4]); - break; - case GLFW_KEY_6: - glfwSetCursor(window, standard_cursors[5]); + case GLFW_KEY_7: + case GLFW_KEY_8: + case GLFW_KEY_9: + { + int index = key - GLFW_KEY_1; + if (mods & GLFW_MOD_SHIFT) + index += 9; + + if (index < sizeof(standard_cursors) / sizeof(standard_cursors[0])) + glfwSetCursor(window, standard_cursors[index]); + break; + } case GLFW_KEY_F11: case GLFW_KEY_ENTER: @@ -358,17 +361,16 @@ int main(void) GLFW_ARROW_CURSOR, GLFW_IBEAM_CURSOR, GLFW_CROSSHAIR_CURSOR, - GLFW_HAND_CURSOR, - GLFW_HRESIZE_CURSOR, - GLFW_VRESIZE_CURSOR + GLFW_POINTING_HAND_CURSOR, + GLFW_RESIZE_EW_CURSOR, + GLFW_RESIZE_NS_CURSOR, + GLFW_RESIZE_NWSE_CURSOR, + GLFW_RESIZE_NESW_CURSOR, + GLFW_RESIZE_ALL_CURSOR, + GLFW_NOT_ALLOWED_CURSOR }; standard_cursors[i] = glfwCreateStandardCursor(shapes[i]); - if (!standard_cursors[i]) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/empty.c b/src/lib/src/vendor/glfw-3.4/tests/empty.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/tests/empty.c rename to src/lib/src/vendor/glfw-3.4/tests/empty.c index c3877a7..72caccb 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/empty.c +++ b/src/lib/src/vendor/glfw-3.4/tests/empty.c @@ -29,6 +29,7 @@ #include "tinycthread.h" +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/events.c b/src/lib/src/vendor/glfw-3.4/tests/events.c similarity index 92% rename from src/lib/src/vendor/glfw-3.3.8/tests/events.c rename to src/lib/src/vendor/glfw-3.4/tests/events.c index f29dfbb..fdc3c19 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/events.c +++ b/src/lib/src/vendor/glfw-3.4/tests/events.c @@ -31,6 +31,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include @@ -320,6 +321,12 @@ static void window_close_callback(GLFWwindow* window) printf("%08x to %i at %0.3f: Window close\n", counter++, slot->number, glfwGetTime()); + if (!slot->closeable) + { + printf("(( closing is disabled, press %s to re-enable )\n", + glfwGetKeyName(GLFW_KEY_C, 0)); + } + glfwSetWindowShouldClose(window, slot->closeable); } @@ -393,24 +400,34 @@ static void scroll_callback(GLFWwindow* window, double x, double y) static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { Slot* slot = glfwGetWindowUserPointer(window); - const char* name = glfwGetKeyName(key, scancode); - if (name) + if (key == GLFW_KEY_UNKNOWN) { - printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (%s) (with%s) was %s\n", - counter++, slot->number, glfwGetTime(), key, scancode, - get_key_name(key), - name, - get_mods_name(mods), - get_action_name(action)); + printf("%08x to %i at %0.3f: Key (%s) Scancode 0x%04x (with%s) was %s\n", + counter++, slot->number, glfwGetTime(), + get_key_name(key), scancode, + get_mods_name(mods), + get_action_name(action)); } else { - printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (with%s) was %s\n", - counter++, slot->number, glfwGetTime(), key, scancode, - get_key_name(key), - get_mods_name(mods), - get_action_name(action)); + const char* name = glfwGetKeyName(key, scancode); + if (name) + { + printf("%08x to %i at %0.3f: Key 0x%04x (%s) Scancode 0x%04x Name %s (with%s) was %s\n", + counter++, slot->number, glfwGetTime(), + key, get_key_name(key), scancode, name, + get_mods_name(mods), + get_action_name(action)); + } + else + { + printf("%08x to %i at %0.3f: Key 0x%04x (%s) Scancode 0x%04x (with%s) was %s\n", + counter++, slot->number, glfwGetTime(), + key, get_key_name(key), scancode, + get_mods_name(mods), + get_action_name(action)); + } } if (action != GLFW_PRESS) @@ -503,6 +520,20 @@ static void joystick_callback(int jid, int event) axisCount, buttonCount, hatCount); + + if (glfwJoystickIsGamepad(jid)) + { + printf(" Joystick %i (%s) has a gamepad mapping (%s)\n", + jid, + glfwGetJoystickGUID(jid), + glfwGetGamepadName(jid)); + } + else + { + printf(" Joystick %i (%s) has no gamepad mapping\n", + jid, + glfwGetJoystickGUID(jid)); + } } else { @@ -621,7 +652,7 @@ int main(int argc, char** argv) glfwMakeContextCurrent(slots[i].window); gladLoadGL(glfwGetProcAddress); - glfwSwapInterval(1); + glfwSwapBuffers(slots[i].window); } printf("Main loop starting\n"); diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/gamma.c b/src/lib/src/vendor/glfw-3.4/tests/gamma.c similarity index 98% rename from src/lib/src/vendor/glfw-3.3.8/tests/gamma.c rename to src/lib/src/vendor/glfw-3.4/tests/gamma.c index 7419592..d1f6dc2 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/gamma.c +++ b/src/lib/src/vendor/glfw-3.4/tests/gamma.c @@ -28,6 +28,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include @@ -101,6 +102,7 @@ int main(int argc, char** argv) monitor = glfwGetPrimaryMonitor(); glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); + glfwWindowHint(GLFW_WIN32_KEYBOARD_MENU, GLFW_TRUE); window = glfwCreateWindow(800, 400, "Gamma Test", NULL, NULL); if (!window) diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/glfwinfo.c b/src/lib/src/vendor/glfw-3.4/tests/glfwinfo.c similarity index 50% rename from src/lib/src/vendor/glfw-3.3.8/tests/glfwinfo.c rename to src/lib/src/vendor/glfw-3.4/tests/glfwinfo.c index f681e0a..12acbcc 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/glfwinfo.c +++ b/src/lib/src/vendor/glfw-3.4/tests/glfwinfo.c @@ -23,7 +23,9 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include +#define GLAD_VULKAN_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include @@ -31,6 +33,7 @@ #include #include #include +#include #include "getopt.h" @@ -54,10 +57,31 @@ #define BEHAVIOR_NAME_NONE "none" #define BEHAVIOR_NAME_FLUSH "flush" +#define ANGLE_TYPE_OPENGL "gl" +#define ANGLE_TYPE_OPENGLES "es" +#define ANGLE_TYPE_D3D9 "d3d9" +#define ANGLE_TYPE_D3D11 "d3d11" +#define ANGLE_TYPE_VULKAN "vk" +#define ANGLE_TYPE_METAL "mtl" + +#define PLATFORM_NAME_ANY "any" +#define PLATFORM_NAME_WIN32 "win32" +#define PLATFORM_NAME_COCOA "cooca" +#define PLATFORM_NAME_WL "wayland" +#define PLATFORM_NAME_X11 "x11" +#define PLATFORM_NAME_NULL "null" + static void usage(void) { printf("Usage: glfwinfo [OPTION]...\n"); printf("Options:\n"); + printf(" --platform=PLATFORM the platform to use (" + PLATFORM_NAME_ANY " or " + PLATFORM_NAME_WIN32 " or " + PLATFORM_NAME_COCOA " or " + PLATFORM_NAME_X11 " or " + PLATFORM_NAME_WL " or " + PLATFORM_NAME_NULL ")\n"); printf(" -a, --client-api=API the client API to use (" API_NAME_OPENGL " or " API_NAME_OPENGL_ES ")\n"); @@ -100,7 +124,15 @@ static void usage(void) printf(" --srgb request an sRGB capable framebuffer\n"); printf(" --singlebuffer request single-buffering\n"); printf(" --no-error request a context that does not emit errors\n"); + printf(" --angle-type=TYPE the ANGLE platform type to use (" + ANGLE_TYPE_OPENGL ", " + ANGLE_TYPE_OPENGLES ", " + ANGLE_TYPE_D3D9 ", " + ANGLE_TYPE_D3D11 ", " + ANGLE_TYPE_VULKAN " or " + ANGLE_TYPE_METAL ")\n"); printf(" --graphics-switching request macOS graphics switching\n"); + printf(" --disable-xcb-surface disable VK_KHR_xcb_surface extension\n"); } static void error_callback(int error, const char* description) @@ -108,6 +140,22 @@ static void error_callback(int error, const char* description) fprintf(stderr, "Error: %s\n", description); } +static const char* get_platform_name(int platform) +{ + if (platform == GLFW_PLATFORM_WIN32) + return "Win32"; + else if (platform == GLFW_PLATFORM_COCOA) + return "Cocoa"; + else if (platform == GLFW_PLATFORM_WAYLAND) + return "Wayland"; + else if (platform == GLFW_PLATFORM_X11) + return "X11"; + else if (platform == GLFW_PLATFORM_NULL) + return "Null"; + + return "unknown"; +} + static const char* get_device_type_name(VkPhysicalDeviceType type) { if (type == VK_PHYSICAL_DEVICE_TYPE_OTHER) @@ -176,22 +224,19 @@ static const char* get_strategy_name_glfw(int strategy) static void list_context_extensions(int client, int major, int minor) { - int i; - GLint count; - const GLubyte* extensions; - printf("%s context extensions:\n", get_api_name(client)); if (client == GLFW_OPENGL_API && major > 2) { + GLint count; glGetIntegerv(GL_NUM_EXTENSIONS, &count); - for (i = 0; i < count; i++) + for (int i = 0; i < count; i++) printf(" %s\n", (const char*) glGetStringi(GL_EXTENSIONS, i)); } else { - extensions = glGetString(GL_EXTENSIONS); + const GLubyte* extensions = glGetString(GL_EXTENSIONS); while (*extensions != '\0') { putchar(' '); @@ -212,27 +257,19 @@ static void list_context_extensions(int client, int major, int minor) static void list_vulkan_instance_layers(void) { - uint32_t i, lp_count = 0; - VkLayerProperties* lp; - printf("Vulkan instance layers:\n"); - if (vkEnumerateInstanceLayerProperties(&lp_count, NULL) != VK_SUCCESS) - return; + uint32_t lp_count; + vkEnumerateInstanceLayerProperties(&lp_count, NULL); + VkLayerProperties* lp = calloc(lp_count, sizeof(VkLayerProperties)); + vkEnumerateInstanceLayerProperties(&lp_count, lp); - lp = calloc(lp_count, sizeof(VkLayerProperties)); - - if (vkEnumerateInstanceLayerProperties(&lp_count, lp) != VK_SUCCESS) + for (uint32_t i = 0; i < lp_count; i++) { - free(lp); - return; - } - - for (i = 0; i < lp_count; i++) - { - printf(" %s (v%u) \"%s\"\n", + printf(" %s (spec version %u.%u) \"%s\"\n", lp[i].layerName, - lp[i].specVersion >> 22, + VK_VERSION_MAJOR(lp[i].specVersion), + VK_VERSION_MINOR(lp[i].specVersion), lp[i].description); } @@ -241,34 +278,26 @@ static void list_vulkan_instance_layers(void) static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice device) { - uint32_t i, lp_count; - VkLayerProperties* lp; - printf("Vulkan device layers:\n"); - if (vkEnumerateDeviceLayerProperties(device, &lp_count, NULL) != VK_SUCCESS) - return; + uint32_t lp_count; + vkEnumerateDeviceLayerProperties(device, &lp_count, NULL); + VkLayerProperties* lp = calloc(lp_count, sizeof(VkLayerProperties)); + vkEnumerateDeviceLayerProperties(device, &lp_count, lp); - lp = calloc(lp_count, sizeof(VkLayerProperties)); - - if (vkEnumerateDeviceLayerProperties(device, &lp_count, lp) != VK_SUCCESS) + for (uint32_t i = 0; i < lp_count; i++) { - free(lp); - return; - } - - for (i = 0; i < lp_count; i++) - { - printf(" %s (v%u) \"%s\"\n", + printf(" %s (spec version %u.%u) \"%s\"\n", lp[i].layerName, - lp[i].specVersion >> 22, + VK_VERSION_MAJOR(lp[i].specVersion), + VK_VERSION_MINOR(lp[i].specVersion), lp[i].description); } free(lp); } -static int valid_version(void) +static bool valid_version(void) { int major, minor, revision; glfwGetVersion(&major, &minor, &revision); @@ -276,13 +305,13 @@ static int valid_version(void) if (major != GLFW_VERSION_MAJOR) { printf("*** ERROR: GLFW major version mismatch! ***\n"); - return GLFW_FALSE; + return false; } if (minor != GLFW_VERSION_MINOR || revision != GLFW_VERSION_REVISION) printf("*** WARNING: GLFW version mismatch! ***\n"); - return GLFW_TRUE; + return true; } static void print_version(void) @@ -298,23 +327,73 @@ static void print_version(void) printf("GLFW library version string: \"%s\"\n", glfwGetVersionString()); } +static void print_platform(void) +{ + const int platforms[] = + { + GLFW_PLATFORM_WIN32, + GLFW_PLATFORM_COCOA, + GLFW_PLATFORM_WAYLAND, + GLFW_PLATFORM_X11, + GLFW_PLATFORM_NULL + }; + + printf("GLFW platform: %s\n", get_platform_name(glfwGetPlatform())); + printf("GLFW supported platforms:\n"); + + for (size_t i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) + { + if (glfwPlatformSupported(platforms[i])) + printf(" %s\n", get_platform_name(platforms[i])); + } +} + int main(int argc, char** argv) { - int ch, client, major, minor, revision, profile; - GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits; - int list_extensions = GLFW_FALSE, list_layers = GLFW_FALSE; - GLenum error; - GLFWwindow* window; + int ch; + bool list_extensions = false, list_layers = false; - enum { CLIENT, CONTEXT, BEHAVIOR, DEBUG_CONTEXT, FORWARD, HELP, + // These duplicate the defaults for each hint + int platform = GLFW_ANY_PLATFORM; + int client_api = GLFW_OPENGL_API; + int context_major = 1; + int context_minor = 0; + int context_release = GLFW_ANY_RELEASE_BEHAVIOR; + int context_creation_api = GLFW_NATIVE_CONTEXT_API; + int context_robustness = GLFW_NO_ROBUSTNESS; + bool context_debug = false; + bool context_no_error = false; + bool opengl_forward = false; + int opengl_profile = GLFW_OPENGL_ANY_PROFILE; + int fb_red_bits = 8; + int fb_green_bits = 8; + int fb_blue_bits = 8; + int fb_alpha_bits = 8; + int fb_depth_bits = 24; + int fb_stencil_bits = 8; + int fb_accum_red_bits = 0; + int fb_accum_green_bits = 0; + int fb_accum_blue_bits = 0; + int fb_accum_alpha_bits = 0; + int fb_aux_buffers = 0; + int fb_samples = 0; + bool fb_stereo = false; + bool fb_srgb = false; + bool fb_doublebuffer = true; + int angle_type = GLFW_ANGLE_PLATFORM_TYPE_NONE; + bool cocoa_graphics_switching = false; + bool disable_xcb_surface = false; + + enum { PLATFORM, CLIENT, CONTEXT, BEHAVIOR, DEBUG_CONTEXT, FORWARD, HELP, EXTENSIONS, LAYERS, MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION, REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS, ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS, AUXBUFFERS, SAMPLES, STEREO, SRGB, SINGLEBUFFER, NOERROR_SRSLY, - GRAPHICS_SWITCHING }; + ANGLE_TYPE, GRAPHICS_SWITCHING, XCB_SURFACE }; const struct option options[] = { + { "platform", 1, NULL, PLATFORM }, { "behavior", 1, NULL, BEHAVIOR }, { "client-api", 1, NULL, CLIENT }, { "context-api", 1, NULL, CONTEXT }, @@ -344,32 +423,41 @@ int main(int argc, char** argv) { "srgb", 0, NULL, SRGB }, { "singlebuffer", 0, NULL, SINGLEBUFFER }, { "no-error", 0, NULL, NOERROR_SRSLY }, + { "angle-type", 1, NULL, ANGLE_TYPE }, { "graphics-switching", 0, NULL, GRAPHICS_SWITCHING }, + { "vk-xcb-surface", 0, NULL, XCB_SURFACE }, { NULL, 0, NULL, 0 } }; - // Initialize GLFW and create window - - if (!valid_version()) - exit(EXIT_FAILURE); - - glfwSetErrorCallback(error_callback); - - glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE); - - if (!glfwInit()) - exit(EXIT_FAILURE); - while ((ch = getopt_long(argc, argv, "a:b:c:dfhlm:n:p:s:v", options, NULL)) != -1) { switch (ch) { + case PLATFORM: + if (strcasecmp(optarg, PLATFORM_NAME_ANY) == 0) + platform = GLFW_ANY_PLATFORM; + else if (strcasecmp(optarg, PLATFORM_NAME_WIN32) == 0) + platform = GLFW_PLATFORM_WIN32; + else if (strcasecmp(optarg, PLATFORM_NAME_COCOA) == 0) + platform = GLFW_PLATFORM_COCOA; + else if (strcasecmp(optarg, PLATFORM_NAME_WL) == 0) + platform = GLFW_PLATFORM_WAYLAND; + else if (strcasecmp(optarg, PLATFORM_NAME_X11) == 0) + platform = GLFW_PLATFORM_X11; + else if (strcasecmp(optarg, PLATFORM_NAME_NULL) == 0) + platform = GLFW_PLATFORM_NULL; + else + { + usage(); + exit(EXIT_FAILURE); + } + break; case 'a': case CLIENT: if (strcasecmp(optarg, API_NAME_OPENGL) == 0) - glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); + client_api = GLFW_OPENGL_API; else if (strcasecmp(optarg, API_NAME_OPENGL_ES) == 0) - glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); + client_api = GLFW_OPENGL_ES_API; else { usage(); @@ -379,15 +467,9 @@ int main(int argc, char** argv) case 'b': case BEHAVIOR: if (strcasecmp(optarg, BEHAVIOR_NAME_NONE) == 0) - { - glfwWindowHint(GLFW_CONTEXT_RELEASE_BEHAVIOR, - GLFW_RELEASE_BEHAVIOR_NONE); - } + context_release = GLFW_RELEASE_BEHAVIOR_NONE; else if (strcasecmp(optarg, BEHAVIOR_NAME_FLUSH) == 0) - { - glfwWindowHint(GLFW_CONTEXT_RELEASE_BEHAVIOR, - GLFW_RELEASE_BEHAVIOR_FLUSH); - } + context_release = GLFW_RELEASE_BEHAVIOR_FLUSH; else { usage(); @@ -397,11 +479,11 @@ int main(int argc, char** argv) case 'c': case CONTEXT: if (strcasecmp(optarg, API_NAME_NATIVE) == 0) - glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API); + context_creation_api = GLFW_NATIVE_CONTEXT_API; else if (strcasecmp(optarg, API_NAME_EGL) == 0) - glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API); + context_creation_api = GLFW_EGL_CONTEXT_API; else if (strcasecmp(optarg, API_NAME_OSMESA) == 0) - glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_OSMESA_CONTEXT_API); + context_creation_api = GLFW_OSMESA_CONTEXT_API; else { usage(); @@ -410,11 +492,11 @@ int main(int argc, char** argv) break; case 'd': case DEBUG_CONTEXT: - glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); + context_debug = true; break; case 'f': case FORWARD: - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); + opengl_forward = true; break; case 'h': case HELP: @@ -422,31 +504,25 @@ int main(int argc, char** argv) exit(EXIT_SUCCESS); case 'l': case EXTENSIONS: - list_extensions = GLFW_TRUE; + list_extensions = true; break; case LAYERS: - list_layers = GLFW_TRUE; + list_layers = true; break; case 'm': case MAJOR: - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, atoi(optarg)); + context_major = atoi(optarg); break; case 'n': case MINOR: - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, atoi(optarg)); + context_minor = atoi(optarg); break; case 'p': case PROFILE: if (strcasecmp(optarg, PROFILE_NAME_CORE) == 0) - { - glfwWindowHint(GLFW_OPENGL_PROFILE, - GLFW_OPENGL_CORE_PROFILE); - } + opengl_profile = GLFW_OPENGL_CORE_PROFILE; else if (strcasecmp(optarg, PROFILE_NAME_COMPAT) == 0) - { - glfwWindowHint(GLFW_OPENGL_PROFILE, - GLFW_OPENGL_COMPAT_PROFILE); - } + opengl_profile = GLFW_OPENGL_COMPAT_PROFILE; else { usage(); @@ -456,15 +532,9 @@ int main(int argc, char** argv) case 's': case ROBUSTNESS: if (strcasecmp(optarg, STRATEGY_NAME_NONE) == 0) - { - glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, - GLFW_NO_RESET_NOTIFICATION); - } + context_robustness = GLFW_NO_RESET_NOTIFICATION; else if (strcasecmp(optarg, STRATEGY_NAME_LOSE) == 0) - { - glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, - GLFW_LOSE_CONTEXT_ON_RESET); - } + context_robustness = GLFW_LOSE_CONTEXT_ON_RESET; else { usage(); @@ -477,90 +547,112 @@ int main(int argc, char** argv) exit(EXIT_SUCCESS); case REDBITS: if (strcmp(optarg, "-") == 0) - glfwWindowHint(GLFW_RED_BITS, GLFW_DONT_CARE); + fb_red_bits = GLFW_DONT_CARE; else - glfwWindowHint(GLFW_RED_BITS, atoi(optarg)); + fb_red_bits = atoi(optarg); break; case GREENBITS: if (strcmp(optarg, "-") == 0) - glfwWindowHint(GLFW_GREEN_BITS, GLFW_DONT_CARE); + fb_green_bits = GLFW_DONT_CARE; else - glfwWindowHint(GLFW_GREEN_BITS, atoi(optarg)); + fb_green_bits = atoi(optarg); break; case BLUEBITS: if (strcmp(optarg, "-") == 0) - glfwWindowHint(GLFW_BLUE_BITS, GLFW_DONT_CARE); + fb_blue_bits = GLFW_DONT_CARE; else - glfwWindowHint(GLFW_BLUE_BITS, atoi(optarg)); + fb_blue_bits = atoi(optarg); break; case ALPHABITS: if (strcmp(optarg, "-") == 0) - glfwWindowHint(GLFW_ALPHA_BITS, GLFW_DONT_CARE); + fb_alpha_bits = GLFW_DONT_CARE; else - glfwWindowHint(GLFW_ALPHA_BITS, atoi(optarg)); + fb_alpha_bits = atoi(optarg); break; case DEPTHBITS: if (strcmp(optarg, "-") == 0) - glfwWindowHint(GLFW_DEPTH_BITS, GLFW_DONT_CARE); + fb_depth_bits = GLFW_DONT_CARE; else - glfwWindowHint(GLFW_DEPTH_BITS, atoi(optarg)); + fb_depth_bits = atoi(optarg); break; case STENCILBITS: if (strcmp(optarg, "-") == 0) - glfwWindowHint(GLFW_STENCIL_BITS, GLFW_DONT_CARE); + fb_stencil_bits = GLFW_DONT_CARE; else - glfwWindowHint(GLFW_STENCIL_BITS, atoi(optarg)); + fb_stencil_bits = atoi(optarg); break; case ACCUMREDBITS: if (strcmp(optarg, "-") == 0) - glfwWindowHint(GLFW_ACCUM_RED_BITS, GLFW_DONT_CARE); + fb_accum_red_bits = GLFW_DONT_CARE; else - glfwWindowHint(GLFW_ACCUM_RED_BITS, atoi(optarg)); + fb_accum_red_bits = atoi(optarg); break; case ACCUMGREENBITS: if (strcmp(optarg, "-") == 0) - glfwWindowHint(GLFW_ACCUM_GREEN_BITS, GLFW_DONT_CARE); + fb_accum_green_bits = GLFW_DONT_CARE; else - glfwWindowHint(GLFW_ACCUM_GREEN_BITS, atoi(optarg)); + fb_accum_green_bits = atoi(optarg); break; case ACCUMBLUEBITS: if (strcmp(optarg, "-") == 0) - glfwWindowHint(GLFW_ACCUM_BLUE_BITS, GLFW_DONT_CARE); + fb_accum_blue_bits = GLFW_DONT_CARE; else - glfwWindowHint(GLFW_ACCUM_BLUE_BITS, atoi(optarg)); + fb_accum_blue_bits = atoi(optarg); break; case ACCUMALPHABITS: if (strcmp(optarg, "-") == 0) - glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, GLFW_DONT_CARE); + fb_accum_alpha_bits = GLFW_DONT_CARE; else - glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, atoi(optarg)); + fb_accum_alpha_bits = atoi(optarg); break; case AUXBUFFERS: if (strcmp(optarg, "-") == 0) - glfwWindowHint(GLFW_AUX_BUFFERS, GLFW_DONT_CARE); + fb_aux_buffers = GLFW_DONT_CARE; else - glfwWindowHint(GLFW_AUX_BUFFERS, atoi(optarg)); + fb_aux_buffers = atoi(optarg); break; case SAMPLES: if (strcmp(optarg, "-") == 0) - glfwWindowHint(GLFW_SAMPLES, GLFW_DONT_CARE); + fb_samples = GLFW_DONT_CARE; else - glfwWindowHint(GLFW_SAMPLES, atoi(optarg)); + fb_samples = atoi(optarg); break; case STEREO: - glfwWindowHint(GLFW_STEREO, GLFW_TRUE); + fb_stereo = true; break; case SRGB: - glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_TRUE); + fb_srgb = true; break; case SINGLEBUFFER: - glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_FALSE); + fb_doublebuffer = false; break; case NOERROR_SRSLY: - glfwWindowHint(GLFW_CONTEXT_NO_ERROR, GLFW_TRUE); + context_no_error = true; + break; + case ANGLE_TYPE: + if (strcmp(optarg, ANGLE_TYPE_OPENGL) == 0) + angle_type = GLFW_ANGLE_PLATFORM_TYPE_OPENGL; + else if (strcmp(optarg, ANGLE_TYPE_OPENGLES) == 0) + angle_type = GLFW_ANGLE_PLATFORM_TYPE_OPENGLES; + else if (strcmp(optarg, ANGLE_TYPE_D3D9) == 0) + angle_type = GLFW_ANGLE_PLATFORM_TYPE_D3D9; + else if (strcmp(optarg, ANGLE_TYPE_D3D11) == 0) + angle_type = GLFW_ANGLE_PLATFORM_TYPE_D3D11; + else if (strcmp(optarg, ANGLE_TYPE_VULKAN) == 0) + angle_type = GLFW_ANGLE_PLATFORM_TYPE_VULKAN; + else if (strcmp(optarg, ANGLE_TYPE_METAL) == 0) + angle_type = GLFW_ANGLE_PLATFORM_TYPE_METAL; + else + { + usage(); + exit(EXIT_FAILURE); + } break; case GRAPHICS_SWITCHING: - glfwWindowHint(GLFW_COCOA_GRAPHICS_SWITCHING, GLFW_TRUE); + cocoa_graphics_switching = true; + break; + case XCB_SURFACE: + disable_xcb_surface = true; break; default: usage(); @@ -568,9 +660,240 @@ int main(int argc, char** argv) } } - print_version(); + // Initialize GLFW and create window - glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + if (!valid_version()) + exit(EXIT_FAILURE); + + glfwSetErrorCallback(error_callback); + + glfwInitHint(GLFW_PLATFORM, platform); + + glfwInitHint(GLFW_COCOA_MENUBAR, false); + + glfwInitHint(GLFW_ANGLE_PLATFORM_TYPE, angle_type); + glfwInitHint(GLFW_X11_XCB_VULKAN_SURFACE, !disable_xcb_surface); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + print_version(); + print_platform(); + + glfwWindowHint(GLFW_VISIBLE, false); + + glfwWindowHint(GLFW_CLIENT_API, client_api); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, context_major); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, context_minor); + glfwWindowHint(GLFW_CONTEXT_RELEASE_BEHAVIOR, context_release); + glfwWindowHint(GLFW_CONTEXT_CREATION_API, context_creation_api); + glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, context_robustness); + glfwWindowHint(GLFW_CONTEXT_DEBUG, context_debug); + glfwWindowHint(GLFW_CONTEXT_NO_ERROR, context_no_error); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, opengl_forward); + glfwWindowHint(GLFW_OPENGL_PROFILE, opengl_profile); + + glfwWindowHint(GLFW_RED_BITS, fb_red_bits); + glfwWindowHint(GLFW_BLUE_BITS, fb_blue_bits); + glfwWindowHint(GLFW_GREEN_BITS, fb_green_bits); + glfwWindowHint(GLFW_ALPHA_BITS, fb_alpha_bits); + glfwWindowHint(GLFW_DEPTH_BITS, fb_depth_bits); + glfwWindowHint(GLFW_STENCIL_BITS, fb_stencil_bits); + glfwWindowHint(GLFW_ACCUM_RED_BITS, fb_accum_red_bits); + glfwWindowHint(GLFW_ACCUM_GREEN_BITS, fb_accum_green_bits); + glfwWindowHint(GLFW_ACCUM_BLUE_BITS, fb_accum_blue_bits); + glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, fb_accum_alpha_bits); + glfwWindowHint(GLFW_AUX_BUFFERS, fb_aux_buffers); + glfwWindowHint(GLFW_SAMPLES, fb_samples); + glfwWindowHint(GLFW_STEREO, fb_stereo); + glfwWindowHint(GLFW_SRGB_CAPABLE, fb_srgb); + glfwWindowHint(GLFW_DOUBLEBUFFER, fb_doublebuffer); + + glfwWindowHint(GLFW_COCOA_GRAPHICS_SWITCHING, cocoa_graphics_switching); + + GLFWwindow* window = glfwCreateWindow(200, 200, "Version", NULL, NULL); + if (window) + { + glfwMakeContextCurrent(window); + gladLoadGL(glfwGetProcAddress); + + const GLenum error = glGetError(); + if (error != GL_NO_ERROR) + printf("*** OpenGL error after make current: 0x%08x ***\n", error); + + // Report client API version + + const int client = glfwGetWindowAttrib(window, GLFW_CLIENT_API); + const int major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR); + const int minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR); + const int revision = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION); + const int profile = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE); + + printf("%s context version string: \"%s\"\n", + get_api_name(client), + glGetString(GL_VERSION)); + + printf("%s context version parsed by GLFW: %u.%u.%u\n", + get_api_name(client), + major, minor, revision); + + // Report client API context properties + + if (client == GLFW_OPENGL_API) + { + if (major >= 3) + { + GLint flags; + + glGetIntegerv(GL_CONTEXT_FLAGS, &flags); + printf("%s context flags (0x%08x):", get_api_name(client), flags); + + if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) + printf(" forward-compatible"); + if (flags & 2/*GL_CONTEXT_FLAG_DEBUG_BIT*/) + printf(" debug"); + if (flags & GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB) + printf(" robustness"); + if (flags & 8/*GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR*/) + printf(" no-error"); + putchar('\n'); + + printf("%s context flags parsed by GLFW:", get_api_name(client)); + + if (glfwGetWindowAttrib(window, GLFW_OPENGL_FORWARD_COMPAT)) + printf(" forward-compatible"); + if (glfwGetWindowAttrib(window, GLFW_CONTEXT_DEBUG)) + printf(" debug"); + if (glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS) == GLFW_LOSE_CONTEXT_ON_RESET) + printf(" robustness"); + if (glfwGetWindowAttrib(window, GLFW_CONTEXT_NO_ERROR)) + printf(" no-error"); + putchar('\n'); + } + + if (major >= 4 || (major == 3 && minor >= 2)) + { + GLint mask; + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); + + printf("%s profile mask (0x%08x): %s\n", + get_api_name(client), + mask, + get_profile_name_gl(mask)); + + printf("%s profile mask parsed by GLFW: %s\n", + get_api_name(client), + get_profile_name_glfw(profile)); + } + + if (GLAD_GL_ARB_robustness) + { + const int robustness = glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS); + GLint strategy; + glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy); + + printf("%s robustness strategy (0x%08x): %s\n", + get_api_name(client), + strategy, + get_strategy_name_gl(strategy)); + + printf("%s robustness strategy parsed by GLFW: %s\n", + get_api_name(client), + get_strategy_name_glfw(robustness)); + } + } + + printf("%s context renderer string: \"%s\"\n", + get_api_name(client), + glGetString(GL_RENDERER)); + printf("%s context vendor string: \"%s\"\n", + get_api_name(client), + glGetString(GL_VENDOR)); + + if (major >= 2) + { + printf("%s context shading language version: \"%s\"\n", + get_api_name(client), + glGetString(GL_SHADING_LANGUAGE_VERSION)); + } + + printf("%s framebuffer:\n", get_api_name(client)); + + GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits; + + if (client == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE) + { + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_BACK_LEFT, + GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, + &redbits); + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_BACK_LEFT, + GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, + &greenbits); + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_BACK_LEFT, + GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, + &bluebits); + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_BACK_LEFT, + GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, + &alphabits); + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_DEPTH, + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, + &depthbits); + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_STENCIL, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, + &stencilbits); + } + else + { + glGetIntegerv(GL_RED_BITS, &redbits); + glGetIntegerv(GL_GREEN_BITS, &greenbits); + glGetIntegerv(GL_BLUE_BITS, &bluebits); + glGetIntegerv(GL_ALPHA_BITS, &alphabits); + glGetIntegerv(GL_DEPTH_BITS, &depthbits); + glGetIntegerv(GL_STENCIL_BITS, &stencilbits); + } + + printf(" red: %u green: %u blue: %u alpha: %u depth: %u stencil: %u\n", + redbits, greenbits, bluebits, alphabits, depthbits, stencilbits); + + if (client == GLFW_OPENGL_ES_API || + GLAD_GL_ARB_multisample || + major > 1 || minor >= 3) + { + GLint samples, samplebuffers; + glGetIntegerv(GL_SAMPLES, &samples); + glGetIntegerv(GL_SAMPLE_BUFFERS, &samplebuffers); + + printf(" samples: %u sample buffers: %u\n", samples, samplebuffers); + } + + if (client == GLFW_OPENGL_API && profile != GLFW_OPENGL_CORE_PROFILE) + { + GLint accumredbits, accumgreenbits, accumbluebits, accumalphabits; + GLint auxbuffers; + + glGetIntegerv(GL_ACCUM_RED_BITS, &accumredbits); + glGetIntegerv(GL_ACCUM_GREEN_BITS, &accumgreenbits); + glGetIntegerv(GL_ACCUM_BLUE_BITS, &accumbluebits); + glGetIntegerv(GL_ACCUM_ALPHA_BITS, &accumalphabits); + glGetIntegerv(GL_AUX_BUFFERS, &auxbuffers); + + printf(" accum red: %u accum green: %u accum blue: %u accum alpha: %u aux buffers: %u\n", + accumredbits, accumgreenbits, accumbluebits, accumalphabits, auxbuffers); + } + + if (list_extensions) + list_context_extensions(client, major, minor); + + glfwDestroyWindow(window); + } + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); window = glfwCreateWindow(200, 200, "Version", NULL, NULL); if (!window) @@ -579,197 +902,15 @@ int main(int argc, char** argv) exit(EXIT_FAILURE); } - glfwMakeContextCurrent(window); - gladLoadGL(glfwGetProcAddress); - - error = glGetError(); - if (error != GL_NO_ERROR) - printf("*** OpenGL error after make current: 0x%08x ***\n", error); - - // Report client API version - - client = glfwGetWindowAttrib(window, GLFW_CLIENT_API); - major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR); - minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR); - revision = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION); - profile = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE); - - printf("%s context version string: \"%s\"\n", - get_api_name(client), - glGetString(GL_VERSION)); - - printf("%s context version parsed by GLFW: %u.%u.%u\n", - get_api_name(client), - major, minor, revision); - - // Report client API context properties - - if (client == GLFW_OPENGL_API) - { - if (major >= 3) - { - GLint flags; - - glGetIntegerv(GL_CONTEXT_FLAGS, &flags); - printf("%s context flags (0x%08x):", get_api_name(client), flags); - - if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) - printf(" forward-compatible"); - if (flags & 2/*GL_CONTEXT_FLAG_DEBUG_BIT*/) - printf(" debug"); - if (flags & GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB) - printf(" robustness"); - if (flags & 8/*GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR*/) - printf(" no-error"); - putchar('\n'); - - printf("%s context flags parsed by GLFW:", get_api_name(client)); - - if (glfwGetWindowAttrib(window, GLFW_OPENGL_FORWARD_COMPAT)) - printf(" forward-compatible"); - if (glfwGetWindowAttrib(window, GLFW_OPENGL_DEBUG_CONTEXT)) - printf(" debug"); - if (glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS) == GLFW_LOSE_CONTEXT_ON_RESET) - printf(" robustness"); - if (glfwGetWindowAttrib(window, GLFW_CONTEXT_NO_ERROR)) - printf(" no-error"); - putchar('\n'); - } - - if (major >= 4 || (major == 3 && minor >= 2)) - { - GLint mask; - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); - - printf("%s profile mask (0x%08x): %s\n", - get_api_name(client), - mask, - get_profile_name_gl(mask)); - - printf("%s profile mask parsed by GLFW: %s\n", - get_api_name(client), - get_profile_name_glfw(profile)); - } - - if (GLAD_GL_ARB_robustness) - { - const int robustness = glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS); - GLint strategy; - glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy); - - printf("%s robustness strategy (0x%08x): %s\n", - get_api_name(client), - strategy, - get_strategy_name_gl(strategy)); - - printf("%s robustness strategy parsed by GLFW: %s\n", - get_api_name(client), - get_strategy_name_glfw(robustness)); - } - } - - printf("%s context renderer string: \"%s\"\n", - get_api_name(client), - glGetString(GL_RENDERER)); - printf("%s context vendor string: \"%s\"\n", - get_api_name(client), - glGetString(GL_VENDOR)); - - if (major >= 2) - { - printf("%s context shading language version: \"%s\"\n", - get_api_name(client), - glGetString(GL_SHADING_LANGUAGE_VERSION)); - } - - printf("%s framebuffer:\n", get_api_name(client)); - - if (client == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE) - { - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, - GL_BACK_LEFT, - GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, - &redbits); - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, - GL_BACK_LEFT, - GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, - &greenbits); - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, - GL_BACK_LEFT, - GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, - &bluebits); - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, - GL_BACK_LEFT, - GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, - &alphabits); - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, - GL_DEPTH, - GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, - &depthbits); - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, - GL_STENCIL, - GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, - &stencilbits); - } - else - { - glGetIntegerv(GL_RED_BITS, &redbits); - glGetIntegerv(GL_GREEN_BITS, &greenbits); - glGetIntegerv(GL_BLUE_BITS, &bluebits); - glGetIntegerv(GL_ALPHA_BITS, &alphabits); - glGetIntegerv(GL_DEPTH_BITS, &depthbits); - glGetIntegerv(GL_STENCIL_BITS, &stencilbits); - } - - printf(" red: %u green: %u blue: %u alpha: %u depth: %u stencil: %u\n", - redbits, greenbits, bluebits, alphabits, depthbits, stencilbits); - - if (client == GLFW_OPENGL_ES_API || - GLAD_GL_ARB_multisample || - major > 1 || minor >= 3) - { - GLint samples, samplebuffers; - glGetIntegerv(GL_SAMPLES, &samples); - glGetIntegerv(GL_SAMPLE_BUFFERS, &samplebuffers); - - printf(" samples: %u sample buffers: %u\n", samples, samplebuffers); - } - - if (client == GLFW_OPENGL_API && profile != GLFW_OPENGL_CORE_PROFILE) - { - GLint accumredbits, accumgreenbits, accumbluebits, accumalphabits; - GLint auxbuffers; - - glGetIntegerv(GL_ACCUM_RED_BITS, &accumredbits); - glGetIntegerv(GL_ACCUM_GREEN_BITS, &accumgreenbits); - glGetIntegerv(GL_ACCUM_BLUE_BITS, &accumbluebits); - glGetIntegerv(GL_ACCUM_ALPHA_BITS, &accumalphabits); - glGetIntegerv(GL_AUX_BUFFERS, &auxbuffers); - - printf(" accum red: %u accum green: %u accum blue: %u accum alpha: %u aux buffers: %u\n", - accumredbits, accumgreenbits, accumbluebits, accumalphabits, auxbuffers); - } - - if (list_extensions) - list_context_extensions(client, major, minor); - printf("Vulkan loader: %s\n", glfwVulkanSupported() ? "available" : "missing"); if (glfwVulkanSupported()) { - uint32_t loader_version = VK_API_VERSION_1_0; - int portability_enumeration = GLFW_FALSE; - uint32_t i, j, glfw_re_count, re_count, pd_count, ep_count; - const char** glfw_re; - const char** re; - VkApplicationInfo ai = {0}; - VkInstanceCreateInfo ici = {0}; - VkInstance instance; - VkPhysicalDevice* pd; - gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, NULL); + uint32_t loader_version = VK_API_VERSION_1_0; + if (vkEnumerateInstanceVersion) { uint32_t version; @@ -781,23 +922,25 @@ int main(int argc, char** argv) VK_VERSION_MAJOR(loader_version), VK_VERSION_MINOR(loader_version)); - glfw_re = glfwGetRequiredInstanceExtensions(&glfw_re_count); + uint32_t glfw_re_count; + const char** glfw_re = glfwGetRequiredInstanceExtensions(&glfw_re_count); - re_count = glfw_re_count; - re = calloc(glfw_re_count, sizeof(char*)); + uint32_t re_count = glfw_re_count; + const char** re = calloc(glfw_re_count, sizeof(char*)); - printf("Vulkan window surface required instance extensions:\n"); if (glfw_re) { - for (i = 0; i < glfw_re_count; i++) + printf("Vulkan window surface required instance extensions:\n"); + for (uint32_t i = 0; i < glfw_re_count; i++) { printf(" %s\n", glfw_re[i]); re[i] = glfw_re[i]; } } else - printf(" missing\n"); + printf("Vulkan window surface extensions missing\n"); + uint32_t ep_count; vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL); VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties)); vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep); @@ -806,11 +949,13 @@ int main(int argc, char** argv) { printf("Vulkan instance extensions:\n"); - for (i = 0; i < ep_count; i++) + for (uint32_t i = 0; i < ep_count; i++) printf(" %s (spec version %u)\n", ep[i].extensionName, ep[i].specVersion); } - for (i = 0; i < ep_count; i++) + bool portability_enumeration = false; + + for (uint32_t i = 0; i < ep_count; i++) { if (strcmp(ep[i].extensionName, "VK_KHR_portability_enumeration") != 0) continue; @@ -818,7 +963,7 @@ int main(int argc, char** argv) re_count++; re = realloc((void*) re, sizeof(char*) * re_count); re[re_count - 1] = "VK_KHR_portability_enumeration"; - portability_enumeration = GLFW_TRUE; + portability_enumeration = true; } free(ep); @@ -826,7 +971,7 @@ int main(int argc, char** argv) if (list_layers) list_vulkan_instance_layers(); - ai.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + VkApplicationInfo ai = { VK_STRUCTURE_TYPE_APPLICATION_INFO }; ai.pApplicationName = "glfwinfo"; ai.applicationVersion = VK_MAKE_VERSION(GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, @@ -837,7 +982,7 @@ int main(int argc, char** argv) else ai.apiVersion = VK_API_VERSION_1_0; - ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + VkInstanceCreateInfo ici = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; ici.pApplicationInfo = &ai; ici.enabledExtensionCount = re_count; ici.ppEnabledExtensionNames = re; @@ -845,6 +990,8 @@ int main(int argc, char** argv) if (portability_enumeration) ici.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; + VkInstance instance = VK_NULL_HANDLE; + if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS) { glfwTerminate(); @@ -855,38 +1002,46 @@ int main(int argc, char** argv) gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, instance); + if (glfw_re_count) + { + VkSurfaceKHR surface = VK_NULL_HANDLE; + + if (glfwCreateWindowSurface(instance, window, NULL, &surface) == VK_SUCCESS) + { + printf("Vulkan window surface created successfully\n"); + vkDestroySurfaceKHR(instance, surface, NULL); + } + else + printf("Failed to create Vulkan window surface\n"); + } + + uint32_t pd_count; vkEnumeratePhysicalDevices(instance, &pd_count, NULL); - pd = calloc(pd_count, sizeof(VkPhysicalDevice)); + VkPhysicalDevice* pd = calloc(pd_count, sizeof(VkPhysicalDevice)); vkEnumeratePhysicalDevices(instance, &pd_count, pd); - for (i = 0; i < pd_count; i++) + for (uint32_t i = 0; i < pd_count; i++) { VkPhysicalDeviceProperties pdp; - uint32_t qfp_count, ep_count; - vkGetPhysicalDeviceProperties(pd[i], &pdp); - printf("Vulkan %s device: \"%s\" API version %i.%i\n", - get_device_type_name(pdp.deviceType), - pdp.deviceName, - VK_VERSION_MAJOR(pdp.apiVersion), - VK_VERSION_MINOR(pdp.apiVersion)); - + uint32_t qfp_count; vkGetPhysicalDeviceQueueFamilyProperties(pd[i], &qfp_count, NULL); + uint32_t ep_count; vkEnumerateDeviceExtensionProperties(pd[i], NULL, &ep_count, NULL); VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties)); vkEnumerateDeviceExtensionProperties(pd[i], NULL, &ep_count, ep); if (portability_enumeration) { - int conformant = GLFW_TRUE; + bool conformant = true; - for (j = 0; j < ep_count; j++) + for (uint32_t j = 0; j < ep_count; j++) { if (strcmp(ep[j].extensionName, "VK_KHR_portability_subset") == 0) { - conformant = GLFW_FALSE; + conformant = false; break; } } @@ -910,7 +1065,7 @@ int main(int argc, char** argv) if (glfw_re_count) { printf("Vulkan device queue family presentation support:\n"); - for (j = 0; j < qfp_count; j++) + for (uint32_t j = 0; j < qfp_count; j++) { printf(" %u: ", j); if (glfwGetPhysicalDevicePresentationSupport(instance, pd[i], j)) @@ -923,7 +1078,7 @@ int main(int argc, char** argv) if (list_extensions) { printf("Vulkan device extensions:\n"); - for (j = 0; j < ep_count; j++) + for (uint32_t j = 0; j < ep_count; j++) printf(" %s (spec version %u)\n", ep[j].extensionName, ep[j].specVersion); } @@ -937,6 +1092,8 @@ int main(int argc, char** argv) vkDestroyInstance(instance, NULL); } + glfwDestroyWindow(window); + glfwTerminate(); exit(EXIT_SUCCESS); } diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/icon.c b/src/lib/src/vendor/glfw-3.4/tests/icon.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/tests/icon.c rename to src/lib/src/vendor/glfw-3.4/tests/icon.c index aa7ee18..d5baf0a 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/icon.c +++ b/src/lib/src/vendor/glfw-3.4/tests/icon.c @@ -27,6 +27,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/iconify.c b/src/lib/src/vendor/glfw-3.4/tests/iconify.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/tests/iconify.c rename to src/lib/src/vendor/glfw-3.4/tests/iconify.c index 27dcdf9..32fd44f 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/iconify.c +++ b/src/lib/src/vendor/glfw-3.4/tests/iconify.c @@ -28,6 +28,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/inputlag.c b/src/lib/src/vendor/glfw-3.4/tests/inputlag.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/tests/inputlag.c rename to src/lib/src/vendor/glfw-3.4/tests/inputlag.c index 269a0c8..12e693f 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/inputlag.c +++ b/src/lib/src/vendor/glfw-3.4/tests/inputlag.c @@ -28,6 +28,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include @@ -202,6 +203,7 @@ int main(int argc, char** argv) glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); + glfwWindowHint(GLFW_WIN32_KEYBOARD_MENU, GLFW_TRUE); window = glfwCreateWindow(width, height, "Input lag test", monitor, NULL); if (!window) diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/joysticks.c b/src/lib/src/vendor/glfw-3.4/tests/joysticks.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/tests/joysticks.c rename to src/lib/src/vendor/glfw-3.4/tests/joysticks.c index 8eae021..df00021 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/joysticks.c +++ b/src/lib/src/vendor/glfw-3.4/tests/joysticks.c @@ -28,6 +28,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include @@ -182,6 +183,7 @@ int main(void) exit(EXIT_FAILURE); glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); + glfwWindowHint(GLFW_WIN32_KEYBOARD_MENU, GLFW_TRUE); window = glfwCreateWindow(800, 600, "Joystick Test", NULL, NULL); if (!window) diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/monitors.c b/src/lib/src/vendor/glfw-3.4/tests/monitors.c similarity index 98% rename from src/lib/src/vendor/glfw-3.3.8/tests/monitors.c rename to src/lib/src/vendor/glfw-3.4/tests/monitors.c index 2b75d7b..1043e66 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/monitors.c +++ b/src/lib/src/vendor/glfw-3.4/tests/monitors.c @@ -28,6 +28,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include @@ -241,6 +242,8 @@ int main(int argc, char** argv) glfwSetErrorCallback(error_callback); + glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE); + if (!glfwInit()) exit(EXIT_FAILURE); diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/msaa.c b/src/lib/src/vendor/glfw-3.4/tests/msaa.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/tests/msaa.c rename to src/lib/src/vendor/glfw-3.4/tests/msaa.c index 33e2ccc..10bfa3c 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/msaa.c +++ b/src/lib/src/vendor/glfw-3.4/tests/msaa.c @@ -29,6 +29,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/reopen.c b/src/lib/src/vendor/glfw-3.4/tests/reopen.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/tests/reopen.c rename to src/lib/src/vendor/glfw-3.4/tests/reopen.c index 10d22b2..b458755 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/reopen.c +++ b/src/lib/src/vendor/glfw-3.4/tests/reopen.c @@ -33,6 +33,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/tearing.c b/src/lib/src/vendor/glfw-3.4/tests/tearing.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/tests/tearing.c rename to src/lib/src/vendor/glfw-3.4/tests/tearing.c index 1760121..5c7893c 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/tearing.c +++ b/src/lib/src/vendor/glfw-3.4/tests/tearing.c @@ -28,6 +28,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/threads.c b/src/lib/src/vendor/glfw-3.4/tests/threads.c similarity index 96% rename from src/lib/src/vendor/glfw-3.3.8/tests/threads.c rename to src/lib/src/vendor/glfw-3.4/tests/threads.c index 9829493..a2caea5 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/threads.c +++ b/src/lib/src/vendor/glfw-3.4/tests/threads.c @@ -30,6 +30,7 @@ #include "tinycthread.h" +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include @@ -95,10 +96,11 @@ int main(void) if (!glfwInit()) exit(EXIT_FAILURE); - glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); - for (i = 0; i < count; i++) { + glfwWindowHint(GLFW_POSITION_X, 200 + 250 * i); + glfwWindowHint(GLFW_POSITION_Y, 200); + threads[i].window = glfwCreateWindow(200, 200, threads[i].title, NULL, NULL); @@ -109,9 +111,6 @@ int main(void) } glfwSetKeyCallback(threads[i].window, key_callback); - - glfwSetWindowPos(threads[i].window, 200 + 250 * i, 200); - glfwShowWindow(threads[i].window); } glfwMakeContextCurrent(threads[0].window); diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/timeout.c b/src/lib/src/vendor/glfw-3.4/tests/timeout.c similarity index 98% rename from src/lib/src/vendor/glfw-3.3.8/tests/timeout.c rename to src/lib/src/vendor/glfw-3.4/tests/timeout.c index bda2560..c273746 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/timeout.c +++ b/src/lib/src/vendor/glfw-3.4/tests/timeout.c @@ -27,6 +27,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/title.c b/src/lib/src/vendor/glfw-3.4/tests/title.c similarity index 98% rename from src/lib/src/vendor/glfw-3.3.8/tests/title.c rename to src/lib/src/vendor/glfw-3.4/tests/title.c index a5bad34..08a24e7 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/title.c +++ b/src/lib/src/vendor/glfw-3.4/tests/title.c @@ -27,6 +27,7 @@ // //======================================================================== +#define GLAD_GL_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include diff --git a/src/lib/src/vendor/glfw-3.3.8/tests/triangle-vulkan.c b/src/lib/src/vendor/glfw-3.4/tests/triangle-vulkan.c similarity index 99% rename from src/lib/src/vendor/glfw-3.3.8/tests/triangle-vulkan.c rename to src/lib/src/vendor/glfw-3.4/tests/triangle-vulkan.c index 3a4bfb1..b38ee13 100644 --- a/src/lib/src/vendor/glfw-3.3.8/tests/triangle-vulkan.c +++ b/src/lib/src/vendor/glfw-3.4/tests/triangle-vulkan.c @@ -41,6 +41,7 @@ #include #endif +#define GLAD_VULKAN_IMPLEMENTATION #include #define GLFW_INCLUDE_NONE #include @@ -1246,7 +1247,7 @@ static void demo_prepare_pipeline(struct demo *demo) { VkPipelineDepthStencilStateCreateInfo ds; VkPipelineViewportStateCreateInfo vp; VkPipelineMultisampleStateCreateInfo ms; - VkDynamicState dynamicStateEnables[2]; + VkDynamicState dynamicStateEnables[(VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1)]; VkPipelineDynamicStateCreateInfo dynamicState; VkResult U_ASSERT_ONLY err; diff --git a/src/lib/src/vendor/glfw-3.4/tests/window.c b/src/lib/src/vendor/glfw-3.4/tests/window.c new file mode 100644 index 0000000..c81bf02 --- /dev/null +++ b/src/lib/src/vendor/glfw-3.4/tests/window.c @@ -0,0 +1,457 @@ +//======================================================================== +// Window properties test +// Copyright (c) Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as 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 GLAD_GL_IMPLEMENTATION +#include +#define GLFW_INCLUDE_NONE +#include + +#include + +#define NK_IMPLEMENTATION +#define NK_INCLUDE_FIXED_TYPES +#define NK_INCLUDE_FONT_BAKING +#define NK_INCLUDE_DEFAULT_FONT +#define NK_INCLUDE_DEFAULT_ALLOCATOR +#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT +#define NK_INCLUDE_STANDARD_VARARGS +#define NK_BUTTON_TRIGGER_ON_RELEASE +#include + +#define NK_GLFW_GL2_IMPLEMENTATION +#include + +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + int windowed_x, windowed_y, windowed_width, windowed_height; + int last_xpos = INT_MIN, last_ypos = INT_MIN; + int last_width = INT_MIN, last_height = INT_MIN; + int limit_aspect_ratio = false, aspect_numer = 1, aspect_denom = 1; + int limit_min_size = false, min_width = 400, min_height = 400; + int limit_max_size = false, max_width = 400, max_height = 400; + char width_buffer[12] = "", height_buffer[12] = ""; + char xpos_buffer[12] = "", ypos_buffer[12] = ""; + char numer_buffer[12] = "", denom_buffer[12] = ""; + char min_width_buffer[12] = "", min_height_buffer[12] = ""; + char max_width_buffer[12] = "", max_height_buffer[12] = ""; + int may_close = true; + char window_title[64] = ""; + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); + glfwWindowHint(GLFW_WIN32_KEYBOARD_MENU, GLFW_TRUE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); + + GLFWwindow* window = glfwCreateWindow(600, 660, "Window Features", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + gladLoadGL(glfwGetProcAddress); + glfwSwapInterval(0); + + bool position_supported = true; + + glfwGetError(NULL); + glfwGetWindowPos(window, &last_xpos, &last_ypos); + sprintf(xpos_buffer, "%i", last_xpos); + sprintf(ypos_buffer, "%i", last_ypos); + if (glfwGetError(NULL) == GLFW_FEATURE_UNAVAILABLE) + position_supported = false; + + glfwGetWindowSize(window, &last_width, &last_height); + sprintf(width_buffer, "%i", last_width); + sprintf(height_buffer, "%i", last_height); + + sprintf(numer_buffer, "%i", aspect_numer); + sprintf(denom_buffer, "%i", aspect_denom); + + sprintf(min_width_buffer, "%i", min_width); + sprintf(min_height_buffer, "%i", min_height); + sprintf(max_width_buffer, "%i", max_width); + sprintf(max_height_buffer, "%i", max_height); + + struct nk_context* nk = nk_glfw3_init(window, NK_GLFW3_INSTALL_CALLBACKS); + + struct nk_font_atlas* atlas; + nk_glfw3_font_stash_begin(&atlas); + nk_glfw3_font_stash_end(); + + strncpy(window_title, glfwGetWindowTitle(window), sizeof(window_title)); + + while (!(may_close && glfwWindowShouldClose(window))) + { + int width, height; + + glfwGetWindowSize(window, &width, &height); + + struct nk_rect area = nk_rect(0.f, 0.f, (float) width, (float) height); + nk_window_set_bounds(nk, "main", area); + + nk_glfw3_new_frame(); + if (nk_begin(nk, "main", area, 0)) + { + nk_layout_row_dynamic(nk, 30, 4); + + if (glfwGetWindowMonitor(window)) + { + if (nk_button_label(nk, "Make Windowed")) + { + glfwSetWindowMonitor(window, NULL, + windowed_x, windowed_y, + windowed_width, windowed_height, 0); + } + } + else + { + if (nk_button_label(nk, "Make Fullscreen")) + { + GLFWmonitor* monitor = glfwGetPrimaryMonitor(); + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + glfwGetWindowPos(window, &windowed_x, &windowed_y); + glfwGetWindowSize(window, &windowed_width, &windowed_height); + glfwSetWindowMonitor(window, monitor, + 0, 0, mode->width, mode->height, + mode->refreshRate); + } + } + + if (nk_button_label(nk, "Maximize")) + glfwMaximizeWindow(window); + if (nk_button_label(nk, "Iconify")) + glfwIconifyWindow(window); + if (nk_button_label(nk, "Restore")) + glfwRestoreWindow(window); + + nk_layout_row_dynamic(nk, 30, 2); + + if (nk_button_label(nk, "Hide (for 3s)")) + { + glfwHideWindow(window); + + const double time = glfwGetTime() + 3.0; + while (glfwGetTime() < time) + glfwWaitEventsTimeout(1.0); + + glfwShowWindow(window); + } + if (nk_button_label(nk, "Request Attention (after 3s)")) + { + glfwIconifyWindow(window); + + const double time = glfwGetTime() + 3.0; + while (glfwGetTime() < time) + glfwWaitEventsTimeout(1.0); + + glfwRequestWindowAttention(window); + } + + nk_layout_row_dynamic(nk, 30, 1); + + if (glfwGetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH)) + { + nk_label(nk, "Press H to disable mouse passthrough", NK_TEXT_CENTERED); + + if (glfwGetKey(window, GLFW_KEY_H)) + glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, false); + } + + nk_label(nk, "Press Enter in a text field to set value", NK_TEXT_CENTERED); + + nk_flags events; + const nk_flags flags = NK_EDIT_FIELD | + NK_EDIT_SIG_ENTER | + NK_EDIT_GOTO_END_ON_ACTIVATE; + + nk_layout_row_begin(nk, NK_DYNAMIC, 30, 2); + nk_layout_row_push(nk, 1.f / 3.f); + nk_label(nk, "Title", NK_TEXT_LEFT); + nk_layout_row_push(nk, 2.f / 3.f); + events = nk_edit_string_zero_terminated(nk, flags, window_title, + sizeof(window_title), NULL); + if (events & NK_EDIT_COMMITED) + glfwSetWindowTitle(window, window_title); + nk_layout_row_end(nk); + + if (position_supported) + { + int xpos, ypos; + glfwGetWindowPos(window, &xpos, &ypos); + + nk_layout_row_dynamic(nk, 30, 3); + nk_label(nk, "Position", NK_TEXT_LEFT); + + events = nk_edit_string_zero_terminated(nk, flags, xpos_buffer, + sizeof(xpos_buffer), + nk_filter_decimal); + if (events & NK_EDIT_COMMITED) + { + xpos = atoi(xpos_buffer); + glfwSetWindowPos(window, xpos, ypos); + } + else if (xpos != last_xpos || (events & NK_EDIT_DEACTIVATED)) + sprintf(xpos_buffer, "%i", xpos); + + events = nk_edit_string_zero_terminated(nk, flags, ypos_buffer, + sizeof(ypos_buffer), + nk_filter_decimal); + if (events & NK_EDIT_COMMITED) + { + ypos = atoi(ypos_buffer); + glfwSetWindowPos(window, xpos, ypos); + } + else if (ypos != last_ypos || (events & NK_EDIT_DEACTIVATED)) + sprintf(ypos_buffer, "%i", ypos); + + last_xpos = xpos; + last_ypos = ypos; + } + else + nk_label(nk, "Platform does not support window position", NK_TEXT_LEFT); + + nk_layout_row_dynamic(nk, 30, 3); + nk_label(nk, "Size", NK_TEXT_LEFT); + + events = nk_edit_string_zero_terminated(nk, flags, width_buffer, + sizeof(width_buffer), + nk_filter_decimal); + if (events & NK_EDIT_COMMITED) + { + width = atoi(width_buffer); + glfwSetWindowSize(window, width, height); + } + else if (width != last_width || (events & NK_EDIT_DEACTIVATED)) + sprintf(width_buffer, "%i", width); + + events = nk_edit_string_zero_terminated(nk, flags, height_buffer, + sizeof(height_buffer), + nk_filter_decimal); + if (events & NK_EDIT_COMMITED) + { + height = atoi(height_buffer); + glfwSetWindowSize(window, width, height); + } + else if (height != last_height || (events & NK_EDIT_DEACTIVATED)) + sprintf(height_buffer, "%i", height); + + last_width = width; + last_height = height; + + bool update_ratio_limit = false; + if (nk_checkbox_label(nk, "Aspect Ratio", &limit_aspect_ratio)) + update_ratio_limit = true; + + events = nk_edit_string_zero_terminated(nk, flags, numer_buffer, + sizeof(numer_buffer), + nk_filter_decimal); + if (events & NK_EDIT_COMMITED) + { + aspect_numer = abs(atoi(numer_buffer)); + update_ratio_limit = true; + } + else if (events & NK_EDIT_DEACTIVATED) + sprintf(numer_buffer, "%i", aspect_numer); + + events = nk_edit_string_zero_terminated(nk, flags, denom_buffer, + sizeof(denom_buffer), + nk_filter_decimal); + if (events & NK_EDIT_COMMITED) + { + aspect_denom = abs(atoi(denom_buffer)); + update_ratio_limit = true; + } + else if (events & NK_EDIT_DEACTIVATED) + sprintf(denom_buffer, "%i", aspect_denom); + + if (update_ratio_limit) + { + if (limit_aspect_ratio) + glfwSetWindowAspectRatio(window, aspect_numer, aspect_denom); + else + glfwSetWindowAspectRatio(window, GLFW_DONT_CARE, GLFW_DONT_CARE); + } + + bool update_size_limit = false; + + if (nk_checkbox_label(nk, "Minimum Size", &limit_min_size)) + update_size_limit = true; + + events = nk_edit_string_zero_terminated(nk, flags, min_width_buffer, + sizeof(min_width_buffer), + nk_filter_decimal); + if (events & NK_EDIT_COMMITED) + { + min_width = abs(atoi(min_width_buffer)); + update_size_limit = true; + } + else if (events & NK_EDIT_DEACTIVATED) + sprintf(min_width_buffer, "%i", min_width); + + events = nk_edit_string_zero_terminated(nk, flags, min_height_buffer, + sizeof(min_height_buffer), + nk_filter_decimal); + if (events & NK_EDIT_COMMITED) + { + min_height = abs(atoi(min_height_buffer)); + update_size_limit = true; + } + else if (events & NK_EDIT_DEACTIVATED) + sprintf(min_height_buffer, "%i", min_height); + + if (nk_checkbox_label(nk, "Maximum Size", &limit_max_size)) + update_size_limit = true; + + events = nk_edit_string_zero_terminated(nk, flags, max_width_buffer, + sizeof(max_width_buffer), + nk_filter_decimal); + if (events & NK_EDIT_COMMITED) + { + max_width = abs(atoi(max_width_buffer)); + update_size_limit = true; + } + else if (events & NK_EDIT_DEACTIVATED) + sprintf(max_width_buffer, "%i", max_width); + + events = nk_edit_string_zero_terminated(nk, flags, max_height_buffer, + sizeof(max_height_buffer), + nk_filter_decimal); + if (events & NK_EDIT_COMMITED) + { + max_height = abs(atoi(max_height_buffer)); + update_size_limit = true; + } + else if (events & NK_EDIT_DEACTIVATED) + sprintf(max_height_buffer, "%i", max_height); + + if (update_size_limit) + { + glfwSetWindowSizeLimits(window, + limit_min_size ? min_width : GLFW_DONT_CARE, + limit_min_size ? min_height : GLFW_DONT_CARE, + limit_max_size ? max_width : GLFW_DONT_CARE, + limit_max_size ? max_height : GLFW_DONT_CARE); + } + + int fb_width, fb_height; + glfwGetFramebufferSize(window, &fb_width, &fb_height); + nk_label(nk, "Framebuffer Size", NK_TEXT_LEFT); + nk_labelf(nk, NK_TEXT_LEFT, "%i", fb_width); + nk_labelf(nk, NK_TEXT_LEFT, "%i", fb_height); + + float xscale, yscale; + glfwGetWindowContentScale(window, &xscale, &yscale); + nk_label(nk, "Content Scale", NK_TEXT_LEFT); + nk_labelf(nk, NK_TEXT_LEFT, "%f", xscale); + nk_labelf(nk, NK_TEXT_LEFT, "%f", yscale); + + nk_layout_row_begin(nk, NK_DYNAMIC, 30, 5); + int frame_left, frame_top, frame_right, frame_bottom; + glfwGetWindowFrameSize(window, &frame_left, &frame_top, &frame_right, &frame_bottom); + nk_layout_row_push(nk, 1.f / 3.f); + nk_label(nk, "Frame Size:", NK_TEXT_LEFT); + nk_layout_row_push(nk, 1.f / 6.f); + nk_labelf(nk, NK_TEXT_LEFT, "%i", frame_left); + nk_layout_row_push(nk, 1.f / 6.f); + nk_labelf(nk, NK_TEXT_LEFT, "%i", frame_top); + nk_layout_row_push(nk, 1.f / 6.f); + nk_labelf(nk, NK_TEXT_LEFT, "%i", frame_right); + nk_layout_row_push(nk, 1.f / 6.f); + nk_labelf(nk, NK_TEXT_LEFT, "%i", frame_bottom); + nk_layout_row_end(nk); + + nk_layout_row_begin(nk, NK_DYNAMIC, 30, 2); + float opacity = glfwGetWindowOpacity(window); + nk_layout_row_push(nk, 1.f / 3.f); + nk_labelf(nk, NK_TEXT_LEFT, "Opacity: %0.3f", opacity); + nk_layout_row_push(nk, 2.f / 3.f); + if (nk_slider_float(nk, 0.f, &opacity, 1.f, 0.001f)) + glfwSetWindowOpacity(window, opacity); + nk_layout_row_end(nk); + + nk_layout_row_begin(nk, NK_DYNAMIC, 30, 2); + int should_close = glfwWindowShouldClose(window); + nk_layout_row_push(nk, 1.f / 3.f); + if (nk_checkbox_label(nk, "Should Close", &should_close)) + glfwSetWindowShouldClose(window, should_close); + nk_layout_row_push(nk, 2.f / 3.f); + nk_checkbox_label(nk, "May Close", &may_close); + nk_layout_row_end(nk); + + nk_layout_row_dynamic(nk, 30, 1); + nk_label(nk, "Attributes", NK_TEXT_CENTERED); + + nk_layout_row_dynamic(nk, 30, width > 200 ? width / 200 : 1); + + int decorated = glfwGetWindowAttrib(window, GLFW_DECORATED); + if (nk_checkbox_label(nk, "Decorated", &decorated)) + glfwSetWindowAttrib(window, GLFW_DECORATED, decorated); + + int resizable = glfwGetWindowAttrib(window, GLFW_RESIZABLE); + if (nk_checkbox_label(nk, "Resizable", &resizable)) + glfwSetWindowAttrib(window, GLFW_RESIZABLE, resizable); + + int floating = glfwGetWindowAttrib(window, GLFW_FLOATING); + if (nk_checkbox_label(nk, "Floating", &floating)) + glfwSetWindowAttrib(window, GLFW_FLOATING, floating); + + int passthrough = glfwGetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH); + if (nk_checkbox_label(nk, "Mouse Passthrough", &passthrough)) + glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, passthrough); + + int auto_iconify = glfwGetWindowAttrib(window, GLFW_AUTO_ICONIFY); + if (nk_checkbox_label(nk, "Auto Iconify", &auto_iconify)) + glfwSetWindowAttrib(window, GLFW_AUTO_ICONIFY, auto_iconify); + + nk_value_bool(nk, "Focused", glfwGetWindowAttrib(window, GLFW_FOCUSED)); + nk_value_bool(nk, "Hovered", glfwGetWindowAttrib(window, GLFW_HOVERED)); + nk_value_bool(nk, "Visible", glfwGetWindowAttrib(window, GLFW_VISIBLE)); + nk_value_bool(nk, "Iconified", glfwGetWindowAttrib(window, GLFW_ICONIFIED)); + nk_value_bool(nk, "Maximized", glfwGetWindowAttrib(window, GLFW_MAXIMIZED)); + } + nk_end(nk); + + glClear(GL_COLOR_BUFFER_BIT); + nk_glfw3_render(NK_ANTI_ALIASING_ON); + glfwSwapBuffers(window); + + glfwWaitEvents(); + } + + nk_glfw3_shutdown(); + glfwTerminate(); + exit(EXIT_SUCCESS); +} + From a12adc1a34f88db744fd7428306cd6cb878b078b Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Thu, 22 May 2025 22:25:19 +0200 Subject: [PATCH 24/28] added clangd cache folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ad0a7b2..3499fc3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build .vscode /.vs +.cache From a4f6803c35e8fc26db17f40d8867adea328c919f Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Thu, 22 May 2025 22:39:05 +0200 Subject: [PATCH 25/28] remove deprecated GLFW calls and tame clang-format --- CMakeLists.txt | 6 +++--- src/lib/src/window.cpp | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index effda97..4715d0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,14 +11,14 @@ project(paradiso # boilerplate locations for build set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin CACHE PATH "Executables go here") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib CACHE PATH "Libraries go here") -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin CACHE PATH "Standalone DLLs go here") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin CACHE PATH "Standalone DLLs go here") # # C++20 is mandatory # -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) add_subdirectory(src) -add_subdirectory(examples) \ No newline at end of file +add_subdirectory(examples) diff --git a/src/lib/src/window.cpp b/src/lib/src/window.cpp index a264dcf..253d338 100644 --- a/src/lib/src/window.cpp +++ b/src/lib/src/window.cpp @@ -22,8 +22,10 @@ */ #include "paradiso/window.hpp" +// clang-format off #include "glad/glad.h" #include "GLFW/glfw3.h" +// clang-format on #include #include @@ -89,9 +91,8 @@ struct Window::impl { static void charmods_callback(GLFWwindow* window, unsigned int codepoint, int mods) { // build the string from a Unicode code point - std::wstring_convert, char32_t> converter; - std::string u8str = converter.to_bytes(codepoint); - + // std::wstring_convert, char32_t> + // converter; std::string u8str = converter.to_bytes(codepoint); // input::get()._input_string = u8str; } @@ -146,8 +147,9 @@ struct Window::impl { glfwSetFramebufferSizeCallback(window_, Window::impl::framebuffer_size_callback); glfwSetKeyCallback(window_, Window::impl::key_callback); - // glfwSetCharCallback(_window, character_callback); - glfwSetCharModsCallback(window_, charmods_callback); + // glfwSetCharCallback(_window, character_callback); + // glfwSetCharModsCallback(window_, charmods_callback); // will be + // deprecated in 4.0 glfwSetScrollCallback(window_, scroll_callback); glfwSetDropCallback(window_, drop_callback); @@ -182,7 +184,6 @@ struct Window::impl { // delete events paradiso::Window::KeyboardInputStack{}.swap(keyboard_input_); - // get new events glfwPollEvents(); @@ -310,5 +311,4 @@ const Window::KeyboardInputStack& Window::keyboard_input() const { return impl_->keyboard_input_; } - } // namespace paradiso From 317cde6fa14575630c2fb41d75f02da40dff81cb Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Sun, 25 May 2025 12:31:16 +0200 Subject: [PATCH 26/28] - update copyright - add instructions for cross-compilation - add utility function for Windows and Linux executable path --- .gitignore | 2 +- docs/COMPILATION.md | 31 +++++++++ etc/cmake/mingw64-toolchain.cmake | 17 +++++ examples/pong/pong.cpp | 24 ++++--- examples/quickwings/CMakeLists.txt | 7 ++- examples/quickwings/quickwings.cpp | 83 ++++++++++++++----------- examples/simple/simple.cpp | 7 ++- src/lib/CMakeLists.txt | 2 + src/lib/include/paradiso/aabb.hpp | 2 +- src/lib/include/paradiso/bitmap.hpp | 5 +- src/lib/include/paradiso/bitmap_io.hpp | 5 +- src/lib/include/paradiso/context.hpp | 2 +- src/lib/include/paradiso/geometry.hpp | 2 +- src/lib/include/paradiso/globals.hpp | 12 ++-- src/lib/include/paradiso/matrix.hpp | 3 +- src/lib/include/paradiso/matrixbase.hpp | 16 +++-- src/lib/include/paradiso/renderer.hpp | 2 +- src/lib/include/paradiso/rgba.hpp | 2 +- src/lib/include/paradiso/shader.hpp | 2 +- src/lib/include/paradiso/sprite.hpp | 2 +- src/lib/include/paradiso/utils.hpp | 38 +++++++++++ src/lib/include/paradiso/vector.hpp | 2 +- src/lib/include/paradiso/window.hpp | 7 +-- src/lib/src/bitmap_io.cpp | 11 +--- src/lib/src/context.cpp | 2 +- src/lib/src/renderer.cpp | 4 +- src/lib/src/shader.cpp | 2 +- src/lib/src/shader_sprite.hpp | 3 +- src/lib/src/utils.cpp | 46 ++++++++++++++ src/lib/src/window.cpp | 2 +- 30 files changed, 243 insertions(+), 102 deletions(-) create mode 100644 docs/COMPILATION.md create mode 100644 etc/cmake/mingw64-toolchain.cmake create mode 100644 src/lib/include/paradiso/utils.hpp create mode 100644 src/lib/src/utils.cpp diff --git a/.gitignore b/.gitignore index 3499fc3..a42757e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -build +build* .vscode /.vs .cache diff --git a/docs/COMPILATION.md b/docs/COMPILATION.md new file mode 100644 index 0000000..3634afb --- /dev/null +++ b/docs/COMPILATION.md @@ -0,0 +1,31 @@ +# Cross Compiling with MinGW 64 + + +As I do not own any Windows machine, builds on Windows rely on [MinGW](https://www.mingw-w64.org) which is install with the ArchLinux package group `mingw-64-toolchain` (contains [MinGW64 Crosscompilation parts](https://archlinux.org/packages/?q=mingw-w64)) + +## Install MinGW + +```bash +pacman -S mingw-w64-toolchain +``` + +## Create Build + +The root folder adds a `.gitignore` rule to leave out everything `build*` + +```bash +mkdir -p build_w64 +cd build_w64 +``` + +## Configure + +```bash +cmake . -DCMAKE_TOOLCHAIN_FILE=../etc/cmake/mingw64-toolchain.cmake +``` + +## Build + +```bash +cmake --build . +``` diff --git a/etc/cmake/mingw64-toolchain.cmake b/etc/cmake/mingw64-toolchain.cmake new file mode 100644 index 0000000..86ac70b --- /dev/null +++ b/etc/cmake/mingw64-toolchain.cmake @@ -0,0 +1,17 @@ +# toolchain-mingw64.cmake +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_PROCESSOR x86_64) + +# specify the cross compiler +set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) +set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) +set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) + +# where is the target environment +set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) + +# search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +# for libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/examples/pong/pong.cpp b/examples/pong/pong.cpp index 2b979f7..031c62e 100644 --- a/examples/pong/pong.cpp +++ b/examples/pong/pong.cpp @@ -1,7 +1,7 @@ /** * paradiso - Paradigmen der Softwareentwicklung * - * (c) Copyright 2023-2024 Hartmut Seichter + * (c) Copyright 2023-2025 Hartmut Seichter and Contributors * */ @@ -45,13 +45,10 @@ struct PongStage { // sprite paradiso::Sprite sprite{ - .bitmap = paradiso::Bitmap::from_data(paradiso::Size{1, 1}, - paradiso::RGBA::from_rgb(0x80,0xFF,0xFF)) - }; + .bitmap = paradiso::Bitmap::from_data( + paradiso::Size{1, 1}, paradiso::RGBA::from_rgb(0x80, 0xFF, 0xFF))}; - void draw(const paradiso::Shader& shader) { - renderer.draw(sprite, shader); - } + void draw(const paradiso::Shader& shader) { renderer.draw(sprite, shader); } paradiso::Renderer renderer{}; }; @@ -166,8 +163,9 @@ struct PongBall { constexpr void push(const auto& impulse) noexcept { velocity += impulse; } - constexpr void whoop(const auto& whoopiness) noexcept { velocity *= whoopiness; } - + constexpr void whoop(const auto& whoopiness) noexcept { + velocity *= whoopiness; + } }; auto main() -> int { @@ -233,19 +231,19 @@ auto main() -> int { if (!w.keyboard_input().empty()) { if (w.keyboard_input().top().key == 'R') { - ball.sprite.pivot.x() = 0.0f; - ball.sprite.pivot.y() = 0.9f; + ball.sprite.pivot.x() = 0.0f; + ball.sprite.pivot.y() = 0.9f; } // speed adjust if (w.keyboard_input().top().key == 'N') { std::cout << "Speed Up!\n"; - ball.push(paradiso::Vector2::make(0.f,0.01f)); + ball.push(paradiso::Vector2::make(0.f, 0.01f)); } else if (w.keyboard_input().top().key == 'M') { - ball.push(paradiso::Vector2::make(0.f,-0.01f)); + ball.push(paradiso::Vector2::make(0.f, -0.01f)); std::cout << "Speed Lower!\n"; } diff --git a/examples/quickwings/CMakeLists.txt b/examples/quickwings/CMakeLists.txt index 0b5ffe2..5ac3667 100644 --- a/examples/quickwings/CMakeLists.txt +++ b/examples/quickwings/CMakeLists.txt @@ -14,7 +14,10 @@ add_executable(quickwings ${quickwings_srcs} ${quickwings_assets}) target_link_libraries(quickwings paradiso_core) +# +# copy files to bin/../assets folder +# add_custom_command(TARGET quickwings POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_SOURCE_DIR}/assets/ $/assets) - \ No newline at end of file + ${CMAKE_CURRENT_SOURCE_DIR}/assets/ + $/assets) diff --git a/examples/quickwings/quickwings.cpp b/examples/quickwings/quickwings.cpp index 9df112b..2259737 100644 --- a/examples/quickwings/quickwings.cpp +++ b/examples/quickwings/quickwings.cpp @@ -1,7 +1,8 @@ /** * paradiso - Paradigmen der Softwareentwicklung * - * (c) Copyright 2023-2024 Hartmut Seichter, Robin Rottstädt, brxxh (Hannes Brothuhn) + * (c) Copyright 2023-2025 Hartmut Seichter and Contributors, Robin Rottstädt, + * brxxh (Hannes Brothuhn) * */ @@ -77,8 +78,8 @@ struct Background { }; struct Pipe { - paradiso::Sprite pipe_top; - paradiso::Sprite pipe_bottom; + paradiso::Sprite pipe_top{}; + paradiso::Sprite pipe_bottom{}; paradiso::Renderer renderer1{}; paradiso::Renderer renderer2{}; @@ -95,16 +96,21 @@ struct Pipe { pipe_top = paradiso::Sprite{ .bitmap = pipe_image, - .pivot = {paradiso::Vector2::make(1.4f, pipe_spawn_rand + 1.0f)}, - .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 320.0f)) / 700.0f) * 2.25f)}, + .pivot = {paradiso::Vector2::make(1.4f, + pipe_spawn_rand + 1.0f)}, + .scale = {paradiso::Vector2::make( + ((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f, + ((700.0f - (700.0f - 320.0f)) / 700.0f) * 2.25f)}, .rotation = 3.1415926f}; pipe_bottom = paradiso::Sprite{ .bitmap = pipe_image, - .pivot = {paradiso::Vector2::make(1.4f, pipe_spawn_rand - 1.5f)}, - .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 320.0f)) / 700.0f) * 2.25f)}}; + .pivot = {paradiso::Vector2::make(1.4f, + pipe_spawn_rand - 1.5f)}, + .scale = {paradiso::Vector2::make( + ((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f, + ((700.0f - (700.0f - 320.0f)) / 700.0f) * 2.25f)}}; paused = true; - } void update() { @@ -115,8 +121,7 @@ struct Pipe { if (paused == true) { return; - } - else { + } else { pipe_spawn_rand_int = rand() % 80 + 15; pipe_spawn_rand = float(pipe_spawn_rand_int) / 100; @@ -124,7 +129,8 @@ struct Pipe { pipe_bottom.pivot.x() -= 0.02f; risky_pos_x = pipe_top.pivot.x(); - risky_pos_max_x = pipe_top.pivot.x() + ((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f; + risky_pos_max_x = pipe_top.pivot.x() + + ((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f; risky_pos_top_y = pipe_top.pivot.y(); risky_pos_top_max_y = pipe_top.pivot.y() + 10.0f; @@ -173,11 +179,15 @@ struct Grass { grassLeft = paradiso::Sprite{ .bitmap = grassImage, .pivot = {paradiso::Vector2::make(0.0f, -0.9f)}, - .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 504.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 112.0f)) / 700.0f) * 2.25f)}}; + .scale = {paradiso::Vector2::make( + ((500.0f - (500.0f - 504.0f)) / 500.0f) * 2.25f, + ((700.0f - (700.0f - 112.0f)) / 700.0f) * 2.25f)}}; grassRight = paradiso::Sprite{ .bitmap = grassImage, .pivot = {paradiso::Vector2::make(1.002f, -0.9f)}, - .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 504.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 112.0f)) / 700.0f) * 2.25f)}}; + .scale = {paradiso::Vector2::make( + ((500.0f - (500.0f - 504.0f)) / 500.0f) * 2.25f, + ((700.0f - (700.0f - 112.0f)) / 700.0f) * 2.25f)}}; } void draw(const paradiso::Shader& shader) { @@ -206,7 +216,6 @@ struct Grass { } }; - struct QuickWings { paradiso::Renderer renderer1{}; paradiso::Renderer renderer2{}; @@ -295,13 +304,12 @@ struct QuickWings { // Stop game if (paused) { return; - } - else { - // Apply gravity - velocity += gravity; + } else { + // Apply gravity + velocity += gravity; - if (move_up) - velocity += move_up_velocity - gravity; + if (move_up) + velocity += move_up_velocity - gravity; // Cap velocity if (velocity > max_velocity) @@ -333,11 +341,11 @@ struct QuickWings { if (pos >= final_risky_pos_top_y && pos <= risky_pos_top_max_y) { game_over = true; } - if (pos <= final_risky_pos_bottom_y && pos >= risky_pos_bottom_max_y) { + if (pos <= final_risky_pos_bottom_y && + pos >= risky_pos_bottom_max_y) { if (collision_counter == 0) { collision_counter++; - } - else { + } else { collision_counter = 2; } @@ -354,15 +362,15 @@ struct QuickWings { paused = false; if (paused == false) { - bool pressed_up = input.top().key == ' ' || input.top().key == 'W'; + bool pressed_up = + input.top().key == ' ' || input.top().key == 'W'; if (input.top().action == 1 && pressed_up) { move_up = true; } else if (input.top().action == 0 && pressed_up) { move_up = false; } - } - else { + } else { return; } } @@ -377,11 +385,10 @@ struct Message { Message() { auto messageImage = paradiso::BitmapIO::get().load("message.png"); - messageSprite = paradiso::Sprite{ + messageSprite = paradiso::Sprite{ .bitmap = messageImage, .pivot = {paradiso::Vector2::make(0.0f, 0.0f)}, - .scale = {paradiso::Vector2::make(0.8f, 0.8f)} - }; + .scale = {paradiso::Vector2::make(0.8f, 0.8f)}}; }; void draw(const paradiso::Shader& shader) { @@ -409,11 +416,12 @@ struct GameOverMessage { GameOverMessage() { auto messageImage = paradiso::BitmapIO::get().load("gameover.png"); - messageSprite = paradiso::Sprite{ + messageSprite = paradiso::Sprite{ .bitmap = messageImage, .pivot = {paradiso::Vector2::make(0.0f, 0.4f)}, - .scale = {paradiso::Vector2::make(((500.0f - (500.0f - 192.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 42.0f)) / 700.0f) * 2.25f)} - }; + .scale = {paradiso::Vector2::make( + ((500.0f - (500.0f - 192.0f)) / 500.0f) * 2.25f, + ((700.0f - (700.0f - 42.0f)) / 700.0f) * 2.25f)}}; }; void draw(const paradiso::Shader& shader) { @@ -438,9 +446,10 @@ auto main() -> int { */ window - .set_size(size) // ... Grösse - .set_position(paradiso::Point{.x = 1920 / 2 - 500 / 2, .y = 1080 / 2 - 700 / 2}) // ... Position - .set_title("PardiSO.FlappyBird") // ... Titel + .set_size(size) // ... Grösse + .set_position(paradiso::Point{.x = 1920 / 2 - 500 / 2, + .y = 1080 / 2 - 700 / 2}) // ... Position + .set_title("PardiSO.FlappyBird") // ... Titel .set_visible(true); // ... und jetzt anzeigen! // der Fenster Kontext @@ -461,7 +470,6 @@ auto main() -> int { // nothing beats a classic look ctx.set_clearcolor(paradiso::RGBA::from_rgb(0x00, 0x00, 0x00)); - // Asset loader bekommt den Pfad paradiso::BitmapIO::get().set_path("assets"); @@ -474,7 +482,6 @@ auto main() -> int { auto message = Message{}; auto gameover = GameOverMessage{}; - // timer // das update führt den hier mitgegebnen Ausdruck innerhalb der internen @@ -522,7 +529,7 @@ auto main() -> int { // Quit return !(w.keyboard_input().size() && w.keyboard_input().top().key == 'Q'); - })) { + })) { }; return 0; diff --git a/examples/simple/simple.cpp b/examples/simple/simple.cpp index 09db5f1..84ae90e 100644 --- a/examples/simple/simple.cpp +++ b/examples/simple/simple.cpp @@ -5,12 +5,14 @@ * */ +#include #include #include #include #include #include #include +#include #include #include @@ -18,6 +20,9 @@ auto main() -> int { + // + std::cout << "running: " << paradiso::get_executable_path() << '\n'; + // Ausgabefenster ... sieht aus als wäre es auf dem Stack auto window = paradiso::Window(); @@ -122,4 +127,4 @@ auto main() -> int { }; return 0; -} \ No newline at end of file +} diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 63e2fdd..d5921f1 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -14,6 +14,7 @@ set(paradiso_srcs src/renderer.cpp src/context.cpp src/shader_sprite.hpp + src/utils.cpp ) set(paradiso_incs @@ -26,6 +27,7 @@ set(paradiso_incs include/paradiso/window.hpp include/paradiso/renderer.hpp include/paradiso/context.hpp + include/paradiso/utils.hpp ) add_library(paradiso_core diff --git a/src/lib/include/paradiso/aabb.hpp b/src/lib/include/paradiso/aabb.hpp index cad123f..a7f49ae 100644 --- a/src/lib/include/paradiso/aabb.hpp +++ b/src/lib/include/paradiso/aabb.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib/include/paradiso/bitmap.hpp b/src/lib/include/paradiso/bitmap.hpp index d6971f5..7b7ac34 100644 --- a/src/lib/include/paradiso/bitmap.hpp +++ b/src/lib/include/paradiso/bitmap.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -60,7 +60,8 @@ struct Bitmap final { * @param[in] data vector of RGBA values * @return bitmap with data from this call */ - static constexpr Bitmap from_data(Size size, std::vector data) noexcept { + static constexpr Bitmap from_data(Size size, + std::vector data) noexcept { assert(data.size() == size.height * size.width); return {.size = size, .data = data}; } diff --git a/src/lib/include/paradiso/bitmap_io.hpp b/src/lib/include/paradiso/bitmap_io.hpp index af0c529..1700bc1 100644 --- a/src/lib/include/paradiso/bitmap_io.hpp +++ b/src/lib/include/paradiso/bitmap_io.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,8 +25,8 @@ #include -#include #include +#include namespace paradiso { @@ -41,7 +41,6 @@ struct BitmapIO { std::string path() const; private: - struct Impl; std::unique_ptr impl_; diff --git a/src/lib/include/paradiso/context.hpp b/src/lib/include/paradiso/context.hpp index 31a9ac1..08e1053 100644 --- a/src/lib/include/paradiso/context.hpp +++ b/src/lib/include/paradiso/context.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib/include/paradiso/geometry.hpp b/src/lib/include/paradiso/geometry.hpp index acd018a..42adf1c 100644 --- a/src/lib/include/paradiso/geometry.hpp +++ b/src/lib/include/paradiso/geometry.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib/include/paradiso/globals.hpp b/src/lib/include/paradiso/globals.hpp index 440bc7d..5cd4ead 100644 --- a/src/lib/include/paradiso/globals.hpp +++ b/src/lib/include/paradiso/globals.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,22 +23,20 @@ #ifndef PARADISO_GLOBALS_HPP #define PARADISO_GLOBALS_HPP -#include #include #include +#include -#include #include -#include #include +#include #include #include +#include #include -#include #include - - +#include #endif diff --git a/src/lib/include/paradiso/matrix.hpp b/src/lib/include/paradiso/matrix.hpp index c359a87..7de0113 100644 --- a/src/lib/include/paradiso/matrix.hpp +++ b/src/lib/include/paradiso/matrix.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,7 +26,6 @@ #include #include - namespace paradiso { template diff --git a/src/lib/include/paradiso/matrixbase.hpp b/src/lib/include/paradiso/matrixbase.hpp index b20a8d4..3fb4227 100644 --- a/src/lib/include/paradiso/matrixbase.hpp +++ b/src/lib/include/paradiso/matrixbase.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -43,9 +43,13 @@ template struct MatrixBase { constexpr iterator begin() noexcept { return this->data(); } constexpr iterator end() noexcept { return this->data() + size(); } constexpr const_iterator begin() const noexcept { return this->data(); } - constexpr const_iterator end() const noexcept { return this->data() + size(); } + constexpr const_iterator end() const noexcept { + return this->data() + size(); + } constexpr const_iterator cbegin() const noexcept { return this->data(); } - constexpr const_iterator cend() const noexcept { return this->data() + size(); } + constexpr const_iterator cend() const noexcept { + return this->data() + size(); + } constexpr Scalar& operator[](std::size_t i) { return this->data()[i]; } constexpr const Scalar& operator[](std::size_t i) const { @@ -111,10 +115,12 @@ template struct MatrixBase { } constexpr void operator+=(const Derived& b) { - std::transform((*this).begin(),(*this).end(),b.begin(),(*this).begin(),std::plus<>()); + std::transform((*this).begin(), (*this).end(), b.begin(), + (*this).begin(), std::plus<>()); } constexpr void operator-=(const Derived& b) { - std::transform((*this).begin(),(*this).end(),b.begin(),(*this).begin(),std::minus<>()); + std::transform((*this).begin(), (*this).end(), b.begin(), + (*this).begin(), std::minus<>()); } constexpr const Derived operator*(const Scalar& b) const { diff --git a/src/lib/include/paradiso/renderer.hpp b/src/lib/include/paradiso/renderer.hpp index b52a908..824eeeb 100644 --- a/src/lib/include/paradiso/renderer.hpp +++ b/src/lib/include/paradiso/renderer.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib/include/paradiso/rgba.hpp b/src/lib/include/paradiso/rgba.hpp index d7745e2..fc039e2 100644 --- a/src/lib/include/paradiso/rgba.hpp +++ b/src/lib/include/paradiso/rgba.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib/include/paradiso/shader.hpp b/src/lib/include/paradiso/shader.hpp index d51f6cf..cdc96c8 100644 --- a/src/lib/include/paradiso/shader.hpp +++ b/src/lib/include/paradiso/shader.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib/include/paradiso/sprite.hpp b/src/lib/include/paradiso/sprite.hpp index a518e51..cf4652c 100644 --- a/src/lib/include/paradiso/sprite.hpp +++ b/src/lib/include/paradiso/sprite.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib/include/paradiso/utils.hpp b/src/lib/include/paradiso/utils.hpp new file mode 100644 index 0000000..64b53a5 --- /dev/null +++ b/src/lib/include/paradiso/utils.hpp @@ -0,0 +1,38 @@ +/* + * Copyright 2023-2025 Hartmut Seichter and Contributors + * + * 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. + * + */ +#ifndef PARADISO_UTILS_HPP +#define PARADISO_UTILS_HPP + +#include + +namespace paradiso { + +using path = std::filesystem::path; + +/** + * @return executable path + */ +path get_executable_path(); +} // namespace paradiso + +#endif diff --git a/src/lib/include/paradiso/vector.hpp b/src/lib/include/paradiso/vector.hpp index 2012ef5..5ac40f2 100644 --- a/src/lib/include/paradiso/vector.hpp +++ b/src/lib/include/paradiso/vector.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib/include/paradiso/window.hpp b/src/lib/include/paradiso/window.hpp index 91337ac..b55124d 100644 --- a/src/lib/include/paradiso/window.hpp +++ b/src/lib/include/paradiso/window.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,8 +23,8 @@ #ifndef PARADISO_WINDOW_HPP #define PARADISO_WINDOW_HPP -#include #include +#include #include #include @@ -72,7 +72,6 @@ struct Window final { void set_resizecallback(on_resizecallback_t f) { on_resize_ = f; } - bool visible() const; Window& set_visible(bool is_visible); @@ -83,8 +82,6 @@ struct Window final { std::unique_ptr impl_; on_resizecallback_t on_resize_; - - }; } // namespace paradiso diff --git a/src/lib/src/bitmap_io.cpp b/src/lib/src/bitmap_io.cpp index 3490669..b279244 100644 --- a/src/lib/src/bitmap_io.cpp +++ b/src/lib/src/bitmap_io.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -127,15 +127,10 @@ Bitmap BitmapIO::load(std::string_view filename, bool ignore_cache) const { return impl_->load(filename); } -void BitmapIO::set_path(std::string_view path) -{ - impl_->asset_path_ = path; -} +void BitmapIO::set_path(std::string_view path) { impl_->asset_path_ = path; } -std::string BitmapIO::path() const -{ +std::string BitmapIO::path() const { return impl_->asset_path_.generic_string(); } - } // namespace paradiso diff --git a/src/lib/src/context.cpp b/src/lib/src/context.cpp index 6ef465c..6d16a33 100644 --- a/src/lib/src/context.cpp +++ b/src/lib/src/context.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib/src/renderer.cpp b/src/lib/src/renderer.cpp index ab03c23..ff4b7ed 100644 --- a/src/lib/src/renderer.cpp +++ b/src/lib/src/renderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,8 +31,8 @@ #include #include #include -#include #include +#include #if defined(_WIN32) #undef max diff --git a/src/lib/src/shader.cpp b/src/lib/src/shader.cpp index e3d6b73..12b7719 100644 --- a/src/lib/src/shader.cpp +++ b/src/lib/src/shader.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib/src/shader_sprite.hpp b/src/lib/src/shader_sprite.hpp index 1f546c9..bc374ef 100644 --- a/src/lib/src/shader_sprite.hpp +++ b/src/lib/src/shader_sprite.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -65,7 +65,6 @@ void main() { } )"; - static constexpr auto sprite_unlit_fragment = R"( #version 400 core diff --git a/src/lib/src/utils.cpp b/src/lib/src/utils.cpp new file mode 100644 index 0000000..bfd05d9 --- /dev/null +++ b/src/lib/src/utils.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2023-2025 Hartmut Seichter and Contributors + * + * 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 "paradiso/utils.hpp" + +#include +#include +#include + +#if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE) +#define WIN32_LEAN_AND_MEAN +#include +#endif + +namespace paradiso { + +path get_executable_path() { +#if defined(_WIN32) + std::array lpFname{}; + DWORD ret = GetModuleFileName(NULL, lpFname.data(), lpFname.size()); + return {std::string{std::from_range, lpFname}}; +#elif defined(__linux) + return std::filesystem::canonical(u8"/proc/self/exe"); +#endif +} + +} // namespace paradiso diff --git a/src/lib/src/window.cpp b/src/lib/src/window.cpp index 253d338..c417836 100644 --- a/src/lib/src/window.cpp +++ b/src/lib/src/window.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Hartmut Seichter + * Copyright 2023-2025 Hartmut Seichter and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal From aea5ca958aeee379f0b0221f2ca5a86d0dced05a Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Sun, 25 May 2025 14:03:25 +0200 Subject: [PATCH 27/28] update to contributors and ideas files --- CONTRIBUTORS.md | 6 ++++++ docs/README.md | 10 ++++++---- examples/quickwings/quickwings.cpp | 4 ++-- 3 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 CONTRIBUTORS.md diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 0000000..f5d7881 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,6 @@ +# Contributors + +- Hartmut Seichter (dev lead) +- Robin Rottstädt (image loader) +- Tim Gösselmann (Win32 fixes) +- Hannes Brothuhn (Flappy Bird clone) diff --git a/docs/README.md b/docs/README.md index 64ecc08..b373f58 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,6 +4,7 @@ Here some ideas for improving this tiny engine: ## Rendering - [ ] replace the OpenGL renderer with a Vulkan backend +- [ ] add sprite atlas support (test case Kenny flappy bird) - [ ] add animatable sprites (access to UV mapping and tiling) - [ ] add a SDF based renderer (parametric tiles and font rendering) @@ -15,11 +16,11 @@ Here some ideas for improving this tiny engine: ## System Level - [ ] add a `Asset` handler to load cache and manage assets -- [ ] introspection of file system if we load assset +- [ ] introspection of file system if we load asset ## Design -- [ ] replace some of the 'unkown source' assets +- [ ] replace some of the 'unknown source' assets ## Build / Dev Support - [ ] add a test rig either with Snitch or Catch2 @@ -27,10 +28,11 @@ Here some ideas for improving this tiny engine: - [ ] add CPU and GPU benchmarks to address various issues -# Issues +# Performance +For such a small engine, this should never happen: -```sh +```bash Performance counter stats for 'bin/paradiso_pong': 555,35 msec task-clock:u # 0,042 CPUs utilized diff --git a/examples/quickwings/quickwings.cpp b/examples/quickwings/quickwings.cpp index 2259737..17730a7 100644 --- a/examples/quickwings/quickwings.cpp +++ b/examples/quickwings/quickwings.cpp @@ -1,8 +1,7 @@ /** * paradiso - Paradigmen der Softwareentwicklung * - * (c) Copyright 2023-2025 Hartmut Seichter and Contributors, Robin Rottstädt, - * brxxh (Hannes Brothuhn) + * (c) Copyright 2023-2025 Hartmut Seichter and Contributors * */ @@ -13,6 +12,7 @@ #include #include #include +#include #include #include From 42a0d56173d77152b4cc210a17bacdff822ca7e5 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Sun, 25 May 2025 14:12:20 +0200 Subject: [PATCH 28/28] add some notes about design problems in quickwings --- examples/quickwings/quickwings.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/quickwings/quickwings.cpp b/examples/quickwings/quickwings.cpp index 17730a7..dd51112 100644 --- a/examples/quickwings/quickwings.cpp +++ b/examples/quickwings/quickwings.cpp @@ -19,6 +19,9 @@ #include #include +// TODO remove all hard coded 'magic' values! + +// TODO - remove global variables const int frame_rate = 60; bool game_over = false; float risky_pos_x; @@ -38,6 +41,7 @@ struct Background { paradiso::Renderer renderer{}; + // TODO no constructors in rule of zero Background() { auto backgroundImage = paradiso::BitmapIO::get().load("background-day.png"); @@ -91,6 +95,8 @@ struct Pipe { bool pos_reset = false; + // TODO no constructors in rule of zero + Pipe() { auto pipe_image = paradiso::BitmapIO::get().load("pipe-green.png"); @@ -115,6 +121,8 @@ struct Pipe { void update() { + // TODO improve state handling + if (game_over == true) { paused = true; } @@ -174,6 +182,7 @@ struct Grass { paradiso::Renderer renderer1{}; paradiso::Renderer renderer2{}; + // TODO no constructors in rule of zero Grass() { auto grassImage = paradiso::BitmapIO::get().load("base.png"); grassLeft = paradiso::Sprite{ @@ -244,6 +253,7 @@ struct QuickWings { int collision_counter = 0; + // TODO no constructors in rule of zero QuickWings() { float scaleh = 0.08f; float scalew = 0.158f;