Merge branch 'master' into window-visibility
This commit is contained in:
commit
56173d7cf4
24
.travis.yml
24
.travis.yml
@ -17,7 +17,7 @@ matrix:
|
|||||||
env: ARCH=amd64 INSTALL_GLFW=YES USE_EXTERNAL_GLFW=OFF
|
env: ARCH=amd64 INSTALL_GLFW=YES USE_EXTERNAL_GLFW=OFF
|
||||||
sudo: required
|
sudo: required
|
||||||
- os: linux
|
- os: linux
|
||||||
env: ARCH=amd64 INSTALL_GLFW=YES OPENAL=ON STATIC=OFF RELEASE=NO
|
env: ARCH=amd64 INSTALL_GLFW=YES STATIC=OFF RELEASE=NO
|
||||||
sudo: required
|
sudo: required
|
||||||
- os: linux
|
- os: linux
|
||||||
env: WAYLAND=ON ARCH=amd64 RELEASE=NO
|
env: WAYLAND=ON ARCH=amd64 RELEASE=NO
|
||||||
@ -42,6 +42,9 @@ matrix:
|
|||||||
- os: linux
|
- os: linux
|
||||||
env: ARCH=html5 RELEASE=NO
|
env: ARCH=html5 RELEASE=NO
|
||||||
sudo: required
|
sudo: required
|
||||||
|
- os: windows
|
||||||
|
compiler: gcc
|
||||||
|
env: ARCH=i386 SHARED=OFF RELEASE=NO
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
|
|
||||||
@ -49,7 +52,6 @@ before_install:
|
|||||||
- if [ -z "$USE_EXTERNAL_GLFW" ]; then export USE_EXTERNAL_GLFW=IF_POSSIBLE; fi
|
- if [ -z "$USE_EXTERNAL_GLFW" ]; then export USE_EXTERNAL_GLFW=IF_POSSIBLE; fi
|
||||||
- if [ -z "$SHARED" ]; then export SHARED=ON ; fi
|
- if [ -z "$SHARED" ]; then export SHARED=ON ; fi
|
||||||
- if [ -z "$STATIC" ]; then export STATIC=ON ; fi
|
- if [ -z "$STATIC" ]; then export STATIC=ON ; fi
|
||||||
- if [ -z "$OPENAL" ]; then export OPENAL=OFF; fi
|
|
||||||
- if [[ "$INSTALL_GLFW" == "YES" && "$USE_EXTERNAL_GLFW" != "OFF" ]]; then
|
- if [[ "$INSTALL_GLFW" == "YES" && "$USE_EXTERNAL_GLFW" != "OFF" ]]; then
|
||||||
export DONT_TEST=1;
|
export DONT_TEST=1;
|
||||||
fi
|
fi
|
||||||
@ -101,6 +103,11 @@ before_install:
|
|||||||
export RAYLIB_PACKAGE_SUFFIX="-macOS";
|
export RAYLIB_PACKAGE_SUFFIX="-macOS";
|
||||||
if [ "$INSTALL_GLFW" == "YES" ]; then brew update; brew install glfw; fi;
|
if [ "$INSTALL_GLFW" == "YES" ]; then brew update; brew install glfw; fi;
|
||||||
fi
|
fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "windows" ]; then
|
||||||
|
export DONT_TEST=1;
|
||||||
|
export RAYLIB_PACKAGE_SUFFIX="-windows";
|
||||||
|
export CMAKE_ARCH_ARGS='-DPLATFORM=Desktop';
|
||||||
|
fi
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- $RUNNER $CC --version
|
- $RUNNER $CC --version
|
||||||
|
|
||||||
@ -111,7 +118,7 @@ script:
|
|||||||
sudo dpkg -i extra-cmake-modules_5.38.0a-0ubuntu1_amd64.deb;
|
sudo dpkg -i extra-cmake-modules_5.38.0a-0ubuntu1_amd64.deb;
|
||||||
git clone git://anongit.freedesktop.org/wayland/wayland-protocols;
|
git clone git://anongit.freedesktop.org/wayland/wayland-protocols;
|
||||||
pushd wayland-protocols;
|
pushd wayland-protocols;
|
||||||
git checkout 1.12 && ./autogen.sh --prefix=/usr && make && sudo make install;
|
git checkout 1.15 && ./autogen.sh --prefix=/usr && make && sudo make install;
|
||||||
popd;
|
popd;
|
||||||
fi
|
fi
|
||||||
- $RUNNER cmake $CMAKE_ARCH_ARGS
|
- $RUNNER cmake $CMAKE_ARCH_ARGS
|
||||||
@ -121,10 +128,15 @@ script:
|
|||||||
-DUSE_EXTERNAL_GLFW=$USE_EXTERNAL_GLFW
|
-DUSE_EXTERNAL_GLFW=$USE_EXTERNAL_GLFW
|
||||||
-DUSE_WAYLAND=$WAYLAND
|
-DUSE_WAYLAND=$WAYLAND
|
||||||
-DINCLUDE_EVERYTHING=ON
|
-DINCLUDE_EVERYTHING=ON
|
||||||
|
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
|
||||||
..
|
..
|
||||||
- $RUNNER make VERBOSE=1
|
- $RUNNER cmake --build . --target
|
||||||
- if [ "$RELEASE" != "NO" ]; then $RUNNER make package; fi
|
- if [ "$RELEASE" != "NO" ]; then $RUNNER cmake --build . --target package; fi
|
||||||
- sudo $RUNNER make install
|
- if [ -n "$RUNNER" ]; then
|
||||||
|
sudo $RUNNER cmake --build . --target install;
|
||||||
|
else
|
||||||
|
$(which sudo) $RUNNER "$(which cmake)" --build . --target install;
|
||||||
|
fi
|
||||||
- if [ ! "$DONT_TEST" ]; then
|
- if [ ! "$DONT_TEST" ]; then
|
||||||
pkg-config --static --libs raylib;
|
pkg-config --static --libs raylib;
|
||||||
nm -g release/libraylib.a | grep glfwGetProcAddress || (echo "libraylib.a doesn't contain GLFW symbols! Aborting..." && false);
|
nm -g release/libraylib.a | grep glfwGetProcAddress || (echo "libraylib.a doesn't contain GLFW symbols! Aborting..." && false);
|
||||||
|
@ -61,6 +61,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||||||
|
|
||||||
- [raylib](https://github.com/raysan5/raylib) : raylib **C/C++** version (default)
|
- [raylib](https://github.com/raysan5/raylib) : raylib **C/C++** version (default)
|
||||||
- [raylib-lua](https://github.com/raysan5/raylib-lua) : raylib **Lua** binding
|
- [raylib-lua](https://github.com/raysan5/raylib-lua) : raylib **Lua** binding
|
||||||
|
- [raylib-lua-ffi](https://github.com/raysan5/raylib/issues/693) : raylib **Lua** ffi binding
|
||||||
- [raylib-go](https://github.com/gen2brain/raylib-go) : raylib **Go** binding
|
- [raylib-go](https://github.com/gen2brain/raylib-go) : raylib **Go** binding
|
||||||
- [raylib-Nim](https://gitlab.com/define-private-public/raylib-Nim) : raylib **Nim** binding
|
- [raylib-Nim](https://gitlab.com/define-private-public/raylib-Nim) : raylib **Nim** binding
|
||||||
- [cray](https://gitlab.com/Zatherz/cray) - raylib **Crystal** binding
|
- [cray](https://gitlab.com/Zatherz/cray) - raylib **Crystal** binding
|
||||||
@ -74,7 +75,9 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||||||
- [raylib-py](https://github.com/overdev/raylib-py) : raylib **Python** binding
|
- [raylib-py](https://github.com/overdev/raylib-py) : raylib **Python** binding
|
||||||
- [raylib-haskell](https://github.com/DevJac/raylib-haskell) : raylib **Haskell** binding
|
- [raylib-haskell](https://github.com/DevJac/raylib-haskell) : raylib **Haskell** binding
|
||||||
- [raylib-java](https://github.com/XoanaIO/raylib-java) : raylib **Java** binding
|
- [raylib-java](https://github.com/XoanaIO/raylib-java) : raylib **Java** binding
|
||||||
- *[raylib flat-assembler Usage example](http://forum.raylib.com/index.php?p=/discussion/comment/425/#Comment_425)*
|
- [raylib-chaiscript](https://github.com/RobLoach/raylib-chaiscript) : raylib **ChaiScript** binding
|
||||||
|
- [node-raylib](https://github.com/RobLoach/node-raylib) : **Node.js** raylib binding
|
||||||
|
- *[raylib flat-assembler Usage example]()*
|
||||||
- *[raylib COBOL Usage example](https://github.com/Martinfx/Cobol/tree/master/OpenCobol/Games/raylib)*
|
- *[raylib COBOL Usage example](https://github.com/Martinfx/Cobol/tree/master/OpenCobol/Games/raylib)*
|
||||||
|
|
||||||
Usually, raylib bindings follow the convention: `raylib-{language}`
|
Usually, raylib bindings follow the convention: `raylib-{language}`
|
||||||
|
@ -149,7 +149,7 @@ On November 2016, only 4 months after raylib 1.5, arrives raylib 1.6. This new v
|
|||||||
|
|
||||||
Complete [raylib Lua binding](https://github.com/raysan5/raylib-lua). All raylib functions plus the +60 code examples have been ported to Lua, now Lua users can enjoy coding videogames in Lua while using all the internal power of raylib. This addition also open the doors to Lua scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to Lua scripts while keep using raylib functionality.
|
Complete [raylib Lua binding](https://github.com/raysan5/raylib-lua). All raylib functions plus the +60 code examples have been ported to Lua, now Lua users can enjoy coding videogames in Lua while using all the internal power of raylib. This addition also open the doors to Lua scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to Lua scripts while keep using raylib functionality.
|
||||||
|
|
||||||
Completely redesigned [audio module](https://github.com/raysan5/raylib/blob/master/src/audio.c). Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. [FLAC file format support](https://github.com/raysan5/raylib/blob/master/src/external/dr_flac.h) has also been added. In the same line, [OpenAL Soft](https://github.com/kcat/openal-soft) backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completey self-contained, no external libraries required any more!
|
Completely redesigned [audio module](https://github.com/raysan5/raylib/blob/master/src/raudio.c). Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. [FLAC file format support](https://github.com/raysan5/raylib/blob/master/src/external/dr_flac.h) has also been added. In the same line, [OpenAL Soft](https://github.com/kcat/openal-soft) backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completey self-contained, no external libraries required any more!
|
||||||
|
|
||||||
[Physac](https://github.com/victorfisac/Physac) module has been moved to its own repository and it has been improved A LOT, actually, library has been completely rewritten from scratch by [@victorfisac](https://github.com/victorfisac), multiple samples have been added together with countless new features to match current standard 2D physic libraries. Results are amazing!
|
[Physac](https://github.com/victorfisac/Physac) module has been moved to its own repository and it has been improved A LOT, actually, library has been completely rewritten from scratch by [@victorfisac](https://github.com/victorfisac), multiple samples have been added together with countless new features to match current standard 2D physic libraries. Results are amazing!
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ NOTE for ADVENTURERS: raylib is a programming library to enjoy videogames progra
|
|||||||
no fancy interface, no visual helpers, no auto-debugging... just coding in the most
|
no fancy interface, no visual helpers, no auto-debugging... just coding in the most
|
||||||
pure spartan-programmers way. Are you ready to learn? Jump to [code examples!](http://www.raylib.com/examples.html)
|
pure spartan-programmers way. Are you ready to learn? Jump to [code examples!](http://www.raylib.com/examples.html)
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/raysan5/raylib.svg?branch=develop)](https://travis-ci.org/raysan5/raylib)
|
[![Build Status](https://travis-ci.org/raysan5/raylib.svg?branch=master)](https://travis-ci.org/raysan5/raylib)
|
||||||
[![https://ci.appveyor.com/api/projects/status/github/raysan5/raylib?svg=true](https://ci.appveyor.com/api/projects/status/github/raysan5/raylib?svg=true)](https://ci.appveyor.com/project/raysan5/raylib)
|
[![https://ci.appveyor.com/api/projects/status/github/raysan5/raylib?svg=true](https://ci.appveyor.com/api/projects/status/github/raysan5/raylib?svg=true)](https://ci.appveyor.com/project/raysan5/raylib)
|
||||||
[![Chat on Discord](https://img.shields.io/discord/308323056592486420.svg?logo=discord)](https://discord.gg/VkzNHUE)
|
[![Chat on Discord](https://img.shields.io/discord/308323056592486420.svg?logo=discord)](https://discord.gg/VkzNHUE)
|
||||||
[![License](https://img.shields.io/badge/license-zlib%2Flibpng-blue.svg)](LICENSE.md)
|
[![License](https://img.shields.io/badge/license-zlib%2Flibpng-blue.svg)](LICENSE.md)
|
||||||
@ -35,7 +35,7 @@ features
|
|||||||
|
|
||||||
raylib uses on its [core](https://github.com/raysan5/raylib/blob/master/src/core.c) module the outstanding [GLFW3](http://www.glfw.org/) library, embedded inside raylib in the form of [rglfw](https://github.com/raysan5/raylib/blob/master/src/rglfw.c) module, avoiding that way external dependencies.
|
raylib uses on its [core](https://github.com/raysan5/raylib/blob/master/src/core.c) module the outstanding [GLFW3](http://www.glfw.org/) library, embedded inside raylib in the form of [rglfw](https://github.com/raysan5/raylib/blob/master/src/rglfw.c) module, avoiding that way external dependencies.
|
||||||
|
|
||||||
raylib uses on its [audio](https://github.com/raysan5/raylib/blob/master/src/audio.c) module, the amazing [mini_al](https://github.com/dr-soft/mini_al) audio library, single-file header-only and supporting multiple platforms and multiple audio backends.
|
raylib uses on its [audio](https://github.com/raysan5/raylib/blob/master/src/raudio.c) module, the amazing [mini_al](https://github.com/dr-soft/mini_al) audio library, single-file header-only and supporting multiple platforms and multiple audio backends.
|
||||||
|
|
||||||
raylib uses internally multiple single-file header-only libraries to support multiple fileformats loading and saving, all those libraries are embedded with raylib and available in [src/external](https://github.com/raysan5/raylib/tree/master/src/external) directory.
|
raylib uses internally multiple single-file header-only libraries to support multiple fileformats loading and saving, all those libraries are embedded with raylib and available in [src/external](https://github.com/raysan5/raylib/tree/master/src/external) directory.
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ if(${PLATFORM} MATCHES "Android")
|
|||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_model_shader.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_model_shader.c)
|
||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_postprocessing.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_postprocessing.c)
|
||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_raymarching.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_raymarching.c)
|
||||||
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_palette_switch.c)
|
||||||
|
|
||||||
elseif(${PLATFORM} MATCHES "Web")
|
elseif(${PLATFORM} MATCHES "Web")
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1")
|
||||||
|
@ -118,8 +118,8 @@ endif
|
|||||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||||
# Emscripten required variables
|
# Emscripten required variables
|
||||||
EMSDK_PATH = C:/emsdk
|
EMSDK_PATH = C:/emsdk
|
||||||
EMSCRIPTEN_VERSION = 1.38.20
|
EMSCRIPTEN_VERSION = 1.38.21
|
||||||
CLANG_VERSION = e1.38.20_64bit
|
CLANG_VERSION = e1.38.21_64bit
|
||||||
PYTHON_VERSION = 2.7.13.1_64bit\python-2.7.13.amd64
|
PYTHON_VERSION = 2.7.13.1_64bit\python-2.7.13.amd64
|
||||||
NODE_VERSION = 8.9.1_64bit
|
NODE_VERSION = 8.9.1_64bit
|
||||||
export PATH = $(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
|
export PATH = $(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
|
||||||
@ -130,23 +130,23 @@ endif
|
|||||||
# RAYLIB_RELEASE_PATH points to provided binaries or your freshly built version.
|
# RAYLIB_RELEASE_PATH points to provided binaries or your freshly built version.
|
||||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||||
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/win32/mingw32
|
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/src
|
||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM_OS),LINUX)
|
ifeq ($(PLATFORM_OS),LINUX)
|
||||||
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/linux
|
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/src
|
||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM_OS),OSX)
|
ifeq ($(PLATFORM_OS),OSX)
|
||||||
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/osx
|
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/src
|
||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM_OS),BSD)
|
ifeq ($(PLATFORM_OS),BSD)
|
||||||
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/bsd
|
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/src
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||||
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/rpi
|
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/src
|
||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||||
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/html5
|
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/src
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# EXAMPLE_RUNTIME_PATH embeds a custom runtime location of libraylib.so or other desired libraries
|
# EXAMPLE_RUNTIME_PATH embeds a custom runtime location of libraylib.so or other desired libraries
|
||||||
@ -249,7 +249,7 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
|
|||||||
# -s EMTERPRETIFY_ASYNC=1 # support synchronous loops by emterpreter
|
# -s EMTERPRETIFY_ASYNC=1 # support synchronous loops by emterpreter
|
||||||
# --profiling # include information for code profiling
|
# --profiling # include information for code profiling
|
||||||
# --preload-file resources # specify a resources folder for data compilation
|
# --preload-file resources # specify a resources folder for data compilation
|
||||||
CFLAGS += -Os -s USE_GLFW=3 -s USE_SDL=2 -s ASSERTIONS=1 -s WASM=1 -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1
|
CFLAGS += -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1
|
||||||
|
|
||||||
# NOTE: Simple raylib examples are compiled to be interpreter by emterpreter, that way,
|
# NOTE: Simple raylib examples are compiled to be interpreter by emterpreter, that way,
|
||||||
# we can compile same code for ALL platforms with no change required, but, working on bigger
|
# we can compile same code for ALL platforms with no change required, but, working on bigger
|
||||||
@ -407,7 +407,7 @@ EXAMPLES = \
|
|||||||
models/models_box_collisions \
|
models/models_box_collisions \
|
||||||
models/models_billboard \
|
models/models_billboard \
|
||||||
models/models_obj_loading \
|
models/models_obj_loading \
|
||||||
models/models_obj_viewing \
|
models/models_obj_viewer \
|
||||||
models/models_heightmap \
|
models/models_heightmap \
|
||||||
models/models_cubicmap \
|
models/models_cubicmap \
|
||||||
models/models_mesh_picking \
|
models/models_mesh_picking \
|
||||||
@ -420,6 +420,7 @@ EXAMPLES = \
|
|||||||
shaders/shaders_custom_uniform \
|
shaders/shaders_custom_uniform \
|
||||||
shaders/shaders_postprocessing \
|
shaders/shaders_postprocessing \
|
||||||
shaders/shaders_raymarching \
|
shaders/shaders_raymarching \
|
||||||
|
shaders/shaders_palette_switch \
|
||||||
audio/audio_sound_loading \
|
audio/audio_sound_loading \
|
||||||
audio/audio_music_stream \
|
audio/audio_music_stream \
|
||||||
audio/audio_module_playing \
|
audio/audio_module_playing \
|
||||||
|
@ -30,11 +30,11 @@ int main()
|
|||||||
int screenWidth = 800;
|
int screenWidth = 800;
|
||||||
int screenHeight = 450;
|
int screenHeight = 450;
|
||||||
|
|
||||||
SetConfigFlags(FLAG_MSAA_4X_HINT); // NOTE: Try to enable MSAA 4X
|
SetConfigFlags(FLAG_MSAA_4X_HINT); // NOTE: Try to enable MSAA 4X
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - module playing (streaming)");
|
InitWindow(screenWidth, screenHeight, "raylib [audio] example - module playing (streaming)");
|
||||||
|
|
||||||
InitAudioDevice(); // Initialize audio device
|
InitAudioDevice(); // Initialize audio device
|
||||||
|
|
||||||
Color colors[14] = { ORANGE, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK,
|
Color colors[14] = { ORANGE, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK,
|
||||||
YELLOW, GREEN, SKYBLUE, PURPLE, BEIGE };
|
YELLOW, GREEN, SKYBLUE, PURPLE, BEIGE };
|
||||||
@ -52,7 +52,7 @@ int main()
|
|||||||
circles[i].color = colors[GetRandomValue(0, 13)];
|
circles[i].color = colors[GetRandomValue(0, 13)];
|
||||||
}
|
}
|
||||||
|
|
||||||
Music xm = LoadMusicStream("resources/mini1111.xm");
|
Music xm = LoadMusicStream("resources/chiptun1.mod");
|
||||||
|
|
||||||
PlayMusicStream(xm);
|
PlayMusicStream(xm);
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ int main()
|
|||||||
|
|
||||||
// Send to material PBR shader camera view position
|
// Send to material PBR shader camera view position
|
||||||
float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
|
float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
|
||||||
SetShaderValue(model.material.shader, model.material.shader.locs[LOC_VECTOR_VIEW], cameraPos, 3);
|
SetShaderValue(model.material.shader, model.material.shader.locs[LOC_VECTOR_VIEW], cameraPos, UNIFORM_VEC3);
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
@ -148,15 +148,15 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness)
|
|||||||
Shader shdrBRDF = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS);
|
Shader shdrBRDF = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS);
|
||||||
|
|
||||||
// Setup required shader locations
|
// Setup required shader locations
|
||||||
SetShaderValuei(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, 1);
|
SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, UNIFORM_INT);
|
||||||
SetShaderValuei(shdrIrradiance, GetShaderLocation(shdrIrradiance, "environmentMap"), (int[1]){ 0 }, 1);
|
SetShaderValue(shdrIrradiance, GetShaderLocation(shdrIrradiance, "environmentMap"), (int[1]){ 0 }, UNIFORM_INT);
|
||||||
SetShaderValuei(shdrPrefilter, GetShaderLocation(shdrPrefilter, "environmentMap"), (int[1]){ 0 }, 1);
|
SetShaderValue(shdrPrefilter, GetShaderLocation(shdrPrefilter, "environmentMap"), (int[1]){ 0 }, UNIFORM_INT);
|
||||||
|
|
||||||
Texture2D texHDR = LoadTexture("resources/dresden_square.hdr");
|
Texture2D texHDR = LoadTexture("resources/dresden_square.hdr");
|
||||||
Texture2D cubemap = GenTextureCubemap(shdrCubemap, texHDR, CUBEMAP_SIZE);
|
Texture2D cubemap = GenTextureCubemap(shdrCubemap, texHDR, CUBEMAP_SIZE);
|
||||||
mat.maps[MAP_IRRADIANCE].texture = GenTextureIrradiance(shdrIrradiance, cubemap, IRRADIANCE_SIZE);
|
mat.maps[MAP_IRRADIANCE].texture = GenTextureIrradiance(shdrIrradiance, cubemap, IRRADIANCE_SIZE);
|
||||||
mat.maps[MAP_PREFILTER].texture = GenTexturePrefilter(shdrPrefilter, cubemap, PREFILTERED_SIZE);
|
mat.maps[MAP_PREFILTER].texture = GenTexturePrefilter(shdrPrefilter, cubemap, PREFILTERED_SIZE);
|
||||||
mat.maps[MAP_BRDF].texture = GenTextureBRDF(shdrBRDF, cubemap, BRDF_SIZE);
|
mat.maps[MAP_BRDF].texture = GenTextureBRDF(shdrBRDF, BRDF_SIZE);
|
||||||
UnloadTexture(cubemap);
|
UnloadTexture(cubemap);
|
||||||
UnloadTexture(texHDR);
|
UnloadTexture(texHDR);
|
||||||
|
|
||||||
@ -174,14 +174,14 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness)
|
|||||||
SetTextureFilter(mat.maps[MAP_OCCLUSION].texture, FILTER_BILINEAR);
|
SetTextureFilter(mat.maps[MAP_OCCLUSION].texture, FILTER_BILINEAR);
|
||||||
|
|
||||||
// Enable sample usage in shader for assigned textures
|
// Enable sample usage in shader for assigned textures
|
||||||
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "albedo.useSampler"), (int[1]){ 1 }, 1);
|
SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "albedo.useSampler"), (int[1]){ 1 }, UNIFORM_INT);
|
||||||
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "normals.useSampler"), (int[1]){ 1 }, 1);
|
SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "normals.useSampler"), (int[1]){ 1 }, UNIFORM_INT);
|
||||||
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "metalness.useSampler"), (int[1]){ 1 }, 1);
|
SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "metalness.useSampler"), (int[1]){ 1 }, UNIFORM_INT);
|
||||||
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "roughness.useSampler"), (int[1]){ 1 }, 1);
|
SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "roughness.useSampler"), (int[1]){ 1 }, UNIFORM_INT);
|
||||||
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "occlusion.useSampler"), (int[1]){ 1 }, 1);
|
SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "occlusion.useSampler"), (int[1]){ 1 }, UNIFORM_INT);
|
||||||
|
|
||||||
int renderModeLoc = GetShaderLocation(mat.shader, "renderMode");
|
int renderModeLoc = GetShaderLocation(mat.shader, "renderMode");
|
||||||
SetShaderValuei(mat.shader, renderModeLoc, (int[1]){ 0 }, 1);
|
SetShaderValue(mat.shader, renderModeLoc, (int[1]){ 0 }, UNIFORM_INT);
|
||||||
|
|
||||||
// Set up material properties color
|
// Set up material properties color
|
||||||
mat.maps[MAP_ALBEDO].color = albedo;
|
mat.maps[MAP_ALBEDO].color = albedo;
|
||||||
|
@ -21,7 +21,7 @@ int main()
|
|||||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - skybox loading and drawing");
|
InitWindow(screenWidth, screenHeight, "raylib [models] example - skybox loading and drawing");
|
||||||
|
|
||||||
// Define the camera to look into our 3d world
|
// Define the camera to look into our 3d world
|
||||||
Camera camera = {{ 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
|
Camera camera = {{ 1.0f, 1.0f, 1.0f }, { 4.0f, 1.0f, 4.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
|
||||||
|
|
||||||
// Load skybox model
|
// Load skybox model
|
||||||
Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
|
Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
|
||||||
@ -30,11 +30,11 @@ int main()
|
|||||||
// Load skybox shader and set required locations
|
// Load skybox shader and set required locations
|
||||||
// NOTE: Some locations are automatically set at shader loading
|
// NOTE: Some locations are automatically set at shader loading
|
||||||
skybox.material.shader = LoadShader("resources/shaders/skybox.vs", "resources/shaders/skybox.fs");
|
skybox.material.shader = LoadShader("resources/shaders/skybox.vs", "resources/shaders/skybox.fs");
|
||||||
SetShaderValuei(skybox.material.shader, GetShaderLocation(skybox.material.shader, "environmentMap"), (int[1]){ MAP_CUBEMAP }, 1);
|
SetShaderValue(skybox.material.shader, GetShaderLocation(skybox.material.shader, "environmentMap"), (int[1]){ MAP_CUBEMAP }, UNIFORM_INT);
|
||||||
|
|
||||||
// Load cubemap shader and setup required shader locations
|
// Load cubemap shader and setup required shader locations
|
||||||
Shader shdrCubemap = LoadShader("resources/shaders/cubemap.vs", "resources/shaders/cubemap.fs");
|
Shader shdrCubemap = LoadShader("resources/shaders/cubemap.vs", "resources/shaders/cubemap.fs");
|
||||||
SetShaderValuei(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, 1);
|
SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, UNIFORM_INT);
|
||||||
|
|
||||||
// Load HDR panorama (sphere) texture
|
// Load HDR panorama (sphere) texture
|
||||||
Texture2D texHDR = LoadTexture("resources/dresden_square.hdr");
|
Texture2D texHDR = LoadTexture("resources/dresden_square.hdr");
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
*
|
*
|
||||||
* rPBR [shader] - Bidirectional reflectance distribution function fragment shader
|
* BRDF LUT Generation - Bidirectional reflectance distribution function fragment shader
|
||||||
|
*
|
||||||
|
* REF: https://github.com/HectorMF/BRDFGenerator
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017 Victor Fisac
|
* Copyright (c) 2017 Victor Fisac
|
||||||
*
|
*
|
||||||
**********************************************************************************************/
|
**********************************************************************************************/
|
||||||
|
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
#define MAX_SAMPLES 1024u
|
#define MAX_SAMPLES 1024u
|
||||||
|
|
||||||
// Input vertex attributes (from vertex shader)
|
// Input vertex attributes (from vertex shader)
|
||||||
@ -18,43 +21,30 @@ const float PI = 3.14159265359;
|
|||||||
// Output fragment color
|
// Output fragment color
|
||||||
out vec4 finalColor;
|
out vec4 finalColor;
|
||||||
|
|
||||||
float DistributionGGX(vec3 N, vec3 H, float roughness);
|
|
||||||
float RadicalInverse_VdC(uint bits);
|
|
||||||
vec2 Hammersley(uint i, uint N);
|
vec2 Hammersley(uint i, uint N);
|
||||||
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness);
|
float RadicalInverseVdC(uint bits);
|
||||||
float GeometrySchlickGGX(float NdotV, float roughness);
|
float GeometrySchlickGGX(float NdotV, float roughness);
|
||||||
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness);
|
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness);
|
||||||
|
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness);
|
||||||
vec2 IntegrateBRDF(float NdotV, float roughness);
|
vec2 IntegrateBRDF(float NdotV, float roughness);
|
||||||
|
|
||||||
float DistributionGGX(vec3 N, vec3 H, float roughness)
|
float RadicalInverseVdC(uint bits)
|
||||||
{
|
{
|
||||||
float a = roughness*roughness;
|
bits = (bits << 16u) | (bits >> 16u);
|
||||||
float a2 = a*a;
|
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
||||||
float NdotH = max(dot(N, H), 0.0);
|
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
||||||
float NdotH2 = NdotH*NdotH;
|
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
||||||
|
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
||||||
float nom = a2;
|
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
|
||||||
float denom = (NdotH2*(a2 - 1.0) + 1.0);
|
|
||||||
denom = PI*denom*denom;
|
|
||||||
|
|
||||||
return nom/denom;
|
|
||||||
}
|
|
||||||
|
|
||||||
float RadicalInverse_VdC(uint bits)
|
|
||||||
{
|
|
||||||
bits = (bits << 16u) | (bits >> 16u);
|
|
||||||
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
|
||||||
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
|
||||||
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
|
||||||
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
|
||||||
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute Hammersley coordinates
|
||||||
vec2 Hammersley(uint i, uint N)
|
vec2 Hammersley(uint i, uint N)
|
||||||
{
|
{
|
||||||
return vec2(float(i)/float(N), RadicalInverse_VdC(i));
|
return vec2(float(i)/float(N), RadicalInverseVdC(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Integrate number of importance samples for (roughness and NoV)
|
||||||
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
|
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
|
||||||
{
|
{
|
||||||
float a = roughness*roughness;
|
float a = roughness*roughness;
|
||||||
@ -85,6 +75,7 @@ float GeometrySchlickGGX(float NdotV, float roughness)
|
|||||||
return nom/denom;
|
return nom/denom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute the geometry term for the BRDF given roughness squared, NoV, NoL
|
||||||
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
|
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
|
||||||
{
|
{
|
||||||
float NdotV = max(dot(N, V), 0.0);
|
float NdotV = max(dot(N, V), 0.0);
|
||||||
@ -97,29 +88,31 @@ float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
|
|||||||
|
|
||||||
vec2 IntegrateBRDF(float NdotV, float roughness)
|
vec2 IntegrateBRDF(float NdotV, float roughness)
|
||||||
{
|
{
|
||||||
vec3 V = vec3(sqrt(1.0 - NdotV*NdotV), 0.0, NdotV);
|
|
||||||
float A = 0.0;
|
float A = 0.0;
|
||||||
float B = 0.0;
|
float B = 0.0;
|
||||||
|
vec3 V = vec3(sqrt(1.0 - NdotV*NdotV), 0.0, NdotV);
|
||||||
vec3 N = vec3(0.0, 0.0, 1.0);
|
vec3 N = vec3(0.0, 0.0, 1.0);
|
||||||
|
|
||||||
for(uint i = 0u; i < MAX_SAMPLES; i++)
|
for (int i = 0; i < MAX_SAMPLES; i++)
|
||||||
{
|
{
|
||||||
// Generate a sample vector that's biased towards the preferred alignment direction (importance sampling)
|
// Generate a sample vector that's biased towards the preferred alignment direction (importance sampling)
|
||||||
vec2 Xi = Hammersley(i, MAX_SAMPLES);
|
|
||||||
vec3 H = ImportanceSampleGGX(Xi, N, roughness);
|
vec2 Xi = Hammersley(i, MAX_SAMPLES); // Compute a Hammersely coordinate
|
||||||
vec3 L = normalize(2.0*dot(V, H)*H - V);
|
vec3 H = ImportanceSampleGGX(Xi, N, roughness); // Integrate number of importance samples for (roughness and NoV)
|
||||||
float NdotL = max(L.z, 0.0);
|
vec3 L = normalize(2.0*dot(V, H)*H - V); // Compute reflection vector L
|
||||||
float NdotH = max(H.z, 0.0);
|
|
||||||
float VdotH = max(dot(V, H), 0.0);
|
float NdotL = max(L.z, 0.0); // Compute normal dot light
|
||||||
|
float NdotH = max(H.z, 0.0); // Compute normal dot half
|
||||||
|
float VdotH = max(dot(V, H), 0.0); // Compute view dot half
|
||||||
|
|
||||||
if (NdotL > 0.0)
|
if (NdotL > 0.0)
|
||||||
{
|
{
|
||||||
float G = GeometrySmith(N, V, L, roughness);
|
float G = GeometrySmith(N, V, L, roughness); // Compute the geometry term for the BRDF given roughness squared, NoV, NoL
|
||||||
float G_Vis = (G*VdotH)/(NdotH*NdotV);
|
float GVis = (G*VdotH)/(NdotH*NdotV); // Compute the visibility term given G, VoH, NoH, NoV, NoL
|
||||||
float Fc = pow(1.0 - VdotH, 5.0);
|
float Fc = pow(1.0 - VdotH, 5.0); // Compute the fresnel term given VoH
|
||||||
|
|
||||||
A += (1.0 - Fc)*G_Vis;
|
A += (1.0 - Fc)*GVis; // Sum the result given fresnel, geometry, visibility
|
||||||
B += Fc*G_Vis;
|
B += Fc*GVis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
// Input vertex attributes (from vertex shader)
|
// Input vertex attributes (from vertex shader)
|
||||||
in vec3 fragPos;
|
in vec3 fragPosition;
|
||||||
|
|
||||||
// Input uniform values
|
// Input uniform values
|
||||||
uniform sampler2D equirectangularMap;
|
uniform sampler2D equirectangularMap;
|
||||||
@ -28,7 +28,7 @@ vec2 SampleSphericalMap(vec3 v)
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Normalize local position
|
// Normalize local position
|
||||||
vec2 uv = SampleSphericalMap(normalize(fragPos));
|
vec2 uv = SampleSphericalMap(normalize(fragPosition));
|
||||||
|
|
||||||
// Fetch color from texture map
|
// Fetch color from texture map
|
||||||
vec3 color = texture(equirectangularMap, uv).rgb;
|
vec3 color = texture(equirectangularMap, uv).rgb;
|
||||||
|
@ -16,12 +16,12 @@ uniform mat4 projection;
|
|||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
|
|
||||||
// Output vertex attributes (to fragment shader)
|
// Output vertex attributes (to fragment shader)
|
||||||
out vec3 fragPos;
|
out vec3 fragPosition;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Calculate fragment position based on model transformations
|
// Calculate fragment position based on model transformations
|
||||||
fragPos = vertexPosition;
|
fragPosition = vertexPosition;
|
||||||
|
|
||||||
// Calculate final vertex position
|
// Calculate final vertex position
|
||||||
gl_Position = projection*view*vec4(vertexPosition, 1.0);
|
gl_Position = projection*view*vec4(vertexPosition, 1.0);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
// Input vertex attributes (from vertex shader)
|
// Input vertex attributes (from vertex shader)
|
||||||
in vec3 fragPos;
|
in vec3 fragPosition;
|
||||||
|
|
||||||
// Input uniform values
|
// Input uniform values
|
||||||
uniform samplerCube environmentMap;
|
uniform samplerCube environmentMap;
|
||||||
@ -20,7 +20,7 @@ out vec4 finalColor;
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Fetch color from texture map
|
// Fetch color from texture map
|
||||||
vec3 color = texture(environmentMap, fragPos).rgb;
|
vec3 color = texture(environmentMap, fragPosition).rgb;
|
||||||
|
|
||||||
// Apply gamma correction
|
// Apply gamma correction
|
||||||
color = color/(color + vec3(1.0));
|
color = color/(color + vec3(1.0));
|
||||||
|
@ -16,12 +16,12 @@ uniform mat4 projection;
|
|||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
|
|
||||||
// Output vertex attributes (to fragment shader)
|
// Output vertex attributes (to fragment shader)
|
||||||
out vec3 fragPos;
|
out vec3 fragPosition;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Calculate fragment position based on model transformations
|
// Calculate fragment position based on model transformations
|
||||||
fragPos = vertexPosition;
|
fragPosition = vertexPosition;
|
||||||
|
|
||||||
// Remove translation from the view matrix
|
// Remove translation from the view matrix
|
||||||
mat4 rotView = mat4(mat3(view));
|
mat4 rotView = mat4(mat3(view));
|
||||||
|
@ -158,20 +158,20 @@ Light CreateLight(int type, Vector3 pos, Vector3 targ, Color color, Shader shade
|
|||||||
void UpdateLightValues(Shader shader, Light light)
|
void UpdateLightValues(Shader shader, Light light)
|
||||||
{
|
{
|
||||||
// Send to shader light enabled state and type
|
// Send to shader light enabled state and type
|
||||||
SetShaderValuei(shader, light.enabledLoc, (int[1]){ light.enabled }, 1);
|
SetShaderValue(shader, light.enabledLoc, &light.enabled, UNIFORM_INT);
|
||||||
SetShaderValuei(shader, light.typeLoc, (int[1]){ light.type }, 1);
|
SetShaderValue(shader, light.typeLoc, &light.type, UNIFORM_INT);
|
||||||
|
|
||||||
// Send to shader light position values
|
// Send to shader light position values
|
||||||
float position[3] = { light.position.x, light.position.y, light.position.z };
|
float position[3] = { light.position.x, light.position.y, light.position.z };
|
||||||
SetShaderValue(shader, light.posLoc, position, 3);
|
SetShaderValue(shader, light.posLoc, position, UNIFORM_VEC3);
|
||||||
|
|
||||||
// Send to shader light target position values
|
// Send to shader light target position values
|
||||||
float target[3] = { light.target.x, light.target.y, light.target.z };
|
float target[3] = { light.target.x, light.target.y, light.target.z };
|
||||||
SetShaderValue(shader, light.targetLoc, target, 3);
|
SetShaderValue(shader, light.targetLoc, target, UNIFORM_VEC3);
|
||||||
|
|
||||||
// Send to shader light color values
|
// Send to shader light color values
|
||||||
float diff[4] = { (float)light.color.r/(float)255, (float)light.color.g/(float)255, (float)light.color.b/(float)255, (float)light.color.a/(float)255 };
|
float diff[4] = { (float)light.color.r/(float)255, (float)light.color.g/(float)255, (float)light.color.b/(float)255, (float)light.color.a/(float)255 };
|
||||||
SetShaderValue(shader, light.colorLoc, diff, 4);
|
SetShaderValue(shader, light.colorLoc, diff, UNIFORM_VEC4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // RLIGHTS_IMPLEMENTATION
|
#endif // RLIGHTS_IMPLEMENTATION
|
@ -1,19 +1,19 @@
|
|||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
*
|
*
|
||||||
* raylib [audio] example - Using audio module as standalone module
|
* raylib [audio] example - Using raudio module as standalone module
|
||||||
*
|
*
|
||||||
* NOTE: This example does not require any graphic device, it can run directly on console.
|
* NOTE: This example does not require any graphic device, it can run directly on console.
|
||||||
*
|
*
|
||||||
* DEPENDENCIES:
|
* DEPENDENCIES:
|
||||||
* mini_al.h - Audio device management lib (http://kcat.strangesoft.net/openal.html)
|
* mini_al.h - Audio device management lib (http://kcat.strangesoft.net/openal.html)
|
||||||
* stb_vorbis.c - Ogg audio files loading (http://www.nothings.org/stb_vorbis/)
|
* stb_vorbis.h - Ogg audio files loading (http://www.nothings.org/stb_vorbis/)
|
||||||
* jar_xm.h - XM module file loading
|
* jar_xm.h - XM module file loading
|
||||||
* jar_mod.h - MOD audio file loading
|
* jar_mod.h - MOD audio file loading
|
||||||
* dr_flac.h - FLAC audio file loading
|
* dr_flac.h - FLAC audio file loading
|
||||||
*
|
*
|
||||||
* COMPILATION:
|
* COMPILATION:
|
||||||
* gcc -c ..\..\src\external\mini_al.c -Wall -I.
|
* gcc -c ..\..\src\external\mini_al.c -Wall -I.
|
||||||
* gcc -o audio_standalone.exe audio_standalone.c ..\..\src\audio.c ..\..\src\external\stb_vorbis.c mini_al.o /
|
* gcc -o audio_standalone.exe audio_standalone.c ..\..\src\raudio.c mini_al.o /
|
||||||
* -I..\..\src -I..\..\src\external -L. -Wall -std=c99 /
|
* -I..\..\src -I..\..\src\external -L. -Wall -std=c99 /
|
||||||
* -DAUDIO_STANDALONE -DSUPPORT_FILEFORMAT_WAV -DSUPPORT_FILEFORMAT_OGG
|
* -DAUDIO_STANDALONE -DSUPPORT_FILEFORMAT_WAV -DSUPPORT_FILEFORMAT_OGG
|
||||||
*
|
*
|
||||||
@ -22,7 +22,7 @@
|
|||||||
* This example is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
* This example is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
* BSD-like license that allows static linking with closed source software:
|
* BSD-like license that allows static linking with closed source software:
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
|
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
* 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.
|
* will the authors be held liable for any damages arising from the use of this software.
|
||||||
@ -41,7 +41,7 @@
|
|||||||
*
|
*
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
#include "audio.h" // Audio library
|
#include "raudio.h" // raylib audio library
|
||||||
|
|
||||||
#include <stdio.h> // Required for: printf()
|
#include <stdio.h> // Required for: printf()
|
||||||
|
|
@ -350,9 +350,6 @@ static void GetShaderLightsLocations(Shader shader)
|
|||||||
|
|
||||||
// Set shader uniform values for lights
|
// Set shader uniform values for lights
|
||||||
// NOTE: It would be far easier with shader UBOs but are not supported on OpenGL ES 2.0
|
// NOTE: It would be far easier with shader UBOs but are not supported on OpenGL ES 2.0
|
||||||
// TODO: Replace glUniform1i(), glUniform1f(), glUniform3f(), glUniform4f():
|
|
||||||
//SetShaderValue(Shader shader, int uniformLoc, float *value, int size)
|
|
||||||
//SetShaderValuei(Shader shader, int uniformLoc, int *value, int size)
|
|
||||||
static void SetShaderLightsValues(Shader shader)
|
static void SetShaderLightsValues(Shader shader)
|
||||||
{
|
{
|
||||||
int tempInt[8] = { 0 };
|
int tempInt[8] = { 0 };
|
||||||
@ -363,20 +360,20 @@ static void SetShaderLightsValues(Shader shader)
|
|||||||
if (i < lightsCount)
|
if (i < lightsCount)
|
||||||
{
|
{
|
||||||
tempInt[0] = lights[i]->enabled;
|
tempInt[0] = lights[i]->enabled;
|
||||||
SetShaderValuei(shader, lightsLocs[i][0], tempInt, 1); //glUniform1i(lightsLocs[i][0], lights[i]->enabled);
|
SetShaderValue(shader, lightsLocs[i][0], tempInt, UNIFORM_INT); //glUniform1i(lightsLocs[i][0], lights[i]->enabled);
|
||||||
|
|
||||||
tempInt[0] = lights[i]->type;
|
tempInt[0] = lights[i]->type;
|
||||||
SetShaderValuei(shader, lightsLocs[i][1], tempInt, 1); //glUniform1i(lightsLocs[i][1], lights[i]->type);
|
SetShaderValue(shader, lightsLocs[i][1], tempInt, UNIFORM_INT); //glUniform1i(lightsLocs[i][1], lights[i]->type);
|
||||||
|
|
||||||
tempFloat[0] = (float)lights[i]->diffuse.r/255.0f;
|
tempFloat[0] = (float)lights[i]->diffuse.r/255.0f;
|
||||||
tempFloat[1] = (float)lights[i]->diffuse.g/255.0f;
|
tempFloat[1] = (float)lights[i]->diffuse.g/255.0f;
|
||||||
tempFloat[2] = (float)lights[i]->diffuse.b/255.0f;
|
tempFloat[2] = (float)lights[i]->diffuse.b/255.0f;
|
||||||
tempFloat[3] = (float)lights[i]->diffuse.a/255.0f;
|
tempFloat[3] = (float)lights[i]->diffuse.a/255.0f;
|
||||||
SetShaderValue(shader, lightsLocs[i][5], tempFloat, 4);
|
SetShaderValue(shader, lightsLocs[i][5], tempFloat, UNIFORM_VEC4);
|
||||||
//glUniform4f(lightsLocs[i][5], (float)lights[i]->diffuse.r/255, (float)lights[i]->diffuse.g/255, (float)lights[i]->diffuse.b/255, (float)lights[i]->diffuse.a/255);
|
//glUniform4f(lightsLocs[i][5], (float)lights[i]->diffuse.r/255, (float)lights[i]->diffuse.g/255, (float)lights[i]->diffuse.b/255, (float)lights[i]->diffuse.a/255);
|
||||||
|
|
||||||
tempFloat[0] = lights[i]->intensity;
|
tempFloat[0] = lights[i]->intensity;
|
||||||
SetShaderValue(shader, lightsLocs[i][6], tempFloat, 1);
|
SetShaderValue(shader, lightsLocs[i][6], tempFloat, UNIFORM_FLOAT);
|
||||||
|
|
||||||
switch (lights[i]->type)
|
switch (lights[i]->type)
|
||||||
{
|
{
|
||||||
@ -385,10 +382,10 @@ static void SetShaderLightsValues(Shader shader)
|
|||||||
tempFloat[0] = lights[i]->position.x;
|
tempFloat[0] = lights[i]->position.x;
|
||||||
tempFloat[1] = lights[i]->position.y;
|
tempFloat[1] = lights[i]->position.y;
|
||||||
tempFloat[2] = lights[i]->position.z;
|
tempFloat[2] = lights[i]->position.z;
|
||||||
SetShaderValue(shader, lightsLocs[i][2], tempFloat, 3);
|
SetShaderValue(shader, lightsLocs[i][2], tempFloat, UNIFORM_VEC3);
|
||||||
|
|
||||||
tempFloat[0] = lights[i]->radius;
|
tempFloat[0] = lights[i]->radius;
|
||||||
SetShaderValue(shader, lightsLocs[i][4], tempFloat, 1);
|
SetShaderValue(shader, lightsLocs[i][4], tempFloat, UNIFORM_FLOAT);
|
||||||
|
|
||||||
//glUniform3f(lightsLocs[i][2], lights[i]->position.x, lights[i]->position.y, lights[i]->position.z);
|
//glUniform3f(lightsLocs[i][2], lights[i]->position.x, lights[i]->position.y, lights[i]->position.z);
|
||||||
//glUniform1f(lightsLocs[i][4], lights[i]->radius);
|
//glUniform1f(lightsLocs[i][4], lights[i]->radius);
|
||||||
@ -401,7 +398,7 @@ static void SetShaderLightsValues(Shader shader)
|
|||||||
tempFloat[0] = direction.x;
|
tempFloat[0] = direction.x;
|
||||||
tempFloat[1] = direction.y;
|
tempFloat[1] = direction.y;
|
||||||
tempFloat[2] = direction.z;
|
tempFloat[2] = direction.z;
|
||||||
SetShaderValue(shader, lightsLocs[i][3], tempFloat, 3);
|
SetShaderValue(shader, lightsLocs[i][3], tempFloat, UNIFORM_VEC3);
|
||||||
|
|
||||||
//glUniform3f(lightsLocs[i][3], direction.x, direction.y, direction.z);
|
//glUniform3f(lightsLocs[i][3], direction.x, direction.y, direction.z);
|
||||||
} break;
|
} break;
|
||||||
@ -410,7 +407,7 @@ static void SetShaderLightsValues(Shader shader)
|
|||||||
tempFloat[0] = lights[i]->position.x;
|
tempFloat[0] = lights[i]->position.x;
|
||||||
tempFloat[1] = lights[i]->position.y;
|
tempFloat[1] = lights[i]->position.y;
|
||||||
tempFloat[2] = lights[i]->position.z;
|
tempFloat[2] = lights[i]->position.z;
|
||||||
SetShaderValue(shader, lightsLocs[i][2], tempFloat, 3);
|
SetShaderValue(shader, lightsLocs[i][2], tempFloat, UNIFORM_VEC3);
|
||||||
|
|
||||||
//glUniform3f(lightsLocs[i][2], lights[i]->position.x, lights[i]->position.y, lights[i]->position.z);
|
//glUniform3f(lightsLocs[i][2], lights[i]->position.x, lights[i]->position.y, lights[i]->position.z);
|
||||||
|
|
||||||
@ -420,11 +417,11 @@ static void SetShaderLightsValues(Shader shader)
|
|||||||
tempFloat[0] = direction.x;
|
tempFloat[0] = direction.x;
|
||||||
tempFloat[1] = direction.y;
|
tempFloat[1] = direction.y;
|
||||||
tempFloat[2] = direction.z;
|
tempFloat[2] = direction.z;
|
||||||
SetShaderValue(shader, lightsLocs[i][3], tempFloat, 3);
|
SetShaderValue(shader, lightsLocs[i][3], tempFloat, UNIFORM_VEC3);
|
||||||
//glUniform3f(lightsLocs[i][3], direction.x, direction.y, direction.z);
|
//glUniform3f(lightsLocs[i][3], direction.x, direction.y, direction.z);
|
||||||
|
|
||||||
tempFloat[0] = lights[i]->coneAngle;
|
tempFloat[0] = lights[i]->coneAngle;
|
||||||
SetShaderValue(shader, lightsLocs[i][7], tempFloat, 1);
|
SetShaderValue(shader, lightsLocs[i][7], tempFloat, UNIFORM_FLOAT);
|
||||||
//glUniform1f(lightsLocs[i][7], lights[i]->coneAngle);
|
//glUniform1f(lightsLocs[i][7], lights[i]->coneAngle);
|
||||||
} break;
|
} break;
|
||||||
default: break;
|
default: break;
|
||||||
@ -433,7 +430,7 @@ static void SetShaderLightsValues(Shader shader)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
tempInt[0] = 0;
|
tempInt[0] = 0;
|
||||||
SetShaderValuei(shader, lightsLocs[i][0], tempInt, 1); //glUniform1i(lightsLocs[i][0], 0); // Light disabled
|
SetShaderValue(shader, lightsLocs[i][0], tempInt, UNIFORM_INT); //glUniform1i(lightsLocs[i][0], 0); // Light disabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
examples/shaders/resources/shaders/glsl100/palette-switch.fs
Normal file
29
examples/shaders/resources/shaders/glsl100/palette-switch.fs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#version 100
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
const int colors = 8;
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
varying vec4 fragColor;
|
||||||
|
|
||||||
|
// Input uniform values
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform ivec3 palette[colors];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Texel color fetching from texture sampler
|
||||||
|
vec4 texelColor = texture(texture0, fragTexCoord) * fragColor;
|
||||||
|
|
||||||
|
// Convert the (normalized) texel color RED component (GB would work, too)
|
||||||
|
// to the palette index by scaling up from [0, 1] to [0, 255].
|
||||||
|
int index = int(texelColor.r * 255.0);
|
||||||
|
ivec3 color = palette[index];
|
||||||
|
|
||||||
|
// Calculate final fragment color. Note that the palette color components
|
||||||
|
// are defined in the range [0, 255] and need to be normalized to [0, 1]
|
||||||
|
// for OpenGL to work.
|
||||||
|
gl_FragColor = vec4(color / 255.0, texelColor.a);
|
||||||
|
}
|
27
examples/shaders/resources/shaders/glsl120/palette-switch.fs
Normal file
27
examples/shaders/resources/shaders/glsl120/palette-switch.fs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#version 120
|
||||||
|
|
||||||
|
const int colors = 8;
|
||||||
|
|
||||||
|
// Input fragment attributes (from fragment shader)
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
varying vec4 fragColor;
|
||||||
|
|
||||||
|
// Input uniform values
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform ivec3 palette[colors];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Texel color fetching from texture sampler
|
||||||
|
vec4 texelColor = texture(texture0, fragTexCoord) * fragColor;
|
||||||
|
|
||||||
|
// Convert the (normalized) texel color RED component (GB would work, too)
|
||||||
|
// to the palette index by scaling up from [0, 1] to [0, 255].
|
||||||
|
int index = int(texelColor.r * 255.0);
|
||||||
|
ivec3 color = palette[index];
|
||||||
|
|
||||||
|
// Calculate final fragment color. Note that the palette color components
|
||||||
|
// are defined in the range [0, 255] and need to be normalized to [0, 1]
|
||||||
|
// for OpenGL to work.
|
||||||
|
gl_FragColor = vec4(color / 255.0, texelColor.a);
|
||||||
|
}
|
30
examples/shaders/resources/shaders/glsl330/palette-switch.fs
Normal file
30
examples/shaders/resources/shaders/glsl330/palette-switch.fs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
const int colors = 8;
|
||||||
|
|
||||||
|
// Input fragment attributes (from fragment shader)
|
||||||
|
in vec2 fragTexCoord;
|
||||||
|
in vec4 fragColor;
|
||||||
|
|
||||||
|
// Input uniform values
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform ivec3 palette[colors];
|
||||||
|
|
||||||
|
// Output fragment color
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Texel color fetching from texture sampler
|
||||||
|
vec4 texelColor = texture(texture0, fragTexCoord)*fragColor;
|
||||||
|
|
||||||
|
// Convert the (normalized) texel color RED component (GB would work, too)
|
||||||
|
// to the palette index by scaling up from [0, 1] to [0, 255].
|
||||||
|
int index = int(texelColor.r * 255.0);
|
||||||
|
ivec3 color = palette[index];
|
||||||
|
|
||||||
|
// Calculate final fragment color. Note that the palette color components
|
||||||
|
// are defined in the range [0, 255] and need to be normalized to [0, 1]
|
||||||
|
// for OpenGL to work.
|
||||||
|
finalColor = vec4(color / 255.0, texelColor.a);
|
||||||
|
}
|
@ -79,7 +79,7 @@ int main()
|
|||||||
swirlCenter[1] = screenHeight - mousePosition.y;
|
swirlCenter[1] = screenHeight - mousePosition.y;
|
||||||
|
|
||||||
// Send new value to the shader to be used on drawing
|
// Send new value to the shader to be used on drawing
|
||||||
SetShaderValue(shader, swirlCenterLoc, swirlCenter, 2);
|
SetShaderValue(shader, swirlCenterLoc, swirlCenter, UNIFORM_VEC2);
|
||||||
|
|
||||||
UpdateCamera(&camera); // Update camera
|
UpdateCamera(&camera); // Update camera
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
165
examples/shaders/shaders_palette_switch.c
Normal file
165
examples/shaders/shaders_palette_switch.c
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shaders] example - Color palette switch
|
||||||
|
*
|
||||||
|
* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
|
||||||
|
* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
|
||||||
|
*
|
||||||
|
* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example
|
||||||
|
* on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders
|
||||||
|
* raylib comes with shaders ready for both versions, check raylib/shaders install folder
|
||||||
|
*
|
||||||
|
* This example has been created using raylib 2.3 (www.raylib.com)
|
||||||
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
#define GLSL_VERSION 330
|
||||||
|
#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
|
||||||
|
#define GLSL_VERSION 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_PALETTES 3
|
||||||
|
#define COLORS_PER_PALETTE 8
|
||||||
|
#define VALUES_PER_COLOR 3
|
||||||
|
|
||||||
|
static const int palettes[MAX_PALETTES][COLORS_PER_PALETTE*VALUES_PER_COLOR] = {
|
||||||
|
{
|
||||||
|
0, 0, 0,
|
||||||
|
255, 0, 0,
|
||||||
|
0, 255, 0,
|
||||||
|
0, 0, 255,
|
||||||
|
0, 255, 255,
|
||||||
|
255, 0, 255,
|
||||||
|
255, 255, 0,
|
||||||
|
255, 255, 255,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
4, 12, 6,
|
||||||
|
17, 35, 24,
|
||||||
|
30, 58, 41,
|
||||||
|
48, 93, 66,
|
||||||
|
77, 128, 97,
|
||||||
|
137, 162, 87,
|
||||||
|
190, 220, 127,
|
||||||
|
238, 255, 204,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
21, 25, 26,
|
||||||
|
138, 76, 88,
|
||||||
|
217, 98, 117,
|
||||||
|
230, 184, 193,
|
||||||
|
69, 107, 115,
|
||||||
|
75, 151, 166,
|
||||||
|
165, 189, 194,
|
||||||
|
255, 245, 247,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *paletteText[] = {
|
||||||
|
"3-BIT RGB",
|
||||||
|
"AMMO-8 (GameBoy-like)",
|
||||||
|
"RKBV (2-strip film)"
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
int screenWidth = 800;
|
||||||
|
int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - color palette switch");
|
||||||
|
|
||||||
|
// Load shader to be used on some parts drawing
|
||||||
|
// NOTE 1: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version
|
||||||
|
// NOTE 2: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
|
||||||
|
Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/palette-switch.fs", GLSL_VERSION));
|
||||||
|
|
||||||
|
// Get variable (uniform) location on the shader to connect with the program
|
||||||
|
// NOTE: If uniform variable could not be found in the shader, function returns -1
|
||||||
|
int paletteLoc = GetShaderLocation(shader, "palette");
|
||||||
|
|
||||||
|
// Initial index not set, will be automatically bounded below.
|
||||||
|
int currentPalette = -1;
|
||||||
|
|
||||||
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
int paletteIndex = currentPalette;
|
||||||
|
if (IsKeyPressed(KEY_RIGHT)) paletteIndex++;
|
||||||
|
else if (IsKeyPressed(KEY_LEFT)) paletteIndex--;
|
||||||
|
|
||||||
|
if (paletteIndex >= MAX_PALETTES) paletteIndex = 0;
|
||||||
|
else if (paletteIndex < 0) paletteIndex = MAX_PALETTES - 1;
|
||||||
|
|
||||||
|
// Send new value to the shader to be used on drawing.
|
||||||
|
// Note that we are sending RGB triplets w/o the alpha channel *only* if the current
|
||||||
|
// palette index has changed (in order to save performances).
|
||||||
|
if (currentPalette != paletteIndex)
|
||||||
|
{
|
||||||
|
currentPalette = paletteIndex;
|
||||||
|
SetShaderValueV(shader, paletteLoc, palettes[currentPalette], UNIFORM_IVEC3, COLORS_PER_PALETTE);
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
BeginShaderMode(shader);
|
||||||
|
|
||||||
|
// Draw horizontal screen-wide rectangles with increasing "palette index".
|
||||||
|
// The used palette index is encoded in the RGB components of the pixel.
|
||||||
|
int linesPerRectangle = screenHeight / COLORS_PER_PALETTE;
|
||||||
|
int leftover = screenHeight % COLORS_PER_PALETTE;
|
||||||
|
int y = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < COLORS_PER_PALETTE; ++i)
|
||||||
|
{
|
||||||
|
int height = linesPerRectangle;
|
||||||
|
|
||||||
|
if (leftover > 0)
|
||||||
|
{
|
||||||
|
height += 1;
|
||||||
|
leftover -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawRectangle(0, y, screenWidth, height, (Color){ i, i, i, 255 });
|
||||||
|
|
||||||
|
y += height;
|
||||||
|
}
|
||||||
|
|
||||||
|
EndShaderMode();
|
||||||
|
|
||||||
|
DrawText("CURRENT PALETTE:", 10, 15, 20, RAYWHITE);
|
||||||
|
DrawText(paletteText[currentPalette], 240, 15, 20, RED);
|
||||||
|
DrawText("< >", 540, 10, 30, DARKBLUE);
|
||||||
|
|
||||||
|
DrawFPS(700, 15);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadShader(shader); // Unload shader
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -48,7 +48,7 @@ int main()
|
|||||||
int resolutionLoc = GetShaderLocation(shader, "resolution");
|
int resolutionLoc = GetShaderLocation(shader, "resolution");
|
||||||
|
|
||||||
float resolution[2] = { screenWidth, screenHeight };
|
float resolution[2] = { screenWidth, screenHeight };
|
||||||
SetShaderValue(shader, resolutionLoc, resolution, 2);
|
SetShaderValue(shader, resolutionLoc, resolution, UNIFORM_VEC2);
|
||||||
|
|
||||||
float runTime = 0.0f;
|
float runTime = 0.0f;
|
||||||
|
|
||||||
@ -70,11 +70,11 @@ int main()
|
|||||||
runTime += deltaTime;
|
runTime += deltaTime;
|
||||||
|
|
||||||
// Set shader required uniform values
|
// Set shader required uniform values
|
||||||
SetShaderValue(shader, viewEyeLoc, cameraPos, 3);
|
SetShaderValue(shader, viewEyeLoc, cameraPos, UNIFORM_VEC3);
|
||||||
SetShaderValue(shader, viewCenterLoc, cameraTarget, 3);
|
SetShaderValue(shader, viewCenterLoc, cameraTarget, UNIFORM_VEC3);
|
||||||
SetShaderValue(shader, viewUpLoc, cameraUp, 3);
|
SetShaderValue(shader, viewUpLoc, cameraUp, UNIFORM_VEC3);
|
||||||
SetShaderValue(shader, deltaTimeLoc, &deltaTime, 1);
|
SetShaderValue(shader, deltaTimeLoc, &deltaTime, UNIFORM_FLOAT);
|
||||||
SetShaderValue(shader, runTimeLoc, &runTime, 1);
|
SetShaderValue(shader, runTimeLoc, &runTime, UNIFORM_FLOAT);
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* raylib [shapes] example - raylib logo animation
|
* raylib [shapes] example - raylib logo animation
|
||||||
*
|
*
|
||||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
* This example has been created using raylib 2.3 (www.raylib.com)
|
||||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||||
@ -140,7 +140,7 @@ int main()
|
|||||||
|
|
||||||
DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
|
DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
|
||||||
|
|
||||||
DrawText(SubText("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha));
|
DrawText(TextSubtext("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha));
|
||||||
}
|
}
|
||||||
else if (state == 4)
|
else if (state == 4)
|
||||||
{
|
{
|
||||||
|
120
examples/text/text_draw_inside_rectangle.c
Normal file
120
examples/text/text_draw_inside_rectangle.c
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [text] example - Draw text inside a rectangle
|
||||||
|
*
|
||||||
|
* This example has been created using raylib 2.3 (www.raylib.com)
|
||||||
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Vlad Adrian (@demizdor)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
int screenWidth = 800;
|
||||||
|
int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [text] example - draw text inside a rectangle");
|
||||||
|
|
||||||
|
char text[] = "Text cannot escape\tthis container\t...word wrap also works when active so here's\
|
||||||
|
a long text for testing.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod\
|
||||||
|
tempor incididunt ut labore et dolore magna aliqua. Nec ullamcorper sit amet risus nullam eget felis eget.";
|
||||||
|
|
||||||
|
bool resizing = false;
|
||||||
|
bool wordWrap = true;
|
||||||
|
|
||||||
|
Rectangle container = { 25, 25, screenWidth - 50, screenHeight - 250};
|
||||||
|
Rectangle resizer = { container.x + container.width - 17, container.y + container.height - 17, 14, 14 };
|
||||||
|
|
||||||
|
// Minimum width and heigh for the container rectangle
|
||||||
|
const int minWidth = 60;
|
||||||
|
const int minHeight = 60;
|
||||||
|
const int maxWidth = screenWidth - 50;
|
||||||
|
const int maxHeight = screenHeight - 160;
|
||||||
|
|
||||||
|
Vector2 lastMouse = { 0, 0 }; // Stores last mouse coordinates
|
||||||
|
|
||||||
|
Color borderColor = MAROON; // Container border color
|
||||||
|
|
||||||
|
Font font = GetFontDefault(); // Get default system font
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
if (IsKeyPressed(KEY_SPACE)) wordWrap = !wordWrap;
|
||||||
|
|
||||||
|
Vector2 mouse = GetMousePosition();
|
||||||
|
|
||||||
|
// Check if the mouse is inside the container and toggle border color
|
||||||
|
if (CheckCollisionPointRec(mouse, container)) borderColor = Fade(MAROON, 0.4f);
|
||||||
|
else if (!resizing) borderColor = MAROON;
|
||||||
|
|
||||||
|
// Container resizing logic
|
||||||
|
if (resizing)
|
||||||
|
{
|
||||||
|
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) resizing = false;
|
||||||
|
|
||||||
|
int width = container.width + (mouse.x - lastMouse.x);
|
||||||
|
container.width = (width > minWidth)? ((width < maxWidth)? width : maxWidth) : minWidth;
|
||||||
|
|
||||||
|
int height = container.height + (mouse.y - lastMouse.y);
|
||||||
|
container.height = (height > minHeight)? ((height < maxHeight)? height : maxHeight) : minHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Check if we're resizing
|
||||||
|
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && CheckCollisionPointRec(mouse, resizer)) resizing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move resizer rectangle properly
|
||||||
|
resizer.x = container.x + container.width - 17;
|
||||||
|
resizer.y = container.y + container.height - 17;
|
||||||
|
|
||||||
|
lastMouse = mouse; // Update mouse
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
DrawRectangleLinesEx(container, 3, borderColor); // Draw container border
|
||||||
|
|
||||||
|
// Draw text in container (add some padding)
|
||||||
|
DrawTextRec(font, text,
|
||||||
|
(Rectangle){ container.x + 4, container.y + 4, container.width - 4, container.height - 4 },
|
||||||
|
20.0f, 2.0f, wordWrap, GRAY);
|
||||||
|
|
||||||
|
DrawRectangleRec(resizer, borderColor); // Draw the resize box
|
||||||
|
|
||||||
|
// Draw info
|
||||||
|
DrawText("Word Wrap: ", 313, screenHeight-115, 20, BLACK);
|
||||||
|
if (wordWrap) DrawText("ON", 447, screenHeight - 115, 20, RED);
|
||||||
|
else DrawText("OFF", 447, screenHeight - 115, 20, BLACK);
|
||||||
|
DrawText("Press [SPACE] to toggle word wrap", 218, screenHeight - 91, 20, GRAY);
|
||||||
|
|
||||||
|
DrawRectangle(0, screenHeight - 54, screenWidth, 54, GRAY);
|
||||||
|
DrawText("Click hold & drag the to resize the container", 155, screenHeight - 38, 20, RAYWHITE);
|
||||||
|
DrawRectangleRec((Rectangle){ 382, screenHeight - 34, 12, 12 }, MAROON);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
BIN
examples/text/text_draw_inside_rectangle.png
Normal file
BIN
examples/text/text_draw_inside_rectangle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* raylib [text] example - Text Writing Animation
|
* raylib [text] example - Text Writing Animation
|
||||||
*
|
*
|
||||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
* This example has been created using raylib 2.3 (www.raylib.com)
|
||||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016 Ramon Santamaria (@raysan5)
|
* Copyright (c) 2016 Ramon Santamaria (@raysan5)
|
||||||
@ -44,7 +44,7 @@ int main()
|
|||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
DrawText(SubText(message, 0, framesCounter/10), 210, 160, 20, MAROON);
|
DrawText(TextSubtext(message, 0, framesCounter/10), 210, 160, 20, MAROON);
|
||||||
|
|
||||||
DrawText("PRESS [ENTER] to RESTART!", 240, 260, 20, LIGHTGRAY);
|
DrawText("PRESS [ENTER] to RESTART!", 240, 260, 20, LIGHTGRAY);
|
||||||
DrawText("PRESS [SPACE] to SPEED UP!", 239, 300, 20, LIGHTGRAY);
|
DrawText("PRESS [SPACE] to SPEED UP!", 239, 300, 20, LIGHTGRAY);
|
||||||
|
@ -21,7 +21,7 @@ int main()
|
|||||||
InitWindow(screenWidth, screenHeight, "raylib [texture] example - image text drawing");
|
InitWindow(screenWidth, screenHeight, "raylib [texture] example - image text drawing");
|
||||||
|
|
||||||
// TTF Font loading with custom generation parameters
|
// TTF Font loading with custom generation parameters
|
||||||
Font font = LoadFontEx("resources/KAISG.ttf", 64, 95, 0);
|
Font font = LoadFontEx("resources/KAISG.ttf", 64, 0, 0);
|
||||||
|
|
||||||
Image parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM)
|
Image parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM)
|
||||||
|
|
||||||
|
@ -32,8 +32,8 @@ int main()
|
|||||||
UnloadImage(fudesumiRaw); // Unload CPU (RAM) image data
|
UnloadImage(fudesumiRaw); // Unload CPU (RAM) image data
|
||||||
|
|
||||||
// Generate a checked texture by code (1024x1024 pixels)
|
// Generate a checked texture by code (1024x1024 pixels)
|
||||||
int width = 1024;
|
int width = 960;
|
||||||
int height = 1024;
|
int height = 480;
|
||||||
|
|
||||||
// Dynamic memory allocation to store pixels data (Color type)
|
// Dynamic memory allocation to store pixels data (Color type)
|
||||||
Color *pixels = (Color *)malloc(width*height*sizeof(Color));
|
Color *pixels = (Color *)malloc(width*height*sizeof(Color));
|
||||||
@ -42,8 +42,8 @@ int main()
|
|||||||
{
|
{
|
||||||
for (int x = 0; x < width; x++)
|
for (int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
if (((x/32+y/32)/1)%2 == 0) pixels[y*height + x] = ORANGE;
|
if (((x/32+y/32)/1)%2 == 0) pixels[y*width + x] = ORANGE;
|
||||||
else pixels[y*height + x] = GOLD;
|
else pixels[y*width + x] = GOLD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,9 +73,9 @@ int main()
|
|||||||
DrawTexture(checked, screenWidth/2 - checked.width/2, screenHeight/2 - checked.height/2, Fade(WHITE, 0.5f));
|
DrawTexture(checked, screenWidth/2 - checked.width/2, screenHeight/2 - checked.height/2, Fade(WHITE, 0.5f));
|
||||||
DrawTexture(fudesumi, 430, -30, WHITE);
|
DrawTexture(fudesumi, 430, -30, WHITE);
|
||||||
|
|
||||||
DrawText("CHECKED TEXTURE ", 84, 100, 30, BROWN);
|
DrawText("CHECKED TEXTURE ", 84, 85, 30, BROWN);
|
||||||
DrawText("GENERATED by CODE", 72, 164, 30, BROWN);
|
DrawText("GENERATED by CODE", 72, 148, 30, BROWN);
|
||||||
DrawText("and RAW IMAGE LOADING", 46, 226, 30, BROWN);
|
DrawText("and RAW IMAGE LOADING", 46, 210, 30, BROWN);
|
||||||
|
|
||||||
DrawText("(c) Fudesumi sprite by Eiden Marsal", 310, screenHeight - 20, 10, BROWN);
|
DrawText("(c) Fudesumi sprite by Eiden Marsal", 310, screenHeight - 20, 10, BROWN);
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@ int main()
|
|||||||
const int screenHeight = 720;
|
const int screenHeight = 720;
|
||||||
|
|
||||||
// Init window
|
// Init window
|
||||||
ShowLogo();
|
|
||||||
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
|
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
|
||||||
|
|
||||||
// Initialize audio device
|
// Initialize audio device
|
||||||
|
@ -50,7 +50,6 @@ int main(void) {
|
|||||||
const int screenHeight = 720;
|
const int screenHeight = 720;
|
||||||
const char windowTitle[30] = "KOALA SEASONS";
|
const char windowTitle[30] = "KOALA SEASONS";
|
||||||
|
|
||||||
//ShowLogo();
|
|
||||||
//SetConfigFlags(FLAG_FULLSCREEN_MODE);
|
//SetConfigFlags(FLAG_FULLSCREEN_MODE);
|
||||||
|
|
||||||
// Note that windowTitle is ignored on Android
|
// Note that windowTitle is ignored on Android
|
||||||
|
@ -35,13 +35,13 @@
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Global Variables Definition (local to this module)
|
// Global Variables Definition (local to this module)
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
static char *codingWords[MAX_CODING_WORDS] = {
|
static char *codingWords[MAX_CODING_WORDS] = {
|
||||||
"pollo\0",
|
"pollo\0",
|
||||||
"conejo\0",
|
"conejo\0",
|
||||||
"huevo\0",
|
"huevo\0",
|
||||||
"nido\0",
|
"nido\0",
|
||||||
"aire\0",
|
"aire\0",
|
||||||
"armario\0",
|
"armario\0",
|
||||||
"agujero\0",
|
"agujero\0",
|
||||||
"platano\0",
|
"platano\0",
|
||||||
"pastel\0",
|
"pastel\0",
|
||||||
@ -82,21 +82,21 @@ void InitEndingScreen(void)
|
|||||||
{
|
{
|
||||||
framesCounter = 0;
|
framesCounter = 0;
|
||||||
finishScreen = 0;
|
finishScreen = 0;
|
||||||
|
|
||||||
rotation = 0.1f;
|
rotation = 0.1f;
|
||||||
scale = 0.05f;
|
scale = 0.05f;
|
||||||
state = 0;
|
state = 0;
|
||||||
|
|
||||||
texBackground = LoadTexture("resources/textures/ending_background.png");
|
texBackground = LoadTexture("resources/textures/ending_background.png");
|
||||||
texVignette = LoadTexture("resources/textures/message_vignette.png");
|
texVignette = LoadTexture("resources/textures/message_vignette.png");
|
||||||
fxNews = LoadSound("resources/audio/fx_batman.ogg");
|
fxNews = LoadSound("resources/audio/fx_batman.ogg");
|
||||||
|
|
||||||
missions = LoadMissions("resources/missions.txt");
|
missions = LoadMissions("resources/missions.txt");
|
||||||
int wordsCount = missions[currentMission].wordsCount;
|
int wordsCount = missions[currentMission].wordsCount;
|
||||||
|
|
||||||
strcpy(headline, missions[currentMission].msg); // Base headline
|
strcpy(headline, missions[currentMission].msg); // Base headline
|
||||||
int len = strlen(headline);
|
int len = strlen(headline);
|
||||||
|
|
||||||
// Remove @ from headline
|
// Remove @ from headline
|
||||||
// TODO: Also remove additional spaces
|
// TODO: Also remove additional spaces
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
@ -110,7 +110,7 @@ void InitEndingScreen(void)
|
|||||||
{
|
{
|
||||||
// WARNING: It fails if the last sentence word has a '.' after space
|
// WARNING: It fails if the last sentence word has a '.' after space
|
||||||
char *title = StringReplace(headline, messageWords[i].text, codingWords[messageWords[i].id]);
|
char *title = StringReplace(headline, messageWords[i].text, codingWords[messageWords[i].id]);
|
||||||
|
|
||||||
if (title != NULL)
|
if (title != NULL)
|
||||||
{
|
{
|
||||||
strcpy(headline, title); // Base headline updated
|
strcpy(headline, title); // Base headline updated
|
||||||
@ -118,14 +118,14 @@ void InitEndingScreen(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceLog(LOG_WARNING, "Titular: %s", headline);
|
TraceLog(LOG_WARNING, "Titular: %s", headline);
|
||||||
|
|
||||||
// Generate newspaper with title and subtitle
|
// Generate newspaper with title and subtitle
|
||||||
Image imNewspaper = LoadImage("resources/textures/ending_newspaper.png");
|
Image imNewspaper = LoadImage("resources/textures/ending_newspaper.png");
|
||||||
fontNews = LoadFontEx("resources/fonts/Lora-Bold.ttf", 32, 250, 0);
|
fontNews = LoadFontEx("resources/fonts/Lora-Bold.ttf", 32, 0, 250);
|
||||||
ImageDrawTextEx(&imNewspaper, (Vector2){ 50, 220 }, fontNews, headline, fontNews.baseSize, 0, DARKGRAY);
|
ImageDrawTextEx(&imNewspaper, (Vector2){ 50, 220 }, fontNews, headline, fontNews.baseSize, 0, DARKGRAY);
|
||||||
|
|
||||||
texNewspaper = LoadTextureFromImage(imNewspaper);
|
texNewspaper = LoadTextureFromImage(imNewspaper);
|
||||||
//UnloadFont(fontNews);
|
//UnloadFont(fontNews);
|
||||||
UnloadImage(imNewspaper);
|
UnloadImage(imNewspaper);
|
||||||
@ -135,25 +135,25 @@ void InitEndingScreen(void)
|
|||||||
void UpdateEndingScreen(void)
|
void UpdateEndingScreen(void)
|
||||||
{
|
{
|
||||||
framesCounter++;
|
framesCounter++;
|
||||||
|
|
||||||
if (framesCounter == 10) PlaySound(fxNews);
|
if (framesCounter == 10) PlaySound(fxNews);
|
||||||
|
|
||||||
if (state == 0)
|
if (state == 0)
|
||||||
{
|
{
|
||||||
rotation += 18.0f;
|
rotation += 18.0f;
|
||||||
scale += 0.0096f;
|
scale += 0.0096f;
|
||||||
|
|
||||||
if (scale >= 1.0f)
|
if (scale >= 1.0f)
|
||||||
{
|
{
|
||||||
scale = 1.0f;
|
scale = 1.0f;
|
||||||
state = 1;
|
state = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((state == 1) && (IsKeyPressed(KEY_ENTER) || IsButtonPressed()))
|
if ((state == 1) && (IsKeyPressed(KEY_ENTER) || IsButtonPressed()))
|
||||||
{
|
{
|
||||||
currentMission++;
|
currentMission++;
|
||||||
|
|
||||||
if (currentMission >= totalMissions) finishScreen = 2;
|
if (currentMission >= totalMissions) finishScreen = 2;
|
||||||
else finishScreen = 1;
|
else finishScreen = 1;
|
||||||
}
|
}
|
||||||
@ -163,16 +163,16 @@ void UpdateEndingScreen(void)
|
|||||||
void DrawEndingScreen(void)
|
void DrawEndingScreen(void)
|
||||||
{
|
{
|
||||||
DrawTexture(texBackground, 0, 0, WHITE);
|
DrawTexture(texBackground, 0, 0, WHITE);
|
||||||
|
|
||||||
DrawTexturePro(texNewspaper, (Rectangle){ 0, 0, texNewspaper.width, texNewspaper.height },
|
DrawTexturePro(texNewspaper, (Rectangle){ 0, 0, texNewspaper.width, texNewspaper.height },
|
||||||
(Rectangle){ GetScreenWidth()/2, GetScreenHeight()/2, texNewspaper.width*scale, texNewspaper.height*scale },
|
(Rectangle){ GetScreenWidth()/2, GetScreenHeight()/2, texNewspaper.width*scale, texNewspaper.height*scale },
|
||||||
(Vector2){ (float)texNewspaper.width*scale/2, (float)texNewspaper.height*scale/2 }, rotation, WHITE);
|
(Vector2){ (float)texNewspaper.width*scale/2, (float)texNewspaper.height*scale/2 }, rotation, WHITE);
|
||||||
|
|
||||||
DrawTextureEx(texVignette, (Vector2){ 0, 0 }, 0.0f, 2.0f, WHITE);
|
DrawTextureEx(texVignette, (Vector2){ 0, 0 }, 0.0f, 2.0f, WHITE);
|
||||||
|
|
||||||
// Draw debug information
|
// Draw debug information
|
||||||
DrawTextEx(fontNews, headline, (Vector2){ 10, 10 }, fontNews.baseSize, 0, RAYWHITE);
|
DrawTextEx(fontNews, headline, (Vector2){ 10, 10 }, fontNews.baseSize, 0, RAYWHITE);
|
||||||
|
|
||||||
for (int i = 0; i < missions[currentMission].wordsCount; i++)
|
for (int i = 0; i < missions[currentMission].wordsCount; i++)
|
||||||
{
|
{
|
||||||
DrawText(codingWords[messageWords[i].id], 10, 60 + 30*i, 20, (messageWords[i].id == missions[currentMission].sols[i]) ? GREEN : RED);
|
DrawText(codingWords[messageWords[i].id], 10, 60 + 30*i, 20, (messageWords[i].id == missions[currentMission].sols[i]) ? GREEN : RED);
|
||||||
@ -187,9 +187,9 @@ void UnloadEndingScreen(void)
|
|||||||
UnloadTexture(texBackground);
|
UnloadTexture(texBackground);
|
||||||
UnloadTexture(texNewspaper);
|
UnloadTexture(texNewspaper);
|
||||||
UnloadTexture(texVignette);
|
UnloadTexture(texVignette);
|
||||||
|
|
||||||
UnloadSound(fxNews);
|
UnloadSound(fxNews);
|
||||||
free(missions);
|
free(missions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ending Screen should finish?
|
// Ending Screen should finish?
|
||||||
@ -213,16 +213,16 @@ static char *StringReplace(char *orig, char *rep, char *with)
|
|||||||
|
|
||||||
// Sanity checks and initialization
|
// Sanity checks and initialization
|
||||||
if (!orig || !rep) return NULL;
|
if (!orig || !rep) return NULL;
|
||||||
|
|
||||||
len_rep = strlen(rep);
|
len_rep = strlen(rep);
|
||||||
if (len_rep == 0) return NULL; // Empty rep causes infinite loop during count
|
if (len_rep == 0) return NULL; // Empty rep causes infinite loop during count
|
||||||
|
|
||||||
if (!with) with = ""; // Replace with nothing if not provided
|
if (!with) with = ""; // Replace with nothing if not provided
|
||||||
len_with = strlen(with);
|
len_with = strlen(with);
|
||||||
|
|
||||||
// Count the number of replacements needed
|
// Count the number of replacements needed
|
||||||
ins = orig;
|
ins = orig;
|
||||||
for (count = 0; tmp = strstr(ins, rep); ++count)
|
for (count = 0; tmp = strstr(ins, rep); ++count)
|
||||||
{
|
{
|
||||||
ins = tmp + len_rep;
|
ins = tmp + len_rep;
|
||||||
}
|
}
|
||||||
@ -235,7 +235,7 @@ static char *StringReplace(char *orig, char *rep, char *with)
|
|||||||
// tmp points to the end of the result string
|
// tmp points to the end of the result string
|
||||||
// ins points to the next occurrence of rep in orig
|
// ins points to the next occurrence of rep in orig
|
||||||
// orig points to the remainder of orig after "end of rep"
|
// orig points to the remainder of orig after "end of rep"
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
ins = strstr(orig, rep);
|
ins = strstr(orig, rep);
|
||||||
len_front = ins - orig;
|
len_front = ins - orig;
|
||||||
@ -243,8 +243,8 @@ static char *StringReplace(char *orig, char *rep, char *with)
|
|||||||
tmp = strcpy(tmp, with) + len_with;
|
tmp = strcpy(tmp, with) + len_with;
|
||||||
orig += len_front + len_rep; // move to next "end of rep"
|
orig += len_front + len_rep; // move to next "end of rep"
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(tmp, orig);
|
strcpy(tmp, orig);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,9 @@
|
|||||||
#define MAX_LINE_CHAR 30
|
#define MAX_LINE_CHAR 30
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// NOTE: Coding words are generic and the same words
|
// NOTE: Coding words are generic and the same words
|
||||||
// are used for all missions,
|
// are used for all missions,
|
||||||
typedef enum CodingWords {
|
typedef enum CodingWords {
|
||||||
POLLO = 0,
|
POLLO = 0,
|
||||||
CONEJO,
|
CONEJO,
|
||||||
HUEVO,
|
HUEVO,
|
||||||
@ -50,13 +50,13 @@ typedef enum CodingWords {
|
|||||||
} CodingWords;
|
} CodingWords;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *codingWords[MAX_CODING_WORDS] = {
|
static char *codingWords[MAX_CODING_WORDS] = {
|
||||||
"pollo\0",
|
"pollo\0",
|
||||||
"conejo\0",
|
"conejo\0",
|
||||||
"huevo\0",
|
"huevo\0",
|
||||||
"nido\0",
|
"nido\0",
|
||||||
"aire\0",
|
"aire\0",
|
||||||
"armario\0",
|
"armario\0",
|
||||||
"agujero\0",
|
"agujero\0",
|
||||||
"platano\0",
|
"platano\0",
|
||||||
"pastel\0",
|
"pastel\0",
|
||||||
@ -125,19 +125,19 @@ void InitGameplayScreen(void)
|
|||||||
{
|
{
|
||||||
framesCounter = 0;
|
framesCounter = 0;
|
||||||
finishScreen = 0;
|
finishScreen = 0;
|
||||||
|
|
||||||
fontMessage = LoadFontEx("resources/fonts/traveling_typewriter.ttf", 30, 250, 0);
|
fontMessage = LoadFontEx("resources/fonts/traveling_typewriter.ttf", 30, 0, 250);
|
||||||
|
|
||||||
texBackground = LoadTexture("resources/textures/message_background.png");
|
texBackground = LoadTexture("resources/textures/message_background.png");
|
||||||
texVignette = LoadTexture("resources/textures/message_vignette.png");
|
texVignette = LoadTexture("resources/textures/message_vignette.png");
|
||||||
|
|
||||||
fxGrab = LoadSound("resources/audio/fx_grab.ogg");
|
fxGrab = LoadSound("resources/audio/fx_grab.ogg");
|
||||||
fxPlace = LoadSound("resources/audio/fx_place.ogg");
|
fxPlace = LoadSound("resources/audio/fx_place.ogg");
|
||||||
fxLeave = LoadSound("resources/audio/fx_leave.ogg");
|
fxLeave = LoadSound("resources/audio/fx_leave.ogg");
|
||||||
|
|
||||||
musSpy = LoadMusicStream("resources/audio/s_p_y.xm");
|
musSpy = LoadMusicStream("resources/audio/s_p_y.xm");
|
||||||
PlayMusicStream(musSpy);
|
PlayMusicStream(musSpy);
|
||||||
|
|
||||||
#if defined(PLATFORM_WEB)
|
#if defined(PLATFORM_WEB)
|
||||||
#define WORD_ATLAS_FROM_FILE
|
#define WORD_ATLAS_FROM_FILE
|
||||||
#endif
|
#endif
|
||||||
@ -147,20 +147,20 @@ void InitGameplayScreen(void)
|
|||||||
// Generate coding words atlas directly from text
|
// Generate coding words atlas directly from text
|
||||||
Image imWordsBase = LoadImage("resources/textures/words_base.png");
|
Image imWordsBase = LoadImage("resources/textures/words_base.png");
|
||||||
Image imWords = GenImageColor(imWordsBase.width, imWordsBase.height*MAX_CODING_WORDS, WHITE);
|
Image imWords = GenImageColor(imWordsBase.width, imWordsBase.height*MAX_CODING_WORDS, WHITE);
|
||||||
|
|
||||||
for (int i = 0; i < MAX_CODING_WORDS; i++)
|
for (int i = 0; i < MAX_CODING_WORDS; i++)
|
||||||
{
|
{
|
||||||
ImageDraw(&imWords, imWordsBase,
|
ImageDraw(&imWords, imWordsBase,
|
||||||
(Rectangle){ 0, 0, imWordsBase.width, imWordsBase.height },
|
(Rectangle){ 0, 0, imWordsBase.width, imWordsBase.height },
|
||||||
(Rectangle){ 0, imWordsBase.height*i, imWordsBase.width, imWordsBase.height });
|
(Rectangle){ 0, imWordsBase.height*i, imWordsBase.width, imWordsBase.height });
|
||||||
|
|
||||||
ImageDrawTextEx(&imWords,(Vector2){ imWordsBase.width/2 - MeasureTextEx(fontMessage, codingWords[i],
|
ImageDrawTextEx(&imWords,(Vector2){ imWordsBase.width/2 - MeasureTextEx(fontMessage, codingWords[i],
|
||||||
fontMessage.baseSize, 0).x/2, imWordsBase.height*i }, fontMessage, codingWords[i],
|
fontMessage.baseSize, 0).x/2, imWordsBase.height*i }, fontMessage, codingWords[i],
|
||||||
fontMessage.baseSize, 0, BLACK);
|
fontMessage.baseSize, 0, BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
texWordsAtlas = LoadTextureFromImage(imWords);
|
texWordsAtlas = LoadTextureFromImage(imWords);
|
||||||
|
|
||||||
UnloadImage(imWordsBase);
|
UnloadImage(imWordsBase);
|
||||||
UnloadImage(imWords);
|
UnloadImage(imWords);
|
||||||
#endif
|
#endif
|
||||||
@ -183,13 +183,13 @@ void InitGameplayScreen(void)
|
|||||||
words[i].iniRec = words[i].rec;
|
words[i].iniRec = words[i].rec;
|
||||||
words[i].hover = false; // Mouse hover detected
|
words[i].hover = false; // Mouse hover detected
|
||||||
words[i].picked = false; // Mouse picked
|
words[i].picked = false; // Mouse picked
|
||||||
|
|
||||||
//words[i].text = ''; //codingWords[i]; // Fill text if required...
|
//words[i].text = ''; //codingWords[i]; // Fill text if required...
|
||||||
}
|
}
|
||||||
|
|
||||||
// Analize missions[currentMission].msg string for words!
|
// Analize missions[currentMission].msg string for words!
|
||||||
int msgLen = strlen(missions[currentMission].msg);
|
int msgLen = strlen(missions[currentMission].msg);
|
||||||
|
|
||||||
// Add '/' each MAX_LINE_CHAR chars
|
// Add '/' each MAX_LINE_CHAR chars
|
||||||
int currentLine = 1;
|
int currentLine = 1;
|
||||||
int i = currentLine * MAX_LINE_CHAR;
|
int i = currentLine * MAX_LINE_CHAR;
|
||||||
@ -203,39 +203,35 @@ void InitGameplayScreen(void)
|
|||||||
i = currentLine*MAX_LINE_CHAR;
|
i = currentLine*MAX_LINE_CHAR;
|
||||||
}
|
}
|
||||||
else i++;
|
else i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int currentWord = 0;
|
int currentWord = 0;
|
||||||
int offsetX = 0;
|
int offsetX = 0;
|
||||||
int offsetY = 0;
|
int offsetY = 0;
|
||||||
bool foundWord = false;
|
bool foundWord = false;
|
||||||
int wordInitPosX = 0;
|
int wordInitPosX = 0;
|
||||||
int wordInitPosY = 0;
|
int wordInitPosY = 0;
|
||||||
|
|
||||||
// TODO: messageWords should be reseted every mission
|
|
||||||
//memcpy(messageWords, 0, sizeof(Word)*MAX_MISSION_WORDS);
|
|
||||||
|
|
||||||
for (int i = 0; i < msgLen; i++)
|
for (int i = 0; i < msgLen; i++)
|
||||||
{
|
{
|
||||||
char c = missions[currentMission].msg[i];
|
char c = missions[currentMission].msg[i];
|
||||||
if (foundWord && (c == ' ' || c == '.'))
|
if (foundWord && (c == ' ' || c == '.'))
|
||||||
{
|
{
|
||||||
foundWord = false;
|
foundWord = false;
|
||||||
|
|
||||||
messageWords[currentWord - 1].rec.width = (int)MeasureTextEx(fontMessage, SubText(missions[currentMission].msg, wordInitPosX, (i - wordInitPosX)), 30, 0).x;
|
messageWords[currentWord - 1].rec.width = (int)MeasureTextEx(fontMessage, TextSubtext(missions[currentMission].msg, wordInitPosX, (i - wordInitPosX)), 30, 0).x;
|
||||||
messageWords[currentWord - 1].rec.height = fontMessage.baseSize;
|
messageWords[currentWord - 1].rec.height = fontMessage.baseSize;
|
||||||
|
|
||||||
//TODO: Guardar en message
|
strncpy(messageWords[currentWord - 1].text, TextSubtext(missions[currentMission].msg, wordInitPosX, (i - wordInitPosX)), i - wordInitPosX);
|
||||||
strncpy(messageWords[currentWord - 1].text, SubText(missions[currentMission].msg, wordInitPosX, (i - wordInitPosX)), i - wordInitPosX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == '@') // One word to change
|
if (c == '@') // One word to change
|
||||||
{
|
{
|
||||||
foundWord = true;
|
foundWord = true;
|
||||||
missions[currentMission].msg[i] = ' ';
|
missions[currentMission].msg[i] = ' ';
|
||||||
|
|
||||||
offsetX = (int)MeasureTextEx(fontMessage, SubText(missions[currentMission].msg, wordInitPosY, (i + 1) - wordInitPosY), 30, 0).x;
|
offsetX = (int)MeasureTextEx(fontMessage, TextSubtext(missions[currentMission].msg, wordInitPosY, (i + 1) - wordInitPosY), 30, 0).x;
|
||||||
|
|
||||||
messageWords[currentWord].rec.x = offsetX;
|
messageWords[currentWord].rec.x = offsetX;
|
||||||
messageWords[currentWord].rec.y = offsetY;
|
messageWords[currentWord].rec.y = offsetY;
|
||||||
|
|
||||||
@ -254,16 +250,16 @@ void InitGameplayScreen(void)
|
|||||||
for (int i = 0; i < missions[currentMission].wordsCount; i++)
|
for (int i = 0; i < missions[currentMission].wordsCount; i++)
|
||||||
{
|
{
|
||||||
messageWords[i].id = -1; // Not required for message words, id is the array position
|
messageWords[i].id = -1; // Not required for message words, id is the array position
|
||||||
|
|
||||||
// Recalculate words rectangles considering text offset on screen
|
// Recalculate words rectangles considering text offset on screen
|
||||||
messageWords[i].rec.x += msgOffset.x;
|
messageWords[i].rec.x += msgOffset.x;
|
||||||
messageWords[i].rec.y += msgOffset.y;
|
messageWords[i].rec.y += msgOffset.y;
|
||||||
|
|
||||||
// Recalculate words rectangle considering new width height
|
// Recalculate words rectangle considering new width height
|
||||||
messageWords[i].rec.x -= (texWordsAtlas.width - messageWords[i].rec.width)/2;
|
messageWords[i].rec.x -= (texWordsAtlas.width - messageWords[i].rec.width)/2;
|
||||||
messageWords[i].rec.y -= ((texWordsAtlas.height / MAX_CODING_WORDS) - messageWords[i].rec.height)/2;
|
messageWords[i].rec.y -= ((texWordsAtlas.height / MAX_CODING_WORDS) - messageWords[i].rec.height)/2;
|
||||||
|
|
||||||
//Recalculate width height
|
//Recalculate width height
|
||||||
messageWords[i].rec.width = texWordsAtlas.width;
|
messageWords[i].rec.width = texWordsAtlas.width;
|
||||||
messageWords[i].rec.height = texWordsAtlas.height / MAX_CODING_WORDS;
|
messageWords[i].rec.height = texWordsAtlas.height / MAX_CODING_WORDS;
|
||||||
|
|
||||||
@ -276,13 +272,13 @@ void InitGameplayScreen(void)
|
|||||||
void UpdateGameplayScreen(void)
|
void UpdateGameplayScreen(void)
|
||||||
{
|
{
|
||||||
UpdateMusicStream(musSpy);
|
UpdateMusicStream(musSpy);
|
||||||
|
|
||||||
for (int i = 0; i < MAX_CODING_WORDS; i++)
|
for (int i = 0; i < MAX_CODING_WORDS; i++)
|
||||||
{
|
{
|
||||||
if (CheckCollisionPointRec(GetMousePosition(), words[i].rec))
|
if (CheckCollisionPointRec(GetMousePosition(), words[i].rec))
|
||||||
{
|
{
|
||||||
words[i].hover = true;
|
words[i].hover = true;
|
||||||
|
|
||||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||||
{
|
{
|
||||||
words[i].picked = true;
|
words[i].picked = true;
|
||||||
@ -290,41 +286,41 @@ void UpdateGameplayScreen(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else words[i].hover = false;
|
else words[i].hover = false;
|
||||||
|
|
||||||
|
|
||||||
if (words[i].picked)
|
if (words[i].picked)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < missions[currentMission].wordsCount; j++)
|
for (int j = 0; j < missions[currentMission].wordsCount; j++)
|
||||||
{
|
{
|
||||||
if (CheckCollisionPointRec(GetMousePosition(), messageWords[j].rec)) messageWords[j].hover = true;
|
if (CheckCollisionPointRec(GetMousePosition(), messageWords[j].rec)) messageWords[j].hover = true;
|
||||||
else messageWords[j].hover = false;
|
else messageWords[j].hover = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
|
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
|
||||||
{
|
{
|
||||||
words[i].picked = false;
|
words[i].picked = false;
|
||||||
|
|
||||||
for (int j = 0; j < missions[currentMission].wordsCount; j++)
|
for (int j = 0; j < missions[currentMission].wordsCount; j++)
|
||||||
{
|
{
|
||||||
messageWords[j].hover = false;
|
messageWords[j].hover = false;
|
||||||
|
|
||||||
if (CheckCollisionPointRec(GetMousePosition(), messageWords[j].rec))
|
if (CheckCollisionPointRec(GetMousePosition(), messageWords[j].rec))
|
||||||
{
|
{
|
||||||
PlaySound(fxPlace);
|
PlaySound(fxPlace);
|
||||||
|
|
||||||
words[i].rec.x = messageWords[j].rec.x;
|
words[i].rec.x = messageWords[j].rec.x;
|
||||||
words[i].rec.y = messageWords[j].rec.y;
|
words[i].rec.y = messageWords[j].rec.y;
|
||||||
|
|
||||||
if (messageWords[j].id != -1)
|
if (messageWords[j].id != -1)
|
||||||
{
|
{
|
||||||
int id = messageWords[j].id;
|
int id = messageWords[j].id;
|
||||||
words[id].rec = words[id].iniRec;
|
words[id].rec = words[id].iniRec;
|
||||||
}
|
}
|
||||||
|
|
||||||
messageWords[j].id = i;
|
messageWords[j].id = i;
|
||||||
for (int k = 0; k < missions[currentMission].wordsCount; k++)
|
for (int k = 0; k < missions[currentMission].wordsCount; k++)
|
||||||
{
|
{
|
||||||
if (j != k && messageWords[j].id == messageWords[k].id)
|
if (j != k && messageWords[j].id == messageWords[k].id)
|
||||||
{
|
{
|
||||||
messageWords[k].id = -1;
|
messageWords[k].id = -1;
|
||||||
break;
|
break;
|
||||||
@ -332,60 +328,53 @@ void UpdateGameplayScreen(void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PlaySound(fxLeave);
|
PlaySound(fxLeave);
|
||||||
|
|
||||||
words[i].rec = words[i].iniRec;
|
words[i].rec = words[i].iniRec;
|
||||||
if (i == messageWords[j].id) messageWords[j].id = -1;
|
if (i == messageWords[j].id) messageWords[j].id = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move word picked with mouse
|
// Move word picked with mouse
|
||||||
if (words[i].picked)
|
if (words[i].picked)
|
||||||
{
|
{
|
||||||
words[i].rec.x = GetMouseX() - words[i].rec.width/2;
|
words[i].rec.x = GetMouseX() - words[i].rec.width/2;
|
||||||
words[i].rec.y = GetMouseY() - words[i].rec.height/2;
|
words[i].rec.y = GetMouseY() - words[i].rec.height/2;
|
||||||
|
|
||||||
// TODO: Check if label is placed in some mission word position
|
|
||||||
//if (CheckCollisionRecs(words[i].rec))
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//if (words[i].id != -1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
canSend = true;
|
canSend = true;
|
||||||
for(int j = 0; j < missions[currentMission].wordsCount; j++)
|
for (int j = 0; j < missions[currentMission].wordsCount; j++)
|
||||||
{
|
{
|
||||||
if(messageWords[j].id == -1)
|
if (messageWords[j].id == -1)
|
||||||
{
|
{
|
||||||
canSend = false;
|
canSend = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canSend && (IsKeyPressed(KEY_ENTER) || IsButtonPressed()))
|
if (canSend && (IsKeyPressed(KEY_ENTER) || IsButtonPressed()))
|
||||||
{
|
{
|
||||||
finishScreen = true;
|
finishScreen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gameplay Screen Draw logic
|
// Gameplay Screen Draw logic
|
||||||
void DrawGameplayScreen(void)
|
void DrawGameplayScreen(void)
|
||||||
{
|
{
|
||||||
DrawTexture(texBackground, 0, 0, WHITE);
|
DrawTexture(texBackground, 0, 0, WHITE);
|
||||||
|
|
||||||
DrawTextEx(fontMessage, missions[currentMission].msg, msgOffset, fontMessage.baseSize, 0, BLACK);
|
DrawTextEx(fontMessage, missions[currentMission].msg, msgOffset, fontMessage.baseSize, 0, BLACK);
|
||||||
|
|
||||||
for (int i = 0; i < missions[currentMission].wordsCount; i++)
|
for (int i = 0; i < missions[currentMission].wordsCount; i++)
|
||||||
{
|
{
|
||||||
Rectangle recLines = messageWords[i].rec;
|
Rectangle recLines = messageWords[i].rec;
|
||||||
DrawRectangleLines(recLines.x, recLines.y, recLines.width, recLines.height, Fade(RED, 0.35f));
|
DrawRectangleLines(recLines.x, recLines.y, recLines.width, recLines.height, Fade(RED, 0.35f));
|
||||||
if(messageWords[i].hover) DrawRectangleRec(messageWords[i].rec, Fade(RED, 0.30f));
|
if (messageWords[i].hover) DrawRectangleRec(messageWords[i].rec, Fade(RED, 0.30f));
|
||||||
DrawText(FormatText("%i", messageWords[i].id), i*25, 0, 30, RED);
|
DrawText(FormatText("%i", messageWords[i].id), i*25, 0, 30, RED);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < MAX_CODING_WORDS; i++)
|
for (int i = 0; i < MAX_CODING_WORDS; i++)
|
||||||
@ -394,9 +383,9 @@ void DrawGameplayScreen(void)
|
|||||||
else if (words[i].hover) DrawTextureRec(texWordsAtlas, (Rectangle){ 0, i*35, 140, 35 }, (Vector2){ words[i].rec.x, words[i].rec.y }, RED);
|
else if (words[i].hover) DrawTextureRec(texWordsAtlas, (Rectangle){ 0, i*35, 140, 35 }, (Vector2){ words[i].rec.x, words[i].rec.y }, RED);
|
||||||
else DrawTextureRec(texWordsAtlas, (Rectangle){ 0, i*35, 140, 35 }, (Vector2){ words[i].rec.x, words[i].rec.y }, WHITE);
|
else DrawTextureRec(texWordsAtlas, (Rectangle){ 0, i*35, 140, 35 }, (Vector2){ words[i].rec.x, words[i].rec.y }, WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawTexturePro(texVignette, (Rectangle){0,0,texVignette.width, texVignette.height}, (Rectangle){0,0,GetScreenWidth(), GetScreenHeight()}, (Vector2){0,0}, 0, WHITE);
|
DrawTexturePro(texVignette, (Rectangle){0,0,texVignette.width, texVignette.height}, (Rectangle){0,0,GetScreenWidth(), GetScreenHeight()}, (Vector2){0,0}, 0, WHITE);
|
||||||
|
|
||||||
if (canSend) DrawButton("enviar");
|
if (canSend) DrawButton("enviar");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,13 +395,13 @@ void UnloadGameplayScreen(void)
|
|||||||
UnloadTexture(texBackground);
|
UnloadTexture(texBackground);
|
||||||
UnloadTexture(texVignette);
|
UnloadTexture(texVignette);
|
||||||
UnloadTexture(texWordsAtlas);
|
UnloadTexture(texWordsAtlas);
|
||||||
|
|
||||||
UnloadSound(fxGrab);
|
UnloadSound(fxGrab);
|
||||||
UnloadSound(fxLeave);
|
UnloadSound(fxLeave);
|
||||||
UnloadSound(fxPlace);
|
UnloadSound(fxPlace);
|
||||||
|
|
||||||
UnloadMusicStream(musSpy);
|
UnloadMusicStream(musSpy);
|
||||||
|
|
||||||
free(missions);
|
free(missions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,15 +61,15 @@ void InitLogoScreen(void)
|
|||||||
// Logo Screen Update logic
|
// Logo Screen Update logic
|
||||||
void UpdateLogoScreen(void)
|
void UpdateLogoScreen(void)
|
||||||
{
|
{
|
||||||
if(!fadeOut)
|
if (!fadeOut)
|
||||||
{
|
{
|
||||||
fadeValue += 0.02f;
|
fadeValue += 0.02f;
|
||||||
if(fadeValue > 1.01f)
|
if (fadeValue > 1.01f)
|
||||||
{
|
{
|
||||||
fadeValue = 1.0f;
|
fadeValue = 1.0f;
|
||||||
framesCounter++;
|
framesCounter++;
|
||||||
|
|
||||||
if(framesCounter % showLogoFrames == 0)
|
if ((framesCounter%showLogoFrames) == 0)
|
||||||
{
|
{
|
||||||
fadeOut = true;
|
fadeOut = true;
|
||||||
finishScreen = true;
|
finishScreen = true;
|
||||||
@ -77,10 +77,7 @@ void UpdateLogoScreen(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IsKeyPressed(KEY_ENTER))
|
if (IsKeyPressed(KEY_ENTER)) finishScreen = true;
|
||||||
{
|
|
||||||
finishScreen = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logo Screen Draw logic
|
// Logo Screen Draw logic
|
||||||
|
@ -88,34 +88,33 @@ static Music musMission;
|
|||||||
// Mission Screen Functions Definition
|
// Mission Screen Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
static void WriteMissionText();
|
static void WriteMissionText();
|
||||||
static void EndWritting();
|
|
||||||
static void BlinkKeyword();
|
|
||||||
|
|
||||||
// Mission Screen Initialization logic
|
// Mission Screen Initialization logic
|
||||||
void InitMissionScreen(void)
|
void InitMissionScreen(void)
|
||||||
{
|
{
|
||||||
framesCounter = 0;
|
framesCounter = 0;
|
||||||
finishScreen = 0;
|
finishScreen = 0;
|
||||||
|
|
||||||
fadeButton = 0.80f;
|
fadeButton = 0.80f;
|
||||||
|
|
||||||
texBackground = LoadTexture("resources/textures/mission_background.png");
|
texBackground = LoadTexture("resources/textures/mission_background.png");
|
||||||
|
|
||||||
texBackline = LoadTexture("resources/textures/mission_backline.png");
|
texBackline = LoadTexture("resources/textures/mission_backline.png");
|
||||||
sourceRecBackLine = (Rectangle){0,0,GetScreenWidth(), texBackline.height};
|
sourceRecBackLine = (Rectangle){0,0,GetScreenWidth(), texBackline.height};
|
||||||
destRecBackLine = (Rectangle){0,0,sourceRecBackLine.width, sourceRecBackLine.height};
|
destRecBackLine = (Rectangle){0,0,sourceRecBackLine.width, sourceRecBackLine.height};
|
||||||
fadeBackLine = 0;
|
fadeBackLine = 0;
|
||||||
|
|
||||||
fxTransmit = LoadSound("resources/audio/fx_message.ogg");
|
fxTransmit = LoadSound("resources/audio/fx_message.ogg");
|
||||||
musMission = LoadMusicStream("resources/audio/music_mission.ogg");
|
musMission = LoadMusicStream("resources/audio/music_mission.ogg");
|
||||||
|
|
||||||
PlayMusicStream(musMission);
|
PlayMusicStream(musMission);
|
||||||
|
|
||||||
// Initialize missions
|
// Initialize missions
|
||||||
missions = LoadMissions("resources/missions.txt");
|
missions = LoadMissions("resources/missions.txt");
|
||||||
|
|
||||||
missionMaxLength = strlen(missions[currentMission].brief);
|
missionMaxLength = strlen(missions[currentMission].brief);
|
||||||
|
|
||||||
// Insert line breaks every MAX_LINE_CHAR
|
// Insert line breaks every MAX_LINE_CHAR
|
||||||
int currentLine = 1;
|
int currentLine = 1;
|
||||||
int i = currentLine * MAX_LINE_CHAR;
|
int i = currentLine * MAX_LINE_CHAR;
|
||||||
@ -129,35 +128,35 @@ void InitMissionScreen(void)
|
|||||||
i = currentLine*MAX_LINE_CHAR;
|
i = currentLine*MAX_LINE_CHAR;
|
||||||
}
|
}
|
||||||
else i++;
|
else i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
missionSize = 30;
|
missionSize = 30;
|
||||||
missionLenght = 0;
|
missionLenght = 0;
|
||||||
missionSpeed = 1;
|
missionSpeed = 1;
|
||||||
|
|
||||||
numberColor = RAYWHITE;
|
numberColor = RAYWHITE;
|
||||||
missionColor = LIGHTGRAY;
|
missionColor = LIGHTGRAY;
|
||||||
keywordColor = (Color){198, 49, 60, 255}; //RED
|
keywordColor = (Color){198, 49, 60, 255}; //RED
|
||||||
|
|
||||||
numberPosition = (Vector2){150, 185};
|
numberPosition = (Vector2){150, 185};
|
||||||
missionPosition = (Vector2){numberPosition.x, numberPosition.y + 60};
|
missionPosition = (Vector2){numberPosition.x, numberPosition.y + 60};
|
||||||
keywordPosition = (Vector2){missionPosition.x, missionPosition.y + MeasureTextEx(fontMission, missions[currentMission].brief, missionSize, 0).y + 60};
|
keywordPosition = (Vector2){missionPosition.x, missionPosition.y + MeasureTextEx(fontMission, missions[currentMission].brief, missionSize, 0).y + 60};
|
||||||
|
|
||||||
startWritting = false;
|
startWritting = false;
|
||||||
writeNumber = false;
|
writeNumber = false;
|
||||||
writeMission = false;
|
writeMission = false;
|
||||||
writeKeyword = false;
|
writeKeyword = false;
|
||||||
writeEnd = false;
|
writeEnd = false;
|
||||||
|
|
||||||
writtingMission = false;
|
writtingMission = false;
|
||||||
|
|
||||||
showNumberWaitFrames = 30;
|
showNumberWaitFrames = 30;
|
||||||
showMissionWaitFrames = 60;
|
showMissionWaitFrames = 60;
|
||||||
showKeywordWaitFrames = 60;
|
showKeywordWaitFrames = 60;
|
||||||
|
|
||||||
blinkKeyWord = true;
|
blinkKeyWord = true;
|
||||||
blinkFrames = 15;
|
blinkFrames = 15;
|
||||||
|
|
||||||
PlaySound(fxTransmit);
|
PlaySound(fxTransmit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,37 +164,52 @@ void InitMissionScreen(void)
|
|||||||
void UpdateMissionScreen(void)
|
void UpdateMissionScreen(void)
|
||||||
{
|
{
|
||||||
UpdateMusicStream(musMission);
|
UpdateMusicStream(musMission);
|
||||||
|
|
||||||
if (!writeEnd) WriteMissionText();
|
if (!writeEnd) WriteMissionText();
|
||||||
else BlinkKeyword();
|
else
|
||||||
|
{
|
||||||
|
framesCounter++;
|
||||||
|
|
||||||
|
if ((framesCounter%blinkFrames) == 0)
|
||||||
|
{
|
||||||
|
framesCounter = 0;
|
||||||
|
blinkKeyWord = !blinkKeyWord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (showButton)
|
if (showButton)
|
||||||
{
|
{
|
||||||
if (IsKeyPressed(KEY_ENTER) || IsButtonPressed())
|
if (IsKeyPressed(KEY_ENTER) || IsButtonPressed())
|
||||||
{
|
{
|
||||||
if (!writeEnd) EndWritting();
|
if (!writeEnd)
|
||||||
|
{
|
||||||
|
writeEnd = true;
|
||||||
|
writeKeyword = true;
|
||||||
|
writeNumber = true;
|
||||||
|
missionLenght = missionMaxLength;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
finishScreen = true;
|
finishScreen = true;
|
||||||
showButton = false;
|
showButton = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mission Screen Draw logic
|
// Mission Screen Draw logic
|
||||||
void DrawMissionScreen(void)
|
void DrawMissionScreen(void)
|
||||||
{
|
{
|
||||||
// TODO: Draw MISSION screen here!
|
// Draw MISSION screen here!
|
||||||
DrawTexture(texBackground, 0,0, WHITE);
|
DrawTexture(texBackground, 0,0, WHITE);
|
||||||
DrawTexturePro(texBackline, sourceRecBackLine, destRecBackLine, (Vector2){0,0},0, Fade(WHITE, fadeBackLine));
|
DrawTexturePro(texBackline, sourceRecBackLine, destRecBackLine, (Vector2){0,0},0, Fade(WHITE, fadeBackLine));
|
||||||
|
|
||||||
if (writeNumber) DrawTextEx(fontMission, FormatText("Filtración #%02i ", currentMission + 1), numberPosition, missionSize + 10, 0, numberColor);
|
if (writeNumber) DrawTextEx(fontMission, FormatText("Filtración #%02i ", currentMission + 1), numberPosition, missionSize + 10, 0, numberColor);
|
||||||
DrawTextEx(fontMission, SubText(missions[currentMission].brief, 0, missionLenght), missionPosition, missionSize, 0, missionColor);
|
DrawTextEx(fontMission, TextSubtext(missions[currentMission].brief, 0, missionLenght), missionPosition, missionSize, 0, missionColor);
|
||||||
if (writeKeyword && blinkKeyWord) DrawTextEx(fontMission, FormatText("Keyword: %s", missions[currentMission].key), keywordPosition, missionSize + 10, 0, keywordColor);
|
if (writeKeyword && blinkKeyWord) DrawTextEx(fontMission, FormatText("Keyword: %s", missions[currentMission].key), keywordPosition, missionSize + 10, 0, keywordColor);
|
||||||
|
|
||||||
if (showButton)
|
if (showButton)
|
||||||
{
|
{
|
||||||
if (!writeEnd) DrawButton("saltar");
|
if (!writeEnd) DrawButton("saltar");
|
||||||
else DrawButton("codificar");
|
else DrawButton("codificar");
|
||||||
}
|
}
|
||||||
@ -204,8 +218,8 @@ void DrawMissionScreen(void)
|
|||||||
// Mission Screen Unload logic
|
// Mission Screen Unload logic
|
||||||
void UnloadMissionScreen(void)
|
void UnloadMissionScreen(void)
|
||||||
{
|
{
|
||||||
// TODO: Unload MISSION screen variables here!
|
// Unload MISSION screen variables here!
|
||||||
UnloadTexture(texBackground);
|
UnloadTexture(texBackground);
|
||||||
UnloadTexture(texBackline);
|
UnloadTexture(texBackline);
|
||||||
UnloadSound(fxTransmit);
|
UnloadSound(fxTransmit);
|
||||||
UnloadMusicStream(musMission);
|
UnloadMusicStream(musMission);
|
||||||
@ -220,74 +234,58 @@ int FinishMissionScreen(void)
|
|||||||
|
|
||||||
static void WriteMissionText()
|
static void WriteMissionText()
|
||||||
{
|
{
|
||||||
if(!startWritting)
|
if (!startWritting)
|
||||||
{
|
{
|
||||||
framesCounter++;
|
framesCounter++;
|
||||||
if(framesCounter % 60 == 0)
|
if (framesCounter % 60 == 0)
|
||||||
{
|
{
|
||||||
framesCounter = 0;
|
framesCounter = 0;
|
||||||
startWritting = true;
|
startWritting = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!writeNumber)
|
else if (!writeNumber)
|
||||||
{
|
{
|
||||||
framesCounter++;
|
framesCounter++;
|
||||||
fadeBackLine += 0.020f;
|
fadeBackLine += 0.020f;
|
||||||
if(framesCounter % showNumberWaitFrames == 0)
|
if (framesCounter % showNumberWaitFrames == 0)
|
||||||
{
|
{
|
||||||
framesCounter = 0;
|
framesCounter = 0;
|
||||||
writeNumber = true;
|
writeNumber = true;
|
||||||
showButton = true;
|
showButton = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!writeMission)
|
else if (!writeMission)
|
||||||
{
|
{
|
||||||
framesCounter ++;
|
framesCounter ++;
|
||||||
if(framesCounter % showMissionWaitFrames == 0)
|
if (framesCounter % showMissionWaitFrames == 0)
|
||||||
{
|
{
|
||||||
framesCounter = 0;
|
framesCounter = 0;
|
||||||
writeMission = true;
|
writeMission = true;
|
||||||
writtingMission = true;
|
writtingMission = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(writeMission && writtingMission)
|
else if (writeMission && writtingMission)
|
||||||
{
|
{
|
||||||
framesCounter++;
|
framesCounter++;
|
||||||
if(framesCounter % missionSpeed == 0)
|
if (framesCounter % missionSpeed == 0)
|
||||||
{
|
{
|
||||||
framesCounter = 0;
|
framesCounter = 0;
|
||||||
missionLenght++;
|
missionLenght++;
|
||||||
|
|
||||||
if(missionLenght == missionMaxLength)
|
if (missionLenght == missionMaxLength)
|
||||||
{
|
{
|
||||||
writtingMission = false;
|
writtingMission = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!writeKeyword)
|
else if (!writeKeyword)
|
||||||
{
|
{
|
||||||
framesCounter++;
|
framesCounter++;
|
||||||
if(framesCounter % showKeywordWaitFrames == 0)
|
if (framesCounter % showKeywordWaitFrames == 0)
|
||||||
{
|
{
|
||||||
framesCounter = 0;
|
framesCounter = 0;
|
||||||
writeKeyword = true;
|
writeKeyword = true;
|
||||||
writeEnd = true;
|
writeEnd = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
static void EndWritting()
|
|
||||||
{
|
|
||||||
writeEnd = true;
|
|
||||||
writeKeyword = true;
|
|
||||||
writeNumber = true;
|
|
||||||
missionLenght = missionMaxLength;
|
|
||||||
}
|
|
||||||
static void BlinkKeyword()
|
|
||||||
{
|
|
||||||
framesCounter++;
|
|
||||||
if(framesCounter % blinkFrames == 0)
|
|
||||||
{
|
|
||||||
framesCounter = 0;
|
|
||||||
blinkKeyWord = !blinkKeyWord;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,8 +137,8 @@ void UpdateTitleScreen(void)
|
|||||||
void DrawTitleScreen(void)
|
void DrawTitleScreen(void)
|
||||||
{
|
{
|
||||||
DrawTexture(texBackground, 0,0, WHITE);
|
DrawTexture(texBackground, 0,0, WHITE);
|
||||||
DrawTextEx(fontTitle, SubText(textTitle, 0, transmissionLenght), transmissionPosition, titleSize, 0, titleColor);
|
DrawTextEx(fontTitle, TextSubtext(textTitle, 0, transmissionLenght), transmissionPosition, titleSize, 0, titleColor);
|
||||||
DrawTextEx(fontTitle, SubText(textTitle, 12, missionLenght), missionPositon, titleSize, 0, titleColor);
|
DrawTextEx(fontTitle, TextSubtext(textTitle, 12, missionLenght), missionPositon, titleSize, 0, titleColor);
|
||||||
|
|
||||||
DrawButton("start");
|
DrawButton("start");
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ int main(void)
|
|||||||
SetMusicVolume(music, 1.0f);
|
SetMusicVolume(music, 1.0f);
|
||||||
PlayMusicStream(music);
|
PlayMusicStream(music);
|
||||||
|
|
||||||
fontMission = LoadFontEx("resources/fonts/traveling_typewriter.ttf", 64, 250, 0);
|
fontMission = LoadFontEx("resources/fonts/traveling_typewriter.ttf", 64, 0, 250);
|
||||||
texButton = LoadTexture("resources/textures/title_ribbon.png");
|
texButton = LoadTexture("resources/textures/title_ribbon.png");
|
||||||
|
|
||||||
// UI BUTTON
|
// UI BUTTON
|
||||||
|
@ -23,14 +23,14 @@ gcc -O2 -c shapes.c -std=c99 -Wall -DPLATFORM_DESKTOP
|
|||||||
gcc -O2 -c textures.c -std=c99 -Wall -DPLATFORM_DESKTOP
|
gcc -O2 -c textures.c -std=c99 -Wall -DPLATFORM_DESKTOP
|
||||||
gcc -O2 -c text.c -std=c99 -Wall -DPLATFORM_DESKTOP
|
gcc -O2 -c text.c -std=c99 -Wall -DPLATFORM_DESKTOP
|
||||||
gcc -O2 -c models.c -std=c99 -Wall -DPLATFORM_DESKTOP
|
gcc -O2 -c models.c -std=c99 -Wall -DPLATFORM_DESKTOP
|
||||||
gcc -O2 -c audio.c -std=c99 -Wall -DPLATFORM_DESKTOP
|
gcc -O2 -c raudio.c -std=c99 -Wall -DPLATFORM_DESKTOP
|
||||||
gcc -O2 -c external/stb_vorbis.c -Wall -I.
|
|
||||||
gcc -O2 -c external/mini_al.c -Wall -I.
|
gcc -O2 -c external/mini_al.c -Wall -I.
|
||||||
gcc -O2 -c utils.c -std=c99 -Wall -DPLATFORM_DESKTOP
|
gcc -O2 -c utils.c -std=c99 -Wall -DPLATFORM_DESKTOP
|
||||||
|
|
||||||
:: .
|
:: .
|
||||||
:: . > Generate raylib library
|
:: . > Generate raylib library
|
||||||
:: ------------------------------
|
:: ------------------------------
|
||||||
ar rcs libraylib.a core.o rglfw.o shapes.o textures.o text.o models.o audio.o mini_al.o stb_vorbis.o utils.o
|
ar rcs libraylib.a core.o rglfw.o shapes.o textures.o text.o models.o raudio.o mini_al.o utils.o
|
||||||
:: .
|
:: .
|
||||||
:: > Installing raylib library
|
:: > Installing raylib library
|
||||||
:: -----------------------------
|
:: -----------------------------
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -379,6 +379,8 @@ RLAPI Texture2D GetTextureDefault(void); // Get
|
|||||||
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
|
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
|
||||||
RLAPI void SetShaderValue(Shader shader, int uniformLoc, const float *value, int size); // Set shader uniform value (float)
|
RLAPI void SetShaderValue(Shader shader, int uniformLoc, const float *value, int size); // Set shader uniform value (float)
|
||||||
RLAPI void SetShaderValuei(Shader shader, int uniformLoc, const int *value, int size); // Set shader uniform value (int)
|
RLAPI void SetShaderValuei(Shader shader, int uniformLoc, const int *value, int size); // Set shader uniform value (int)
|
||||||
|
RLAPI void SetShaderValueArray(Shader shader, int uniformLoc, const float *value, int size, int count); // Set shader uniform value (array of float/vec2/vec3/vec4)
|
||||||
|
RLAPI void SetShaderValueArrayi(Shader shader, int uniformLoc, const int *value, int size, int count); // Set shader uniform value (array of int/ivec2/ivec3/ivec4)
|
||||||
RLAPI void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
|
RLAPI void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
|
||||||
RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
|
RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
|
||||||
RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
|
RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
|
||||||
|
@ -153,7 +153,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\..\src\audio.c" />
|
<ClCompile Include="..\..\..\src\audio.c" />
|
||||||
<ClCompile Include="..\..\..\src\core.c" />
|
<ClCompile Include="..\..\..\src\core.c" />
|
||||||
<ClCompile Include="..\..\..\src\external\stb_vorbis.c" />
|
|
||||||
<ClCompile Include="..\..\..\src\models.c" />
|
<ClCompile Include="..\..\..\src\models.c" />
|
||||||
<ClCompile Include="..\..\..\src\shapes.c" />
|
<ClCompile Include="..\..\..\src\shapes.c" />
|
||||||
<ClCompile Include="..\..\..\src\text.c" />
|
<ClCompile Include="..\..\..\src\text.c" />
|
||||||
|
@ -235,7 +235,6 @@
|
|||||||
<ClCompile Include="..\..\..\src\audio.c" />
|
<ClCompile Include="..\..\..\src\audio.c" />
|
||||||
<ClCompile Include="..\..\..\src\core.c" />
|
<ClCompile Include="..\..\..\src\core.c" />
|
||||||
<ClCompile Include="..\..\..\src\external\mini_al.c" />
|
<ClCompile Include="..\..\..\src\external\mini_al.c" />
|
||||||
<ClCompile Include="..\..\..\src\external\stb_vorbis.c" />
|
|
||||||
<ClCompile Include="..\..\..\src\models.c" />
|
<ClCompile Include="..\..\..\src\models.c" />
|
||||||
<ClCompile Include="..\..\..\src\rglfw.c" />
|
<ClCompile Include="..\..\..\src\rglfw.c" />
|
||||||
<ClCompile Include="..\..\..\src\shapes.c" />
|
<ClCompile Include="..\..\..\src\shapes.c" />
|
||||||
|
@ -162,7 +162,6 @@
|
|||||||
<ClCompile Include="..\..\..\src\audio.c" />
|
<ClCompile Include="..\..\..\src\audio.c" />
|
||||||
<ClCompile Include="..\..\..\src\core.c" />
|
<ClCompile Include="..\..\..\src\core.c" />
|
||||||
<ClCompile Include="..\..\..\src\external\mini_al.c" />
|
<ClCompile Include="..\..\..\src\external\mini_al.c" />
|
||||||
<ClCompile Include="..\..\..\src\external\stb_vorbis.c" />
|
|
||||||
<ClCompile Include="..\..\..\src\models.c" />
|
<ClCompile Include="..\..\..\src\models.c" />
|
||||||
<ClCompile Include="..\..\..\src\rglfw.c" />
|
<ClCompile Include="..\..\..\src\rglfw.c" />
|
||||||
<ClCompile Include="..\..\..\src\shapes.c" />
|
<ClCompile Include="..\..\..\src\shapes.c" />
|
||||||
|
4
projects/VSCode/.vscode/tasks.json
vendored
4
projects/VSCode/.vscode/tasks.json
vendored
@ -19,7 +19,7 @@
|
|||||||
},
|
},
|
||||||
"osx": {
|
"osx": {
|
||||||
"args": [
|
"args": [
|
||||||
"RAYLIB_PATH=/Users/murray/work/ray/raylib"
|
"RAYLIB_PATH=<path_to_raylib>/raylib"
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"group": {
|
"group": {
|
||||||
@ -42,7 +42,7 @@
|
|||||||
},
|
},
|
||||||
"osx": {
|
"osx": {
|
||||||
"args": [
|
"args": [
|
||||||
"RAYLIB_PATH=/Users/murray/work/ray/raylib",
|
"RAYLIB_PATH=<path_to_raylib>/raylib",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"group": "build"
|
"group": "build"
|
||||||
|
68
projects/scripts/README.md
Normal file
68
projects/scripts/README.md
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
Here are dependency-less build scripts for raylib projects.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
The scripts, as mentioned above, do not have dependencies. There's one
|
||||||
|
exception to this however, and that is Windows, because Windows
|
||||||
|
doesn't have a built-in C compiler. On Windows, you'll need to install
|
||||||
|
[Visual Studio][visual-studio] or the [build tools][vs-tools]. If you
|
||||||
|
didn't install them in the default location, write your changes around
|
||||||
|
line 101 of [`windows-build.bat`](windows-build.bat).
|
||||||
|
|
||||||
|
## Script customization
|
||||||
|
First of all, the scripts have a few variables at the very top, which
|
||||||
|
are supposed to be configured for each project separately:
|
||||||
|
- `GAME_NAME` variable is used for the executable name.
|
||||||
|
- `SOURCES` is a list of .c source files, divided by spaces, which are
|
||||||
|
going to be compiled and linked with raylib to create the final
|
||||||
|
executable. You can use wildcards, so if you have all your .c files
|
||||||
|
in a directory called `src`, you can just set `SOURCES` to
|
||||||
|
`../../src/*.c`. Note: the paths should be either absolute, or
|
||||||
|
relative to `builds/platform`, hence `../../`.
|
||||||
|
- `RAYLIB_SRC` should point to the raylib/src directory. In this case,
|
||||||
|
it's `../../src`, but as with the `SOURCES`, if the path is
|
||||||
|
relative, it should be relative to `temp/debug`, so it's actually
|
||||||
|
`../../../../src`.
|
||||||
|
|
||||||
|
## Compilation flags
|
||||||
|
- `-Os` (`/O1` with MSVC, `-O2` with clang\*) is used for release
|
||||||
|
builds, to save space. Since it's a good practice to make your games
|
||||||
|
run on the slowest possible systems, only a few games would benefit
|
||||||
|
from additional runtime performance on almost all systems. Other
|
||||||
|
flags: `-flto` (`/GL` and `/LTCG` for MSVC) in release builds, `-O0
|
||||||
|
-g` (`/Od /Zi` for MSVC) in debug builds.
|
||||||
|
- `-Wall -Wextra -Wpedantic` (`/Wall` for MSVC) are used for warnings.
|
||||||
|
|
||||||
|
\* Clang 7.0.1 seems to have problems compiling with `-flto` and `-Os`
|
||||||
|
enabled at the same time, so `-Os` is replaced with `-O2` for clang.
|
||||||
|
|
||||||
|
## Command line arguments
|
||||||
|
The build scripts accept some flags, which can be given either one at
|
||||||
|
a time (`-d -c -r`) or in bunches (`-dcr`). Here's a description of
|
||||||
|
all of the flags.
|
||||||
|
- `-h` Describes all the flags, and a few example commands
|
||||||
|
- `-d` Faster builds that have debug symbols, and enable warnings
|
||||||
|
- `-u` Run upx\* on the executable after compilation (before -r)
|
||||||
|
- `-r` Run the executable after compilation
|
||||||
|
- `-c` Remove the temp/(debug|release) directory, ie. full recompile
|
||||||
|
- `-q` Suppress this script's informational prints
|
||||||
|
- `-qq` Suppress all prints, complete silence
|
||||||
|
- `-v` cl.exe normally prints out a lot of superficial information, as
|
||||||
|
well as the MSVC build environment activation scripts, but these are
|
||||||
|
mostly suppressed by default. If you do want to see everything, use
|
||||||
|
this flag.
|
||||||
|
|
||||||
|
\* This is mostly here to make building simple "shipping" versions
|
||||||
|
easier, and it's a very small bit in the build scripts. The option
|
||||||
|
requires that you have upx installed and on your path, of course.
|
||||||
|
|
||||||
|
#### Examples
|
||||||
|
| What the command does | Command |
|
||||||
|
|-------------------------------------------------------------|---------------------------|
|
||||||
|
| Build a release build, on Windows | `windows-build.bat` |
|
||||||
|
| Build a release build, full recompile, on Linux | `./linux-build.sh -c` |
|
||||||
|
| Build a debug build and run, on macOS | `./osx-build.sh -d -r` |
|
||||||
|
| Build in debug, run, don't print at all, on Linux with `sh` | `sh linux-build.sh -drqq` |
|
||||||
|
|
||||||
|
|
||||||
|
[visual-studio]: https://visualstudio.microsoft.com/downloads/#visual-studio-community-2017
|
||||||
|
[vs-tools]: https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2017
|
62
projects/scripts/core_basic_window.c
Normal file
62
projects/scripts/core_basic_window.c
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - Basic window
|
||||||
|
*
|
||||||
|
* Welcome to raylib!
|
||||||
|
*
|
||||||
|
* To test examples, just press F6 and execute raylib_compile_execute script
|
||||||
|
* Note that compiled executable is placed in the same folder as .c file
|
||||||
|
*
|
||||||
|
* You can find all basic examples on C:\raylib\raylib\examples folder or
|
||||||
|
* raylib official webpage: www.raylib.com
|
||||||
|
*
|
||||||
|
* Enjoy using raylib. :)
|
||||||
|
*
|
||||||
|
* This example has been created using raylib 1.0 (www.raylib.com)
|
||||||
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2016 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
int screenWidth = 800;
|
||||||
|
int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window");
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// TODO: Update your variables here
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
158
projects/scripts/linux-build.sh
Executable file
158
projects/scripts/linux-build.sh
Executable file
@ -0,0 +1,158 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Change your executable name here
|
||||||
|
GAME_NAME="game"
|
||||||
|
|
||||||
|
# Set your sources here (relative to the ./builds/linux directory)
|
||||||
|
# Example with two source folders:
|
||||||
|
# SOURCES="../../src/*.c ../../src/submodule/*.c"
|
||||||
|
SOURCES="../../core_basic_window.c"
|
||||||
|
|
||||||
|
# Set your raylib/src location here, relative to the ./temp/x directory
|
||||||
|
RAYLIB_SRC="../../../../src"
|
||||||
|
|
||||||
|
# About this build script: it does many things, but in essence, it's
|
||||||
|
# very simple. It has 3 compiler invocations: building raylib (which
|
||||||
|
# is not done always, see logic by searching "Build raylib"), building
|
||||||
|
# src/*.c files, and linking together those two. Each invocation is
|
||||||
|
# wrapped in an if statement to make the -qq flag work, it's pretty
|
||||||
|
# verbose, sorry.
|
||||||
|
|
||||||
|
# Get arguments
|
||||||
|
while getopts ":hdurcq" opt; do
|
||||||
|
case $opt in
|
||||||
|
h)
|
||||||
|
echo "Usage: ./linux-build.sh [-hdurcqq]"
|
||||||
|
echo " -h Show this information"
|
||||||
|
echo " -d Faster builds that have debug symbols, and enable warnings"
|
||||||
|
echo " -u Run upx* on the executable after compilation (before -r)"
|
||||||
|
echo " -r Run the executable after compilation"
|
||||||
|
echo " -c Remove the temp/(debug|release) directory, ie. full recompile"
|
||||||
|
echo " -q Suppress this script's informational prints"
|
||||||
|
echo " -qq Suppress all prints, complete silence (> /dev/null 2>&1)"
|
||||||
|
echo ""
|
||||||
|
echo "* This is mostly here to make building simple \"shipping\" versions"
|
||||||
|
echo " easier, and it's a very small bit in the build scripts. The option"
|
||||||
|
echo " requires that you have upx installed and on your path, of course."
|
||||||
|
echo ""
|
||||||
|
echo "Examples:"
|
||||||
|
echo " Build a release build: ./linux-build.sh"
|
||||||
|
echo " Build a release build, full recompile: ./linux-build.sh -c"
|
||||||
|
echo " Build a debug build and run: ./linux-build.sh -d -r"
|
||||||
|
echo " Build in debug, run, don't print at all: ./linux-build.sh -drqq"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
d)
|
||||||
|
BUILD_DEBUG="1"
|
||||||
|
;;
|
||||||
|
u)
|
||||||
|
UPX_IT="1"
|
||||||
|
;;
|
||||||
|
r)
|
||||||
|
RUN_AFTER_BUILD="1"
|
||||||
|
;;
|
||||||
|
c)
|
||||||
|
BUILD_ALL="1"
|
||||||
|
;;
|
||||||
|
q)
|
||||||
|
if [ -n "$QUIET" ]; then
|
||||||
|
REALLY_QUIET="1"
|
||||||
|
else
|
||||||
|
QUIET="1"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
\?)
|
||||||
|
echo "Invalid option: -$OPTARG" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Set CC if it's not set already
|
||||||
|
if [ -z "$CC" ]; then
|
||||||
|
CC=cc
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Flags
|
||||||
|
OUTPUT_DIR="builds/linux"
|
||||||
|
COMPILATION_FLAGS="-std=c99 -Os -flto"
|
||||||
|
if [ "$CC" = "clang" ]; then
|
||||||
|
# Clang 7.0.1 fails to compile with -Os, possibly the same bug as this:
|
||||||
|
# https://www.mail-archive.com/llvm-bugs@lists.llvm.org/msg25771.html
|
||||||
|
COMPILATION_FLAGS="-std=c99 -O2 -flto"
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-WARNING: \$CC is clang, using -O2 instead of -Os."
|
||||||
|
fi
|
||||||
|
FINAL_COMPILE_FLAGS="-s"
|
||||||
|
WARNING_FLAGS="-Wall -Wextra -Wpedantic"
|
||||||
|
LINK_FLAGS="-lm -ldl -lpthread -lX11 -lxcb -lGL -lGLX -lXext -lGLdispatch -lXau -lXdmcp"
|
||||||
|
# Debug changes to flags
|
||||||
|
if [ -n "$BUILD_DEBUG" ]; then
|
||||||
|
OUTPUT_DIR="builds-debug/linux"
|
||||||
|
COMPILATION_FLAGS="-std=c99 -O0 -g"
|
||||||
|
FINAL_COMPILE_FLAGS=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Display what we're doing
|
||||||
|
if [ -n "$BUILD_DEBUG" ]; then
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Compiling in debug mode. ($COMPILATION_FLAGS $WARNING_FLAGS)"
|
||||||
|
else
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Compiling in release mode. ($COMPILATION_FLAGS $FINAL_COMPILE_FLAGS)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the raylib cache directory
|
||||||
|
ROOT_DIR=$(pwd)
|
||||||
|
TEMP_DIR="temp/release"
|
||||||
|
if [ -n "$BUILD_DEBUG" ]; then
|
||||||
|
TEMP_DIR="temp/debug"
|
||||||
|
fi
|
||||||
|
# If there's a -c flag, remove the cache
|
||||||
|
if [ -d "$TEMP_DIR" ] && [ -n "$BUILD_ALL" ]; then
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Found cached raylib, rebuilding."
|
||||||
|
rm -r "$TEMP_DIR"
|
||||||
|
fi
|
||||||
|
# If temp directory doesn't exist, build raylib
|
||||||
|
if [ ! -d "$TEMP_DIR" ]; then
|
||||||
|
mkdir -p $TEMP_DIR
|
||||||
|
cd $TEMP_DIR
|
||||||
|
RAYLIB_DEFINES="-D_DEFAULT_SOURCE -DPLATFORM_DESKTOP -DGRAPHICS_API_OPENGL_33"
|
||||||
|
RAYLIB_C_FILES="$RAYLIB_SRC/core.c $RAYLIB_SRC/shapes.c $RAYLIB_SRC/textures.c $RAYLIB_SRC/text.c $RAYLIB_SRC/models.c $RAYLIB_SRC/utils.c $RAYLIB_SRC/raudio.c $RAYLIB_SRC/rglfw.c $RAYLIB_SRC/external/mini_al.c"
|
||||||
|
RAYLIB_INCLUDE_FLAGS="-I$RAYLIB_SRC -I$RAYLIB_SRC/external/glfw/include"
|
||||||
|
|
||||||
|
if [ -n "$REALLY_QUIET" ]; then
|
||||||
|
$CC -c $RAYLIB_DEFINES $RAYLIB_INCLUDE_FLAGS $COMPILATION_FLAGS $RAYLIB_C_FILES > /dev/null 2>&1
|
||||||
|
else
|
||||||
|
$CC -c $RAYLIB_DEFINES $RAYLIB_INCLUDE_FLAGS $COMPILATION_FLAGS $RAYLIB_C_FILES
|
||||||
|
fi
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Raylib compiled into object files in: $TEMP_DIR/"
|
||||||
|
cd $ROOT_DIR
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build the actual game
|
||||||
|
mkdir -p $OUTPUT_DIR
|
||||||
|
cd $OUTPUT_DIR
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Compiling game code."
|
||||||
|
if [ -n "$REALLY_QUIET" ]; then
|
||||||
|
$CC -c -o main.o -I$RAYLIB_SRC $COMPILATION_FLAGS $WARNING_FLAGS $SOURCES > /dev/null 2>&1
|
||||||
|
$CC -o $GAME_NAME $ROOT_DIR/$TEMP_DIR/*.o main.o $LINK_FLAGS > /dev/null 2>&1
|
||||||
|
else
|
||||||
|
$CC -c -o main.o -I$RAYLIB_SRC $COMPILATION_FLAGS $WARNING_FLAGS $SOURCES
|
||||||
|
$CC -o $GAME_NAME $ROOT_DIR/$TEMP_DIR/*.o main.o $LINK_FLAGS
|
||||||
|
fi
|
||||||
|
rm main.o
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Game compiled into an executable in: $OUTPUT_DIR/"
|
||||||
|
|
||||||
|
if [ -n "$UPX_IT" ]; then
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Packing $GAME_NAME with upx."
|
||||||
|
upx $GAME_NAME > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$RUN_AFTER_BUILD" ]; then
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Running."
|
||||||
|
if [ -n "$REALLY_QUIET" ]; then
|
||||||
|
./$GAME_NAME > /dev/null 2>&1
|
||||||
|
else
|
||||||
|
./$GAME_NAME
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
cd $ROOT_DIR
|
||||||
|
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: All done."
|
154
projects/scripts/osx-build.sh
Executable file
154
projects/scripts/osx-build.sh
Executable file
@ -0,0 +1,154 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Change your executable name here
|
||||||
|
GAME_NAME="game"
|
||||||
|
|
||||||
|
# Set your sources here (relative to the ./builds/osx directory)
|
||||||
|
# Example with two source folders:
|
||||||
|
# SOURCES="../../src/*.c ../../src/submodule/*.c"
|
||||||
|
SOURCES="../../core_basic_window.c"
|
||||||
|
|
||||||
|
# Set your raylib/src location here, relative to the ./temp/x directory
|
||||||
|
RAYLIB_SRC="../../../../src"
|
||||||
|
|
||||||
|
# About this build script: it does many things, but in essence, it's
|
||||||
|
# very simple. It has 3 compiler invocations: building raylib (which
|
||||||
|
# is not done always, see logic by searching "Build raylib"), building
|
||||||
|
# src/*.c files, and linking together those two. Each invocation is
|
||||||
|
# wrapped in an if statement to make the -qq flag work, it's pretty
|
||||||
|
# verbose, sorry.
|
||||||
|
|
||||||
|
# Get arguments
|
||||||
|
while getopts ":hdurcq" opt; do
|
||||||
|
case $opt in
|
||||||
|
h)
|
||||||
|
echo "Usage: ./osx-build.sh [-hdurcqq]"
|
||||||
|
echo " -h Show this information"
|
||||||
|
echo " -d Faster builds that have debug symbols, and enable warnings"
|
||||||
|
echo " -u Run upx* on the executable after compilation (before -r)"
|
||||||
|
echo " -r Run the executable after compilation"
|
||||||
|
echo " -c Remove the temp/(debug|release) directory, ie. full recompile"
|
||||||
|
echo " -q Suppress this script's informational prints"
|
||||||
|
echo " -qq Suppress all prints, complete silence (> /dev/null 2>&1)"
|
||||||
|
echo ""
|
||||||
|
echo "* This is mostly here to make building simple \"shipping\" versions"
|
||||||
|
echo " easier, and it's a very small bit in the build scripts. The option"
|
||||||
|
echo " requires that you have upx installed and on your path, of course."
|
||||||
|
echo ""
|
||||||
|
echo "Examples:"
|
||||||
|
echo " Build a release build: ./osx-build.sh"
|
||||||
|
echo " Build a release build, full recompile: ./osx-build.sh -c"
|
||||||
|
echo " Build a debug build and run: ./osx-build.sh -d -r"
|
||||||
|
echo " Build in debug, run, don't print at all: ./osx-build.sh -drqq"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
d)
|
||||||
|
BUILD_DEBUG="1"
|
||||||
|
;;
|
||||||
|
u)
|
||||||
|
UPX_IT="1"
|
||||||
|
;;
|
||||||
|
r)
|
||||||
|
RUN_AFTER_BUILD="1"
|
||||||
|
;;
|
||||||
|
c)
|
||||||
|
BUILD_ALL="1"
|
||||||
|
;;
|
||||||
|
q)
|
||||||
|
if [ -n "$QUIET" ]; then
|
||||||
|
REALLY_QUIET="1"
|
||||||
|
else
|
||||||
|
QUIET="1"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
\?)
|
||||||
|
echo "Invalid option: -$OPTARG" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Set CC if it's not set already
|
||||||
|
if [ -z "$CC" ]; then
|
||||||
|
CC=cc
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Flags
|
||||||
|
OUTPUT_DIR="builds/osx"
|
||||||
|
COMPILATION_FLAGS="-std=c99 -O2 -flto"
|
||||||
|
FINAL_COMPILE_FLAGS="-s"
|
||||||
|
WARNING_FLAGS="-Wall -Wextra -Wpedantic"
|
||||||
|
LINK_FLAGS="-framework OpenGL -framework OpenAL -framework IOKit -framework CoreVideo -framework Cocoa"
|
||||||
|
# Debug changes to flags
|
||||||
|
if [ -n "$BUILD_DEBUG" ]; then
|
||||||
|
OUTPUT_DIR="builds-debug/osx"
|
||||||
|
COMPILATION_FLAGS="-std=c99 -O0 -g"
|
||||||
|
FINAL_COMPILE_FLAGS=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Display what we're doing
|
||||||
|
if [ -n "$BUILD_DEBUG" ]; then
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Compiling in debug mode. ($COMPILATION_FLAGS $WARNING_FLAGS)"
|
||||||
|
else
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Compiling in release mode. ($COMPILATION_FLAGS $FINAL_COMPILE_FLAGS)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the raylib cache directory
|
||||||
|
ROOT_DIR=$(pwd)
|
||||||
|
TEMP_DIR="temp/release"
|
||||||
|
if [ -n "$BUILD_DEBUG" ]; then
|
||||||
|
TEMP_DIR="temp/debug"
|
||||||
|
fi
|
||||||
|
# If there's a -c flag, remove the cache
|
||||||
|
if [ -d "$TEMP_DIR" ] && [ -n "$BUILD_ALL" ]; then
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Found cached raylib, rebuilding."
|
||||||
|
rm -r "$TEMP_DIR"
|
||||||
|
fi
|
||||||
|
# If temp directory doesn't exist, build raylib
|
||||||
|
if [ ! -d "$TEMP_DIR" ]; then
|
||||||
|
mkdir -p $TEMP_DIR
|
||||||
|
cd $TEMP_DIR
|
||||||
|
RAYLIB_DEFINES="-D_DEFAULT_SOURCE -DPLATFORM_DESKTOP -DGRAPHICS_API_OPENGL_33"
|
||||||
|
RAYLIB_C_FILES="$RAYLIB_SRC/core.c $RAYLIB_SRC/shapes.c $RAYLIB_SRC/textures.c $RAYLIB_SRC/text.c $RAYLIB_SRC/models.c $RAYLIB_SRC/utils.c $RAYLIB_SRC/raudio.c $RAYLIB_SRC/external/mini_al.c"
|
||||||
|
RAYLIB_INCLUDE_FLAGS="-I$RAYLIB_SRC -I$RAYLIB_SRC/external/glfw/include"
|
||||||
|
|
||||||
|
if [ -n "$REALLY_QUIET" ]; then
|
||||||
|
$CC -c $RAYLIB_DEFINES $RAYLIB_INCLUDE_FLAGS $COMPILATION_FLAGS -x objective-c $RAYLIB_SRC/rglfw.c > /dev/null 2>&1
|
||||||
|
$CC -c $RAYLIB_DEFINES $RAYLIB_INCLUDE_FLAGS $COMPILATION_FLAGS $RAYLIB_C_FILES > /dev/null 2>&1
|
||||||
|
else
|
||||||
|
$CC -c $RAYLIB_DEFINES $RAYLIB_INCLUDE_FLAGS $COMPILATION_FLAGS -x objective-c $RAYLIB_SRC/rglfw.c
|
||||||
|
$CC -c $RAYLIB_DEFINES $RAYLIB_INCLUDE_FLAGS $COMPILATION_FLAGS $RAYLIB_C_FILES
|
||||||
|
fi
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Raylib compiled into object files in: $TEMP_DIR/"
|
||||||
|
cd $ROOT_DIR
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build the actual game
|
||||||
|
mkdir -p $OUTPUT_DIR
|
||||||
|
cd $OUTPUT_DIR
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Compiling game code."
|
||||||
|
if [ -n "$REALLY_QUIET" ]; then
|
||||||
|
$CC -c -o main.o -I$RAYLIB_SRC $COMPILATION_FLAGS $WARNING_FLAGS $SOURCES > /dev/null 2>&1
|
||||||
|
$CC -o $GAME_NAME $ROOT_DIR/$TEMP_DIR/*.o main.o $LINK_FLAGS > /dev/null 2>&1
|
||||||
|
else
|
||||||
|
$CC -c -o main.o -I$RAYLIB_SRC $COMPILATION_FLAGS $WARNING_FLAGS $SOURCES
|
||||||
|
$CC -o $GAME_NAME $ROOT_DIR/$TEMP_DIR/*.o main.o $LINK_FLAGS
|
||||||
|
fi
|
||||||
|
rm main.o
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Game compiled into an executable in: $OUTPUT_DIR/"
|
||||||
|
|
||||||
|
if [ -n "$UPX_IT" ]; then
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Packing $GAME_NAME with upx."
|
||||||
|
upx $GAME_NAME > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$RUN_AFTER_BUILD" ]; then
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: Running."
|
||||||
|
if [ -n "$REALLY_QUIET" ]; then
|
||||||
|
./$GAME_NAME > /dev/null 2>&1
|
||||||
|
else
|
||||||
|
./$GAME_NAME
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
cd $ROOT_DIR
|
||||||
|
|
||||||
|
[ -z "$QUIET" ] && echo "COMPILE-INFO: All done."
|
211
projects/scripts/windows-build.bat
Normal file
211
projects/scripts/windows-build.bat
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
@echo off
|
||||||
|
REM Change your executable name here
|
||||||
|
set GAME_NAME=game.exe
|
||||||
|
|
||||||
|
REM Set your sources here (relative to the builds\windows directory)
|
||||||
|
REM Example with two source folders:
|
||||||
|
REM set SOURCES=..\..\src\*.c ..\..\src\submodule\*.c
|
||||||
|
set SOURCES=..\..\core_basic_window.c
|
||||||
|
|
||||||
|
REM Set your raylib/src location here, relative to the ./temp/x directory
|
||||||
|
set RAYLIB_SRC=..\..\..\..\src
|
||||||
|
|
||||||
|
REM About this build script: it does many things, but in essence, it's
|
||||||
|
REM very simple. It has 3 compiler invocations: building raylib (which
|
||||||
|
REM is not done always, see logic by searching "Build raylib"), building
|
||||||
|
REM src/*.c files, and linking together those two. Each invocation is
|
||||||
|
REM wrapped in an if statement to make the -qq flag work, it's pretty
|
||||||
|
REM verbose, sorry.
|
||||||
|
|
||||||
|
REM To skip to the actual building part of the script, search for ":BUILD"
|
||||||
|
|
||||||
|
REM For the ! variable notation
|
||||||
|
setlocal EnableDelayedExpansion
|
||||||
|
REM For shifting, which the command line argument parsing needs
|
||||||
|
setlocal EnableExtensions
|
||||||
|
|
||||||
|
|
||||||
|
:ARG_LOOP
|
||||||
|
set ARG=%1
|
||||||
|
if "!ARG!" == "" ( goto PREPARE )
|
||||||
|
IF NOT "x!ARG!" == "x!ARG:h=!" (
|
||||||
|
goto HELP
|
||||||
|
)
|
||||||
|
IF NOT "x!ARG!" == "x!ARG:d=!" (
|
||||||
|
set BUILD_DEBUG=1
|
||||||
|
)
|
||||||
|
IF NOT "x!ARG!" == "x!ARG:u=!" (
|
||||||
|
set UPX_IT=1
|
||||||
|
)
|
||||||
|
IF NOT "x!ARG!" == "x!ARG:r=!" (
|
||||||
|
set RUN_AFTER_BUILD=1
|
||||||
|
)
|
||||||
|
IF NOT "x!ARG!" == "x!ARG:c=!" (
|
||||||
|
set BUILD_ALL=1
|
||||||
|
)
|
||||||
|
IF NOT "x!ARG!" == "x!ARG:qq=!" (
|
||||||
|
set QUIET=1
|
||||||
|
set REALLY_QUIET=1
|
||||||
|
) ELSE IF NOT "x!ARG!" == "x!ARG:q=!" (
|
||||||
|
IF DEFINED QUIET (
|
||||||
|
set REALLY_QUIET=1
|
||||||
|
) ELSE (
|
||||||
|
set QUIET=1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
IF NOT "x!ARG!" == "x!ARG:v=!" (
|
||||||
|
set VERBOSE=1
|
||||||
|
)
|
||||||
|
IF NOT "%1" == "" (
|
||||||
|
shift /1
|
||||||
|
goto ARG_LOOP
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
:HELP
|
||||||
|
echo Usage: windows-build.bat [-hdurcqqv]
|
||||||
|
echo -h Show this information
|
||||||
|
echo -d Faster builds that have debug symbols, and enable warnings
|
||||||
|
echo -u Run upx* on the executable after compilation (before -r)
|
||||||
|
echo -r Run the executable after compilation
|
||||||
|
echo -c Remove the temp\{debug,release} directory, ie. full recompile
|
||||||
|
echo -q Suppress this script's informational prints
|
||||||
|
echo -qq Suppress all prints, complete silence
|
||||||
|
echo -v cl.exe normally prints out a lot of superficial information, as
|
||||||
|
echo well as the MSVC build environment activation scripts, but these are
|
||||||
|
echo mostly suppressed by default. If you do want to see everything, use
|
||||||
|
echo this flag.
|
||||||
|
echo.
|
||||||
|
echo * This is mostly here to make building simple "shipping" versions
|
||||||
|
echo easier, and it's a very small bit in the build scripts. The option
|
||||||
|
echo requires that you have upx installed and on your path, of course.
|
||||||
|
echo.
|
||||||
|
echo Examples:
|
||||||
|
echo Build a release build: windows-build.bat
|
||||||
|
echo Build a release build, full recompile: windows-build.bat -c
|
||||||
|
echo Build a debug build and run: windows-build.bat -d -r
|
||||||
|
echo Build in debug, run, don't print at all: windows-build.bat -drqq
|
||||||
|
exit /B
|
||||||
|
|
||||||
|
|
||||||
|
:PREPARE
|
||||||
|
REM Activate the msvc build environment
|
||||||
|
IF EXIST "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" (
|
||||||
|
set VC_INIT="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat"
|
||||||
|
) ELSE IF EXIST "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" (
|
||||||
|
set VC_INIT="C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat"
|
||||||
|
) ELSE IF EXIST "C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat" (
|
||||||
|
set VC_INIT="C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat"
|
||||||
|
) ELSE (
|
||||||
|
REM Initialize your vc environment here if the defaults don't work
|
||||||
|
REM set VC_INIT="C:\your\path\here\vcvarsall.bat"
|
||||||
|
REM And then remove/comment out the following two lines
|
||||||
|
echo "Couldn't find vcvarsall.bat or vcbuildtools.bat, please set it manually."
|
||||||
|
exit /B
|
||||||
|
)
|
||||||
|
IF DEFINED VERBOSE (
|
||||||
|
call !VC_INIT! x86
|
||||||
|
) ELSE (
|
||||||
|
call !VC_INIT! x86 > NUL 2>&1
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
:BUILD
|
||||||
|
REM Flags
|
||||||
|
set OUTPUT_FLAG=/Fe: "!GAME_NAME!"
|
||||||
|
set COMPILATION_FLAGS=/O1 /GL
|
||||||
|
set WARNING_FLAGS=
|
||||||
|
set SUBSYSTEM_FLAGS=/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup
|
||||||
|
set LINK_FLAGS=/link /LTCG kernel32.lib user32.lib shell32.lib winmm.lib gdi32.lib opengl32.lib
|
||||||
|
set OUTPUT_DIR=builds\windows
|
||||||
|
REM Debug changes to flags
|
||||||
|
IF DEFINED BUILD_DEBUG (
|
||||||
|
set OUTPUT_FLAG=/Fe: "!GAME_NAME!"
|
||||||
|
set COMPILATION_FLAGS=/Od /Zi
|
||||||
|
set WARNING_FLAGS=/Wall
|
||||||
|
set SUBSYSTEM_FLAGS=
|
||||||
|
set LINK_FLAGS=/link kernel32.lib user32.lib shell32.lib winmm.lib gdi32.lib opengl32.lib
|
||||||
|
set OUTPUT_DIR=builds-debug\windows
|
||||||
|
)
|
||||||
|
IF NOT DEFINED VERBOSE (
|
||||||
|
set VERBOSITY_FLAG=/nologo
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Display what we're doing
|
||||||
|
IF DEFINED BUILD_DEBUG (
|
||||||
|
IF NOT DEFINED QUIET echo COMPILE-INFO: Compiling in debug mode, flags: !COMPILATION_FLAGS! !WARNING_FLAGS!
|
||||||
|
) ELSE (
|
||||||
|
IF NOT DEFINED QUIET echo COMPILE-INFO: Compiling in release mode, flags: !COMPILATION_FLAGS! /link /LTCG
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Create the temp directory for raylib
|
||||||
|
set "ROOT_DIR=%CD%"
|
||||||
|
set "TEMP_DIR=temp\release"
|
||||||
|
IF DEFINED BUILD_DEBUG (
|
||||||
|
set "TEMP_DIR=temp\debug"
|
||||||
|
)
|
||||||
|
|
||||||
|
IF DEFINED BUILD_ALL (
|
||||||
|
IF EXIST !TEMP_DIR!\ (
|
||||||
|
IF NOT DEFINED QUIET echo COMPILE-INFO: Found cached raylib, rebuilding.
|
||||||
|
del /Q !TEMP_DIR!
|
||||||
|
rmdir !TEMP_DIR!
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Build raylib if it hasn't been cached in TEMP_DIR
|
||||||
|
IF NOT EXIST !TEMP_DIR!\ (
|
||||||
|
mkdir !TEMP_DIR!
|
||||||
|
cd !TEMP_DIR!
|
||||||
|
REM Raylib's src folder
|
||||||
|
set "RAYLIB_DEFINES=/D_DEFAULT_SOURCE /DPLATFORM_DESKTOP /DGRAPHICS_API_OPENGL_33"
|
||||||
|
set RAYLIB_C_FILES="!RAYLIB_SRC!\core.c" "!RAYLIB_SRC!\shapes.c" "!RAYLIB_SRC!\textures.c" "!RAYLIB_SRC!\text.c" "!RAYLIB_SRC!\models.c" "!RAYLIB_SRC!\utils.c" "!RAYLIB_SRC!\raudio.c" "!RAYLIB_SRC!\rglfw.c" "!RAYLIB_SRC!\external\mini_al.c"
|
||||||
|
set RAYLIB_INCLUDE_FLAGS=/I"!RAYLIB_SRC!" /I"!RAYLIB_SRC!\external\glfw\include"
|
||||||
|
|
||||||
|
IF DEFINED REALLY_QUIET (
|
||||||
|
cl.exe /w /c !RAYLIB_DEFINES! !RAYLIB_INCLUDE_FLAGS! !COMPILATION_FLAGS! !RAYLIB_C_FILES! > NUL 2>&1
|
||||||
|
) ELSE (
|
||||||
|
cl.exe /w /c !VERBOSITY_FLAG! !RAYLIB_DEFINES! !RAYLIB_INCLUDE_FLAGS! !COMPILATION_FLAGS! !RAYLIB_C_FILES!
|
||||||
|
)
|
||||||
|
IF NOT DEFINED QUIET echo COMPILE-INFO: Raylib compiled into object files in: !TEMP_DIR!\
|
||||||
|
|
||||||
|
REM Out of the temp directory
|
||||||
|
cd !ROOT_DIR!
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Move to the build directory
|
||||||
|
IF NOT EXIST !OUTPUT_DIR! mkdir !OUTPUT_DIR!
|
||||||
|
cd !OUTPUT_DIR!
|
||||||
|
|
||||||
|
REM Build the actual game
|
||||||
|
IF NOT DEFINED QUIET echo COMPILE-INFO: Compiling game code.
|
||||||
|
IF DEFINED REALLY_QUIET (
|
||||||
|
cl.exe !VERBOSITY_FLAG! /Fo"main.obj" !COMPILATION_FLAGS! !WARNING_FLAGS! /c /I"!RAYLIB_SRC!" !SOURCES! > NUL 2>&1
|
||||||
|
cl.exe !VERBOSITY_FLAG! !OUTPUT_FLAG! "!ROOT_DIR!\!TEMP_DIR!\*.obj" main.obj !LINK_FLAGS! !SUBSYSTEM_FLAGS! > NUL 2>&1
|
||||||
|
) ELSE (
|
||||||
|
cl.exe !VERBOSITY_FLAG! /Fo"main.obj" !COMPILATION_FLAGS! !WARNING_FLAGS! /c /I"!RAYLIB_SRC!" !SOURCES!
|
||||||
|
cl.exe !VERBOSITY_FLAG! !OUTPUT_FLAG! "!ROOT_DIR!\!TEMP_DIR!\*.obj" main.obj !LINK_FLAGS! !SUBSYSTEM_FLAGS!
|
||||||
|
)
|
||||||
|
del main.obj
|
||||||
|
IF NOT DEFINED QUIET echo COMPILE-INFO: Game compiled into an executable in: !OUTPUT_DIR!\
|
||||||
|
|
||||||
|
REM Run upx
|
||||||
|
IF DEFINED UPX_IT (
|
||||||
|
IF NOT DEFINED QUIET echo COMPILE-INFO: Packing !GAME_NAME! with upx.
|
||||||
|
upx !GAME_NAME! > NUL 2>&1
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Finally, run the produced executable
|
||||||
|
IF DEFINED RUN_AFTER_BUILD (
|
||||||
|
IF NOT DEFINED QUIET echo COMPILE-INFO: Running.
|
||||||
|
IF DEFINED REALLY_QUIET (
|
||||||
|
!GAME_NAME! > NUL 2>&1
|
||||||
|
) ELSE (
|
||||||
|
!GAME_NAME!
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Back to development directory
|
||||||
|
cd !ROOT_DIR!
|
||||||
|
|
||||||
|
IF NOT DEFINED QUIET echo COMPILE-INFO: All done.
|
@ -47,12 +47,11 @@ add_definitions("-DRAYLIB_CMAKE=1")
|
|||||||
if(USE_AUDIO)
|
if(USE_AUDIO)
|
||||||
file(GLOB mini_al external/mini_al.c)
|
file(GLOB mini_al external/mini_al.c)
|
||||||
MESSAGE(STATUS "Audio Backend: mini_al")
|
MESSAGE(STATUS "Audio Backend: mini_al")
|
||||||
file(GLOB stb_vorbis external/stb_vorbis.c)
|
set(sources ${raylib_sources} ${mini_al})
|
||||||
set(sources ${raylib_sources} ${mini_al} ${stb_vorbis})
|
|
||||||
else()
|
else()
|
||||||
MESSAGE(STATUS "Audio Backend: None (-DUSE_AUDIO=OFF)")
|
MESSAGE(STATUS "Audio Backend: None (-DUSE_AUDIO=OFF)")
|
||||||
set(INCLUDE_AUDIO_MODULE 0)
|
set(INCLUDE_AUDIO_MODULE 0)
|
||||||
list(REMOVE_ITEM raylib_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio.c)
|
list(REMOVE_ITEM raylib_sources ${CMAKE_CURRENT_SOURCE_DIR}/raudio.c)
|
||||||
set(sources ${raylib_sources})
|
set(sources ${raylib_sources})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -251,7 +250,7 @@ file(COPY "raylib.h" DESTINATION ".")
|
|||||||
file(COPY "rlgl.h" DESTINATION ".")
|
file(COPY "rlgl.h" DESTINATION ".")
|
||||||
file(COPY "physac.h" DESTINATION ".")
|
file(COPY "physac.h" DESTINATION ".")
|
||||||
file(COPY "raymath.h" DESTINATION ".")
|
file(COPY "raymath.h" DESTINATION ".")
|
||||||
file(COPY "audio.h" DESTINATION ".")
|
file(COPY "raudio.h" DESTINATION ".")
|
||||||
|
|
||||||
# Print the flags for the user
|
# Print the flags for the user
|
||||||
message(STATUS "Compiling with the flags:")
|
message(STATUS "Compiling with the flags:")
|
||||||
|
@ -61,7 +61,7 @@ option(SUPPORT_FILEFORMAT_OBJ "Support loading OBJ file format" ON)
|
|||||||
option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" ON)
|
option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" ON)
|
||||||
option(SUPPORT_MESH_GENERATION "Support procedural mesh generation functions, uses external par_shapes.h library. NOTE: Some generated meshes DO NOT include generated texture coordinates" ON)
|
option(SUPPORT_MESH_GENERATION "Support procedural mesh generation functions, uses external par_shapes.h library. NOTE: Some generated meshes DO NOT include generated texture coordinates" ON)
|
||||||
|
|
||||||
# audio.c
|
# raudio.c
|
||||||
option(SUPPORT_FILEFORMAT_WAV "Support loading WAV for sound" ON)
|
option(SUPPORT_FILEFORMAT_WAV "Support loading WAV for sound" ON)
|
||||||
option(SUPPORT_FILEFORMAT_OGG "Support loading OGG for sound" ON)
|
option(SUPPORT_FILEFORMAT_OGG "Support loading OGG for sound" ON)
|
||||||
option(SUPPORT_FILEFORMAT_XM "Support loading XM for sound" ON)
|
option(SUPPORT_FILEFORMAT_XM "Support loading XM for sound" ON)
|
||||||
|
19
src/Makefile
19
src/Makefile
@ -149,8 +149,8 @@ endif
|
|||||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||||
# Emscripten required variables
|
# Emscripten required variables
|
||||||
EMSDK_PATH = C:/emsdk
|
EMSDK_PATH = C:/emsdk
|
||||||
EMSCRIPTEN_VERSION = 1.38.20
|
EMSCRIPTEN_VERSION ?= 1.38.21
|
||||||
CLANG_VERSION = e1.38.20_64bit
|
CLANG_VERSION = e$(EMSCRIPTEN_VERSION)_64bit
|
||||||
PYTHON_VERSION = 2.7.13.1_64bit\python-2.7.13.amd64
|
PYTHON_VERSION = 2.7.13.1_64bit\python-2.7.13.amd64
|
||||||
NODE_VERSION = 8.9.1_64bit
|
NODE_VERSION = 8.9.1_64bit
|
||||||
export PATH = $(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
|
export PATH = $(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
|
||||||
@ -300,7 +300,7 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
|
|||||||
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
|
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
|
||||||
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
|
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
|
||||||
# -s USE_PTHREADS=1 # multithreading support
|
# -s USE_PTHREADS=1 # multithreading support
|
||||||
CFLAGS += -s USE_GLFW=3 -s USE_SDL=2 -s ASSERTIONS=1 --profiling
|
CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 --profiling
|
||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||||
# Compiler flags for arquitecture
|
# Compiler flags for arquitecture
|
||||||
@ -403,8 +403,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(INCLUDE_AUDIO_MODULE),TRUE)
|
ifeq ($(INCLUDE_AUDIO_MODULE),TRUE)
|
||||||
OBJS += audio.o
|
OBJS += raudio.o
|
||||||
OBJS += stb_vorbis.o
|
|
||||||
OBJS += mini_al.o
|
OBJS += mini_al.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -530,17 +529,13 @@ models.o : models.c raylib.h rlgl.h raymath.h
|
|||||||
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS)
|
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS)
|
||||||
|
|
||||||
# Compile audio module
|
# Compile audio module
|
||||||
audio.o : audio.c raylib.h
|
raudio.o : raudio.c raylib.h
|
||||||
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
|
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
|
||||||
|
|
||||||
# Compile mini_al audio library
|
# Compile mini_al audio library
|
||||||
mini_al.o : external/mini_al.c external/mini_al.h
|
mini_al.o : external/mini_al.c external/mini_al.h
|
||||||
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
|
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
|
||||||
|
|
||||||
# Compile stb_vorbis library
|
|
||||||
stb_vorbis.o: external/stb_vorbis.c external/stb_vorbis.h
|
|
||||||
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
|
|
||||||
|
|
||||||
# Compile utils module
|
# Compile utils module
|
||||||
utils.o : utils.c utils.h
|
utils.o : utils.c utils.h
|
||||||
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
|
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
|
||||||
@ -628,9 +623,9 @@ endif
|
|||||||
# Clean everything
|
# Clean everything
|
||||||
clean:
|
clean:
|
||||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||||
del *.o $(RAYLIB_RELEASE_PATH)/libraylib.a $(RAYLIB_RELEASE_PATH)/libraylib.bc $(RAYLIB_RELEASE_PATH)/libraylib.so external/stb_vorbis.o
|
del *.o $(RAYLIB_RELEASE_PATH)/libraylib.a $(RAYLIB_RELEASE_PATH)/libraylib.bc $(RAYLIB_RELEASE_PATH)/libraylib.so
|
||||||
else
|
else
|
||||||
rm -fv *.o $(RAYLIB_RELEASE_PATH)/libraylib.a $(RAYLIB_RELEASE_PATH)/libraylib.bc $(RAYLIB_RELEASE_PATH)/libraylib.so* external/stb_vorbis.o
|
rm -fv *.o $(RAYLIB_RELEASE_PATH)/libraylib.a $(RAYLIB_RELEASE_PATH)/libraylib.bc $(RAYLIB_RELEASE_PATH)/libraylib.so*
|
||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||||
rm -rf $(ANDROID_TOOLCHAIN)
|
rm -rf $(ANDROID_TOOLCHAIN)
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*
|
*
|
||||||
**********************************************************************************************/
|
**********************************************************************************************/
|
||||||
|
|
||||||
#define RAYLIB_VERSION "2.2-dev"
|
#define RAYLIB_VERSION "2.4-dev"
|
||||||
|
|
||||||
// Edit to control what features Makefile'd raylib is compiled with
|
// Edit to control what features Makefile'd raylib is compiled with
|
||||||
#if defined(RAYLIB_CMAKE)
|
#if defined(RAYLIB_CMAKE)
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
* NOTE: Some generated meshes DO NOT include generated texture coordinates */
|
* NOTE: Some generated meshes DO NOT include generated texture coordinates */
|
||||||
#cmakedefine SUPPORT_MESH_GENERATION 1
|
#cmakedefine SUPPORT_MESH_GENERATION 1
|
||||||
|
|
||||||
// audio.c
|
// raudio.c
|
||||||
/* Desired fileformats to be supported for loading. */
|
/* Desired fileformats to be supported for loading. */
|
||||||
#cmakedefine SUPPORT_FILEFORMAT_WAV 1
|
#cmakedefine SUPPORT_FILEFORMAT_WAV 1
|
||||||
#cmakedefine SUPPORT_FILEFORMAT_OGG 1
|
#cmakedefine SUPPORT_FILEFORMAT_OGG 1
|
||||||
|
171
src/core.c
171
src/core.c
@ -175,11 +175,9 @@
|
|||||||
#include <GLFW/glfw3native.h> // Required for: glfwGetX11Window()
|
#include <GLFW/glfw3native.h> // Required for: glfwGetX11Window()
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
#include <unistd.h> // Required for: usleep()
|
#include <unistd.h> // Required for: usleep()
|
||||||
#include <objc/message.h> // Required for: objc_msgsend(), sel_registerName()
|
|
||||||
|
|
||||||
//#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition
|
//#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition
|
||||||
#define GLFW_EXPOSE_NATIVE_NSGL
|
#include <GLFW/glfw3native.h> // Required for: glfwGetCocoaWindow()
|
||||||
#include <GLFW/glfw3native.h> // Required for: glfwGetCocoaWindow(), glfwGetNSGLContext()
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -277,10 +275,6 @@ static bool windowReady = false; // Check if window has been init
|
|||||||
static bool windowMinimized = false; // Check if window has been minimized
|
static bool windowMinimized = false; // Check if window has been minimized
|
||||||
static const char *windowTitle = NULL; // Window text title...
|
static const char *windowTitle = NULL; // Window text title...
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
static int windowNeedsUpdating = 2; // Times the Cocoa window needs to be updated initially
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static unsigned int displayWidth, displayHeight;// Display width and height (monitor, device-screen, LCD, ...)
|
static unsigned int displayWidth, displayHeight;// Display width and height (monitor, device-screen, LCD, ...)
|
||||||
static int screenWidth, screenHeight; // Screen width and height (used render area)
|
static int screenWidth, screenHeight; // Screen width and height (used render area)
|
||||||
static int renderWidth, renderHeight; // Framebuffer width and height (render area, including black bars if required)
|
static int renderWidth, renderHeight; // Framebuffer width and height (render area, including black bars if required)
|
||||||
@ -311,7 +305,7 @@ extern EGLNativeWindowType uwpWindow; // Native EGL window handler for
|
|||||||
static struct android_app *androidApp; // Android activity
|
static struct android_app *androidApp; // Android activity
|
||||||
static struct android_poll_source *source; // Android events polling source
|
static struct android_poll_source *source; // Android events polling source
|
||||||
static int ident, events; // Android ALooper_pollAll() variables
|
static int ident, events; // Android ALooper_pollAll() variables
|
||||||
static const char *internalDataPath; // Android internal data path to write data (/data/data/<package>/files)
|
static const char *internalDataPath = NULL; // Android internal data path to write data (/data/data/<package>/files)
|
||||||
|
|
||||||
static bool appEnabled = true; // Used to detec if app is active
|
static bool appEnabled = true; // Used to detec if app is active
|
||||||
static bool contextRebindRequired = false; // Used to know context rebind required
|
static bool contextRebindRequired = false; // Used to know context rebind required
|
||||||
@ -332,8 +326,9 @@ static int defaultKeyboardMode; // Used to store default keyboar
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Mouse states
|
// Mouse states
|
||||||
static Vector2 mousePosition; // Mouse position on screen
|
static Vector2 mousePosition = { 0.0f, 0.0f }; // Mouse position on screen
|
||||||
static float mouseScale = 1.0f; // Mouse default scale
|
static Vector2 mouseScale = { 1.0f, 1.0f }; // Mouse scaling
|
||||||
|
static Vector2 mouseOffset = { 0.0f, 0.0f }; // Mouse offset
|
||||||
static bool cursorHidden = false; // Track if cursor is hidden
|
static bool cursorHidden = false; // Track if cursor is hidden
|
||||||
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
|
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
|
||||||
static Vector2 touchPosition[MAX_TOUCH_POINTS]; // Touch position on screen
|
static Vector2 touchPosition[MAX_TOUCH_POINTS]; // Touch position on screen
|
||||||
@ -1485,12 +1480,6 @@ Color Fade(Color color, float alpha)
|
|||||||
return (Color){color.r, color.g, color.b, (unsigned char)(255.0f*alpha)};
|
return (Color){color.r, color.g, color.b, (unsigned char)(255.0f*alpha)};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate raylib logo at startup (can be done with flags)
|
|
||||||
void ShowLogo(void)
|
|
||||||
{
|
|
||||||
showLogo = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup window configuration flags (view FLAGS)
|
// Setup window configuration flags (view FLAGS)
|
||||||
void SetConfigFlags(unsigned char flags)
|
void SetConfigFlags(unsigned char flags)
|
||||||
{
|
{
|
||||||
@ -1503,17 +1492,32 @@ void SetConfigFlags(unsigned char flags)
|
|||||||
// NOTE TraceLog() function is located in [utils.h]
|
// NOTE TraceLog() function is located in [utils.h]
|
||||||
|
|
||||||
// Takes a screenshot of current screen (saved a .png)
|
// Takes a screenshot of current screen (saved a .png)
|
||||||
|
// NOTE: This function could work in any platform but some platforms: PLATFORM_ANDROID and PLATFORM_WEB
|
||||||
|
// have their own internal file-systems, to dowload image to user file-system some additional mechanism is required
|
||||||
void TakeScreenshot(const char *fileName)
|
void TakeScreenshot(const char *fileName)
|
||||||
{
|
{
|
||||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
|
||||||
unsigned char *imgData = rlReadScreenPixels(renderWidth, renderHeight);
|
unsigned char *imgData = rlReadScreenPixels(renderWidth, renderHeight);
|
||||||
|
|
||||||
Image image = { imgData, renderWidth, renderHeight, 1, UNCOMPRESSED_R8G8B8A8 };
|
Image image = { imgData, renderWidth, renderHeight, 1, UNCOMPRESSED_R8G8B8A8 };
|
||||||
ExportImage(image, fileName);
|
|
||||||
free(imgData);
|
char path[512] = { 0 };
|
||||||
|
#if defined(PLATFORM_ANDROID)
|
||||||
TraceLog(LOG_INFO, "Screenshot taken: %s", fileName);
|
strcpy(path, internalDataPath);
|
||||||
|
strcat(path, "/");
|
||||||
|
strcat(path, fileName);
|
||||||
|
#else
|
||||||
|
strcpy(path, fileName);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ExportImage(image, path);
|
||||||
|
free(imgData);
|
||||||
|
|
||||||
|
#if defined(PLATFORM_WEB)
|
||||||
|
// Download file from MEMFS (emscripten memory filesystem)
|
||||||
|
// SaveFileFromMEMFSToDisk() function is defined in raylib/templates/web_shel/shell.html
|
||||||
|
emscripten_run_script(TextFormat("SaveFileFromMEMFSToDisk('%s','%s')", GetFileName(path), GetFileName(path)));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TraceLog(LOG_INFO, "Screenshot taken: %s", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the file exists
|
// Check if the file exists
|
||||||
@ -1522,11 +1526,10 @@ bool FileExists(const char *fileName)
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
if (_access(fileName, 0) != -1)
|
if (_access(fileName, 0) != -1) result = true;
|
||||||
#else
|
#else
|
||||||
if (access(fileName, F_OK) != -1)
|
if (access(fileName, F_OK) != -1) result = true;
|
||||||
#endif
|
#endif
|
||||||
result = true;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1539,7 +1542,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
|
|||||||
|
|
||||||
if ((fileExt = strrchr(fileName, '.')) != NULL)
|
if ((fileExt = strrchr(fileName, '.')) != NULL)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
result = true;
|
result = true;
|
||||||
int extLen = strlen(ext);
|
int extLen = strlen(ext);
|
||||||
|
|
||||||
@ -1555,9 +1558,9 @@ bool IsFileExtension(const char *fileName, const char *ext)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else result = false;
|
else result = false;
|
||||||
#else
|
#else
|
||||||
if (strcmp(fileExt, ext) == 0) result = true;
|
if (strcmp(fileExt, ext) == 0) result = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -1759,7 +1762,7 @@ void StorageSaveValue(int position, int value)
|
|||||||
{
|
{
|
||||||
FILE *storageFile = NULL;
|
FILE *storageFile = NULL;
|
||||||
|
|
||||||
char path[128];
|
char path[512] = { 0 };
|
||||||
#if defined(PLATFORM_ANDROID)
|
#if defined(PLATFORM_ANDROID)
|
||||||
strcpy(path, internalDataPath);
|
strcpy(path, internalDataPath);
|
||||||
strcat(path, "/");
|
strcat(path, "/");
|
||||||
@ -1799,7 +1802,7 @@ int StorageLoadValue(int position)
|
|||||||
{
|
{
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
|
||||||
char path[128];
|
char path[512] = { 0 };
|
||||||
#if defined(PLATFORM_ANDROID)
|
#if defined(PLATFORM_ANDROID)
|
||||||
strcpy(path, internalDataPath);
|
strcpy(path, internalDataPath);
|
||||||
strcat(path, "/");
|
strcat(path, "/");
|
||||||
@ -1844,7 +1847,9 @@ void OpenURL(const char *url)
|
|||||||
if (strchr(url, '\'') != NULL)
|
if (strchr(url, '\'') != NULL)
|
||||||
{
|
{
|
||||||
TraceLog(LOG_WARNING, "Provided URL does not seem to be valid.");
|
TraceLog(LOG_WARNING, "Provided URL does not seem to be valid.");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
char *cmd = calloc(strlen(url) + 10, sizeof(char));
|
char *cmd = calloc(strlen(url) + 10, sizeof(char));
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
@ -2100,7 +2105,7 @@ int GetMouseX(void)
|
|||||||
#if defined(PLATFORM_ANDROID)
|
#if defined(PLATFORM_ANDROID)
|
||||||
return (int)touchPosition[0].x;
|
return (int)touchPosition[0].x;
|
||||||
#else
|
#else
|
||||||
return (int)(mousePosition.x*mouseScale);
|
return (int)((mousePosition.x + mouseOffset.x)*mouseScale.x);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2110,7 +2115,7 @@ int GetMouseY(void)
|
|||||||
#if defined(PLATFORM_ANDROID)
|
#if defined(PLATFORM_ANDROID)
|
||||||
return (int)touchPosition[0].x;
|
return (int)touchPosition[0].x;
|
||||||
#else
|
#else
|
||||||
return (int)(mousePosition.y*mouseScale);
|
return (int)((mousePosition.y + mouseOffset.y)*mouseScale.y);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2120,27 +2125,32 @@ Vector2 GetMousePosition(void)
|
|||||||
#if defined(PLATFORM_ANDROID)
|
#if defined(PLATFORM_ANDROID)
|
||||||
return GetTouchPosition(0);
|
return GetTouchPosition(0);
|
||||||
#else
|
#else
|
||||||
return (Vector2){ mousePosition.x*mouseScale, mousePosition.y*mouseScale };
|
return (Vector2){ (mousePosition.x + mouseOffset.x)*mouseScale.x, (mousePosition.y + mouseOffset.y)*mouseScale.y };
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set mouse position XY
|
// Set mouse position XY
|
||||||
void SetMousePosition(Vector2 position)
|
void SetMousePosition(int x, int y)
|
||||||
{
|
{
|
||||||
mousePosition = position;
|
mousePosition = (Vector2){ (float)x, (float)y };
|
||||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||||
// NOTE: emscripten not implemented
|
// NOTE: emscripten not implemented
|
||||||
glfwSetCursorPos(window, position.x, position.y);
|
glfwSetCursorPos(window, mousePosition.x, mousePosition.y);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set mouse offset
|
||||||
|
// NOTE: Useful when rendering to different size targets
|
||||||
|
void SetMouseOffset(int offsetX, int offsetY)
|
||||||
|
{
|
||||||
|
mouseOffset = (Vector2){ (float)offsetX, (float)offsetY };
|
||||||
|
}
|
||||||
|
|
||||||
// Set mouse scaling
|
// Set mouse scaling
|
||||||
// NOTE: Useful when rendering to different size targets
|
// NOTE: Useful when rendering to different size targets
|
||||||
void SetMouseScale(float scale)
|
void SetMouseScale(float scaleX, float scaleY)
|
||||||
{
|
{
|
||||||
#if !defined(PLATFORM_ANDROID)
|
mouseScale = (Vector2){ scaleX, scaleY };
|
||||||
mouseScale = scale;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns mouse wheel movement Y
|
// Returns mouse wheel movement Y
|
||||||
@ -2278,8 +2288,8 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
if (configFlags & FLAG_WINDOW_RESIZABLE) glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // Resizable window
|
if (configFlags & FLAG_WINDOW_RESIZABLE) glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // Resizable window
|
||||||
else glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
|
else glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
|
||||||
|
|
||||||
if (configFlags & FLAG_WINDOW_UNDECORATED) glfwWindowHint(GLFW_DECORATED, GL_FALSE); // Border and buttons on Window
|
if (configFlags & FLAG_WINDOW_UNDECORATED) glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); // Border and buttons on Window
|
||||||
else glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Decorated window
|
else glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); // Decorated window
|
||||||
// FLAG_WINDOW_TRANSPARENT not supported on HTML5 and not included in any released GLFW version yet
|
// FLAG_WINDOW_TRANSPARENT not supported on HTML5 and not included in any released GLFW version yet
|
||||||
#if defined(GLFW_TRANSPARENT_FRAMEBUFFER)
|
#if defined(GLFW_TRANSPARENT_FRAMEBUFFER)
|
||||||
if (configFlags & FLAG_WINDOW_TRANSPARENT) glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); // Transparent framebuffer
|
if (configFlags & FLAG_WINDOW_TRANSPARENT) glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); // Transparent framebuffer
|
||||||
@ -2295,21 +2305,28 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
// Check selection OpenGL version
|
// Check selection OpenGL version
|
||||||
if (rlGetVersion() == OPENGL_21)
|
if (rlGetVersion() == OPENGL_21)
|
||||||
{
|
{
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); // Choose OpenGL major version (just hint)
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); // Choose OpenGL major version (just hint)
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); // Choose OpenGL minor version (just hint)
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); // Choose OpenGL minor version (just hint)
|
||||||
}
|
}
|
||||||
else if (rlGetVersion() == OPENGL_33)
|
else if (rlGetVersion() == OPENGL_33)
|
||||||
{
|
{
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Choose OpenGL major version (just hint)
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Choose OpenGL major version (just hint)
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Profiles Hint: Only 3.3 and above!
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Profiles Hint: Only 3.3 and above!
|
||||||
// Values: GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE
|
// Values: GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // OSX Requires fordward compatibility
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); // OSX Requires fordward compatibility
|
||||||
#else
|
#else
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE); // Fordward Compatibility Hint: Only 3.3 and above!
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE); // Fordward Compatibility Hint: Only 3.3 and above!
|
||||||
#endif
|
#endif
|
||||||
//glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); // Request OpenGL DEBUG context
|
//glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Request OpenGL DEBUG context
|
||||||
|
}
|
||||||
|
else if (rlGetVersion() == OPENGL_ES_20) // Request OpenGL ES 2.0 context
|
||||||
|
{
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||||
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API); // Alternative: GLFW_EGL_CONTEXT_API (ANGLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fullscreen)
|
if (fullscreen)
|
||||||
@ -2402,7 +2419,9 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
|
|
||||||
// Try to disable GPU V-Sync by default, set framerate using SetTargetFPS()
|
// Try to disable GPU V-Sync by default, set framerate using SetTargetFPS()
|
||||||
// NOTE: V-Sync can be enabled by graphic driver configuration
|
// NOTE: V-Sync can be enabled by graphic driver configuration
|
||||||
|
#if !defined(PLATFORM_WEB)
|
||||||
glfwSwapInterval(0);
|
glfwSwapInterval(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(PLATFORM_DESKTOP)
|
#if defined(PLATFORM_DESKTOP)
|
||||||
// Load OpenGL 3.3 extensions
|
// Load OpenGL 3.3 extensions
|
||||||
@ -3138,16 +3157,6 @@ static void SwapBuffers(void)
|
|||||||
{
|
{
|
||||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
#if __APPLE__
|
|
||||||
// Workaround for missing/erroneous initial rendering on macOS
|
|
||||||
if (windowNeedsUpdating)
|
|
||||||
{
|
|
||||||
// Desugared version of Objective C: [glfwGetNSGLContext(window) update]
|
|
||||||
((id (*)(id, SEL))objc_msgSend)(glfwGetNSGLContext(window), sel_registerName("update"));
|
|
||||||
|
|
||||||
windowNeedsUpdating--;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
|
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
|
||||||
@ -3173,20 +3182,25 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
|||||||
{
|
{
|
||||||
if (key == exitKey && action == GLFW_PRESS)
|
if (key == exitKey && action == GLFW_PRESS)
|
||||||
{
|
{
|
||||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||||
|
|
||||||
// NOTE: Before closing window, while loop must be left!
|
// NOTE: Before closing window, while loop must be left!
|
||||||
}
|
}
|
||||||
#if defined(PLATFORM_DESKTOP)
|
|
||||||
else if (key == GLFW_KEY_F12 && action == GLFW_PRESS)
|
else if (key == GLFW_KEY_F12 && action == GLFW_PRESS)
|
||||||
{
|
{
|
||||||
#if defined(SUPPORT_GIF_RECORDING)
|
#if defined(SUPPORT_GIF_RECORDING)
|
||||||
if (mods == GLFW_MOD_CONTROL)
|
if (mods == GLFW_MOD_CONTROL)
|
||||||
{
|
{
|
||||||
if (gifRecording)
|
if (gifRecording)
|
||||||
{
|
{
|
||||||
GifEnd();
|
GifEnd();
|
||||||
gifRecording = false;
|
gifRecording = false;
|
||||||
|
|
||||||
|
#if defined(PLATFORM_WEB)
|
||||||
|
// Download file from MEMFS (emscripten memory filesystem)
|
||||||
|
// SaveFileFromMEMFSToDisk() function is defined in raylib/templates/web_shel/shell.html
|
||||||
|
emscripten_run_script(TextFormat("SaveFileFromMEMFSToDisk('%s','%s')", TextFormat("screenrec%03i.gif", screenshotCounter - 1), TextFormat("screenrec%03i.gif", screenshotCounter - 1)));
|
||||||
|
#endif
|
||||||
|
|
||||||
TraceLog(LOG_INFO, "End animated GIF recording");
|
TraceLog(LOG_INFO, "End animated GIF recording");
|
||||||
}
|
}
|
||||||
@ -3194,25 +3208,32 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
|||||||
{
|
{
|
||||||
gifRecording = true;
|
gifRecording = true;
|
||||||
gifFramesCounter = 0;
|
gifFramesCounter = 0;
|
||||||
|
|
||||||
|
char path[512] = { 0 };
|
||||||
|
#if defined(PLATFORM_ANDROID)
|
||||||
|
strcpy(path, internalDataPath);
|
||||||
|
strcat(path, TextFormat("/screenrec%03i.gif", screenshotCounter));
|
||||||
|
#else
|
||||||
|
strcpy(path, TextFormat("/screenrec%03i.gif", screenshotCounter));
|
||||||
|
#endif
|
||||||
|
|
||||||
// NOTE: delay represents the time between frames in the gif, if we capture a gif frame every
|
// NOTE: delay represents the time between frames in the gif, if we capture a gif frame every
|
||||||
// 10 game frames and each frame trakes 16.6ms (60fps), delay between gif frames should be ~16.6*10.
|
// 10 game frames and each frame trakes 16.6ms (60fps), delay between gif frames should be ~16.6*10.
|
||||||
GifBegin(FormatText("screenrec%03i.gif", screenshotCounter), screenWidth, screenHeight, (int)(GetFrameTime()*10.0f), 8, false);
|
GifBegin(path, screenWidth, screenHeight, (int)(GetFrameTime()*10.0f), 8, false);
|
||||||
screenshotCounter++;
|
screenshotCounter++;
|
||||||
|
|
||||||
TraceLog(LOG_INFO, "Begin animated GIF recording: %s", FormatText("screenrec%03i.gif", screenshotCounter));
|
TraceLog(LOG_INFO, "Begin animated GIF recording: %s", TextFormat("screenrec%03i.gif", screenshotCounter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif // SUPPORT_GIF_RECORDING
|
#endif // SUPPORT_GIF_RECORDING
|
||||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||||
{
|
{
|
||||||
TakeScreenshot(FormatText("screenshot%03i.png", screenshotCounter));
|
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
|
||||||
screenshotCounter++;
|
screenshotCounter++;
|
||||||
}
|
}
|
||||||
#endif // SUPPORT_SCREEN_CAPTURE
|
#endif // SUPPORT_SCREEN_CAPTURE
|
||||||
}
|
}
|
||||||
#endif // PLATFORM_DESKTOP
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
currentKeyState[key] = action;
|
currentKeyState[key] = action;
|
||||||
@ -3394,11 +3415,11 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||||||
// Init hi-res timer
|
// Init hi-res timer
|
||||||
InitTimer();
|
InitTimer();
|
||||||
|
|
||||||
#if defined(SUPPORT_DEFAULT_FONT)
|
#if defined(SUPPORT_DEFAULT_FONT)
|
||||||
// Load default font
|
// Load default font
|
||||||
// NOTE: External function (defined in module: text)
|
// NOTE: External function (defined in module: text)
|
||||||
LoadDefaultFont();
|
LoadDefaultFont();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: GPU assets reload in case of lost focus (lost context)
|
// TODO: GPU assets reload in case of lost focus (lost context)
|
||||||
// NOTE: This problem has been solved just unbinding and rebinding context from display
|
// NOTE: This problem has been solved just unbinding and rebinding context from display
|
||||||
@ -4246,10 +4267,10 @@ static void *EventThread(void *arg)
|
|||||||
|
|
||||||
// Screen confinement
|
// Screen confinement
|
||||||
if (mousePosition.x < 0) mousePosition.x = 0;
|
if (mousePosition.x < 0) mousePosition.x = 0;
|
||||||
if (mousePosition.x > screenWidth/mouseScale) mousePosition.x = screenWidth/mouseScale;
|
if (mousePosition.x > screenWidth/mouseScale.x) mousePosition.x = screenWidth/mouseScale.x;
|
||||||
|
|
||||||
if (mousePosition.y < 0) mousePosition.y = 0;
|
if (mousePosition.y < 0) mousePosition.y = 0;
|
||||||
if (mousePosition.y > screenHeight/mouseScale) mousePosition.y = screenHeight/mouseScale;
|
if (mousePosition.y > screenHeight/mouseScale.y) mousePosition.y = screenHeight/mouseScale.y;
|
||||||
|
|
||||||
// Gesture update
|
// Gesture update
|
||||||
if (GestureNeedsUpdate)
|
if (GestureNeedsUpdate)
|
||||||
@ -4475,7 +4496,7 @@ static void LogoAnimation(void)
|
|||||||
|
|
||||||
DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
|
DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
|
||||||
|
|
||||||
DrawText(SubText("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha));
|
DrawText(TextSubtext("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
3
src/external/.gitignore
vendored
Normal file
3
src/external/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
glfw/docs/
|
||||||
|
glfw/examples/
|
||||||
|
glfw/tests/
|
2
src/external/glfw/.travis.yml
vendored
2
src/external/glfw/.travis.yml
vendored
@ -65,7 +65,7 @@ script:
|
|||||||
sudo dpkg -i extra-cmake-modules_5.38.0a-0ubuntu1_amd64.deb;
|
sudo dpkg -i extra-cmake-modules_5.38.0a-0ubuntu1_amd64.deb;
|
||||||
git clone git://anongit.freedesktop.org/wayland/wayland-protocols;
|
git clone git://anongit.freedesktop.org/wayland/wayland-protocols;
|
||||||
pushd wayland-protocols;
|
pushd wayland-protocols;
|
||||||
git checkout 1.12 && ./autogen.sh --prefix=/usr && make && sudo make install;
|
git checkout 1.15 && ./autogen.sh --prefix=/usr && make && sudo make install;
|
||||||
popd;
|
popd;
|
||||||
fi
|
fi
|
||||||
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DGLFW_USE_WAYLAND=${USE_WAYLAND} ..
|
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DGLFW_USE_WAYLAND=${USE_WAYLAND} ..
|
||||||
|
34
src/external/glfw/CMake/modules/FindMir.cmake
vendored
34
src/external/glfw/CMake/modules/FindMir.cmake
vendored
@ -1,34 +0,0 @@
|
|||||||
# FindMir
|
|
||||||
# -------
|
|
||||||
# Finds the Mir library
|
|
||||||
#
|
|
||||||
# This will will define the following variables::
|
|
||||||
#
|
|
||||||
# MIR_FOUND - the system has Mir
|
|
||||||
# MIR_INCLUDE_DIRS - the Mir include directory
|
|
||||||
# MIR_LIBRARIES - the Mir libraries
|
|
||||||
# MIR_DEFINITIONS - the Mir definitions
|
|
||||||
|
|
||||||
|
|
||||||
find_package (PkgConfig)
|
|
||||||
if(PKG_CONFIG_FOUND)
|
|
||||||
pkg_check_modules (PC_MIR mirclient>=0.26.2 QUIET)
|
|
||||||
|
|
||||||
find_path(MIR_INCLUDE_DIR NAMES mir_toolkit/mir_client_library.h
|
|
||||||
PATHS ${PC_MIR_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
find_library(MIR_LIBRARY NAMES mirclient
|
|
||||||
PATHS ${PC_MIR_LIBRARIES} ${PC_MIR_LIBRARY_DIRS})
|
|
||||||
|
|
||||||
include (FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args (MIR
|
|
||||||
REQUIRED_VARS MIR_LIBRARY MIR_INCLUDE_DIR)
|
|
||||||
|
|
||||||
if (MIR_FOUND)
|
|
||||||
set(MIR_LIBRARIES ${MIR_LIBRARY})
|
|
||||||
set(MIR_INCLUDE_DIRS ${PC_MIR_INCLUDE_DIRS})
|
|
||||||
set(MIR_DEFINITIONS -DHAVE_MIR=1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mark_as_advanced (MIR_LIBRARY MIR_INCLUDE_DIR)
|
|
||||||
endif()
|
|
35
src/external/glfw/CMakeLists.txt
vendored
35
src/external/glfw/CMakeLists.txt
vendored
@ -4,7 +4,7 @@ project(GLFW C)
|
|||||||
|
|
||||||
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
||||||
|
|
||||||
if (NOT CMAKE_VERSION VERSION_LESS "3.1")
|
if (POLICY CMP0054)
|
||||||
cmake_policy(SET CMP0054 NEW)
|
cmake_policy(SET CMP0054 NEW)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -14,7 +14,6 @@ set(GLFW_VERSION_PATCH "0")
|
|||||||
set(GLFW_VERSION_EXTRA "")
|
set(GLFW_VERSION_EXTRA "")
|
||||||
set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}")
|
set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}")
|
||||||
set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA}")
|
set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA}")
|
||||||
set(LIB_SUFFIX "" CACHE STRING "Takes an empty string or 64. Directory where lib will be installed: lib or lib64")
|
|
||||||
|
|
||||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
@ -25,6 +24,8 @@ option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON)
|
|||||||
option(GLFW_INSTALL "Generate installation target" ON)
|
option(GLFW_INSTALL "Generate installation target" ON)
|
||||||
option(GLFW_VULKAN_STATIC "Use the Vulkan loader statically linked into application" OFF)
|
option(GLFW_VULKAN_STATIC "Use the Vulkan loader statically linked into application" OFF)
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
option(GLFW_USE_OSMESA "Use OSMesa for offscreen context creation" OFF)
|
option(GLFW_USE_OSMESA "Use OSMesa for offscreen context creation" OFF)
|
||||||
endif()
|
endif()
|
||||||
@ -35,7 +36,6 @@ endif()
|
|||||||
|
|
||||||
if (UNIX AND NOT APPLE)
|
if (UNIX AND NOT APPLE)
|
||||||
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
|
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
|
||||||
option(GLFW_USE_MIR "Use Mir for window creation" OFF)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
@ -141,9 +141,6 @@ endif()
|
|||||||
if (GLFW_USE_WAYLAND)
|
if (GLFW_USE_WAYLAND)
|
||||||
set(_GLFW_WAYLAND 1)
|
set(_GLFW_WAYLAND 1)
|
||||||
message(STATUS "Using Wayland for window creation")
|
message(STATUS "Using Wayland for window creation")
|
||||||
elseif (GLFW_USE_MIR)
|
|
||||||
set(_GLFW_MIR 1)
|
|
||||||
message(STATUS "Using Mir for window creation")
|
|
||||||
elseif (GLFW_USE_OSMESA)
|
elseif (GLFW_USE_OSMESA)
|
||||||
set(_GLFW_OSMESA 1)
|
set(_GLFW_OSMESA 1)
|
||||||
message(STATUS "Using OSMesa for headless context creation")
|
message(STATUS "Using OSMesa for headless context creation")
|
||||||
@ -262,7 +259,7 @@ if (_GLFW_WAYLAND)
|
|||||||
|
|
||||||
find_package(Wayland REQUIRED Client Cursor Egl)
|
find_package(Wayland REQUIRED Client Cursor Egl)
|
||||||
find_package(WaylandScanner REQUIRED)
|
find_package(WaylandScanner REQUIRED)
|
||||||
find_package(WaylandProtocols 1.12 REQUIRED)
|
find_package(WaylandProtocols 1.15 REQUIRED)
|
||||||
|
|
||||||
list(APPEND glfw_PKG_DEPS "wayland-egl")
|
list(APPEND glfw_PKG_DEPS "wayland-egl")
|
||||||
|
|
||||||
@ -273,7 +270,9 @@ if (_GLFW_WAYLAND)
|
|||||||
list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")
|
list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")
|
||||||
|
|
||||||
include(CheckIncludeFiles)
|
include(CheckIncludeFiles)
|
||||||
|
include(CheckFunctionExists)
|
||||||
check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H)
|
check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H)
|
||||||
|
check_function_exists(memfd_create HAVE_MEMFD_CREATE)
|
||||||
|
|
||||||
if (NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux"))
|
if (NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux"))
|
||||||
find_package(EpollShim)
|
find_package(EpollShim)
|
||||||
@ -284,22 +283,6 @@ if (_GLFW_WAYLAND)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
|
||||||
# Use Mir for window creation
|
|
||||||
#--------------------------------------------------------------------
|
|
||||||
if (_GLFW_MIR)
|
|
||||||
find_package(Mir REQUIRED)
|
|
||||||
list(APPEND glfw_PKG_DEPS "mirclient")
|
|
||||||
|
|
||||||
list(APPEND glfw_INCLUDE_DIRS "${MIR_INCLUDE_DIRS}")
|
|
||||||
list(APPEND glfw_LIBRARIES "${MIR_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}")
|
|
||||||
|
|
||||||
find_package(XKBCommon REQUIRED)
|
|
||||||
list(APPEND glfw_PKG_DEPS "xkbcommon")
|
|
||||||
list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")
|
|
||||||
list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Use OSMesa for offscreen context creation
|
# Use OSMesa for offscreen context creation
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
@ -340,7 +323,7 @@ endforeach()
|
|||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
set(GLFW_CONFIG_PATH "lib${LIB_SUFFIX}/cmake/glfw3")
|
set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_LIBDIR}/cmake/glfw3")
|
||||||
|
|
||||||
configure_package_config_file(src/glfw3Config.cmake.in
|
configure_package_config_file(src/glfw3Config.cmake.in
|
||||||
src/glfw3Config.cmake
|
src/glfw3Config.cmake
|
||||||
@ -377,7 +360,7 @@ endif()
|
|||||||
# The library is installed by src/CMakeLists.txt
|
# The library is installed by src/CMakeLists.txt
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
if (GLFW_INSTALL)
|
if (GLFW_INSTALL)
|
||||||
install(DIRECTORY include/GLFW DESTINATION include
|
install(DIRECTORY include/GLFW DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||||
FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h)
|
FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h)
|
||||||
|
|
||||||
install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake"
|
install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake"
|
||||||
@ -388,7 +371,7 @@ if (GLFW_INSTALL)
|
|||||||
EXPORT_LINK_INTERFACE_LIBRARIES
|
EXPORT_LINK_INTERFACE_LIBRARIES
|
||||||
DESTINATION "${GLFW_CONFIG_PATH}")
|
DESTINATION "${GLFW_CONFIG_PATH}")
|
||||||
install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc"
|
install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc"
|
||||||
DESTINATION "lib${LIB_SUFFIX}/pkgconfig")
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||||
|
|
||||||
# Only generate this target if no higher-level project already has
|
# Only generate this target if no higher-level project already has
|
||||||
if (NOT TARGET uninstall)
|
if (NOT TARGET uninstall)
|
||||||
|
25
src/external/glfw/README.md
vendored
25
src/external/glfw/README.md
vendored
@ -11,8 +11,8 @@ application development. It provides a simple, platform-independent API for
|
|||||||
creating windows, contexts and surfaces, reading input, handling events, etc.
|
creating windows, contexts and surfaces, reading input, handling events, etc.
|
||||||
|
|
||||||
GLFW natively supports Windows, macOS and Linux and other Unix-like systems.
|
GLFW natively supports Windows, macOS and Linux and other Unix-like systems.
|
||||||
Experimental implementations for the Wayland protocol and the Mir display server
|
An experimental implementation for the Wayland protocol is available but not
|
||||||
are available but not yet officially supported.
|
yet officially supported.
|
||||||
|
|
||||||
GLFW is licensed under the [zlib/libpng
|
GLFW is licensed under the [zlib/libpng
|
||||||
license](http://www.glfw.org/license.html).
|
license](http://www.glfw.org/license.html).
|
||||||
@ -167,6 +167,8 @@ information on what to include when reporting a bug.
|
|||||||
(#749,#842)
|
(#749,#842)
|
||||||
- Added `GLFW_FOCUS_ON_SHOW` window hint and attribute to control input focus
|
- Added `GLFW_FOCUS_ON_SHOW` window hint and attribute to control input focus
|
||||||
on calling show window (#1189)
|
on calling show window (#1189)
|
||||||
|
- Added `GLFW_SCALE_TO_MONITOR` window hint for automatic window resizing
|
||||||
|
(#676,#1115)
|
||||||
- Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889)
|
- Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889)
|
||||||
- Added `GLFW_LOCK_KEY_MODS` input mode and `GLFW_MOD_*_LOCK` mod bits (#946)
|
- Added `GLFW_LOCK_KEY_MODS` input mode and `GLFW_MOD_*_LOCK` mod bits (#946)
|
||||||
- Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint
|
- Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint
|
||||||
@ -180,6 +182,10 @@ information on what to include when reporting a bug.
|
|||||||
- Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with
|
- Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with
|
||||||
[OSMesa](https://www.mesa3d.org/osmesa.html) (#281)
|
[OSMesa](https://www.mesa3d.org/osmesa.html) (#281)
|
||||||
- Added `GenerateMappings.cmake` script for updating gamepad mappings
|
- Added `GenerateMappings.cmake` script for updating gamepad mappings
|
||||||
|
- Export CMake `GLFW_PKG_DEPS` and `GLFW_PKG_LIBS` to parent scope for use
|
||||||
|
in client pkg-configs (#1307)
|
||||||
|
- Added a `glfw_objlib` CMake OBJECT library target for embedding into static
|
||||||
|
libraries (#1307)
|
||||||
- Made `glfwCreateWindowSurface` emit an error when the window has a context
|
- Made `glfwCreateWindowSurface` emit an error when the window has a context
|
||||||
(#1194,#1205)
|
(#1194,#1205)
|
||||||
- Deprecated window parameter of clipboard string functions
|
- Deprecated window parameter of clipboard string functions
|
||||||
@ -195,6 +201,8 @@ information on what to include when reporting a bug.
|
|||||||
- Bugfix: Invalid library paths were used in test and example CMake files (#930)
|
- Bugfix: Invalid library paths were used in test and example CMake files (#930)
|
||||||
- Bugfix: The scancode for synthetic key release events was always zero
|
- Bugfix: The scancode for synthetic key release events was always zero
|
||||||
- Bugfix: The generated Doxyfile did not handle paths with spaces (#1081)
|
- Bugfix: The generated Doxyfile did not handle paths with spaces (#1081)
|
||||||
|
- Bugfix: The gamma ramp generated by `glfwSetGamma` did not use the monitor
|
||||||
|
ramp size (#1387,#1388)
|
||||||
- [Win32] Added system error strings to relevant GLFW error descriptions (#733)
|
- [Win32] Added system error strings to relevant GLFW error descriptions (#733)
|
||||||
- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125)
|
- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125)
|
||||||
- [Win32] Removed XInput circular deadzone from joystick axis data (#1045)
|
- [Win32] Removed XInput circular deadzone from joystick axis data (#1045)
|
||||||
@ -221,6 +229,10 @@ information on what to include when reporting a bug.
|
|||||||
- [Win32] Bugfix: The HID device notification was not unregistered (#1170)
|
- [Win32] Bugfix: The HID device notification was not unregistered (#1170)
|
||||||
- [Win32] Bugfix: `glfwCreateWindow` activated window even with `GLFW_FOCUSED`
|
- [Win32] Bugfix: `glfwCreateWindow` activated window even with `GLFW_FOCUSED`
|
||||||
hint set to false (#1179,#1180)
|
hint set to false (#1179,#1180)
|
||||||
|
- [Win32] Bugfix: The keypad equals key was reported as `GLFW_KEY_UNKNOWN`
|
||||||
|
(#1315,#1316)
|
||||||
|
- [Win32] Bugfix: A title bar would be drawn over undecorated windows in some
|
||||||
|
circumstances (#1383)
|
||||||
- [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125)
|
- [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125)
|
||||||
- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
|
- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
|
||||||
- [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X
|
- [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X
|
||||||
@ -235,6 +247,8 @@ information on what to include when reporting a bug.
|
|||||||
- [X11] Bugfix: Selection I/O reported but did not support `COMPOUND_TEXT`
|
- [X11] Bugfix: Selection I/O reported but did not support `COMPOUND_TEXT`
|
||||||
- [X11] Bugfix: Latin-1 text read from selections was not converted to UTF-8
|
- [X11] Bugfix: Latin-1 text read from selections was not converted to UTF-8
|
||||||
- [X11] Bugfix: NVidia EGL would segfault if unloaded before closing the display
|
- [X11] Bugfix: NVidia EGL would segfault if unloaded before closing the display
|
||||||
|
- [X11] Bugfix: Checking window maximized attrib could crash some WMs (#1356)
|
||||||
|
- [X11] Bugfix: Update cursor position on enter event (#1366)
|
||||||
- [Linux] Added workaround for missing `SYN_DROPPED` in pre-2.6.39 kernel
|
- [Linux] Added workaround for missing `SYN_DROPPED` in pre-2.6.39 kernel
|
||||||
headers (#1196)
|
headers (#1196)
|
||||||
- [Linux] Moved to evdev for joystick input (#906,#1005)
|
- [Linux] Moved to evdev for joystick input (#906,#1005)
|
||||||
@ -267,6 +281,9 @@ information on what to include when reporting a bug.
|
|||||||
- [Cocoa] Bugfix: Window was resized twice when entering full screen (#1085)
|
- [Cocoa] Bugfix: Window was resized twice when entering full screen (#1085)
|
||||||
- [Cocoa] Bugfix: Duplicate size events were not filtered (#1085)
|
- [Cocoa] Bugfix: Duplicate size events were not filtered (#1085)
|
||||||
- [Cocoa] Bugfix: Event polling did not initialize AppKit if necessary (#1218)
|
- [Cocoa] Bugfix: Event polling did not initialize AppKit if necessary (#1218)
|
||||||
|
- [Cocoa] Bugfix: OpenGL rendering was not initially visible on 10.14
|
||||||
|
(#1334,#1346)
|
||||||
|
- [Cocoa] Bugfix: Caps Lock did not generate any key events (#1368,#1373)
|
||||||
- [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts
|
- [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts
|
||||||
- [WGL] Added support for `WGL_ARB_create_context_no_error`
|
- [WGL] Added support for `WGL_ARB_create_context_no_error`
|
||||||
- [GLX] Added support for `GLX_ARB_create_context_no_error`
|
- [GLX] Added support for `GLX_ARB_create_context_no_error`
|
||||||
@ -304,7 +321,9 @@ skills.
|
|||||||
- David Avedissian
|
- David Avedissian
|
||||||
- Keith Bauer
|
- Keith Bauer
|
||||||
- John Bartholomew
|
- John Bartholomew
|
||||||
|
- Coşku Baş
|
||||||
- Niklas Behrens
|
- Niklas Behrens
|
||||||
|
- Andrew Belt
|
||||||
- Niklas Bergström
|
- Niklas Bergström
|
||||||
- Denis Bernard
|
- Denis Bernard
|
||||||
- Doug Binks
|
- Doug Binks
|
||||||
@ -371,6 +390,7 @@ skills.
|
|||||||
- Glenn Lewis
|
- Glenn Lewis
|
||||||
- Shane Liesegang
|
- Shane Liesegang
|
||||||
- Eyal Lotem
|
- Eyal Lotem
|
||||||
|
- Aaron Loucks
|
||||||
- Tristam MacDonald
|
- Tristam MacDonald
|
||||||
- Hans Mackowiak
|
- Hans Mackowiak
|
||||||
- Дмитри Малышев
|
- Дмитри Малышев
|
||||||
@ -387,6 +407,7 @@ skills.
|
|||||||
- Bruce Mitchener
|
- Bruce Mitchener
|
||||||
- Jack Moffitt
|
- Jack Moffitt
|
||||||
- Jeff Molofee
|
- Jeff Molofee
|
||||||
|
- Alexander Monakov
|
||||||
- Pierre Morel
|
- Pierre Morel
|
||||||
- Jon Morton
|
- Jon Morton
|
||||||
- Pierre Moulon
|
- Pierre Moulon
|
||||||
|
17420
src/external/glfw/deps/nuklear.h
vendored
17420
src/external/glfw/deps/nuklear.h
vendored
File diff suppressed because it is too large
Load Diff
6
src/external/glfw/deps/vulkan/vulkan.h
vendored
6
src/external/glfw/deps/vulkan/vulkan.h
vendored
@ -35,12 +35,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef VK_USE_PLATFORM_MIR_KHR
|
|
||||||
#include <mir_toolkit/client_types.h>
|
|
||||||
#include "vulkan_mir.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef VK_USE_PLATFORM_VI_NN
|
#ifdef VK_USE_PLATFORM_VI_NN
|
||||||
#include "vulkan_vi.h"
|
#include "vulkan_vi.h"
|
||||||
#endif
|
#endif
|
||||||
|
70
src/external/glfw/include/GLFW/glfw3.h
vendored
70
src/external/glfw/include/GLFW/glfw3.h
vendored
@ -269,23 +269,22 @@ extern "C" {
|
|||||||
#define GLFW_VERSION_REVISION 0
|
#define GLFW_VERSION_REVISION 0
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! @name Boolean values
|
|
||||||
* @{ */
|
|
||||||
/*! @brief One.
|
/*! @brief One.
|
||||||
*
|
*
|
||||||
* One. Seriously. You don't _need_ to use this symbol in your code. It's
|
* This is only semantic sugar for the number 1. You can instead use `1` or
|
||||||
* semantic sugar for the number 1. You can also use `1` or `true` or `_True`
|
* `true` or `_True` or `GL_TRUE` or anything else that is equal to one.
|
||||||
* or `GL_TRUE` or whatever you want.
|
*
|
||||||
|
* @ingroup init
|
||||||
*/
|
*/
|
||||||
#define GLFW_TRUE 1
|
#define GLFW_TRUE 1
|
||||||
/*! @brief Zero.
|
/*! @brief Zero.
|
||||||
*
|
*
|
||||||
* Zero. Seriously. You don't _need_ to use this symbol in your code. It's
|
* This is only semantic sugar for the number 0. You can instead use `0` or
|
||||||
* semantic sugar for the number 0. You can also use `0` or `false` or
|
* `false` or `_False` or `GL_FALSE` or anything else that is equal to zero.
|
||||||
* `_False` or `GL_FALSE` or whatever you want.
|
*
|
||||||
|
* @ingroup init
|
||||||
*/
|
*/
|
||||||
#define GLFW_FALSE 0
|
#define GLFW_FALSE 0
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/*! @name Key and button actions
|
/*! @name Key and button actions
|
||||||
* @{ */
|
* @{ */
|
||||||
@ -313,6 +312,7 @@ extern "C" {
|
|||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! @defgroup hat_state Joystick hat states
|
/*! @defgroup hat_state Joystick hat states
|
||||||
|
* @brief Joystick hat states.
|
||||||
*
|
*
|
||||||
* See [joystick hat input](@ref joystick_hat) for how these are used.
|
* See [joystick hat input](@ref joystick_hat) for how these are used.
|
||||||
*
|
*
|
||||||
@ -973,6 +973,10 @@ extern "C" {
|
|||||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_CONTEXT_CREATION_API 0x0002200B
|
#define GLFW_CONTEXT_CREATION_API 0x0002200B
|
||||||
|
/*! @brief Window content area scaling window
|
||||||
|
* [window hint](@ref GLFW_SCALE_TO_MONITOR).
|
||||||
|
*/
|
||||||
|
#define GLFW_SCALE_TO_MONITOR 0x0002200C
|
||||||
|
|
||||||
#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
|
#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
|
||||||
#define GLFW_COCOA_FRAME_NAME 0x00023002
|
#define GLFW_COCOA_FRAME_NAME 0x00023002
|
||||||
@ -1056,9 +1060,20 @@ extern "C" {
|
|||||||
|
|
||||||
/*! @addtogroup init
|
/*! @addtogroup init
|
||||||
* @{ */
|
* @{ */
|
||||||
|
/*! @brief Joystick hat buttons init hint.
|
||||||
|
*
|
||||||
|
* Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS)
|
||||||
|
*/
|
||||||
#define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001
|
#define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001
|
||||||
|
/*! @brief macOS specific init hint.
|
||||||
|
*
|
||||||
|
* macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES)
|
||||||
|
*/
|
||||||
#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001
|
#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001
|
||||||
|
/*! @brief macOS specific init hint.
|
||||||
|
*
|
||||||
|
* macOS specific [init hint](@ref GLFW_COCOA_MENUBAR)
|
||||||
|
*/
|
||||||
#define GLFW_COCOA_MENUBAR 0x00051002
|
#define GLFW_COCOA_MENUBAR 0x00051002
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
@ -1129,7 +1144,7 @@ typedef struct GLFWwindow GLFWwindow;
|
|||||||
*
|
*
|
||||||
* @since Added in version 3.1.
|
* @since Added in version 3.1.
|
||||||
*
|
*
|
||||||
* @ingroup cursor
|
* @ingroup input
|
||||||
*/
|
*/
|
||||||
typedef struct GLFWcursor GLFWcursor;
|
typedef struct GLFWcursor GLFWcursor;
|
||||||
|
|
||||||
@ -1567,6 +1582,8 @@ typedef struct GLFWgammaramp
|
|||||||
*
|
*
|
||||||
* @since Added in version 2.1.
|
* @since Added in version 2.1.
|
||||||
* @glfw3 Removed format and bytes-per-pixel members.
|
* @glfw3 Removed format and bytes-per-pixel members.
|
||||||
|
*
|
||||||
|
* @ingroup window
|
||||||
*/
|
*/
|
||||||
typedef struct GLFWimage
|
typedef struct GLFWimage
|
||||||
{
|
{
|
||||||
@ -1589,6 +1606,8 @@ typedef struct GLFWimage
|
|||||||
* @sa @ref glfwGetGamepadState
|
* @sa @ref glfwGetGamepadState
|
||||||
*
|
*
|
||||||
* @since Added in version 3.3.
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
*/
|
*/
|
||||||
typedef struct GLFWgamepadstate
|
typedef struct GLFWgamepadstate
|
||||||
{
|
{
|
||||||
@ -2137,9 +2156,9 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
|
|||||||
|
|
||||||
/*! @brief Generates a gamma ramp and sets it for the specified monitor.
|
/*! @brief Generates a gamma ramp and sets it for the specified monitor.
|
||||||
*
|
*
|
||||||
* This function generates a 256-element gamma ramp from the specified exponent
|
* This function generates an appropriately sized gamma ramp from the specified
|
||||||
* and then calls @ref glfwSetGammaRamp with it. The value must be a finite
|
* exponent and then calls @ref glfwSetGammaRamp with it. The value must be
|
||||||
* number greater than zero.
|
* a finite number greater than zero.
|
||||||
*
|
*
|
||||||
* The software controlled gamma ramp is applied _in addition_ to the hardware
|
* The software controlled gamma ramp is applied _in addition_ to the hardware
|
||||||
* gamma correction, which today is usually an approximation of sRGB gamma.
|
* gamma correction, which today is usually an approximation of sRGB gamma.
|
||||||
@ -2218,8 +2237,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
|
|||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_PLATFORM_ERROR.
|
||||||
*
|
*
|
||||||
* @remark Gamma ramp sizes other than 256 are not supported by all platforms
|
* @remark The size of the specified gamma ramp should match the size of the
|
||||||
* or graphics hardware.
|
* current ramp for that monitor.
|
||||||
*
|
*
|
||||||
* @remark @win32 The gamma ramp size must be 256.
|
* @remark @win32 The gamma ramp size must be 256.
|
||||||
*
|
*
|
||||||
@ -3758,6 +3777,9 @@ GLFWAPI void glfwWaitEvents(void);
|
|||||||
*
|
*
|
||||||
* @param[in] timeout The maximum amount of time, in seconds, to wait.
|
* @param[in] timeout The maximum amount of time, in seconds, to wait.
|
||||||
*
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
|
* GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
|
||||||
|
*
|
||||||
* @reentrancy This function must not be called from a callback.
|
* @reentrancy This function must not be called from a callback.
|
||||||
*
|
*
|
||||||
* @thread_safety This function must only be called from the main thread.
|
* @thread_safety This function must only be called from the main thread.
|
||||||
@ -4011,8 +4033,8 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
|
|||||||
* `GLFW_RELEASE`.
|
* `GLFW_RELEASE`.
|
||||||
*
|
*
|
||||||
* If the @ref GLFW_STICKY_MOUSE_BUTTONS input mode is enabled, this function
|
* If the @ref GLFW_STICKY_MOUSE_BUTTONS input mode is enabled, this function
|
||||||
* `GLFW_PRESS` the first time you call it for a mouse button that was pressed,
|
* returns `GLFW_PRESS` the first time you call it for a mouse button that was
|
||||||
* even if that mouse button has already been released.
|
* pressed, even if that mouse button has already been released.
|
||||||
*
|
*
|
||||||
* @param[in] window The desired window.
|
* @param[in] window The desired window.
|
||||||
* @param[in] button The desired [mouse button](@ref buttons).
|
* @param[in] button The desired [mouse button](@ref buttons).
|
||||||
@ -4283,9 +4305,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);
|
|||||||
* The character callback behaves as system text input normally does and will
|
* 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
|
* 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
|
* input on that platform, for example a Super (Command) key on macOS or Alt key
|
||||||
* on Windows. There is a
|
* on Windows.
|
||||||
* [character with modifiers callback](@ref glfwSetCharModsCallback) that
|
|
||||||
* receives these events.
|
|
||||||
*
|
*
|
||||||
* @param[in] window The window whose callback to set.
|
* @param[in] window The window whose callback to set.
|
||||||
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
|
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
|
||||||
@ -4581,7 +4601,7 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count);
|
|||||||
* Each element in the array is one of the following values:
|
* Each element in the array is one of the following values:
|
||||||
*
|
*
|
||||||
* Name | Value
|
* Name | Value
|
||||||
* --------------------- | --------------------------------
|
* ---- | -----
|
||||||
* `GLFW_HAT_CENTERED` | 0
|
* `GLFW_HAT_CENTERED` | 0
|
||||||
* `GLFW_HAT_UP` | 1
|
* `GLFW_HAT_UP` | 1
|
||||||
* `GLFW_HAT_RIGHT` | 2
|
* `GLFW_HAT_RIGHT` | 2
|
||||||
@ -4901,6 +4921,8 @@ GLFWAPI const char* glfwGetGamepadName(int jid);
|
|||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
* GLFW_INVALID_ENUM.
|
* GLFW_INVALID_ENUM.
|
||||||
*
|
*
|
||||||
|
* @thread_safety This function must only be called from the main thread.
|
||||||
|
*
|
||||||
* @sa @ref gamepad
|
* @sa @ref gamepad
|
||||||
* @sa @ref glfwUpdateGamepadMappings
|
* @sa @ref glfwUpdateGamepadMappings
|
||||||
* @sa @ref glfwJoystickIsGamepad
|
* @sa @ref glfwJoystickIsGamepad
|
||||||
@ -4922,8 +4944,6 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
|
|||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_PLATFORM_ERROR.
|
||||||
*
|
*
|
||||||
* @remark @wayland Clipboard is currently unimplemented.
|
|
||||||
*
|
|
||||||
* @pointer_lifetime The specified string is copied before this function
|
* @pointer_lifetime The specified string is copied before this function
|
||||||
* returns.
|
* returns.
|
||||||
*
|
*
|
||||||
@ -4952,8 +4972,6 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
|
|||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_PLATFORM_ERROR.
|
||||||
*
|
*
|
||||||
* @remark @wayland Clipboard is currently unimplemented.
|
|
||||||
*
|
|
||||||
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
|
* @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
|
* should not free it yourself. It is valid until the next call to @ref
|
||||||
* glfwGetClipboardString or @ref glfwSetClipboardString, or until the library
|
* glfwGetClipboardString or @ref glfwSetClipboardString, or until the library
|
||||||
|
59
src/external/glfw/include/GLFW/glfw3native.h
vendored
59
src/external/glfw/include/GLFW/glfw3native.h
vendored
@ -62,7 +62,6 @@ extern "C" {
|
|||||||
* * `GLFW_EXPOSE_NATIVE_COCOA`
|
* * `GLFW_EXPOSE_NATIVE_COCOA`
|
||||||
* * `GLFW_EXPOSE_NATIVE_X11`
|
* * `GLFW_EXPOSE_NATIVE_X11`
|
||||||
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
|
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
|
||||||
* * `GLFW_EXPOSE_NATIVE_MIR`
|
|
||||||
*
|
*
|
||||||
* The available context API macros are:
|
* The available context API macros are:
|
||||||
* * `GLFW_EXPOSE_NATIVE_WGL`
|
* * `GLFW_EXPOSE_NATIVE_WGL`
|
||||||
@ -82,7 +81,7 @@ extern "C" {
|
|||||||
* System headers and types
|
* System headers and types
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
|
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||||
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
||||||
// example to allow applications to correctly declare a GL_ARB_debug_output
|
// example to allow applications to correctly declare a GL_ARB_debug_output
|
||||||
// callback) but windows.h assumes no one will define APIENTRY before it does
|
// callback) but windows.h assumes no one will define APIENTRY before it does
|
||||||
@ -96,23 +95,19 @@ extern "C" {
|
|||||||
typedef void *PVOID;
|
typedef void *PVOID;
|
||||||
typedef PVOID HANDLE;
|
typedef PVOID HANDLE;
|
||||||
typedef HANDLE HWND;
|
typedef HANDLE HWND;
|
||||||
#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
|
#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
#if defined(__OBJC__)
|
#if defined(__OBJC__)
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#else
|
#else
|
||||||
// RAY: Added protection in case OBJC types defined
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
#if !OBJC_TYPES_DEFINED
|
typedef void* id;
|
||||||
typedef void* id;
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#elif defined(GLFW_EXPOSE_NATIVE_X11)
|
#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/extensions/Xrandr.h>
|
#include <X11/extensions/Xrandr.h>
|
||||||
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#elif defined(GLFW_EXPOSE_NATIVE_MIR)
|
|
||||||
#include <mir_toolkit/mir_client_library.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||||
@ -426,50 +421,6 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
|
|||||||
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_MIR)
|
|
||||||
/*! @brief Returns the `MirConnection*` used by GLFW.
|
|
||||||
*
|
|
||||||
* @return The `MirConnection*` used by GLFW, or `NULL` if an
|
|
||||||
* [error](@ref error_handling) occurred.
|
|
||||||
*
|
|
||||||
* @thread_safety This function may be called from any thread. Access is not
|
|
||||||
* synchronized.
|
|
||||||
*
|
|
||||||
* @since Added in version 3.2.
|
|
||||||
*
|
|
||||||
* @ingroup native
|
|
||||||
*/
|
|
||||||
GLFWAPI MirConnection* glfwGetMirDisplay(void);
|
|
||||||
|
|
||||||
/*! @brief Returns the Mir output ID of the specified monitor.
|
|
||||||
*
|
|
||||||
* @return The Mir output ID of the specified monitor, or zero if an
|
|
||||||
* [error](@ref error_handling) occurred.
|
|
||||||
*
|
|
||||||
* @thread_safety This function may be called from any thread. Access is not
|
|
||||||
* synchronized.
|
|
||||||
*
|
|
||||||
* @since Added in version 3.2.
|
|
||||||
*
|
|
||||||
* @ingroup native
|
|
||||||
*/
|
|
||||||
GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
|
|
||||||
|
|
||||||
/*! @brief Returns the `MirWindow*` of the specified window.
|
|
||||||
*
|
|
||||||
* @return The `MirWindow*` of the specified window, or `NULL` if an
|
|
||||||
* [error](@ref error_handling) occurred.
|
|
||||||
*
|
|
||||||
* @thread_safety This function may be called from any thread. Access is not
|
|
||||||
* synchronized.
|
|
||||||
*
|
|
||||||
* @since Added in version 3.2.
|
|
||||||
*
|
|
||||||
* @ingroup native
|
|
||||||
*/
|
|
||||||
GLFWAPI MirWindow* glfwGetMirWindow(GLFWwindow* window);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||||
/*! @brief Returns the `EGLDisplay` used by GLFW.
|
/*! @brief Returns the `EGLDisplay` used by GLFW.
|
||||||
*
|
*
|
||||||
|
23
src/external/glfw/src/CMakeLists.txt
vendored
23
src/external/glfw/src/CMakeLists.txt
vendored
@ -35,6 +35,10 @@ elseif (_GLFW_WAYLAND)
|
|||||||
PROTOCOL
|
PROTOCOL
|
||||||
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/xdg-shell/xdg-shell.xml"
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/xdg-shell/xdg-shell.xml"
|
||||||
BASENAME xdg-shell)
|
BASENAME xdg-shell)
|
||||||
|
ecm_add_wayland_client_protocol(glfw_SOURCES
|
||||||
|
PROTOCOL
|
||||||
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
|
||||||
|
BASENAME xdg-decoration)
|
||||||
ecm_add_wayland_client_protocol(glfw_SOURCES
|
ecm_add_wayland_client_protocol(glfw_SOURCES
|
||||||
PROTOCOL
|
PROTOCOL
|
||||||
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/viewporter/viewporter.xml"
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/viewporter/viewporter.xml"
|
||||||
@ -51,13 +55,6 @@ elseif (_GLFW_WAYLAND)
|
|||||||
PROTOCOL
|
PROTOCOL
|
||||||
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml"
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml"
|
||||||
BASENAME idle-inhibit-unstable-v1)
|
BASENAME idle-inhibit-unstable-v1)
|
||||||
elseif (_GLFW_MIR)
|
|
||||||
set(glfw_HEADERS ${common_HEADERS} mir_platform.h linux_joystick.h
|
|
||||||
posix_time.h posix_thread.h xkb_unicode.h egl_context.h
|
|
||||||
osmesa_context.h)
|
|
||||||
set(glfw_SOURCES ${common_SOURCES} mir_init.c mir_monitor.c mir_window.c
|
|
||||||
linux_joystick.c posix_time.c posix_thread.c xkb_unicode.c
|
|
||||||
egl_context.c osmesa_context.c)
|
|
||||||
elseif (_GLFW_OSMESA)
|
elseif (_GLFW_OSMESA)
|
||||||
set(glfw_HEADERS ${common_HEADERS} null_platform.h null_joystick.h
|
set(glfw_HEADERS ${common_HEADERS} null_platform.h null_joystick.h
|
||||||
posix_time.h posix_thread.h osmesa_context.h)
|
posix_time.h posix_thread.h osmesa_context.h)
|
||||||
@ -104,10 +101,10 @@ set_target_properties(glfw PROPERTIES
|
|||||||
target_compile_definitions(glfw_objlib PRIVATE _GLFW_USE_CONFIG_H)
|
target_compile_definitions(glfw_objlib PRIVATE _GLFW_USE_CONFIG_H)
|
||||||
target_include_directories(glfw_objlib PUBLIC
|
target_include_directories(glfw_objlib PUBLIC
|
||||||
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
|
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
|
||||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>")
|
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_FULL_INCLUDEDIR}>")
|
||||||
target_include_directories(glfw PUBLIC
|
target_include_directories(glfw PUBLIC
|
||||||
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
|
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
|
||||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>")
|
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_FULL_INCLUDEDIR}>")
|
||||||
target_include_directories(glfw_objlib PRIVATE
|
target_include_directories(glfw_objlib PRIVATE
|
||||||
"${GLFW_SOURCE_DIR}/src"
|
"${GLFW_SOURCE_DIR}/src"
|
||||||
"${GLFW_BINARY_DIR}/src"
|
"${GLFW_BINARY_DIR}/src"
|
||||||
@ -128,7 +125,7 @@ target_compile_options(glfw_objlib PRIVATE
|
|||||||
if (BUILD_SHARED_LIBS)
|
if (BUILD_SHARED_LIBS)
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
# Remove the lib prefix on the DLL (but not the import library
|
# Remove the lib prefix on the DLL (but not the import library)
|
||||||
set_target_properties(glfw PROPERTIES PREFIX "")
|
set_target_properties(glfw PROPERTIES PREFIX "")
|
||||||
|
|
||||||
# Add a suffix to the import library to avoid naming conflicts
|
# Add a suffix to the import library to avoid naming conflicts
|
||||||
@ -142,7 +139,7 @@ if (BUILD_SHARED_LIBS)
|
|||||||
target_compile_options(glfw_objlib PRIVATE "-fno-common")
|
target_compile_options(glfw_objlib PRIVATE "-fno-common")
|
||||||
|
|
||||||
set_target_properties(glfw PROPERTIES
|
set_target_properties(glfw PROPERTIES
|
||||||
INSTALL_NAME_DIR "lib${LIB_SUFFIX}")
|
INSTALL_NAME_DIR "${CMAKE_INSTALL_LIBDIR}")
|
||||||
elseif (UNIX)
|
elseif (UNIX)
|
||||||
# Hide symbols not explicitly tagged for export from the shared library
|
# Hide symbols not explicitly tagged for export from the shared library
|
||||||
target_compile_options(glfw_objlib PRIVATE "-fvisibility=hidden")
|
target_compile_options(glfw_objlib PRIVATE "-fvisibility=hidden")
|
||||||
@ -162,7 +159,7 @@ if (GLFW_INSTALL)
|
|||||||
install(TARGETS glfw
|
install(TARGETS glfw
|
||||||
EXPORT glfwTargets
|
EXPORT glfwTargets
|
||||||
RUNTIME DESTINATION "bin"
|
RUNTIME DESTINATION "bin"
|
||||||
ARCHIVE DESTINATION "lib${LIB_SUFFIX}"
|
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||||
LIBRARY DESTINATION "lib${LIB_SUFFIX}")
|
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
49
src/external/glfw/src/cocoa_init.m
vendored
49
src/external/glfw/src/cocoa_init.m
vendored
@ -27,6 +27,10 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <sys/param.h> // For MAXPATHLEN
|
#include <sys/param.h> // For MAXPATHLEN
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
|
||||||
|
#define NSEventMaskKeyUp NSKeyUpMask
|
||||||
|
#define NSEventModifierFlagCommand NSCommandKeyMask
|
||||||
|
#endif
|
||||||
|
|
||||||
// Change to our application bundle's resources directory, if present
|
// Change to our application bundle's resources directory, if present
|
||||||
//
|
//
|
||||||
@ -271,17 +275,21 @@ static GLFWbool initializeTIS(void)
|
|||||||
return updateUnicodeDataNS();
|
return updateUnicodeDataNS();
|
||||||
}
|
}
|
||||||
|
|
||||||
@interface GLFWLayoutListener : NSObject
|
@interface GLFWHelper : NSObject
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation GLFWLayoutListener
|
@implementation GLFWHelper
|
||||||
|
|
||||||
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object
|
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object
|
||||||
{
|
{
|
||||||
updateUnicodeDataNS();
|
updateUnicodeDataNS();
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
- (void)doNothing:(id)object
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@end // GLFWHelper
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -291,13 +299,31 @@ static GLFWbool initializeTIS(void)
|
|||||||
int _glfwPlatformInit(void)
|
int _glfwPlatformInit(void)
|
||||||
{
|
{
|
||||||
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
|
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
|
||||||
|
_glfw.ns.helper = [[GLFWHelper alloc] init];
|
||||||
|
|
||||||
|
[NSThread detachNewThreadSelector:@selector(doNothing:)
|
||||||
|
toTarget:_glfw.ns.helper
|
||||||
|
withObject:nil];
|
||||||
|
|
||||||
|
[NSApplication sharedApplication];
|
||||||
|
|
||||||
|
NSEvent* (^block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
|
||||||
|
{
|
||||||
|
if ([event modifierFlags] & NSEventModifierFlagCommand)
|
||||||
|
[[NSApp keyWindow] sendEvent:event];
|
||||||
|
|
||||||
|
return event;
|
||||||
|
};
|
||||||
|
|
||||||
|
_glfw.ns.keyUpMonitor =
|
||||||
|
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyUp
|
||||||
|
handler:block];
|
||||||
|
|
||||||
if (_glfw.hints.init.ns.chdir)
|
if (_glfw.hints.init.ns.chdir)
|
||||||
changeToResourcesDirectory();
|
changeToResourcesDirectory();
|
||||||
|
|
||||||
_glfw.ns.listener = [[GLFWLayoutListener alloc] init];
|
|
||||||
[[NSNotificationCenter defaultCenter]
|
[[NSNotificationCenter defaultCenter]
|
||||||
addObserver:_glfw.ns.listener
|
addObserver:_glfw.ns.helper
|
||||||
selector:@selector(selectedKeyboardInputSourceChanged:)
|
selector:@selector(selectedKeyboardInputSourceChanged:)
|
||||||
name:NSTextInputContextKeyboardSelectionDidChangeNotification
|
name:NSTextInputContextKeyboardSelectionDidChangeNotification
|
||||||
object:nil];
|
object:nil];
|
||||||
@ -342,18 +368,21 @@ void _glfwPlatformTerminate(void)
|
|||||||
_glfw.ns.delegate = nil;
|
_glfw.ns.delegate = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_glfw.ns.listener)
|
if (_glfw.ns.helper)
|
||||||
{
|
{
|
||||||
[[NSNotificationCenter defaultCenter]
|
[[NSNotificationCenter defaultCenter]
|
||||||
removeObserver:_glfw.ns.listener
|
removeObserver:_glfw.ns.helper
|
||||||
name:NSTextInputContextKeyboardSelectionDidChangeNotification
|
name:NSTextInputContextKeyboardSelectionDidChangeNotification
|
||||||
object:nil];
|
object:nil];
|
||||||
[[NSNotificationCenter defaultCenter]
|
[[NSNotificationCenter defaultCenter]
|
||||||
removeObserver:_glfw.ns.listener];
|
removeObserver:_glfw.ns.helper];
|
||||||
[_glfw.ns.listener release];
|
[_glfw.ns.helper release];
|
||||||
_glfw.ns.listener = nil;
|
_glfw.ns.helper = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_glfw.ns.keyUpMonitor)
|
||||||
|
[NSEvent removeMonitor:_glfw.ns.keyUpMonitor];
|
||||||
|
|
||||||
free(_glfw.ns.clipboardString);
|
free(_glfw.ns.clipboardString);
|
||||||
|
|
||||||
_glfwTerminateNSGL();
|
_glfwTerminateNSGL();
|
||||||
|
3
src/external/glfw/src/cocoa_monitor.m
vendored
3
src/external/glfw/src/cocoa_monitor.m
vendored
@ -467,7 +467,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
|
|||||||
CVDisplayLinkRelease(link);
|
CVDisplayLinkRelease(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
{
|
{
|
||||||
uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
|
uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
|
||||||
CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue));
|
CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue));
|
||||||
@ -489,6 +489,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(values);
|
free(values);
|
||||||
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||||
|
8
src/external/glfw/src/cocoa_platform.h
vendored
8
src/external/glfw/src/cocoa_platform.h
vendored
@ -27,12 +27,10 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include <Carbon/Carbon.h>
|
||||||
#if defined(__OBJC__)
|
#if defined(__OBJC__)
|
||||||
#import <Carbon/Carbon.h>
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#else
|
#else
|
||||||
#include <Carbon/Carbon.h>
|
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
|
||||||
typedef void* id;
|
typedef void* id;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -111,7 +109,9 @@ typedef struct _GLFWlibraryNS
|
|||||||
TISInputSourceRef inputSource;
|
TISInputSourceRef inputSource;
|
||||||
IOHIDManagerRef hidManager;
|
IOHIDManagerRef hidManager;
|
||||||
id unicodeData;
|
id unicodeData;
|
||||||
id listener;
|
id helper;
|
||||||
|
id keyUpMonitor;
|
||||||
|
id nibObjects;
|
||||||
|
|
||||||
char keyName[64];
|
char keyName[64];
|
||||||
short int keycodes[256];
|
short int keycodes[256];
|
||||||
|
188
src/external/glfw/src/cocoa_window.m
vendored
188
src/external/glfw/src/cocoa_window.m
vendored
@ -32,7 +32,6 @@
|
|||||||
// Needed for _NSGetProgname
|
// Needed for _NSGetProgname
|
||||||
#include <crt_externs.h>
|
#include <crt_externs.h>
|
||||||
|
|
||||||
// HACK: The 10.12 SDK adds new symbols and immediately deprecates the old ones
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
|
||||||
#define NSWindowStyleMaskBorderless NSBorderlessWindowMask
|
#define NSWindowStyleMaskBorderless NSBorderlessWindowMask
|
||||||
#define NSWindowStyleMaskClosable NSClosableWindowMask
|
#define NSWindowStyleMaskClosable NSClosableWindowMask
|
||||||
@ -47,10 +46,9 @@
|
|||||||
#define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask
|
#define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask
|
||||||
#define NSEventMaskAny NSAnyEventMask
|
#define NSEventMaskAny NSAnyEventMask
|
||||||
#define NSEventTypeApplicationDefined NSApplicationDefined
|
#define NSEventTypeApplicationDefined NSApplicationDefined
|
||||||
#define NSEventTypeKeyUp NSKeyUp
|
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Returns the style mask corresponding to the window settings
|
// Returns the style mask corresponding to the window settings
|
||||||
//
|
//
|
||||||
static NSUInteger getStyleMask(_GLFWwindow* window)
|
static NSUInteger getStyleMask(_GLFWwindow* window)
|
||||||
@ -237,6 +235,8 @@ static NSUInteger translateKeyToModifierFlag(int key)
|
|||||||
case GLFW_KEY_LEFT_SUPER:
|
case GLFW_KEY_LEFT_SUPER:
|
||||||
case GLFW_KEY_RIGHT_SUPER:
|
case GLFW_KEY_RIGHT_SUPER:
|
||||||
return NSEventModifierFlagCommand;
|
return NSEventModifierFlagCommand;
|
||||||
|
case GLFW_KEY_CAPS_LOCK:
|
||||||
|
return NSEventModifierFlagCapsLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -365,7 +365,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
// Delegate for application related notifications
|
// Delegate for application related notifications
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
@interface GLFWApplicationDelegate : NSObject
|
@interface GLFWApplicationDelegate : NSObject <NSApplicationDelegate>
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation GLFWApplicationDelegate
|
@implementation GLFWApplicationDelegate
|
||||||
@ -438,8 +438,9 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
markedText = [[NSMutableAttributedString alloc] init];
|
markedText = [[NSMutableAttributedString alloc] init];
|
||||||
|
|
||||||
[self updateTrackingAreas];
|
[self updateTrackingAreas];
|
||||||
[self registerForDraggedTypes:[NSArray arrayWithObjects:
|
// NOTE: kUTTypeURL corresponds to NSPasteboardTypeURL but is available
|
||||||
NSFilenamesPboardType, nil]];
|
// on 10.7 without having been deprecated yet
|
||||||
|
[self registerForDraggedTypes:@[(__bridge NSString*) kUTTypeURL]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@ -472,6 +473,14 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)updateLayer
|
||||||
|
{
|
||||||
|
if (window->context.client != GLFW_NO_API)
|
||||||
|
[window->context.nsgl.object update];
|
||||||
|
|
||||||
|
_glfwInputWindowDamage(window);
|
||||||
|
}
|
||||||
|
|
||||||
- (id)makeBackingLayer
|
- (id)makeBackingLayer
|
||||||
{
|
{
|
||||||
if (window->ns.layer)
|
if (window->ns.layer)
|
||||||
@ -485,6 +494,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
updateCursorImage(window);
|
updateCursorImage(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)acceptsFirstMouse:(NSEvent *)event
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)mouseDown:(NSEvent *)event
|
- (void)mouseDown:(NSEvent *)event
|
||||||
{
|
{
|
||||||
_glfwInputMouseClick(window,
|
_glfwInputMouseClick(window,
|
||||||
@ -650,7 +664,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
|
|
||||||
_glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);
|
_glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);
|
||||||
|
|
||||||
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
|
[self interpretKeyEvents:@[event]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flagsChanged:(NSEvent *)event
|
- (void)flagsChanged:(NSEvent *)event
|
||||||
@ -701,45 +715,33 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
|
|
||||||
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
if ((NSDragOperationGeneric & [sender draggingSourceOperationMask])
|
// HACK: We don't know what to say here because we don't know what the
|
||||||
== NSDragOperationGeneric)
|
// application wants to do with the paths
|
||||||
{
|
return NSDragOperationGeneric;
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
return NSDragOperationGeneric;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NSDragOperationNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
|
|
||||||
{
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
return YES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
NSPasteboard* pasteboard = [sender draggingPasteboard];
|
|
||||||
NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType];
|
|
||||||
|
|
||||||
const NSRect contentRect = [window->ns.view frame];
|
const NSRect contentRect = [window->ns.view frame];
|
||||||
_glfwInputCursorPos(window,
|
_glfwInputCursorPos(window,
|
||||||
[sender draggingLocation].x,
|
[sender draggingLocation].x,
|
||||||
contentRect.size.height - [sender draggingLocation].y);
|
contentRect.size.height - [sender draggingLocation].y);
|
||||||
|
|
||||||
const NSUInteger count = [files count];
|
NSPasteboard* pasteboard = [sender draggingPasteboard];
|
||||||
|
NSDictionary* options = @{NSPasteboardURLReadingFileURLsOnlyKey:@YES};
|
||||||
|
NSArray* urls = [pasteboard readObjectsForClasses:@[[NSURL class]]
|
||||||
|
options:options];
|
||||||
|
const NSUInteger count = [urls count];
|
||||||
if (count)
|
if (count)
|
||||||
{
|
{
|
||||||
NSEnumerator* e = [files objectEnumerator];
|
|
||||||
char** paths = calloc(count, sizeof(char*));
|
char** paths = calloc(count, sizeof(char*));
|
||||||
NSUInteger i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (NSUInteger i = 0; i < count; i++)
|
||||||
paths[i] = _glfw_strdup([[e nextObject] UTF8String]);
|
paths[i] = _glfw_strdup([[urls objectAtIndex:i] fileSystemRepresentation]);
|
||||||
|
|
||||||
_glfwInputDrop(window, (int) count, (const char**) paths);
|
_glfwInputDrop(window, (int) count, (const char**) paths);
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (NSUInteger i = 0; i < count; i++)
|
||||||
free(paths[i]);
|
free(paths[i]);
|
||||||
free(paths);
|
free(paths);
|
||||||
}
|
}
|
||||||
@ -747,11 +749,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
|
|
||||||
{
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)hasMarkedText
|
- (BOOL)hasMarkedText
|
||||||
{
|
{
|
||||||
return [markedText length] > 0;
|
return [markedText length] > 0;
|
||||||
@ -865,52 +862,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// GLFW application class
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@interface GLFWApplication : NSApplication
|
|
||||||
{
|
|
||||||
NSArray* nibObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation GLFWApplication
|
|
||||||
|
|
||||||
// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost
|
|
||||||
// This works around an AppKit bug, where key up events while holding
|
|
||||||
// down the command key don't get sent to the key window.
|
|
||||||
- (void)sendEvent:(NSEvent *)event
|
|
||||||
{
|
|
||||||
if ([event type] == NSEventTypeKeyUp &&
|
|
||||||
([event modifierFlags] & NSEventModifierFlagCommand))
|
|
||||||
{
|
|
||||||
[[self keyWindow] sendEvent:event];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
[super sendEvent:event];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// No-op thread entry point
|
|
||||||
//
|
|
||||||
- (void)doNothing:(id)object
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)loadMainMenu
|
|
||||||
{
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
|
||||||
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
|
|
||||||
owner:NSApp
|
|
||||||
topLevelObjects:&nibObjects];
|
|
||||||
#else
|
|
||||||
[[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
// Set up the menu bar (manually)
|
// Set up the menu bar (manually)
|
||||||
// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
|
// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
|
||||||
// could go away at any moment, lots of stuff that really should be
|
// could go away at any moment, lots of stuff that really should be
|
||||||
@ -1020,32 +971,9 @@ static void createMenuBar(void)
|
|||||||
//
|
//
|
||||||
static GLFWbool initializeAppKit(void)
|
static GLFWbool initializeAppKit(void)
|
||||||
{
|
{
|
||||||
if (NSApp)
|
if (_glfw.ns.delegate)
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
|
|
||||||
// Implicitly create shared NSApplication instance
|
|
||||||
[GLFWApplication sharedApplication];
|
|
||||||
|
|
||||||
// Make Cocoa enter multi-threaded mode
|
|
||||||
[NSThread detachNewThreadSelector:@selector(doNothing:)
|
|
||||||
toTarget:NSApp
|
|
||||||
withObject:nil];
|
|
||||||
|
|
||||||
if (_glfw.hints.init.ns.menubar)
|
|
||||||
{
|
|
||||||
// In case we are unbundled, make us a proper UI application
|
|
||||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
|
||||||
|
|
||||||
// Menu bar setup must go between sharedApplication above and
|
|
||||||
// finishLaunching below, in order to properly emulate the behavior
|
|
||||||
// of NSApplicationMain
|
|
||||||
|
|
||||||
if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
|
|
||||||
[NSApp loadMainMenu];
|
|
||||||
else
|
|
||||||
createMenuBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
// There can only be one application delegate, but we allocate it the
|
// There can only be one application delegate, but we allocate it the
|
||||||
// first time a window is created to keep all window code in this file
|
// first time a window is created to keep all window code in this file
|
||||||
_glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init];
|
_glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init];
|
||||||
@ -1057,13 +985,34 @@ static GLFWbool initializeAppKit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
[NSApp setDelegate:_glfw.ns.delegate];
|
[NSApp setDelegate:_glfw.ns.delegate];
|
||||||
|
|
||||||
|
if (_glfw.hints.init.ns.menubar)
|
||||||
|
{
|
||||||
|
// In case we are unbundled, make us a proper UI application
|
||||||
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
|
|
||||||
|
// Menu bar setup must go between sharedApplication above and
|
||||||
|
// finishLaunching below, in order to properly emulate the behavior
|
||||||
|
// of NSApplicationMain
|
||||||
|
|
||||||
|
if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
|
||||||
|
{
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||||
|
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
|
||||||
|
owner:NSApp
|
||||||
|
topLevelObjects:&_glfw.ns.nibObjects];
|
||||||
|
#else
|
||||||
|
[[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
createMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
[NSApp run];
|
[NSApp run];
|
||||||
|
|
||||||
// Press and Hold prevents some keys from emitting repeated characters
|
// Press and Hold prevents some keys from emitting repeated characters
|
||||||
NSDictionary* defaults =
|
NSDictionary* defaults = @{@"ApplePressAndHoldEnabled":@NO};
|
||||||
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],
|
|
||||||
@"ApplePressAndHoldEnabled",
|
|
||||||
nil];
|
|
||||||
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
|
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
@ -1563,9 +1512,6 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
|||||||
|
|
||||||
void _glfwPlatformPollEvents(void)
|
void _glfwPlatformPollEvents(void)
|
||||||
{
|
{
|
||||||
if (!initializeAppKit())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
|
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
|
||||||
@ -1716,9 +1662,6 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
NSImage* native;
|
NSImage* native;
|
||||||
NSBitmapImageRep* rep;
|
NSBitmapImageRep* rep;
|
||||||
|
|
||||||
if (!initializeAppKit())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
rep = [[NSBitmapImageRep alloc]
|
rep = [[NSBitmapImageRep alloc]
|
||||||
initWithBitmapDataPlanes:NULL
|
initWithBitmapDataPlanes:NULL
|
||||||
pixelsWide:image->width
|
pixelsWide:image->width
|
||||||
@ -1728,7 +1671,7 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
hasAlpha:YES
|
hasAlpha:YES
|
||||||
isPlanar:NO
|
isPlanar:NO
|
||||||
colorSpaceName:NSCalibratedRGBColorSpace
|
colorSpaceName:NSCalibratedRGBColorSpace
|
||||||
bitmapFormat:NSAlphaNonpremultipliedBitmapFormat
|
bitmapFormat:NSBitmapFormatAlphaNonpremultiplied
|
||||||
bytesPerRow:image->width * 4
|
bytesPerRow:image->width * 4
|
||||||
bitsPerPixel:32];
|
bitsPerPixel:32];
|
||||||
|
|
||||||
@ -1754,9 +1697,6 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
|
|
||||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||||
{
|
{
|
||||||
if (!initializeAppKit())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
if (shape == GLFW_ARROW_CURSOR)
|
if (shape == GLFW_ARROW_CURSOR)
|
||||||
cursor->ns.object = [NSCursor arrowCursor];
|
cursor->ns.object = [NSCursor arrowCursor];
|
||||||
else if (shape == GLFW_IBEAM_CURSOR)
|
else if (shape == GLFW_IBEAM_CURSOR)
|
||||||
@ -1795,26 +1735,24 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
|||||||
|
|
||||||
void _glfwPlatformSetClipboardString(const char* string)
|
void _glfwPlatformSetClipboardString(const char* string)
|
||||||
{
|
{
|
||||||
NSArray* types = [NSArray arrayWithObjects:NSStringPboardType, nil];
|
|
||||||
|
|
||||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||||
[pasteboard declareTypes:types owner:nil];
|
[pasteboard declareTypes:@[NSPasteboardTypeString] owner:nil];
|
||||||
[pasteboard setString:[NSString stringWithUTF8String:string]
|
[pasteboard setString:[NSString stringWithUTF8String:string]
|
||||||
forType:NSStringPboardType];
|
forType:NSPasteboardTypeString];
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetClipboardString(void)
|
const char* _glfwPlatformGetClipboardString(void)
|
||||||
{
|
{
|
||||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||||
|
|
||||||
if (![[pasteboard types] containsObject:NSStringPboardType])
|
if (![[pasteboard types] containsObject:NSPasteboardTypeString])
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
"Cocoa: Failed to retrieve string from pasteboard");
|
"Cocoa: Failed to retrieve string from pasteboard");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString* object = [pasteboard stringForType:NSStringPboardType];
|
NSString* object = [pasteboard stringForType:NSPasteboardTypeString];
|
||||||
if (!object)
|
if (!object)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
4
src/external/glfw/src/egl_context.h
vendored
4
src/external/glfw/src/egl_context.h
vendored
@ -43,10 +43,6 @@ typedef Window EGLNativeWindowType;
|
|||||||
#define EGLAPIENTRY
|
#define EGLAPIENTRY
|
||||||
typedef struct wl_display* EGLNativeDisplayType;
|
typedef struct wl_display* EGLNativeDisplayType;
|
||||||
typedef struct wl_egl_window* EGLNativeWindowType;
|
typedef struct wl_egl_window* EGLNativeWindowType;
|
||||||
#elif defined(_GLFW_MIR)
|
|
||||||
#define EGLAPIENTRY
|
|
||||||
typedef MirEGLNativeDisplayType EGLNativeDisplayType;
|
|
||||||
typedef MirEGLNativeWindowType EGLNativeWindowType;
|
|
||||||
#else
|
#else
|
||||||
#error "No supported EGL platform selected"
|
#error "No supported EGL platform selected"
|
||||||
#endif
|
#endif
|
||||||
|
6
src/external/glfw/src/glfw3.pc.in
vendored
6
src/external/glfw/src/glfw3.pc.in
vendored
@ -1,12 +1,12 @@
|
|||||||
prefix=@CMAKE_INSTALL_PREFIX@
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
exec_prefix=${prefix}
|
exec_prefix=${prefix}
|
||||||
includedir=${prefix}/include
|
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||||
libdir=${exec_prefix}/lib@LIB_SUFFIX@
|
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||||
|
|
||||||
Name: GLFW
|
Name: GLFW
|
||||||
Description: A multi-platform library for OpenGL, window and input
|
Description: A multi-platform library for OpenGL, window and input
|
||||||
Version: @GLFW_VERSION_FULL@
|
Version: @GLFW_VERSION_FULL@
|
||||||
URL: http://www.glfw.org/
|
URL: https://www.glfw.org/
|
||||||
Requires.private: @GLFW_PKG_DEPS@
|
Requires.private: @GLFW_PKG_DEPS@
|
||||||
Libs: -L${libdir} -l@GLFW_LIB_NAME@
|
Libs: -L${libdir} -l@GLFW_LIB_NAME@
|
||||||
Libs.private: @GLFW_PKG_LIBS@
|
Libs.private: @GLFW_PKG_LIBS@
|
||||||
|
4
src/external/glfw/src/glfw_config.h.in
vendored
4
src/external/glfw/src/glfw_config.h.in
vendored
@ -42,8 +42,6 @@
|
|||||||
#cmakedefine _GLFW_COCOA
|
#cmakedefine _GLFW_COCOA
|
||||||
// Define this to 1 if building GLFW for Wayland
|
// Define this to 1 if building GLFW for Wayland
|
||||||
#cmakedefine _GLFW_WAYLAND
|
#cmakedefine _GLFW_WAYLAND
|
||||||
// Define this to 1 if building GLFW for Mir
|
|
||||||
#cmakedefine _GLFW_MIR
|
|
||||||
// Define this to 1 if building GLFW for OSMesa
|
// Define this to 1 if building GLFW for OSMesa
|
||||||
#cmakedefine _GLFW_OSMESA
|
#cmakedefine _GLFW_OSMESA
|
||||||
|
|
||||||
@ -57,4 +55,6 @@
|
|||||||
|
|
||||||
// Define this to 1 if xkbcommon supports the compose key
|
// Define this to 1 if xkbcommon supports the compose key
|
||||||
#cmakedefine HAVE_XKBCOMMON_COMPOSE_H
|
#cmakedefine HAVE_XKBCOMMON_COMPOSE_H
|
||||||
|
// Define this to 1 if the libc supports memfd_create()
|
||||||
|
#cmakedefine HAVE_MEMFD_CREATE
|
||||||
|
|
||||||
|
24
src/external/glfw/src/init.c
vendored
24
src/external/glfw/src/init.c
vendored
@ -119,6 +119,30 @@ char* _glfw_strdup(const char* source)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float _glfw_fminf(float a, float b)
|
||||||
|
{
|
||||||
|
if (a != a)
|
||||||
|
return b;
|
||||||
|
else if (b != b)
|
||||||
|
return a;
|
||||||
|
else if (a < b)
|
||||||
|
return a;
|
||||||
|
else
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
float _glfw_fmaxf(float a, float b)
|
||||||
|
{
|
||||||
|
if (a != a)
|
||||||
|
return b;
|
||||||
|
else if (b != b)
|
||||||
|
return a;
|
||||||
|
else if (a > b)
|
||||||
|
return a;
|
||||||
|
else
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW event API //////
|
////// GLFW event API //////
|
||||||
|
2
src/external/glfw/src/input.c
vendored
2
src/external/glfw/src/input.c
vendored
@ -1242,7 +1242,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
|
|||||||
if (e->type == _GLFW_JOYSTICK_AXIS)
|
if (e->type == _GLFW_JOYSTICK_AXIS)
|
||||||
{
|
{
|
||||||
const float value = js->axes[e->index] * e->axisScale + e->axisOffset;
|
const float value = js->axes[e->index] * e->axisScale + e->axisOffset;
|
||||||
state->axes[i] = fminf(fmaxf(value, -1.f), 1.f);
|
state->axes[i] = _glfw_fminf(_glfw_fmaxf(value, -1.f), 1.f);
|
||||||
}
|
}
|
||||||
else if (e->type == _GLFW_JOYSTICK_HATBIT)
|
else if (e->type == _GLFW_JOYSTICK_HATBIT)
|
||||||
{
|
{
|
||||||
|
10
src/external/glfw/src/internal.h
vendored
10
src/external/glfw/src/internal.h
vendored
@ -126,7 +126,6 @@ typedef enum VkStructureType
|
|||||||
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
|
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
|
||||||
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
|
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
|
||||||
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
|
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
|
||||||
VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000,
|
|
||||||
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
|
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
|
||||||
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
|
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
|
||||||
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
|
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
|
||||||
@ -188,8 +187,6 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
|||||||
#include "x11_platform.h"
|
#include "x11_platform.h"
|
||||||
#elif defined(_GLFW_WAYLAND)
|
#elif defined(_GLFW_WAYLAND)
|
||||||
#include "wl_platform.h"
|
#include "wl_platform.h"
|
||||||
#elif defined(_GLFW_MIR)
|
|
||||||
#include "mir_platform.h"
|
|
||||||
#elif defined(_GLFW_OSMESA)
|
#elif defined(_GLFW_OSMESA)
|
||||||
#include "null_platform.h"
|
#include "null_platform.h"
|
||||||
#else
|
#else
|
||||||
@ -268,6 +265,7 @@ struct _GLFWwndconfig
|
|||||||
GLFWbool maximized;
|
GLFWbool maximized;
|
||||||
GLFWbool centerCursor;
|
GLFWbool centerCursor;
|
||||||
GLFWbool focusOnShow;
|
GLFWbool focusOnShow;
|
||||||
|
GLFWbool scaleToMonitor;
|
||||||
struct {
|
struct {
|
||||||
GLFWbool retina;
|
GLFWbool retina;
|
||||||
char frameName[256];
|
char frameName[256];
|
||||||
@ -562,8 +560,6 @@ struct _GLFWlibrary
|
|||||||
GLFWbool KHR_xcb_surface;
|
GLFWbool KHR_xcb_surface;
|
||||||
#elif defined(_GLFW_WAYLAND)
|
#elif defined(_GLFW_WAYLAND)
|
||||||
GLFWbool KHR_wayland_surface;
|
GLFWbool KHR_wayland_surface;
|
||||||
#elif defined(_GLFW_MIR)
|
|
||||||
GLFWbool KHR_mir_surface;
|
|
||||||
#endif
|
#endif
|
||||||
} vk;
|
} vk;
|
||||||
|
|
||||||
@ -615,7 +611,7 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
|||||||
float* xscale, float* yscale);
|
float* xscale, float* yscale);
|
||||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
|
||||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
|
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
|
||||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
||||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
||||||
|
|
||||||
void _glfwPlatformSetClipboardString(const char* string);
|
void _glfwPlatformSetClipboardString(const char* string);
|
||||||
@ -770,4 +766,6 @@ void _glfwTerminateVulkan(void);
|
|||||||
const char* _glfwGetVulkanResultString(VkResult result);
|
const char* _glfwGetVulkanResultString(VkResult result);
|
||||||
|
|
||||||
char* _glfw_strdup(const char* source);
|
char* _glfw_strdup(const char* source);
|
||||||
|
float _glfw_fminf(float a, float b);
|
||||||
|
float _glfw_fmaxf(float a, float b);
|
||||||
|
|
||||||
|
2
src/external/glfw/src/linux_joystick.c
vendored
2
src/external/glfw/src/linux_joystick.c
vendored
@ -228,7 +228,7 @@ static GLFWbool openJoystickDevice(const char* path)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(linjs.path, path, sizeof(linjs.path));
|
strncpy(linjs.path, path, sizeof(linjs.path) - 1);
|
||||||
memcpy(&js->linjs, &linjs, sizeof(linjs));
|
memcpy(&js->linjs, &linjs, sizeof(linjs));
|
||||||
|
|
||||||
pollAbsState(js);
|
pollAbsState(js);
|
||||||
|
240
src/external/glfw/src/mir_init.c
vendored
240
src/external/glfw/src/mir_init.c
vendored
@ -1,240 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 Mir - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2014-2017 Brandon Schaefer <brandon.schaefer@canonical.com>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
#include <linux/input.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
// Create key code translation tables
|
|
||||||
//
|
|
||||||
static void createKeyTables(void)
|
|
||||||
{
|
|
||||||
int scancode;
|
|
||||||
|
|
||||||
memset(_glfw.mir.keycodes, -1, sizeof(_glfw.mir.keycodes));
|
|
||||||
memset(_glfw.mir.scancodes, -1, sizeof(_glfw.mir.scancodes));
|
|
||||||
|
|
||||||
_glfw.mir.keycodes[KEY_GRAVE] = GLFW_KEY_GRAVE_ACCENT;
|
|
||||||
_glfw.mir.keycodes[KEY_1] = GLFW_KEY_1;
|
|
||||||
_glfw.mir.keycodes[KEY_2] = GLFW_KEY_2;
|
|
||||||
_glfw.mir.keycodes[KEY_3] = GLFW_KEY_3;
|
|
||||||
_glfw.mir.keycodes[KEY_4] = GLFW_KEY_4;
|
|
||||||
_glfw.mir.keycodes[KEY_5] = GLFW_KEY_5;
|
|
||||||
_glfw.mir.keycodes[KEY_6] = GLFW_KEY_6;
|
|
||||||
_glfw.mir.keycodes[KEY_7] = GLFW_KEY_7;
|
|
||||||
_glfw.mir.keycodes[KEY_8] = GLFW_KEY_8;
|
|
||||||
_glfw.mir.keycodes[KEY_9] = GLFW_KEY_9;
|
|
||||||
_glfw.mir.keycodes[KEY_0] = GLFW_KEY_0;
|
|
||||||
_glfw.mir.keycodes[KEY_SPACE] = GLFW_KEY_SPACE;
|
|
||||||
_glfw.mir.keycodes[KEY_MINUS] = GLFW_KEY_MINUS;
|
|
||||||
_glfw.mir.keycodes[KEY_EQUAL] = GLFW_KEY_EQUAL;
|
|
||||||
_glfw.mir.keycodes[KEY_Q] = GLFW_KEY_Q;
|
|
||||||
_glfw.mir.keycodes[KEY_W] = GLFW_KEY_W;
|
|
||||||
_glfw.mir.keycodes[KEY_E] = GLFW_KEY_E;
|
|
||||||
_glfw.mir.keycodes[KEY_R] = GLFW_KEY_R;
|
|
||||||
_glfw.mir.keycodes[KEY_T] = GLFW_KEY_T;
|
|
||||||
_glfw.mir.keycodes[KEY_Y] = GLFW_KEY_Y;
|
|
||||||
_glfw.mir.keycodes[KEY_U] = GLFW_KEY_U;
|
|
||||||
_glfw.mir.keycodes[KEY_I] = GLFW_KEY_I;
|
|
||||||
_glfw.mir.keycodes[KEY_O] = GLFW_KEY_O;
|
|
||||||
_glfw.mir.keycodes[KEY_P] = GLFW_KEY_P;
|
|
||||||
_glfw.mir.keycodes[KEY_LEFTBRACE] = GLFW_KEY_LEFT_BRACKET;
|
|
||||||
_glfw.mir.keycodes[KEY_RIGHTBRACE] = GLFW_KEY_RIGHT_BRACKET;
|
|
||||||
_glfw.mir.keycodes[KEY_A] = GLFW_KEY_A;
|
|
||||||
_glfw.mir.keycodes[KEY_S] = GLFW_KEY_S;
|
|
||||||
_glfw.mir.keycodes[KEY_D] = GLFW_KEY_D;
|
|
||||||
_glfw.mir.keycodes[KEY_F] = GLFW_KEY_F;
|
|
||||||
_glfw.mir.keycodes[KEY_G] = GLFW_KEY_G;
|
|
||||||
_glfw.mir.keycodes[KEY_H] = GLFW_KEY_H;
|
|
||||||
_glfw.mir.keycodes[KEY_J] = GLFW_KEY_J;
|
|
||||||
_glfw.mir.keycodes[KEY_K] = GLFW_KEY_K;
|
|
||||||
_glfw.mir.keycodes[KEY_L] = GLFW_KEY_L;
|
|
||||||
_glfw.mir.keycodes[KEY_SEMICOLON] = GLFW_KEY_SEMICOLON;
|
|
||||||
_glfw.mir.keycodes[KEY_APOSTROPHE] = GLFW_KEY_APOSTROPHE;
|
|
||||||
_glfw.mir.keycodes[KEY_Z] = GLFW_KEY_Z;
|
|
||||||
_glfw.mir.keycodes[KEY_X] = GLFW_KEY_X;
|
|
||||||
_glfw.mir.keycodes[KEY_C] = GLFW_KEY_C;
|
|
||||||
_glfw.mir.keycodes[KEY_V] = GLFW_KEY_V;
|
|
||||||
_glfw.mir.keycodes[KEY_B] = GLFW_KEY_B;
|
|
||||||
_glfw.mir.keycodes[KEY_N] = GLFW_KEY_N;
|
|
||||||
_glfw.mir.keycodes[KEY_M] = GLFW_KEY_M;
|
|
||||||
_glfw.mir.keycodes[KEY_COMMA] = GLFW_KEY_COMMA;
|
|
||||||
_glfw.mir.keycodes[KEY_DOT] = GLFW_KEY_PERIOD;
|
|
||||||
_glfw.mir.keycodes[KEY_SLASH] = GLFW_KEY_SLASH;
|
|
||||||
_glfw.mir.keycodes[KEY_BACKSLASH] = GLFW_KEY_BACKSLASH;
|
|
||||||
_glfw.mir.keycodes[KEY_ESC] = GLFW_KEY_ESCAPE;
|
|
||||||
_glfw.mir.keycodes[KEY_TAB] = GLFW_KEY_TAB;
|
|
||||||
_glfw.mir.keycodes[KEY_LEFTSHIFT] = GLFW_KEY_LEFT_SHIFT;
|
|
||||||
_glfw.mir.keycodes[KEY_RIGHTSHIFT] = GLFW_KEY_RIGHT_SHIFT;
|
|
||||||
_glfw.mir.keycodes[KEY_LEFTCTRL] = GLFW_KEY_LEFT_CONTROL;
|
|
||||||
_glfw.mir.keycodes[KEY_RIGHTCTRL] = GLFW_KEY_RIGHT_CONTROL;
|
|
||||||
_glfw.mir.keycodes[KEY_LEFTALT] = GLFW_KEY_LEFT_ALT;
|
|
||||||
_glfw.mir.keycodes[KEY_RIGHTALT] = GLFW_KEY_RIGHT_ALT;
|
|
||||||
_glfw.mir.keycodes[KEY_LEFTMETA] = GLFW_KEY_LEFT_SUPER;
|
|
||||||
_glfw.mir.keycodes[KEY_RIGHTMETA] = GLFW_KEY_RIGHT_SUPER;
|
|
||||||
_glfw.mir.keycodes[KEY_MENU] = GLFW_KEY_MENU;
|
|
||||||
_glfw.mir.keycodes[KEY_NUMLOCK] = GLFW_KEY_NUM_LOCK;
|
|
||||||
_glfw.mir.keycodes[KEY_CAPSLOCK] = GLFW_KEY_CAPS_LOCK;
|
|
||||||
_glfw.mir.keycodes[KEY_PRINT] = GLFW_KEY_PRINT_SCREEN;
|
|
||||||
_glfw.mir.keycodes[KEY_SCROLLLOCK] = GLFW_KEY_SCROLL_LOCK;
|
|
||||||
_glfw.mir.keycodes[KEY_PAUSE] = GLFW_KEY_PAUSE;
|
|
||||||
_glfw.mir.keycodes[KEY_DELETE] = GLFW_KEY_DELETE;
|
|
||||||
_glfw.mir.keycodes[KEY_BACKSPACE] = GLFW_KEY_BACKSPACE;
|
|
||||||
_glfw.mir.keycodes[KEY_ENTER] = GLFW_KEY_ENTER;
|
|
||||||
_glfw.mir.keycodes[KEY_HOME] = GLFW_KEY_HOME;
|
|
||||||
_glfw.mir.keycodes[KEY_END] = GLFW_KEY_END;
|
|
||||||
_glfw.mir.keycodes[KEY_PAGEUP] = GLFW_KEY_PAGE_UP;
|
|
||||||
_glfw.mir.keycodes[KEY_PAGEDOWN] = GLFW_KEY_PAGE_DOWN;
|
|
||||||
_glfw.mir.keycodes[KEY_INSERT] = GLFW_KEY_INSERT;
|
|
||||||
_glfw.mir.keycodes[KEY_LEFT] = GLFW_KEY_LEFT;
|
|
||||||
_glfw.mir.keycodes[KEY_RIGHT] = GLFW_KEY_RIGHT;
|
|
||||||
_glfw.mir.keycodes[KEY_DOWN] = GLFW_KEY_DOWN;
|
|
||||||
_glfw.mir.keycodes[KEY_UP] = GLFW_KEY_UP;
|
|
||||||
_glfw.mir.keycodes[KEY_F1] = GLFW_KEY_F1;
|
|
||||||
_glfw.mir.keycodes[KEY_F2] = GLFW_KEY_F2;
|
|
||||||
_glfw.mir.keycodes[KEY_F3] = GLFW_KEY_F3;
|
|
||||||
_glfw.mir.keycodes[KEY_F4] = GLFW_KEY_F4;
|
|
||||||
_glfw.mir.keycodes[KEY_F5] = GLFW_KEY_F5;
|
|
||||||
_glfw.mir.keycodes[KEY_F6] = GLFW_KEY_F6;
|
|
||||||
_glfw.mir.keycodes[KEY_F7] = GLFW_KEY_F7;
|
|
||||||
_glfw.mir.keycodes[KEY_F8] = GLFW_KEY_F8;
|
|
||||||
_glfw.mir.keycodes[KEY_F9] = GLFW_KEY_F9;
|
|
||||||
_glfw.mir.keycodes[KEY_F10] = GLFW_KEY_F10;
|
|
||||||
_glfw.mir.keycodes[KEY_F11] = GLFW_KEY_F11;
|
|
||||||
_glfw.mir.keycodes[KEY_F12] = GLFW_KEY_F12;
|
|
||||||
_glfw.mir.keycodes[KEY_F13] = GLFW_KEY_F13;
|
|
||||||
_glfw.mir.keycodes[KEY_F14] = GLFW_KEY_F14;
|
|
||||||
_glfw.mir.keycodes[KEY_F15] = GLFW_KEY_F15;
|
|
||||||
_glfw.mir.keycodes[KEY_F16] = GLFW_KEY_F16;
|
|
||||||
_glfw.mir.keycodes[KEY_F17] = GLFW_KEY_F17;
|
|
||||||
_glfw.mir.keycodes[KEY_F18] = GLFW_KEY_F18;
|
|
||||||
_glfw.mir.keycodes[KEY_F19] = GLFW_KEY_F19;
|
|
||||||
_glfw.mir.keycodes[KEY_F20] = GLFW_KEY_F20;
|
|
||||||
_glfw.mir.keycodes[KEY_F21] = GLFW_KEY_F21;
|
|
||||||
_glfw.mir.keycodes[KEY_F22] = GLFW_KEY_F22;
|
|
||||||
_glfw.mir.keycodes[KEY_F23] = GLFW_KEY_F23;
|
|
||||||
_glfw.mir.keycodes[KEY_F24] = GLFW_KEY_F24;
|
|
||||||
_glfw.mir.keycodes[KEY_KPSLASH] = GLFW_KEY_KP_DIVIDE;
|
|
||||||
_glfw.mir.keycodes[KEY_KPDOT] = GLFW_KEY_KP_MULTIPLY;
|
|
||||||
_glfw.mir.keycodes[KEY_KPMINUS] = GLFW_KEY_KP_SUBTRACT;
|
|
||||||
_glfw.mir.keycodes[KEY_KPPLUS] = GLFW_KEY_KP_ADD;
|
|
||||||
_glfw.mir.keycodes[KEY_KP0] = GLFW_KEY_KP_0;
|
|
||||||
_glfw.mir.keycodes[KEY_KP1] = GLFW_KEY_KP_1;
|
|
||||||
_glfw.mir.keycodes[KEY_KP2] = GLFW_KEY_KP_2;
|
|
||||||
_glfw.mir.keycodes[KEY_KP3] = GLFW_KEY_KP_3;
|
|
||||||
_glfw.mir.keycodes[KEY_KP4] = GLFW_KEY_KP_4;
|
|
||||||
_glfw.mir.keycodes[KEY_KP5] = GLFW_KEY_KP_5;
|
|
||||||
_glfw.mir.keycodes[KEY_KP6] = GLFW_KEY_KP_6;
|
|
||||||
_glfw.mir.keycodes[KEY_KP7] = GLFW_KEY_KP_7;
|
|
||||||
_glfw.mir.keycodes[KEY_KP8] = GLFW_KEY_KP_8;
|
|
||||||
_glfw.mir.keycodes[KEY_KP9] = GLFW_KEY_KP_9;
|
|
||||||
_glfw.mir.keycodes[KEY_KPCOMMA] = GLFW_KEY_KP_DECIMAL;
|
|
||||||
_glfw.mir.keycodes[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL;
|
|
||||||
_glfw.mir.keycodes[KEY_KPENTER] = GLFW_KEY_KP_ENTER;
|
|
||||||
|
|
||||||
for (scancode = 0; scancode < 256; scancode++)
|
|
||||||
{
|
|
||||||
if (_glfw.mir.keycodes[scancode] > 0)
|
|
||||||
_glfw.mir.scancodes[_glfw.mir.keycodes[scancode]] = scancode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW internal API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int _glfwPlatformInit(void)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
|
|
||||||
_glfw.mir.connection = mir_connect_sync(NULL, __PRETTY_FUNCTION__);
|
|
||||||
|
|
||||||
if (!mir_connection_is_valid(_glfw.mir.connection))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unable to connect to server: %s",
|
|
||||||
mir_connection_get_error_message(_glfw.mir.connection));
|
|
||||||
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.mir.display =
|
|
||||||
mir_connection_get_egl_native_display(_glfw.mir.connection);
|
|
||||||
|
|
||||||
createKeyTables();
|
|
||||||
|
|
||||||
if (!_glfwInitJoysticksLinux())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
_glfwInitTimerPOSIX();
|
|
||||||
|
|
||||||
_glfw.mir.eventQueue = calloc(1, sizeof(EventQueue));
|
|
||||||
_glfwInitEventQueueMir(_glfw.mir.eventQueue);
|
|
||||||
|
|
||||||
error = pthread_mutex_init(&_glfw.mir.eventMutex, NULL);
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Failed to create event mutex: %s",
|
|
||||||
strerror(error));
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwPollMonitorsMir();
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformTerminate(void)
|
|
||||||
{
|
|
||||||
_glfwTerminateEGL();
|
|
||||||
_glfwTerminateJoysticksLinux();
|
|
||||||
|
|
||||||
_glfwDeleteEventQueueMir(_glfw.mir.eventQueue);
|
|
||||||
|
|
||||||
pthread_mutex_destroy(&_glfw.mir.eventMutex);
|
|
||||||
|
|
||||||
mir_connection_release(_glfw.mir.connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* _glfwPlatformGetVersionString(void)
|
|
||||||
{
|
|
||||||
return _GLFW_VERSION_NUMBER " Mir EGL"
|
|
||||||
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
|
|
||||||
" clock_gettime"
|
|
||||||
#else
|
|
||||||
" gettimeofday"
|
|
||||||
#endif
|
|
||||||
" evdev"
|
|
||||||
#if defined(_GLFW_BUILD_DLL)
|
|
||||||
" shared"
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
218
src/external/glfw/src/mir_monitor.c
vendored
218
src/external/glfw/src/mir_monitor.c
vendored
@ -1,218 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 Mir - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2014-2017 Brandon Schaefer <brandon.schaefer@canonical.com>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW internal API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Poll for changes in the set of connected monitors
|
|
||||||
//
|
|
||||||
void _glfwPollMonitorsMir(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
MirDisplayConfig* displayConfig =
|
|
||||||
mir_connection_create_display_configuration(_glfw.mir.connection);
|
|
||||||
|
|
||||||
int numOutputs = mir_display_config_get_num_outputs(displayConfig);
|
|
||||||
|
|
||||||
for (i = 0; i < numOutputs; i++)
|
|
||||||
{
|
|
||||||
const MirOutput* output = mir_display_config_get_output(displayConfig, i);
|
|
||||||
MirOutputConnectionState state = mir_output_get_connection_state(output);
|
|
||||||
bool enabled = mir_output_is_enabled(output);
|
|
||||||
|
|
||||||
if (enabled && state == mir_output_connection_state_connected)
|
|
||||||
{
|
|
||||||
int widthMM = mir_output_get_physical_width_mm(output);
|
|
||||||
int heightMM = mir_output_get_physical_height_mm(output);
|
|
||||||
int x = mir_output_get_position_x(output);
|
|
||||||
int y = mir_output_get_position_y(output);
|
|
||||||
int id = mir_output_get_id(output);
|
|
||||||
size_t currentMode = mir_output_get_current_mode_index(output);
|
|
||||||
const char* name = mir_output_type_name(mir_output_get_type(output));
|
|
||||||
|
|
||||||
_GLFWmonitor* monitor = _glfwAllocMonitor(name,
|
|
||||||
widthMM,
|
|
||||||
heightMM);
|
|
||||||
monitor->mir.x = x;
|
|
||||||
monitor->mir.y = y;
|
|
||||||
monitor->mir.outputId = id;
|
|
||||||
monitor->mir.curMode = currentMode;
|
|
||||||
monitor->modes = _glfwPlatformGetVideoModes(monitor, &monitor->modeCount);
|
|
||||||
|
|
||||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mir_display_config_release(displayConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW platform API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
|
||||||
{
|
|
||||||
if (xpos)
|
|
||||||
*xpos = monitor->mir.x;
|
|
||||||
if (ypos)
|
|
||||||
*ypos = monitor->mir.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
|
||||||
float* xscale, float* yscale)
|
|
||||||
{
|
|
||||||
if (xscale)
|
|
||||||
*xscale = 1.f;
|
|
||||||
if (yscale)
|
|
||||||
*yscale = 1.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FillInRGBBitsFromPixelFormat(GLFWvidmode* mode, const MirPixelFormat pf)
|
|
||||||
{
|
|
||||||
switch (pf)
|
|
||||||
{
|
|
||||||
case mir_pixel_format_rgb_565:
|
|
||||||
mode->redBits = 5;
|
|
||||||
mode->greenBits = 6;
|
|
||||||
mode->blueBits = 5;
|
|
||||||
break;
|
|
||||||
case mir_pixel_format_rgba_5551:
|
|
||||||
mode->redBits = 5;
|
|
||||||
mode->greenBits = 5;
|
|
||||||
mode->blueBits = 5;
|
|
||||||
break;
|
|
||||||
case mir_pixel_format_rgba_4444:
|
|
||||||
mode->redBits = 4;
|
|
||||||
mode->greenBits = 4;
|
|
||||||
mode->blueBits = 4;
|
|
||||||
break;
|
|
||||||
case mir_pixel_format_abgr_8888:
|
|
||||||
case mir_pixel_format_xbgr_8888:
|
|
||||||
case mir_pixel_format_argb_8888:
|
|
||||||
case mir_pixel_format_xrgb_8888:
|
|
||||||
case mir_pixel_format_bgr_888:
|
|
||||||
case mir_pixel_format_rgb_888:
|
|
||||||
default:
|
|
||||||
mode->redBits = 8;
|
|
||||||
mode->greenBits = 8;
|
|
||||||
mode->blueBits = 8;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
GLFWvidmode* modes = NULL;
|
|
||||||
MirDisplayConfig* displayConfig =
|
|
||||||
mir_connection_create_display_configuration(_glfw.mir.connection);
|
|
||||||
|
|
||||||
int numOutputs = mir_display_config_get_num_outputs(displayConfig);
|
|
||||||
|
|
||||||
for (i = 0; i < numOutputs; i++)
|
|
||||||
{
|
|
||||||
const MirOutput* output = mir_display_config_get_output(displayConfig, i);
|
|
||||||
int id = mir_output_get_id(output);
|
|
||||||
|
|
||||||
if (id != monitor->mir.outputId)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
MirOutputConnectionState state = mir_output_get_connection_state(output);
|
|
||||||
bool enabled = mir_output_is_enabled(output);
|
|
||||||
|
|
||||||
// We must have been disconnected
|
|
||||||
if (!enabled || state != mir_output_connection_state_connected)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Monitor no longer connected");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int numModes = mir_output_get_num_modes(output);
|
|
||||||
modes = calloc(numModes, sizeof(GLFWvidmode));
|
|
||||||
|
|
||||||
for (*found = 0; *found < numModes; (*found)++)
|
|
||||||
{
|
|
||||||
const MirOutputMode* mode = mir_output_get_mode(output, *found);
|
|
||||||
int width = mir_output_mode_get_width(mode);
|
|
||||||
int height = mir_output_mode_get_height(mode);
|
|
||||||
double refreshRate = mir_output_mode_get_refresh_rate(mode);
|
|
||||||
MirPixelFormat currentFormat = mir_output_get_current_pixel_format(output);
|
|
||||||
|
|
||||||
modes[*found].width = width;
|
|
||||||
modes[*found].height = height;
|
|
||||||
modes[*found].refreshRate = refreshRate;
|
|
||||||
|
|
||||||
FillInRGBBitsFromPixelFormat(&modes[*found], currentFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
mir_display_config_release(displayConfig);
|
|
||||||
|
|
||||||
return modes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
|
||||||
{
|
|
||||||
*mode = monitor->modes[monitor->mir.curMode];
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW native API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
GLFWAPI int glfwGetMirMonitor(GLFWmonitor* handle)
|
|
||||||
{
|
|
||||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
|
||||||
return monitor->mir.outputId;
|
|
||||||
}
|
|
133
src/external/glfw/src/mir_platform.h
vendored
133
src/external/glfw/src/mir_platform.h
vendored
@ -1,133 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 Mir - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2014-2017 Brandon Schaefer <brandon.schaefer@canonical.com>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include <sys/queue.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <dlfcn.h>
|
|
||||||
|
|
||||||
#include <mir_toolkit/mir_client_library.h>
|
|
||||||
|
|
||||||
typedef VkFlags VkMirWindowCreateFlagsKHR;
|
|
||||||
|
|
||||||
typedef struct VkMirWindowCreateInfoKHR
|
|
||||||
{
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
VkMirWindowCreateFlagsKHR flags;
|
|
||||||
MirConnection* connection;
|
|
||||||
MirWindow* mirWindow;
|
|
||||||
} VkMirWindowCreateInfoKHR;
|
|
||||||
|
|
||||||
typedef VkResult (APIENTRY *PFN_vkCreateMirWindowKHR)(VkInstance,const VkMirWindowCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
|
||||||
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice,uint32_t,MirConnection*);
|
|
||||||
|
|
||||||
#include "posix_thread.h"
|
|
||||||
#include "posix_time.h"
|
|
||||||
#include "linux_joystick.h"
|
|
||||||
#include "xkb_unicode.h"
|
|
||||||
#include "egl_context.h"
|
|
||||||
#include "osmesa_context.h"
|
|
||||||
|
|
||||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
|
||||||
#define _glfw_dlclose(handle) dlclose(handle)
|
|
||||||
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
|
||||||
|
|
||||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->mir.nativeWindow)
|
|
||||||
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.mir.display)
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowMir mir
|
|
||||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorMir mir
|
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryMir mir
|
|
||||||
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorMir mir
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_CONTEXT_STATE
|
|
||||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
|
||||||
|
|
||||||
|
|
||||||
// Mir-specific Event Queue
|
|
||||||
//
|
|
||||||
typedef struct EventQueue
|
|
||||||
{
|
|
||||||
TAILQ_HEAD(, EventNode) head;
|
|
||||||
} EventQueue;
|
|
||||||
|
|
||||||
// Mir-specific per-window data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWwindowMir
|
|
||||||
{
|
|
||||||
MirWindow* window;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
MirEGLNativeWindowType nativeWindow;
|
|
||||||
_GLFWcursor* currentCursor;
|
|
||||||
|
|
||||||
} _GLFWwindowMir;
|
|
||||||
|
|
||||||
// Mir-specific per-monitor data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWmonitorMir
|
|
||||||
{
|
|
||||||
int curMode;
|
|
||||||
int outputId;
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
|
|
||||||
} _GLFWmonitorMir;
|
|
||||||
|
|
||||||
// Mir-specific global data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWlibraryMir
|
|
||||||
{
|
|
||||||
MirConnection* connection;
|
|
||||||
MirEGLNativeDisplayType display;
|
|
||||||
EventQueue* eventQueue;
|
|
||||||
|
|
||||||
short int keycodes[256];
|
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
|
||||||
|
|
||||||
pthread_mutex_t eventMutex;
|
|
||||||
pthread_cond_t eventCond;
|
|
||||||
|
|
||||||
// The window whose disabled cursor mode is active
|
|
||||||
_GLFWwindow* disabledCursorWindow;
|
|
||||||
|
|
||||||
} _GLFWlibraryMir;
|
|
||||||
|
|
||||||
// Mir-specific per-cursor data
|
|
||||||
// TODO: Only system cursors are implemented in Mir atm. Need to wait for support.
|
|
||||||
//
|
|
||||||
typedef struct _GLFWcursorMir
|
|
||||||
{
|
|
||||||
MirCursorConfiguration* conf;
|
|
||||||
MirBufferStream* customCursor;
|
|
||||||
char const* cursorName; // only needed for system cursors
|
|
||||||
} _GLFWcursorMir;
|
|
||||||
|
|
||||||
|
|
||||||
extern void _glfwPollMonitorsMir(void);
|
|
||||||
extern void _glfwInitEventQueueMir(EventQueue* queue);
|
|
||||||
extern void _glfwDeleteEventQueueMir(EventQueue* queue);
|
|
||||||
|
|
975
src/external/glfw/src/mir_window.c
vendored
975
src/external/glfw/src/mir_window.c
vendored
@ -1,975 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 Mir - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2014-2017 Brandon Schaefer <brandon.schaefer@canonical.com>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
#include <linux/input.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct EventNode
|
|
||||||
{
|
|
||||||
TAILQ_ENTRY(EventNode) entries;
|
|
||||||
const MirEvent* event;
|
|
||||||
_GLFWwindow* window;
|
|
||||||
} EventNode;
|
|
||||||
|
|
||||||
static void deleteNode(EventQueue* queue, EventNode* node)
|
|
||||||
{
|
|
||||||
mir_event_unref(node->event);
|
|
||||||
free(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GLFWbool emptyEventQueue(EventQueue* queue)
|
|
||||||
{
|
|
||||||
return queue->head.tqh_first == NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO The mir_event_ref is not supposed to be used but ... its needed
|
|
||||||
// in this case. Need to wait until we can read from an FD set up by mir
|
|
||||||
// for single threaded event handling.
|
|
||||||
static EventNode* newEventNode(const MirEvent* event, _GLFWwindow* context)
|
|
||||||
{
|
|
||||||
EventNode* newNode = calloc(1, sizeof(EventNode));
|
|
||||||
newNode->event = mir_event_ref(event);
|
|
||||||
newNode->window = context;
|
|
||||||
|
|
||||||
return newNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void enqueueEvent(const MirEvent* event, _GLFWwindow* context)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&_glfw.mir.eventMutex);
|
|
||||||
|
|
||||||
EventNode* newNode = newEventNode(event, context);
|
|
||||||
TAILQ_INSERT_TAIL(&_glfw.mir.eventQueue->head, newNode, entries);
|
|
||||||
|
|
||||||
pthread_cond_signal(&_glfw.mir.eventCond);
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&_glfw.mir.eventMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static EventNode* dequeueEvent(EventQueue* queue)
|
|
||||||
{
|
|
||||||
EventNode* node = NULL;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&_glfw.mir.eventMutex);
|
|
||||||
|
|
||||||
node = queue->head.tqh_first;
|
|
||||||
|
|
||||||
if (node)
|
|
||||||
TAILQ_REMOVE(&queue->head, node, entries);
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&_glfw.mir.eventMutex);
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
static MirPixelFormat findValidPixelFormat(void)
|
|
||||||
{
|
|
||||||
unsigned int i, validFormats, mirPixelFormats = 32;
|
|
||||||
MirPixelFormat formats[mir_pixel_formats];
|
|
||||||
|
|
||||||
mir_connection_get_available_surface_formats(_glfw.mir.connection, formats,
|
|
||||||
mirPixelFormats, &validFormats);
|
|
||||||
|
|
||||||
for (i = 0; i < validFormats; i++)
|
|
||||||
{
|
|
||||||
if (formats[i] == mir_pixel_format_abgr_8888 ||
|
|
||||||
formats[i] == mir_pixel_format_xbgr_8888 ||
|
|
||||||
formats[i] == mir_pixel_format_argb_8888 ||
|
|
||||||
formats[i] == mir_pixel_format_xrgb_8888)
|
|
||||||
{
|
|
||||||
return formats[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mir_pixel_format_invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mirModToGLFWMod(uint32_t mods)
|
|
||||||
{
|
|
||||||
int publicMods = 0x0;
|
|
||||||
|
|
||||||
if (mods & mir_input_event_modifier_alt)
|
|
||||||
publicMods |= GLFW_MOD_ALT;
|
|
||||||
if (mods & mir_input_event_modifier_shift)
|
|
||||||
publicMods |= GLFW_MOD_SHIFT;
|
|
||||||
if (mods & mir_input_event_modifier_ctrl)
|
|
||||||
publicMods |= GLFW_MOD_CONTROL;
|
|
||||||
if (mods & mir_input_event_modifier_meta)
|
|
||||||
publicMods |= GLFW_MOD_SUPER;
|
|
||||||
if (mods & mir_input_event_modifier_caps_lock)
|
|
||||||
publicMods |= GLFW_MOD_CAPS_LOCK;
|
|
||||||
if (mods & mir_input_event_modifier_num_lock)
|
|
||||||
publicMods |= GLFW_MOD_NUM_LOCK;
|
|
||||||
|
|
||||||
return publicMods;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int toGLFWKeyCode(uint32_t key)
|
|
||||||
{
|
|
||||||
if (key < sizeof(_glfw.mir.keycodes) / sizeof(_glfw.mir.keycodes[0]))
|
|
||||||
return _glfw.mir.keycodes[key];
|
|
||||||
|
|
||||||
return GLFW_KEY_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handleKeyEvent(const MirKeyboardEvent* key_event, _GLFWwindow* window)
|
|
||||||
{
|
|
||||||
const int action = mir_keyboard_event_action (key_event);
|
|
||||||
const int scan_code = mir_keyboard_event_scan_code(key_event);
|
|
||||||
const int key_code = mir_keyboard_event_key_code (key_event);
|
|
||||||
const int modifiers = mir_keyboard_event_modifiers(key_event);
|
|
||||||
|
|
||||||
const int pressed = action == mir_keyboard_action_up ? GLFW_RELEASE : GLFW_PRESS;
|
|
||||||
const int mods = mirModToGLFWMod(modifiers);
|
|
||||||
const long text = _glfwKeySym2Unicode(key_code);
|
|
||||||
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
|
|
||||||
|
|
||||||
_glfwInputKey(window, toGLFWKeyCode(scan_code), scan_code, pressed, mods);
|
|
||||||
|
|
||||||
if (text != -1)
|
|
||||||
_glfwInputChar(window, text, mods, plain);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handlePointerButton(_GLFWwindow* window,
|
|
||||||
int pressed,
|
|
||||||
const MirPointerEvent* pointer_event)
|
|
||||||
{
|
|
||||||
int mods = mir_pointer_event_modifiers(pointer_event);
|
|
||||||
const int publicMods = mirModToGLFWMod(mods);
|
|
||||||
MirPointerButton button = mir_pointer_button_primary;
|
|
||||||
static uint32_t oldButtonStates = 0;
|
|
||||||
uint32_t newButtonStates = mir_pointer_event_buttons(pointer_event);
|
|
||||||
int publicButton = GLFW_MOUSE_BUTTON_LEFT;
|
|
||||||
|
|
||||||
// XOR our old button states our new states to figure out what was added or removed
|
|
||||||
button = newButtonStates ^ oldButtonStates;
|
|
||||||
|
|
||||||
switch (button)
|
|
||||||
{
|
|
||||||
case mir_pointer_button_primary:
|
|
||||||
publicButton = GLFW_MOUSE_BUTTON_LEFT;
|
|
||||||
break;
|
|
||||||
case mir_pointer_button_secondary:
|
|
||||||
publicButton = GLFW_MOUSE_BUTTON_RIGHT;
|
|
||||||
break;
|
|
||||||
case mir_pointer_button_tertiary:
|
|
||||||
publicButton = GLFW_MOUSE_BUTTON_MIDDLE;
|
|
||||||
break;
|
|
||||||
case mir_pointer_button_forward:
|
|
||||||
// FIXME What is the forward button?
|
|
||||||
publicButton = GLFW_MOUSE_BUTTON_4;
|
|
||||||
break;
|
|
||||||
case mir_pointer_button_back:
|
|
||||||
// FIXME What is the back button?
|
|
||||||
publicButton = GLFW_MOUSE_BUTTON_5;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
oldButtonStates = newButtonStates;
|
|
||||||
|
|
||||||
_glfwInputMouseClick(window, publicButton, pressed, publicMods);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handlePointerMotion(_GLFWwindow* window,
|
|
||||||
const MirPointerEvent* pointer_event)
|
|
||||||
{
|
|
||||||
const int hscroll = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll);
|
|
||||||
const int vscroll = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll);
|
|
||||||
|
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
|
||||||
{
|
|
||||||
if (_glfw.mir.disabledCursorWindow != window)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const int dx = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_relative_x);
|
|
||||||
const int dy = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_relative_y);
|
|
||||||
const int current_x = window->virtualCursorPosX;
|
|
||||||
const int current_y = window->virtualCursorPosY;
|
|
||||||
|
|
||||||
_glfwInputCursorPos(window, dx + current_x, dy + current_y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const int x = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_x);
|
|
||||||
const int y = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_y);
|
|
||||||
|
|
||||||
_glfwInputCursorPos(window, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hscroll != 0 || vscroll != 0)
|
|
||||||
_glfwInputScroll(window, hscroll, vscroll);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handlePointerEvent(const MirPointerEvent* pointer_event,
|
|
||||||
_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
int action = mir_pointer_event_action(pointer_event);
|
|
||||||
|
|
||||||
switch (action)
|
|
||||||
{
|
|
||||||
case mir_pointer_action_button_down:
|
|
||||||
handlePointerButton(window, GLFW_PRESS, pointer_event);
|
|
||||||
break;
|
|
||||||
case mir_pointer_action_button_up:
|
|
||||||
handlePointerButton(window, GLFW_RELEASE, pointer_event);
|
|
||||||
break;
|
|
||||||
case mir_pointer_action_motion:
|
|
||||||
handlePointerMotion(window, pointer_event);
|
|
||||||
break;
|
|
||||||
case mir_pointer_action_enter:
|
|
||||||
case mir_pointer_action_leave:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handleInput(const MirInputEvent* input_event, _GLFWwindow* window)
|
|
||||||
{
|
|
||||||
int type = mir_input_event_get_type(input_event);
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case mir_input_event_type_key:
|
|
||||||
handleKeyEvent(mir_input_event_get_keyboard_event(input_event), window);
|
|
||||||
break;
|
|
||||||
case mir_input_event_type_pointer:
|
|
||||||
handlePointerEvent(mir_input_event_get_pointer_event(input_event), window);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handleEvent(const MirEvent* event, _GLFWwindow* window)
|
|
||||||
{
|
|
||||||
int type = mir_event_get_type(event);
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case mir_event_type_input:
|
|
||||||
handleInput(mir_event_get_input_event(event), window);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addNewEvent(MirWindow* window, const MirEvent* event, void* context)
|
|
||||||
{
|
|
||||||
enqueueEvent(event, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GLFWbool createWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
MirWindowSpec* spec;
|
|
||||||
MirBufferUsage buffer_usage = mir_buffer_usage_hardware;
|
|
||||||
MirPixelFormat pixel_format = findValidPixelFormat();
|
|
||||||
|
|
||||||
if (pixel_format == mir_pixel_format_invalid)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unable to find a correct pixel format");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
spec = mir_create_normal_window_spec(_glfw.mir.connection,
|
|
||||||
window->mir.width,
|
|
||||||
window->mir.height);
|
|
||||||
|
|
||||||
mir_window_spec_set_pixel_format(spec, pixel_format);
|
|
||||||
mir_window_spec_set_buffer_usage(spec, buffer_usage);
|
|
||||||
|
|
||||||
window->mir.window = mir_create_window_sync(spec);
|
|
||||||
mir_window_spec_release(spec);
|
|
||||||
|
|
||||||
if (!mir_window_is_valid(window->mir.window))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unable to create window: %s",
|
|
||||||
mir_window_get_error_message(window->mir.window));
|
|
||||||
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mir_window_set_event_handler(window->mir.window, addNewEvent, window);
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setWindowConfinement(_GLFWwindow* window, MirPointerConfinementState state)
|
|
||||||
{
|
|
||||||
MirWindowSpec* spec;
|
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
|
||||||
mir_window_spec_set_pointer_confinement(spec, state);
|
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
|
||||||
mir_window_spec_release(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW internal API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void _glfwInitEventQueueMir(EventQueue* queue)
|
|
||||||
{
|
|
||||||
TAILQ_INIT(&queue->head);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwDeleteEventQueueMir(EventQueue* queue)
|
|
||||||
{
|
|
||||||
if (queue)
|
|
||||||
{
|
|
||||||
EventNode* node, *node_next;
|
|
||||||
node = queue->head.tqh_first;
|
|
||||||
|
|
||||||
while (node != NULL)
|
|
||||||
{
|
|
||||||
node_next = node->entries.tqe_next;
|
|
||||||
|
|
||||||
TAILQ_REMOVE(&queue->head, node, entries);
|
|
||||||
deleteNode(queue, node);
|
|
||||||
|
|
||||||
node = node_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(queue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW platform API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|
||||||
const _GLFWwndconfig* wndconfig,
|
|
||||||
const _GLFWctxconfig* ctxconfig,
|
|
||||||
const _GLFWfbconfig* fbconfig)
|
|
||||||
{
|
|
||||||
if (window->monitor)
|
|
||||||
{
|
|
||||||
GLFWvidmode mode;
|
|
||||||
_glfwPlatformGetVideoMode(window->monitor, &mode);
|
|
||||||
|
|
||||||
mir_window_set_state(window->mir.window, mir_window_state_fullscreen);
|
|
||||||
|
|
||||||
if (wndconfig->width > mode.width || wndconfig->height > mode.height)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Requested window size too large: %ix%i",
|
|
||||||
wndconfig->width, wndconfig->height);
|
|
||||||
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window->mir.width = wndconfig->width;
|
|
||||||
window->mir.height = wndconfig->height;
|
|
||||||
window->mir.currentCursor = NULL;
|
|
||||||
|
|
||||||
if (!createWindow(window))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
window->mir.nativeWindow = mir_buffer_stream_get_egl_native_window(
|
|
||||||
mir_window_get_buffer_stream(window->mir.window));
|
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
|
||||||
{
|
|
||||||
if (ctxconfig->source == GLFW_EGL_CONTEXT_API ||
|
|
||||||
ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
|
||||||
{
|
|
||||||
if (!_glfwInitEGL())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
|
||||||
if (!_glfwInitOSMesa())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
if (_glfw.mir.disabledCursorWindow == window)
|
|
||||||
_glfw.mir.disabledCursorWindow = NULL;
|
|
||||||
|
|
||||||
if (mir_window_is_valid(window->mir.window))
|
|
||||||
{
|
|
||||||
mir_window_release_sync(window->mir.window);
|
|
||||||
window->mir.window= NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->context.destroy)
|
|
||||||
window->context.destroy(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
|
||||||
{
|
|
||||||
MirWindowSpec* spec;
|
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
|
||||||
mir_window_spec_set_name(spec, title);
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
|
||||||
mir_window_spec_release(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
|
||||||
int count, const GLFWimage* images)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
|
||||||
{
|
|
||||||
MirWindowSpec* spec;
|
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
|
||||||
mir_window_spec_set_width (spec, width);
|
|
||||||
mir_window_spec_set_height(spec, height);
|
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
|
||||||
mir_window_spec_release(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
|
||||||
int minwidth, int minheight,
|
|
||||||
int maxwidth, int maxheight)
|
|
||||||
{
|
|
||||||
MirWindowSpec* spec;
|
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
|
||||||
mir_window_spec_set_max_width (spec, maxwidth);
|
|
||||||
mir_window_spec_set_max_height(spec, maxheight);
|
|
||||||
mir_window_spec_set_min_width (spec, minwidth);
|
|
||||||
mir_window_spec_set_min_height(spec, minheight);
|
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
|
||||||
mir_window_spec_release(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
|
||||||
int* left, int* top,
|
|
||||||
int* right, int* bottom)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
|
||||||
{
|
|
||||||
if (width)
|
|
||||||
*width = window->mir.width;
|
|
||||||
if (height)
|
|
||||||
*height = window->mir.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
|
|
||||||
float* xscale, float* yscale)
|
|
||||||
{
|
|
||||||
if (xscale)
|
|
||||||
*xscale = 1.f;
|
|
||||||
if (yscale)
|
|
||||||
*yscale = 1.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
MirWindowSpec* spec;
|
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
|
||||||
mir_window_spec_set_state(spec, mir_window_state_minimized);
|
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
|
||||||
mir_window_spec_release(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
MirWindowSpec* spec;
|
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
|
||||||
mir_window_spec_set_state(spec, mir_window_state_restored);
|
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
|
||||||
mir_window_spec_release(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
MirWindowSpec* spec;
|
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
|
||||||
mir_window_spec_set_state(spec, mir_window_state_maximized);
|
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
|
||||||
mir_window_spec_release(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformHideWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
MirWindowSpec* spec;
|
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
|
||||||
mir_window_spec_set_state(spec, mir_window_state_hidden);
|
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
|
||||||
mir_window_spec_release(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
MirWindowSpec* spec;
|
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
|
||||||
mir_window_spec_set_state(spec, mir_window_state_restored);
|
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
|
||||||
mir_window_spec_release(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
|
||||||
_GLFWmonitor* monitor,
|
|
||||||
int xpos, int ypos,
|
|
||||||
int width, int height,
|
|
||||||
int refreshRate)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
return mir_window_get_focus_state(window->mir.window) == mir_window_focus_state_focused;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformWindowIconified(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformWindowVisible(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
return mir_window_get_visibility(window->mir.window) == mir_window_visibility_exposed;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
return mir_window_get_state(window->mir.window) == mir_window_state_maximized;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformWindowHovered(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
return 1.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformPollEvents(void)
|
|
||||||
{
|
|
||||||
EventNode* node = NULL;
|
|
||||||
|
|
||||||
while ((node = dequeueEvent(_glfw.mir.eventQueue)))
|
|
||||||
{
|
|
||||||
handleEvent(node->event, node->window);
|
|
||||||
deleteNode(_glfw.mir.eventQueue, node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformWaitEvents(void)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&_glfw.mir.eventMutex);
|
|
||||||
|
|
||||||
while (emptyEventQueue(_glfw.mir.eventQueue))
|
|
||||||
pthread_cond_wait(&_glfw.mir.eventCond, &_glfw.mir.eventMutex);
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&_glfw.mir.eventMutex);
|
|
||||||
|
|
||||||
_glfwPlatformPollEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformWaitEventsTimeout(double timeout)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&_glfw.mir.eventMutex);
|
|
||||||
|
|
||||||
if (emptyEventQueue(_glfw.mir.eventQueue))
|
|
||||||
{
|
|
||||||
struct timespec time;
|
|
||||||
clock_gettime(CLOCK_REALTIME, &time);
|
|
||||||
time.tv_sec += (long) timeout;
|
|
||||||
time.tv_nsec += (long) ((timeout - (long) timeout) * 1e9);
|
|
||||||
pthread_cond_timedwait(&_glfw.mir.eventCond, &_glfw.mir.eventMutex, &time);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&_glfw.mir.eventMutex);
|
|
||||||
|
|
||||||
_glfwPlatformPollEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformPostEmptyEvent(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
|
|
||||||
{
|
|
||||||
if (width)
|
|
||||||
*width = window->mir.width;
|
|
||||||
if (height)
|
|
||||||
*height = window->mir.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|
||||||
const GLFWimage* image,
|
|
||||||
int xhot, int yhot)
|
|
||||||
{
|
|
||||||
MirBufferStream* stream;
|
|
||||||
|
|
||||||
int i_w = image->width;
|
|
||||||
int i_h = image->height;
|
|
||||||
|
|
||||||
stream = mir_connection_create_buffer_stream_sync(_glfw.mir.connection,
|
|
||||||
i_w, i_h,
|
|
||||||
mir_pixel_format_argb_8888,
|
|
||||||
mir_buffer_usage_software);
|
|
||||||
|
|
||||||
cursor->mir.conf = mir_cursor_configuration_from_buffer_stream(stream, xhot, yhot);
|
|
||||||
|
|
||||||
MirGraphicsRegion region;
|
|
||||||
mir_buffer_stream_get_graphics_region(stream, ®ion);
|
|
||||||
|
|
||||||
unsigned char* pixels = image->pixels;
|
|
||||||
char* dest = region.vaddr;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < i_w * i_h; i++, pixels += 4)
|
|
||||||
{
|
|
||||||
unsigned int alpha = pixels[3];
|
|
||||||
*dest++ = (char)(pixels[2] * alpha / 255);
|
|
||||||
*dest++ = (char)(pixels[1] * alpha / 255);
|
|
||||||
*dest++ = (char)(pixels[0] * alpha / 255);
|
|
||||||
*dest++ = (char)alpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
mir_buffer_stream_swap_buffers_sync(stream);
|
|
||||||
cursor->mir.customCursor = stream;
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* getSystemCursorName(int shape)
|
|
||||||
{
|
|
||||||
switch (shape)
|
|
||||||
{
|
|
||||||
case GLFW_ARROW_CURSOR:
|
|
||||||
return mir_arrow_cursor_name;
|
|
||||||
case GLFW_IBEAM_CURSOR:
|
|
||||||
return mir_caret_cursor_name;
|
|
||||||
case GLFW_CROSSHAIR_CURSOR:
|
|
||||||
return mir_crosshair_cursor_name;
|
|
||||||
case GLFW_HAND_CURSOR:
|
|
||||||
return mir_open_hand_cursor_name;
|
|
||||||
case GLFW_HRESIZE_CURSOR:
|
|
||||||
return mir_horizontal_resize_cursor_name;
|
|
||||||
case GLFW_VRESIZE_CURSOR:
|
|
||||||
return mir_vertical_resize_cursor_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
|
||||||
{
|
|
||||||
cursor->mir.conf = NULL;
|
|
||||||
cursor->mir.customCursor = NULL;
|
|
||||||
cursor->mir.cursorName = getSystemCursorName(shape);
|
|
||||||
|
|
||||||
return cursor->mir.cursorName != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
|
||||||
{
|
|
||||||
if (cursor->mir.conf)
|
|
||||||
mir_cursor_configuration_destroy(cursor->mir.conf);
|
|
||||||
if (cursor->mir.customCursor)
|
|
||||||
mir_buffer_stream_release_sync(cursor->mir.customCursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setCursorNameForWindow(MirWindow* window, char const* name)
|
|
||||||
{
|
|
||||||
MirWindowSpec* spec = mir_create_window_spec(_glfw.mir.connection);
|
|
||||||
mir_window_spec_set_cursor_name(spec, name);
|
|
||||||
mir_window_apply_spec(window, spec);
|
|
||||||
mir_window_spec_release(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
|
||||||
{
|
|
||||||
if (cursor)
|
|
||||||
{
|
|
||||||
window->mir.currentCursor = cursor;
|
|
||||||
|
|
||||||
if (cursor->mir.cursorName)
|
|
||||||
{
|
|
||||||
setCursorNameForWindow(window->mir.window, cursor->mir.cursorName);
|
|
||||||
}
|
|
||||||
else if (cursor->mir.conf)
|
|
||||||
{
|
|
||||||
mir_window_configure_cursor(window->mir.window, cursor->mir.conf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setCursorNameForWindow(window->mir.window, mir_default_cursor_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|
||||||
{
|
|
||||||
if (mode == GLFW_CURSOR_DISABLED)
|
|
||||||
{
|
|
||||||
_glfw.mir.disabledCursorWindow = window;
|
|
||||||
setWindowConfinement(window, mir_pointer_confined_to_window);
|
|
||||||
setCursorNameForWindow(window->mir.window, mir_disabled_cursor_name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If we were disabled before lets undo that!
|
|
||||||
if (_glfw.mir.disabledCursorWindow == window)
|
|
||||||
{
|
|
||||||
_glfw.mir.disabledCursorWindow = NULL;
|
|
||||||
setWindowConfinement(window, mir_pointer_unconfined);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->cursorMode == GLFW_CURSOR_NORMAL)
|
|
||||||
{
|
|
||||||
_glfwPlatformSetCursor(window, window->mir.currentCursor);
|
|
||||||
}
|
|
||||||
else if (window->cursorMode == GLFW_CURSOR_HIDDEN)
|
|
||||||
{
|
|
||||||
setCursorNameForWindow(window->mir.window, mir_disabled_cursor_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformGetKeyScancode(int key)
|
|
||||||
{
|
|
||||||
return _glfw.mir.scancodes[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetClipboardString(const char* string)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* _glfwPlatformGetClipboardString(void)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
|
||||||
{
|
|
||||||
if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_mir_surface)
|
|
||||||
return;
|
|
||||||
|
|
||||||
extensions[0] = "VK_KHR_surface";
|
|
||||||
extensions[1] = "VK_KHR_mir_surface";
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
|
||||||
VkPhysicalDevice device,
|
|
||||||
uint32_t queuefamily)
|
|
||||||
{
|
|
||||||
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR
|
|
||||||
vkGetPhysicalDeviceMirPresentationSupportKHR =
|
|
||||||
(PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)
|
|
||||||
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
|
|
||||||
if (!vkGetPhysicalDeviceMirPresentationSupportKHR)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"Mir: Vulkan instance missing VK_KHR_mir_surface extension");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return vkGetPhysicalDeviceMirPresentationSupportKHR(device,
|
|
||||||
queuefamily,
|
|
||||||
_glfw.mir.connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
|
||||||
_GLFWwindow* window,
|
|
||||||
const VkAllocationCallbacks* allocator,
|
|
||||||
VkSurfaceKHR* surface)
|
|
||||||
{
|
|
||||||
VkResult err;
|
|
||||||
VkMirWindowCreateInfoKHR sci;
|
|
||||||
PFN_vkCreateMirWindowKHR vkCreateMirWindowKHR;
|
|
||||||
|
|
||||||
vkCreateMirWindowKHR = (PFN_vkCreateMirWindowKHR)
|
|
||||||
vkGetInstanceProcAddr(instance, "vkCreateMirWindowKHR");
|
|
||||||
if (!vkCreateMirWindowKHR)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"Mir: Vulkan instance missing VK_KHR_mir_surface extension");
|
|
||||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&sci, 0, sizeof(sci));
|
|
||||||
sci.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR;
|
|
||||||
sci.connection = _glfw.mir.connection;
|
|
||||||
sci.mirWindow = window->mir.window;
|
|
||||||
|
|
||||||
err = vkCreateMirWindowKHR(instance, &sci, allocator, surface);
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Failed to create Vulkan surface: %s",
|
|
||||||
_glfwGetVulkanResultString(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW native API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
GLFWAPI MirConnection* glfwGetMirDisplay(void)
|
|
||||||
{
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
|
||||||
return _glfw.mir.connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI MirWindow* glfwGetMirWindow(GLFWwindow* handle)
|
|
||||||
{
|
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
|
||||||
return window->mir.window;
|
|
||||||
}
|
|
||||||
|
|
33
src/external/glfw/src/monitor.c
vendored
33
src/external/glfw/src/monitor.c
vendored
@ -427,12 +427,12 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle)
|
|||||||
|
|
||||||
GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned int i;
|
||||||
unsigned short values[256];
|
unsigned short* values;
|
||||||
GLFWgammaramp ramp;
|
GLFWgammaramp ramp;
|
||||||
|
const GLFWgammaramp* original;
|
||||||
assert(handle != NULL);
|
assert(handle != NULL);
|
||||||
assert(gamma == gamma);
|
assert(gamma > 0.f);
|
||||||
assert(gamma >= 0.f);
|
|
||||||
assert(gamma <= FLT_MAX);
|
assert(gamma <= FLT_MAX);
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
@ -443,18 +443,22 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
original = glfwGetGammaRamp(handle);
|
||||||
|
if (!original)
|
||||||
|
return;
|
||||||
|
|
||||||
|
values = calloc(original->size, sizeof(unsigned short));
|
||||||
|
|
||||||
|
for (i = 0; i < original->size; i++)
|
||||||
{
|
{
|
||||||
float value;
|
float value;
|
||||||
|
|
||||||
// Calculate intensity
|
// Calculate intensity
|
||||||
value = i / 255.f;
|
value = i / (float) (original->size - 1);
|
||||||
// Apply gamma curve
|
// Apply gamma curve
|
||||||
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
|
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
|
||||||
|
|
||||||
// Clamp to value range
|
// Clamp to value range
|
||||||
if (value > 65535.f)
|
value = _glfw_fminf(value, 65535.f);
|
||||||
value = 65535.f;
|
|
||||||
|
|
||||||
values[i] = (unsigned short) value;
|
values[i] = (unsigned short) value;
|
||||||
}
|
}
|
||||||
@ -462,9 +466,10 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
|||||||
ramp.red = values;
|
ramp.red = values;
|
||||||
ramp.green = values;
|
ramp.green = values;
|
||||||
ramp.blue = values;
|
ramp.blue = values;
|
||||||
ramp.size = 256;
|
ramp.size = original->size;
|
||||||
|
|
||||||
glfwSetGammaRamp(handle, &ramp);
|
glfwSetGammaRamp(handle, &ramp);
|
||||||
|
free(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
|
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
|
||||||
@ -475,7 +480,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
|
|||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
_glfwFreeGammaArrays(&monitor->currentRamp);
|
_glfwFreeGammaArrays(&monitor->currentRamp);
|
||||||
_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp);
|
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return &monitor->currentRamp;
|
return &monitor->currentRamp;
|
||||||
}
|
}
|
||||||
@ -501,7 +507,10 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
|
|||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
if (!monitor->originalRamp.size)
|
if (!monitor->originalRamp.size)
|
||||||
_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp);
|
{
|
||||||
|
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_glfwPlatformSetGammaRamp(monitor, ramp);
|
_glfwPlatformSetGammaRamp(monitor, ramp);
|
||||||
}
|
}
|
||||||
|
9
src/external/glfw/src/nsgl_context.m
vendored
9
src/external/glfw/src/nsgl_context.m
vendored
@ -26,6 +26,10 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101400
|
||||||
|
#define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
|
||||||
|
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
|
||||||
|
#endif
|
||||||
|
|
||||||
static void makeContextCurrentNSGL(_GLFWwindow* window)
|
static void makeContextCurrentNSGL(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
@ -49,7 +53,7 @@ static void swapIntervalNSGL(int interval)
|
|||||||
|
|
||||||
GLint sync = interval;
|
GLint sync = interval;
|
||||||
[window->context.nsgl.object setValues:&sync
|
[window->context.nsgl.object setValues:&sync
|
||||||
forParameter:NSOpenGLCPSwapInterval];
|
forParameter:NSOpenGLContextParameterSwapInterval];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int extensionSupportedNSGL(const char* extension)
|
static int extensionSupportedNSGL(const char* extension)
|
||||||
@ -299,7 +303,8 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
if (fbconfig->transparent)
|
if (fbconfig->transparent)
|
||||||
{
|
{
|
||||||
GLint opaque = 0;
|
GLint opaque = 0;
|
||||||
[window->context.nsgl.object setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
|
[window->context.nsgl.object setValues:&opaque
|
||||||
|
forParameter:NSOpenGLContextParameterSurfaceOpacity];
|
||||||
}
|
}
|
||||||
|
|
||||||
[window->context.nsgl.object setView:window->ns.view];
|
[window->context.nsgl.object setView:window->ns.view];
|
||||||
|
3
src/external/glfw/src/null_monitor.c
vendored
3
src/external/glfw/src/null_monitor.c
vendored
@ -58,8 +58,9 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
{
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||||
|
2
src/external/glfw/src/osmesa_context.c
vendored
2
src/external/glfw/src/osmesa_context.c
vendored
@ -240,7 +240,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
|||||||
if (ctxconfig->forward)
|
if (ctxconfig->forward)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
"OSMesa: Foward-compatible contexts not supported");
|
"OSMesa: Forward-compatible contexts not supported");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
src/external/glfw/src/vulkan.c
vendored
3
src/external/glfw/src/vulkan.c
vendored
@ -136,9 +136,6 @@ GLFWbool _glfwInitVulkan(int mode)
|
|||||||
#elif defined(_GLFW_WAYLAND)
|
#elif defined(_GLFW_WAYLAND)
|
||||||
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
|
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
|
||||||
_glfw.vk.KHR_wayland_surface = GLFW_TRUE;
|
_glfw.vk.KHR_wayland_surface = GLFW_TRUE;
|
||||||
#elif defined(_GLFW_MIR)
|
|
||||||
else if (strcmp(ep[i].extensionName, "VK_KHR_mir_surface") == 0)
|
|
||||||
_glfw.vk.KHR_mir_surface = GLFW_TRUE;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
60
src/external/glfw/src/wgl_context.c
vendored
60
src/external/glfw/src/wgl_context.c
vendored
@ -256,12 +256,20 @@ static void makeContextCurrentWGL(_GLFWwindow* window)
|
|||||||
|
|
||||||
static void swapBuffersWGL(_GLFWwindow* window)
|
static void swapBuffersWGL(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
// HACK: Use DwmFlush when desktop composition is enabled
|
if (!window->monitor)
|
||||||
if (_glfwIsCompositionEnabledWin32() && !window->monitor)
|
|
||||||
{
|
{
|
||||||
int count = abs(window->context.wgl.interval);
|
if (IsWindowsVistaOrGreater())
|
||||||
while (count--)
|
{
|
||||||
DwmFlush();
|
BOOL enabled;
|
||||||
|
|
||||||
|
// HACK: Use DwmFlush when desktop composition is enabled
|
||||||
|
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
|
||||||
|
{
|
||||||
|
int count = abs(window->context.wgl.interval);
|
||||||
|
while (count--)
|
||||||
|
DwmFlush();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SwapBuffers(window->context.wgl.dc);
|
SwapBuffers(window->context.wgl.dc);
|
||||||
@ -273,10 +281,18 @@ static void swapIntervalWGL(int interval)
|
|||||||
|
|
||||||
window->context.wgl.interval = interval;
|
window->context.wgl.interval = interval;
|
||||||
|
|
||||||
// HACK: Disable WGL swap interval when desktop composition is enabled to
|
if (!window->monitor)
|
||||||
// avoid interfering with DWM vsync
|
{
|
||||||
if (_glfwIsCompositionEnabledWin32() && !window->monitor)
|
if (IsWindowsVistaOrGreater())
|
||||||
interval = 0;
|
{
|
||||||
|
BOOL enabled;
|
||||||
|
|
||||||
|
// HACK: Disable WGL swap interval when desktop composition is enabled to
|
||||||
|
// avoid interfering with DWM vsync
|
||||||
|
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
|
||||||
|
interval = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_glfw.wgl.EXT_swap_control)
|
if (_glfw.wgl.EXT_swap_control)
|
||||||
_glfw.wgl.SwapIntervalEXT(interval);
|
_glfw.wgl.SwapIntervalEXT(interval);
|
||||||
@ -284,29 +300,17 @@ static void swapIntervalWGL(int interval)
|
|||||||
|
|
||||||
static int extensionSupportedWGL(const char* extension)
|
static int extensionSupportedWGL(const char* extension)
|
||||||
{
|
{
|
||||||
const char* extensions;
|
const char* extensions = NULL;
|
||||||
|
|
||||||
if (_glfw.wgl.GetExtensionsStringEXT)
|
|
||||||
{
|
|
||||||
extensions = _glfw.wgl.GetExtensionsStringEXT();
|
|
||||||
if (extensions)
|
|
||||||
{
|
|
||||||
if (_glfwStringInExtensionString(extension, extensions))
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.wgl.GetExtensionsStringARB)
|
if (_glfw.wgl.GetExtensionsStringARB)
|
||||||
{
|
|
||||||
extensions = _glfw.wgl.GetExtensionsStringARB(wglGetCurrentDC());
|
extensions = _glfw.wgl.GetExtensionsStringARB(wglGetCurrentDC());
|
||||||
if (extensions)
|
else if (_glfw.wgl.GetExtensionsStringEXT)
|
||||||
{
|
extensions = _glfw.wgl.GetExtensionsStringEXT();
|
||||||
if (_glfwStringInExtensionString(extension, extensions))
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_FALSE;
|
if (!extensions)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
return _glfwStringInExtensionString(extension, extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLFWglproc getProcAddressWGL(const char* procname)
|
static GLFWglproc getProcAddressWGL(const char* procname)
|
||||||
|
68
src/external/glfw/src/win32_init.c
vendored
68
src/external/glfw/src/win32_init.c
vendored
@ -62,17 +62,6 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
|
|||||||
|
|
||||||
#endif // _GLFW_BUILD_DLL
|
#endif // _GLFW_BUILD_DLL
|
||||||
|
|
||||||
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
|
|
||||||
BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp)
|
|
||||||
{
|
|
||||||
OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp };
|
|
||||||
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR;
|
|
||||||
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
|
||||||
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
|
||||||
cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
|
||||||
return VerifyVersionInfoW(&osvi, mask, cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load necessary libraries (DLLs)
|
// Load necessary libraries (DLLs)
|
||||||
//
|
//
|
||||||
static GLFWbool loadLibraries(void)
|
static GLFWbool loadLibraries(void)
|
||||||
@ -100,6 +89,14 @@ static GLFWbool loadLibraries(void)
|
|||||||
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware");
|
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware");
|
||||||
_glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
|
_glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
|
||||||
GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
|
GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
|
||||||
|
_glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling)
|
||||||
|
GetProcAddress(_glfw.win32.user32.instance, "EnableNonClientDpiScaling");
|
||||||
|
_glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext)
|
||||||
|
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext");
|
||||||
|
_glfw.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow)
|
||||||
|
GetProcAddress(_glfw.win32.user32.instance, "GetDpiForWindow");
|
||||||
|
_glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi)
|
||||||
|
GetProcAddress(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi");
|
||||||
|
|
||||||
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
|
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
|
||||||
if (_glfw.win32.dinput8.instance)
|
if (_glfw.win32.dinput8.instance)
|
||||||
@ -155,6 +152,13 @@ static GLFWbool loadLibraries(void)
|
|||||||
GetProcAddress(_glfw.win32.shcore.instance, "GetDpiForMonitor");
|
GetProcAddress(_glfw.win32.shcore.instance, "GetDpiForMonitor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfw.win32.ntdll.instance = LoadLibraryA("ntdll.dll");
|
||||||
|
if (_glfw.win32.ntdll.instance)
|
||||||
|
{
|
||||||
|
_glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo)
|
||||||
|
GetProcAddress(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
|
||||||
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,6 +183,9 @@ static void freeLibraries(void)
|
|||||||
|
|
||||||
if (_glfw.win32.shcore.instance)
|
if (_glfw.win32.shcore.instance)
|
||||||
FreeLibrary(_glfw.win32.shcore.instance);
|
FreeLibrary(_glfw.win32.shcore.instance);
|
||||||
|
|
||||||
|
if (_glfw.win32.ntdll.instance)
|
||||||
|
FreeLibrary(_glfw.win32.ntdll.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create key code translation tables
|
// Create key code translation tables
|
||||||
@ -309,6 +316,7 @@ static void createKeyTables(void)
|
|||||||
_glfw.win32.keycodes[0x053] = GLFW_KEY_KP_DECIMAL;
|
_glfw.win32.keycodes[0x053] = GLFW_KEY_KP_DECIMAL;
|
||||||
_glfw.win32.keycodes[0x135] = GLFW_KEY_KP_DIVIDE;
|
_glfw.win32.keycodes[0x135] = GLFW_KEY_KP_DIVIDE;
|
||||||
_glfw.win32.keycodes[0x11C] = GLFW_KEY_KP_ENTER;
|
_glfw.win32.keycodes[0x11C] = GLFW_KEY_KP_ENTER;
|
||||||
|
_glfw.win32.keycodes[0x059] = GLFW_KEY_KP_EQUAL;
|
||||||
_glfw.win32.keycodes[0x037] = GLFW_KEY_KP_MULTIPLY;
|
_glfw.win32.keycodes[0x037] = GLFW_KEY_KP_MULTIPLY;
|
||||||
_glfw.win32.keycodes[0x04A] = GLFW_KEY_KP_SUBTRACT;
|
_glfw.win32.keycodes[0x04A] = GLFW_KEY_KP_SUBTRACT;
|
||||||
|
|
||||||
@ -339,8 +347,8 @@ static HWND createHelperWindow(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK: The first call to ShowWindow is ignored if the parent process
|
// HACK: The command to the first ShowWindow call is ignored if the parent
|
||||||
// passed along a STARTUPINFO, so clear that flag with a no-op call
|
// process passed along a STARTUPINFO, so clear that with a no-op call
|
||||||
ShowWindow(window, SW_HIDE);
|
ShowWindow(window, SW_HIDE);
|
||||||
|
|
||||||
// Register for HID device notifications
|
// Register for HID device notifications
|
||||||
@ -502,6 +510,36 @@ void _glfwUpdateKeyNamesWin32(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replacement for IsWindowsVersionOrGreater as MinGW lacks versionhelpers.h
|
||||||
|
//
|
||||||
|
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp)
|
||||||
|
{
|
||||||
|
OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp };
|
||||||
|
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR;
|
||||||
|
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||||
|
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||||
|
cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||||
|
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
||||||
|
// latter lies unless the user knew to embedd a non-default manifest
|
||||||
|
// announcing support for Windows 10 via supportedOS GUID
|
||||||
|
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks whether we are on at least the specified build of Windows 10
|
||||||
|
//
|
||||||
|
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build)
|
||||||
|
{
|
||||||
|
OSVERSIONINFOEXW osvi = { sizeof(osvi), 10, 0, build };
|
||||||
|
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER;
|
||||||
|
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||||
|
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||||
|
cond = VerSetConditionMask(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL);
|
||||||
|
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
||||||
|
// latter lies unless the user knew to embedd a non-default manifest
|
||||||
|
// announcing support for Windows 10 via supportedOS GUID
|
||||||
|
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
@ -523,7 +561,9 @@ int _glfwPlatformInit(void)
|
|||||||
createKeyTables();
|
createKeyTables();
|
||||||
_glfwUpdateKeyNamesWin32();
|
_glfwUpdateKeyNamesWin32();
|
||||||
|
|
||||||
if (IsWindows8Point1OrGreater())
|
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
|
||||||
|
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||||
|
else if (IsWindows8Point1OrGreater())
|
||||||
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||||
else if (IsWindowsVistaOrGreater())
|
else if (IsWindowsVistaOrGreater())
|
||||||
SetProcessDPIAware();
|
SetProcessDPIAware();
|
||||||
|
2
src/external/glfw/src/win32_joystick.c
vendored
2
src/external/glfw/src/win32_joystick.c
vendored
@ -260,6 +260,8 @@ static void closeJoystick(_GLFWjoystick* js)
|
|||||||
IDirectInputDevice8_Release(js->win32.device);
|
IDirectInputDevice8_Release(js->win32.device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(js->win32.objects);
|
||||||
|
|
||||||
_glfwFreeJoystick(js);
|
_glfwFreeJoystick(js);
|
||||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||||
}
|
}
|
||||||
|
8
src/external/glfw/src/win32_monitor.c
vendored
8
src/external/glfw/src/win32_monitor.c
vendored
@ -324,9 +324,9 @@ void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* ysc
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (xscale)
|
if (xscale)
|
||||||
*xscale = xdpi / 96.f;
|
*xscale = xdpi / (float) USER_DEFAULT_SCREEN_DPI;
|
||||||
if (yscale)
|
if (yscale)
|
||||||
*yscale = ydpi / 96.f;
|
*yscale = ydpi / (float) USER_DEFAULT_SCREEN_DPI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -455,7 +455,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
|||||||
&mode->blueBits);
|
&mode->blueBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
{
|
{
|
||||||
HDC dc;
|
HDC dc;
|
||||||
WORD values[768];
|
WORD values[768];
|
||||||
@ -469,6 +469,8 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|||||||
memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short));
|
memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short));
|
||||||
memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short));
|
memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short));
|
||||||
memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short));
|
memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short));
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||||
|
69
src/external/glfw/src/win32_platform.h
vendored
69
src/external/glfw/src/win32_platform.h
vendored
@ -98,6 +98,12 @@
|
|||||||
#ifndef _WIN32_WINNT_WINBLUE
|
#ifndef _WIN32_WINNT_WINBLUE
|
||||||
#define _WIN32_WINNT_WINBLUE 0x0602
|
#define _WIN32_WINNT_WINBLUE 0x0602
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef WM_GETDPISCALEDSIZE
|
||||||
|
#define WM_GETDPISCALEDSIZE 0x02e4
|
||||||
|
#endif
|
||||||
|
#ifndef USER_DEFAULT_SCREEN_DPI
|
||||||
|
#define USER_DEFAULT_SCREEN_DPI 96
|
||||||
|
#endif
|
||||||
|
|
||||||
#if WINVER < 0x0601
|
#if WINVER < 0x0601
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -140,20 +146,31 @@ typedef enum
|
|||||||
} MONITOR_DPI_TYPE;
|
} MONITOR_DPI_TYPE;
|
||||||
#endif /*DPI_ENUMS_DECLARED*/
|
#endif /*DPI_ENUMS_DECLARED*/
|
||||||
|
|
||||||
|
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
|
||||||
|
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((HANDLE) -4)
|
||||||
|
#endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
|
||||||
|
|
||||||
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
|
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
|
||||||
BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp);
|
#define IsWindowsXPOrGreater() \
|
||||||
#define IsWindowsVistaOrGreater() \
|
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINXP), \
|
||||||
IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), \
|
LOBYTE(_WIN32_WINNT_WINXP), 0)
|
||||||
LOBYTE(_WIN32_WINNT_VISTA), 0)
|
#define IsWindowsVistaOrGreater() \
|
||||||
#define IsWindows7OrGreater() \
|
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
|
||||||
IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), \
|
LOBYTE(_WIN32_WINNT_VISTA), 0)
|
||||||
LOBYTE(_WIN32_WINNT_WIN7), 0)
|
#define IsWindows7OrGreater() \
|
||||||
#define IsWindows8OrGreater() \
|
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN7), \
|
||||||
IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), \
|
LOBYTE(_WIN32_WINNT_WIN7), 0)
|
||||||
LOBYTE(_WIN32_WINNT_WIN8), 0)
|
#define IsWindows8OrGreater() \
|
||||||
#define IsWindows8Point1OrGreater() \
|
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN8), \
|
||||||
IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), \
|
LOBYTE(_WIN32_WINNT_WIN8), 0)
|
||||||
LOBYTE(_WIN32_WINNT_WINBLUE), 0)
|
#define IsWindows8Point1OrGreater() \
|
||||||
|
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \
|
||||||
|
LOBYTE(_WIN32_WINNT_WINBLUE), 0)
|
||||||
|
|
||||||
|
#define _glfwIsWindows10AnniversaryUpdateOrGreaterWin32() \
|
||||||
|
_glfwIsWindows10BuildOrGreaterWin32(14393)
|
||||||
|
#define _glfwIsWindows10CreatorsUpdateOrGreaterWin32() \
|
||||||
|
_glfwIsWindows10BuildOrGreaterWin32(15063)
|
||||||
|
|
||||||
// HACK: Define macros that some xinput.h variants don't
|
// HACK: Define macros that some xinput.h variants don't
|
||||||
#ifndef XINPUT_CAPS_WIRELESS
|
#ifndef XINPUT_CAPS_WIRELESS
|
||||||
@ -206,8 +223,16 @@ typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*
|
|||||||
// user32.dll function pointer typedefs
|
// user32.dll function pointer typedefs
|
||||||
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
|
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
|
||||||
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*);
|
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*);
|
||||||
|
typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND);
|
||||||
|
typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE);
|
||||||
|
typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
|
||||||
|
typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
|
||||||
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
|
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
|
||||||
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
|
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
|
||||||
|
#define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_
|
||||||
|
#define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_
|
||||||
|
#define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_
|
||||||
|
#define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_
|
||||||
|
|
||||||
// dwmapi.dll function pointer typedefs
|
// dwmapi.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
||||||
@ -223,6 +248,10 @@ typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,
|
|||||||
#define SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness_
|
#define SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness_
|
||||||
#define GetDpiForMonitor _glfw.win32.shcore.GetDpiForMonitor_
|
#define GetDpiForMonitor _glfw.win32.shcore.GetDpiForMonitor_
|
||||||
|
|
||||||
|
// ntdll.dll function pointer typedefs
|
||||||
|
typedef LONG (WINAPI * PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*,ULONG,ULONGLONG);
|
||||||
|
#define RtlVerifyVersionInfo _glfw.win32.ntdll.RtlVerifyVersionInfo_
|
||||||
|
|
||||||
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
|
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
typedef struct VkWin32SurfaceCreateInfoKHR
|
typedef struct VkWin32SurfaceCreateInfoKHR
|
||||||
@ -276,6 +305,7 @@ typedef struct _GLFWwindowWin32
|
|||||||
GLFWbool maximized;
|
GLFWbool maximized;
|
||||||
// Whether to enable framebuffer transparency on DWM
|
// Whether to enable framebuffer transparency on DWM
|
||||||
GLFWbool transparent;
|
GLFWbool transparent;
|
||||||
|
GLFWbool scaleToMonitor;
|
||||||
|
|
||||||
// The last received cursor position, regardless of source
|
// The last received cursor position, regardless of source
|
||||||
int lastCursorPosX, lastCursorPosY;
|
int lastCursorPosX, lastCursorPosY;
|
||||||
@ -300,6 +330,7 @@ typedef struct _GLFWlibraryWin32
|
|||||||
_GLFWwindow* disabledCursorWindow;
|
_GLFWwindow* disabledCursorWindow;
|
||||||
RAWINPUT* rawInput;
|
RAWINPUT* rawInput;
|
||||||
int rawInputSize;
|
int rawInputSize;
|
||||||
|
UINT mouseTrailSize;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
@ -322,6 +353,10 @@ typedef struct _GLFWlibraryWin32
|
|||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
PFN_SetProcessDPIAware SetProcessDPIAware_;
|
PFN_SetProcessDPIAware SetProcessDPIAware_;
|
||||||
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
|
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
|
||||||
|
PFN_EnableNonClientDpiScaling EnableNonClientDpiScaling_;
|
||||||
|
PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
|
||||||
|
PFN_GetDpiForWindow GetDpiForWindow_;
|
||||||
|
PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_;
|
||||||
} user32;
|
} user32;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -337,6 +372,11 @@ typedef struct _GLFWlibraryWin32
|
|||||||
PFN_GetDpiForMonitor GetDpiForMonitor_;
|
PFN_GetDpiForMonitor GetDpiForMonitor_;
|
||||||
} shcore;
|
} shcore;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
HINSTANCE instance;
|
||||||
|
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
|
||||||
|
} ntdll;
|
||||||
|
|
||||||
} _GLFWlibraryWin32;
|
} _GLFWlibraryWin32;
|
||||||
|
|
||||||
// Win32-specific per-monitor data
|
// Win32-specific per-monitor data
|
||||||
@ -392,10 +432,11 @@ typedef struct _GLFWmutexWin32
|
|||||||
|
|
||||||
GLFWbool _glfwRegisterWindowClassWin32(void);
|
GLFWbool _glfwRegisterWindowClassWin32(void);
|
||||||
void _glfwUnregisterWindowClassWin32(void);
|
void _glfwUnregisterWindowClassWin32(void);
|
||||||
GLFWbool _glfwIsCompositionEnabledWin32(void);
|
|
||||||
|
|
||||||
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
|
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
|
||||||
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
|
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
|
||||||
|
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp);
|
||||||
|
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build);
|
||||||
void _glfwInputErrorWin32(int error, const char* description);
|
void _glfwInputErrorWin32(int error, const char* description);
|
||||||
void _glfwUpdateKeyNamesWin32(void);
|
void _glfwUpdateKeyNamesWin32(void);
|
||||||
|
|
||||||
|
299
src/external/glfw/src/win32_window.c
vendored
299
src/external/glfw/src/win32_window.c
vendored
@ -186,14 +186,20 @@ static HICON createIcon(const GLFWimage* image,
|
|||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translate client window size to full window size according to styles
|
// Translate client window size to full window size according to styles and DPI
|
||||||
//
|
//
|
||||||
static void getFullWindowSize(DWORD style, DWORD exStyle,
|
static void getFullWindowSize(DWORD style, DWORD exStyle,
|
||||||
int clientWidth, int clientHeight,
|
int clientWidth, int clientHeight,
|
||||||
int* fullWidth, int* fullHeight)
|
int* fullWidth, int* fullHeight,
|
||||||
|
UINT dpi)
|
||||||
{
|
{
|
||||||
RECT rect = { 0, 0, clientWidth, clientHeight };
|
RECT rect = { 0, 0, clientWidth, clientHeight };
|
||||||
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
|
||||||
|
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||||
|
AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi);
|
||||||
|
else
|
||||||
|
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
||||||
|
|
||||||
*fullWidth = rect.right - rect.left;
|
*fullWidth = rect.right - rect.left;
|
||||||
*fullHeight = rect.bottom - rect.top;
|
*fullHeight = rect.bottom - rect.top;
|
||||||
}
|
}
|
||||||
@ -203,10 +209,14 @@ static void getFullWindowSize(DWORD style, DWORD exStyle,
|
|||||||
static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area)
|
static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area)
|
||||||
{
|
{
|
||||||
int xoff, yoff;
|
int xoff, yoff;
|
||||||
|
UINT dpi = USER_DEFAULT_SCREEN_DPI;
|
||||||
const float ratio = (float) window->numer / (float) window->denom;
|
const float ratio = (float) window->numer / (float) window->denom;
|
||||||
|
|
||||||
|
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||||
|
dpi = GetDpiForWindow(window->win32.handle);
|
||||||
|
|
||||||
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
|
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
|
||||||
0, 0, &xoff, &yoff);
|
0, 0, &xoff, &yoff, dpi);
|
||||||
|
|
||||||
if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT ||
|
if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT ||
|
||||||
edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT)
|
edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT)
|
||||||
@ -337,7 +347,16 @@ static void updateWindowStyles(const _GLFWwindow* window)
|
|||||||
style |= getWindowStyle(window);
|
style |= getWindowStyle(window);
|
||||||
|
|
||||||
GetClientRect(window->win32.handle, &rect);
|
GetClientRect(window->win32.handle, &rect);
|
||||||
AdjustWindowRectEx(&rect, style, FALSE, getWindowExStyle(window));
|
|
||||||
|
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||||
|
{
|
||||||
|
AdjustWindowRectExForDpi(&rect, style, FALSE,
|
||||||
|
getWindowExStyle(window),
|
||||||
|
GetDpiForWindow(window->win32.handle));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
AdjustWindowRectEx(&rect, style, FALSE, getWindowExStyle(window));
|
||||||
|
|
||||||
ClientToScreen(window->win32.handle, (POINT*) &rect.left);
|
ClientToScreen(window->win32.handle, (POINT*) &rect.left);
|
||||||
ClientToScreen(window->win32.handle, (POINT*) &rect.right);
|
ClientToScreen(window->win32.handle, (POINT*) &rect.right);
|
||||||
SetWindowLongW(window->win32.handle, GWL_STYLE, style);
|
SetWindowLongW(window->win32.handle, GWL_STYLE, style);
|
||||||
@ -351,10 +370,12 @@ static void updateWindowStyles(const _GLFWwindow* window)
|
|||||||
//
|
//
|
||||||
static void updateFramebufferTransparency(const _GLFWwindow* window)
|
static void updateFramebufferTransparency(const _GLFWwindow* window)
|
||||||
{
|
{
|
||||||
|
BOOL enabled;
|
||||||
|
|
||||||
if (!IsWindowsVistaOrGreater())
|
if (!IsWindowsVistaOrGreater())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_glfwIsCompositionEnabledWin32())
|
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
|
||||||
{
|
{
|
||||||
HRGN region = CreateRectRgn(0, 0, -1, -1);
|
HRGN region = CreateRectRgn(0, 0, -1, -1);
|
||||||
DWM_BLURBEHIND bb = {0};
|
DWM_BLURBEHIND bb = {0};
|
||||||
@ -396,29 +417,6 @@ static void updateFramebufferTransparency(const _GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translates a GLFW standard cursor to a resource ID
|
|
||||||
//
|
|
||||||
static LPWSTR translateCursorShape(int shape)
|
|
||||||
{
|
|
||||||
switch (shape)
|
|
||||||
{
|
|
||||||
case GLFW_ARROW_CURSOR:
|
|
||||||
return IDC_ARROW;
|
|
||||||
case GLFW_IBEAM_CURSOR:
|
|
||||||
return IDC_IBEAM;
|
|
||||||
case GLFW_CROSSHAIR_CURSOR:
|
|
||||||
return IDC_CROSS;
|
|
||||||
case GLFW_HAND_CURSOR:
|
|
||||||
return IDC_HAND;
|
|
||||||
case GLFW_HRESIZE_CURSOR:
|
|
||||||
return IDC_SIZEWE;
|
|
||||||
case GLFW_VRESIZE_CURSOR:
|
|
||||||
return IDC_SIZENS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieves and translates modifier keys
|
// Retrieves and translates modifier keys
|
||||||
//
|
//
|
||||||
static int getKeyMods(void)
|
static int getKeyMods(void)
|
||||||
@ -529,7 +527,18 @@ static void fitToMonitor(_GLFWwindow* window)
|
|||||||
static void acquireMonitor(_GLFWwindow* window)
|
static void acquireMonitor(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (!_glfw.win32.acquiredMonitorCount)
|
if (!_glfw.win32.acquiredMonitorCount)
|
||||||
|
{
|
||||||
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
|
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
|
||||||
|
|
||||||
|
// HACK: When mouse trails are enabled the cursor becomes invisible when
|
||||||
|
// the OpenGL ICD switches to page flipping
|
||||||
|
if (IsWindowsXPOrGreater())
|
||||||
|
{
|
||||||
|
SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &_glfw.win32.mouseTrailSize, 0);
|
||||||
|
SystemParametersInfo(SPI_SETMOUSETRAILS, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!window->monitor->window)
|
if (!window->monitor->window)
|
||||||
_glfw.win32.acquiredMonitorCount++;
|
_glfw.win32.acquiredMonitorCount++;
|
||||||
|
|
||||||
@ -546,8 +555,14 @@ static void releaseMonitor(_GLFWwindow* window)
|
|||||||
|
|
||||||
_glfw.win32.acquiredMonitorCount--;
|
_glfw.win32.acquiredMonitorCount--;
|
||||||
if (!_glfw.win32.acquiredMonitorCount)
|
if (!_glfw.win32.acquiredMonitorCount)
|
||||||
|
{
|
||||||
SetThreadExecutionState(ES_CONTINUOUS);
|
SetThreadExecutionState(ES_CONTINUOUS);
|
||||||
|
|
||||||
|
// HACK: Restore mouse trail length saved in acquireMonitor
|
||||||
|
if (IsWindowsXPOrGreater())
|
||||||
|
SystemParametersInfo(SPI_SETMOUSETRAILS, _glfw.win32.mouseTrailSize, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
_glfwInputMonitorWindow(window->monitor, NULL);
|
_glfwInputMonitorWindow(window->monitor, NULL);
|
||||||
_glfwRestoreVideoModeWin32(window->monitor);
|
_glfwRestoreVideoModeWin32(window->monitor);
|
||||||
}
|
}
|
||||||
@ -561,9 +576,18 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
// This is the message handling for the hidden helper window
|
// This is the message handling for the hidden helper window
|
||||||
|
// and for a regular window during its initial creation
|
||||||
|
|
||||||
switch (uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
|
case WM_NCCREATE:
|
||||||
|
{
|
||||||
|
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||||
|
EnableNonClientDpiScaling(hWnd);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WM_DISPLAYCHANGE:
|
case WM_DISPLAYCHANGE:
|
||||||
_glfwPollMonitorsWin32();
|
_glfwPollMonitorsWin32();
|
||||||
break;
|
break;
|
||||||
@ -980,13 +1004,17 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
case WM_GETMINMAXINFO:
|
case WM_GETMINMAXINFO:
|
||||||
{
|
{
|
||||||
int xoff, yoff;
|
int xoff, yoff;
|
||||||
|
UINT dpi = USER_DEFAULT_SCREEN_DPI;
|
||||||
MINMAXINFO* mmi = (MINMAXINFO*) lParam;
|
MINMAXINFO* mmi = (MINMAXINFO*) lParam;
|
||||||
|
|
||||||
if (window->monitor)
|
if (window->monitor)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||||
|
dpi = GetDpiForWindow(window->win32.handle);
|
||||||
|
|
||||||
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
|
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
|
||||||
0, 0, &xoff, &yoff);
|
0, 0, &xoff, &yoff, dpi);
|
||||||
|
|
||||||
if (window->minwidth != GLFW_DONT_CARE &&
|
if (window->minwidth != GLFW_DONT_CARE &&
|
||||||
window->minheight != GLFW_DONT_CARE)
|
window->minheight != GLFW_DONT_CARE)
|
||||||
@ -1032,6 +1060,17 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_NCACTIVATE:
|
||||||
|
case WM_NCPAINT:
|
||||||
|
{
|
||||||
|
// Prevent title bar from being drawn after restoring a minimized
|
||||||
|
// undecorated window
|
||||||
|
if (!window->decorated)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WM_DWMCOMPOSITIONCHANGED:
|
case WM_DWMCOMPOSITIONCHANGED:
|
||||||
{
|
{
|
||||||
if (window->win32.transparent)
|
if (window->win32.transparent)
|
||||||
@ -1039,10 +1078,52 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_GETDPISCALEDSIZE:
|
||||||
|
{
|
||||||
|
if (window->win32.scaleToMonitor)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Adjust the window size to keep the client area size constant
|
||||||
|
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
|
||||||
|
{
|
||||||
|
RECT source = {0}, target = {0};
|
||||||
|
SIZE* size = (SIZE*) lParam;
|
||||||
|
|
||||||
|
AdjustWindowRectExForDpi(&source, getWindowStyle(window),
|
||||||
|
FALSE, getWindowExStyle(window),
|
||||||
|
GetDpiForWindow(window->win32.handle));
|
||||||
|
AdjustWindowRectExForDpi(&target, getWindowStyle(window),
|
||||||
|
FALSE, getWindowExStyle(window),
|
||||||
|
LOWORD(wParam));
|
||||||
|
|
||||||
|
size->cx += (target.right - target.left) -
|
||||||
|
(source.right - source.left);
|
||||||
|
size->cy += (target.bottom - target.top) -
|
||||||
|
(source.bottom - source.top);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WM_DPICHANGED:
|
case WM_DPICHANGED:
|
||||||
{
|
{
|
||||||
const float xscale = HIWORD(wParam) / 96.f;
|
const float xscale = HIWORD(wParam) / (float) USER_DEFAULT_SCREEN_DPI;
|
||||||
const float yscale = LOWORD(wParam) / 96.f;
|
const float yscale = LOWORD(wParam) / (float) USER_DEFAULT_SCREEN_DPI;
|
||||||
|
|
||||||
|
// Only apply the suggested size if the OS is new enough to have
|
||||||
|
// sent a WM_GETDPISCALEDSIZE before this
|
||||||
|
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
|
||||||
|
{
|
||||||
|
RECT* suggested = (RECT*) lParam;
|
||||||
|
SetWindowPos(window->win32.handle, HWND_TOP,
|
||||||
|
suggested->left,
|
||||||
|
suggested->top,
|
||||||
|
suggested->right - suggested->left,
|
||||||
|
suggested->bottom - suggested->top,
|
||||||
|
SWP_NOACTIVATE | SWP_NOZORDER);
|
||||||
|
}
|
||||||
|
|
||||||
_glfwInputWindowContentScale(window, xscale, yscale);
|
_glfwInputWindowContentScale(window, xscale, yscale);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1129,7 +1210,8 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
getFullWindowSize(style, exStyle,
|
getFullWindowSize(style, exStyle,
|
||||||
wndconfig->width, wndconfig->height,
|
wndconfig->width, wndconfig->height,
|
||||||
&fullWidth, &fullHeight);
|
&fullWidth, &fullHeight,
|
||||||
|
USER_DEFAULT_SCREEN_DPI);
|
||||||
}
|
}
|
||||||
|
|
||||||
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
|
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
|
||||||
@ -1168,6 +1250,40 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
|
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window->win32.scaleToMonitor = wndconfig->scaleToMonitor;
|
||||||
|
|
||||||
|
// Adjust window size to account for DPI scaling of the window frame and
|
||||||
|
// optionally DPI scaling of the client area
|
||||||
|
// This cannot be done until we know what monitor it was placed on
|
||||||
|
if (!window->monitor)
|
||||||
|
{
|
||||||
|
RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
|
||||||
|
|
||||||
|
if (wndconfig->scaleToMonitor)
|
||||||
|
{
|
||||||
|
float xscale, yscale;
|
||||||
|
_glfwPlatformGetWindowContentScale(window, &xscale, &yscale);
|
||||||
|
rect.right = (int) (rect.right * xscale);
|
||||||
|
rect.bottom = (int) (rect.bottom * yscale);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientToScreen(window->win32.handle, (POINT*) &rect.left);
|
||||||
|
ClientToScreen(window->win32.handle, (POINT*) &rect.right);
|
||||||
|
|
||||||
|
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||||
|
{
|
||||||
|
AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle,
|
||||||
|
GetDpiForWindow(window->win32.handle));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
||||||
|
|
||||||
|
SetWindowPos(window->win32.handle, NULL,
|
||||||
|
rect.left, rect.top,
|
||||||
|
rect.right - rect.left, rect.bottom - rect.top,
|
||||||
|
SWP_NOACTIVATE | SWP_NOZORDER);
|
||||||
|
}
|
||||||
|
|
||||||
DragAcceptFiles(window->win32.handle, TRUE);
|
DragAcceptFiles(window->win32.handle, TRUE);
|
||||||
|
|
||||||
if (fbconfig->transparent)
|
if (fbconfig->transparent)
|
||||||
@ -1227,20 +1343,6 @@ void _glfwUnregisterWindowClassWin32(void)
|
|||||||
UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL));
|
UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether desktop compositing is enabled
|
|
||||||
//
|
|
||||||
GLFWbool _glfwIsCompositionEnabledWin32(void)
|
|
||||||
{
|
|
||||||
if (IsWindowsVistaOrGreater())
|
|
||||||
{
|
|
||||||
BOOL enabled;
|
|
||||||
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)))
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
@ -1378,8 +1480,19 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
|||||||
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
|
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
|
||||||
{
|
{
|
||||||
RECT rect = { xpos, ypos, xpos, ypos };
|
RECT rect = { xpos, ypos, xpos, ypos };
|
||||||
AdjustWindowRectEx(&rect, getWindowStyle(window),
|
|
||||||
FALSE, getWindowExStyle(window));
|
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||||
|
{
|
||||||
|
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
||||||
|
FALSE, getWindowExStyle(window),
|
||||||
|
GetDpiForWindow(window->win32.handle));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AdjustWindowRectEx(&rect, getWindowStyle(window),
|
||||||
|
FALSE, getWindowExStyle(window));
|
||||||
|
}
|
||||||
|
|
||||||
SetWindowPos(window->win32.handle, NULL, rect.left, rect.top, 0, 0,
|
SetWindowPos(window->win32.handle, NULL, rect.left, rect.top, 0, 0,
|
||||||
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
|
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
|
||||||
}
|
}
|
||||||
@ -1408,8 +1521,19 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
RECT rect = { 0, 0, width, height };
|
RECT rect = { 0, 0, width, height };
|
||||||
AdjustWindowRectEx(&rect, getWindowStyle(window),
|
|
||||||
FALSE, getWindowExStyle(window));
|
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||||
|
{
|
||||||
|
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
||||||
|
FALSE, getWindowExStyle(window),
|
||||||
|
GetDpiForWindow(window->win32.handle));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AdjustWindowRectEx(&rect, getWindowStyle(window),
|
||||||
|
FALSE, getWindowExStyle(window));
|
||||||
|
}
|
||||||
|
|
||||||
SetWindowPos(window->win32.handle, HWND_TOP,
|
SetWindowPos(window->win32.handle, HWND_TOP,
|
||||||
0, 0, rect.right - rect.left, rect.bottom - rect.top,
|
0, 0, rect.right - rect.left, rect.bottom - rect.top,
|
||||||
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER);
|
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER);
|
||||||
@ -1464,8 +1588,18 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
|||||||
|
|
||||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||||
SetRect(&rect, 0, 0, width, height);
|
SetRect(&rect, 0, 0, width, height);
|
||||||
AdjustWindowRectEx(&rect, getWindowStyle(window),
|
|
||||||
FALSE, getWindowExStyle(window));
|
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||||
|
{
|
||||||
|
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
||||||
|
FALSE, getWindowExStyle(window),
|
||||||
|
GetDpiForWindow(window->win32.handle));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AdjustWindowRectEx(&rect, getWindowStyle(window),
|
||||||
|
FALSE, getWindowExStyle(window));
|
||||||
|
}
|
||||||
|
|
||||||
if (left)
|
if (left)
|
||||||
*left = -rect.left;
|
*left = -rect.left;
|
||||||
@ -1541,8 +1675,19 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
RECT rect = { xpos, ypos, xpos + width, ypos + height };
|
RECT rect = { xpos, ypos, xpos + width, ypos + height };
|
||||||
AdjustWindowRectEx(&rect, getWindowStyle(window),
|
|
||||||
FALSE, getWindowExStyle(window));
|
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||||
|
{
|
||||||
|
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
||||||
|
FALSE, getWindowExStyle(window),
|
||||||
|
GetDpiForWindow(window->win32.handle));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AdjustWindowRectEx(&rect, getWindowStyle(window),
|
||||||
|
FALSE, getWindowExStyle(window));
|
||||||
|
}
|
||||||
|
|
||||||
SetWindowPos(window->win32.handle, HWND_TOP,
|
SetWindowPos(window->win32.handle, HWND_TOP,
|
||||||
rect.left, rect.top,
|
rect.left, rect.top,
|
||||||
rect.right - rect.left, rect.bottom - rect.top,
|
rect.right - rect.left, rect.bottom - rect.top,
|
||||||
@ -1602,8 +1747,18 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
|||||||
else
|
else
|
||||||
after = HWND_NOTOPMOST;
|
after = HWND_NOTOPMOST;
|
||||||
|
|
||||||
AdjustWindowRectEx(&rect, getWindowStyle(window),
|
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||||
FALSE, getWindowExStyle(window));
|
{
|
||||||
|
AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
|
||||||
|
FALSE, getWindowExStyle(window),
|
||||||
|
GetDpiForWindow(window->win32.handle));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AdjustWindowRectEx(&rect, getWindowStyle(window),
|
||||||
|
FALSE, getWindowExStyle(window));
|
||||||
|
}
|
||||||
|
|
||||||
SetWindowPos(window->win32.handle, after,
|
SetWindowPos(window->win32.handle, after,
|
||||||
rect.left, rect.top,
|
rect.left, rect.top,
|
||||||
rect.right - rect.left, rect.bottom - rect.top,
|
rect.right - rect.left, rect.bottom - rect.top,
|
||||||
@ -1638,7 +1793,15 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window)
|
|||||||
|
|
||||||
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
return window->win32.transparent && _glfwIsCompositionEnabledWin32();
|
BOOL enabled;
|
||||||
|
|
||||||
|
if (!window->win32.transparent)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
if (!IsWindowsVistaOrGreater())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
return SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||||
@ -1845,8 +2008,24 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
|
|
||||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||||
{
|
{
|
||||||
cursor->win32.handle =
|
LPCWSTR name = NULL;
|
||||||
CopyCursor(LoadCursorW(NULL, translateCursorShape(shape)));
|
|
||||||
|
if (shape == GLFW_ARROW_CURSOR)
|
||||||
|
name = IDC_ARROW;
|
||||||
|
else if (shape == GLFW_IBEAM_CURSOR)
|
||||||
|
name = IDC_IBEAM;
|
||||||
|
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||||
|
name = IDC_CROSS;
|
||||||
|
else if (shape == GLFW_HAND_CURSOR)
|
||||||
|
name = IDC_HAND;
|
||||||
|
else if (shape == GLFW_HRESIZE_CURSOR)
|
||||||
|
name = IDC_SIZEWE;
|
||||||
|
else if (shape == GLFW_VRESIZE_CURSOR)
|
||||||
|
name = IDC_SIZENS;
|
||||||
|
else
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
cursor->win32.handle = CopyCursor(LoadCursorW(NULL, name));
|
||||||
if (!cursor->win32.handle)
|
if (!cursor->win32.handle)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
3
src/external/glfw/src/window.c
vendored
3
src/external/glfw/src/window.c
vendored
@ -369,6 +369,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
|||||||
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
||||||
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
return;
|
||||||
|
case GLFW_SCALE_TO_MONITOR:
|
||||||
|
_glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
|
return;
|
||||||
case GLFW_CENTER_CURSOR:
|
case GLFW_CENTER_CURSOR:
|
||||||
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
return;
|
||||||
|
183
src/external/glfw/src/wl_init.c
vendored
183
src/external/glfw/src/wl_init.c
vendored
@ -27,6 +27,8 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -42,7 +44,8 @@ static inline int min(int n1, int n2)
|
|||||||
return n1 < n2 ? n1 : n2;
|
return n1 < n2 ? n1 : n2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, int* which)
|
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
|
||||||
|
int* which)
|
||||||
{
|
{
|
||||||
int focus;
|
int focus;
|
||||||
_GLFWwindow* window = _glfw.windowListHead;
|
_GLFWwindow* window = _glfw.windowListHead;
|
||||||
@ -96,7 +99,7 @@ static void pointerHandleEnter(void* data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
window->wl.decorations.focus = focus;
|
window->wl.decorations.focus = focus;
|
||||||
_glfw.wl.pointerSerial = serial;
|
_glfw.wl.serial = serial;
|
||||||
_glfw.wl.pointerFocus = window;
|
_glfw.wl.pointerFocus = window;
|
||||||
|
|
||||||
window->wl.hovered = GLFW_TRUE;
|
window->wl.hovered = GLFW_TRUE;
|
||||||
@ -117,26 +120,36 @@ static void pointerHandleLeave(void* data,
|
|||||||
|
|
||||||
window->wl.hovered = GLFW_FALSE;
|
window->wl.hovered = GLFW_FALSE;
|
||||||
|
|
||||||
_glfw.wl.pointerSerial = serial;
|
_glfw.wl.serial = serial;
|
||||||
_glfw.wl.pointerFocus = NULL;
|
_glfw.wl.pointerFocus = NULL;
|
||||||
_glfwInputCursorEnter(window, GLFW_FALSE);
|
_glfwInputCursorEnter(window, GLFW_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setCursor(const char* name)
|
static void setCursor(_GLFWwindow* window, const char* name)
|
||||||
{
|
{
|
||||||
struct wl_buffer* buffer;
|
struct wl_buffer* buffer;
|
||||||
struct wl_cursor* cursor;
|
struct wl_cursor* cursor;
|
||||||
struct wl_cursor_image* image;
|
struct wl_cursor_image* image;
|
||||||
struct wl_surface* surface = _glfw.wl.cursorSurface;
|
struct wl_surface* surface = _glfw.wl.cursorSurface;
|
||||||
|
struct wl_cursor_theme* theme = _glfw.wl.cursorTheme;
|
||||||
|
int scale = 1;
|
||||||
|
|
||||||
cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,
|
if (window->wl.scale > 1 && _glfw.wl.cursorThemeHiDPI)
|
||||||
name);
|
{
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor = wl_cursor_theme_get_cursor(theme, name);
|
||||||
if (!cursor)
|
if (!cursor)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Wayland: Standard cursor not found");
|
"Wayland: Standard cursor not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// TODO: handle animated cursors too.
|
||||||
image = cursor->images[0];
|
image = cursor->images[0];
|
||||||
|
|
||||||
if (!image)
|
if (!image)
|
||||||
@ -145,10 +158,11 @@ static void setCursor(const char* name)
|
|||||||
buffer = wl_cursor_image_get_buffer(image);
|
buffer = wl_cursor_image_get_buffer(image);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return;
|
return;
|
||||||
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial,
|
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial,
|
||||||
surface,
|
surface,
|
||||||
image->hotspot_x,
|
image->hotspot_x / scale,
|
||||||
image->hotspot_y);
|
image->hotspot_y / scale);
|
||||||
|
wl_surface_set_buffer_scale(surface, scale);
|
||||||
wl_surface_attach(surface, buffer, 0, 0);
|
wl_surface_attach(surface, buffer, 0, 0);
|
||||||
wl_surface_damage(surface, 0, 0,
|
wl_surface_damage(surface, 0, 0,
|
||||||
image->width, image->height);
|
image->width, image->height);
|
||||||
@ -211,7 +225,7 @@ static void pointerHandleMotion(void* data,
|
|||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
setCursor(cursorName);
|
setCursor(window, cursorName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pointerHandleButton(void* data,
|
static void pointerHandleButton(void* data,
|
||||||
@ -295,7 +309,7 @@ static void pointerHandleButton(void* data,
|
|||||||
if (window->wl.decorations.focus != mainWindow)
|
if (window->wl.decorations.focus != mainWindow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_glfw.wl.pointerSerial = serial;
|
_glfw.wl.serial = serial;
|
||||||
|
|
||||||
/* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
|
/* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
|
||||||
* codes. */
|
* codes. */
|
||||||
@ -464,6 +478,7 @@ static void keyboardHandleEnter(void* data,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfw.wl.serial = serial;
|
||||||
_glfw.wl.keyboardFocus = window;
|
_glfw.wl.keyboardFocus = window;
|
||||||
_glfwInputWindowFocus(window, GLFW_TRUE);
|
_glfwInputWindowFocus(window, GLFW_TRUE);
|
||||||
}
|
}
|
||||||
@ -478,6 +493,7 @@ static void keyboardHandleLeave(void* data,
|
|||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
_glfw.wl.serial = serial;
|
||||||
_glfw.wl.keyboardFocus = NULL;
|
_glfw.wl.keyboardFocus = NULL;
|
||||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||||
}
|
}
|
||||||
@ -561,6 +577,7 @@ static void keyboardHandleKey(void* data,
|
|||||||
action = state == WL_KEYBOARD_KEY_STATE_PRESSED
|
action = state == WL_KEYBOARD_KEY_STATE_PRESSED
|
||||||
? GLFW_PRESS : GLFW_RELEASE;
|
? GLFW_PRESS : GLFW_RELEASE;
|
||||||
|
|
||||||
|
_glfw.wl.serial = serial;
|
||||||
_glfwInputKey(window, keyCode, key, action,
|
_glfwInputKey(window, keyCode, key, action,
|
||||||
_glfw.wl.xkb.modifiers);
|
_glfw.wl.xkb.modifiers);
|
||||||
|
|
||||||
@ -592,6 +609,8 @@ static void keyboardHandleModifiers(void* data,
|
|||||||
xkb_mod_mask_t mask;
|
xkb_mod_mask_t mask;
|
||||||
unsigned int modifiers = 0;
|
unsigned int modifiers = 0;
|
||||||
|
|
||||||
|
_glfw.wl.serial = serial;
|
||||||
|
|
||||||
if (!_glfw.wl.xkb.keymap)
|
if (!_glfw.wl.xkb.keymap)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -686,6 +705,70 @@ static const struct wl_seat_listener seatListener = {
|
|||||||
seatHandleName,
|
seatHandleName,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void dataOfferHandleOffer(void* data,
|
||||||
|
struct wl_data_offer* dataOffer,
|
||||||
|
const char* mimeType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_data_offer_listener dataOfferListener = {
|
||||||
|
dataOfferHandleOffer,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void dataDeviceHandleDataOffer(void* data,
|
||||||
|
struct wl_data_device* dataDevice,
|
||||||
|
struct wl_data_offer* id)
|
||||||
|
{
|
||||||
|
if (_glfw.wl.dataOffer)
|
||||||
|
wl_data_offer_destroy(_glfw.wl.dataOffer);
|
||||||
|
|
||||||
|
_glfw.wl.dataOffer = id;
|
||||||
|
wl_data_offer_add_listener(_glfw.wl.dataOffer, &dataOfferListener, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dataDeviceHandleEnter(void* data,
|
||||||
|
struct wl_data_device* dataDevice,
|
||||||
|
uint32_t serial,
|
||||||
|
struct wl_surface *surface,
|
||||||
|
wl_fixed_t x,
|
||||||
|
wl_fixed_t y,
|
||||||
|
struct wl_data_offer *id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dataDeviceHandleLeave(void* data,
|
||||||
|
struct wl_data_device* dataDevice)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dataDeviceHandleMotion(void* data,
|
||||||
|
struct wl_data_device* dataDevice,
|
||||||
|
uint32_t time,
|
||||||
|
wl_fixed_t x,
|
||||||
|
wl_fixed_t y)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dataDeviceHandleDrop(void* data,
|
||||||
|
struct wl_data_device* dataDevice)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dataDeviceHandleSelection(void* data,
|
||||||
|
struct wl_data_device* dataDevice,
|
||||||
|
struct wl_data_offer* id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_data_device_listener dataDeviceListener = {
|
||||||
|
dataDeviceHandleDataOffer,
|
||||||
|
dataDeviceHandleEnter,
|
||||||
|
dataDeviceHandleLeave,
|
||||||
|
dataDeviceHandleMotion,
|
||||||
|
dataDeviceHandleDrop,
|
||||||
|
dataDeviceHandleSelection,
|
||||||
|
};
|
||||||
|
|
||||||
static void wmBaseHandlePing(void* data,
|
static void wmBaseHandlePing(void* data,
|
||||||
struct xdg_wm_base* wmBase,
|
struct xdg_wm_base* wmBase,
|
||||||
uint32_t serial)
|
uint32_t serial)
|
||||||
@ -740,12 +823,28 @@ static void registryHandleGlobal(void* data,
|
|||||||
wl_seat_add_listener(_glfw.wl.seat, &seatListener, NULL);
|
wl_seat_add_listener(_glfw.wl.seat, &seatListener, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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)
|
else if (strcmp(interface, "xdg_wm_base") == 0)
|
||||||
{
|
{
|
||||||
_glfw.wl.wmBase =
|
_glfw.wl.wmBase =
|
||||||
wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
|
wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
|
||||||
xdg_wm_base_add_listener(_glfw.wl.wmBase, &wmBaseListener, NULL);
|
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)
|
else if (strcmp(interface, "wp_viewporter") == 0)
|
||||||
{
|
{
|
||||||
_glfw.wl.viewporter =
|
_glfw.wl.viewporter =
|
||||||
@ -939,6 +1038,12 @@ static void createKeyTables(void)
|
|||||||
|
|
||||||
int _glfwPlatformInit(void)
|
int _glfwPlatformInit(void)
|
||||||
{
|
{
|
||||||
|
const char *cursorTheme;
|
||||||
|
const char *cursorSizeStr;
|
||||||
|
char *cursorSizeEnd;
|
||||||
|
long cursorSizeLong;
|
||||||
|
int cursorSize;
|
||||||
|
|
||||||
_glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
|
_glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
|
||||||
if (!_glfw.wl.cursor.handle)
|
if (!_glfw.wl.cursor.handle)
|
||||||
{
|
{
|
||||||
@ -1059,15 +1164,46 @@ int _glfwPlatformInit(void)
|
|||||||
|
|
||||||
if (_glfw.wl.pointer && _glfw.wl.shm)
|
if (_glfw.wl.pointer && _glfw.wl.shm)
|
||||||
{
|
{
|
||||||
_glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 32, _glfw.wl.shm);
|
cursorTheme = getenv("XCURSOR_THEME");
|
||||||
|
cursorSizeStr = getenv("XCURSOR_SIZE");
|
||||||
|
cursorSize = 32;
|
||||||
|
if (cursorSizeStr)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
cursorSizeLong = strtol(cursorSizeStr, &cursorSizeEnd, 10);
|
||||||
|
if (!*cursorSizeEnd && !errno && cursorSizeLong > 0 && cursorSizeLong <= INT_MAX)
|
||||||
|
cursorSize = (int)cursorSizeLong;
|
||||||
|
}
|
||||||
|
_glfw.wl.cursorTheme =
|
||||||
|
wl_cursor_theme_load(cursorTheme, cursorSize, _glfw.wl.shm);
|
||||||
if (!_glfw.wl.cursorTheme)
|
if (!_glfw.wl.cursorTheme)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Wayland: Unable to load default cursor theme");
|
"Wayland: Unable to load default cursor theme");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
// If this happens to be NULL, we just fallback to the scale=1 version.
|
||||||
|
_glfw.wl.cursorThemeHiDPI =
|
||||||
|
wl_cursor_theme_load(cursorTheme, 2 * cursorSize, _glfw.wl.shm);
|
||||||
_glfw.wl.cursorSurface =
|
_glfw.wl.cursorSurface =
|
||||||
wl_compositor_create_surface(_glfw.wl.compositor);
|
wl_compositor_create_surface(_glfw.wl.compositor);
|
||||||
|
_glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.wl.seat && _glfw.wl.dataDeviceManager)
|
||||||
|
{
|
||||||
|
_glfw.wl.dataDevice =
|
||||||
|
wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager,
|
||||||
|
_glfw.wl.seat);
|
||||||
|
wl_data_device_add_listener(_glfw.wl.dataDevice, &dataDeviceListener, NULL);
|
||||||
|
_glfw.wl.clipboardString = malloc(4096);
|
||||||
|
if (!_glfw.wl.clipboardString)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Unable to allocate clipboard memory");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
_glfw.wl.clipboardSize = 4096;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
@ -1103,6 +1239,8 @@ void _glfwPlatformTerminate(void)
|
|||||||
|
|
||||||
if (_glfw.wl.cursorTheme)
|
if (_glfw.wl.cursorTheme)
|
||||||
wl_cursor_theme_destroy(_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)
|
if (_glfw.wl.cursor.handle)
|
||||||
{
|
{
|
||||||
_glfw_dlclose(_glfw.wl.cursor.handle);
|
_glfw_dlclose(_glfw.wl.cursor.handle);
|
||||||
@ -1121,8 +1259,18 @@ void _glfwPlatformTerminate(void)
|
|||||||
wl_shell_destroy(_glfw.wl.shell);
|
wl_shell_destroy(_glfw.wl.shell);
|
||||||
if (_glfw.wl.viewporter)
|
if (_glfw.wl.viewporter)
|
||||||
wp_viewporter_destroy(_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)
|
if (_glfw.wl.wmBase)
|
||||||
xdg_wm_base_destroy(_glfw.wl.wmBase);
|
xdg_wm_base_destroy(_glfw.wl.wmBase);
|
||||||
|
if (_glfw.wl.dataSource)
|
||||||
|
wl_data_source_destroy(_glfw.wl.dataSource);
|
||||||
|
if (_glfw.wl.dataDevice)
|
||||||
|
wl_data_device_destroy(_glfw.wl.dataDevice);
|
||||||
|
if (_glfw.wl.dataOffer)
|
||||||
|
wl_data_offer_destroy(_glfw.wl.dataOffer);
|
||||||
|
if (_glfw.wl.dataDeviceManager)
|
||||||
|
wl_data_device_manager_destroy(_glfw.wl.dataDeviceManager);
|
||||||
if (_glfw.wl.pointer)
|
if (_glfw.wl.pointer)
|
||||||
wl_pointer_destroy(_glfw.wl.pointer);
|
wl_pointer_destroy(_glfw.wl.pointer);
|
||||||
if (_glfw.wl.keyboard)
|
if (_glfw.wl.keyboard)
|
||||||
@ -1142,6 +1290,16 @@ void _glfwPlatformTerminate(void)
|
|||||||
wl_display_flush(_glfw.wl.display);
|
wl_display_flush(_glfw.wl.display);
|
||||||
wl_display_disconnect(_glfw.wl.display);
|
wl_display_disconnect(_glfw.wl.display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_glfw.wl.timerfd >= 0)
|
||||||
|
close(_glfw.wl.timerfd);
|
||||||
|
if (_glfw.wl.cursorTimerfd >= 0)
|
||||||
|
close(_glfw.wl.cursorTimerfd);
|
||||||
|
|
||||||
|
if (_glfw.wl.clipboardString)
|
||||||
|
free(_glfw.wl.clipboardString);
|
||||||
|
if (_glfw.wl.clipboardSendString)
|
||||||
|
free(_glfw.wl.clipboardSendString);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetVersionString(void)
|
const char* _glfwPlatformGetVersionString(void)
|
||||||
@ -1158,4 +1316,3 @@ const char* _glfwPlatformGetVersionString(void)
|
|||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
60
src/external/glfw/src/wl_monitor.c
vendored
60
src/external/glfw/src/wl_monitor.c
vendored
@ -32,16 +32,16 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
static void geometry(void* data,
|
static void outputHandleGeometry(void* data,
|
||||||
struct wl_output* output,
|
struct wl_output* output,
|
||||||
int32_t x,
|
int32_t x,
|
||||||
int32_t y,
|
int32_t y,
|
||||||
int32_t physicalWidth,
|
int32_t physicalWidth,
|
||||||
int32_t physicalHeight,
|
int32_t physicalHeight,
|
||||||
int32_t subpixel,
|
int32_t subpixel,
|
||||||
const char* make,
|
const char* make,
|
||||||
const char* model,
|
const char* model,
|
||||||
int32_t transform)
|
int32_t transform)
|
||||||
{
|
{
|
||||||
struct _GLFWmonitor *monitor = data;
|
struct _GLFWmonitor *monitor = data;
|
||||||
char name[1024];
|
char name[1024];
|
||||||
@ -55,12 +55,12 @@ static void geometry(void* data,
|
|||||||
monitor->name = _glfw_strdup(name);
|
monitor->name = _glfw_strdup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mode(void* data,
|
static void outputHandleMode(void* data,
|
||||||
struct wl_output* output,
|
struct wl_output* output,
|
||||||
uint32_t flags,
|
uint32_t flags,
|
||||||
int32_t width,
|
int32_t width,
|
||||||
int32_t height,
|
int32_t height,
|
||||||
int32_t refresh)
|
int32_t refresh)
|
||||||
{
|
{
|
||||||
struct _GLFWmonitor *monitor = data;
|
struct _GLFWmonitor *monitor = data;
|
||||||
GLFWvidmode mode;
|
GLFWvidmode mode;
|
||||||
@ -81,16 +81,16 @@ static void mode(void* data,
|
|||||||
monitor->wl.currentMode = monitor->modeCount - 1;
|
monitor->wl.currentMode = monitor->modeCount - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void done(void* data, struct wl_output* output)
|
static void outputHandleDone(void* data, struct wl_output* output)
|
||||||
{
|
{
|
||||||
struct _GLFWmonitor *monitor = data;
|
struct _GLFWmonitor *monitor = data;
|
||||||
|
|
||||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scale(void* data,
|
static void outputHandleScale(void* data,
|
||||||
struct wl_output* output,
|
struct wl_output* output,
|
||||||
int32_t factor)
|
int32_t factor)
|
||||||
{
|
{
|
||||||
struct _GLFWmonitor *monitor = data;
|
struct _GLFWmonitor *monitor = data;
|
||||||
|
|
||||||
@ -98,10 +98,10 @@ static void scale(void* data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_output_listener outputListener = {
|
static const struct wl_output_listener outputListener = {
|
||||||
geometry,
|
outputHandleGeometry,
|
||||||
mode,
|
outputHandleMode,
|
||||||
done,
|
outputHandleDone,
|
||||||
scale,
|
outputHandleScale,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -180,18 +180,18 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
|||||||
*mode = monitor->modes[monitor->wl.currentMode];
|
*mode = monitor->modes[monitor->wl.currentMode];
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
{
|
{
|
||||||
// TODO
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Wayland: Gamma ramp getting not supported yet");
|
"Wayland: Gamma ramp access it not available");
|
||||||
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor,
|
||||||
|
const GLFWgammaramp* ramp)
|
||||||
{
|
{
|
||||||
// TODO
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Wayland: Gamma ramp setting not supported yet");
|
"Wayland: Gamma ramp access is not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
20
src/external/glfw/src/wl_platform.h
vendored
20
src/external/glfw/src/wl_platform.h
vendored
@ -57,6 +57,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
|||||||
#include "osmesa_context.h"
|
#include "osmesa_context.h"
|
||||||
|
|
||||||
#include "wayland-xdg-shell-client-protocol.h"
|
#include "wayland-xdg-shell-client-protocol.h"
|
||||||
|
#include "wayland-xdg-decoration-client-protocol.h"
|
||||||
#include "wayland-viewporter-client-protocol.h"
|
#include "wayland-viewporter-client-protocol.h"
|
||||||
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
|
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
|
||||||
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
||||||
@ -185,6 +186,7 @@ typedef struct _GLFWwindowWayland
|
|||||||
struct {
|
struct {
|
||||||
struct xdg_surface* surface;
|
struct xdg_surface* surface;
|
||||||
struct xdg_toplevel* toplevel;
|
struct xdg_toplevel* toplevel;
|
||||||
|
struct zxdg_toplevel_decoration_v1* decoration;
|
||||||
} xdg;
|
} xdg;
|
||||||
|
|
||||||
_GLFWcursor* currentCursor;
|
_GLFWcursor* currentCursor;
|
||||||
@ -210,6 +212,7 @@ typedef struct _GLFWwindowWayland
|
|||||||
GLFWbool justCreated;
|
GLFWbool justCreated;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
GLFWbool serverSide;
|
||||||
struct wl_buffer* buffer;
|
struct wl_buffer* buffer;
|
||||||
_GLFWdecorationWayland top, left, right, bottom;
|
_GLFWdecorationWayland top, left, right, bottom;
|
||||||
int focus;
|
int focus;
|
||||||
@ -230,7 +233,12 @@ typedef struct _GLFWlibraryWayland
|
|||||||
struct wl_seat* seat;
|
struct wl_seat* seat;
|
||||||
struct wl_pointer* pointer;
|
struct wl_pointer* pointer;
|
||||||
struct wl_keyboard* keyboard;
|
struct wl_keyboard* keyboard;
|
||||||
|
struct wl_data_device_manager* dataDeviceManager;
|
||||||
|
struct wl_data_device* dataDevice;
|
||||||
|
struct wl_data_offer* dataOffer;
|
||||||
|
struct wl_data_source* dataSource;
|
||||||
struct xdg_wm_base* wmBase;
|
struct xdg_wm_base* wmBase;
|
||||||
|
struct zxdg_decoration_manager_v1* decorationManager;
|
||||||
struct wp_viewporter* viewporter;
|
struct wp_viewporter* viewporter;
|
||||||
struct zwp_relative_pointer_manager_v1* relativePointerManager;
|
struct zwp_relative_pointer_manager_v1* relativePointerManager;
|
||||||
struct zwp_pointer_constraints_v1* pointerConstraints;
|
struct zwp_pointer_constraints_v1* pointerConstraints;
|
||||||
@ -240,13 +248,19 @@ typedef struct _GLFWlibraryWayland
|
|||||||
int seatVersion;
|
int seatVersion;
|
||||||
|
|
||||||
struct wl_cursor_theme* cursorTheme;
|
struct wl_cursor_theme* cursorTheme;
|
||||||
|
struct wl_cursor_theme* cursorThemeHiDPI;
|
||||||
struct wl_surface* cursorSurface;
|
struct wl_surface* cursorSurface;
|
||||||
uint32_t pointerSerial;
|
int cursorTimerfd;
|
||||||
|
uint32_t serial;
|
||||||
|
|
||||||
int32_t keyboardRepeatRate;
|
int32_t keyboardRepeatRate;
|
||||||
int32_t keyboardRepeatDelay;
|
int32_t keyboardRepeatDelay;
|
||||||
int keyboardLastKey;
|
int keyboardLastKey;
|
||||||
int keyboardLastScancode;
|
int keyboardLastScancode;
|
||||||
|
char* clipboardString;
|
||||||
|
size_t clipboardSize;
|
||||||
|
char* clipboardSendString;
|
||||||
|
size_t clipboardSendSize;
|
||||||
int timerfd;
|
int timerfd;
|
||||||
short int keycodes[256];
|
short int keycodes[256];
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
@ -332,10 +346,12 @@ typedef struct _GLFWmonitorWayland
|
|||||||
//
|
//
|
||||||
typedef struct _GLFWcursorWayland
|
typedef struct _GLFWcursorWayland
|
||||||
{
|
{
|
||||||
struct wl_cursor_image* image;
|
struct wl_cursor* cursor;
|
||||||
|
struct wl_cursor* cursorHiDPI;
|
||||||
struct wl_buffer* buffer;
|
struct wl_buffer* buffer;
|
||||||
int width, height;
|
int width, height;
|
||||||
int xhot, yhot;
|
int xhot, yhot;
|
||||||
|
int currentImage;
|
||||||
} _GLFWcursorWayland;
|
} _GLFWcursorWayland;
|
||||||
|
|
||||||
|
|
||||||
|
541
src/external/glfw/src/wl_window.c
vendored
541
src/external/glfw/src/wl_window.c
vendored
@ -39,18 +39,18 @@
|
|||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
|
||||||
|
|
||||||
static void handlePing(void* data,
|
static void shellSurfaceHandlePing(void* data,
|
||||||
struct wl_shell_surface* shellSurface,
|
struct wl_shell_surface* shellSurface,
|
||||||
uint32_t serial)
|
uint32_t serial)
|
||||||
{
|
{
|
||||||
wl_shell_surface_pong(shellSurface, serial);
|
wl_shell_surface_pong(shellSurface, serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleConfigure(void* data,
|
static void shellSurfaceHandleConfigure(void* data,
|
||||||
struct wl_shell_surface* shellSurface,
|
struct wl_shell_surface* shellSurface,
|
||||||
uint32_t edges,
|
uint32_t edges,
|
||||||
int32_t width,
|
int32_t width,
|
||||||
int32_t height)
|
int32_t height)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = data;
|
_GLFWwindow* window = data;
|
||||||
float aspectRatio;
|
float aspectRatio;
|
||||||
@ -94,19 +94,18 @@ static void handleConfigure(void* data,
|
|||||||
_glfwInputWindowDamage(window);
|
_glfwInputWindowDamage(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handlePopupDone(void* data,
|
static void shellSurfaceHandlePopupDone(void* data,
|
||||||
struct wl_shell_surface* shellSurface)
|
struct wl_shell_surface* shellSurface)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_shell_surface_listener shellSurfaceListener = {
|
static const struct wl_shell_surface_listener shellSurfaceListener = {
|
||||||
handlePing,
|
shellSurfaceHandlePing,
|
||||||
handleConfigure,
|
shellSurfaceHandleConfigure,
|
||||||
handlePopupDone
|
shellSurfaceHandlePopupDone
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int createTmpfileCloexec(char* tmpname)
|
||||||
createTmpfileCloexec(char* tmpname)
|
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@ -137,8 +136,7 @@ createTmpfileCloexec(char* tmpname)
|
|||||||
* is set to ENOSPC. If posix_fallocate() is not supported, program may
|
* is set to ENOSPC. If posix_fallocate() is not supported, program may
|
||||||
* receive SIGBUS on accessing mmap()'ed file contents instead.
|
* receive SIGBUS on accessing mmap()'ed file contents instead.
|
||||||
*/
|
*/
|
||||||
static int
|
static int createAnonymousFile(off_t size)
|
||||||
createAnonymousFile(off_t size)
|
|
||||||
{
|
{
|
||||||
static const char template[] = "/glfw-shared-XXXXXX";
|
static const char template[] = "/glfw-shared-XXXXXX";
|
||||||
const char* path;
|
const char* path;
|
||||||
@ -146,23 +144,37 @@ createAnonymousFile(off_t size)
|
|||||||
int fd;
|
int fd;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
path = getenv("XDG_RUNTIME_DIR");
|
#ifdef HAVE_MEMFD_CREATE
|
||||||
if (!path)
|
fd = memfd_create("glfw-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||||
|
if (fd >= 0)
|
||||||
{
|
{
|
||||||
errno = ENOENT;
|
// We can add this seal before calling posix_fallocate(), as the file
|
||||||
return -1;
|
// is currently zero-sized anyway.
|
||||||
|
//
|
||||||
|
// There is also no need to check for the return value, we couldn’t do
|
||||||
|
// anything with it anyway.
|
||||||
|
fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
path = getenv("XDG_RUNTIME_DIR");
|
||||||
|
if (!path)
|
||||||
|
{
|
||||||
|
errno = ENOENT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = calloc(strlen(path) + sizeof(template), 1);
|
||||||
|
strcpy(name, path);
|
||||||
|
strcat(name, template);
|
||||||
|
|
||||||
|
fd = createTmpfileCloexec(name);
|
||||||
|
free(name);
|
||||||
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = calloc(strlen(path) + sizeof(template), 1);
|
|
||||||
strcpy(name, path);
|
|
||||||
strcat(name, template);
|
|
||||||
|
|
||||||
fd = createTmpfileCloexec(name);
|
|
||||||
|
|
||||||
free(name);
|
|
||||||
|
|
||||||
if (fd < 0)
|
|
||||||
return -1;
|
|
||||||
ret = posix_fallocate(fd, 0, size);
|
ret = posix_fallocate(fd, 0, size);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
@ -188,7 +200,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
|||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Wayland: Creating a buffer file for %d B failed: %m",
|
"Wayland: Creating a buffer file for %d B failed: %m",
|
||||||
length);
|
length);
|
||||||
return GLFW_FALSE;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
@ -197,7 +209,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
|||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Wayland: mmap failed: %m");
|
"Wayland: mmap failed: %m");
|
||||||
close(fd);
|
close(fd);
|
||||||
return GLFW_FALSE;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pool = wl_shm_create_pool(_glfw.wl.shm, fd, length);
|
pool = wl_shm_create_pool(_glfw.wl.shm, fd, length);
|
||||||
@ -262,11 +274,13 @@ static void createDecorations(_GLFWwindow* window)
|
|||||||
const GLFWimage image = { 1, 1, data };
|
const GLFWimage image = { 1, 1, data };
|
||||||
GLFWbool opaque = (data[3] == 255);
|
GLFWbool opaque = (data[3] == 255);
|
||||||
|
|
||||||
if (!_glfw.wl.viewporter)
|
if (!_glfw.wl.viewporter || !window->decorated || window->wl.decorations.serverSide)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!window->wl.decorations.buffer)
|
if (!window->wl.decorations.buffer)
|
||||||
window->wl.decorations.buffer = createShmBuffer(&image);
|
window->wl.decorations.buffer = createShmBuffer(&image);
|
||||||
|
if (!window->wl.decorations.buffer)
|
||||||
|
return;
|
||||||
|
|
||||||
createDecoration(&window->wl.decorations.top, window->wl.surface,
|
createDecoration(&window->wl.decorations.top, window->wl.surface,
|
||||||
window->wl.decorations.buffer, opaque,
|
window->wl.decorations.buffer, opaque,
|
||||||
@ -307,6 +321,22 @@ static void destroyDecorations(_GLFWwindow* window)
|
|||||||
destroyDecoration(&window->wl.decorations.bottom);
|
destroyDecoration(&window->wl.decorations.bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xdgDecorationHandleConfigure(void* data,
|
||||||
|
struct zxdg_toplevel_decoration_v1* decoration,
|
||||||
|
uint32_t mode)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = data;
|
||||||
|
|
||||||
|
window->wl.decorations.serverSide = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||||
|
|
||||||
|
if (!window->wl.decorations.serverSide)
|
||||||
|
createDecorations(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener = {
|
||||||
|
xdgDecorationHandleConfigure,
|
||||||
|
};
|
||||||
|
|
||||||
// Makes the surface considered as XRGB instead of ARGB.
|
// Makes the surface considered as XRGB instead of ARGB.
|
||||||
static void setOpaqueRegion(_GLFWwindow* window)
|
static void setOpaqueRegion(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
@ -389,9 +419,9 @@ static void checkScaleChange(_GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleEnter(void *data,
|
static void surfaceHandleEnter(void *data,
|
||||||
struct wl_surface *surface,
|
struct wl_surface *surface,
|
||||||
struct wl_output *output)
|
struct wl_output *output)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = data;
|
_GLFWwindow* window = data;
|
||||||
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
||||||
@ -409,9 +439,9 @@ static void handleEnter(void *data,
|
|||||||
checkScaleChange(window);
|
checkScaleChange(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleLeave(void *data,
|
static void surfaceHandleLeave(void *data,
|
||||||
struct wl_surface *surface,
|
struct wl_surface *surface,
|
||||||
struct wl_output *output)
|
struct wl_output *output)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = data;
|
_GLFWwindow* window = data;
|
||||||
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
||||||
@ -431,8 +461,8 @@ static void handleLeave(void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_surface_listener surfaceListener = {
|
static const struct wl_surface_listener surfaceListener = {
|
||||||
handleEnter,
|
surfaceHandleEnter,
|
||||||
handleLeave
|
surfaceHandleLeave
|
||||||
};
|
};
|
||||||
|
|
||||||
static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)
|
static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)
|
||||||
@ -479,13 +509,11 @@ static GLFWbool createSurface(_GLFWwindow* window,
|
|||||||
if (!window->wl.transparent)
|
if (!window->wl.transparent)
|
||||||
setOpaqueRegion(window);
|
setOpaqueRegion(window);
|
||||||
|
|
||||||
if (window->decorated && !window->monitor)
|
|
||||||
createDecorations(window);
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, int refreshRate)
|
static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor,
|
||||||
|
int refreshRate)
|
||||||
{
|
{
|
||||||
if (window->wl.xdg.toplevel)
|
if (window->wl.xdg.toplevel)
|
||||||
{
|
{
|
||||||
@ -502,7 +530,8 @@ static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, int refres
|
|||||||
monitor->wl.output);
|
monitor->wl.output);
|
||||||
}
|
}
|
||||||
setIdleInhibitor(window, GLFW_TRUE);
|
setIdleInhibitor(window, GLFW_TRUE);
|
||||||
destroyDecorations(window);
|
if (!window->wl.decorations.serverSide)
|
||||||
|
destroyDecorations(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLFWbool createShellSurface(_GLFWwindow* window)
|
static GLFWbool createShellSurface(_GLFWwindow* window)
|
||||||
@ -538,11 +567,13 @@ static GLFWbool createShellSurface(_GLFWwindow* window)
|
|||||||
{
|
{
|
||||||
wl_shell_surface_set_maximized(window->wl.shellSurface, NULL);
|
wl_shell_surface_set_maximized(window->wl.shellSurface, NULL);
|
||||||
setIdleInhibitor(window, GLFW_FALSE);
|
setIdleInhibitor(window, GLFW_FALSE);
|
||||||
|
createDecorations(window);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wl_shell_surface_set_toplevel(window->wl.shellSurface);
|
wl_shell_surface_set_toplevel(window->wl.shellSurface);
|
||||||
setIdleInhibitor(window, GLFW_FALSE);
|
setIdleInhibitor(window, GLFW_FALSE);
|
||||||
|
createDecorations(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_surface_commit(window->wl.surface);
|
wl_surface_commit(window->wl.surface);
|
||||||
@ -631,6 +662,27 @@ static const struct xdg_surface_listener xdgSurfaceListener = {
|
|||||||
xdgSurfaceHandleConfigure
|
xdgSurfaceHandleConfigure
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void setXdgDecorations(_GLFWwindow* 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);
|
||||||
|
zxdg_toplevel_decoration_v1_set_mode(
|
||||||
|
window->wl.xdg.decoration,
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->wl.decorations.serverSide = GLFW_FALSE;
|
||||||
|
createDecorations(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GLFWbool createXdgSurface(_GLFWwindow* window)
|
static GLFWbool createXdgSurface(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase,
|
window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase,
|
||||||
@ -678,10 +730,12 @@ static GLFWbool createXdgSurface(_GLFWwindow* window)
|
|||||||
{
|
{
|
||||||
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
|
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
|
||||||
setIdleInhibitor(window, GLFW_FALSE);
|
setIdleInhibitor(window, GLFW_FALSE);
|
||||||
|
setXdgDecorations(window);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
setIdleInhibitor(window, GLFW_FALSE);
|
setIdleInhibitor(window, GLFW_FALSE);
|
||||||
|
setXdgDecorations(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_surface_commit(window->wl.surface);
|
wl_surface_commit(window->wl.surface);
|
||||||
@ -690,13 +744,75 @@ static GLFWbool createXdgSurface(_GLFWwindow* window)
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void setCursorImage(_GLFWwindow* window,
|
||||||
handleEvents(int timeout)
|
_GLFWcursorWayland* cursorWayland)
|
||||||
|
{
|
||||||
|
struct itimerspec timer = {};
|
||||||
|
struct wl_cursor* wlCursor = cursorWayland->cursor;
|
||||||
|
struct wl_cursor_image* image;
|
||||||
|
struct wl_buffer* buffer;
|
||||||
|
struct wl_surface* surface = _glfw.wl.cursorSurface;
|
||||||
|
int scale = 1;
|
||||||
|
|
||||||
|
if (!wlCursor)
|
||||||
|
buffer = cursorWayland->buffer;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (window->wl.scale > 1 && cursorWayland->cursorHiDPI)
|
||||||
|
{
|
||||||
|
wlCursor = cursorWayland->cursorHiDPI;
|
||||||
|
scale = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
image = wlCursor->images[cursorWayland->currentImage];
|
||||||
|
buffer = wl_cursor_image_get_buffer(image);
|
||||||
|
if (!buffer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
timer.it_value.tv_sec = image->delay / 1000;
|
||||||
|
timer.it_value.tv_nsec = (image->delay % 1000) * 1000000;
|
||||||
|
timerfd_settime(_glfw.wl.cursorTimerfd, 0, &timer, NULL);
|
||||||
|
|
||||||
|
cursorWayland->width = image->width;
|
||||||
|
cursorWayland->height = image->height;
|
||||||
|
cursorWayland->xhot = image->hotspot_x;
|
||||||
|
cursorWayland->yhot = image->hotspot_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial,
|
||||||
|
surface,
|
||||||
|
cursorWayland->xhot / scale,
|
||||||
|
cursorWayland->yhot / scale);
|
||||||
|
wl_surface_set_buffer_scale(surface, scale);
|
||||||
|
wl_surface_attach(surface, buffer, 0, 0);
|
||||||
|
wl_surface_damage(surface, 0, 0,
|
||||||
|
cursorWayland->width, cursorWayland->height);
|
||||||
|
wl_surface_commit(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void incrementCursorImage(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
_GLFWcursor* cursor;
|
||||||
|
|
||||||
|
if (!window || window->wl.decorations.focus != mainWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cursor = window->wl.currentCursor;
|
||||||
|
if (cursor && cursor->wl.cursor)
|
||||||
|
{
|
||||||
|
cursor->wl.currentImage += 1;
|
||||||
|
cursor->wl.currentImage %= cursor->wl.cursor->image_count;
|
||||||
|
setCursorImage(window, &cursor->wl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleEvents(int timeout)
|
||||||
{
|
{
|
||||||
struct wl_display* display = _glfw.wl.display;
|
struct wl_display* display = _glfw.wl.display;
|
||||||
struct pollfd fds[] = {
|
struct pollfd fds[] = {
|
||||||
{ wl_display_get_fd(display), POLLIN },
|
{ wl_display_get_fd(display), POLLIN },
|
||||||
{ _glfw.wl.timerfd, POLLIN },
|
{ _glfw.wl.timerfd, POLLIN },
|
||||||
|
{ _glfw.wl.cursorTimerfd, POLLIN },
|
||||||
};
|
};
|
||||||
ssize_t read_ret;
|
ssize_t read_ret;
|
||||||
uint64_t repeats, i;
|
uint64_t repeats, i;
|
||||||
@ -719,7 +835,7 @@ handleEvents(int timeout)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (poll(fds, 2, timeout) > 0)
|
if (poll(fds, 3, timeout) > 0)
|
||||||
{
|
{
|
||||||
if (fds[0].revents & POLLIN)
|
if (fds[0].revents & POLLIN)
|
||||||
{
|
{
|
||||||
@ -742,6 +858,15 @@ handleEvents(int timeout)
|
|||||||
_glfw.wl.keyboardLastScancode, GLFW_REPEAT,
|
_glfw.wl.keyboardLastScancode, GLFW_REPEAT,
|
||||||
_glfw.wl.xkb.modifiers);
|
_glfw.wl.xkb.modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fds[2].revents & POLLIN)
|
||||||
|
{
|
||||||
|
read_ret = read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats));
|
||||||
|
if (read_ret != 8)
|
||||||
|
return;
|
||||||
|
|
||||||
|
incrementCursorImage(_glfw.wl.pointerFocus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -860,6 +985,9 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||||||
window->context.destroy(window);
|
window->context.destroy(window);
|
||||||
|
|
||||||
destroyDecorations(window);
|
destroyDecorations(window);
|
||||||
|
if (window->wl.xdg.decoration)
|
||||||
|
zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration);
|
||||||
|
|
||||||
if (window->wl.decorations.buffer)
|
if (window->wl.decorations.buffer)
|
||||||
wl_buffer_destroy(window->wl.decorations.buffer);
|
wl_buffer_destroy(window->wl.decorations.buffer);
|
||||||
|
|
||||||
@ -956,13 +1084,15 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
|
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window,
|
||||||
|
int numer, int denom)
|
||||||
{
|
{
|
||||||
// TODO: find out how to trigger a resize.
|
// TODO: find out how to trigger a resize.
|
||||||
// The actual limits are checked in the wl_shell_surface::configure handler.
|
// The actual limits are checked in the wl_shell_surface::configure handler.
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
|
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window,
|
||||||
|
int* width, int* height)
|
||||||
{
|
{
|
||||||
_glfwPlatformGetWindowSize(window, width, height);
|
_glfwPlatformGetWindowSize(window, width, height);
|
||||||
*width *= window->wl.scale;
|
*width *= window->wl.scale;
|
||||||
@ -973,7 +1103,7 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
|||||||
int* left, int* top,
|
int* left, int* top,
|
||||||
int* right, int* bottom)
|
int* right, int* bottom)
|
||||||
{
|
{
|
||||||
if (window->decorated && !window->monitor)
|
if (window->decorated && !window->monitor && !window->wl.decorations.serverSide)
|
||||||
{
|
{
|
||||||
if (top)
|
if (top)
|
||||||
*top = _GLFW_DECORATION_TOP;
|
*top = _GLFW_DECORATION_TOP;
|
||||||
@ -1102,7 +1232,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
|||||||
else if (window->wl.shellSurface)
|
else if (window->wl.shellSurface)
|
||||||
wl_shell_surface_set_toplevel(window->wl.shellSurface);
|
wl_shell_surface_set_toplevel(window->wl.shellSurface);
|
||||||
setIdleInhibitor(window, GLFW_FALSE);
|
setIdleInhibitor(window, GLFW_FALSE);
|
||||||
if (window->decorated)
|
if (!_glfw.wl.decorationManager)
|
||||||
createDecorations(window);
|
createDecorations(window);
|
||||||
}
|
}
|
||||||
_glfwInputWindowMonitor(window, monitor);
|
_glfwInputWindowMonitor(window, monitor);
|
||||||
@ -1236,6 +1366,9 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
int xhot, int yhot)
|
int xhot, int yhot)
|
||||||
{
|
{
|
||||||
cursor->wl.buffer = createShmBuffer(image);
|
cursor->wl.buffer = createShmBuffer(image);
|
||||||
|
if (!cursor->wl.buffer)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
cursor->wl.width = image->width;
|
cursor->wl.width = image->width;
|
||||||
cursor->wl.height = image->height;
|
cursor->wl.height = image->height;
|
||||||
cursor->wl.xhot = xhot;
|
cursor->wl.xhot = xhot;
|
||||||
@ -1257,28 +1390,37 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor->wl.image = standardCursor->images[0];
|
cursor->wl.cursor = standardCursor;
|
||||||
|
cursor->wl.currentImage = 0;
|
||||||
|
|
||||||
|
if (_glfw.wl.cursorThemeHiDPI)
|
||||||
|
{
|
||||||
|
standardCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI,
|
||||||
|
translateCursorShape(shape));
|
||||||
|
cursor->wl.cursorHiDPI = standardCursor;
|
||||||
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||||
{
|
{
|
||||||
// If it's a standard cursor we don't need to do anything here
|
// If it's a standard cursor we don't need to do anything here
|
||||||
if (cursor->wl.image)
|
if (cursor->wl.cursor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cursor->wl.buffer)
|
if (cursor->wl.buffer)
|
||||||
wl_buffer_destroy(cursor->wl.buffer);
|
wl_buffer_destroy(cursor->wl.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleRelativeMotion(void* data,
|
static void relativePointerHandleRelativeMotion(void* data,
|
||||||
struct zwp_relative_pointer_v1* pointer,
|
struct zwp_relative_pointer_v1* pointer,
|
||||||
uint32_t timeHi,
|
uint32_t timeHi,
|
||||||
uint32_t timeLo,
|
uint32_t timeLo,
|
||||||
wl_fixed_t dx,
|
wl_fixed_t dx,
|
||||||
wl_fixed_t dy,
|
wl_fixed_t dy,
|
||||||
wl_fixed_t dxUnaccel,
|
wl_fixed_t dxUnaccel,
|
||||||
wl_fixed_t dyUnaccel)
|
wl_fixed_t dyUnaccel)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = data;
|
_GLFWwindow* window = data;
|
||||||
|
|
||||||
@ -1291,11 +1433,11 @@ static void handleRelativeMotion(void* data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct zwp_relative_pointer_v1_listener relativePointerListener = {
|
static const struct zwp_relative_pointer_v1_listener relativePointerListener = {
|
||||||
handleRelativeMotion
|
relativePointerHandleRelativeMotion
|
||||||
};
|
};
|
||||||
|
|
||||||
static void handleLocked(void* data,
|
static void lockedPointerHandleLocked(void* data,
|
||||||
struct zwp_locked_pointer_v1* lockedPointer)
|
struct zwp_locked_pointer_v1* lockedPointer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1315,14 +1457,14 @@ static void unlockPointer(_GLFWwindow* window)
|
|||||||
|
|
||||||
static void lockPointer(_GLFWwindow* window);
|
static void lockPointer(_GLFWwindow* window);
|
||||||
|
|
||||||
static void handleUnlocked(void* data,
|
static void lockedPointerHandleUnlocked(void* data,
|
||||||
struct zwp_locked_pointer_v1* lockedPointer)
|
struct zwp_locked_pointer_v1* lockedPointer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct zwp_locked_pointer_v1_listener lockedPointerListener = {
|
static const struct zwp_locked_pointer_v1_listener lockedPointerListener = {
|
||||||
handleLocked,
|
lockedPointerHandleLocked,
|
||||||
handleUnlocked
|
lockedPointerHandleUnlocked
|
||||||
};
|
};
|
||||||
|
|
||||||
static void lockPointer(_GLFWwindow* window)
|
static void lockPointer(_GLFWwindow* window)
|
||||||
@ -1359,7 +1501,7 @@ static void lockPointer(_GLFWwindow* window)
|
|||||||
window->wl.pointerLock.relativePointer = relativePointer;
|
window->wl.pointerLock.relativePointer = relativePointer;
|
||||||
window->wl.pointerLock.lockedPointer = lockedPointer;
|
window->wl.pointerLock.lockedPointer = lockedPointer;
|
||||||
|
|
||||||
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial,
|
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial,
|
||||||
NULL, 0, 0);
|
NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1370,10 +1512,8 @@ static GLFWbool isPointerLocked(_GLFWwindow* window)
|
|||||||
|
|
||||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
||||||
{
|
{
|
||||||
struct wl_buffer* buffer;
|
|
||||||
struct wl_cursor* defaultCursor;
|
struct wl_cursor* defaultCursor;
|
||||||
struct wl_cursor_image* image;
|
struct wl_cursor* defaultCursorHiDPI = NULL;
|
||||||
struct wl_surface* surface = _glfw.wl.cursorSurface;
|
|
||||||
|
|
||||||
if (!_glfw.wl.pointer)
|
if (!_glfw.wl.pointer)
|
||||||
return;
|
return;
|
||||||
@ -1382,7 +1522,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
|||||||
|
|
||||||
// If we're not in the correct window just save the 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
|
// the next time the pointer enters the window the cursor will change
|
||||||
if (window != _glfw.wl.pointerFocus)
|
if (window != _glfw.wl.pointerFocus || window->wl.decorations.focus != mainWindow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Unlock possible pointer lock if no longer disabled.
|
// Unlock possible pointer lock if no longer disabled.
|
||||||
@ -1392,7 +1532,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
|||||||
if (window->cursorMode == GLFW_CURSOR_NORMAL)
|
if (window->cursorMode == GLFW_CURSOR_NORMAL)
|
||||||
{
|
{
|
||||||
if (cursor)
|
if (cursor)
|
||||||
image = cursor->wl.image;
|
setCursorImage(window, &cursor->wl);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
defaultCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,
|
defaultCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,
|
||||||
@ -1403,33 +1543,19 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
|||||||
"Wayland: Standard cursor not found");
|
"Wayland: Standard cursor not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
image = defaultCursor->images[0];
|
if (_glfw.wl.cursorThemeHiDPI)
|
||||||
}
|
defaultCursorHiDPI =
|
||||||
|
wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI,
|
||||||
if (image)
|
"left_ptr");
|
||||||
{
|
_GLFWcursorWayland cursorWayland = {
|
||||||
buffer = wl_cursor_image_get_buffer(image);
|
defaultCursor,
|
||||||
if (!buffer)
|
defaultCursorHiDPI,
|
||||||
return;
|
NULL,
|
||||||
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial,
|
0, 0,
|
||||||
surface,
|
0, 0,
|
||||||
image->hotspot_x,
|
0
|
||||||
image->hotspot_y);
|
};
|
||||||
wl_surface_attach(surface, buffer, 0, 0);
|
setCursorImage(window, &cursorWayland);
|
||||||
wl_surface_damage(surface, 0, 0,
|
|
||||||
image->width, image->height);
|
|
||||||
wl_surface_commit(surface);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial,
|
|
||||||
surface,
|
|
||||||
cursor->wl.xhot,
|
|
||||||
cursor->wl.yhot);
|
|
||||||
wl_surface_attach(surface, cursor->wl.buffer, 0, 0);
|
|
||||||
wl_surface_damage(surface, 0, 0,
|
|
||||||
cursor->wl.width, cursor->wl.height);
|
|
||||||
wl_surface_commit(surface);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
else if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
@ -1439,24 +1565,213 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
|||||||
}
|
}
|
||||||
else if (window->cursorMode == GLFW_CURSOR_HIDDEN)
|
else if (window->cursorMode == GLFW_CURSOR_HIDDEN)
|
||||||
{
|
{
|
||||||
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial,
|
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial, NULL, 0, 0);
|
||||||
NULL, 0, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dataSourceHandleTarget(void* data,
|
||||||
|
struct wl_data_source* dataSource,
|
||||||
|
const char* mimeType)
|
||||||
|
{
|
||||||
|
if (_glfw.wl.dataSource != dataSource)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Unknown clipboard data source");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dataSourceHandleSend(void* data,
|
||||||
|
struct wl_data_source* dataSource,
|
||||||
|
const char* mimeType,
|
||||||
|
int fd)
|
||||||
|
{
|
||||||
|
const char* string = _glfw.wl.clipboardSendString;
|
||||||
|
size_t len = _glfw.wl.clipboardSendSize;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (_glfw.wl.dataSource != dataSource)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Unknown clipboard data source");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Copy requested from an invalid string");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(mimeType, "text/plain;charset=utf-8") != 0)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Wrong MIME type asked from clipboard");
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
ret = write(fd, string, len);
|
||||||
|
if (ret == -1 && errno == EINTR)
|
||||||
|
continue;
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
// TODO: also report errno maybe.
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Error while writing the clipboard");
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
len -= ret;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dataSourceHandleCancelled(void* data,
|
||||||
|
struct wl_data_source* dataSource)
|
||||||
|
{
|
||||||
|
wl_data_source_destroy(dataSource);
|
||||||
|
|
||||||
|
if (_glfw.wl.dataSource != dataSource)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Unknown clipboard data source");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.wl.dataSource = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_data_source_listener dataSourceListener = {
|
||||||
|
dataSourceHandleTarget,
|
||||||
|
dataSourceHandleSend,
|
||||||
|
dataSourceHandleCancelled,
|
||||||
|
};
|
||||||
|
|
||||||
void _glfwPlatformSetClipboardString(const char* string)
|
void _glfwPlatformSetClipboardString(const char* string)
|
||||||
{
|
{
|
||||||
// TODO
|
if (_glfw.wl.dataSource)
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
{
|
||||||
"Wayland: Clipboard setting not implemented yet");
|
wl_data_source_destroy(_glfw.wl.dataSource);
|
||||||
|
_glfw.wl.dataSource = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.wl.clipboardSendString)
|
||||||
|
{
|
||||||
|
free(_glfw.wl.clipboardSendString);
|
||||||
|
_glfw.wl.clipboardSendString = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.wl.clipboardSendString = strdup(string);
|
||||||
|
if (!_glfw.wl.clipboardSendString)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Impossible to allocate clipboard string");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_glfw.wl.clipboardSendSize = strlen(string);
|
||||||
|
_glfw.wl.dataSource =
|
||||||
|
wl_data_device_manager_create_data_source(_glfw.wl.dataDeviceManager);
|
||||||
|
if (!_glfw.wl.dataSource)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Impossible to create clipboard source");
|
||||||
|
free(_glfw.wl.clipboardSendString);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wl_data_source_add_listener(_glfw.wl.dataSource,
|
||||||
|
&dataSourceListener,
|
||||||
|
NULL);
|
||||||
|
wl_data_source_offer(_glfw.wl.dataSource, "text/plain;charset=utf-8");
|
||||||
|
wl_data_device_set_selection(_glfw.wl.dataDevice,
|
||||||
|
_glfw.wl.dataSource,
|
||||||
|
_glfw.wl.serial);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLFWbool growClipboardString(void)
|
||||||
|
{
|
||||||
|
char* clipboard = _glfw.wl.clipboardString;
|
||||||
|
|
||||||
|
clipboard = realloc(clipboard, _glfw.wl.clipboardSize * 2);
|
||||||
|
if (!clipboard)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Impossible to grow clipboard string");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
_glfw.wl.clipboardString = clipboard;
|
||||||
|
_glfw.wl.clipboardSize = _glfw.wl.clipboardSize * 2;
|
||||||
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetClipboardString(void)
|
const char* _glfwPlatformGetClipboardString(void)
|
||||||
{
|
{
|
||||||
// TODO
|
int fds[2];
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
int ret;
|
||||||
"Wayland: Clipboard getting not implemented yet");
|
size_t len = 0;
|
||||||
return NULL;
|
|
||||||
|
if (!_glfw.wl.dataOffer)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
|
"No clipboard data has been sent yet");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = pipe2(fds, O_CLOEXEC);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
// TODO: also report errno maybe?
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Impossible to create clipboard pipe fds");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_data_offer_receive(_glfw.wl.dataOffer, "text/plain;charset=utf-8", fds[1]);
|
||||||
|
close(fds[1]);
|
||||||
|
|
||||||
|
// XXX: this is a huge hack, this function shouldn’t be synchronous!
|
||||||
|
handleEvents(-1);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
// Grow the clipboard if we need to paste something bigger, there is no
|
||||||
|
// shrink operation yet.
|
||||||
|
if (len + 4096 > _glfw.wl.clipboardSize)
|
||||||
|
{
|
||||||
|
if (!growClipboardString())
|
||||||
|
{
|
||||||
|
close(fds[0]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then read from the fd to the clipboard, handling all known errors.
|
||||||
|
ret = read(fds[0], _glfw.wl.clipboardString + len, 4096);
|
||||||
|
if (ret == 0)
|
||||||
|
break;
|
||||||
|
if (ret == -1 && errno == EINTR)
|
||||||
|
continue;
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
// TODO: also report errno maybe.
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Impossible to read from clipboard fd");
|
||||||
|
close(fds[0]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
len += ret;
|
||||||
|
}
|
||||||
|
close(fds[0]);
|
||||||
|
if (len + 1 > _glfw.wl.clipboardSize)
|
||||||
|
{
|
||||||
|
if (!growClipboardString())
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
_glfw.wl.clipboardString[len] = '\0';
|
||||||
|
return _glfw.wl.clipboardString;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
||||||
|
5
src/external/glfw/src/x11_init.c
vendored
5
src/external/glfw/src/x11_init.c
vendored
@ -780,8 +780,9 @@ static GLFWbool initExtensions(void)
|
|||||||
//
|
//
|
||||||
static void getSystemContentScale(float* xscale, float* yscale)
|
static void getSystemContentScale(float* xscale, float* yscale)
|
||||||
{
|
{
|
||||||
// NOTE: Default to the display-wide DPI as we don't currently have a policy
|
// NOTE: Fall back to the display-wide DPI instead of RandR monitor DPI if
|
||||||
// for which monitor a window is considered to be on
|
// Xft.dpi retrieval below fails as we don't currently have an exact
|
||||||
|
// policy for which monitor a window is considered to "be on"
|
||||||
float xdpi = DisplayWidth(_glfw.x11.display, _glfw.x11.screen) *
|
float xdpi = DisplayWidth(_glfw.x11.display, _glfw.x11.screen) *
|
||||||
25.4f / DisplayWidthMM(_glfw.x11.display, _glfw.x11.screen);
|
25.4f / DisplayWidthMM(_glfw.x11.display, _glfw.x11.screen);
|
||||||
float ydpi = DisplayHeight(_glfw.x11.display, _glfw.x11.screen) *
|
float ydpi = DisplayHeight(_glfw.x11.display, _glfw.x11.screen) *
|
||||||
|
15
src/external/glfw/src/x11_monitor.c
vendored
15
src/external/glfw/src/x11_monitor.c
vendored
@ -422,7 +422,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
{
|
{
|
||||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
|
||||||
{
|
{
|
||||||
@ -438,6 +438,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|||||||
memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short));
|
memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short));
|
||||||
|
|
||||||
XRRFreeGamma(gamma);
|
XRRFreeGamma(gamma);
|
||||||
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
else if (_glfw.x11.vidmode.available)
|
else if (_glfw.x11.vidmode.available)
|
||||||
{
|
{
|
||||||
@ -449,6 +450,13 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|||||||
XF86VidModeGetGammaRamp(_glfw.x11.display,
|
XF86VidModeGetGammaRamp(_glfw.x11.display,
|
||||||
_glfw.x11.screen,
|
_glfw.x11.screen,
|
||||||
ramp->size, ramp->red, ramp->green, ramp->blue);
|
ramp->size, ramp->red, ramp->green, ramp->blue);
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Gamma ramp access not supported by server");
|
||||||
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,6 +489,11 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
|||||||
(unsigned short*) ramp->green,
|
(unsigned short*) ramp->green,
|
||||||
(unsigned short*) ramp->blue);
|
(unsigned short*) ramp->blue);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Gamma ramp access not supported by server");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
95
src/external/glfw/src/x11_window.c
vendored
95
src/external/glfw/src/x11_window.c
vendored
@ -175,29 +175,6 @@ static Bool isSelPropNewValueNotify(Display* display, XEvent* event, XPointer po
|
|||||||
event->xproperty.atom == notification->xselection.property;
|
event->xproperty.atom == notification->xselection.property;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translates a GLFW standard cursor to a font cursor shape
|
|
||||||
//
|
|
||||||
static int translateCursorShape(int shape)
|
|
||||||
{
|
|
||||||
switch (shape)
|
|
||||||
{
|
|
||||||
case GLFW_ARROW_CURSOR:
|
|
||||||
return XC_left_ptr;
|
|
||||||
case GLFW_IBEAM_CURSOR:
|
|
||||||
return XC_xterm;
|
|
||||||
case GLFW_CROSSHAIR_CURSOR:
|
|
||||||
return XC_crosshair;
|
|
||||||
case GLFW_HAND_CURSOR:
|
|
||||||
return XC_hand1;
|
|
||||||
case GLFW_HRESIZE_CURSOR:
|
|
||||||
return XC_sb_h_double_arrow;
|
|
||||||
case GLFW_VRESIZE_CURSOR:
|
|
||||||
return XC_sb_v_double_arrow;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translates an X event modifier state mask
|
// Translates an X event modifier state mask
|
||||||
//
|
//
|
||||||
static int translateState(int state)
|
static int translateState(int state)
|
||||||
@ -231,23 +208,6 @@ static int translateKey(int scancode)
|
|||||||
return _glfw.x11.keycodes[scancode];
|
return _glfw.x11.keycodes[scancode];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the GLFW window corresponding to the specified X11 window
|
|
||||||
//
|
|
||||||
static _GLFWwindow* findWindowByHandle(Window handle)
|
|
||||||
{
|
|
||||||
_GLFWwindow* window;
|
|
||||||
|
|
||||||
if (XFindContext(_glfw.x11.display,
|
|
||||||
handle,
|
|
||||||
_glfw.x11.context,
|
|
||||||
(XPointer*) &window) != 0)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sends an EWMH or ICCCM event to the window manager
|
// Sends an EWMH or ICCCM event to the window manager
|
||||||
//
|
//
|
||||||
static void sendEventToWM(_GLFWwindow* window, Atom type,
|
static void sendEventToWM(_GLFWwindow* window, Atom type,
|
||||||
@ -632,6 +592,15 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
const _GLFWwndconfig* wndconfig,
|
const _GLFWwndconfig* wndconfig,
|
||||||
Visual* visual, int depth)
|
Visual* visual, int depth)
|
||||||
{
|
{
|
||||||
|
int width = wndconfig->width;
|
||||||
|
int height = wndconfig->height;
|
||||||
|
|
||||||
|
if (wndconfig->scaleToMonitor)
|
||||||
|
{
|
||||||
|
width *= _glfw.x11.contentScaleX;
|
||||||
|
height *= _glfw.x11.contentScaleY;
|
||||||
|
}
|
||||||
|
|
||||||
// Create a colormap based on the visual used by the current context
|
// Create a colormap based on the visual used by the current context
|
||||||
window->x11.colormap = XCreateColormap(_glfw.x11.display,
|
window->x11.colormap = XCreateColormap(_glfw.x11.display,
|
||||||
_glfw.x11.root,
|
_glfw.x11.root,
|
||||||
@ -657,7 +626,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
window->x11.handle = XCreateWindow(_glfw.x11.display,
|
window->x11.handle = XCreateWindow(_glfw.x11.display,
|
||||||
_glfw.x11.root,
|
_glfw.x11.root,
|
||||||
0, 0,
|
0, 0,
|
||||||
wndconfig->width, wndconfig->height,
|
width, height,
|
||||||
0, // Border width
|
0, // Border width
|
||||||
depth, // Color depth
|
depth, // Color depth
|
||||||
InputOutput,
|
InputOutput,
|
||||||
@ -760,7 +729,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
XFree(hints);
|
XFree(hints);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNormalHints(window, wndconfig->width, wndconfig->height);
|
updateNormalHints(window, width, height);
|
||||||
|
|
||||||
// Set ICCCM WM_CLASS property
|
// Set ICCCM WM_CLASS property
|
||||||
{
|
{
|
||||||
@ -1264,8 +1233,10 @@ static void processEvent(XEvent *event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window = findWindowByHandle(event->xany.window);
|
if (XFindContext(_glfw.x11.display,
|
||||||
if (window == NULL)
|
event->xany.window,
|
||||||
|
_glfw.x11.context,
|
||||||
|
(XPointer*) &window) != 0)
|
||||||
{
|
{
|
||||||
// This is an event for a window that has already been destroyed
|
// This is an event for a window that has already been destroyed
|
||||||
return;
|
return;
|
||||||
@ -1484,12 +1455,20 @@ static void processEvent(XEvent *event)
|
|||||||
|
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
{
|
{
|
||||||
|
// XEnterWindowEvent is XCrossingEvent
|
||||||
|
const int x = event->xcrossing.x;
|
||||||
|
const int y = event->xcrossing.y;
|
||||||
|
|
||||||
// HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise
|
// HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise
|
||||||
// ignore the defined cursor for hidden cursor mode
|
// ignore the defined cursor for hidden cursor mode
|
||||||
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
|
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
|
||||||
updateCursorImage(window);
|
updateCursorImage(window);
|
||||||
|
|
||||||
_glfwInputCursorEnter(window, GLFW_TRUE);
|
_glfwInputCursorEnter(window, GLFW_TRUE);
|
||||||
|
_glfwInputCursorPos(window, x, y);
|
||||||
|
|
||||||
|
window->x11.lastCursorPosX = x;
|
||||||
|
window->x11.lastCursorPosY = y;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2479,6 +2458,14 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
|||||||
Atom* states;
|
Atom* states;
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
GLFWbool maximized = GLFW_FALSE;
|
GLFWbool maximized = GLFW_FALSE;
|
||||||
|
|
||||||
|
if (!_glfw.x11.NET_WM_STATE ||
|
||||||
|
!_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
|
||||||
|
!_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
|
||||||
|
{
|
||||||
|
return maximized;
|
||||||
|
}
|
||||||
|
|
||||||
const unsigned long count =
|
const unsigned long count =
|
||||||
_glfwGetWindowPropertyX11(window->x11.handle,
|
_glfwGetWindowPropertyX11(window->x11.handle,
|
||||||
_glfw.x11.NET_WM_STATE,
|
_glfw.x11.NET_WM_STATE,
|
||||||
@ -2814,8 +2801,24 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
|
|
||||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||||
{
|
{
|
||||||
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display,
|
int native = 0;
|
||||||
translateCursorShape(shape));
|
|
||||||
|
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_hand1;
|
||||||
|
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;
|
||||||
|
|
||||||
|
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
|
||||||
if (!cursor->x11.handle)
|
if (!cursor->x11.handle)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user