build #1

Merged
Synthasmagoria merged 24 commits from build into master 2026-09-15 13:38:54 +00:00
105 changed files with 13399 additions and 8732 deletions
Showing only changes of commit 400c5a02d1 - Show all commits

Optimized build that works

Synthasmagoria 2026-08-30 21:05:55 +02:00

View file

@ -9,6 +9,9 @@ if [[ -v 1 ]]; then
elif [ "$1" = "RELEASE" ]; then
MFLAGS="RAYLIB_BUILD_MODE=RELEASE"
CFLAGS="-Os -ffunction-sections -fdata-sections"
elif [ "$1" = "TEST" ]; then
MFLAGS="RAYLIB_BUILD_MODE=RELEASE"
CFLAGS="-Os"
else
echo "Usage: <script> <DEBUG/RELEASE>"
exit 1
@ -34,67 +37,67 @@ config_cflags="\
-DSUPPORT_MODULE_RSHAPES=1 \
-DSUPPORT_MODULE_RTEXTURES=1 \
-DSUPPORT_MODULE_RTEXT=1 \
-DSUPPORT_MODULE_RMODELS=0 \
-DSUPPORT_MODULE_RAUDIO=0 \
-DSUPPORT_MODULE_RMODELS=1 \
-DSUPPORT_MODULE_RAUDIO=1 \
-DSUPPORT_TRACELOG=1 \
-DSUPPORT_CAMERA_SYSTEM=0 \
-DSUPPORT_GESTURES_SYSTEM=0 \
-DSUPPORT_RPRAND_GENERATOR=0 \
-DSUPPORT_MOUSE_GESTURES=0 \
-DSUPPORT_SSH_KEYBOARD_RPI=0 \
-DSUPPORT_WINMM_HIGHRES_TIMER=0 \
-DSUPPORT_BUSY_WAIT_LOOP=0 \
-DSUPPORT_PARTIALBUSY_WAIT_LOOP=0 \
-DSUPPORT_SCREEN_CAPTURE=0 \
-DSUPPORT_COMPRESSION_API=0 \
-DSUPPORT_AUTOMATION_EVENTS=0 \
-DSUPPORT_CUSTOM_FRAME_CONTROL=0 \
-DSUPPORT_CLIPBOARD_IMAGE=0 \
-DRLGL_ENABLE_OPENGL_DEBUG_CONTEXT=0 \
-DRLGL_SHOW_GL_DETAILS_INFO=0 \
-DSUPPORT_QUADS_DRAW_MODE=0 \
-DSUPPORT_FILEFORMAT_PNG=0 \
-DSUPPORT_FILEFORMAT_BMP=0 \
-DSUPPORT_FILEFORMAT_TGA=0 \
-DSUPPORT_FILEFORMAT_JPG=0 \
-DSUPPORT_FILEFORMAT_GIF=0 \
-DSUPPORT_FILEFORMAT_QOI=0 \
-DSUPPORT_FILEFORMAT_PEP=0 \
-DSUPPORT_FILEFORMAT_PSD=0 \
-DSUPPORT_FILEFORMAT_DDS=0 \
-DSUPPORT_FILEFORMAT_HDR=0 \
-DSUPPORT_FILEFORMAT_PIC=0 \
-DSUPPORT_FILEFORMAT_PNM=0 \
-DSUPPORT_FILEFORMAT_KTX=0 \
-DSUPPORT_FILEFORMAT_ASTC=0 \
-DSUPPORT_FILEFORMAT_PKM=0 \
-DSUPPORT_FILEFORMAT_PVR=0 \
-DSUPPORT_IMAGE_EXPORT=0 \
-DSUPPORT_IMAGE_GENERATION=0 \
-DSUPPORT_CAMERA_SYSTEM=1 \
-DSUPPORT_GESTURES_SYSTEM=1 \
-DSUPPORT_RPRAND_GENERATOR=1 \
-DSUPPORT_MOUSE_GESTURES=1 \
-DSUPPORT_SSH_KEYBOARD_RPI=1 \
-DSUPPORT_WINMM_HIGHRES_TIMER=1 \
-DSUPPORT_BUSY_WAIT_LOOP=1 \
-DSUPPORT_PARTIALBUSY_WAIT_LOOP=1 \
-DSUPPORT_SCREEN_CAPTURE=1 \
-DSUPPORT_COMPRESSION_API=1 \
-DSUPPORT_AUTOMATION_EVENTS=1 \
-DSUPPORT_CUSTOM_FRAME_CONTROL=1 \
-DSUPPORT_CLIPBOARD_IMAGE=1 \
-DRLGL_ENABLE_OPENGL_DEBUG_CONTEXT=1 \
-DRLGL_SHOW_GL_DETAILS_INFO=1 \
-DSUPPORT_QUADS_DRAW_MODE=1 \
-DSUPPORT_FILEFORMAT_PNG=1 \
-DSUPPORT_FILEFORMAT_BMP=1 \
-DSUPPORT_FILEFORMAT_TGA=1 \
-DSUPPORT_FILEFORMAT_JPG=1 \
-DSUPPORT_FILEFORMAT_GIF=1 \
-DSUPPORT_FILEFORMAT_QOI=1 \
-DSUPPORT_FILEFORMAT_PEP=1 \
-DSUPPORT_FILEFORMAT_PSD=1 \
-DSUPPORT_FILEFORMAT_DDS=1 \
-DSUPPORT_FILEFORMAT_HDR=1 \
-DSUPPORT_FILEFORMAT_PIC=1 \
-DSUPPORT_FILEFORMAT_PNM=1 \
-DSUPPORT_FILEFORMAT_KTX=1 \
-DSUPPORT_FILEFORMAT_ASTC=1 \
-DSUPPORT_FILEFORMAT_PKM=1 \
-DSUPPORT_FILEFORMAT_PVR=1 \
-DSUPPORT_IMAGE_EXPORT=1 \
-DSUPPORT_IMAGE_GENERATION=1 \
-DSUPPORT_FILEFORMAT_TTF=1 \
-DSUPPORT_FILEFORMAT_FNT=0 \
-DSUPPORT_FILEFORMAT_BDF=0 \
-DSUPPORT_FILEFORMAT_OBJ=0 \
-DSUPPORT_FILEFORMAT_MTL=0 \
-DSUPPORT_FILEFORMAT_IQM=0 \
-DSUPPORT_FILEFORMAT_GLTF=0 \
-DSUPPORT_FILEFORMAT_VOX=0 \
-DSUPPORT_FILEFORMAT_M3D=0 \
-DSUPPORT_MESH_GENERATION=0 \
-DSUPPORT_GPU_SKINNING=0 \
-DSUPPORT_FILEFORMAT_WAV=0 \
-DSUPPORT_FILEFORMAT_OGG=0 \
-DSUPPORT_FILEFORMAT_MP3=0 \
-DSUPPORT_FILEFORMAT_QOA=0 \
-DSUPPORT_FILEFORMAT_FLAC=0 \
-DSUPPORT_FILEFORMAT_XM=0 \
-DSUPPORT_FILEFORMAT_MOD=0"
-DSUPPORT_FILEFORMAT_FNT=1 \
-DSUPPORT_FILEFORMAT_BDF=1 \
-DSUPPORT_FILEFORMAT_OBJ=1 \
-DSUPPORT_FILEFORMAT_MTL=1 \
-DSUPPORT_FILEFORMAT_IQM=1 \
-DSUPPORT_FILEFORMAT_GLTF=1 \
-DSUPPORT_FILEFORMAT_VOX=1 \
-DSUPPORT_FILEFORMAT_M3D=1 \
-DSUPPORT_MESH_GENERATION=1 \
-DSUPPORT_GPU_SKINNING=1 \
-DSUPPORT_FILEFORMAT_WAV=1 \
-DSUPPORT_FILEFORMAT_OGG=1 \
-DSUPPORT_FILEFORMAT_MP3=1 \
-DSUPPORT_FILEFORMAT_QOA=1 \
-DSUPPORT_FILEFORMAT_FLAC=1 \
-DSUPPORT_FILEFORMAT_XM=1 \
-DSUPPORT_FILEFORMAT_MOD=1"
source $emsdk_env
pushd raylib/src
echo "Compiling raylib static library for linux"
make --silent $modules $MFLAGS RAYLIB_CONFIG_FLAGS="$config_cflags" CUSTOM_CFLAGS="$CFLAGS" PLATFORM_OS=LINUX
make --silent $modules $MFLAGS CUSTOM_CFLAGS="$CFLAGS" PLATFORM_OS=LINUX
mv libraylib.a "../../${linux_library_dest}"
make --silent clean
@ -104,7 +107,7 @@ make --silent clean
# make --silent clean
echo "Compiling raylib static library for web"
make --silent $modules RAYLIB_CONFIG_FLAGS="$config_cflags" PLATFORM=PLATFORM_WEB
make --silent $modules PLATFORM=PLATFORM_WEB
mv libraylib.web.a libraylib.a
mv libraylib.a "../../${wasm_library_dest}"
make --silent clean

View file

@ -4157,22 +4157,22 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue)
{
// Draw hue bar:color bars
// NOTE: Using DrawRectangleGradientEx(bounds, color1, color2, color2, color1);
DrawRectangleGradientEx(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, bounds.width, bounds.height/6.0f },
DrawRectangleGradientEx(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, bounds.width, bounds.height/6.0f },
Fade(RAYGUI_CLITERAL(Color){ 255, 0, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 255, 0, 255 }, guiAlpha),
Fade(RAYGUI_CLITERAL(Color){ 255, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 0, 255 }, guiAlpha));
DrawRectangleGradientEx(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 1*(bounds.height/6.0f), bounds.width, bounds.height/6.0f },
DrawRectangleGradientEx(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 1*(bounds.height/6.0f), bounds.width, bounds.height/6.0f },
Fade(RAYGUI_CLITERAL(Color){ 255, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 0, 255 }, guiAlpha),
Fade(RAYGUI_CLITERAL(Color){ 0, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 255, 0, 255 }, guiAlpha));
DrawRectangleGradientEx(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 2*(bounds.height/6.0f), bounds.width, bounds.height/6.0f },
DrawRectangleGradientEx(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 2*(bounds.height/6.0f), bounds.width, bounds.height/6.0f },
Fade(RAYGUI_CLITERAL(Color){ 0, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 255, 255 }, guiAlpha),
Fade(RAYGUI_CLITERAL(Color){ 0, 255, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 0, 255 }, guiAlpha));
DrawRectangleGradientEx(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 3*(bounds.height/6.0f), bounds.width, bounds.height/6.0f },
DrawRectangleGradientEx(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 3*(bounds.height/6.0f), bounds.width, bounds.height/6.0f },
Fade(RAYGUI_CLITERAL(Color){ 0, 255, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 0, 255, 255 }, guiAlpha),
Fade(RAYGUI_CLITERAL(Color){ 0, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 255, 255 }, guiAlpha));
DrawRectangleGradientEx(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 4*(bounds.height/6.0f), bounds.width, bounds.height/6.0f },
DrawRectangleGradientEx(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 4*(bounds.height/6.0f), bounds.width, bounds.height/6.0f },
Fade(RAYGUI_CLITERAL(Color){ 0, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 255, 255 }, guiAlpha),
Fade(RAYGUI_CLITERAL(Color){ 255, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 0, 255, 255 }, guiAlpha));
DrawRectangleGradientEx(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 5*(bounds.height/6.0f), bounds.width, bounds.height/6.0f },
DrawRectangleGradientEx(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 5*(bounds.height/6.0f), bounds.width, bounds.height/6.0f },
Fade(RAYGUI_CLITERAL(Color){ 255, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 0, 255 }, guiAlpha),
Fade(RAYGUI_CLITERAL(Color){ 255, 0, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 255, 255 }, guiAlpha));
}
@ -4214,7 +4214,7 @@ int GuiColorPicker(Rectangle bounds, const char *text, Color *color)
// NOTE: this conversion can cause low hue-resolution, if the r, g and b value are very similar, which causes the hue bar to shift around when only the GuiColorPanel is used
Vector3 hsv = ConvertRGBtoHSV(RAYGUI_CLITERAL(Vector3){ (*color).r/255.0f, (*color).g/255.0f, (*color).b/255.0f });
if (result != RESULT_CHANGED) result = GuiColorBarHue(boundsHue, NULL, &hsv.x);
result = GuiColorBarHue(boundsHue, NULL, &hsv.x);
//color.a = (unsigned char)(GuiColorBarAlpha(boundsAlpha, (float)color.a/255.0f)*255.0f);
Vector3 rgb = ConvertHSVtoRGB(hsv);
@ -4449,11 +4449,11 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, ch
Rectangle textBounds = { 0 };
if (message != NULL)
{
int textSize = GuiGetTextWidth(message) + 2;
int messageTextSize = GuiGetTextWidth(message) + 2;
textBounds.x = bounds.x + bounds.width/2 - textSize/2;
textBounds.x = bounds.x + bounds.width/2 - messageTextSize/2;
textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + messageInputHeight/4 - (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
textBounds.width = (float)textSize;
textBounds.width = (float)messageTextSize;
textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
}
@ -4641,8 +4641,8 @@ void GuiLoadStyle(const char *fileName)
{
case 'v':
{
sscanf(buffer, "v %d", &version);
}
sscanf(buffer, "v %u", &version);
} break;
case 'p':
{
// Style property: p <control_id> <property_id> <property_value> <property_name>

View file

@ -30,14 +30,22 @@ set(raylib_public_headers
# Sources to be compiled
set(raylib_sources
raudio.c
rcore.c
rmodels.c
rshapes.c
rtext.c
rtextures.c
)
# Only build raudio if it's enabled
if (NOT DEFINED SUPPORT_MODULE_RAUDIO OR SUPPORT_MODULE_RAUDIO)
list(APPEND raylib_sources raudio.c)
endif()
# Only build rmodels if it's enabled
if (NOT DEFINED SUPPORT_MODULE_RMODELS OR SUPPORT_MODULE_RMODELS)
list(APPEND raylib_sources rmodels.c)
endif()
# <root>/cmake/GlfwImport.cmake handles the details around the inclusion of glfw
if (NOT ${PLATFORM} MATCHES "Web")
include(GlfwImport)
@ -48,10 +56,10 @@ endif ()
# Produces a variable LIBS_PRIVATE that will be used later
include(LibraryConfigurations)
if (SUPPORT_MODULE_RAUDIO)
MESSAGE(STATUS "Audio Backend: miniaudio")
else ()
if (DEFINED SUPPORT_MODULE_RAUDIO AND NOT SUPPORT_MODULE_RAUDIO)
MESSAGE(STATUS "Audio Backend: None (-DCUSTOMIZE_BUILD=ON -DSUPPORT_MODULE_RAUDIO=OFF)")
else ()
MESSAGE(STATUS "Audio Backend: miniaudio")
endif ()
add_library(raylib ${raylib_sources} ${raylib_public_headers})
@ -99,6 +107,34 @@ endif ()
target_link_libraries(raylib PRIVATE $<BUILD_INTERFACE:${LIBS_PRIVATE}>)
target_link_libraries(raylib PUBLIC ${LIBS_PUBLIC})
# Static libraries must export their private link dependencies for installed consumers.
# LINK_ONLY keeps those dependencies out of the compile interface.
if (NOT BUILD_SHARED_LIBS)
set(raylib_install_private_libs ${LIBS_PRIVATE})
if (NOT glfw3_FOUND)
list(REMOVE_ITEM raylib_install_private_libs glfw)
# Bundled GLFW links its Cocoa backend frameworks privately, so they
# must be propagated to consumers of the static library, whose final
# link line would otherwise miss them. Only the Desktop platform uses
# bundled GLFW; other platforms (e.g. Memory) have no Cocoa/GLFW symbols.
if (APPLE AND PLATFORM STREQUAL "Desktop")
find_library(COCOA_FRAMEWORK Cocoa)
find_library(IOKIT_FRAMEWORK IOKit)
find_library(QUARTZCORE_FRAMEWORK QuartzCore)
list(APPEND raylib_install_private_libs
${COCOA_FRAMEWORK}
${IOKIT_FRAMEWORK}
${QUARTZCORE_FRAMEWORK})
endif ()
endif()
foreach(lib IN LISTS raylib_install_private_libs)
target_link_libraries(raylib INTERFACE $<INSTALL_INTERFACE:$<LINK_ONLY:${lib}>>)
endforeach()
endif()
# Sets some compile time definitions for the pre-processor
# If CUSTOMIZE_BUILD option is on you will not use config.h by default
# and you will be able to select more build options

View file

@ -240,6 +240,9 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
ifeq ($(ANDROID_ARCH),x86_64)
ANDROID_COMPILER_ARCH = x86_64
endif
ifndef ANDROID_COMPILER_ARCH
$(error ANDROID_COMPILER_ARCH: Unknown ANDROID_ARCH=$(ANDROID_ARCH))
endif
endif
# Define raylib graphics api depending on selected platform
@ -652,7 +655,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
#LDLIBS += -latomic
endif
ifeq ($(PLATFORM_OS),OSX)
LDLIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreAudio -framework CoreVideo
LDLIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreAudio -framework CoreVideo -framework QuartzCore
endif
ifeq ($(PLATFORM_OS),BSD)
LDLIBS = -lGL -lpthread
@ -704,7 +707,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW)
ifeq ($(PLATFORM_OS),OSX)
# Libraries for Debian MacOS desktop compiling
# NOTE: Required packages: libegl1-mesa-dev
LDLIBS += -lm -framework Foundation -framework AppKit -framework IOKit -framework OpenGL -framework CoreVideo
LDLIBS += -lm -framework Foundation -framework AppKit -framework IOKit -framework OpenGL -framework CoreVideo -framework QuartzCore
endif
endif
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)

View file

@ -173,20 +173,22 @@
//#define RL_CULL_DISTANCE_FAR 4000.0 // Default projection matrix far cull distance
// Default shader vertex attribute locations
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION 0
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD 1
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL 2
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR 3
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT 4
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES 7
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
// NOTE: Locations can be redefined by user if required
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION 0
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD 1
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL 2
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR 3
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT 4
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES 7
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
//#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM 9
// Default shader vertex attribute/uniform names to set location points
// NOTE: When a new shader is loaded, locations are tried to be set for convenience, looking for the names defined here
// In case custom shader names are used, it's up to the user to set locations with GetShaderLocation*() functions
// WARNING: Location pre-defined names can not be changed, they are used by default shaders and all raylib examples shaders, they are just listed here for reference
// WARNING: In case custom shader names are used, it's up to the user to set locations with GetShaderLocation*() functions
//#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
//#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD
//#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL
@ -196,6 +198,7 @@
//#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES "vertexBoneIndices" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES
//#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
//#define RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM "instanceTransform" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM
//#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
//#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
//#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
@ -203,6 +206,7 @@
//#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))
//#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (tint color, multiplied by texture color)
//#define RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES "boneMatrices" // bone matrices
//#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
//#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
//#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
@ -240,6 +244,9 @@
#ifndef SUPPORT_FILEFORMAT_QOI
#define SUPPORT_FILEFORMAT_QOI 1
#endif
#ifndef SUPPORT_FILEFORMAT_PEP
#define SUPPORT_FILEFORMAT_PEP 0
#endif
#ifndef SUPPORT_FILEFORMAT_PSD
#define SUPPORT_FILEFORMAT_PSD 0 // Disabled by default
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/*
FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
dr_flac - v0.13.3 - 2026-01-17
dr_flac - v0.13.4 - TBD
David Reid - mackron@gmail.com
@ -126,7 +126,7 @@ extern "C" {
#define DRFLAC_VERSION_MAJOR 0
#define DRFLAC_VERSION_MINOR 13
#define DRFLAC_VERSION_REVISION 3
#define DRFLAC_VERSION_REVISION 4
#define DRFLAC_VERSION_STRING DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION)
#include <stddef.h> /* For size_t. */
@ -1547,6 +1547,8 @@ static DRFLAC_INLINE drflac_bool32 drflac_has_sse41(void)
#define DRFLAC_ZERO_OBJECT(p) DRFLAC_ZERO_MEMORY((p), sizeof(*(p)))
#endif
#define DRFLAC_MIN(a, b) (((a) < (b)) ? (a) : (b))
#define DRFLAC_MAX_SIMD_VECTOR_SIZE 64 /* 64 for AVX-512 in the future. */
/* Result Codes */
@ -5980,8 +5982,6 @@ static drflac_bool32 drflac__seek_to_pcm_frame__binary_search_internal(drflac* p
break; /* Failed to seek to FLAC frame. */
}
} else {
const float approxCompressionRatio = (drflac_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / ((drflac_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0f);
if (pcmRangeLo > pcmFrameIndex) {
/* We seeked too far forward. We need to move our target byte backward and try again. */
byteRangeHi = lastSuccessfulSeekOffset;
@ -6004,12 +6004,14 @@ static drflac_bool32 drflac__seek_to_pcm_frame__binary_search_internal(drflac* p
break; /* Failed to seek to FLAC frame. */
}
} else {
const double approxCompressionRatio = (drflac_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / ((drflac_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0);
byteRangeLo = lastSuccessfulSeekOffset;
if (byteRangeHi < byteRangeLo) {
byteRangeHi = byteRangeLo;
}
targetByte = lastSuccessfulSeekOffset + (drflac_uint64)(((drflac_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * approxCompressionRatio);
targetByte = lastSuccessfulSeekOffset + (drflac_uint64)(((drflac_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * pFlac->bitsPerSample)/8.0) * approxCompressionRatio);
if (targetByte > byteRangeHi) {
targetByte = byteRangeHi;
}
@ -6402,7 +6404,7 @@ static void* drflac__realloc_from_callbacks(void* p, size_t szNew, size_t szOld,
}
if (p != NULL) {
DRFLAC_COPY_MEMORY(p2, p, szOld);
DRFLAC_COPY_MEMORY(p2, p, DRFLAC_MIN(szNew, szOld));
pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
}
@ -6430,11 +6432,22 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
We want to keep track of the byte position in the stream of the seektable. At the time of calling this function we know that
we'll be sitting on byte 42.
*/
drflac_uint64 runningFilePos = 42;
drflac_uint64 seektablePos = 0;
drflac_uint32 seektableSize = 0;
drflac_uint64 runningFilePos = 42;
drflac_uint64 seektablePos = 0;
drflac_uint32 seektableSize = 0;
drflac_int64 fileSize = 0;
drflac_bool32 hasKnownFileSize = DRFLAC_FALSE;
(void)onTell;
/* We'll be doing some memory allocations here against untrusted data. We'll do a basic validation check that they don't exceed the size of the file. */
if (onTell != NULL && onSeek != NULL) {
if (onSeek(pUserData, 0, DRFLAC_SEEK_END)) {
if (onTell(pUserData, &fileSize)) {
hasKnownFileSize = DRFLAC_TRUE;
}
onSeek(pUserData, runningFilePos, DRFLAC_SEEK_SET);
}
}
for (;;) {
drflac_metadata metadata;
@ -6444,6 +6457,11 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
if (drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == DRFLAC_FALSE) {
return DRFLAC_FALSE;
}
if (hasKnownFileSize && (blockSize > ((drflac_uint64)fileSize - runningFilePos))) {
return DRFLAC_FALSE; /* Block size exceeds the size of the file. */
}
runningFilePos += 4;
metadata.type = blockType;
@ -6559,7 +6577,7 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
return DRFLAC_FALSE;
}
metadata.data.vorbis_comment.vendor = pRunningData; pRunningData += metadata.data.vorbis_comment.vendorLength;
metadata.data.vorbis_comment.vendor = pRunningData; pRunningData += metadata.data.vorbis_comment.vendorLength;
metadata.data.vorbis_comment.commentCount = drflac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
/* Need space for 'commentCount' comments after the block, which at minimum is a drflac_uint32 per comment */
@ -6747,13 +6765,18 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
blockSizeRemaining -= 4;
metadata.data.picture.mimeLength = drflac__be2host_32(metadata.data.picture.mimeLength);
if (blockSizeRemaining < metadata.data.picture.mimeLength) {
result = DRFLAC_FALSE;
goto done_flac;
}
pMime = (char*)drflac__malloc_from_callbacks(metadata.data.picture.mimeLength + 1, pAllocationCallbacks); /* +1 for null terminator. */
if (pMime == NULL) {
result = DRFLAC_FALSE;
goto done_flac;
}
if (blockSizeRemaining < metadata.data.picture.mimeLength || onRead(pUserData, pMime, metadata.data.picture.mimeLength) != metadata.data.picture.mimeLength) {
if (onRead(pUserData, pMime, metadata.data.picture.mimeLength) != metadata.data.picture.mimeLength) {
result = DRFLAC_FALSE;
goto done_flac;
}
@ -6769,13 +6792,18 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
blockSizeRemaining -= 4;
metadata.data.picture.descriptionLength = drflac__be2host_32(metadata.data.picture.descriptionLength);
if (blockSizeRemaining < metadata.data.picture.descriptionLength) {
result = DRFLAC_FALSE;
goto done_flac;
}
pDescription = (char*)drflac__malloc_from_callbacks(metadata.data.picture.descriptionLength + 1, pAllocationCallbacks); /* +1 for null terminator. */
if (pDescription == NULL) {
result = DRFLAC_FALSE;
goto done_flac;
}
if (blockSizeRemaining < metadata.data.picture.descriptionLength || onRead(pUserData, pDescription, metadata.data.picture.descriptionLength) != metadata.data.picture.descriptionLength) {
if (onRead(pUserData, pDescription, metadata.data.picture.descriptionLength) != metadata.data.picture.descriptionLength) {
result = DRFLAC_FALSE;
goto done_flac;
}
@ -8094,11 +8122,17 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
return NULL;
}
if ((0xFFFFFFFF - (seekpointCount * sizeof(drflac_seekpoint))) < allocationSize) {
#ifndef DR_FLAC_NO_OGG
drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
#endif
return NULL;
}
allocationSize += seekpointCount * sizeof(drflac_seekpoint);
}
pFlac = (drflac*)drflac__malloc_from_callbacks(allocationSize, &allocationCallbacks);
pFlac = (drflac*)drflac__malloc_from_callbacks((size_t)allocationSize, &allocationCallbacks);
if (pFlac == NULL) {
#ifndef DR_FLAC_NO_OGG
drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
@ -12169,6 +12203,10 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
/*
REVISION HISTORY
================
v0.13.4 - TBD
- Add a bounds check when allocating memory during metadata processing.
- Fix a possible overflow error when parsing picture metadata.
v0.13.3 - 2026-01-17
- Fix a compiler compatibility issue with some inlined assembly.
- Fix a compilation warning.

View file

@ -3188,6 +3188,10 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
pTagDataBeg = pFirstFrameData + DRMP3_HDR_SIZE + (bs.pos/8);
pTagData = pTagDataBeg;
if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 8) {
goto done_xing_info; /* Frame too small for a Xing/Info tag. */
}
/* Check for both "Xing" and "Info" identifiers. */
isXing = (pTagData[0] == 'X' && pTagData[1] == 'i' && pTagData[2] == 'n' && pTagData[3] == 'g');
isInfo = (pTagData[0] == 'I' && pTagData[1] == 'n' && pTagData[2] == 'f' && pTagData[3] == 'o');
@ -3199,42 +3203,60 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
pTagData += 8; /* Skip past the ID and flags. */
if (flags & 0x01) { /* FRAMES flag. */
if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 4) {
goto done_xing_info; /* Invalid Xing/Info tag. */
}
detectedMP3FrameCount = (drmp3_uint32)pTagData[0] << 24 | (drmp3_uint32)pTagData[1] << 16 | (drmp3_uint32)pTagData[2] << 8 | (drmp3_uint32)pTagData[3];
pTagData += 4;
}
if (flags & 0x02) { /* BYTES flag. */
if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 4) {
goto done_xing_info; /* Invalid Xing/Info tag. */
}
bytes = (drmp3_uint32)pTagData[0] << 24 | (drmp3_uint32)pTagData[1] << 16 | (drmp3_uint32)pTagData[2] << 8 | (drmp3_uint32)pTagData[3];
(void)bytes; /* <-- Just to silence a warning about `bytes` being assigned but unused. Want to leave this here in case I want to make use of it later. */
pTagData += 4;
}
if (flags & 0x04) { /* TOC flag. */
if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 100) {
goto done_xing_info; /* Invalid Xing/Info tag. */
}
/* TODO: Extract and bind seek points. */
pTagData += 100;
}
if (flags & 0x08) { /* SCALE flag. */
if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 4) {
goto done_xing_info; /* Invalid Xing/Info tag. */
}
pTagData += 4;
}
/* At this point we're done with the Xing/Info header. Now we can look at the LAME data. */
if (pTagData[0]) {
int delayInPCMFrames;
int paddingInPCMFrames;
if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 36) {
goto done_xing_info; /* Invalid Xing/Info tag. */
}
pTagData += 21;
if (pTagData - pFirstFrameData + 14 < firstFrameInfo.frame_bytes) {
int delayInPCMFrames;
int paddingInPCMFrames;
delayInPCMFrames = (( (drmp3_uint32)pTagData[0] << 4) | ((drmp3_uint32)pTagData[1] >> 4)) + (528 + 1);
paddingInPCMFrames = ((((drmp3_uint32)pTagData[1] & 0xF) << 8) | ((drmp3_uint32)pTagData[2] )) - (528 + 1);
if (paddingInPCMFrames < 0) {
paddingInPCMFrames = 0; /* Padding cannot be negative. Probably a malformed file. Ignore. */
}
pMP3->delayInPCMFrames = (drmp3_uint32)delayInPCMFrames;
pMP3->paddingInPCMFrames = (drmp3_uint32)paddingInPCMFrames;
delayInPCMFrames = (( (drmp3_uint32)pTagData[0] << 4) | ((drmp3_uint32)pTagData[1] >> 4)) + (528 + 1);
paddingInPCMFrames = ((((drmp3_uint32)pTagData[1] & 0xF) << 8) | ((drmp3_uint32)pTagData[2] )) - (528 + 1);
if (paddingInPCMFrames < 0) {
paddingInPCMFrames = 0; /* Padding cannot be negative. Probably a malformed file. Ignore. */
}
pMP3->delayInPCMFrames = (drmp3_uint32)delayInPCMFrames;
pMP3->paddingInPCMFrames = (drmp3_uint32)paddingInPCMFrames;
}
/*
@ -3273,6 +3295,8 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
*/
drmp3dec_init(&pMP3->decoder);
}
done_xing_info:;
} else {
/* Failed to read the side info. */
}
@ -3285,7 +3309,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
}
if (detectedMP3FrameCount != 0xFFFFFFFF) {
pMP3->totalPCMFrameCount = detectedMP3FrameCount * firstFramePCMFrameCount;
pMP3->totalPCMFrameCount = (drmp3_uint64)detectedMP3FrameCount * firstFramePCMFrameCount;
}
pMP3->channels = pMP3->mp3FrameChannels;
@ -4247,7 +4271,7 @@ DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 frame
#else
/* Slow path. Convert from s16 to f32. */
{
drmp3_int16 pTempS16[8192];
drmp3_int16 pTempS16[1152*2]; /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */
drmp3_uint64 totalPCMFramesRead = 0;
while (totalPCMFramesRead < framesToRead) {
@ -4284,7 +4308,7 @@ DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 frame
#else
/* Slow path. Convert from f32 to s16. */
{
float pTempF32[4096];
float pTempF32[1152*2]; /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */
drmp3_uint64 totalPCMFramesRead = 0;
while (totalPCMFramesRead < framesToRead) {
@ -4772,7 +4796,7 @@ static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig,
drmp3_uint64 totalFramesRead = 0;
drmp3_uint64 framesCapacity = 0;
float* pFrames = NULL;
float temp[4096];
float temp[1152*2]; /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */
DRMP3_ASSERT(pMP3 != NULL);
@ -4841,7 +4865,7 @@ static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pC
drmp3_uint64 totalFramesRead = 0;
drmp3_uint64 framesCapacity = 0;
drmp3_int16* pFrames = NULL;
drmp3_int16 temp[4096];
drmp3_int16 temp[1152*2]; /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */
DRMP3_ASSERT(pMP3 != NULL);
@ -5010,6 +5034,9 @@ DIFFERENCES BETWEEN minimp3 AND dr_mp3
REVISION HISTORY
================
v0.7.4 - TBD
- Fix an overflow error with "Xing" and "Info" tag parsing.
- Add some validation checks for "Xing" and "Info" tag parsing.
- Reduce size of some stack allocations.
- Improvements to SIMD detection.
v0.7.3 - 2026-01-17

View file

@ -1,6 +1,6 @@
/*
WAV audio loader and writer. Choice of public domain or MIT-0. See license statements at the end of this file.
dr_wav - v0.14.5 - 2026-03-03
dr_wav - v0.14.6 - TBD
David Reid - mackron@gmail.com
@ -147,7 +147,7 @@ extern "C" {
#define DRWAV_VERSION_MAJOR 0
#define DRWAV_VERSION_MINOR 14
#define DRWAV_VERSION_REVISION 5
#define DRWAV_VERSION_REVISION 6
#define DRWAV_VERSION_STRING DRWAV_XSTRINGIFY(DRWAV_VERSION_MAJOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_MINOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_REVISION)
#include <stddef.h> /* For size_t. */
@ -1971,7 +1971,15 @@ DRWAV_PRIVATE drwav_result drwav__read_chunk_header(drwav_read_proc onRead, void
return DRWAV_INVALID_FILE;
}
pHeaderOut->sizeInBytes = drwav_bytes_to_u64(sizeInBytes) - 24; /* <-- Subtract 24 because w64 includes the size of the header. */
pHeaderOut->sizeInBytes = drwav_bytes_to_u64(sizeInBytes);
/* Subtract 24 from the size because with w64 the reported chunk size includes the size of the header itself. */
if (pHeaderOut->sizeInBytes >= 24) {
pHeaderOut->sizeInBytes -= 24;
} else {
return DRWAV_INVALID_FILE;
}
pHeaderOut->paddingSize = drwav__chunk_padding_size_w64(pHeaderOut->sizeInBytes);
*pRunningBytesReadOut += 24;
} else {
@ -2201,7 +2209,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_smpl_to_metadata_obj(drwav__metadata_pars
so it's consistent with how we do it in the first stage.
*/
loopCount = drwav_bytes_to_u32(smplHeaderData + 28);
calculatedLoopCount = (pChunkHeader->sizeInBytes - DRWAV_SMPL_BYTES) / DRWAV_SMPL_LOOP_BYTES;
calculatedLoopCount = (drwav_uint32)((pChunkHeader->sizeInBytes - DRWAV_SMPL_BYTES) / DRWAV_SMPL_LOOP_BYTES);
if (loopCount != calculatedLoopCount) {
return totalBytesRead;
}
@ -2580,8 +2588,10 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_bext_to_metadata_obj(drwav__metadata_pars
pMetadata->data.bext.pCodingHistory = (char*)drwav__metadata_get_memory(pParser, extraBytes + 1, 1);
DRWAV_ASSERT(pMetadata->data.bext.pCodingHistory != NULL);
bytesRead += drwav__metadata_parser_read(pParser, pMetadata->data.bext.pCodingHistory, extraBytes, NULL);
pMetadata->data.bext.codingHistorySize = (drwav_uint32)drwav__strlen(pMetadata->data.bext.pCodingHistory);
pMetadata->data.bext.codingHistorySize = (drwav_uint32)drwav__metadata_parser_read(pParser, pMetadata->data.bext.pCodingHistory, extraBytes, NULL);
pMetadata->data.bext.pCodingHistory[pMetadata->data.bext.codingHistorySize] = '\0'; /* <-- Explicit null terminator in case of a badly formed file. */
bytesRead += pMetadata->data.bext.codingHistorySize;
} else {
pMetadata->data.bext.pCodingHistory = NULL;
pMetadata->data.bext.codingHistorySize = 0;
@ -2755,10 +2765,10 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser*
bytesJustRead = drwav__metadata_parser_read(pParser, buffer, sizeof(buffer), &bytesRead);
if (bytesJustRead == sizeof(buffer)) {
drwav_uint32 loopCount = drwav_bytes_to_u32(buffer);
drwav_uint64 calculatedLoopCount;
drwav_uint32 calculatedLoopCount;
/* The loop count must be validated against the size of the chunk. */
calculatedLoopCount = (pChunkHeader->sizeInBytes - DRWAV_SMPL_BYTES) / DRWAV_SMPL_LOOP_BYTES;
calculatedLoopCount = (drwav_uint32)((pChunkHeader->sizeInBytes - DRWAV_SMPL_BYTES) / DRWAV_SMPL_LOOP_BYTES);
if (calculatedLoopCount == loopCount) {
bytesJustRead = drwav__metadata_parser_read(pParser, buffer, sizeof(buffer), &bytesRead);
if (bytesJustRead == sizeof(buffer)) {
@ -2860,7 +2870,9 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser*
return bytesRead;
}
allocSizeNeeded += drwav__strlen(buffer) + 1;
allocSizeNeeded += (size_t)pChunkHeader->sizeInBytes - DRWAV_BEXT_BYTES + 1; /* Coding history. */
/* Coding history. */
allocSizeNeeded += (size_t)pChunkHeader->sizeInBytes - DRWAV_BEXT_BYTES + 1;
drwav__metadata_request_extra_memory_for_stage_2(pParser, allocSizeNeeded, 1);
@ -3321,6 +3333,10 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
((pWav->container == drwav_container_w64) && drwav_guid_equal(header.id.guid, drwavGUID_W64_FMT))) {
drwav_uint8 fmtData[16];
if (header.sizeInBytes < sizeof(fmtData)) {
return DRWAV_FALSE; /* Invalid fmt chunk. */
}
foundChunk_fmt = DRWAV_TRUE;
if (pWav->onRead(pWav->pUserData, fmtData, sizeof(fmtData)) != sizeof(fmtData)) {
@ -3833,6 +3849,11 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
/* We decode two samples per byte. There will be blockCount headers in the data chunk. This is enough to know how to calculate the total PCM frame count. */
totalBlockHeaderSizeInBytes = blockCount * (6*fmt.channels);
if (totalBlockHeaderSizeInBytes >= dataChunkSize) { /* <-- We'll be subtracting totalBlockHeaderSizeInBytes from dataChunkSize next so it must be validated. */
drwav_free(pWav->pMetadata, &pWav->allocationCallbacks);
return DRWAV_FALSE; /* Invalid file. */
}
pWav->totalPCMFrameCount = ((dataChunkSize - totalBlockHeaderSizeInBytes) * 2) / fmt.channels;
}
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
@ -3846,6 +3867,11 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
/* We decode two samples per byte. There will be blockCount headers in the data chunk. This is enough to know how to calculate the total PCM frame count. */
totalBlockHeaderSizeInBytes = blockCount * (4*fmt.channels);
if (totalBlockHeaderSizeInBytes >= dataChunkSize) { /* <-- We'll be subtracting totalBlockHeaderSizeInBytes from dataChunkSize next so it must be validated. */
drwav_free(pWav->pMetadata, &pWav->allocationCallbacks);
return DRWAV_FALSE; /* Invalid file. */
}
pWav->totalPCMFrameCount = ((dataChunkSize - totalBlockHeaderSizeInBytes) * 2) / fmt.channels;
/* The header includes a decoded sample for each channel which acts as the initial predictor sample. */
@ -6725,6 +6751,10 @@ DRWAV_PRIVATE void drwav__pcm_to_s16(drwav_int16* pOut, const drwav_uint8* pIn,
shift += 8;
}
if (!drwav__is_little_endian()) {
sample = drwav__bswap64(sample);
}
pIn += j;
*pOut++ = (drwav_int16)((drwav_int64)sample >> 48);
}
@ -7166,6 +7196,10 @@ DRWAV_PRIVATE void drwav__pcm_to_f32(float* pOut, const drwav_uint8* pIn, size_t
shift += 8;
}
if (!drwav__is_little_endian()) {
sample = drwav__bswap64(sample);
}
pIn += j;
*pOut++ = (float)((drwav_int64)sample / 9223372036854775807.0);
}
@ -7650,6 +7684,10 @@ DRWAV_PRIVATE void drwav__pcm_to_s32(drwav_int32* pOut, const drwav_uint8* pIn,
shift += 8;
}
if (!drwav__is_little_endian()) {
sample = drwav__bswap64(sample);
}
pIn += j;
*pOut++ = (drwav_int32)((drwav_int64)sample >> 32);
}
@ -8557,6 +8595,13 @@ DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b)
/*
REVISION HISTORY
================
v0.14.6 - TBD
- Fix an error when loading files with a malformed "bext" chunk.
- Fix an error when loading files with a malformed "fmt" chunk.
- Fix an underflow error with badly formed ADPCM encoded files.
- Fix an underflow error with badly formed W64 files.
- Fix an error when converting from >32 bit samples to s16/f32/s32 on big-endian architectures.
v0.14.5 - 2026-03-03
- Fix a crash when loading files with a malformed "smpl" chunk.
- Fix a signed overflow bug with the MS-ADPCM decoder.

View file

@ -2,7 +2,7 @@
*
* fix_win32_compatibility.h Utility to help include windows.h with raylib projects
*
* Useage: #include "fix_win32_compatibility.h" any library that uses windows.h
* Usage: #include "fix_win32_compatibility.h" any library that uses windows.h
* order is critical, this must be done before raylib
*
* LICENSE: MIT
@ -32,7 +32,7 @@
#pragma once
// move the windows functions to new names
// note that you can't call these functions or structures from your code, but you should not neeed to
// note that you can't call these functions or structures from your code, but you should not need to
#define CloseWindow CloseWindowWin32
#define Rectangle RectangleWin32
#define ShowCursor ShowCursorWin32
@ -46,8 +46,9 @@
// include windows
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <playsoundapi.h>
// remove all our redfintions so that raylib can define them properly
// remove all our redefinitions so that raylib can define them properly
#undef CloseWindow
#undef Rectangle
#undef ShowCursor

View file

@ -1,6 +1,8 @@
# Usage:
# cmake -P GenerateMappings.cmake <path/to/mappings.h.in> <path/to/mappings.h>
cmake_policy(VERSION 3.16)
set(source_url "https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt")
set(source_path "${CMAKE_CURRENT_BINARY_DIR}/gamecontrollerdb.txt")
set(template_path "${CMAKE_ARGV3}")
@ -22,24 +24,24 @@ if (status_code)
endif()
file(STRINGS "${source_path}" lines)
foreach(line ${lines})
if (line MATCHES "^[0-9a-fA-F]")
if (line MATCHES "platform:Windows")
if (GLFW_WIN32_MAPPINGS)
string(APPEND GLFW_WIN32_MAPPINGS "\n")
endif()
string(APPEND GLFW_WIN32_MAPPINGS "\"${line}\",")
elseif (line MATCHES "platform:Mac OS X")
if (GLFW_COCOA_MAPPINGS)
string(APPEND GLFW_COCOA_MAPPINGS "\n")
endif()
string(APPEND GLFW_COCOA_MAPPINGS "\"${line}\",")
elseif (line MATCHES "platform:Linux")
if (GLFW_LINUX_MAPPINGS)
string(APPEND GLFW_LINUX_MAPPINGS "\n")
endif()
string(APPEND GLFW_LINUX_MAPPINGS "\"${line}\",")
list(FILTER lines INCLUDE REGEX "^[0-9a-fA-F]")
foreach(line IN LISTS lines)
if (line MATCHES "platform:Windows")
if (GLFW_WIN32_MAPPINGS)
string(APPEND GLFW_WIN32_MAPPINGS "\n")
endif()
string(APPEND GLFW_WIN32_MAPPINGS "\"${line}\",")
elseif (line MATCHES "platform:Mac OS X")
if (GLFW_COCOA_MAPPINGS)
string(APPEND GLFW_COCOA_MAPPINGS "\n")
endif()
string(APPEND GLFW_COCOA_MAPPINGS "\"${line}\",")
elseif (line MATCHES "platform:Linux")
if (GLFW_LINUX_MAPPINGS)
string(APPEND GLFW_LINUX_MAPPINGS "\n")
endif()
string(APPEND GLFW_LINUX_MAPPINGS "\"${line}\",")
endif()
endforeach()

View file

@ -1,14 +1,6 @@
cmake_minimum_required(VERSION 3.4...3.28 FATAL_ERROR)
cmake_minimum_required(VERSION 3.16...3.28 FATAL_ERROR)
project(GLFW VERSION 3.4.0 LANGUAGES C)
if (POLICY CMP0069)
cmake_policy(SET CMP0069 NEW)
endif()
if (POLICY CMP0077)
cmake_policy(SET CMP0077 NEW)
endif()
project(GLFW VERSION 3.5.1 LANGUAGES C HOMEPAGE_URL "https://www.glfw.org/")
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
@ -46,11 +38,7 @@ set(GLFW_LIBRARY_TYPE "${GLFW_LIBRARY_TYPE}" CACHE STRING
"Library type override for GLFW (SHARED, STATIC, OBJECT, or empty to follow BUILD_SHARED_LIBS)")
if (GLFW_LIBRARY_TYPE)
if (GLFW_LIBRARY_TYPE STREQUAL "SHARED")
set(GLFW_BUILD_SHARED_LIBRARY TRUE)
else()
set(GLFW_BUILD_SHARED_LIBRARY FALSE)
endif()
string(COMPARE EQUAL "${GLFW_LIBRARY_TYPE}" "SHARED" GLFW_BUILD_SHARED_LIBRARY)
else()
set(GLFW_BUILD_SHARED_LIBRARY ${BUILD_SHARED_LIBS})
endif()
@ -80,24 +68,7 @@ endif()
# This is here because it also applies to tests and examples
#--------------------------------------------------------------------
if (MSVC AND NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
if (CMAKE_VERSION VERSION_LESS 3.15)
foreach (flag CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELWITHDEBINFO)
if (flag MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
endif()
if (flag MATCHES "/MDd")
string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}")
endif()
endforeach()
else()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
#--------------------------------------------------------------------

View file

@ -6,10 +6,12 @@ excludes other invaluable contributions like language bindings and text and
video tutorials.
- Bobyshev Alexander
- Alzathar
- Laurent Aphecetche
- Matt Arsenault
- Takuro Ashie
- ashishgamedev
- avagordon01
- David Avedissian
- Luca Bacci
- Keith Bauer
@ -23,6 +25,7 @@ video tutorials.
- Denis Bernard
- BiBi
- Doug Binks
- bitb4ker
- blanco
- Waris Boonyasiriwat
- Kyle Brenneman
@ -33,6 +36,7 @@ video tutorials.
- Nicolas Caramelli
- David Carlier
- Arturo Castro
- Jose Luis Cercós Pita
- Chi-kwan Chan
- Victor Chernyakin
- TheChocolateOre
@ -48,11 +52,15 @@ video tutorials.
- Andrew Corrigan
- Bailey Cosier
- Noel Cower
- James Cowgill
- CuriouserThing
- Bill Currie
- Jason Daly
- danhambleton
- danijel1023
- Jarrod Davis
- Aaron Day
- decce
- Olivier Delannoy
- Paul R. Deppe
- Michael Dickens
@ -65,14 +73,18 @@ video tutorials.
- Robin Eklind
- Jan Ekström
- Siavash Eliasi
- er-azh
- Jan Hendrik Farr
- Ahmad Fatoum
- Nikita Fediuchin
- Felipe Ferreira
- Michael Fogleman
- Folling
- forworldm
- Jason Francis
- Gerald Franz
- Mário Freitas
- Friz64
- GeO4d
- Marcus Geelnard
- Gegy
@ -88,6 +100,7 @@ video tutorials.
- Andrew Gutekanst
- Stephen Gutekanst
- Jonathan Hale
- halx99
- Daniel Hauser
- hdf89shfdfs
- Moritz Heinemann
@ -118,6 +131,7 @@ video tutorials.
- Josh Kilmer
- Byunghoon Kim
- Cameron King
- knokko
- Peter Knut
- Christoph Kubisch
- Yuri Kunde Schlesner
@ -153,8 +167,10 @@ video tutorials.
- Bryce Mehring
- Jonathan Mercier
- Marcel Metz
- Lucas Michaudel
- Liam Middlebrook
- mightgoyardstill
- Mihail
- Ave Milia
- Icyllis Milica
- Jonathan Miller
@ -168,6 +184,7 @@ video tutorials.
- Jon Morton
- Pierre Moulon
- Martins Mozeiko
- Tomáš Mráz
- Pascal Muetschard
- James Murphy
- Julian Møller
@ -214,6 +231,7 @@ video tutorials.
- Philip Rideout
- Eddie Ringle
- Max Risuhin
- road2react
- Joe Roback
- Jorge Rodriguez
- Jari Ronkainen
@ -221,12 +239,13 @@ video tutorials.
- Ed Ropple
- Aleksey Rybalkin
- Mikko Rytkönen
- saikyun
- Riku Salminen
- Yoshinori Sano
- Brandon Schaefer
- Sebastian Schuberth
- Scr3amer
- Jan Schuerkamp
- Jan Schürkamp
- Christian Sdunek
- Matt Sealey
- Steve Sexton
@ -275,10 +294,12 @@ video tutorials.
- Corentin Wallez
- Torsten Walluhn
- Patrick Walton
- Ivor Wanders
- Jim Wang
- Xo Wang
- Andre Weissflog
- Jay Weisskopf
- Drew Weymouth
- Frank Wille
- Andy Williams
- Joel Winarske

View file

@ -1,18 +1,198 @@
# GLFW (modified for raylib)
# GLFW
This directory contains a modification of GLFW, whose official website and
upstream repository are https://glfw.org and https://github.com/glfw/glfw,
respectively.
[![Build status](https://github.com/glfw/glfw/actions/workflows/build.yml/badge.svg)](https://github.com/glfw/glfw/actions)
[![Build status](https://ci.appveyor.com/api/projects/status/0kf0ct9831i5l6sp/branch/master?svg=true)](https://ci.appveyor.com/project/elmindreda/glfw)
In this modification, some static functions sharing the same name in different
platforms have been renamed so all of GLFW's source files can be combined into
one (as done by ``rglfw.c``). Also, the Null platform, which is not used by
raylib, has been disabled. The renamed functions are:
## Introduction
``
createKeyTables()
translateKey()
acquireMonitor()
releaseMonitor()
``
GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan
application development. It provides a simple, platform-independent API for
creating windows, contexts and surfaces, reading input, handling events, etc.
GLFW is written primarily in C99, with parts of macOS support being written in
Objective-C.
GLFW supports Windows, macOS and Linux, and also works on many other Unix-like
systems. On Linux both Wayland and X11 are supported.
GLFW is licensed under the [zlib/libpng
license](https://www.glfw.org/license.html).
You can [download](https://www.glfw.org/download.html) the latest stable release
as source or Windows and macOS binaries. There are [release
tags](https://github.com/glfw/glfw/releases) with source and binary archives
attached for every version since 3.0.
The [documentation](https://www.glfw.org/docs/latest/) is available online and is
also included in source and binary archives, except those generated
automatically by Github. The documentation contains guides, a tutorial and the
API reference. The [release
notes](https://www.glfw.org/docs/latest/news.html) list the new features,
caveats and deprecations in the latest release. The [version
history](https://www.glfw.org/changelog.html) lists every user-visible change
for every release.
GLFW exists because of the contributions of [many people](CONTRIBUTORS.md)
around the world, whether by reporting bugs, providing community support, adding
features, reviewing or testing code, debugging, proofreading docs, suggesting
features or fixing bugs.
## System requirements
GLFW supports Windows 7 and later and macOS 10.11 and later. On GNOME Wayland,
window decorations will be very basic unless the
[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor) package is
installed. Linux and other Unix-like systems running X11 are supported even
without a desktop environment or modern extensions, although some features
require a clipboard manager or a modern window manager.
See the [compatibility guide](https://www.glfw.org/docs/latest/compat.html)
for more detailed information.
## Compiling GLFW
GLFW supports compilation with Visual C++ (2013 and later), GCC and Clang. Both
Clang-CL and MinGW-w64 are supported. Other C99 compilers will likely also
work, but this is not regularly tested.
There are [pre-compiled binaries](https://www.glfw.org/download.html)
available for Windows and macOS.
GLFW itself needs only CMake and the headers and libraries for your operating
system and window system. No other SDKs are required.
See the [compilation guide](https://www.glfw.org/docs/latest/compile.html) for
more information about compiling GLFW and the exact dependencies required for
each window system.
The examples and test programs depend on a number of tiny libraries. These are
bundled in the `deps/` directory. The repository has no submodules.
- [getopt\_port](https://github.com/kimgr/getopt_port/) for examples
with command-line options
- [TinyCThread](https://github.com/tinycthread/tinycthread) for threaded
examples
- [glad2](https://github.com/Dav1dde/glad) for loading OpenGL and Vulkan
functions
- [linmath.h](https://github.com/datenwolf/linmath.h) for linear algebra in
examples
- [Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) for test and example UI
- [stb\_image\_write](https://github.com/nothings/stb) for writing images to disk
The documentation is generated with [Doxygen](https://doxygen.org/) when the
library is built, provided CMake could find a sufficiently new version of it
during configuration.
## Using GLFW
See the [HTML documentation](https://www.glfw.org/docs/latest/) for a tutorial,
guides and the API reference.
## Contributing to GLFW
See the [contribution
guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
more information.
The `master` branch is the stable integration branch and _should_ always compile
and run on all supported platforms. Details of a newly added feature,
including the public API, may change until it has been included in a release.
The `latest` branch is equivalent to the [highest numbered](https://semver.org/)
release, although it may not always point to the same commit as the tag for that
release.
The `ci` branch is used to trigger continuous integration jobs for code under
testing and should never be relied on for any purpose.
## Reporting bugs
Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues).
Please check the [contribution
guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
information on what to include when reporting a bug.
## Changelog since 3.5
None.
## Changelog since 3.4
- Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond
the limit of the mouse button tokens to be reported (#2423)
- Added `glfwGetEGLConfig` function to query the `EGLConfig` of a window (#2045)
- Added `glfwGetGLXFBConfig` function to query the `GLXFBConfig` of a window (#1925)
- Updated minimum CMake version to 3.16 (#2541)
- Removed support for building with original MinGW (#2540)
- [Win32] Removed support for Windows XP and Vista (#2505)
- [Win32] Bugfix: Media keys were reported with a scancode of 256 (#1768,#2417,#2625)
- [Cocoa] Added `QuartzCore` framework as link-time dependency
- [Cocoa] Removed support for OS X 10.10 Yosemite and earlier (#2506)
- [Cocoa] Bugfix: Cmd+Period, Ctrl+Tab and Ctrl+Esc key events were not emitted
(#1362,#2278)
- [Wayland] Bugfix: The fractional scaling related objects were not destroyed
- [Wayland] Bugfix: `glfwInit` would segfault on compositor with no seat (#2517)
- [Wayland] Bugfix: A drag entering a non-GLFW surface could cause a segfault
- [Wayland] Bugfix: Ignore key repeat events when no window has keyboard focus (#2727)
- [Wayland] Bugfix: Reset key repeat timer when window destroyed (#2741,#2727)
- [Wayland] Bugfix: Memory would leak if reading a data offer failed midway
- [Wayland] Bugfix: Retrieved cursor position would be incorrect when hovering over
fallback decorations
- [Wayland] Bugfix: Fallback decorations would report scroll events
- [Wayland] Bugfix: Keyboard repeat events halted when any key is released (#2568)
- [Wayland] Bugfix: Fallback decorations would show menu at wrong position
- [Wayland] Bugfix: The cursor was not updated when clicking through from
a modal to a fallback decoration
- [Wayland] Bugfix: The cursor position was not updated when clicking through
from a modal to the content area
- [Wayland] Bugfix: free modules at end of terminate function to resolve
potential segmentation fault (#2744)
- [Wayland] Bugfix: Confining or disabling the cursor could segfault on
compositors without `pointer-constraints-unstable-v1`
- [Wayland] Bugfix: Key repeat did not function on very old compositors
- [Wayland] Bugfix: The `libwayland-client` library was not unloaded at termination
- [Wayland] Bugfix: Scroll events were sent twice on some versions of GNOME (#2494)
- [Wayland] Bugfix: Two-dimensional scroll input was emitted as separate axes
- [Wayland] Bugfix: Mouse wheel scroll distance was incorrect on some compositors
- [Wayland] Bugfix: `glfwSwapBuffers` would halt with nonzero swap interval when window
was suspended (#1350,#2582,#2640,#2719,#2723,#2800,#2827)
- [Wayland] Bugfix: `glfwPostEmptyEvent` would leak a callback proxy (#2836)
- [Wayland] Bugfix: `glfwHideWindow` did not always send its request immediately
- [Wayland] Bugfix: Some event types were not always processed by `glfwPollEvents` or
`glfwWait*Events` (#2793,#2795)
- [Wayland] Bugfix: Scaled framebuffer size was sometimes incorect (#2713,#2810)
- [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631)
- [X11] Bugfix: Occasional crash when an idle display awakes (#2766)
- [X11] Bugfix: Prevent BadWindow when creating small windows with a content scale
less than 1 (#2754)
- [X11] Bugfix: Clamp width and height to >= 1 to prevent BadValue error and app exit
- [X11] Bugfix: Floating windows silently became non-floating when hidden (#2276)
- [X11] Bugfix: The `libXext` library was not unloaded at termination
- [Linux] Bugfix: The header for `ioctl` was only implicitly included (#2778)
- [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface`
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`
- [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to
`GLFW_NATIVE_CONTEXT_API` (#2518)
## Contact
On [glfw.org](https://www.glfw.org/) you can find the latest version of GLFW, as
well as news, documentation and other information about the project.
If you have questions related to the use of GLFW, we have a
[forum](https://discourse.glfw.org/).
If you have a bug to report, a patch to submit or a feature you'd like to
request, please file it in the
[issue tracker](https://github.com/glfw/glfw/issues) on GitHub.
Finally, if you're interested in helping out with the development of GLFW or
porting it to your favorite platform, join us on the forum or GitHub.

View file

@ -1,5 +1,5 @@
/*************************************************************************
* GLFW 3.4 - www.glfw.org
* GLFW 3.5 - www.glfw.org
* A library for OpenGL, window and input
*------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard
@ -291,14 +291,14 @@ extern "C" {
* features are added to the API but it remains backward-compatible.
* @ingroup init
*/
#define GLFW_VERSION_MINOR 4
#define GLFW_VERSION_MINOR 5
/*! @brief The revision number of the GLFW header.
*
* The revision number of the GLFW header. This is incremented when a bug fix
* release is made that does not contain any API changes.
* @ingroup init
*/
#define GLFW_VERSION_REVISION 0
#define GLFW_VERSION_REVISION 1
/*! @} */
/*! @brief One.
@ -1149,11 +1149,12 @@ extern "C" {
#define GLFW_OPENGL_CORE_PROFILE 0x00032001
#define GLFW_OPENGL_COMPAT_PROFILE 0x00032002
#define GLFW_CURSOR 0x00033001
#define GLFW_STICKY_KEYS 0x00033002
#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
#define GLFW_LOCK_KEY_MODS 0x00033004
#define GLFW_RAW_MOUSE_MOTION 0x00033005
#define GLFW_CURSOR 0x00033001
#define GLFW_STICKY_KEYS 0x00033002
#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
#define GLFW_LOCK_KEY_MODS 0x00033004
#define GLFW_RAW_MOUSE_MOTION 0x00033005
#define GLFW_UNLIMITED_MOUSE_BUTTONS 0x00033006
#define GLFW_CURSOR_NORMAL 0x00034001
#define GLFW_CURSOR_HIDDEN 0x00034002
@ -1227,13 +1228,13 @@ extern "C" {
* The top-left to bottom-right diagonal resize/move shape. This is usually
* a diagonal double-headed arrow.
*
* @note @macos This shape is provided by a private system API and may fail
* @note __macOS:__ This shape is provided by a private system API and may fail
* with @ref GLFW_CURSOR_UNAVAILABLE in the future.
*
* @note @wayland This shape is provided by a newer standard not supported by
* @note __Wayland:__ This shape is provided by a newer standard not supported by
* all cursor themes.
*
* @note @x11 This shape is provided by a newer standard not supported by all
* @note __X11:__ This shape is provided by a newer standard not supported by all
* cursor themes.
*/
#define GLFW_RESIZE_NWSE_CURSOR 0x00036007
@ -1242,13 +1243,13 @@ extern "C" {
* The top-right to bottom-left diagonal resize/move shape. This is usually
* a diagonal double-headed arrow.
*
* @note @macos This shape is provided by a private system API and may fail
* @note __macOS:__ This shape is provided by a private system API and may fail
* with @ref GLFW_CURSOR_UNAVAILABLE in the future.
*
* @note @wayland This shape is provided by a newer standard not supported by
* @note __Wayland:__ This shape is provided by a newer standard not supported by
* all cursor themes.
*
* @note @x11 This shape is provided by a newer standard not supported by all
* @note __X11:__ This shape is provided by a newer standard not supported by all
* cursor themes.
*/
#define GLFW_RESIZE_NESW_CURSOR 0x00036008
@ -1263,10 +1264,10 @@ extern "C" {
* The operation-not-allowed shape. This is usually a circle with a diagonal
* line through it.
*
* @note @wayland This shape is provided by a newer standard not supported by
* @note __Wayland:__ This shape is provided by a newer standard not supported by
* all cursor themes.
*
* @note @x11 This shape is provided by a newer standard not supported by all
* @note __X11:__ This shape is provided by a newer standard not supported by all
* cursor themes.
*/
#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A
@ -1343,6 +1344,10 @@ extern "C" {
#define GLFW_PLATFORM_NULL 0x00060005
/*! @} */
/* Reserved platform define for external Emscripten ports: 0x00060006
* See https://github.com/pongasoft/emscripten-glfw
*/
#define GLFW_DONT_CARE -1
@ -1628,7 +1633,7 @@ typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos);
* @sa @ref glfwSetWindowSizeCallback
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -1648,7 +1653,7 @@ typedef void (* GLFWwindowsizefun)(GLFWwindow* window, int width, int height);
* @sa @ref glfwSetWindowCloseCallback
*
* @since Added in version 2.5.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -1668,7 +1673,7 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow* window);
* @sa @ref glfwSetWindowRefreshCallback
*
* @since Added in version 2.5.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -1799,7 +1804,7 @@ typedef void (* GLFWwindowcontentscalefun)(GLFWwindow* window, float xscale, flo
* @sa @ref glfwSetMouseButtonCallback
*
* @since Added in version 1.0.
* @glfw3 Added window handle and modifier mask parameters.
* __GLFW 3:__ Added window handle and modifier mask parameters.
*
* @ingroup input
*/
@ -1890,7 +1895,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffse
* @sa @ref glfwSetKeyCallback
*
* @since Added in version 1.0.
* @glfw3 Added window handle, scancode and modifier mask parameters.
* __GLFW 3:__ Added window handle, scancode and modifier mask parameters.
*
* @ingroup input
*/
@ -1911,7 +1916,7 @@ typedef void (* GLFWkeyfun)(GLFWwindow* window, int key, int scancode, int actio
* @sa @ref glfwSetCharCallback
*
* @since Added in version 2.4.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup input
*/
@ -2019,7 +2024,7 @@ typedef void (* GLFWjoystickfun)(int jid, int event);
* @sa @ref glfwGetVideoModes
*
* @since Added in version 1.0.
* @glfw3 Added refresh rate member.
* __GLFW 3:__ Added refresh rate member.
*
* @ingroup monitor
*/
@ -2082,7 +2087,7 @@ typedef struct GLFWgammaramp
* @sa @ref window_icon
*
* @since Added in version 2.1.
* @glfw3 Removed format and bytes-per-pixel members.
* __GLFW 3:__ Removed format and bytes-per-pixel members.
*
* @ingroup window
*/
@ -2182,12 +2187,12 @@ typedef struct GLFWallocator
* @errors Possible errors include @ref GLFW_PLATFORM_UNAVAILABLE and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @macos This function will change the current directory of the
* @remark __macOS:__ This function will change the current directory of the
* application to the `Contents/Resources` subdirectory of the application's
* bundle, if present. This can be disabled with the @ref
* GLFW_COCOA_CHDIR_RESOURCES init hint.
*
* @remark @macos This function will create the main menu and dock icon for the
* @remark __macOS:__ This function will create the main menu and dock icon for the
* application. If GLFW finds a `MainMenu.nib` it is loaded and assumed to
* contain a menu bar. Otherwise a minimal menu bar is created manually with
* common commands like Hide, Quit and About. The About entry opens a minimal
@ -2202,7 +2207,7 @@ typedef struct GLFWallocator
* to something other than `wayland` or `x11`, the regular detection mechanism
* will be used instead.
*
* @remark @x11 This function will set the `LC_CTYPE` category of the
* @remark __X11:__ This function will set the `LC_CTYPE` category of the
* application locale according to the current environment if that category is
* still "C". This is because the "C" locale breaks Unicode text input.
*
@ -2678,7 +2683,7 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos,
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark @win32 On Windows 8 and earlier the physical size is calculated from
* @remark __Win32:__ On Windows 8 and earlier the physical size is calculated from
* the current resolution and system DPI instead of querying the monitor EDID data.
*
* @thread_safety This function must only be called from the main thread.
@ -2712,7 +2717,7 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @wayland Fractional scaling information is not yet available for
* @remark __Wayland:__ Fractional scaling information is not yet available for
* monitors, so this function only returns integer content scales.
*
* @thread_safety This function must only be called from the main thread.
@ -2860,7 +2865,7 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun callback);
* @sa @ref glfwGetVideoMode
*
* @since Added in version 1.0.
* @glfw3 Changed to return an array of modes for a specific monitor.
* __GLFW 3:__ Changed to return an array of modes for a specific monitor.
*
* @ingroup monitor
*/
@ -2914,8 +2919,8 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE,
* @ref GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
*
* @remark @wayland Gamma handling is a privileged protocol, this function
* will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
* @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
*
* @thread_safety This function must only be called from the main thread.
*
@ -2938,8 +2943,8 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR
* and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
*
* @remark @wayland Gamma handling is a privileged protocol, this function
* will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while
* @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while
* returning `NULL`.
*
* @pointer_lifetime The returned structure and its arrays are allocated and
@ -2980,10 +2985,10 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
* @remark The size of the specified gamma ramp should match the size of the
* current ramp for that monitor.
*
* @remark @win32 The gamma ramp size must be 256.
* @remark __Win32:__ The gamma ramp size must be 256.
*
* @remark @wayland Gamma handling is a privileged protocol, this function
* will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
* @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
*
* @pointer_lifetime The specified gamma ramp is copied before this function
* returns.
@ -3158,32 +3163,32 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
* GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
*
* @remark @win32 Window creation will fail if the Microsoft GDI software
* @remark __Win32:__ Window creation will fail if the Microsoft GDI software
* OpenGL implementation is the only one available.
*
* @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it
* @remark __Win32:__ If the executable has an icon resource named `GLFW_ICON,` it
* will be set as the initial icon for the window. If no such icon is present,
* the `IDI_APPLICATION` icon will be used instead. To set a different icon,
* see @ref glfwSetWindowIcon.
*
* @remark @win32 The context to share resources with must not be current on
* @remark __Win32:__ The context to share resources with must not be current on
* any other thread.
*
* @remark @macos The OS only supports core profile contexts for OpenGL
* @remark __macOS:__ The OS only supports core profile contexts for OpenGL
* versions 3.2 and later. Before creating an OpenGL context of version 3.2 or
* later you must set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint)
* hint accordingly. OpenGL 3.0 and 3.1 contexts are not supported at all
* on macOS.
*
* @remark @macos The GLFW window has no icon, as it is not a document
* @remark __macOS:__ The GLFW window has no icon, as it is not a document
* window, but the dock icon will be the same as the application bundle's icon.
* For more information on bundles, see the
* [Bundle Programming Guide][bundle-guide] in the Mac Developer Library.
*
* [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/
*
* @remark @macos On OS X 10.10 and later the window frame will not be rendered
* at full resolution on Retina displays unless the
* @remark __macOS:__ The window frame will not be rendered at full resolution
* on Retina displays unless the
* [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint)
* hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the
* application bundle's `Info.plist`. For more information, see
@ -3194,11 +3199,11 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
*
* [hidpi-guide]: https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
*
* @remark @macos When activating frame autosaving with
* @remark __macOS:__ When activating frame autosaving with
* [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified
* window size and position may be overridden by previously saved values.
*
* @remark @wayland GLFW uses [libdecor][] where available to create its window
* @remark __Wayland:__ GLFW uses [libdecor][] where available to create its window
* decorations. This in turn uses server-side XDG decorations where available
* and provides high quality client-side decorations on compositors like GNOME.
* If both XDG decorations and libdecor are unavailable, GLFW falls back to
@ -3207,15 +3212,15 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
*
* [libdecor]: https://gitlab.freedesktop.org/libdecor/libdecor
*
* @remark @x11 Some window managers will not respect the placement of
* @remark __X11:__ Some window managers will not respect the placement of
* initially hidden windows.
*
* @remark @x11 Due to the asynchronous nature of X11, it may take a moment for
* @remark __X11:__ Due to the asynchronous nature of X11, it may take a moment for
* a window to reach its requested state. This means you may not be able to
* query the final size, position or other attributes directly after window
* creation.
*
* @remark @x11 The class part of the `WM_CLASS` window property will by
* @remark __X11:__ The class part of the `WM_CLASS` window property will by
* default be set to the window title passed to this function. The instance
* part will use the contents of the `RESOURCE_NAME` environment variable, if
* present and not empty, or fall back to the window title. Set the
@ -3348,7 +3353,7 @@ GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @macos The window title will not be updated until the next time you
* @remark __macOS:__ The window title will not be updated until the next time you
* process events.
*
* @thread_safety This function must only be called from the main thread.
@ -3357,7 +3362,7 @@ GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window);
* @sa @ref glfwGetWindowTitle
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -3391,14 +3396,14 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
* @pointer_lifetime The specified image data is copied before this function
* returns.
*
* @remark @macos Regular windows do not have icons on macOS. This function
* @remark __macOS:__ Regular windows do not have icons on macOS. This function
* will emit @ref GLFW_FEATURE_UNAVAILABLE. The dock icon will be the same as
* the application bundle's icon. For more information on bundles, see the
* [Bundle Programming Guide][bundle-guide] in the Mac Developer Library.
*
* [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/
*
* @remark @wayland There is no existing protocol to change an icon, the
* @remark __Wayland:__ There is no existing protocol to change an icon, the
* window will thus inherit the one defined in the application's desktop file.
* This function will emit @ref GLFW_FEATURE_UNAVAILABLE.
*
@ -3429,8 +3434,8 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* i
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
*
* @remark @wayland There is no way for an application to retrieve the global
* position of its windows. This function will emit @ref
* @remark __Wayland:__ Window positions are not currently part of any common
* Wayland protocol, so this function cannot be implemented and will emit @ref
* GLFW_FEATURE_UNAVAILABLE.
*
* @thread_safety This function must only be called from the main thread.
@ -3463,8 +3468,8 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
*
* @remark @wayland There is no way for an application to set the global
* position of its windows. This function will emit @ref
* @remark __Wayland:__ Window positions are not currently part of any common
* Wayland protocol, so this function cannot be implemented and will emit @ref
* GLFW_FEATURE_UNAVAILABLE.
*
* @thread_safety This function must only be called from the main thread.
@ -3473,7 +3478,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
* @sa @ref glfwGetWindowPos
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -3503,7 +3508,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
* @sa @ref glfwSetWindowSize
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -3538,7 +3543,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
* @remark If you set size limits and an aspect ratio that conflict, the
* results are undefined.
*
* @remark @wayland The size limits will not be applied until the window is
* @remark __Wayland:__ The size limits will not be applied until the window is
* actually resized, either by the user or by the compositor.
*
* @thread_safety This function must only be called from the main thread.
@ -3581,7 +3586,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe
* @remark If you set size limits and an aspect ratio that conflict, the
* results are undefined.
*
* @remark @wayland The aspect ratio will not be applied until the window is
* @remark __Wayland:__ The aspect ratio will not be applied until the window is
* actually resized, either by the user or by the compositor.
*
* @thread_safety This function must only be called from the main thread.
@ -3627,7 +3632,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
* @sa @ref glfwSetWindowMonitor
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -3777,7 +3782,7 @@ GLFWAPI float glfwGetWindowOpacity(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
*
* @remark @wayland There is no way to set an opacity factor for a window.
* @remark __Wayland:__ There is no way to set an opacity factor for a window.
* This function will emit @ref GLFW_FEATURE_UNAVAILABLE.
*
* @thread_safety This function must only be called from the main thread.
@ -3806,10 +3811,6 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @wayland Once a window is iconified, @ref glfwRestoreWindow won’t
* be able to restore it. This is a design decision of the xdg-shell
* protocol.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_iconify
@ -3817,7 +3818,7 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
* @sa @ref glfwMaximizeWindow
*
* @since Added in version 2.1.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -3837,6 +3838,10 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark __Wayland:__ Restoring a window from maximization is not currently
* part of any common Wayland protocol, so this function can only restore
* windows from maximization.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_iconify
@ -3844,7 +3849,7 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
* @sa @ref glfwMaximizeWindow
*
* @since Added in version 2.1.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -3891,7 +3896,7 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @wayland Because Wayland wants every frame of the desktop to be
* @remark __Wayland:__ Because Wayland wants every frame of the desktop to be
* complete, this function does not immediately make the window visible.
* Instead it will become visible the next time the window framebuffer is
* updated after this call.
@ -3954,7 +3959,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @wayland The compositor will likely ignore focus requests unless
* @remark __Wayland:__ The compositor will likely ignore focus requests unless
* another window created by the same application already has input focus.
*
* @thread_safety This function must only be called from the main thread.
@ -3982,7 +3987,7 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @macos Attention is requested to the application as a whole, not the
* @remark __macOS:__ Attention is requested to the application as a whole, not the
* specific window.
*
* @thread_safety This function must only be called from the main thread.
@ -4057,8 +4062,8 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
* affected by any resizing or mode switching, although you may need to update
* your viewport if the framebuffer size has changed.
*
* @remark @wayland The desired window position is ignored, as there is no way
* for an application to set this property.
* @remark __Wayland:__ Window positions are not currently part of any common
* Wayland protocol. The window position arguments are ignored.
*
* @thread_safety This function must only be called from the main thread.
*
@ -4095,8 +4100,9 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int
* errors. However, this function should not fail as long as it is passed
* valid arguments and the library has been [initialized](@ref intro_init).
*
* @remark @wayland The Wayland protocol provides no way to check whether a
* window is iconfied, so @ref GLFW_ICONIFIED always returns `GLFW_FALSE`.
* @remark __Wayland:__ Checking whether a window is iconified is not currently
* part of any common Wayland protocol, so the @ref GLFW_ICONIFIED attribute
* cannot be implemented and is always `GLFW_FALSE`.
*
* @thread_safety This function must only be called from the main thread.
*
@ -4138,7 +4144,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
* @remark Calling @ref glfwGetWindowAttrib will always return the latest
* value, even if that value is ignored by the current mode of the window.
*
* @remark @wayland The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is
* @remark __Wayland:__ The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is
* not supported. Setting this will emit @ref GLFW_FEATURE_UNAVAILABLE.
*
* @thread_safety This function must only be called from the main thread.
@ -4218,8 +4224,8 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark @wayland This callback will never be called, as there is no way for
* an application to know its global position.
* @remark __Wayland:__ This callback will not be called. The Wayland protocol
* provides no way to be notified of when a window is moved.
*
* @thread_safety This function must only be called from the main thread.
*
@ -4257,7 +4263,7 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow
* @sa @ref window_size
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter and return value.
* __GLFW 3:__ Added window handle parameter and return value.
*
* @ingroup window
*/
@ -4289,7 +4295,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark @macos Selecting Quit from the application menu will trigger the
* @remark __macOS:__ Selecting Quit from the application menu will trigger the
* close callback for all windows.
*
* @thread_safety This function must only be called from the main thread.
@ -4297,7 +4303,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind
* @sa @ref window_close
*
* @since Added in version 2.5.
* @glfw3 Added window handle parameter and return value.
* __GLFW 3:__ Added window handle parameter and return value.
*
* @ingroup window
*/
@ -4333,7 +4339,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi
* @sa @ref window_refresh
*
* @since Added in version 2.5.
* @glfw3 Added window handle parameter and return value.
* __GLFW 3:__ Added window handle parameter and return value.
*
* @ingroup window
*/
@ -4394,6 +4400,10 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark __Wayland:__ This callback will not be called. The Wayland protocol
* provides no way to be notified of when a window is iconified, and no way to
* check whether a window is currently iconified.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_iconify
@ -4514,7 +4524,8 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*
* GLFW will pass those events on to the application callbacks before
* returning.
*
* Event processing is not required for joystick input to work.
* Event processing is not required to receive joystick input. Joystick state
* is polled when a joystick input or gamepad input function is called.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
@ -4559,7 +4570,8 @@ GLFWAPI void glfwPollEvents(void);
* GLFW will pass those events on to the application callbacks before
* returning.
*
* Event processing is not required for joystick input to work.
* Event processing is not required to receive joystick input. Joystick state
* is polled when a joystick input or gamepad input function is called.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
@ -4606,7 +4618,8 @@ GLFWAPI void glfwWaitEvents(void);
* GLFW will pass those events on to the application callbacks before
* returning.
*
* Event processing is not required for joystick input to work.
* Event processing is not required to receive joystick input. Joystick state
* is polled when a joystick input or gamepad input function is called.
*
* @param[in] timeout The maximum amount of time, in seconds, to wait.
*
@ -4676,8 +4689,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
*
* This function sets an input mode option for the specified window. The mode
* must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS,
* @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or
* @ref GLFW_RAW_MOUSE_MOTION.
* @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS
* @ref GLFW_RAW_MOUSE_MOTION, or @ref GLFW_UNLIMITED_MOUSE_BUTTONS.
*
* If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
* modes:
@ -4717,6 +4730,11 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
* attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE. Call @ref
* glfwRawMouseMotionSupported to check for support.
*
* If the mode is `GLFW_UNLIMITED_MOUSE_BUTTONS`, the value must be either
* `GLFW_TRUE` to disable the mouse button limit when calling the mouse button
* callback, or `GLFW_FALSE` to limit the mouse buttons sent to the callback
* to the mouse button token values up to `GLFW_MOUSE_BUTTON_LAST`.
*
* @param[in] window The window whose input mode to set.
* @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`,
* `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or
@ -4894,7 +4912,7 @@ GLFWAPI int glfwGetKeyScancode(int key);
* @sa @ref input_key
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup input
*/
@ -4911,8 +4929,11 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
* returns `GLFW_PRESS` the first time you call it for a mouse button that was
* pressed, even if that mouse button has already been released.
*
* The @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode does not effect the
* limit on buttons which can be polled with this function.
*
* @param[in] window The desired window.
* @param[in] button The desired [mouse button](@ref buttons).
* @param[in] button The desired [mouse button token](@ref buttons).
* @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
@ -4923,7 +4944,7 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
* @sa @ref input_mouse_button
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup input
*/
@ -4993,7 +5014,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
*
* @remark @wayland This function will only work when the cursor mode is
* @remark __Wayland:__ This function will only work when the cursor mode is
* `GLFW_CURSOR_DISABLED`, otherwise it will emit @ref GLFW_FEATURE_UNAVAILABLE.
*
* @thread_safety This function must only be called from the main thread.
@ -5191,7 +5212,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
* @sa @ref input_key
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter and return value.
* __GLFW 3:__ Added window handle parameter and return value.
*
* @ingroup input
*/
@ -5234,7 +5255,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun callback);
* @sa @ref input_char
*
* @since Added in version 2.4.
* @glfw3 Added window handle parameter and return value.
* __GLFW 3:__ Added window handle parameter and return value.
*
* @ingroup input
*/
@ -5288,10 +5309,15 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods
* is called when a mouse button is pressed or released.
*
* When a window loses input focus, it will generate synthetic mouse button
* release events for all pressed mouse buttons. You can tell these events
* from user-generated events by the fact that the synthetic ones are generated
* after the focus loss event has been processed, i.e. after the
* [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
* release events for all pressed mouse buttons with associated button tokens.
* You can tell these events from user-generated events by the fact that the
* synthetic ones are generated after the focus loss event has been processed,
* i.e. after the [window focus callback](@ref glfwSetWindowFocusCallback) has
* been called.
*
* The reported `button` value can be higher than `GLFW_MOUSE_BUTTON_LAST` if
* the button does not have an associated [button token](@ref buttons) and the
* @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode is set.
*
* @param[in] window The window whose callback to set.
* @param[in] callback The new callback, or `NULL` to remove the currently set
@ -5313,7 +5339,7 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods
* @sa @ref input_mouse_button
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter and return value.
* __GLFW 3:__ Added window handle parameter and return value.
*
* @ingroup input
*/
@ -5543,7 +5569,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count);
* @sa @ref joystick_button
*
* @since Added in version 2.2.
* @glfw3 Changed to return a dynamic array.
* __GLFW 3:__ Changed to return a dynamic array.
*
* @ingroup input
*/
@ -5907,7 +5933,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @win32 The clipboard on Windows has a single global lock for reading and
* @remark __Win32:__ The clipboard on Windows has a single global lock for reading and
* writing. GLFW tries to acquire it a few times, which is almost always enough. If it
* cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.
* It is safe to try this multiple times.
@ -5940,7 +5966,7 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
*
* @remark @win32 The clipboard on Windows has a single global lock for reading and
* @remark __Win32:__ The clipboard on Windows has a single global lock for reading and
* writing. GLFW tries to acquire it a few times, which is almost always enough. If it
* cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.
* It is safe to try this multiple times.
@ -6148,6 +6174,10 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
*
* @remark __Wayland:__ When the swap interval is greater than zero and the
* window is not in view, this function may take a few extra milliseconds to
* return.
*
* @remark __EGL:__ The context of the specified window must be current on the
* calling thread.
*
@ -6157,7 +6187,7 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
* @sa @ref glfwSwapInterval
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -6424,7 +6454,7 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
*
* @remark @macos This function currently always returns `GLFW_TRUE`, as the
* @remark __macOS:__ This function currently always returns `GLFW_TRUE`, as the
* `VK_MVK_macos_surface` and `VK_EXT_metal_surface` extensions do not provide
* a `vkGetPhysicalDevice*PresentationSupport` type function.
*
@ -6482,15 +6512,15 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys
* @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
* eliminate almost all occurrences of these errors.
*
* @remark @macos GLFW prefers the `VK_EXT_metal_surface` extension, with the
* @remark __macOS:__ GLFW prefers the `VK_EXT_metal_surface` extension, with the
* `VK_MVK_macos_surface` extension as a fallback. The name of the selected
* extension, if any, is included in the array returned by @ref
* glfwGetRequiredInstanceExtensions.
*
* @remark @macos This function creates and sets a `CAMetalLayer` instance for
* @remark __macOS:__ This function creates and sets a `CAMetalLayer` instance for
* the window content view, which is required for MoltenVK to function.
*
* @remark @x11 By default GLFW prefers the `VK_KHR_xcb_surface` extension,
* @remark __X11:__ By default GLFW prefers the `VK_KHR_xcb_surface` extension,
* with the `VK_KHR_xlib_surface` extension as a fallback. You can make
* `VK_KHR_xlib_surface` the preferred extension by setting the
* [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init

View file

@ -1,5 +1,5 @@
/*************************************************************************
* GLFW 3.4 - www.glfw.org
* GLFW 3.5 - www.glfw.org
* A library for OpenGL, window and input
*------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard
@ -478,6 +478,29 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
* @ingroup native
*/
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
/*! @brief Retrieves the `GLXFBConfig` of the specified window's `GLXWindow`.
*
* @param[in] window The window whose `GLXWindow` to query.
* @param[out] config The `GLXFBConfig` of the window `GLXWindow`, if available.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
*
* @remark `GLXFBConfig` is an opaque type. Unlike other GLFW functions, the
* @p config out parameter is not cleared on error, as core GLX does not define
* any invalid value.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.5
*
* @ingroup native
*/
GLFWAPI int glfwGetGLXFBConfig(GLFWwindow* window, GLXFBConfig* config);
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
@ -586,6 +609,29 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
* @ingroup native
*/
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
/*! @brief Retrieves the `EGLConfig` of the specified window's `EGLSurface`.
*
* @param[in] window The window whose `EGLSurface` to query.
* @param[out] config The `EGLConfig` of the window `EGLSurface`, if available.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @remark `EGLConfig` is an opaque type. Unlike other GLFW functions, the @p
* config out parameter is not cleared on error, as core EGL does not define
* any invalid value.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.5.
*
* @ingroup native
*/
GLFWAPI int glfwGetEGLConfig(GLFWwindow* window, EGLConfig* config);
#endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)

View file

@ -10,7 +10,7 @@ add_library(glfw ${GLFW_LIBRARY_TYPE}
# The time, thread and module code is shared between all backends on a given OS,
# including the null backend, which still needs those bits to be functional
if (APPLE)
target_sources(glfw PRIVATE cocoa_time.h cocoa_time.c posix_thread.h
target_sources(glfw PRIVATE macos_time.h macos_time.c posix_thread.h
posix_module.c posix_thread.c)
elseif (WIN32)
target_sources(glfw PRIVATE win32_time.h win32_thread.h win32_module.c
@ -30,6 +30,7 @@ add_custom_target(update_mappings
set_target_properties(update_mappings PROPERTIES FOLDER "GLFW3")
if (GLFW_BUILD_COCOA)
enable_language(OBJC)
target_compile_definitions(glfw PRIVATE _GLFW_COCOA)
target_sources(glfw PRIVATE cocoa_platform.h cocoa_joystick.h cocoa_init.m
cocoa_joystick.m cocoa_monitor.m cocoa_window.m
@ -45,15 +46,15 @@ endif()
if (GLFW_BUILD_X11)
target_compile_definitions(glfw PRIVATE _GLFW_X11)
target_sources(glfw PRIVATE x11_platform.h xkb_unicode.h x11_init.c
target_sources(glfw PRIVATE x11_platform.h x11_init.c
x11_monitor.c x11_window.c xkb_unicode.c
glx_context.c)
endif()
if (GLFW_BUILD_WAYLAND)
target_compile_definitions(glfw PRIVATE _GLFW_WAYLAND)
target_sources(glfw PRIVATE wl_platform.h xkb_unicode.h wl_init.c
wl_monitor.c wl_window.c xkb_unicode.c)
target_sources(glfw PRIVATE wl_platform.h wl_init.c
wl_monitor.c wl_window.c)
endif()
if (GLFW_BUILD_X11 OR GLFW_BUILD_WAYLAND)
@ -137,13 +138,6 @@ target_include_directories(glfw PRIVATE
"${GLFW_BINARY_DIR}/src")
target_link_libraries(glfw PRIVATE Threads::Threads)
# Workaround for CMake not knowing about .m files before version 3.16
if (CMAKE_VERSION VERSION_LESS "3.16" AND APPLE)
set_source_files_properties(cocoa_init.m cocoa_joystick.m cocoa_monitor.m
cocoa_window.m nsgl_context.m PROPERTIES
LANGUAGE C)
endif()
if (GLFW_BUILD_WIN32)
list(APPEND glfw_PKG_LIBS "-lgdi32")
endif()
@ -151,10 +145,11 @@ endif()
if (GLFW_BUILD_COCOA)
target_link_libraries(glfw PRIVATE "-framework Cocoa"
"-framework IOKit"
"-framework CoreFoundation")
"-framework QuartzCore")
set(glfw_PKG_DEPS "")
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation")
list(APPEND glfw_PKG_LIBS "-framework Cocoa"
"-framework IOKit"
"-framework QuartzCore")
endif()
if (GLFW_BUILD_WAYLAND)
@ -239,6 +234,11 @@ if (UNIX AND NOT APPLE)
endif()
endif()
if (APPLE)
target_link_libraries(glfw PRIVATE "-framework CoreFoundation")
list(APPEND glfw_PKG_LIBS "-framework CoreFoundation")
endif()
if (WIN32)
if (GLFW_USE_HYBRID_HPG)
target_compile_definitions(glfw PRIVATE _GLFW_USE_HYBRID_HPG)
@ -260,24 +260,6 @@ if (GLFW_BUILD_WIN32)
target_compile_definitions(glfw PRIVATE UNICODE _UNICODE)
endif()
# HACK: When building on MinGW, WINVER and UNICODE need to be defined before
# the inclusion of stddef.h (by glfw3.h), which is itself included before
# win32_platform.h. We define them here until a saner solution can be found
# NOTE: MinGW-w64 and Visual C++ do /not/ need this hack.
if (MINGW)
target_compile_definitions(glfw PRIVATE WINVER=0x0501)
endif()
# Workaround for legacy MinGW not providing XInput and DirectInput
if (MINGW)
include(CheckIncludeFile)
check_include_file(dinput.h DINPUT_H_FOUND)
check_include_file(xinput.h XINPUT_H_FOUND)
if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND)
target_include_directories(glfw PRIVATE "${GLFW_SOURCE_DIR}/deps/mingw")
endif()
endif()
# Workaround for the MS CRT deprecating parts of the standard library
if (MSVC OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS)
@ -291,10 +273,6 @@ endif()
if (GLFW_BUILD_SHARED_LIBRARY)
if (WIN32)
if (MINGW)
# Remove the dependency on the shared version of libgcc
# NOTE: MinGW-w64 has the correct default but MinGW needs this
target_link_libraries(glfw PRIVATE "-static-libgcc")
# Remove the lib prefix on the DLL (but not the import library)
set_target_properties(glfw PROPERTIES PREFIX "")
@ -312,30 +290,34 @@ if (GLFW_BUILD_SHARED_LIBRARY)
if (MINGW)
# Enable link-time exploit mitigation features enabled by default on MSVC
include(CheckCCompilerFlag)
include(CMakePushCheckState)
# Compatibility with data execution prevention (DEP)
cmake_push_check_state()
set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat")
check_c_compiler_flag("" _GLFW_HAS_DEP)
if (_GLFW_HAS_DEP)
target_link_libraries(glfw PRIVATE "-Wl,--nxcompat")
endif()
cmake_pop_check_state()
# Compatibility with address space layout randomization (ASLR)
cmake_push_check_state()
set(CMAKE_REQUIRED_FLAGS "-Wl,--dynamicbase")
check_c_compiler_flag("" _GLFW_HAS_ASLR)
if (_GLFW_HAS_ASLR)
target_link_libraries(glfw PRIVATE "-Wl,--dynamicbase")
endif()
cmake_pop_check_state()
# Compatibility with 64-bit address space layout randomization (ASLR)
cmake_push_check_state()
set(CMAKE_REQUIRED_FLAGS "-Wl,--high-entropy-va")
check_c_compiler_flag("" _GLFW_HAS_64ASLR)
if (_GLFW_HAS_64ASLR)
target_link_libraries(glfw PRIVATE "-Wl,--high-entropy-va")
endif()
# Clear flags again to avoid breaking later tests
set(CMAKE_REQUIRED_FLAGS)
cmake_pop_check_state()
endif()
if (UNIX)
@ -344,12 +326,8 @@ if (GLFW_BUILD_SHARED_LIBRARY)
endif()
endif()
foreach(arg ${glfw_PKG_DEPS})
string(APPEND deps " ${arg}")
endforeach()
foreach(arg ${glfw_PKG_LIBS})
string(APPEND libs " ${arg}")
endforeach()
list(JOIN glfw_PKG_DEPS " " deps)
list(JOIN glfw_PKG_LIBS " " libs)
set(GLFW_PKG_CONFIG_REQUIRES_PRIVATE "${deps}" CACHE INTERNAL
"GLFW pkg-config Requires.private")

View file

@ -1,8 +1,7 @@
//========================================================================
// GLFW 3.4 macOS (modified for raylib) - www.glfw.org; www.raylib.com
// GLFW 3.5 Cocoa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@ -176,7 +175,7 @@ static void createMenuBar(void)
// Create key code translation tables
//
static void createKeyTablesCocoa(void)
static void createKeyTables(void)
{
memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes));
memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes));
@ -451,41 +450,6 @@ static GLFWbool initializeTIS(void)
@end // GLFWApplicationDelegate
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
void* _glfwLoadLocalVulkanLoaderCocoa(void)
{
CFBundleRef bundle = CFBundleGetMainBundle();
if (!bundle)
return NULL;
CFURLRef frameworksUrl = CFBundleCopyPrivateFrameworksURL(bundle);
if (!frameworksUrl)
return NULL;
CFURLRef loaderUrl = CFURLCreateCopyAppendingPathComponent(
kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false);
if (!loaderUrl)
{
CFRelease(frameworksUrl);
return NULL;
}
char path[PATH_MAX];
void* handle = NULL;
if (CFURLGetFileSystemRepresentation(loaderUrl, true, (UInt8*) path, sizeof(path) - 1))
handle = _glfwPlatformLoadModule(path);
CFRelease(loaderUrl);
CFRelease(frameworksUrl);
return handle;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
@ -619,7 +583,7 @@ int _glfwInitCocoa(void)
name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil];
createKeyTablesCocoa();
createKeyTables();
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
if (!_glfw.ns.eventSource)
@ -689,6 +653,8 @@ void _glfwTerminateCocoa(void)
_glfwTerminateEGL();
_glfwTerminateOSMesa();
memset(&_glfw.ns, 0, sizeof(_glfw.ns));
} // autoreleasepool
}

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Cocoa - www.glfw.org
// GLFW 3.5 Cocoa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Cocoa - www.glfw.org
// GLFW 3.5 Cocoa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>

View file

@ -1,9 +1,8 @@
//========================================================================
// GLFW 3.4 macOS (modified for raylib) - www.glfw.org; www.raylib.com
// GLFW 3.5 Cocoa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@ -33,6 +32,7 @@
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <assert.h>
#include <IOKit/graphics/IOGraphicsLib.h>
#include <ApplicationServices/ApplicationServices.h>
@ -137,7 +137,7 @@ static GLFWbool modeIsGood(CGDisplayModeRef mode)
if (flags & kDisplayModeStretchedFlag)
return GLFW_FALSE;
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
#if MAC_OS_X_VERSION_MAX_ALLOWED == 101100
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) &&
CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
@ -164,7 +164,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
if (result.refreshRate == 0)
result.refreshRate = (int) round(fallbackRefreshRate);
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
#if MAC_OS_X_VERSION_MAX_ALLOWED == 101100
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0)
{
@ -180,7 +180,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
result.blueBits = 8;
}
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
#if MAC_OS_X_VERSION_MAX_ALLOWED == 101100
CFRelease(format);
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
return result;
@ -628,7 +628,6 @@ void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay);
if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
@ -637,6 +636,9 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
return kCGNullDirectDisplay;
}
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
return monitor->ns.displayID;
}

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 macOS - www.glfw.org
// GLFW 3.5 Cocoa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
//
@ -291,8 +291,6 @@ void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor);
float _glfwTransformYCocoa(float y);
void* _glfwLoadLocalVulkanLoaderCocoa(void);
GLFWbool _glfwInitNSGL(void);
void _glfwTerminateNSGL(void);
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 macOS - www.glfw.org
// GLFW 3.5 Cocoa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
//
@ -28,8 +28,11 @@
#if defined(_GLFW_COCOA)
#import <QuartzCore/CAMetalLayer.h>
#include <float.h>
#include <string.h>
#include <assert.h>
// HACK: This enum value is missing from framework headers on OS X 10.11 despite
// having been (according to documentation) added in Mac OS X 10.7
@ -111,7 +114,7 @@ static void updateCursorMode(_GLFWwindow* window)
// Make the specified window and its video mode active on its monitor
//
static void acquireMonitorCocoa(_GLFWwindow* window)
static void acquireMonitor(_GLFWwindow* window)
{
_glfwSetVideoModeCocoa(window->monitor, &window->videoMode);
const CGRect bounds = CGDisplayBounds(window->monitor->ns.displayID);
@ -127,7 +130,7 @@ static void acquireMonitorCocoa(_GLFWwindow* window)
// Remove the window and restore the original video mode
//
static void releaseMonitorCocoa(_GLFWwindow* window)
static void releaseMonitor(_GLFWwindow* window)
{
if (window->monitor->window != window)
return;
@ -158,7 +161,7 @@ static int translateFlags(NSUInteger flags)
// Translates a macOS keycode to a GLFW keycode
//
static int translateKeyCocoa(unsigned int key)
static int translateKey(unsigned int key)
{
if (key >= sizeof(_glfw.ns.keycodes) / sizeof(_glfw.ns.keycodes[0]))
return GLFW_KEY_UNKNOWN;
@ -277,7 +280,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)windowDidMiniaturize:(NSNotification *)notification
{
if (window->monitor)
releaseMonitorCocoa(window);
releaseMonitor(window);
_glfwInputWindowIconify(window, GLFW_TRUE);
}
@ -285,7 +288,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)windowDidDeminiaturize:(NSNotification *)notification
{
if (window->monitor)
acquireMonitorCocoa(window);
acquireMonitor(window);
_glfwInputWindowIconify(window, GLFW_FALSE);
}
@ -309,7 +312,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)windowDidChangeOcclusionState:(NSNotification* )notification
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
if ([window->ns.object respondsToSelector:@selector(occlusionState)])
{
if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible)
@ -317,7 +319,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
else
window->ns.occluded = GLFW_TRUE;
}
#endif
}
@end
@ -561,7 +562,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)keyDown:(NSEvent *)event
{
const int key = translateKeyCocoa([event keyCode]);
const int key = translateKey([event keyCode]);
const int mods = translateFlags([event modifierFlags]);
_glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);
@ -574,7 +575,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
int action;
const unsigned int modifierFlags =
[event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
const int key = translateKeyCocoa([event keyCode]);
const int key = translateKey([event keyCode]);
const int mods = translateFlags(modifierFlags);
const NSUInteger keyFlag = translateKeyToModifierFlag(key);
@ -593,11 +594,39 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)keyUp:(NSEvent *)event
{
const int key = translateKeyCocoa([event keyCode]);
const int key = translateKey([event keyCode]);
const int mods = translateFlags([event modifierFlags]);
_glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods);
}
- (BOOL)performKeyEquivalent:(NSEvent *)event
{
// HACK: Some key combinations are consumed before reaching keyDown:
// so we claim those events and emit them here
const int key = translateKey([event keyCode]);
const int mods = translateFlags([event modifierFlags]);
if (mods & GLFW_MOD_CONTROL)
{
if (key == GLFW_KEY_TAB || key == GLFW_KEY_ESCAPE)
{
_glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);
return YES;
}
}
if (mods & GLFW_MOD_SUPER)
{
if (key == GLFW_KEY_PERIOD)
{
_glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);
return YES;
}
}
return [super performKeyEquivalent:event];
}
- (void)scrollWheel:(NSEvent *)event
{
double deltaX = [event scrollingDeltaX];
@ -883,7 +912,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
[window->ns.object setContentView:window->ns.view];
[window->ns.object makeFirstResponder:window->ns.view];
[window->ns.object setTitle:@(wndconfig->title)];
[window->ns.object setTitle:@(window->title)];
[window->ns.object setDelegate:window->ns.delegate];
[window->ns.object setAcceptsMouseMovedEvents:YES];
[window->ns.object setRestorable:NO];
@ -966,7 +995,7 @@ GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window,
{
_glfwShowWindowCocoa(window);
_glfwFocusWindowCocoa(window);
acquireMonitorCocoa(window);
acquireMonitor(window);
if (wndconfig->centerCursor)
_glfwCenterCursorInContentArea(window);
@ -996,7 +1025,7 @@ void _glfwDestroyWindowCocoa(_GLFWwindow* window)
[window->ns.object orderOut:nil];
if (window->monitor)
releaseMonitorCocoa(window);
releaseMonitor(window);
if (window->context.destroy)
window->context.destroy(window);
@ -1083,7 +1112,7 @@ void _glfwSetWindowSizeCocoa(_GLFWwindow* window, int width, int height)
if (window->monitor)
{
if (window->monitor->window == window)
acquireMonitorCocoa(window);
acquireMonitor(window);
}
else
{
@ -1252,7 +1281,7 @@ void _glfwSetWindowMonitorCocoa(_GLFWwindow* window,
if (monitor)
{
if (monitor->window == window)
acquireMonitorCocoa(window);
acquireMonitor(window);
}
else
{
@ -1270,7 +1299,7 @@ void _glfwSetWindowMonitorCocoa(_GLFWwindow* window,
}
if (window->monitor)
releaseMonitorCocoa(window);
releaseMonitor(window);
_glfwInputWindowMonitor(window, monitor);
@ -1308,7 +1337,7 @@ void _glfwSetWindowMonitorCocoa(_GLFWwindow* window,
[window->ns.object setLevel:NSMainMenuWindowLevel + 1];
[window->ns.object setHasShadow:NO];
acquireMonitorCocoa(window);
acquireMonitor(window);
}
else
{
@ -1949,19 +1978,8 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance,
{
@autoreleasepool {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
// HACK: Dynamically load Core Animation to avoid adding an extra
// dependency for the majority who don't use MoltenVK
NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/QuartzCore.framework"];
if (!bundle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to find QuartzCore.framework");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
// NOTE: Create the layer here as makeBackingLayer should not return nil
window->ns.layer = [[bundle classNamed:@"CAMetalLayer"] layer];
window->ns.layer = [CAMetalLayer layer];
if (!window->ns.layer)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@ -2026,9 +2044,6 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance,
}
return err;
#else
return VK_ERROR_EXTENSION_NOT_PRESENT;
#endif
} // autoreleasepool
}
@ -2040,7 +2055,6 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance,
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(nil);
if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
@ -2050,12 +2064,14 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle)
return nil;
}
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
return window->ns.object;
}
GLFWAPI id glfwGetCocoaView(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(nil);
if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
@ -2065,6 +2081,9 @@ GLFWAPI id glfwGetCocoaView(GLFWwindow* handle)
return nil;
}
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
return window->ns.view;
}

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
@ -195,7 +195,7 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
{
current = alternatives + i;
if (desired->stereo > 0 && current->stereo == 0)
if (desired->stereo && !current->stereo)
{
// Stereo is a hard constraint
continue;
@ -359,7 +359,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
window->context.source = ctxconfig->source;
window->context.client = GLFW_OPENGL_API;
previous = (_GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
glfwMakeContextCurrent((GLFWwindow*) window);
if (_glfwPlatformGetTls(&_glfw.contextSlot) != window)
return GLFW_FALSE;
@ -368,7 +368,12 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
window->context.getProcAddress("glGetIntegerv");
window->context.GetString = (PFNGLGETSTRINGPROC)
window->context.getProcAddress("glGetString");
if (!window->context.GetIntegerv || !window->context.GetString)
window->context.Flush = (PFNGLFLUSHPROC)
window->context.getProcAddress("glFlush");
if (!window->context.GetIntegerv ||
!window->context.GetString ||
!window->context.Flush)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
glfwMakeContextCurrent((GLFWwindow*) previous);
@ -615,12 +620,12 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow *) handle;
_GLFWwindow* previous;
_GLFW_REQUIRE_INIT();
previous = (_GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFWwindow* previous;
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
if (window && window->context.client == GLFW_NO_API)
{
@ -642,16 +647,16 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return (GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
return _glfwPlatformGetTls(&_glfw.contextSlot);
}
GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow *) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT,
@ -668,7 +673,7 @@ GLFWAPI void glfwSwapInterval(int interval)
_GLFW_REQUIRE_INIT();
window = (_GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
@ -686,7 +691,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
window = (_GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
@ -752,7 +757,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
window = (_GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
@ -762,3 +767,4 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
return window->context.getProcAddress(procname);
}

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 EGL - www.glfw.org
// GLFW 3.5 EGL - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
@ -92,7 +92,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
EGLConfig* nativeConfigs;
_GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest;
int i, nativeCount, usableCount, apiBit;
int i, nativeCount, usableCount, apiBit, surfaceTypeBit;
GLFWbool wrongApiAvailable = GLFW_FALSE;
if (ctxconfig->client == GLFW_OPENGL_ES_API)
@ -105,6 +105,11 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
else
apiBit = EGL_OPENGL_BIT;
if (_glfw.egl.platform == EGL_PLATFORM_SURFACELESS_MESA)
surfaceTypeBit = EGL_PBUFFER_BIT;
else
surfaceTypeBit = EGL_WINDOW_BIT;
if (fbconfig->stereo)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported");
@ -118,10 +123,10 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
return GLFW_FALSE;
}
nativeConfigs = (EGLConfig *)_glfw_calloc(nativeCount, sizeof(EGLConfig));
nativeConfigs = _glfw_calloc(nativeCount, sizeof(EGLConfig));
eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
usableConfigs = (_GLFWfbconfig *)_glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0;
for (i = 0; i < nativeCount; i++)
@ -133,8 +138,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
continue;
// Only consider window EGLConfigs
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & surfaceTypeBit))
continue;
#if defined(_GLFW_X11)
@ -250,6 +254,12 @@ static void makeContextCurrentEGL(_GLFWwindow* window)
getEGLErrorString(eglGetError()));
return;
}
#if defined(_GLFW_WAYLAND)
// NOTE: Disable EGL vsync so we can substitute our own that includes a timeout
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
eglSwapInterval(_glfw.egl.display, 0);
#endif // _GLFW_WAYLAND
}
else
{
@ -283,6 +293,15 @@ static void swapBuffersEGL(_GLFWwindow* window)
// NOTE: Swapping buffers on a hidden window on Wayland makes it visible
if (!window->wl.visible)
return;
// NOTE: We wait for a frame manually so we can add a timeout,
// as the EGL implementation will wait indefinitely
if (window->wl.egl.interval > 0)
{
window->context.Flush();
if (!_glfwWaitForEGLFrameWayland(window))
return;
}
}
#endif
@ -291,6 +310,16 @@ static void swapBuffersEGL(_GLFWwindow* window)
static void swapIntervalEGL(int interval)
{
#if defined(_GLFW_WAYLAND)
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
window->wl.egl.interval = interval;
return;
}
#endif
eglSwapInterval(_glfw.egl.display, interval);
}
@ -308,18 +337,19 @@ static int extensionSupportedEGL(const char* extension)
static GLFWglproc getProcAddressEGL(const char* procname)
{
_GLFWwindow* window = (_GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
const GLFWglproc proc = (GLFWglproc) eglGetProcAddress(procname);
if (proc)
return proc;
if (window->context.egl.client)
if (!_glfw.egl.KHR_get_all_proc_addresses)
{
GLFWglproc proc = (GLFWglproc)
_glfwPlatformGetModuleSymbol(window->context.egl.client, procname);
if (proc)
return proc;
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
return _glfwPlatformGetModuleSymbol(window->context.egl.client, procname);
}
return eglGetProcAddress(procname);
return NULL;
}
static void destroyContextEGL(_GLFWwindow* window)
@ -329,11 +359,8 @@ static void destroyContextEGL(_GLFWwindow* window)
if (_glfw.platform.platformID != GLFW_PLATFORM_X11 ||
window->context.client != GLFW_OPENGL_API)
{
if (window->context.egl.client)
{
_glfwPlatformFreeModule(window->context.egl.client);
window->context.egl.client = NULL;
}
_glfwPlatformFreeModule(window->context.egl.client);
window->context.egl.client = NULL;
}
if (window->context.egl.surface)
@ -354,8 +381,6 @@ static void destroyContextEGL(_GLFWwindow* window)
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize EGL
//
GLFWbool _glfwInitEGL(void)
{
int i;
@ -365,10 +390,10 @@ GLFWbool _glfwInitEGL(void)
{
#if defined(_GLFW_EGL_LIBRARY)
_GLFW_EGL_LIBRARY,
#elif defined(_GLFW_WIN32)
#elif defined(_WIN32)
"libEGL.dll",
"EGL.dll",
#elif defined(_GLFW_COCOA)
#elif defined(__APPLE__)
"libEGL.dylib",
#elif defined(__CYGWIN__)
"libEGL-1.so",
@ -420,6 +445,8 @@ GLFWbool _glfwInitEGL(void)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroyContext");
_glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateWindowSurface");
_glfw.egl.CreatePbufferSurface = (PFN_eglCreatePbufferSurface)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreatePbufferSurface");
_glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglMakeCurrent");
_glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
@ -442,6 +469,7 @@ GLFWbool _glfwInitEGL(void)
!_glfw.egl.DestroySurface ||
!_glfw.egl.DestroyContext ||
!_glfw.egl.CreateWindowSurface ||
!_glfw.egl.CreatePbufferSurface ||
!_glfw.egl.MakeCurrent ||
!_glfw.egl.SwapBuffers ||
!_glfw.egl.SwapInterval ||
@ -477,6 +505,8 @@ GLFWbool _glfwInitEGL(void)
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_vulkan", extensions);
_glfw.egl.ANGLE_platform_angle_metal =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_metal", extensions);
_glfw.egl.MESA_platform_surfaceless =
_glfwStringInExtensionString("EGL_MESA_platform_surfaceless", extensions);
}
if (_glfw.egl.EXT_platform_base)
@ -536,8 +566,6 @@ GLFWbool _glfwInitEGL(void)
return GLFW_TRUE;
}
// Terminate EGL
//
void _glfwTerminateEGL(void)
{
if (_glfw.egl.display)
@ -546,7 +574,8 @@ void _glfwTerminateEGL(void)
_glfw.egl.display = EGL_NO_DISPLAY;
}
if (_glfw.egl.handle)
// Free modules only after all wayland termination functions are called
if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)
{
_glfwPlatformFreeModule(_glfw.egl.handle);
_glfw.egl.handle = NULL;
@ -560,8 +589,6 @@ void _glfwTerminateEGL(void)
attribs[index++] = v; \
}
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
@ -648,7 +675,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (ctxconfig->noerror)
{
if (_glfw.egl.KHR_create_context_no_error)
SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, true);
}
if (mask)
@ -708,20 +735,36 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
}
if (_glfw.egl.platform == EGL_PLATFORM_SURFACELESS_MESA)
{
int width, height;
_glfw.platform.getFramebufferSize(window, &width, &height);
SET_ATTRIB(EGL_WIDTH, width);
SET_ATTRIB(EGL_HEIGHT, height);
}
SET_ATTRIB(EGL_NONE, EGL_NONE);
native = _glfw.platform.getEGLNativeWindow(window);
// HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT
// despite reporting EGL_EXT_platform_base
if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE)
if (!_glfw.egl.platform || _glfw.egl.platform == EGL_PLATFORM_ANGLE_ANGLE)
{
// HACK: Also use non-platform function for ANGLE, as it does not
// implement eglCreatePlatformWindowSurfaceEXT despite reporting
// support for EGL_EXT_platform_base
window->context.egl.surface =
eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs);
eglCreateWindowSurface(_glfw.egl.display, config, native, attribs);
}
else if (_glfw.egl.platform == EGL_PLATFORM_SURFACELESS_MESA)
{
// HACK: Use a pbuffer surface as the default framebuffer
window->context.egl.surface =
eglCreatePbufferSurface(_glfw.egl.display, config, attribs);
}
else
{
window->context.egl.surface =
eglCreateWindowSurface(_glfw.egl.display, config, native, attribs);
eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs);
}
if (window->context.egl.surface == EGL_NO_SURFACE)
@ -743,10 +786,10 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{
#if defined(_GLFW_GLESV1_LIBRARY)
_GLFW_GLESV1_LIBRARY,
#elif defined(_GLFW_WIN32)
#elif defined(_WIN32)
"GLESv1_CM.dll",
"libGLES_CM.dll",
#elif defined(_GLFW_COCOA)
#elif defined(__APPLE__)
"libGLESv1_CM.dylib",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGLESv1_CM.so",
@ -760,10 +803,10 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{
#if defined(_GLFW_GLESV2_LIBRARY)
_GLFW_GLESV2_LIBRARY,
#elif defined(_GLFW_WIN32)
#elif defined(_WIN32)
"GLESv2.dll",
"libGLESv2.dll",
#elif defined(_GLFW_COCOA)
#elif defined(__APPLE__)
"libGLESv2.dylib",
#elif defined(__CYGWIN__)
"libGLESv2-2.so",
@ -778,8 +821,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{
#if defined(_GLFW_OPENGL_LIBRARY)
_GLFW_OPENGL_LIBRARY,
#elif defined(_GLFW_WIN32)
#elif defined(_GLFW_COCOA)
#elif defined(_WIN32)
#elif defined(__APPLE__)
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGL.so",
#else
@ -883,13 +926,19 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void)
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow *) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_EGL_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_CONTEXT;
if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND ||
window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_CONTEXT;
}
}
return window->context.egl.handle;
@ -897,14 +946,43 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow *) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_EGL_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_SURFACE;
if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND ||
window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_SURFACE;
}
}
return window->context.egl.surface;
}
GLFWAPI int glfwGetEGLConfig(GLFWwindow* handle, EGLConfig* config)
{
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(config != NULL);
if (window->context.source != GLFW_EGL_CONTEXT_API)
{
if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND ||
window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
}
*config = window->context.egl.config;
return GLFW_TRUE;
}

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 GLX - www.glfw.org
// GLFW 3.5 GLX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
@ -119,9 +119,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE);
u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS);
if (getGLXFBConfigAttrib(n, GLX_STEREO))
u->stereo = GLFW_TRUE;
u->stereo = getGLXFBConfigAttrib(n, GLX_STEREO);
if (_glfw.glx.ARB_multisample)
u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES);
@ -253,8 +251,6 @@ static void destroyContextGLX(_GLFWwindow* window)
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize GLX
//
GLFWbool _glfwInitGLX(void)
{
const char* sonames[] =
@ -369,7 +365,7 @@ GLFWbool _glfwInitGLX(void)
getProcAddressGLX("glXSwapIntervalEXT");
if (_glfw.glx.SwapIntervalEXT)
_glfw.glx.EXT_swap_control = GLFW_TRUE;
_glfw.glx.EXT_swap_control = true;
}
if (extensionSupportedGLX("GLX_SGI_swap_control"))
@ -378,7 +374,7 @@ GLFWbool _glfwInitGLX(void)
getProcAddressGLX("glXSwapIntervalSGI");
if (_glfw.glx.SwapIntervalSGI)
_glfw.glx.SGI_swap_control = GLFW_TRUE;
_glfw.glx.SGI_swap_control = true;
}
if (extensionSupportedGLX("GLX_MESA_swap_control"))
@ -387,17 +383,17 @@ GLFWbool _glfwInitGLX(void)
getProcAddressGLX("glXSwapIntervalMESA");
if (_glfw.glx.SwapIntervalMESA)
_glfw.glx.MESA_swap_control = GLFW_TRUE;
_glfw.glx.MESA_swap_control = true;
}
if (extensionSupportedGLX("GLX_ARB_multisample"))
_glfw.glx.ARB_multisample = GLFW_TRUE;
_glfw.glx.ARB_multisample = true;
if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))
_glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE;
_glfw.glx.ARB_framebuffer_sRGB = true;
if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))
_glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;
_glfw.glx.EXT_framebuffer_sRGB = true;
if (extensionSupportedGLX("GLX_ARB_create_context"))
{
@ -405,39 +401,34 @@ GLFWbool _glfwInitGLX(void)
getProcAddressGLX("glXCreateContextAttribsARB");
if (_glfw.glx.CreateContextAttribsARB)
_glfw.glx.ARB_create_context = GLFW_TRUE;
_glfw.glx.ARB_create_context = true;
}
if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))
_glfw.glx.ARB_create_context_robustness = GLFW_TRUE;
_glfw.glx.ARB_create_context_robustness = true;
if (extensionSupportedGLX("GLX_ARB_create_context_profile"))
_glfw.glx.ARB_create_context_profile = GLFW_TRUE;
_glfw.glx.ARB_create_context_profile = true;
if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
_glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE;
_glfw.glx.EXT_create_context_es2_profile = true;
if (extensionSupportedGLX("GLX_ARB_create_context_no_error"))
_glfw.glx.ARB_create_context_no_error = GLFW_TRUE;
_glfw.glx.ARB_create_context_no_error = true;
if (extensionSupportedGLX("GLX_ARB_context_flush_control"))
_glfw.glx.ARB_context_flush_control = GLFW_TRUE;
_glfw.glx.ARB_context_flush_control = true;
return GLFW_TRUE;
}
// Terminate GLX
//
void _glfwTerminateGLX(void)
{
// NOTE: This function must not call any X11 functions, as it is called
// after XCloseDisplay (see _glfwTerminateX11 for details)
if (_glfw.glx.handle)
{
_glfwPlatformFreeModule(_glfw.glx.handle);
_glfw.glx.handle = NULL;
}
_glfwPlatformFreeModule(_glfw.glx.handle);
_glfw.glx.handle = NULL;
}
#define SET_ATTRIB(a, v) \
@ -447,8 +438,6 @@ void _glfwTerminateGLX(void)
attribs[index++] = v; \
}
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
@ -626,6 +615,8 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
return GLFW_FALSE;
}
window->context.glx.fbconfig = native;
window->context.makeCurrent = makeContextCurrentGLX;
window->context.swapBuffers = swapBuffersGLX;
window->context.swapInterval = swapIntervalGLX;
@ -677,7 +668,6 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
@ -686,6 +676,9 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
return NULL;
}
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
@ -697,7 +690,6 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
@ -706,6 +698,9 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
return None;
}
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
@ -715,5 +710,29 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
return window->context.glx.window;
}
GLFWAPI int glfwGetGLXFBConfig(GLFWwindow* handle, GLXFBConfig* config)
{
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized");
return GLFW_FALSE;
}
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(config != NULL);
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
*config = window->context.glx.fbconfig;
return GLFW_TRUE;
}
#endif // _GLFW_X11

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
@ -49,18 +49,18 @@ static GLFWerrorfun _glfwErrorCallback;
static GLFWallocator _glfwInitAllocator;
static _GLFWinitconfig _glfwInitHints =
{
.hatButtons = GLFW_TRUE,
.hatButtons = true,
.angleType = GLFW_ANGLE_PLATFORM_TYPE_NONE,
.platformID = GLFW_ANY_PLATFORM,
.vulkanLoader = NULL,
.ns =
{
.menubar = GLFW_TRUE,
.chdir = GLFW_TRUE
.menubar = true,
.chdir = true
},
.x11 =
{
.xcbVulkanSurface = GLFW_TRUE,
.xcbVulkanSurface = true,
},
.wl =
{

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
@ -333,10 +333,8 @@ void _glfwInputChar(_GLFWwindow* window, uint32_t codepoint, int mods, GLFWbool
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
{
assert(window != NULL);
assert(xoffset > -FLT_MAX);
assert(xoffset < FLT_MAX);
assert(yoffset > -FLT_MAX);
assert(yoffset < FLT_MAX);
assert(isfinite(xoffset));
assert(isfinite(yoffset));
if (window->callbacks.scroll)
window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset);
@ -348,20 +346,22 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
{
assert(window != NULL);
assert(button >= 0);
assert(button <= GLFW_MOUSE_BUTTON_LAST);
assert(action == GLFW_PRESS || action == GLFW_RELEASE);
assert(mods == (mods & GLFW_MOD_MASK));
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
if (button < 0 || (!window->disableMouseButtonLimit && button > GLFW_MOUSE_BUTTON_LAST))
return;
if (!window->lockKeyMods)
mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK);
if (action == GLFW_RELEASE && window->stickyMouseButtons)
window->mouseButtons[button] = _GLFW_STICK;
else
window->mouseButtons[button] = (char) action;
if (button <= GLFW_MOUSE_BUTTON_LAST)
{
if (action == GLFW_RELEASE && window->stickyMouseButtons)
window->mouseButtons[button] = _GLFW_STICK;
else
window->mouseButtons[button] = (char) action;
}
if (window->callbacks.mouseButton)
window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods);
@ -373,10 +373,8 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
{
assert(window != NULL);
assert(xpos > -FLT_MAX);
assert(xpos < FLT_MAX);
assert(ypos > -FLT_MAX);
assert(ypos < FLT_MAX);
assert(isfinite(xpos));
assert(isfinite(ypos));
if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos)
return;
@ -434,6 +432,7 @@ void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value)
assert(js != NULL);
assert(axis >= 0);
assert(axis < js->axisCount);
assert(isfinite(value));
js->axes[axis] = value;
}
@ -559,11 +558,11 @@ void _glfwCenterCursorInContentArea(_GLFWwindow* window)
GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(0);
switch (mode)
{
case GLFW_CURSOR:
@ -576,6 +575,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
return window->lockKeyMods;
case GLFW_RAW_MOUSE_MOTION:
return window->rawMouseMotion;
case GLFW_UNLIMITED_MOUSE_BUTTONS:
return window->disableMouseButtonLimit;
}
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
@ -584,11 +585,11 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
switch (mode)
{
case GLFW_CURSOR:
@ -683,6 +684,12 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
_glfw.platform.setRawMouseMotion(window, value);
return;
}
case GLFW_UNLIMITED_MOUSE_BUTTONS:
{
window->disableMouseButtonLimit = value ? GLFW_TRUE : GLFW_FALSE;
return;
}
}
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
@ -734,11 +741,11 @@ GLFWAPI int glfwGetKeyScancode(int key)
GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
{
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
@ -757,11 +764,11 @@ GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
{
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
if (button < GLFW_MOUSE_BUTTON_1 || button > GLFW_MOUSE_BUTTON_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid mouse button %i", button);
@ -780,9 +787,6 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (xpos)
*xpos = 0;
if (ypos)
@ -790,6 +794,9 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->cursorMode == GLFW_CURSOR_DISABLED)
{
if (xpos)
@ -803,13 +810,12 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (xpos != xpos || xpos < -DBL_MAX || xpos > DBL_MAX ||
ypos != ypos || ypos < -DBL_MAX || ypos > DBL_MAX)
if (!isfinite(xpos) || !isfinite(ypos))
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid cursor position %f %f",
@ -897,10 +903,10 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
{
_GLFWcursor* cursor = (_GLFWcursor*) handle;
_GLFW_REQUIRE_INIT();
_GLFWcursor* cursor = (_GLFWcursor*) handle;
if (cursor == NULL)
return;
@ -932,12 +938,12 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) windowHandle;
_GLFWcursor* cursor = (_GLFWcursor*) cursorHandle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
window->cursor = cursor;
_glfw.platform.setCursor(window, cursor);
@ -945,30 +951,33 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWkeyfun, window->callbacks.key, cbfun);
return cbfun;
}
GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWcharfun, window->callbacks.character, cbfun);
return cbfun;
}
GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWcharmodsfun, window->callbacks.charmods, cbfun);
return cbfun;
}
@ -976,10 +985,11 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmods
GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
GLFWmousebuttonfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWmousebuttonfun, window->callbacks.mouseButton, cbfun);
return cbfun;
}
@ -987,10 +997,11 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle,
GLFWcursorposfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWcursorposfun, window->callbacks.cursorPos, cbfun);
return cbfun;
}
@ -998,10 +1009,11 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle,
GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle,
GLFWcursorenterfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWcursorenterfun, window->callbacks.cursorEnter, cbfun);
return cbfun;
}
@ -1009,20 +1021,22 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle,
GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
GLFWscrollfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWscrollfun, window->callbacks.scroll, cbfun);
return cbfun;
}
GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWdropfun, window->callbacks.drop, cbfun);
return cbfun;
}
@ -1481,7 +1495,7 @@ GLFWAPI void glfwSetTime(double time)
{
_GLFW_REQUIRE_INIT();
if (time != time || time < 0.0 || time > 18446744073.0)
if (!isfinite(time) || time < 0.0 || time > 18446744073.0)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", time);
return;

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
@ -48,6 +48,8 @@
#define GLFW_INCLUDE_NONE
#include "../include/GLFW/glfw3.h"
#include <stdbool.h>
#define _GLFW_INSERT_FIRST 0
#define _GLFW_INSERT_LAST 1
@ -107,6 +109,7 @@ typedef void (APIENTRY * PFNGLCLEARPROC)(GLbitfield);
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum);
typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*);
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
typedef void (APIENTRY * PFNGLFLUSHPROC)(void);
#define EGL_SUCCESS 0x3000
#define EGL_NOT_INITIALIZED 0x3001
@ -150,6 +153,9 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
#define EGL_NO_DISPLAY ((EGLDisplay) 0)
#define EGL_NO_CONTEXT ((EGLContext) 0)
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0)
#define EGL_PBUFFER_BIT 0x0001
#define EGL_WIDTH 0x3057
#define EGL_HEIGHT 0x3056
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
@ -181,6 +187,7 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
#define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f
#define EGL_PLATFORM_SURFACELESS_MESA 0x31dd
typedef int EGLint;
typedef unsigned int EGLBoolean;
@ -205,6 +212,7 @@ typedef EGLContext (APIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLCon
typedef EGLBoolean (APIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface);
typedef EGLBoolean (APIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext);
typedef EGLSurface (APIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);
typedef EGLSurface (APIENTRY * PFN_eglCreatePbufferSurface)(EGLDisplay,EGLContext,const EGLint*);
typedef EGLBoolean (APIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);
typedef EGLBoolean (APIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);
typedef EGLBoolean (APIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);
@ -221,6 +229,7 @@ typedef GLFWglproc (APIENTRY * PFN_eglGetProcAddress)(const char*);
#define eglDestroySurface _glfw.egl.DestroySurface
#define eglDestroyContext _glfw.egl.DestroyContext
#define eglCreateWindowSurface _glfw.egl.CreateWindowSurface
#define eglCreatePbufferSurface _glfw.egl.CreatePbufferSurface
#define eglMakeCurrent _glfw.egl.MakeCurrent
#define eglSwapBuffers _glfw.egl.SwapBuffers
#define eglSwapInterval _glfw.egl.SwapInterval
@ -277,6 +286,7 @@ typedef enum VkStructureType
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000,
VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000,
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
} VkStructureType;
@ -365,16 +375,16 @@ struct _GLFWerror
//
struct _GLFWinitconfig
{
GLFWbool hatButtons;
bool hatButtons;
int angleType;
int platformID;
PFN_vkGetInstanceProcAddr vulkanLoader;
struct {
GLFWbool menubar;
GLFWbool chdir;
bool menubar;
bool chdir;
} ns;
struct {
GLFWbool xcbVulkanSurface;
bool xcbVulkanSurface;
} x11;
struct {
int libdecorMode;
@ -393,19 +403,18 @@ struct _GLFWwndconfig
int ypos;
int width;
int height;
const char* title;
GLFWbool resizable;
GLFWbool visible;
GLFWbool decorated;
GLFWbool focused;
GLFWbool autoIconify;
GLFWbool floating;
GLFWbool maximized;
GLFWbool centerCursor;
GLFWbool focusOnShow;
GLFWbool mousePassthrough;
GLFWbool scaleToMonitor;
GLFWbool scaleFramebuffer;
bool resizable;
bool visible;
bool decorated;
bool focused;
bool autoIconify;
bool floating;
bool maximized;
bool centerCursor;
bool focusOnShow;
bool mousePassthrough;
bool scaleToMonitor;
bool scaleFramebuffer;
struct {
char frameName[256];
} ns;
@ -414,8 +423,8 @@ struct _GLFWwndconfig
char instanceName[256];
} x11;
struct {
GLFWbool keymenu;
GLFWbool showDefault;
bool keymenu;
bool showDefault;
} win32;
struct {
char appId[256];
@ -434,15 +443,15 @@ struct _GLFWctxconfig
int source;
int major;
int minor;
GLFWbool forward;
GLFWbool debug;
GLFWbool noerror;
bool forward;
bool debug;
bool noerror;
int profile;
int robustness;
int release;
_GLFWwindow* share;
struct {
GLFWbool offline;
bool offline;
} nsgl;
};
@ -467,11 +476,11 @@ struct _GLFWfbconfig
int accumBlueBits;
int accumAlphaBits;
int auxBuffers;
GLFWbool stereo;
bool stereo;
int samples;
GLFWbool sRGB;
GLFWbool doublebuffer;
GLFWbool transparent;
bool sRGB;
bool doublebuffer;
bool transparent;
uintptr_t handle;
};
@ -490,6 +499,7 @@ struct _GLFWcontext
PFNGLGETSTRINGIPROC GetStringi;
PFNGLGETINTEGERVPROC GetIntegerv;
PFNGLGETSTRINGPROC GetString;
PFNGLFLUSHPROC Flush;
void (*makeCurrent)(_GLFWwindow*);
void (*swapBuffers)(_GLFWwindow*);
@ -544,6 +554,7 @@ struct _GLFWwindow
GLFWbool stickyKeys;
GLFWbool stickyMouseButtons;
GLFWbool lockKeyMods;
GLFWbool disableMouseButtonLimit;
int cursorMode;
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
char keys[GLFW_KEY_LAST + 1];
@ -796,21 +807,22 @@ struct _GLFWlibrary
EGLint major, minor;
GLFWbool prefix;
GLFWbool KHR_create_context;
GLFWbool KHR_create_context_no_error;
GLFWbool KHR_gl_colorspace;
GLFWbool KHR_get_all_proc_addresses;
GLFWbool KHR_context_flush_control;
GLFWbool EXT_client_extensions;
GLFWbool EXT_platform_base;
GLFWbool EXT_platform_x11;
GLFWbool EXT_platform_wayland;
GLFWbool EXT_present_opaque;
GLFWbool ANGLE_platform_angle;
GLFWbool ANGLE_platform_angle_opengl;
GLFWbool ANGLE_platform_angle_d3d;
GLFWbool ANGLE_platform_angle_vulkan;
GLFWbool ANGLE_platform_angle_metal;
bool KHR_create_context;
bool KHR_create_context_no_error;
bool KHR_gl_colorspace;
bool KHR_get_all_proc_addresses;
bool KHR_context_flush_control;
bool EXT_client_extensions;
bool EXT_platform_base;
bool EXT_platform_x11;
bool EXT_platform_wayland;
bool EXT_present_opaque;
bool ANGLE_platform_angle;
bool ANGLE_platform_angle_opengl;
bool ANGLE_platform_angle_d3d;
bool ANGLE_platform_angle_vulkan;
bool ANGLE_platform_angle_metal;
bool MESA_platform_surfaceless;
void* handle;
@ -825,6 +837,7 @@ struct _GLFWlibrary
PFN_eglDestroySurface DestroySurface;
PFN_eglDestroyContext DestroyContext;
PFN_eglCreateWindowSurface CreateWindowSurface;
PFN_eglCreatePbufferSurface CreatePbufferSurface;
PFN_eglMakeCurrent MakeCurrent;
PFN_eglSwapBuffers SwapBuffers;
PFN_eglSwapInterval SwapInterval;
@ -853,13 +866,14 @@ struct _GLFWlibrary
void* handle;
char* extensions[2];
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
GLFWbool KHR_surface;
GLFWbool KHR_win32_surface;
GLFWbool MVK_macos_surface;
GLFWbool EXT_metal_surface;
GLFWbool KHR_xlib_surface;
GLFWbool KHR_xcb_surface;
GLFWbool KHR_wayland_surface;
bool KHR_surface;
bool KHR_win32_surface;
bool MVK_macos_surface;
bool EXT_metal_surface;
bool KHR_xlib_surface;
bool KHR_xcb_surface;
bool KHR_wayland_surface;
bool EXT_headless_surface;
} vk;
struct {

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Linux - www.glfw.org
// GLFW 3.5 Linux - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
@ -32,6 +32,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/inotify.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Linux - www.glfw.org
// GLFW 3.5 Linux - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//

View file

@ -0,0 +1,57 @@
//========================================================================
// GLFW 3.5 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(GLFW_BUILD_MACOS_TIMER)
#include <mach/mach_time.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformInitTimer(void)
{
mach_timebase_info_data_t info;
mach_timebase_info(&info);
_glfw.timer.macos.frequency = (info.denom * 1e9) / info.numer;
}
uint64_t _glfwPlatformGetTimerValue(void)
{
return mach_absolute_time();
}
uint64_t _glfwPlatformGetTimerFrequency(void)
{
return _glfw.timer.macos.frequency;
}
#endif // GLFW_BUILD_MACOS_TIMER

View file

@ -0,0 +1,35 @@
//========================================================================
// GLFW 3.5 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2021 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLFW_MACOS_LIBRARY_TIMER_STATE _GLFWtimerMacOS macos;
// macOS-specific global timer data
//
typedef struct _GLFWtimerMacOS
{
uint64_t frequency;
} _GLFWtimerMacOS;

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
//

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
@ -325,9 +325,6 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void)
GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (xpos)
*xpos = 0;
if (ypos)
@ -335,6 +332,9 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
_GLFW_REQUIRE_INIT();
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_glfw.platform.getMonitorPos(monitor, xpos, ypos);
}
@ -342,9 +342,6 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle,
int* xpos, int* ypos,
int* width, int* height)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (xpos)
*xpos = 0;
if (ypos)
@ -356,14 +353,14 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle,
_GLFW_REQUIRE_INIT();
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_glfw.platform.getMonitorWorkarea(monitor, xpos, ypos, width, height);
}
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (widthMM)
*widthMM = 0;
if (heightMM)
@ -371,6 +368,9 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int*
_GLFW_REQUIRE_INIT();
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (widthMM)
*widthMM = monitor->widthMM;
if (heightMM)
@ -380,42 +380,46 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int*
GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* handle,
float* xscale, float* yscale)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (xscale)
*xscale = 0.f;
if (yscale)
*yscale = 0.f;
_GLFW_REQUIRE_INIT();
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_glfw.platform.getMonitorContentScale(monitor, xscale, yscale);
}
GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->name;
}
GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* handle, void* pointer)
{
_GLFW_REQUIRE_INIT();
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT();
monitor->userPointer = pointer;
}
GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->userPointer;
}
@ -428,14 +432,15 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun)
GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
assert(count != NULL);
*count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (!refreshVideoModes(monitor))
return NULL;
@ -445,11 +450,11 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count)
GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!_glfw.platform.getVideoMode(monitor, &monitor->currentMode))
return NULL;
@ -462,13 +467,15 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
unsigned short* values;
GLFWgammaramp ramp;
const GLFWgammaramp* original;
assert(handle != NULL);
assert(gamma > 0.f);
assert(gamma <= FLT_MAX);
assert(isfinite(gamma));
_GLFW_REQUIRE_INIT();
if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX)
assert(handle != NULL);
if (!isfinite(gamma) || gamma <= 0.f)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma);
return;
@ -505,11 +512,11 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_glfwFreeGammaArrays(&monitor->currentRamp);
if (!_glfw.platform.getGammaRamp(monitor, &monitor->currentRamp))
return NULL;
@ -519,8 +526,6 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
assert(ramp != NULL);
assert(ramp->size > 0);
assert(ramp->red != NULL);
@ -529,6 +534,9 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
_GLFW_REQUIRE_INIT();
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (ramp->size <= 0)
{
_glfwInputError(GLFW_INVALID_VALUE,

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 macOS - www.glfw.org
// GLFW 3.5 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
//
@ -30,6 +30,7 @@
#include <unistd.h>
#include <math.h>
#include <assert.h>
static void makeContextCurrentNSGL(_GLFWwindow* window)
{
@ -127,8 +128,6 @@ static void destroyContextNSGL(_GLFWwindow* window)
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize OpenGL support
//
GLFWbool _glfwInitNSGL(void)
{
if (_glfw.nsgl.framework)
@ -146,14 +145,10 @@ GLFWbool _glfwInitNSGL(void)
return GLFW_TRUE;
}
// Terminate OpenGL support
//
void _glfwTerminateNSGL(void)
{
}
// Create the OpenGL context
//
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
@ -182,16 +177,16 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
return GLFW_FALSE;
}
// Context robustness modes (GL_KHR_robustness) are not yet supported by
// Context robustness modes (GL_KHR_robustness) are not supported by
// macOS but are not a hard constraint, so ignore and continue
// Context release behaviors (GL_KHR_context_flush_control) are not yet
// Context release behaviors (GL_KHR_context_flush_control) are not
// supported by macOS but are not a hard constraint, so ignore and continue
// Debug contexts (GL_KHR_debug) are not yet supported by macOS but are not
// Debug contexts (GL_KHR_debug) are not supported by macOS but are not
// a hard constraint, so ignore and continue
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
// No-error contexts (GL_KHR_no_error) are not supported by macOS but
// are not a hard constraint, so ignore and continue
#define ADD_ATTRIB(a) \
@ -217,14 +212,11 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
ADD_ATTRIB(kCGLPFASupportsAutomaticGraphicsSwitching);
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
if (ctxconfig->major >= 4)
{
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
}
else
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
if (ctxconfig->major >= 3)
else if (ctxconfig->major >= 3)
{
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
}
@ -361,7 +353,6 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(nil);
if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
@ -371,6 +362,9 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
return nil;
}
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
@ -260,5 +260,6 @@ void _glfwTerminateNull(void)
free(_glfw.null.clipboardString);
_glfwTerminateOSMesa();
_glfwTerminateEGL();
memset(&_glfw.null, 0, sizeof(_glfw.null));
}

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
//

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
@ -156,6 +156,17 @@
#define GLFW_NULL_SC_MENU 120
#define GLFW_NULL_SC_LAST GLFW_NULL_SC_MENU
typedef VkFlags VkHeadlessSurfaceCreateFlagsEXT;
typedef struct VkHeadlessSurfaceCreateInfoEXT
{
VkStructureType sType;
const void* pNext;
VkHeadlessSurfaceCreateFlagsEXT flags;
} VkHeadlessSurfaceCreateInfoEXT;
typedef VkResult (APIENTRY *PFN_vkCreateHeadlessSurfaceEXT)(VkInstance,const VkHeadlessSurfaceCreateInfoEXT*,const VkAllocationCallbacks*,VkSurfaceKHR*);
// Null-specific per-window data
//
typedef struct _GLFWwindowNull

View file

@ -1,9 +1,8 @@
//========================================================================
// GLFW 3.4 (modified for raylib) - www.glfw.org; www.raylib.com
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@ -29,6 +28,7 @@
#include "internal.h"
#include <stdlib.h>
#include <string.h>
static void applySizeLimits(_GLFWwindow* window, int* width, int* height)
{
@ -60,12 +60,12 @@ static void fitToMonitor(_GLFWwindow* window)
window->null.height = mode.height;
}
static void acquireMonitorNull(_GLFWwindow* window)
static void acquireMonitor(_GLFWwindow* window)
{
_glfwInputMonitorWindow(window->monitor, window);
}
static void releaseMonitorNull(_GLFWwindow* window)
static void releaseMonitor(_GLFWwindow* window)
{
if (window->monitor->window != window)
return;
@ -148,7 +148,7 @@ GLFWbool _glfwCreateWindowNull(_GLFWwindow* window,
{
_glfwShowWindowNull(window);
_glfwFocusWindowNull(window);
acquireMonitorNull(window);
acquireMonitor(window);
if (wndconfig->centerCursor)
_glfwCenterCursorInContentArea(window);
@ -169,7 +169,7 @@ GLFWbool _glfwCreateWindowNull(_GLFWwindow* window,
void _glfwDestroyWindowNull(_GLFWwindow* window)
{
if (window->monitor)
releaseMonitorNull(window);
releaseMonitor(window);
if (_glfw.null.focusedWindow == window)
_glfw.null.focusedWindow = NULL;
@ -204,14 +204,14 @@ void _glfwSetWindowMonitorNull(_GLFWwindow* window,
}
if (window->monitor)
releaseMonitorNull(window);
releaseMonitor(window);
_glfwInputWindowMonitor(window, monitor);
if (window->monitor)
{
window->null.visible = GLFW_TRUE;
acquireMonitorNull(window);
acquireMonitor(window);
fitToMonitor(window);
}
else
@ -341,7 +341,7 @@ void _glfwIconifyWindowNull(_GLFWwindow* window)
_glfwInputWindowIconify(window, GLFW_TRUE);
if (window->monitor)
releaseMonitorNull(window);
releaseMonitor(window);
}
}
@ -353,7 +353,7 @@ void _glfwRestoreWindowNull(_GLFWwindow* window)
_glfwInputWindowIconify(window, GLFW_FALSE);
if (window->monitor)
acquireMonitorNull(window);
acquireMonitor(window);
}
else if (window->null.maximized)
{
@ -553,12 +553,15 @@ const char* _glfwGetClipboardStringNull(void)
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs)
{
return 0;
if (_glfw.egl.EXT_platform_base && _glfw.egl.MESA_platform_surfaceless)
return EGL_PLATFORM_SURFACELESS_MESA;
else
return 0;
}
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void)
{
return 0;
return EGL_DEFAULT_DISPLAY;
}
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window)
@ -700,13 +703,18 @@ int _glfwGetKeyScancodeNull(int key)
void _glfwGetRequiredInstanceExtensionsNull(char** extensions)
{
if (!_glfw.vk.KHR_surface || !_glfw.vk.EXT_headless_surface)
return;
extensions[0] = "VK_KHR_surface";
extensions[1] = "VK_EXT_headless_surface";
}
GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
return GLFW_FALSE;
return GLFW_TRUE;
}
VkResult _glfwCreateWindowSurfaceNull(VkInstance instance,
@ -714,7 +722,28 @@ VkResult _glfwCreateWindowSurfaceNull(VkInstance instance,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
// This seems like the most appropriate error to return here
return VK_ERROR_EXTENSION_NOT_PRESENT;
PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT =
(PFN_vkCreateHeadlessSurfaceEXT)
vkGetInstanceProcAddr(instance, "vkCreateHeadlessSurfaceEXT");
if (!vkCreateHeadlessSurfaceEXT)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Null: Vulkan instance missing VK_EXT_headless_surface extension");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
VkHeadlessSurfaceCreateInfoEXT sci;
memset(&sci, 0, sizeof(sci));
sci.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT;
const VkResult err = vkCreateHeadlessSurfaceEXT(instance, &sci, allocator, surface);
if (err)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Null: Failed to create Vulkan surface: %s",
_glfwGetVulkanResultString(err));
}
return err;
}

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 OSMesa - www.glfw.org
// GLFW 3.5 OSMesa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
@ -180,11 +180,8 @@ GLFWbool _glfwInitOSMesa(void)
void _glfwTerminateOSMesa(void)
{
if (_glfw.osmesa.handle)
{
_glfwPlatformFreeModule(_glfw.osmesa.handle);
_glfw.osmesa.handle = NULL;
}
_glfwPlatformFreeModule(_glfw.osmesa.handle);
_glfw.osmesa.handle = NULL;
}
#define SET_ATTRIB(a, v) \
@ -296,11 +293,12 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
{
void* mesaBuffer;
GLint mesaWidth, mesaHeight, mesaFormat;
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
@ -335,11 +333,12 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
{
void* mesaBuffer;
GLint mesaWidth, mesaHeight, mesaBytes;
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
@ -369,9 +368,11 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);

View file

@ -1,9 +1,8 @@
//========================================================================
// GLFW 3.4 (modified for raylib) - www.glfw.org; www.raylib.com
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@ -75,6 +74,15 @@ GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)
return GLFW_FALSE;
}
// Only allow the Null platform if specifically requested
if (desiredID == GLFW_PLATFORM_NULL)
return _glfwConnectNull(desiredID, platform);
else if (count == 0)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "This binary only supports the Null platform");
return GLFW_FALSE;
}
#if defined(_GLFW_WAYLAND) && defined(_GLFW_X11)
if (desiredID == GLFW_ANY_PLATFORM)
{
@ -179,8 +187,6 @@ GLFWAPI const char* glfwGetVersionString(void)
" OSMesa"
#if defined(__MINGW64_VERSION_MAJOR)
" MinGW-w64"
#elif defined(__MINGW32__)
" MinGW"
#elif defined(_MSC_VER)
" VisualC"
#endif

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
@ -28,7 +28,7 @@
#if defined(GLFW_BUILD_WIN32_TIMER) || \
defined(GLFW_BUILD_WIN32_MODULE) || \
defined(GLFW_BUILD_WIN32_THREAD) || \
defined(GLFW_BUILD_COCOA_TIMER) || \
defined(GLFW_BUILD_MACOS_TIMER) || \
defined(GLFW_BUILD_POSIX_TIMER) || \
defined(GLFW_BUILD_POSIX_MODULE) || \
defined(GLFW_BUILD_POSIX_THREAD) || \
@ -184,7 +184,7 @@
#if defined(_WIN32)
#define GLFW_BUILD_WIN32_TIMER
#elif defined(__APPLE__)
#define GLFW_BUILD_COCOA_TIMER
#define GLFW_BUILD_MACOS_TIMER
#else
#define GLFW_BUILD_POSIX_TIMER
#endif
@ -192,9 +192,9 @@
#if defined(GLFW_BUILD_WIN32_TIMER)
#include "win32_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_WIN32_LIBRARY_TIMER_STATE
#elif defined(GLFW_BUILD_COCOA_TIMER)
#include "cocoa_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_COCOA_LIBRARY_TIMER_STATE
#elif defined(GLFW_BUILD_MACOS_TIMER)
#include "macos_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_MACOS_LIBRARY_TIMER_STATE
#elif defined(GLFW_BUILD_POSIX_TIMER)
#include "posix_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_POSIX_LIBRARY_TIMER_STATE
@ -207,6 +207,7 @@
#endif
#if defined(_GLFW_WAYLAND) || defined(_GLFW_X11)
#include "posix_poll.h"
#define GLFW_BUILD_POSIX_POLL
#endif

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
// GLFW 3.5 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2021 Camilla Löwy <elmindreda@glfw.org>
//
@ -41,7 +41,8 @@ void* _glfwPlatformLoadModule(const char* path)
void _glfwPlatformFreeModule(void* module)
{
dlclose(module);
if (module)
dlclose(module);
}
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name)

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
// GLFW 3.5 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2022 Camilla Löwy <elmindreda@glfw.org>
//

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
// GLFW 3.5 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2022 Camilla Löwy <elmindreda@glfw.org>
//

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
// GLFW 3.5 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
// GLFW 3.5 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
// GLFW 3.5 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
// GLFW 3.5 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
@ -34,6 +34,40 @@
#define _GLFW_FIND_LOADER 1
#define _GLFW_REQUIRE_LOADER 2
#if defined(__APPLE__)
#include <CoreFoundation/CoreFoundation.h>
static void* loadLocalVulkanLoaderMacOS(void)
{
CFBundleRef bundle = CFBundleGetMainBundle();
if (!bundle)
return NULL;
CFURLRef frameworksUrl = CFBundleCopyPrivateFrameworksURL(bundle);
if (!frameworksUrl)
return NULL;
CFURLRef loaderUrl = CFURLCreateCopyAppendingPathComponent(
kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false);
if (!loaderUrl)
{
CFRelease(frameworksUrl);
return NULL;
}
char path[PATH_MAX];
void* handle = NULL;
if (CFURLGetFileSystemRepresentation(loaderUrl, true, (UInt8*) path, sizeof(path) - 1))
handle = _glfwPlatformLoadModule(path);
CFRelease(loaderUrl);
CFRelease(frameworksUrl);
return handle;
}
#endif // __APPLE__
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
@ -55,12 +89,12 @@ GLFWbool _glfwInitVulkan(int mode)
{
#if defined(_GLFW_VULKAN_LIBRARY)
_glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY);
#elif defined(_GLFW_WIN32)
#elif defined(_WIN32)
_glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll");
#elif defined(_GLFW_COCOA)
#elif defined(__APPLE__)
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib");
if (!_glfw.vk.handle)
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderCocoa();
_glfw.vk.handle = loadLocalVulkanLoaderMacOS();
#elif defined(__OpenBSD__) || defined(__NetBSD__)
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so");
#else
@ -129,19 +163,21 @@ GLFWbool _glfwInitVulkan(int mode)
for (i = 0; i < count; i++)
{
if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
_glfw.vk.KHR_surface = GLFW_TRUE;
_glfw.vk.KHR_surface = true;
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
_glfw.vk.KHR_win32_surface = GLFW_TRUE;
_glfw.vk.KHR_win32_surface = true;
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
_glfw.vk.MVK_macos_surface = GLFW_TRUE;
_glfw.vk.MVK_macos_surface = true;
else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0)
_glfw.vk.EXT_metal_surface = GLFW_TRUE;
_glfw.vk.EXT_metal_surface = true;
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
_glfw.vk.KHR_xlib_surface = true;
else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
_glfw.vk.KHR_xcb_surface = GLFW_TRUE;
_glfw.vk.KHR_xcb_surface = true;
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
_glfw.vk.KHR_wayland_surface = GLFW_TRUE;
_glfw.vk.KHR_wayland_surface = true;
else if (strcmp(ep[i].extensionName, "VK_EXT_headless_surface") == 0)
_glfw.vk.EXT_headless_surface = true;
}
_glfw_free(ep);
@ -155,8 +191,8 @@ GLFWbool _glfwInitVulkan(int mode)
void _glfwTerminateVulkan(void)
{
if (_glfw.vk.handle)
_glfwPlatformFreeModule(_glfw.vk.handle);
_glfwPlatformFreeModule(_glfw.vk.handle);
_glfw.vk.handle = NULL;
}
const char* _glfwGetVulkanResultString(VkResult result)
@ -272,11 +308,11 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
assert(instance != VK_NULL_HANDLE);
assert(device != VK_NULL_HANDLE);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return GLFW_FALSE;
@ -297,15 +333,16 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(instance != VK_NULL_HANDLE);
assert(window != NULL);
assert(surface != NULL);
*surface = VK_NULL_HANDLE;
_GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(instance != VK_NULL_HANDLE);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return VK_ERROR_INITIALIZATION_FAILED;

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 WGL - www.glfw.org
// GLFW 3.5 WGL - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
@ -186,28 +186,22 @@ static int choosePixelFormatWGL(_GLFWwindow* window,
u->accumAlphaBits = FIND_ATTRIB_VALUE(WGL_ACCUM_ALPHA_BITS_ARB);
u->auxBuffers = FIND_ATTRIB_VALUE(WGL_AUX_BUFFERS_ARB);
if (FIND_ATTRIB_VALUE(WGL_STEREO_ARB))
u->stereo = GLFW_TRUE;
u->stereo = FIND_ATTRIB_VALUE(WGL_STEREO_ARB);
if (_glfw.wgl.ARB_multisample)
u->samples = FIND_ATTRIB_VALUE(WGL_SAMPLES_ARB);
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (_glfw.wgl.ARB_framebuffer_sRGB ||
_glfw.wgl.EXT_framebuffer_sRGB)
{
if (FIND_ATTRIB_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
u->sRGB = GLFW_TRUE;
}
if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB)
u->sRGB = FIND_ATTRIB_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
}
else
{
if (_glfw.wgl.EXT_colorspace)
{
if (FIND_ATTRIB_VALUE(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT)
u->sRGB = GLFW_TRUE;
u->sRGB = true;
}
}
}
@ -261,9 +255,7 @@ static int choosePixelFormatWGL(_GLFWwindow* window,
u->accumAlphaBits = pfd.cAccumAlphaBits;
u->auxBuffers = pfd.cAuxBuffers;
if (pfd.dwFlags & PFD_STEREO)
u->stereo = GLFW_TRUE;
u->stereo = (pfd.dwFlags & PFD_STEREO);
}
u->handle = pixelFormat;
@ -327,8 +319,8 @@ static void swapBuffersWGL(_GLFWwindow* window)
{
if (!window->monitor)
{
// HACK: Use DwmFlush when desktop composition is enabled on Windows Vista and 7
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
// HACK: Use DwmFlush when desktop composition is enabled on Windows 7
if (!IsWindows8OrGreater())
{
BOOL enabled = FALSE;
@ -353,9 +345,9 @@ static void swapIntervalWGL(int interval)
if (!window->monitor)
{
// HACK: Disable WGL swap interval when desktop composition is enabled on Windows
// Vista and 7 to avoid interfering with DWM vsync
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
// HACK: Disable WGL swap interval when desktop composition is enabled on
// Windows 7 to avoid interfering with DWM vsync
if (!IsWindows8OrGreater())
{
BOOL enabled = FALSE;
@ -401,8 +393,6 @@ static void destroyContextWGL(_GLFWwindow* window)
}
}
// Initialize WGL
//
GLFWbool _glfwInitWGL(void)
{
PIXELFORMATDESCRIPTOR pfd;
@ -521,12 +511,10 @@ GLFWbool _glfwInitWGL(void)
return GLFW_TRUE;
}
// Terminate WGL
//
void _glfwTerminateWGL(void)
{
if (_glfw.wgl.instance)
_glfwPlatformFreeModule(_glfw.wgl.instance);
_glfwPlatformFreeModule(_glfw.wgl.instance);
_glfw.wgl.instance = NULL;
}
#define SET_ATTRIB(a, v) \
@ -536,8 +524,6 @@ void _glfwTerminateWGL(void)
attribs[index++] = v; \
}
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
@ -670,7 +656,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
if (ctxconfig->noerror)
{
if (_glfw.wgl.ARB_create_context_no_error)
SET_ATTRIB(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
SET_ATTRIB(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, true);
}
// NOTE: Only request an explicitly versioned context when necessary, as
@ -775,7 +761,6 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
@ -785,6 +770,9 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
return NULL;
}
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);

View file

@ -1,9 +1,8 @@
//========================================================================
// GLFW 3.4 Win32 (modified for raylib) - www.glfw.org; www.raylib.com
// GLFW 3.5 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@ -90,10 +89,6 @@ static GLFWbool loadLibraries(void)
return GLFW_FALSE;
}
_glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware)
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "SetProcessDPIAware");
_glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
_glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling)
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "EnableNonClientDpiScaling");
_glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext)
@ -171,32 +166,9 @@ static GLFWbool loadLibraries(void)
return GLFW_TRUE;
}
// Unload used libraries (DLLs)
//
static void freeLibraries(void)
{
if (_glfw.win32.xinput.instance)
_glfwPlatformFreeModule(_glfw.win32.xinput.instance);
if (_glfw.win32.dinput8.instance)
_glfwPlatformFreeModule(_glfw.win32.dinput8.instance);
if (_glfw.win32.user32.instance)
_glfwPlatformFreeModule(_glfw.win32.user32.instance);
if (_glfw.win32.dwmapi.instance)
_glfwPlatformFreeModule(_glfw.win32.dwmapi.instance);
if (_glfw.win32.shcore.instance)
_glfwPlatformFreeModule(_glfw.win32.shcore.instance);
if (_glfw.win32.ntdll.instance)
_glfwPlatformFreeModule(_glfw.win32.ntdll.instance);
}
// Create key code translation tables
//
static void createKeyTablesWin32(void)
static void createKeyTables(void)
{
int scancode;
@ -533,7 +505,8 @@ void _glfwUpdateKeyNamesWin32(void)
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
{
const UINT vks[] = {
const UINT vks[] =
{
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
@ -686,14 +659,14 @@ int _glfwInitWin32(void)
if (!loadLibraries())
return GLFW_FALSE;
createKeyTablesWin32();
createKeyTables();
_glfwUpdateKeyNamesWin32();
if (_glfwIsWindows10Version1703OrGreaterWin32())
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
else if (IsWindows8Point1OrGreater())
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
else if (IsWindowsVistaOrGreater())
else
SetProcessDPIAware();
if (!createHelperWindow())
@ -725,7 +698,14 @@ void _glfwTerminateWin32(void)
_glfwTerminateEGL();
_glfwTerminateOSMesa();
freeLibraries();
_glfwPlatformFreeModule(_glfw.win32.xinput.instance);
_glfwPlatformFreeModule(_glfw.win32.dinput8.instance);
_glfwPlatformFreeModule(_glfw.win32.user32.instance);
_glfwPlatformFreeModule(_glfw.win32.dwmapi.instance);
_glfwPlatformFreeModule(_glfw.win32.shcore.instance);
_glfwPlatformFreeModule(_glfw.win32.ntdll.instance);
memset(&_glfw.win32, 0, sizeof(_glfw.win32));
}
#endif // _GLFW_WIN32

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
// GLFW 3.5 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
// GLFW 3.5 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
// GLFW 3.5 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2021 Camilla Löwy <elmindreda@glfw.org>
//
@ -39,7 +39,8 @@ void* _glfwPlatformLoadModule(const char* path)
void _glfwPlatformFreeModule(void* module)
{
FreeLibrary((HMODULE) module);
if (module)
FreeLibrary((HMODULE) module);
}
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name)

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
// GLFW 3.5 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
@ -33,6 +33,7 @@
#include <string.h>
#include <limits.h>
#include <wchar.h>
#include <assert.h>
// Callback for EnumDisplayMonitors in createMonitor
@ -539,7 +540,6 @@ void _glfwSetGammaRampWin32(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
@ -548,12 +548,14 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle)
return NULL;
}
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
return monitor->win32.publicAdapterName;
}
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
@ -562,6 +564,9 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle)
return NULL;
}
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
return monitor->win32.publicDisplayName;
}

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
// GLFW 3.5 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
@ -48,14 +48,14 @@
#define UNICODE
#endif
// GLFW requires Windows XP or later
#if WINVER < 0x0501
// GLFW requires Windows 7 or later
#if WINVER < 0x0601
#undef WINVER
#define WINVER 0x0501
#define WINVER 0x0601
#endif
#if _WIN32_WINNT < 0x0501
#if _WIN32_WINNT < 0x0601
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#define _WIN32_WINNT 0x0601
#endif
// GLFW uses DirectInput8 interfaces
@ -66,41 +66,21 @@
#include <wctype.h>
#include <windows.h>
#include <dwmapi.h>
#include <dinput.h>
#include <xinput.h>
#include <dbt.h>
// HACK: Define macros that some windows.h variants don't
#ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E
#endif
#ifndef WM_DWMCOMPOSITIONCHANGED
#define WM_DWMCOMPOSITIONCHANGED 0x031E
#endif
#ifndef WM_DWMCOLORIZATIONCOLORCHANGED
#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320
#endif
#ifndef WM_COPYGLOBALDATA
#define WM_COPYGLOBALDATA 0x0049
#endif
#ifndef WM_UNICHAR
#define WM_UNICHAR 0x0109
#endif
#ifndef UNICODE_NOCHAR
#define UNICODE_NOCHAR 0xFFFF
#endif
#ifndef WM_DPICHANGED
#define WM_DPICHANGED 0x02E0
#endif
#ifndef GET_XBUTTON_WPARAM
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
#endif
#ifndef EDS_ROTATEDMODE
#define EDS_ROTATEDMODE 0x00000004
#endif
#ifndef DISPLAY_DEVICE_ACTIVE
#define DISPLAY_DEVICE_ACTIVE 0x00000001
#endif
#ifndef _WIN32_WINNT_WINBLUE
#define _WIN32_WINNT_WINBLUE 0x0603
#endif
@ -113,34 +93,6 @@
#ifndef USER_DEFAULT_SCREEN_DPI
#define USER_DEFAULT_SCREEN_DPI 96
#endif
#ifndef OCR_HAND
#define OCR_HAND 32649
#endif
#if WINVER < 0x0601
typedef struct
{
DWORD cbSize;
DWORD ExtStatus;
} CHANGEFILTERSTRUCT;
#ifndef MSGFLT_ALLOW
#define MSGFLT_ALLOW 1
#endif
#endif /*Windows 7*/
#if WINVER < 0x0600
#define DWM_BB_ENABLE 0x00000001
#define DWM_BB_BLURREGION 0x00000002
typedef struct
{
DWORD dwFlags;
BOOL fEnable;
HRGN hRgnBlur;
BOOL fTransitionOnMaximized;
} DWM_BLURBEHIND;
#else
#include <dwmapi.h>
#endif /*Windows Vista*/
#ifndef DPI_ENUMS_DECLARED
typedef enum
@ -165,12 +117,6 @@ typedef enum
// Replacement for versionhelpers.h macros, as we cannot rely on the
// application having a correct embedded manifest
//
#define IsWindowsVistaOrGreater() \
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
LOBYTE(_WIN32_WINNT_VISTA), 0)
#define IsWindows7OrGreater() \
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN7), \
LOBYTE(_WIN32_WINNT_WIN7), 0)
#define IsWindows8OrGreater() \
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN8), \
LOBYTE(_WIN32_WINNT_WIN8), 0)
@ -281,15 +227,11 @@ typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*
#define DirectInput8Create _glfw.win32.dinput8.Create
// user32.dll function pointer typedefs
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*);
typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND);
typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE);
typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
typedef int (WINAPI * PFN_GetSystemMetricsForDpi)(int,UINT);
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
#define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_
#define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_
#define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_
@ -394,18 +336,18 @@ typedef struct _GLFWlibraryWGL
PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
GLFWbool EXT_swap_control;
GLFWbool EXT_colorspace;
GLFWbool ARB_multisample;
GLFWbool ARB_framebuffer_sRGB;
GLFWbool EXT_framebuffer_sRGB;
GLFWbool ARB_pixel_format;
GLFWbool ARB_create_context;
GLFWbool ARB_create_context_profile;
GLFWbool EXT_create_context_es2_profile;
GLFWbool ARB_create_context_robustness;
GLFWbool ARB_create_context_no_error;
GLFWbool ARB_context_flush_control;
bool EXT_swap_control;
bool EXT_colorspace;
bool ARB_multisample;
bool ARB_framebuffer_sRGB;
bool EXT_framebuffer_sRGB;
bool ARB_pixel_format;
bool ARB_create_context;
bool ARB_create_context_profile;
bool EXT_create_context_es2_profile;
bool ARB_create_context_robustness;
bool ARB_create_context_no_error;
bool ARB_context_flush_control;
} _GLFWlibraryWGL;
// Win32-specific per-window data
@ -475,8 +417,6 @@ typedef struct _GLFWlibraryWin32
struct {
HINSTANCE instance;
PFN_SetProcessDPIAware SetProcessDPIAware_;
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
PFN_EnableNonClientDpiScaling EnableNonClientDpiScaling_;
PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
PFN_GetDpiForWindow GetDpiForWindow_;

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
// GLFW 3.5 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
// GLFW 3.5 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
// GLFW 3.5 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
// GLFW 3.5 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>

View file

@ -1,9 +1,8 @@
//========================================================================
// GLFW 3.4 Win32 (modified for raylib) - www.glfw.org; www.raylib.com
// GLFW 3.5 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@ -33,6 +32,7 @@
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <windowsx.h>
#include <shellapi.h>
@ -374,9 +374,6 @@ static void updateFramebufferTransparency(const _GLFWwindow* window)
BOOL composition, opaque;
DWORD color;
if (!IsWindowsVistaOrGreater())
return;
if (FAILED(DwmIsCompositionEnabled(&composition)) || !composition)
return;
@ -440,7 +437,7 @@ static void fitToMonitor(_GLFWwindow* window)
// Make the specified window and its video mode active on its monitor
//
static void acquireMonitorWin32(_GLFWwindow* window)
static void acquireMonitor(_GLFWwindow* window)
{
if (!_glfw.win32.acquiredMonitorCount)
{
@ -461,7 +458,7 @@ static void acquireMonitorWin32(_GLFWwindow* window)
// Remove the window and restore the original video mode
//
static void releaseMonitorWin32(_GLFWwindow* window)
static void releaseMonitor(_GLFWwindow* window)
{
if (window->monitor->window != window)
return;
@ -471,7 +468,7 @@ static void releaseMonitorWin32(_GLFWwindow* window)
{
SetThreadExecutionState(ES_CONTINUOUS);
// HACK: Restore mouse trail length saved in acquireMonitorWin32
// HACK: Restore mouse trail length saved in acquireMonitor
SystemParametersInfoW(SPI_SETMOUSETRAILS, _glfw.win32.mouseTrailSize, 0, 0);
}
@ -714,11 +711,12 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
const int mods = getKeyMods();
scancode = (HIWORD(lParam) & (KF_EXTENDED | 0xff));
if (!scancode)
if (!(scancode & 0xff))
{
// NOTE: Some synthetic key messages have a scancode of zero
// HACK: Map the virtual key back to a usable scancode
scancode = MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC);
// NOTE: Both media keys and the synthetic key messages from Windows
// Clipboard History are reported with a scancode of zero
// HACK: Map the virtual key to a scancode but preserve extended bit
scancode |= MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC);
}
// HACK: Alt+PrtSc has a different scancode than just PrtSc
@ -983,7 +981,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
case WM_MOUSEHWHEEL:
{
// This message is only sent on Windows Vista and later
// NOTE: The X-axis is inverted for consistency with macOS and X11
_glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0);
return 0;
@ -1051,10 +1048,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
if (window->monitor && window->win32.iconified != iconified)
{
if (iconified)
releaseMonitorWin32(window);
releaseMonitor(window);
else
{
acquireMonitorWin32(window);
acquireMonitor(window);
fitToMonitor(window);
}
}
@ -1381,7 +1378,7 @@ static int createNativeWindow(_GLFWwindow* window,
frameHeight = rect.bottom - rect.top;
}
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
wideTitle = _glfwCreateWideStringFromUTF8Win32(window->title);
if (!wideTitle)
return GLFW_FALSE;
@ -1407,15 +1404,9 @@ static int createNativeWindow(_GLFWwindow* window,
SetPropW(window->win32.handle, L"GLFW", window);
if (IsWindows7OrGreater())
{
ChangeWindowMessageFilterEx(window->win32.handle,
WM_DROPFILES, MSGFLT_ALLOW, NULL);
ChangeWindowMessageFilterEx(window->win32.handle,
WM_COPYDATA, MSGFLT_ALLOW, NULL);
ChangeWindowMessageFilterEx(window->win32.handle,
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
}
ChangeWindowMessageFilterEx(window->win32.handle, WM_DROPFILES, MSGFLT_ALLOW, NULL);
ChangeWindowMessageFilterEx(window->win32.handle, WM_COPYDATA, MSGFLT_ALLOW, NULL);
ChangeWindowMessageFilterEx(window->win32.handle, WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
window->win32.scaleToMonitor = wndconfig->scaleToMonitor;
window->win32.keymenu = wndconfig->win32.keymenu;
@ -1535,7 +1526,7 @@ GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window,
{
_glfwShowWindowWin32(window);
_glfwFocusWindowWin32(window);
acquireMonitorWin32(window);
acquireMonitor(window);
fitToMonitor(window);
if (wndconfig->centerCursor)
@ -1557,7 +1548,7 @@ GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window,
void _glfwDestroyWindowWin32(_GLFWwindow* window)
{
if (window->monitor)
releaseMonitorWin32(window);
releaseMonitor(window);
if (window->context.destroy)
window->context.destroy(window);
@ -1678,7 +1669,7 @@ void _glfwSetWindowSizeWin32(_GLFWwindow* window, int width, int height)
{
if (window->monitor->window == window)
{
acquireMonitorWin32(window);
acquireMonitor(window);
fitToMonitor(window);
}
}
@ -1850,7 +1841,7 @@ void _glfwSetWindowMonitorWin32(_GLFWwindow* window,
{
if (monitor->window == window)
{
acquireMonitorWin32(window);
acquireMonitor(window);
fitToMonitor(window);
}
}
@ -1880,7 +1871,7 @@ void _glfwSetWindowMonitorWin32(_GLFWwindow* window,
}
if (window->monitor)
releaseMonitorWin32(window);
releaseMonitor(window);
_glfwInputWindowMonitor(window, monitor);
@ -1898,7 +1889,7 @@ void _glfwSetWindowMonitorWin32(_GLFWwindow* window,
flags |= SWP_FRAMECHANGED;
}
acquireMonitorWin32(window);
acquireMonitor(window);
GetMonitorInfoW(window->monitor->win32.handle, &mi);
SetWindowPos(window->win32.handle, HWND_TOPMOST,
@ -1981,9 +1972,6 @@ GLFWbool _glfwFramebufferTransparentWin32(_GLFWwindow* window)
if (!window->win32.transparent)
return GLFW_FALSE;
if (!IsWindowsVistaOrGreater())
return GLFW_FALSE;
if (FAILED(DwmIsCompositionEnabled(&composition)) || !composition)
return GLFW_FALSE;
@ -2577,7 +2565,6 @@ VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance,
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
@ -2587,6 +2574,9 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
return NULL;
}
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
return window->win32.handle;
}

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
// GLFW 3.5 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
@ -32,7 +32,7 @@
#include <string.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW event API //////
@ -135,9 +135,9 @@ void _glfwInputWindowContentScale(_GLFWwindow* window, float xscale, float yscal
{
assert(window != NULL);
assert(xscale > 0.f);
assert(xscale < FLT_MAX);
assert(isfinite(xscale));
assert(yscale > 0.f);
assert(yscale < FLT_MAX);
assert(isfinite(yscale));
if (window->callbacks.scale)
window->callbacks.scale((GLFWwindow*) window, xscale, yscale);
@ -208,7 +208,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
wndconfig.width = width;
wndconfig.height = height;
wndconfig.title = title;
ctxconfig.share = (_GLFWwindow*) share;
if (!_glfwIsValidContextConfig(&ctxconfig))
@ -266,16 +265,16 @@ void glfwDefaultWindowHints(void)
// The default is a focused, visible, resizable window with decorations
memset(&_glfw.hints.window, 0, sizeof(_glfw.hints.window));
_glfw.hints.window.resizable = GLFW_TRUE;
_glfw.hints.window.visible = GLFW_TRUE;
_glfw.hints.window.decorated = GLFW_TRUE;
_glfw.hints.window.focused = GLFW_TRUE;
_glfw.hints.window.autoIconify = GLFW_TRUE;
_glfw.hints.window.centerCursor = GLFW_TRUE;
_glfw.hints.window.focusOnShow = GLFW_TRUE;
_glfw.hints.window.resizable = true;
_glfw.hints.window.visible = true;
_glfw.hints.window.decorated = true;
_glfw.hints.window.focused = true;
_glfw.hints.window.autoIconify = true;
_glfw.hints.window.centerCursor = true;
_glfw.hints.window.focusOnShow = true;
_glfw.hints.window.xpos = GLFW_ANY_POSITION;
_glfw.hints.window.ypos = GLFW_ANY_POSITION;
_glfw.hints.window.scaleFramebuffer = GLFW_TRUE;
_glfw.hints.window.scaleFramebuffer = true;
// The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
// double buffered
@ -286,7 +285,7 @@ void glfwDefaultWindowHints(void)
_glfw.hints.framebuffer.alphaBits = 8;
_glfw.hints.framebuffer.depthBits = 24;
_glfw.hints.framebuffer.stencilBits = 8;
_glfw.hints.framebuffer.doublebuffer = GLFW_TRUE;
_glfw.hints.framebuffer.doublebuffer = true;
// The default is to select the highest available refresh rate
_glfw.hints.refreshRate = GLFW_DONT_CARE;
@ -332,40 +331,40 @@ GLFWAPI void glfwWindowHint(int hint, int value)
_glfw.hints.framebuffer.auxBuffers = value;
return;
case GLFW_STEREO:
_glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.framebuffer.stereo = value;
return;
case GLFW_DOUBLEBUFFER:
_glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.framebuffer.doublebuffer = value;
return;
case GLFW_TRANSPARENT_FRAMEBUFFER:
_glfw.hints.framebuffer.transparent = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.framebuffer.transparent = value;
return;
case GLFW_SAMPLES:
_glfw.hints.framebuffer.samples = value;
return;
case GLFW_SRGB_CAPABLE:
_glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.framebuffer.sRGB = value;
return;
case GLFW_RESIZABLE:
_glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.resizable = value;
return;
case GLFW_DECORATED:
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.decorated = value;
return;
case GLFW_FOCUSED:
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.focused = value;
return;
case GLFW_AUTO_ICONIFY:
_glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.autoIconify = value;
return;
case GLFW_FLOATING:
_glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.floating = value;
return;
case GLFW_MAXIMIZED:
_glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.maximized = value;
return;
case GLFW_VISIBLE:
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.visible = value;
return;
case GLFW_POSITION_X:
_glfw.hints.window.xpos = value;
@ -374,29 +373,29 @@ GLFWAPI void glfwWindowHint(int hint, int value)
_glfw.hints.window.ypos = value;
return;
case GLFW_WIN32_KEYBOARD_MENU:
_glfw.hints.window.win32.keymenu = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.win32.keymenu = value;
return;
case GLFW_WIN32_SHOWDEFAULT:
_glfw.hints.window.win32.showDefault = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.win32.showDefault = value;
return;
case GLFW_COCOA_GRAPHICS_SWITCHING:
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.context.nsgl.offline = value;
return;
case GLFW_SCALE_TO_MONITOR:
_glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.scaleToMonitor = value;
return;
case GLFW_SCALE_FRAMEBUFFER:
case GLFW_COCOA_RETINA_FRAMEBUFFER:
_glfw.hints.window.scaleFramebuffer = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.scaleFramebuffer = value;
return;
case GLFW_CENTER_CURSOR:
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.centerCursor = value;
return;
case GLFW_FOCUS_ON_SHOW:
_glfw.hints.window.focusOnShow = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.focusOnShow = value;
return;
case GLFW_MOUSE_PASSTHROUGH:
_glfw.hints.window.mousePassthrough = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.mousePassthrough = value;
return;
case GLFW_CLIENT_API:
_glfw.hints.context.client = value;
@ -414,13 +413,13 @@ GLFWAPI void glfwWindowHint(int hint, int value)
_glfw.hints.context.robustness = value;
return;
case GLFW_OPENGL_FORWARD_COMPAT:
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.context.forward = value;
return;
case GLFW_CONTEXT_DEBUG:
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.context.debug = value;
return;
case GLFW_CONTEXT_NO_ERROR:
_glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.context.noerror = value;
return;
case GLFW_OPENGL_PROFILE:
_glfw.hints.context.profile = value;
@ -467,10 +466,10 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value)
GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
// Allow closing of NULL (to match the behavior of free)
if (window == NULL)
return;
@ -501,40 +500,43 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(0);
return window->shouldClose;
}
GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
window->shouldClose = value;
}
GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* handle)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return window->title;
}
GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(title != NULL);
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
char* prev = window->title;
window->title = _glfw_strdup(title);
@ -546,14 +548,15 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,
int count, const GLFWimage* images)
{
int i;
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(count >= 0);
assert(count == 0 || images != NULL);
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (count < 0)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid image count for window icon");
@ -577,25 +580,26 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,
GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 0;
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_glfw.platform.getWindowPos(window, xpos, ypos);
}
GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (window->monitor)
return;
@ -604,27 +608,29 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (width)
*width = 0;
if (height)
*height = 0;
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_glfw.platform.getWindowSize(window, width, height);
}
GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(width >= 0);
assert(height >= 0);
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
window->videoMode.width = width;
window->videoMode.height = height;
@ -635,11 +641,11 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
int minwidth, int minheight,
int maxwidth, int maxheight)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (minwidth != GLFW_DONT_CARE && minheight != GLFW_DONT_CARE)
{
if (minwidth < 0 || minheight < 0)
@ -678,13 +684,14 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(numer != 0);
assert(denom != 0);
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE)
{
if (numer <= 0 || denom <= 0)
@ -707,15 +714,16 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (width)
*width = 0;
if (height)
*height = 0;
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_glfw.platform.getFramebufferSize(window, width, height);
}
@ -723,9 +731,6 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle,
int* left, int* top,
int* right, int* bottom)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (left)
*left = 0;
if (top)
@ -736,44 +741,51 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle,
*bottom = 0;
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_glfw.platform.getWindowFrameSize(window, left, top, right, bottom);
}
GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle,
float* xscale, float* yscale)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (xscale)
*xscale = 0.f;
if (yscale)
*yscale = 0.f;
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_glfw.platform.getWindowContentScale(window, xscale, yscale);
}
GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0.f);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(0.f);
return _glfw.platform.getWindowOpacity(window);
}
GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(opacity == opacity);
assert(isfinite(opacity));
assert(opacity >= 0.f);
assert(opacity <= 1.f);
_GLFW_REQUIRE_INIT();
if (opacity != opacity || opacity < 0.f || opacity > 1.f)
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (!isfinite(opacity) || opacity < 0.f || opacity > 1.f)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid window opacity %f", opacity);
return;
@ -784,29 +796,31 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity)
GLFWAPI void glfwIconifyWindow(GLFWwindow* handle)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfw.platform.iconifyWindow(window);
}
GLFWAPI void glfwRestoreWindow(GLFWwindow* handle)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfw.platform.restoreWindow(window);
}
GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (window->monitor)
return;
@ -815,11 +829,11 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle)
GLFWAPI void glfwShowWindow(GLFWwindow* handle)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (window->monitor)
return;
@ -831,21 +845,21 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfw.platform.requestWindowAttention(window);
}
GLFWAPI void glfwHideWindow(GLFWwindow* handle)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (window->monitor)
return;
@ -854,21 +868,21 @@ GLFWAPI void glfwHideWindow(GLFWwindow* handle)
GLFWAPI void glfwFocusWindow(GLFWwindow* handle)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfw.platform.focusWindow(window);
}
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(0);
switch (attrib)
{
case GLFW_FOCUSED:
@ -927,11 +941,11 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
value = value ? GLFW_TRUE : GLFW_FALSE;
switch (attrib)
@ -973,10 +987,11 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return (GLFWmonitor*) window->monitor;
}
@ -986,14 +1001,15 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh,
int width, int height,
int refreshRate)
{
_GLFWwindow* window = (_GLFWwindow*) wh;
_GLFWmonitor* monitor = (_GLFWmonitor*) mh;
assert(window != NULL);
assert(width >= 0);
assert(height >= 0);
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) wh;
_GLFWmonitor* monitor = (_GLFWmonitor*) mh;
assert(window != NULL);
if (width <= 0 || height <= 0)
{
_glfwInputError(GLFW_INVALID_VALUE,
@ -1021,29 +1037,32 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh,
GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer)
{
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
window->userPointer = pointer;
}
GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return window->userPointer;
}
GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle,
GLFWwindowposfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowposfun, window->callbacks.pos, cbfun);
return cbfun;
}
@ -1051,10 +1070,11 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle,
GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle,
GLFWwindowsizefun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowsizefun, window->callbacks.size, cbfun);
return cbfun;
}
@ -1062,10 +1082,11 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle,
GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle,
GLFWwindowclosefun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowclosefun, window->callbacks.close, cbfun);
return cbfun;
}
@ -1073,10 +1094,11 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle,
GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle,
GLFWwindowrefreshfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowrefreshfun, window->callbacks.refresh, cbfun);
return cbfun;
}
@ -1084,10 +1106,11 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle,
GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle,
GLFWwindowfocusfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowfocusfun, window->callbacks.focus, cbfun);
return cbfun;
}
@ -1095,10 +1118,11 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle,
GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
GLFWwindowiconifyfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowiconifyfun, window->callbacks.iconify, cbfun);
return cbfun;
}
@ -1106,10 +1130,11 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle,
GLFWwindowmaximizefun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowmaximizefun, window->callbacks.maximize, cbfun);
return cbfun;
}
@ -1117,10 +1142,11 @@ GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle,
GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle,
GLFWframebuffersizefun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWframebuffersizefun, window->callbacks.fbsize, cbfun);
return cbfun;
}
@ -1128,10 +1154,11 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle
GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* handle,
GLFWwindowcontentscalefun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowcontentscalefun, window->callbacks.scale, cbfun);
return cbfun;
}
@ -1151,11 +1178,10 @@ GLFWAPI void glfwWaitEvents(void)
GLFWAPI void glfwWaitEventsTimeout(double timeout)
{
_GLFW_REQUIRE_INIT();
assert(timeout == timeout);
assert(isfinite(timeout));
assert(timeout >= 0.0);
assert(timeout <= DBL_MAX);
if (timeout != timeout || timeout < 0.0 || timeout > DBL_MAX)
if (!isfinite(timeout) || timeout < 0.0)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", timeout);
return;

View file

@ -1,8 +1,7 @@
//========================================================================
// GLFW 3.4 Wayland (modified for raylib) - www.glfw.org; www.raylib.com
// GLFW 3.5 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@ -136,7 +135,7 @@ static void registryHandleGlobal(void* userData,
{
_glfw.wl.seat =
wl_registry_bind(registry, name, &wl_seat_interface,
_glfw_min(4, version));
_glfw_min(8, version));
_glfwAddSeatListenerWayland(_glfw.wl.seat);
}
}
@ -245,10 +244,7 @@ static void libdecorReadyCallback(void* userData,
uint32_t time)
{
_glfw.wl.libdecor.ready = GLFW_TRUE;
assert(_glfw.wl.libdecor.callback == callback);
wl_callback_destroy(_glfw.wl.libdecor.callback);
_glfw.wl.libdecor.callback = NULL;
wl_callback_destroy(callback);
}
static const struct wl_callback_listener libdecorReadyListener =
@ -258,7 +254,7 @@ static const struct wl_callback_listener libdecorReadyListener =
// Create key code translation tables
//
static void createKeyTablesWayland(void)
static void createKeyTables(void)
{
memset(_glfw.wl.keycodes, -1, sizeof(_glfw.wl.keycodes));
memset(_glfw.wl.scancodes, -1, sizeof(_glfw.wl.scancodes));
@ -579,6 +575,14 @@ int _glfwInitWayland(void)
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_get_fd");
_glfw.wl.client.display_prepare_read = (PFN_wl_display_prepare_read)
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_prepare_read");
_glfw.wl.client.display_create_queue = (PFN_wl_display_create_queue)
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_create_queue");
_glfw.wl.client.display_prepare_read_queue = (PFN_wl_display_prepare_read_queue)
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_prepare_read_queue");
_glfw.wl.client.display_dispatch_queue_pending = (PFN_wl_display_dispatch_queue_pending)
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_dispatch_queue_pending");
_glfw.wl.client.event_queue_destroy = (PFN_wl_event_queue_destroy)
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_event_queue_destroy");
_glfw.wl.client.proxy_marshal = (PFN_wl_proxy_marshal)
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal");
_glfw.wl.client.proxy_add_listener = (PFN_wl_proxy_add_listener)
@ -601,6 +605,12 @@ int _glfwInitWayland(void)
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_version");
_glfw.wl.client.proxy_marshal_flags = (PFN_wl_proxy_marshal_flags)
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_flags");
_glfw.wl.client.proxy_create_wrapper = (PFN_wl_proxy_create_wrapper)
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_create_wrapper");
_glfw.wl.client.proxy_wrapper_destroy = (PFN_wl_proxy_wrapper_destroy)
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_wrapper_destroy");
_glfw.wl.client.proxy_set_queue = (PFN_wl_proxy_set_queue)
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_queue");
if (!_glfw.wl.client.display_flush ||
!_glfw.wl.client.display_cancel_read ||
@ -610,6 +620,10 @@ int _glfwInitWayland(void)
!_glfw.wl.client.display_roundtrip ||
!_glfw.wl.client.display_get_fd ||
!_glfw.wl.client.display_prepare_read ||
!_glfw.wl.client.display_create_queue ||
!_glfw.wl.client.display_prepare_read_queue ||
!_glfw.wl.client.display_dispatch_queue_pending ||
!_glfw.wl.client.event_queue_destroy ||
!_glfw.wl.client.proxy_marshal ||
!_glfw.wl.client.proxy_add_listener ||
!_glfw.wl.client.proxy_destroy ||
@ -618,7 +632,10 @@ int _glfwInitWayland(void)
!_glfw.wl.client.proxy_get_user_data ||
!_glfw.wl.client.proxy_set_user_data ||
!_glfw.wl.client.proxy_get_tag ||
!_glfw.wl.client.proxy_set_tag)
!_glfw.wl.client.proxy_set_tag ||
!_glfw.wl.client.proxy_create_wrapper ||
!_glfw.wl.client.proxy_wrapper_destroy ||
!_glfw.wl.client.proxy_set_queue)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to load libwayland-client entry point");
@ -705,6 +722,10 @@ int _glfwInitWayland(void)
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_status");
_glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym)
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym");
_glfw.wl.xkb.keysym_to_utf32 = (PFN_xkb_keysym_to_utf32)
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keysym_to_utf32");
_glfw.wl.xkb.keysym_to_utf8 = (PFN_xkb_keysym_to_utf8)
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keysym_to_utf8");
if (!_glfw.wl.xkb.context_new ||
!_glfw.wl.xkb.context_unref ||
@ -777,6 +798,8 @@ int _glfwInitWayland(void)
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_capabilities");
_glfw.wl.libdecor.libdecor_frame_set_visibility_ = (PFN_libdecor_frame_set_visibility)
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_visibility");
_glfw.wl.libdecor.libdecor_frame_is_visible_ = (PFN_libdecor_frame_is_visible)
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_is_visible");
_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ = (PFN_libdecor_frame_get_xdg_toplevel)
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_get_xdg_toplevel");
_glfw.wl.libdecor.libdecor_configuration_get_content_size_ = (PFN_libdecor_configuration_get_content_size)
@ -808,6 +831,7 @@ int _glfwInitWayland(void)
!_glfw.wl.libdecor.libdecor_frame_set_capabilities_ ||
!_glfw.wl.libdecor.libdecor_frame_unset_capabilities_ ||
!_glfw.wl.libdecor.libdecor_frame_set_visibility_ ||
!_glfw.wl.libdecor.libdecor_frame_is_visible_ ||
!_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ ||
!_glfw.wl.libdecor.libdecor_configuration_get_content_size_ ||
!_glfw.wl.libdecor.libdecor_configuration_get_window_state_ ||
@ -822,9 +846,19 @@ int _glfwInitWayland(void)
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
wl_registry_add_listener(_glfw.wl.registry, &registryListener, NULL);
createKeyTablesWayland();
createKeyTables();
_glfw.wl.xkb.context = xkb_context_new(0);
_glfw.wl.keyRepeatTimerfd =
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
if (_glfw.wl.keyRepeatTimerfd == -1)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to create timerfd: %s",
strerror(errno));
return GLFW_FALSE;
}
_glfw.wl.xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (!_glfw.wl.xkb.context)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@ -847,19 +881,11 @@ int _glfwInitWayland(void)
libdecor_dispatch(_glfw.wl.libdecor.context, 0);
// Create sync point to "know" when libdecor is ready for use
_glfw.wl.libdecor.callback = wl_display_sync(_glfw.wl.display);
wl_callback_add_listener(_glfw.wl.libdecor.callback,
&libdecorReadyListener,
NULL);
struct wl_callback* callback = wl_display_sync(_glfw.wl.display);
wl_callback_add_listener(callback, &libdecorReadyListener, NULL);
}
}
if (wl_seat_get_version(_glfw.wl.seat) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
{
_glfw.wl.keyRepeatTimerfd =
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
}
if (!_glfw.wl.wmBase)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@ -903,18 +929,6 @@ void _glfwTerminateWayland(void)
libdecor_unref(_glfw.wl.libdecor.context);
}
if (_glfw.wl.libdecor.handle)
{
_glfwPlatformFreeModule(_glfw.wl.libdecor.handle);
_glfw.wl.libdecor.handle = NULL;
}
if (_glfw.wl.egl.handle)
{
_glfwPlatformFreeModule(_glfw.wl.egl.handle);
_glfw.wl.egl.handle = NULL;
}
if (_glfw.wl.xkb.composeState)
xkb_compose_state_unref(_glfw.wl.xkb.composeState);
if (_glfw.wl.xkb.keymap)
@ -923,21 +937,11 @@ void _glfwTerminateWayland(void)
xkb_state_unref(_glfw.wl.xkb.state);
if (_glfw.wl.xkb.context)
xkb_context_unref(_glfw.wl.xkb.context);
if (_glfw.wl.xkb.handle)
{
_glfwPlatformFreeModule(_glfw.wl.xkb.handle);
_glfw.wl.xkb.handle = NULL;
}
if (_glfw.wl.cursorTheme)
wl_cursor_theme_destroy(_glfw.wl.cursorTheme);
if (_glfw.wl.cursorThemeHiDPI)
wl_cursor_theme_destroy(_glfw.wl.cursorThemeHiDPI);
if (_glfw.wl.cursor.handle)
{
_glfwPlatformFreeModule(_glfw.wl.cursor.handle);
_glfw.wl.cursor.handle = NULL;
}
for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)
wl_data_offer_destroy(_glfw.wl.offers[i].offer);
@ -997,7 +1001,18 @@ void _glfwTerminateWayland(void)
if (_glfw.wl.cursorTimerfd >= 0)
close(_glfw.wl.cursorTimerfd);
// Free modules only after all Wayland termination functions are called
_glfwPlatformFreeModule(_glfw.egl.handle);
_glfwPlatformFreeModule(_glfw.wl.libdecor.handle);
_glfwPlatformFreeModule(_glfw.wl.egl.handle);
_glfwPlatformFreeModule(_glfw.wl.xkb.handle);
_glfwPlatformFreeModule(_glfw.wl.cursor.handle);
_glfwPlatformFreeModule(_glfw.wl.client.handle);
_glfw_free(_glfw.wl.clipboardString);
memset(&_glfw.wl, 0, sizeof(_glfw.wl));
}
#endif // _GLFW_WAYLAND

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Wayland - www.glfw.org
// GLFW 3.5 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
@ -33,6 +33,7 @@
#include <string.h>
#include <errno.h>
#include <math.h>
#include <assert.h>
#include "wayland-client-protocol.h"
@ -258,7 +259,6 @@ void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)
@ -267,6 +267,9 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
return NULL;
}
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
return monitor->wl.output;
}

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 Wayland - www.glfw.org
// GLFW 3.5 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
@ -28,8 +28,6 @@
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbcommon-compose.h>
#include <stdbool.h>
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
typedef struct VkWaylandSurfaceCreateInfoKHR
@ -44,9 +42,6 @@ typedef struct VkWaylandSurfaceCreateInfoKHR
typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
#include "xkb_unicode.h"
#include "posix_poll.h"
typedef int (* PFN_wl_display_flush)(struct wl_display* display);
typedef void (* PFN_wl_display_cancel_read)(struct wl_display* display);
typedef int (* PFN_wl_display_dispatch_pending)(struct wl_display* display);
@ -56,6 +51,10 @@ typedef void (* PFN_wl_display_disconnect)(struct wl_display*);
typedef int (* PFN_wl_display_roundtrip)(struct wl_display*);
typedef int (* PFN_wl_display_get_fd)(struct wl_display*);
typedef int (* PFN_wl_display_prepare_read)(struct wl_display*);
typedef struct wl_event_queue* (* PFN_wl_display_create_queue)(struct wl_display*);
typedef void (* PFN_wl_event_queue_destroy)(struct wl_event_queue*);
typedef int (* PFN_wl_display_prepare_read_queue)(struct wl_display*,struct wl_event_queue*);
typedef int (* PFN_wl_display_dispatch_queue_pending)(struct wl_display*,struct wl_event_queue*);
typedef void (* PFN_wl_proxy_marshal)(struct wl_proxy*,uint32_t,...);
typedef int (* PFN_wl_proxy_add_listener)(struct wl_proxy*,void(**)(void),void*);
typedef void (* PFN_wl_proxy_destroy)(struct wl_proxy*);
@ -67,6 +66,9 @@ typedef void (* PFN_wl_proxy_set_tag)(struct wl_proxy*,const char*const*);
typedef const char* const* (* PFN_wl_proxy_get_tag)(struct wl_proxy*);
typedef uint32_t (* PFN_wl_proxy_get_version)(struct wl_proxy*);
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,uint32_t,...);
typedef void* (* PFN_wl_proxy_create_wrapper)(void*);
typedef void (* PFN_wl_proxy_wrapper_destroy)(void*);
typedef void (* PFN_wl_proxy_set_queue)(struct wl_proxy*,struct wl_event_queue*);
#define wl_display_flush _glfw.wl.client.display_flush
#define wl_display_cancel_read _glfw.wl.client.display_cancel_read
#define wl_display_dispatch_pending _glfw.wl.client.display_dispatch_pending
@ -75,6 +77,10 @@ typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_
#define wl_display_roundtrip _glfw.wl.client.display_roundtrip
#define wl_display_get_fd _glfw.wl.client.display_get_fd
#define wl_display_prepare_read _glfw.wl.client.display_prepare_read
#define wl_display_create_queue _glfw.wl.client.display_create_queue
#define wl_display_prepare_read_queue _glfw.wl.client.display_prepare_read_queue
#define wl_display_dispatch_queue_pending _glfw.wl.client.display_dispatch_queue_pending
#define wl_event_queue_destroy _glfw.wl.client.event_queue_destroy
#define wl_proxy_marshal _glfw.wl.client.proxy_marshal
#define wl_proxy_add_listener _glfw.wl.client.proxy_add_listener
#define wl_proxy_destroy _glfw.wl.client.proxy_destroy
@ -86,6 +92,9 @@ typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_
#define wl_proxy_set_tag _glfw.wl.client.proxy_set_tag
#define wl_proxy_get_version _glfw.wl.client.proxy_get_version
#define wl_proxy_marshal_flags _glfw.wl.client.proxy_marshal_flags
#define wl_proxy_create_wrapper _glfw.wl.client.proxy_create_wrapper
#define wl_proxy_wrapper_destroy _glfw.wl.client.proxy_wrapper_destroy
#define wl_proxy_set_queue _glfw.wl.client.proxy_set_queue
struct wl_shm;
struct wl_output;
@ -139,18 +148,22 @@ struct wl_output;
#define GLFW_WAYLAND_MONITOR_STATE _GLFWmonitorWayland wl;
#define GLFW_WAYLAND_CURSOR_STATE _GLFWcursorWayland wl;
struct wl_cursor_image {
struct wl_cursor_image
{
uint32_t width;
uint32_t height;
uint32_t hotspot_x;
uint32_t hotspot_y;
uint32_t delay;
};
struct wl_cursor {
struct wl_cursor
{
unsigned int image_count;
struct wl_cursor_image** images;
char* name;
};
typedef struct wl_cursor_theme* (* PFN_wl_cursor_theme_load)(const char*, int, struct wl_shm*);
typedef void (* PFN_wl_cursor_theme_destroy)(struct wl_cursor_theme*);
typedef struct wl_cursor* (* PFN_wl_cursor_theme_get_cursor)(struct wl_cursor_theme*, const char*);
@ -180,6 +193,8 @@ typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, con
typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t);
typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t);
typedef int (* PFN_xkb_state_mod_index_is_active)(struct xkb_state*,xkb_mod_index_t,enum xkb_state_component);
typedef uint32_t (* PFN_xkb_keysym_to_utf32)(xkb_keysym_t);
typedef int (* PFN_xkb_keysym_to_utf8)(xkb_keysym_t, char*, size_t);
#define xkb_context_new _glfw.wl.xkb.context_new
#define xkb_context_unref _glfw.wl.xkb.context_unref
#define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string
@ -193,6 +208,8 @@ typedef int (* PFN_xkb_state_mod_index_is_active)(struct xkb_state*,xkb_mod_inde
#define xkb_state_update_mask _glfw.wl.xkb.state_update_mask
#define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout
#define xkb_state_mod_index_is_active _glfw.wl.xkb.state_mod_index_is_active
#define xkb_keysym_to_utf32 _glfw.wl.xkb.keysym_to_utf32
#define xkb_keysym_to_utf8 _glfw.wl.xkb.keysym_to_utf8
typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags);
typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*);
@ -216,62 +233,62 @@ struct libdecor_configuration;
enum libdecor_error
{
LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE,
LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION,
LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE,
LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION,
};
enum libdecor_window_state
{
LIBDECOR_WINDOW_STATE_NONE = 0,
LIBDECOR_WINDOW_STATE_ACTIVE = 1,
LIBDECOR_WINDOW_STATE_MAXIMIZED = 2,
LIBDECOR_WINDOW_STATE_FULLSCREEN = 4,
LIBDECOR_WINDOW_STATE_TILED_LEFT = 8,
LIBDECOR_WINDOW_STATE_TILED_RIGHT = 16,
LIBDECOR_WINDOW_STATE_TILED_TOP = 32,
LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 64
LIBDECOR_WINDOW_STATE_NONE = 0,
LIBDECOR_WINDOW_STATE_ACTIVE = 1,
LIBDECOR_WINDOW_STATE_MAXIMIZED = 2,
LIBDECOR_WINDOW_STATE_FULLSCREEN = 4,
LIBDECOR_WINDOW_STATE_TILED_LEFT = 8,
LIBDECOR_WINDOW_STATE_TILED_RIGHT = 16,
LIBDECOR_WINDOW_STATE_TILED_TOP = 32,
LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 64
};
enum libdecor_capabilities
{
LIBDECOR_ACTION_MOVE = 1,
LIBDECOR_ACTION_RESIZE = 2,
LIBDECOR_ACTION_MINIMIZE = 4,
LIBDECOR_ACTION_FULLSCREEN = 8,
LIBDECOR_ACTION_CLOSE = 16
LIBDECOR_ACTION_MOVE = 1,
LIBDECOR_ACTION_RESIZE = 2,
LIBDECOR_ACTION_MINIMIZE = 4,
LIBDECOR_ACTION_FULLSCREEN = 8,
LIBDECOR_ACTION_CLOSE = 16
};
struct libdecor_interface
{
void (* error)(struct libdecor*,enum libdecor_error,const char*);
void (* reserved0)(void);
void (* reserved1)(void);
void (* reserved2)(void);
void (* reserved3)(void);
void (* reserved4)(void);
void (* reserved5)(void);
void (* reserved6)(void);
void (* reserved7)(void);
void (* reserved8)(void);
void (* reserved9)(void);
void (* error)(struct libdecor*,enum libdecor_error,const char*);
void (* reserved0)(void);
void (* reserved1)(void);
void (* reserved2)(void);
void (* reserved3)(void);
void (* reserved4)(void);
void (* reserved5)(void);
void (* reserved6)(void);
void (* reserved7)(void);
void (* reserved8)(void);
void (* reserved9)(void);
};
struct libdecor_frame_interface
{
void (* configure)(struct libdecor_frame*,struct libdecor_configuration*,void*);
void (* close)(struct libdecor_frame*,void*);
void (* commit)(struct libdecor_frame*,void*);
void (* dismiss_popup)(struct libdecor_frame*,const char*,void*);
void (* reserved0)(void);
void (* reserved1)(void);
void (* reserved2)(void);
void (* reserved3)(void);
void (* reserved4)(void);
void (* reserved5)(void);
void (* reserved6)(void);
void (* reserved7)(void);
void (* reserved8)(void);
void (* reserved9)(void);
void (* configure)(struct libdecor_frame*,struct libdecor_configuration*,void*);
void (* close)(struct libdecor_frame*,void*);
void (* commit)(struct libdecor_frame*,void*);
void (* dismiss_popup)(struct libdecor_frame*,const char*,void*);
void (* reserved0)(void);
void (* reserved1)(void);
void (* reserved2)(void);
void (* reserved3)(void);
void (* reserved4)(void);
void (* reserved5)(void);
void (* reserved6)(void);
void (* reserved7)(void);
void (* reserved8)(void);
void (* reserved9)(void);
};
typedef struct libdecor* (* PFN_libdecor_new)(struct wl_display*,const struct libdecor_interface*);
@ -294,6 +311,7 @@ typedef void (* PFN_libdecor_frame_unset_maximized)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_set_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);
typedef void (* PFN_libdecor_frame_unset_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);
typedef void (* PFN_libdecor_frame_set_visibility)(struct libdecor_frame*,bool visible);
typedef bool (* PFN_libdecor_frame_is_visible)(struct libdecor_frame*);
typedef struct xdg_toplevel* (* PFN_libdecor_frame_get_xdg_toplevel)(struct libdecor_frame*);
typedef bool (* PFN_libdecor_configuration_get_content_size)(struct libdecor_configuration*,struct libdecor_frame*,int*,int*);
typedef bool (* PFN_libdecor_configuration_get_window_state)(struct libdecor_configuration*,enum libdecor_window_state*);
@ -319,6 +337,7 @@ typedef void (* PFN_libdecor_state_free)(struct libdecor_state*);
#define libdecor_frame_set_capabilities _glfw.wl.libdecor.libdecor_frame_set_capabilities_
#define libdecor_frame_unset_capabilities _glfw.wl.libdecor.libdecor_frame_unset_capabilities_
#define libdecor_frame_set_visibility _glfw.wl.libdecor.libdecor_frame_set_visibility_
#define libdecor_frame_is_visible _glfw.wl.libdecor.libdecor_frame_is_visible_
#define libdecor_frame_get_xdg_toplevel _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_
#define libdecor_configuration_get_content_size _glfw.wl.libdecor.libdecor_configuration_get_content_size_
#define libdecor_configuration_get_window_state _glfw.wl.libdecor.libdecor_configuration_get_window_state_
@ -355,14 +374,16 @@ typedef struct _GLFWwindowWayland
GLFWbool maximized;
GLFWbool activated;
GLFWbool fullscreen;
GLFWbool hovered;
GLFWbool transparent;
GLFWbool scaleFramebuffer;
struct wl_surface* surface;
struct wl_callback* callback;
struct {
struct wl_event_queue* queue;
struct wl_egl_window* window;
struct wl_callback* callback;
struct wl_surface* wrapper;
int interval;
} egl;
struct {
@ -384,7 +405,6 @@ typedef struct _GLFWwindowWayland
struct libdecor_frame* frame;
} libdecor;
_GLFWcursor* currentCursor;
double cursorPosX, cursorPosY;
char* appId;
@ -411,7 +431,9 @@ typedef struct _GLFWwindowWayland
GLFWbool decorations;
struct wl_buffer* buffer;
_GLFWfallbackEdgeWayland top, left, right, bottom;
struct wl_surface* focus;
double pointerX, pointerY;
uint32_t buttonPressSerial;
const char* cursorName;
} fallback;
} _GLFWwindowWayland;
@ -450,10 +472,10 @@ typedef struct _GLFWlibraryWayland
const char* tag;
struct wl_surface* pointerSurface;
struct wl_cursor_theme* cursorTheme;
struct wl_cursor_theme* cursorThemeHiDPI;
struct wl_surface* cursorSurface;
const char* cursorPreviousName;
int cursorTimerfd;
uint32_t serial;
uint32_t pointerEnterSerial;
@ -468,6 +490,19 @@ typedef struct _GLFWlibraryWayland
short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5];
struct {
struct wl_surface* pointerSurface;
unsigned int events;
double pointerX;
double pointerY;
double scrollX;
double scrollY;
double discreteX;
double discreteY;
int button;
int action;
} pending;
struct {
void* handle;
struct xkb_context* context;
@ -497,6 +532,8 @@ typedef struct _GLFWlibraryWayland
PFN_xkb_state_update_mask state_update_mask;
PFN_xkb_state_key_get_layout state_key_get_layout;
PFN_xkb_state_mod_index_is_active state_mod_index_is_active;
PFN_xkb_keysym_to_utf32 keysym_to_utf32;
PFN_xkb_keysym_to_utf8 keysym_to_utf8;
PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale;
PFN_xkb_compose_table_unref compose_table_unref;
@ -507,7 +544,6 @@ typedef struct _GLFWlibraryWayland
PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym;
} xkb;
_GLFWwindow* pointerFocus;
_GLFWwindow* keyboardFocus;
struct {
@ -520,6 +556,10 @@ typedef struct _GLFWlibraryWayland
PFN_wl_display_roundtrip display_roundtrip;
PFN_wl_display_get_fd display_get_fd;
PFN_wl_display_prepare_read display_prepare_read;
PFN_wl_display_create_queue display_create_queue;
PFN_wl_display_prepare_read_queue display_prepare_read_queue;
PFN_wl_display_dispatch_queue_pending display_dispatch_queue_pending;
PFN_wl_event_queue_destroy event_queue_destroy;
PFN_wl_proxy_marshal proxy_marshal;
PFN_wl_proxy_add_listener proxy_add_listener;
PFN_wl_proxy_destroy proxy_destroy;
@ -531,6 +571,9 @@ typedef struct _GLFWlibraryWayland
PFN_wl_proxy_set_tag proxy_set_tag;
PFN_wl_proxy_get_version proxy_get_version;
PFN_wl_proxy_marshal_flags proxy_marshal_flags;
PFN_wl_proxy_create_wrapper proxy_create_wrapper;
PFN_wl_proxy_wrapper_destroy proxy_wrapper_destroy;
PFN_wl_proxy_set_queue proxy_set_queue;
} client;
struct {
@ -553,7 +596,6 @@ typedef struct _GLFWlibraryWayland
struct {
void* handle;
struct libdecor* context;
struct wl_callback* callback;
GLFWbool ready;
PFN_libdecor_new libdecor_new_;
PFN_libdecor_unref libdecor_unref_;
@ -575,6 +617,7 @@ typedef struct _GLFWlibraryWayland
PFN_libdecor_frame_set_capabilities libdecor_frame_set_capabilities_;
PFN_libdecor_frame_unset_capabilities libdecor_frame_unset_capabilities_;
PFN_libdecor_frame_set_visibility libdecor_frame_set_visibility_;
PFN_libdecor_frame_is_visible libdecor_frame_is_visible_;
PFN_libdecor_frame_get_xdg_toplevel libdecor_frame_get_xdg_toplevel_;
PFN_libdecor_configuration_get_content_size libdecor_configuration_get_content_size_;
PFN_libdecor_configuration_get_window_state libdecor_configuration_get_window_state_;
@ -689,3 +732,5 @@ void _glfwUpdateBufferScaleFromOutputsWayland(_GLFWwindow* window);
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
GLFWbool _glfwWaitForEGLFrameWayland(_GLFWwindow* window);

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,8 @@
//========================================================================
// GLFW 3.4 X11 (modified for raylib) - www.glfw.org; www.raylib.com
// GLFW 3.5 X11 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@ -211,7 +210,7 @@ static int translateKeySyms(const KeySym* keysyms, int width)
// Create key code translation tables
//
static void createKeyTablesX11(void)
static void createKeyTables(void)
{
int scancodeMin, scancodeMax;
@ -536,6 +535,7 @@ static void detectEWMH(void)
XA_WINDOW,
(unsigned char**) &windowFromChild))
{
_glfwReleaseErrorHandlerX11();
XFree(windowFromRoot);
return;
}
@ -909,7 +909,7 @@ static GLFWbool initExtensions(void)
// Update the key code LUT
// FIXME: We should listen to XkbMapNotify events to track changes to
// the keyboard mapping.
createKeyTablesX11();
createKeyTables();
// String format atoms
_glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
@ -1592,65 +1592,29 @@ void _glfwTerminateX11(void)
_glfw.x11.display = NULL;
}
if (_glfw.x11.x11xcb.handle)
{
_glfwPlatformFreeModule(_glfw.x11.x11xcb.handle);
_glfw.x11.x11xcb.handle = NULL;
}
if (_glfw.x11.xcursor.handle)
{
_glfwPlatformFreeModule(_glfw.x11.xcursor.handle);
_glfw.x11.xcursor.handle = NULL;
}
if (_glfw.x11.randr.handle)
{
_glfwPlatformFreeModule(_glfw.x11.randr.handle);
_glfw.x11.randr.handle = NULL;
}
if (_glfw.x11.xinerama.handle)
{
_glfwPlatformFreeModule(_glfw.x11.xinerama.handle);
_glfw.x11.xinerama.handle = NULL;
}
if (_glfw.x11.xrender.handle)
{
_glfwPlatformFreeModule(_glfw.x11.xrender.handle);
_glfw.x11.xrender.handle = NULL;
}
if (_glfw.x11.vidmode.handle)
{
_glfwPlatformFreeModule(_glfw.x11.vidmode.handle);
_glfw.x11.vidmode.handle = NULL;
}
if (_glfw.x11.xi.handle)
{
_glfwPlatformFreeModule(_glfw.x11.xi.handle);
_glfw.x11.xi.handle = NULL;
}
_glfwTerminateOSMesa();
// NOTE: These need to be unloaded after XCloseDisplay, as they register
// cleanup callbacks that get called by that function
_glfwTerminateEGL();
_glfwTerminateGLX();
if (_glfw.x11.xlib.handle)
{
_glfwPlatformFreeModule(_glfw.x11.xlib.handle);
_glfw.x11.xlib.handle = NULL;
}
_glfwPlatformFreeModule(_glfw.x11.x11xcb.handle);
_glfwPlatformFreeModule(_glfw.x11.xcursor.handle);
_glfwPlatformFreeModule(_glfw.x11.randr.handle);
_glfwPlatformFreeModule(_glfw.x11.xinerama.handle);
_glfwPlatformFreeModule(_glfw.x11.xrender.handle);
_glfwPlatformFreeModule(_glfw.x11.xshape.handle);
_glfwPlatformFreeModule(_glfw.x11.vidmode.handle);
_glfwPlatformFreeModule(_glfw.x11.xi.handle);
_glfwPlatformFreeModule(_glfw.x11.xlib.handle);
if (_glfw.x11.emptyEventPipe[0] || _glfw.x11.emptyEventPipe[1])
{
close(_glfw.x11.emptyEventPipe[0]);
close(_glfw.x11.emptyEventPipe[1]);
}
memset(&_glfw.x11, 0, sizeof(_glfw.x11));
}
#endif // _GLFW_X11

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 X11 - www.glfw.org
// GLFW 3.5 X11 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
@ -33,6 +33,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
// Check whether the display mode should be included in enumeration
@ -150,6 +151,12 @@ void _glfwPollMonitorsX11(void)
}
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
if (!ci)
{
XRRFreeOutputInfo(oi);
continue;
}
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
{
widthMM = oi->mm_height;
@ -611,7 +618,6 @@ void _glfwSetGammaRampX11(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
@ -620,12 +626,14 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle)
return None;
}
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
return monitor->x11.crtc;
}
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
@ -634,6 +642,9 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle)
return None;
}
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
return monitor->x11.output;
}

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 X11 - www.glfw.org
// GLFW 3.5 X11 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
@ -452,9 +452,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(V
typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t);
#include "xkb_unicode.h"
#include "posix_poll.h"
#define GLFW_X11_WINDOW_STATE _GLFWwindowX11 x11;
#define GLFW_X11_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11;
#define GLFW_X11_MONITOR_STATE _GLFWmonitorX11 x11;
@ -463,6 +460,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(Vk
#define GLFW_GLX_CONTEXT_STATE _GLFWcontextGLX glx;
#define GLFW_GLX_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx;
#define GLFW_INVALID_CODEPOINT 0xffffffffu
// GLX-specific per-context data
//
@ -470,6 +468,7 @@ typedef struct _GLFWcontextGLX
{
GLXContext handle;
GLXWindow window;
GLXFBConfig fbconfig;
} _GLFWcontextGLX;
// GLX-specific global data
@ -504,18 +503,18 @@ typedef struct _GLFWlibraryGLX
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA;
PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
GLFWbool SGI_swap_control;
GLFWbool EXT_swap_control;
GLFWbool MESA_swap_control;
GLFWbool ARB_multisample;
GLFWbool ARB_framebuffer_sRGB;
GLFWbool EXT_framebuffer_sRGB;
GLFWbool ARB_create_context;
GLFWbool ARB_create_context_profile;
GLFWbool ARB_create_context_robustness;
GLFWbool EXT_create_context_es2_profile;
GLFWbool ARB_create_context_no_error;
GLFWbool ARB_context_flush_control;
bool SGI_swap_control;
bool EXT_swap_control;
bool MESA_swap_control;
bool ARB_multisample;
bool ARB_framebuffer_sRGB;
bool EXT_framebuffer_sRGB;
bool ARB_create_context;
bool ARB_create_context_profile;
bool ARB_create_context_robustness;
bool EXT_create_context_es2_profile;
bool ARB_create_context_no_error;
bool ARB_context_flush_control;
} _GLFWlibraryGLX;
// X11-specific per-window data
@ -984,6 +983,8 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
unsigned char** value);
GLFWbool _glfwIsVisualTransparentX11(Visual* visual);
uint32_t _glfwKeySym2UnicodeX11(unsigned int keysym);
void _glfwGrabErrorHandlerX11(void);
void _glfwReleaseErrorHandlerX11(void);
void _glfwInputErrorX11(int error, const char* message);

View file

@ -1,9 +1,8 @@
//========================================================================
// GLFW 3.4 X11 (modified for raylib) - www.glfw.org; www.raylib.com
// GLFW 3.5 X11 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@ -236,9 +235,9 @@ static int translateState(int state)
// Translates an X11 key code to a GLFW key token
//
static int translateKeyX11(int scancode)
static int translateKey(int scancode)
{
// Use the pre-filled LUT (see createKeyTablesX11() in x11_init.c)
// Use the pre-filled LUT (see createKeyTables() in x11_init.c)
if (scancode < 0 || scancode > 255)
return GLFW_KEY_UNKNOWN;
@ -577,6 +576,10 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
height *= _glfw.x11.contentScaleY;
}
// The dimensions must be nonzero, or a BadValue error results.
width = _glfw_max(1, width);
height = _glfw_max(1, height);
int xpos = 0, ypos = 0;
if (wndconfig->xpos != GLFW_ANY_POSITION && wndconfig->ypos != GLFW_ANY_POSITION)
@ -755,13 +758,13 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
const char* resourceName = getenv("RESOURCE_NAME");
if (resourceName && strlen(resourceName))
hint->res_name = (char*) resourceName;
else if (strlen(wndconfig->title))
hint->res_name = (char*) wndconfig->title;
else if (strlen(window->title))
hint->res_name = (char*) window->title;
else
hint->res_name = (char*) "glfw-application";
if (strlen(wndconfig->title))
hint->res_class = (char*) wndconfig->title;
if (strlen(window->title))
hint->res_class = (char*) window->title;
else
hint->res_class = (char*) "GLFW-Application";
}
@ -781,7 +784,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
if (_glfw.x11.im)
_glfwCreateInputContextX11(window);
_glfwSetWindowTitleX11(window, wndconfig->title);
_glfwSetWindowTitleX11(window, window->title);
_glfwGetWindowPosX11(window, &window->x11.xpos, &window->x11.ypos);
_glfwGetWindowSizeX11(window, &window->x11.width, &window->x11.height);
@ -1082,7 +1085,7 @@ static const char* getSelectionString(Atom selection)
// Make the specified window and its video mode active on its monitor
//
static void acquireMonitorX11(_GLFWwindow* window)
static void acquireMonitor(_GLFWwindow* window)
{
if (_glfw.x11.saver.count == 0)
{
@ -1121,7 +1124,7 @@ static void acquireMonitorX11(_GLFWwindow* window)
// Remove the window and restore the original video mode
//
static void releaseMonitorX11(_GLFWwindow* window)
static void releaseMonitor(_GLFWwindow* window)
{
if (window->monitor->window != window)
return;
@ -1243,7 +1246,7 @@ static void processEvent(XEvent *event)
case KeyPress:
{
const int key = translateKeyX11(keycode);
const int key = translateKey(keycode);
const int mods = translateState(event->xkey.state);
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
@ -1305,7 +1308,7 @@ static void processEvent(XEvent *event)
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
const uint32_t codepoint = _glfwKeySym2Unicode(keysym);
const uint32_t codepoint = _glfwKeySym2UnicodeX11(keysym);
if (codepoint != GLFW_INVALID_CODEPOINT)
_glfwInputChar(window, codepoint, mods, plain);
}
@ -1315,7 +1318,7 @@ static void processEvent(XEvent *event)
case KeyRelease:
{
const int key = translateKeyX11(keycode);
const int key = translateKey(keycode);
const int mods = translateState(event->xkey.state);
if (!_glfw.x11.xkb.detectable)
@ -1807,9 +1810,9 @@ static void processEvent(XEvent *event)
if (window->monitor)
{
if (iconified)
releaseMonitorX11(window);
releaseMonitor(window);
else
acquireMonitorX11(window);
acquireMonitor(window);
}
window->x11.iconified = iconified;
@ -2026,7 +2029,7 @@ GLFWbool _glfwCreateWindowX11(_GLFWwindow* window,
{
_glfwShowWindowX11(window);
updateWindowMode(window);
acquireMonitorX11(window);
acquireMonitor(window);
if (wndconfig->centerCursor)
_glfwCenterCursorInContentArea(window);
@ -2051,7 +2054,7 @@ void _glfwDestroyWindowX11(_GLFWwindow* window)
enableCursor(window);
if (window->monitor)
releaseMonitorX11(window);
releaseMonitor(window);
if (window->x11.ic)
{
@ -2204,10 +2207,14 @@ void _glfwGetWindowSizeX11(_GLFWwindow* window, int* width, int* height)
void _glfwSetWindowSizeX11(_GLFWwindow* window, int width, int height)
{
// The dimensions must be nonzero, or a BadValue error results
width = _glfw_max(1, width);
height = _glfw_max(1, height);
if (window->monitor)
{
if (window->monitor->window == window)
acquireMonitorX11(window);
acquireMonitor(window);
}
else
{
@ -2431,6 +2438,38 @@ void _glfwShowWindowX11(_GLFWwindow* window)
if (_glfwWindowVisibleX11(window))
return;
if (window->floating && _glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_ABOVE)
{
Atom* states = NULL;
const unsigned long count =
_glfwGetWindowPropertyX11(window->x11.handle,
_glfw.x11.NET_WM_STATE,
XA_ATOM, (unsigned char**) &states);
// NOTE: We don't check for failure as this property may not exist yet
// and that's fine (and we'll create it implicitly with append)
unsigned long i;
for (i = 0; i < count; i++)
{
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
break;
}
if (i == count)
{
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeAppend,
(unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
1);
}
if (states)
XFree(states);
}
XMapWindow(_glfw.x11.display, window->x11.handle);
waitForVisibilityNotify(window);
}
@ -2478,7 +2517,7 @@ void _glfwSetWindowMonitorX11(_GLFWwindow* window,
if (monitor)
{
if (monitor->window == window)
acquireMonitorX11(window);
acquireMonitor(window);
}
else
{
@ -2497,7 +2536,7 @@ void _glfwSetWindowMonitorX11(_GLFWwindow* window,
{
_glfwSetWindowDecoratedX11(window, window->decorated);
_glfwSetWindowFloatingX11(window, window->floating);
releaseMonitorX11(window);
releaseMonitor(window);
}
_glfwInputWindowMonitor(window, monitor);
@ -2512,7 +2551,7 @@ void _glfwSetWindowMonitorX11(_GLFWwindow* window,
}
updateWindowMode(window);
acquireMonitorX11(window);
acquireMonitor(window);
}
else
{
@ -2660,6 +2699,10 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled)
}
else
{
// NOTE: _NET_WM_STATE_ABOVE is added when the window is shown
if (enabled)
return;
Atom* states = NULL;
const unsigned long count =
_glfwGetWindowPropertyX11(window->x11.handle,
@ -2670,38 +2713,20 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled)
// NOTE: We don't check for failure as this property may not exist yet
// and that's fine (and we'll create it implicitly with append)
if (enabled)
unsigned long i;
for (i = 0; i < count; i++)
{
unsigned long i;
for (i = 0; i < count; i++)
{
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
break;
}
if (i == count)
{
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeAppend,
(unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
1);
}
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
break;
}
else if (states)
if (i < count)
{
for (unsigned long i = 0; i < count; i++)
{
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
{
states[i] = states[count - 1];
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeReplace, (unsigned char*) states, count - 1);
break;
}
}
states[i] = states[count - 1];
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeReplace, (unsigned char*) states, count - 1);
}
if (states)
@ -2919,7 +2944,7 @@ const char* _glfwGetScancodeNameX11(int scancode)
if (keysym == NoSymbol)
return NULL;
const uint32_t codepoint = _glfwKeySym2Unicode(keysym);
const uint32_t codepoint = _glfwKeySym2UnicodeX11(keysym);
if (codepoint == GLFW_INVALID_CODEPOINT)
return NULL;
@ -3303,7 +3328,6 @@ GLFWAPI Display* glfwGetX11Display(void)
GLFWAPI Window glfwGetX11Window(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
@ -3312,6 +3336,9 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* handle)
return None;
}
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
return window->x11.handle;
}
@ -3325,6 +3352,8 @@ GLFWAPI void glfwSetX11SelectionString(const char* string)
return;
}
assert(string != NULL);
_glfw_free(_glfw.x11.primarySelectionString);
_glfw.x11.primarySelectionString = _glfw_strdup(string);

View file

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.4 X11 - www.glfw.org
// GLFW 3.5 X11 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
@ -27,7 +27,7 @@
#include "internal.h"
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
#if defined(_GLFW_X11)
/*
* Marcus: This code was originally written by Markus G. Kuhn.
@ -906,7 +906,7 @@ static const struct codepair {
// Convert XKB KeySym to Unicode
//
uint32_t _glfwKeySym2Unicode(unsigned int keysym)
uint32_t _glfwKeySym2UnicodeX11(unsigned int keysym)
{
int min = 0;
int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
@ -939,5 +939,5 @@ uint32_t _glfwKeySym2Unicode(unsigned int keysym)
return GLFW_INVALID_CODEPOINT;
}
#endif // _GLFW_WAYLAND or _GLFW_X11
#endif // _GLFW_X11

View file

@ -1538,10 +1538,10 @@ mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename)
modctx->modfile = (muchar *) JARMOD_MALLOC(fsize);
modctx->modfilesize = fsize;
memset(modctx->modfile, 0, fsize);
fread(modctx->modfile, fsize, 1, f);
if(fread(modctx->modfile, fsize, 1, f) != 1) fsize = 0;
fclose(f);
if(!jar_mod_load(modctx, (void *)modctx->modfile, fsize)) fsize = 0;
if(fsize && !jar_mod_load(modctx, (void *)modctx->modfile, fsize)) fsize = 0;
} else fsize = 0;
}
return fsize;

View file

@ -1,6 +1,6 @@
/*
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
miniaudio - v0.11.24 - 2026-01-17
miniaudio - v0.11.25 - 2026-03-04
David Reid - mackron@gmail.com
@ -3747,7 +3747,7 @@ extern "C" {
#define MA_VERSION_MAJOR 0
#define MA_VERSION_MINOR 11
#define MA_VERSION_REVISION 24
#define MA_VERSION_REVISION 25
#define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION)
#if defined(_MSC_VER) && !defined(__clang__)
@ -19358,7 +19358,7 @@ MA_API ma_handle ma_dlopen(ma_log* pLog, const char* filename)
#else
/* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */
WCHAR filenameW[4096];
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, sizeof(filenameW)) == 0) {
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, ma_countof(filenameW)) == 0) {
handle = NULL;
} else {
handle = (ma_handle)LoadPackagedLibrary(filenameW, 0);
@ -41495,18 +41495,37 @@ Web Audio Backend
#ifdef MA_HAS_WEBAUDIO
#include <emscripten/emscripten.h>
#if (__EMSCRIPTEN_major__ > 3) || (__EMSCRIPTEN_major__ == 3 && (__EMSCRIPTEN_minor__ > 1 || (__EMSCRIPTEN_minor__ == 1 && __EMSCRIPTEN_tiny__ >= 32)))
#ifndef MA_EMSCRIPTEN_MAJOR
#if defined(__EMSCRIPTEN_MAJOR__)
#define MA_EMSCRIPTEN_MAJOR __EMSCRIPTEN_MAJOR__
#else
#define MA_EMSCRIPTEN_MAJOR __EMSCRIPTEN_major__
#endif
#endif
#ifndef MA_EMSCRIPTEN_MINOR
#if defined(__EMSCRIPTEN_MINOR__)
#define MA_EMSCRIPTEN_MINOR __EMSCRIPTEN_MINOR__
#else
#define MA_EMSCRIPTEN_MINOR __EMSCRIPTEN_minor__
#endif
#endif
#ifndef MA_EMSCRIPTEN_TINY
#if defined(__EMSCRIPTEN_TINY__)
#define MA_EMSCRIPTEN_TINY __EMSCRIPTEN_TINY__
#else
#define MA_EMSCRIPTEN_TINY __EMSCRIPTEN_tiny__
#endif
#endif
#if (MA_EMSCRIPTEN_MAJOR > 3) || (MA_EMSCRIPTEN_MAJOR == 3 && (MA_EMSCRIPTEN_MINOR > 1 || (MA_EMSCRIPTEN_MINOR == 1 && MA_EMSCRIPTEN_TINY >= 32)))
#include <emscripten/webaudio.h>
#define MA_SUPPORT_AUDIO_WORKLETS
#if (__EMSCRIPTEN_major__ > 3) || (__EMSCRIPTEN_major__ == 3 && (__EMSCRIPTEN_minor__ > 1 || (__EMSCRIPTEN_minor__ == 1 && __EMSCRIPTEN_tiny__ >= 70)))
#if (MA_EMSCRIPTEN_MAJOR > 3) || (MA_EMSCRIPTEN_MAJOR == 3 && (MA_EMSCRIPTEN_MINOR > 1 || (MA_EMSCRIPTEN_MINOR == 1 && MA_EMSCRIPTEN_TINY >= 70)))
#define MA_SUPPORT_AUDIO_WORKLETS_VARIABLE_BUFFER_SIZE
#endif
#endif
/*
TODO: Version 0.12: Swap this logic around so that AudioWorklets are used by default. Add MA_NO_AUDIO_WORKLETS.
*/
#if defined(MA_ENABLE_AUDIO_WORKLETS) && defined(MA_SUPPORT_AUDIO_WORKLETS)
#define MA_USE_AUDIO_WORKLETS
#endif
@ -59243,6 +59262,10 @@ static ma_result ma_data_source_read_pcm_frames_within_range(ma_data_source* pDa
ma_uint64 framesRead = 0;
ma_bool32 loop = ma_data_source_is_looping(pDataSource);
if (pFramesRead != NULL) {
*pFramesRead = 0;
}
if (pDataSourceBase == NULL) {
return MA_AT_END;
}
@ -61921,7 +61944,7 @@ extern "C" {
#define MA_DR_WAV_XSTRINGIFY(x) MA_DR_WAV_STRINGIFY(x)
#define MA_DR_WAV_VERSION_MAJOR 0
#define MA_DR_WAV_VERSION_MINOR 14
#define MA_DR_WAV_VERSION_REVISION 4
#define MA_DR_WAV_VERSION_REVISION 5
#define MA_DR_WAV_VERSION_STRING MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_MAJOR) "." MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_MINOR) "." MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_REVISION)
#include <stddef.h>
#define MA_DR_WAVE_FORMAT_PCM 0x1
@ -80503,6 +80526,13 @@ MA_PRIVATE ma_uint64 ma_dr_wav__read_smpl_to_metadata_obj(ma_dr_wav__metadata_pa
MA_DR_WAV_ASSERT(pChunkHeader != NULL);
if (pMetadata != NULL && bytesJustRead == sizeof(smplHeaderData)) {
ma_uint32 iSampleLoop;
ma_uint32 loopCount;
ma_uint32 calculatedLoopCount;
loopCount = ma_dr_wav_bytes_to_u32(smplHeaderData + 28);
calculatedLoopCount = (pChunkHeader->sizeInBytes - MA_DR_WAV_SMPL_BYTES) / MA_DR_WAV_SMPL_LOOP_BYTES;
if (loopCount != calculatedLoopCount) {
return totalBytesRead;
}
pMetadata->type = ma_dr_wav_metadata_type_smpl;
pMetadata->data.smpl.manufacturerId = ma_dr_wav_bytes_to_u32(smplHeaderData + 0);
pMetadata->data.smpl.productId = ma_dr_wav_bytes_to_u32(smplHeaderData + 4);
@ -80513,7 +80543,7 @@ MA_PRIVATE ma_uint64 ma_dr_wav__read_smpl_to_metadata_obj(ma_dr_wav__metadata_pa
pMetadata->data.smpl.smpteOffset = ma_dr_wav_bytes_to_u32(smplHeaderData + 24);
pMetadata->data.smpl.sampleLoopCount = ma_dr_wav_bytes_to_u32(smplHeaderData + 28);
pMetadata->data.smpl.samplerSpecificDataSizeInBytes = ma_dr_wav_bytes_to_u32(smplHeaderData + 32);
if (pMetadata->data.smpl.sampleLoopCount == (pChunkHeader->sizeInBytes - MA_DR_WAV_SMPL_BYTES) / MA_DR_WAV_SMPL_LOOP_BYTES) {
if (pMetadata->data.smpl.sampleLoopCount == calculatedLoopCount) {
pMetadata->data.smpl.pLoops = (ma_dr_wav_smpl_loop*)ma_dr_wav__metadata_get_memory(pParser, sizeof(ma_dr_wav_smpl_loop) * pMetadata->data.smpl.sampleLoopCount, MA_DR_WAV_METADATA_ALIGNMENT);
for (iSampleLoop = 0; iSampleLoop < pMetadata->data.smpl.sampleLoopCount; ++iSampleLoop) {
ma_uint8 smplLoopData[MA_DR_WAV_SMPL_LOOP_BYTES];
@ -80534,6 +80564,8 @@ MA_PRIVATE ma_uint64 ma_dr_wav__read_smpl_to_metadata_obj(ma_dr_wav__metadata_pa
MA_DR_WAV_ASSERT(pMetadata->data.smpl.pSamplerSpecificData != NULL);
ma_dr_wav__metadata_parser_read(pParser, pMetadata->data.smpl.pSamplerSpecificData, pMetadata->data.smpl.samplerSpecificDataSizeInBytes, &totalBytesRead);
}
} else {
MA_DR_WAV_ZERO_OBJECT(&pMetadata->data.smpl);
}
}
return totalBytesRead;
@ -83149,19 +83181,13 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_
newSample0 = ((pWav->msadpcm.prevFrames[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevFrames[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8;
newSample0 += nibble0 * pWav->msadpcm.delta[0];
newSample0 = ma_dr_wav_clamp(newSample0, -32768, 32767);
pWav->msadpcm.delta[0] = (adaptationTable[((nibbles & 0xF0) >> 4)] * pWav->msadpcm.delta[0]) >> 8;
if (pWav->msadpcm.delta[0] < 16) {
pWav->msadpcm.delta[0] = 16;
}
pWav->msadpcm.delta[0] = (ma_int32)ma_dr_wav_clamp(((ma_int64)adaptationTable[((nibbles & 0xF0) >> 4)] * pWav->msadpcm.delta[0]) >> 8, 16, 0x7FFFFFFF);
pWav->msadpcm.prevFrames[0][0] = pWav->msadpcm.prevFrames[0][1];
pWav->msadpcm.prevFrames[0][1] = newSample0;
newSample1 = ((pWav->msadpcm.prevFrames[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevFrames[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8;
newSample1 += nibble1 * pWav->msadpcm.delta[0];
newSample1 = ma_dr_wav_clamp(newSample1, -32768, 32767);
pWav->msadpcm.delta[0] = (adaptationTable[((nibbles & 0x0F) >> 0)] * pWav->msadpcm.delta[0]) >> 8;
if (pWav->msadpcm.delta[0] < 16) {
pWav->msadpcm.delta[0] = 16;
}
pWav->msadpcm.delta[0] = (ma_int32)ma_dr_wav_clamp(((ma_int64)adaptationTable[((nibbles & 0x0F) >> 0)] * pWav->msadpcm.delta[0]) >> 8, 16, 0x7FFFFFFF);
pWav->msadpcm.prevFrames[0][0] = pWav->msadpcm.prevFrames[0][1];
pWav->msadpcm.prevFrames[0][1] = newSample1;
pWav->msadpcm.cachedFrames[2] = newSample0;
@ -83176,10 +83202,7 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_
newSample0 = ((pWav->msadpcm.prevFrames[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevFrames[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8;
newSample0 += nibble0 * pWav->msadpcm.delta[0];
newSample0 = ma_dr_wav_clamp(newSample0, -32768, 32767);
pWav->msadpcm.delta[0] = (adaptationTable[((nibbles & 0xF0) >> 4)] * pWav->msadpcm.delta[0]) >> 8;
if (pWav->msadpcm.delta[0] < 16) {
pWav->msadpcm.delta[0] = 16;
}
pWav->msadpcm.delta[0] = (ma_int32)ma_dr_wav_clamp(((ma_int64)adaptationTable[((nibbles & 0xF0) >> 4)] * pWav->msadpcm.delta[0]) >> 8, 16, 0x7FFFFFFF);
pWav->msadpcm.prevFrames[0][0] = pWav->msadpcm.prevFrames[0][1];
pWav->msadpcm.prevFrames[0][1] = newSample0;
if (pWav->msadpcm.predictor[1] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[1] >= ma_dr_wav_countof(coeff2Table)) {
@ -83188,10 +83211,7 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_
newSample1 = ((pWav->msadpcm.prevFrames[1][1] * coeff1Table[pWav->msadpcm.predictor[1]]) + (pWav->msadpcm.prevFrames[1][0] * coeff2Table[pWav->msadpcm.predictor[1]])) >> 8;
newSample1 += nibble1 * pWav->msadpcm.delta[1];
newSample1 = ma_dr_wav_clamp(newSample1, -32768, 32767);
pWav->msadpcm.delta[1] = (adaptationTable[((nibbles & 0x0F) >> 0)] * pWav->msadpcm.delta[1]) >> 8;
if (pWav->msadpcm.delta[1] < 16) {
pWav->msadpcm.delta[1] = 16;
}
pWav->msadpcm.delta[1] = (ma_int32)ma_dr_wav_clamp(((ma_int64)adaptationTable[((nibbles & 0x0F) >> 0)] * pWav->msadpcm.delta[1]) >> 8, 16, 0x7FFFFFFF);
pWav->msadpcm.prevFrames[1][0] = pWav->msadpcm.prevFrames[1][1];
pWav->msadpcm.prevFrames[1][1] = newSample1;
pWav->msadpcm.cachedFrames[2] = newSample0;
@ -95825,7 +95845,7 @@ For more information, please refer to <http://unlicense.org/>
===============================================================================
ALTERNATIVE 2 - MIT No Attribution
===============================================================================
Copyright 2025 David Reid
Copyright 2026 David Reid
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/**********************************************************************************************
*
* rprand v1.0 - A simple and easy-to-use pseudo-random numbers generator (PRNG)
* rprand v1.1 - A simple and easy-to-use pseudo-random numbers generator (PRNG)
*
* FEATURES:
* - Pseudo-random values generation, 32 bits: [0..4294967295]
@ -118,6 +118,7 @@ extern "C" { // Prevents name mangling of functions
//----------------------------------------------------------------------------------
RPRANDAPI void rprand_set_seed(unsigned long long seed); // Set rprand_state for Xoshiro128**, seed is 64bit
RPRANDAPI int rprand_get_value(int min, int max); // Get random value within a range, min and max included
RPRANDAPI int rprand_get_value_raw(void); // Get random value, Xoshiro128** generator (uses global rprand_state)
RPRANDAPI int *rprand_load_sequence(unsigned int count, int min, int max); // Load pseudo-random numbers sequence with no duplicates
RPRANDAPI void rprand_unload_sequence(int *sequence); // Unload pseudo-random numbers sequence
@ -186,6 +187,13 @@ int rprand_get_value(int min, int max)
return value;
}
int rprand_get_value_raw(void)
{
int value = rprand_xoshiro();
return value;
}
// Load pseudo-random numbers sequence with no duplicates, min and max included
int *rprand_load_sequence(unsigned int count, int min, int max)
{

View file

@ -1020,7 +1020,12 @@ static int parseLine(Command *command, const char *p, unsigned int p_len,
int triangulate) {
char linebuf[4096];
const char *token;
assert(p_len < 4095);
// @raysan5:
// WARNING: If -DNDEBUG is set when compiling, assertions will not
// be present in the compiled binary, replacing by a runtime check
//assert(p_len < 4095);
if (p_len > 4095) return 0;
memcpy(linebuf, p, p_len);
linebuf[p_len] = '\0';
@ -1102,8 +1107,12 @@ static int parseLine(Command *command, const char *p, unsigned int p_len,
tinyobj_vertex_index_t i1;
tinyobj_vertex_index_t i2 = f[1];
assert(3 * num_f < TINYOBJ_MAX_FACES_PER_F_LINE);
// @raysan5:
// WARNING: If -DNDEBUG is set when compiling, assertions will not
// be present in the compiled binary, replacing by a runtime check
//assert(3 * num_f < TINYOBJ_MAX_FACES_PER_F_LINE);
if (3*num_f > TINYOBJ_MAX_FACES_PER_F_LINE) return 0;
for (k = 2; k < num_f; k++) {
i1 = i2;
i2 = f[k];
@ -1119,7 +1128,13 @@ static int parseLine(Command *command, const char *p, unsigned int p_len,
} else {
unsigned int k = 0;
assert(num_f < TINYOBJ_MAX_FACES_PER_F_LINE);
// @raysan5:
// WARNING: If -DNDEBUG is set when compiling, assertions will not
// be present in the compiled binary, replacing by a runtime check
//assert(num_f < TINYOBJ_MAX_FACES_PER_F_LINE);
if (num_f > TINYOBJ_MAX_FACES_PER_F_LINE) return 0;
for (k = 0; k < num_f; k++) {
command->f[k] = f[k];
}

View file

@ -4,14 +4,14 @@
#ifndef WIN32_CLIPBOARD_
#define WIN32_CLIPBOARD_
unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long long int *dataSize);
unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned int *dataSize);
#endif // WIN32_CLIPBOARD_
#ifdef WIN32_CLIPBOARD_IMPLEMENTATION
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
// NOTE: These search for architecture is taken from "windows.h", and it's necessary to avoid including windows.h
// and still make it compile on msvc, because import indirectly importing "winnt.h" (e.g. <minwindef.h>) can cause problems is these are not defined
@ -213,7 +213,7 @@ static int GetPixelDataOffset(BITMAPINFOHEADER bih); // Get pixel data offset fr
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long long int *dataSize)
unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned int *dataSize)
{
unsigned char *bmpData = NULL;
@ -228,7 +228,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long
*width = bmpInfoHeader->biWidth;
*height = bmpInfoHeader->biHeight;
SIZE_T clipDataSize = GlobalSize(clipHandle);
if (clipDataSize >= sizeof(BITMAPINFOHEADER))
if ((clipDataSize >= sizeof(BITMAPINFOHEADER)) && (clipDataSize < INT_MAX))
{
int pixelOffset = GetPixelDataOffset(*bmpInfoHeader);
@ -236,7 +236,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long
//------------------------------------------------------------------------
BITMAPFILEHEADER bmpFileHeader = { 0 };
SIZE_T bmpFileSize = sizeof(bmpFileHeader) + clipDataSize;
*dataSize = bmpFileSize;
*dataSize = (unsigned int)bmpFileSize;
bmpFileHeader.bfType = 0x4D42; // BMP fil type constant
bmpFileHeader.bfSize = (DWORD)bmpFileSize; // Up to 4GB works fine
@ -254,7 +254,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long
}
else
{
TRACELOG(LOG_WARNING, "Clipboard data is malformed");
TRACELOG(LOG_WARNING, "Clipboard data is not supported (>2GB?)");
GlobalUnlock(clipHandle);
CloseClipboard();
}

View file

@ -473,8 +473,7 @@ void SetWindowFocused(void)
// Get native window handle
void *GetWindowHandle(void)
{
TRACELOG(LOG_WARNING, "GetWindowHandle() not implemented on target platform");
return NULL;
return (void *)platform.app->window; // Type: ANativeWindow*
}
// Get number of monitors
@ -616,13 +615,13 @@ void ShowCursor(void)
CORE.Input.Mouse.cursorHidden = false;
}
// Hides mouse cursor
// Hide mouse cursor
void HideCursor(void)
{
CORE.Input.Mouse.cursorHidden = true;
}
// Enables cursor (unlock cursor)
// Enable cursor (unlock cursor)
void EnableCursor(void)
{
// Set cursor position in the middle
@ -656,21 +655,30 @@ double GetTime(void)
double time = 0.0;
struct timespec ts = { 0 };
clock_gettime(CLOCK_MONOTONIC, &ts);
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
unsigned long long nanoSeconds = (unsigned long long)ts.tv_sec*1000000000LLU + (unsigned long long)ts.tv_nsec;
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
return time;
}
// Open URL with default system browser (if available)
// NOTE: This function is only safe to use if the provided URL is safe
// A user could craft a malicious string performing another action
// Avoid calling this function with user input non-validated strings
// WARNING: This function is only safe to use if you control the URL given,
// a user could craft a malicious string to perform and undesired action
// NOTE: Some safety checks have been added to mitigate security issues
void OpenURL(const char *url)
{
// Security check to (partially) avoid malicious code
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
if ((strchr(url, '\'') != NULL) || (strchr(url, '\"') != NULL))
{
// Filter characters: ' and "
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'\"] characters");
}
else if ((strncmp(url, "http://", 7) != 0) && (strncmp(url, "https://", 8) != 0))
{
// Only allow URL starting with "http://" or "https://" protocols
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols");
}
else
{
JNIEnv *env = NULL;
@ -718,7 +726,6 @@ void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float d
void SetMousePosition(int x, int y)
{
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
}
// Set mouse cursor
@ -750,12 +757,12 @@ void PollInputEvents(void)
for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
// Reset last gamepad button/axis registered state
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
//CORE.Input.Gamepad.axisCount = 0;
for (int i = 0; i < MAX_GAMEPADS; i++)
{
if (CORE.Input.Gamepad.ready[i]) // Check if gamepad is available
if (CORE.Input.Gamepad.ready[i]) // Check if gamepad is available
{
// Register previous gamepad states
for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++)
@ -794,6 +801,7 @@ void PollInputEvents(void)
if (platform.app->destroyRequested != 0)
{
CORE.Window.shouldClose = true;
break;
}
}
}
@ -1273,27 +1281,28 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
int32_t keycode = AKeyEvent_getKeyCode(event);
//int32_t AKeyEvent_getMetaState(event);
// Handle gamepad button presses and releases
// NOTE: Skip gamepad handling if this is a keyboard event, as some devices
// report both AINPUT_SOURCE_KEYBOARD and AINPUT_SOURCE_GAMEPAD flags
if ((FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) ||
FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) &&
!FLAG_IS_SET(source, AINPUT_SOURCE_KEYBOARD))
// Handle gamepad button presses and releases. AOSP stamps the
// KEYBOARD source bit on every key event from a gamepad, so
// discriminate on the keycode rather than gating on source bits.
if (FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) ||
FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD))
{
// Assuming a single gamepad, "detected" on its input event
CORE.Input.Gamepad.ready[0] = true;
GamepadButton button = AndroidTranslateGamepadButton(keycode);
if (button == GAMEPAD_BUTTON_UNKNOWN) return 1;
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
if (button != GAMEPAD_BUTTON_UNKNOWN)
{
CORE.Input.Gamepad.currentButtonState[0][button] = 1;
}
else CORE.Input.Gamepad.currentButtonState[0][button] = 0; // Key up
// Assuming a single gamepad, "detected" on its input event
CORE.Input.Gamepad.ready[0] = true;
return 1; // Handled gamepad button
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
{
CORE.Input.Gamepad.currentButtonState[0][button] = 1;
}
else CORE.Input.Gamepad.currentButtonState[0][button] = 0; // Key up
return 1; // Handled gamepad button
}
// Unknown keycode: fall through to the keyboard handler below.
}
KeyboardKey key = ((keycode > 0) && (keycode < KEYCODE_MAP_SIZE))? mapKeycode[keycode] : KEY_NULL;

View file

@ -111,6 +111,12 @@
//----------------------------------------------------------------------------------
typedef struct {
GLFWwindow *handle; // GLFW window handle (graphic device)
#if defined(__linux__) && defined(_GLFW_X11)
// Local storage for the window handle returned by glfwGetX11Window
// This is needed as X11 handles are integers and may not fit inside a pointer depending on platform
// Storing the handle locally and returning a pointer in GetWindowHandle allows the code to work regardless of pointer width
Window windowHandleX11; // Underlying type: unsigned long (XID, Window)
#endif
} PlatformData;
//----------------------------------------------------------------------------------
@ -145,7 +151,7 @@ static void CharCallback(GLFWwindow *window, unsigned int codepoint);
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods); // GLFW3 Mouse Button Callback, runs on mouse button pressed
static void MouseCursorPosCallback(GLFWwindow *window, double x, double y); // GLFW3 Cursor Position Callback, runs on mouse move
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Scrolling Callback, runs on mouse wheel
static void CursorEnterCallback(GLFWwindow *window, int enter); // GLFW3 Cursor Enter Callback, cursor enters client area
static void CursorEnterCallback(GLFWwindow *window, int entered); // GLFW3 Cursor Enter Callback, cursor enters client area
static void JoystickCallback(int jid, int event); // GLFW3 Joystick Connected/Disconnected Callback
// Memory allocator wrappers [used by glfwInitAllocator()]
@ -281,8 +287,14 @@ void ToggleBorderlessWindowed(void)
CORE.Window.screen.height = mode->height;
// Set screen position and size
#if defined(_WIN32)
// NOTE: To prevent the fullscreen window from always staying on top, don't pass a monitor at this point.
glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y,
CORE.Window.screen.width, CORE.Window.screen.height, mode->refreshRate);
#else
glfwSetWindowMonitor(platform.handle, monitors[monitor], CORE.Window.position.x, CORE.Window.position.y,
CORE.Window.screen.width, CORE.Window.screen.height, mode->refreshRate);
#endif
// Refocus window
glfwFocusWindow(platform.handle);
@ -755,18 +767,13 @@ void SetWindowFocused(void)
glfwFocusWindow(platform.handle);
}
#if defined(__linux__) && defined(_GLFW_X11)
// Local storage for the window handle returned by glfwGetX11Window
// This is needed as X11 handles are integers and may not fit inside a pointer depending on platform
// Storing the handle locally and returning a pointer in GetWindowHandle allows the code to work regardless of pointer width
static XID X11WindowHandle;
#endif
// Get native window handle
void *GetWindowHandle(void)
{
void *handle = NULL;
#if defined(_WIN32)
// NOTE: Returned handle is: void *HWND (windows.h)
return glfwGetWin32Window(platform.handle);
handle = glfwGetWin32Window(platform.handle); // Type: HWND
#endif
#if defined(__linux__)
#if defined(_GLFW_WAYLAND)
@ -774,29 +781,27 @@ void *GetWindowHandle(void)
int platformID = glfwGetPlatform();
if (platformID == GLFW_PLATFORM_WAYLAND)
{
return glfwGetWaylandWindow(platform.handle);
handle = (void *)glfwGetWaylandWindow(platform.handle); // Type: struct wl_surface*
}
else
{
X11WindowHandle = glfwGetX11Window(platform.handle);
return &X11WindowHandle;
platform.windowHandleX11 = glfwGetX11Window(platform.handle); // Type: Window (unsigned long)
handle = &platform.windowHandleX11;
}
#else
return glfwGetWaylandWindow(platform.handle);
handle = (void *)glfwGetWaylandWindow(platform.handle);
#endif
#elif defined(_GLFW_X11)
// Store the window handle localy and return a pointer to the variable instead
// Reasoning detailed in the declaration of X11WindowHandle
X11WindowHandle = glfwGetX11Window(platform.handle);
return &X11WindowHandle;
// Store the window handle locally and return a pointer to the variable instead
platform.windowHandleX11 = glfwGetX11Window(platform.handle);
handle = &platform.windowHandleX11;
#endif
#endif
#if defined(__APPLE__)
// NOTE: Returned handle is: (objc_object *)
return (void *)glfwGetCocoaWindow(platform.handle);
handle = (void *)glfwGetCocoaWindow(platform.handle); // Type: NSWindow*
#endif
return NULL;
return handle;
}
// Get number of monitors
@ -840,7 +845,7 @@ int GetCurrentMonitor(void)
// this is probably an overengineered solution for a side case
// trying to match SDL behaviour
int closestDist = 0x7FFFFFFF;
unsigned int closestDist = 0xFFFFFFFFu;
// Window center position
int wcx = 0;
@ -884,7 +889,14 @@ int GetCurrentMonitor(void)
int dx = wcx - xclosest;
int dy = wcy - yclosest;
int dist = (dx*dx) + (dy*dy);
// Unsigned to dodge signed overflow UB; (-x)^2 == x^2 mod 2^32 so sign drops out.
// If |dx| or |dy| >= 65536, dist wraps and the wrong monitor may win.
// Not a concern for realistic monitor layouts.
unsigned int ux = (unsigned int)dx;
unsigned int uy = (unsigned int)dy;
unsigned int dist = ux*ux + uy*uy;
if (dist < closestDist)
{
index = i;
@ -1018,6 +1030,8 @@ const char *GetMonitorName(int monitor)
// Get window position XY on monitor
Vector2 GetWindowPosition(void)
{
glfwGetWindowPos(platform.handle, &CORE.Window.position.x, &CORE.Window.position.y);
return (Vector2){ (float)CORE.Window.position.x, (float)CORE.Window.position.y };
}
@ -1043,11 +1057,6 @@ const char *GetClipboardText(void)
return glfwGetClipboardString(platform.handle);
}
#if SUPPORT_CLIPBOARD_IMAGE && defined(__linux__) && defined(_GLFW_X11)
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#endif
// Get clipboard image
Image GetClipboardImage(void)
{
@ -1055,43 +1064,47 @@ Image GetClipboardImage(void)
#if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES
#if defined(_WIN32)
unsigned long long int dataSize = 0;
unsigned int dataSize = 0;
void *bmpData = NULL;
int width = 0;
int height = 0;
bmpData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize);
bmpData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize);
if (bmpData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data.");
else image = LoadImageFromMemory(".bmp", (const unsigned char *)bmpData, (int)dataSize);
else
{
image = LoadImageFromMemory(".bmp", (const unsigned char *)bmpData, (int)dataSize);
RL_FREE(bmpData);
}
#elif defined(__linux__) && defined(_GLFW_X11)
// REF: https://github.com/ColleagueRiley/Clipboard-Copy-Paste/blob/main/x11.c
Display *dpy = XOpenDisplay(NULL);
if (!dpy) return image;
Window root = DefaultRootWindow(dpy);
Window win = XCreateSimpleWindow(
dpy, // The connection to the X Server
root, // The 'Parent' window (usually the desktop/root)
0, 0, // X and Y position on the screen
1, 1, // Width and Height (1x1 pixel)
0, // Border width
0, // Border color
0 // Background color
);
static Atom clipboard = 0;
static Atom targetType = 0;
static Atom property = 0;
Atom clipboard = XInternAtom(dpy, "CLIPBOARD", False);
Atom targetType = XInternAtom(dpy, "image/png", False); // Ask for PNG
Atom property = XInternAtom(dpy, "RAYLIB_CLIPBOARD_MANAGER", False);
Display *display = glfwGetX11Display();
XID window = glfwGetX11Window(platform.handle);
// Request the data: "Convert whatever is in CLIPBOARD to image/png and put it in RAYLIB_CLIPBOARD_MANAGER"
XConvertSelection(dpy, clipboard, targetType, property, win, CurrentTime);
// Lazy-load X11 atoms
if (clipboard == 0)
{
clipboard = XInternAtom(display, "CLIPBOARD", False);
targetType = XInternAtom(display, "image/png", False);
property = XInternAtom(display, "RAYLIB_CLIPBOARD_MANAGER", False);
}
XConvertSelection(display, clipboard, targetType, property, window, CurrentTime);
XSync(display, 0);
// Wait for the SelectionNotify event
XEvent ev = { 0 };
XNextEvent(dpy, &ev);
// Keep calling until we get SelectionNotify
while (XCheckTypedEvent(display, SelectionNotify, &ev) == False);
Atom actualType = { 0 };
int actualFormat = 0;
@ -1099,9 +1112,8 @@ Image GetClipboardImage(void)
unsigned long bytesAfter = 0;
unsigned char *data = NULL;
// Read the data from our ghost window's property
XGetWindowProperty(dpy, win, property, 0, ~0L, False, AnyPropertyType,
&actualType, &actualFormat, &nitems, &bytesAfter, &data);
XGetWindowProperty(display, window, property, 0, ~0L, False, AnyPropertyType,
&actualType, &actualFormat, &nitems, &bytesAfter, &data);
if (data != NULL)
{
@ -1109,11 +1121,9 @@ Image GetClipboardImage(void)
XFree(data);
}
XDestroyWindow(dpy, win);
XCloseDisplay(dpy);
#else
TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform");
#endif // defined(_WIN32)
#endif // _WIN32
#else
TRACELOG(LOG_WARNING, "Clipboard image: SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_MODULE_RTEXTURES to work properly");
#endif // SUPPORT_CLIPBOARD_IMAGE
@ -1129,7 +1139,7 @@ void ShowCursor(void)
CORE.Input.Mouse.cursorHidden = false;
}
// Hides mouse cursor
// Hide mouse cursor
void HideCursor(void)
{
glfwSetInputMode(platform.handle, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
@ -1137,7 +1147,7 @@ void HideCursor(void)
CORE.Input.Mouse.cursorHidden = true;
}
// Enables cursor (unlock cursor)
// Enable cursor (unlock cursor)
void EnableCursor(void)
{
glfwSetInputMode(platform.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
@ -1151,7 +1161,7 @@ void EnableCursor(void)
CORE.Input.Mouse.cursorLocked = false;
}
// Disables cursor (lock cursor)
// Disable cursor (lock cursor)
void DisableCursor(void)
{
// Reset mouse position within the window area before disabling cursor
@ -1184,17 +1194,25 @@ double GetTime(void)
}
// Open URL with default system browser (if available)
// NOTE: This function is only safe to use if you control the URL given
// A user could craft a malicious string performing another action
// Only call this function yourself not with user input or make sure to check the string yourself
// REF: https://github.com/raysan5/raylib/issues/686
// WARNING: This function is only safe to use if you control the URL given,
// a user could craft a malicious string to perform and undesired action
// NOTE: Some safety checks have been added to mitigate security issues
void OpenURL(const char *url)
{
// Security check to (partially) avoid malicious code
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
if ((strchr(url, '\'') != NULL) || (strchr(url, '\"') != NULL))
{
// Filter characters: ' and "
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'\"] characters");
}
else if ((strncmp(url, "http://", 7) != 0) && (strncmp(url, "https://", 8) != 0))
{
// Only allow URL starting with "http://" or "https://" protocols
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols");
}
else
{
char *cmd = (char *)RL_CALLOC(strlen(url) + 32, sizeof(char));
char *cmd = (char *)RL_CALLOC(strlen(url) + 16, sizeof(char));
#if defined(_WIN32)
sprintf(cmd, "explorer \"%s\"", url);
#endif
@ -1204,7 +1222,9 @@ void OpenURL(const char *url)
#if defined(__APPLE__)
sprintf(cmd, "open '%s'", url);
#endif
// TODO: Replace system() call by custom process
int result = system(cmd);
if (result == -1) TRACELOG(LOG_WARNING, "OpenURL() child process could not be created");
RL_FREE(cmd);
}
@ -1230,7 +1250,6 @@ void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float d
void SetMousePosition(int x, int y)
{
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
// NOTE: emscripten not implemented
glfwSetCursorPos(platform.handle, CORE.Input.Mouse.currentPosition.x, CORE.Input.Mouse.currentPosition.y);
@ -1319,7 +1338,7 @@ void PollInputEvents(void)
// Register previous gamepad states
for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k];
// Get current gamepad state
// Get current gamepad state using internal GLFW mapping, instead of the immediate joystick API
// NOTE: There is no callback available, getting it manually
GLFWgamepadstate state = { 0 };
int result = glfwGetGamepadState(i, &state); // This remaps all gamepads so they have their buttons mapped like an xbox controller
@ -1334,7 +1353,7 @@ void PollInputEvents(void)
for (int k = 0; (buttons != NULL) && (k < MAX_GAMEPAD_BUTTONS); k++)
{
int button = -1; // GamepadButton enum values assigned
int button = -1; // GamepadButton enum values assigned
switch (k)
{
@ -1360,7 +1379,7 @@ void PollInputEvents(void)
default: break;
}
if (button != -1) // Check for valid button
if (button != -1) // Check for valid button
{
if (buttons[k] == GLFW_PRESS)
{
@ -1402,10 +1421,10 @@ void PollInputEvents(void)
if ((CORE.Window.eventWaiting) ||
(FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED) && !FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN)))
{
glfwWaitEvents(); // Wait for in input events before continue (drawing is paused)
glfwWaitEvents(); // Wait for in input events before continue (drawing is paused)
CORE.Time.previous = GetTime();
}
else glfwPollEvents(); // Poll input events: keyboard/mouse/window events (callbacks) -> Update keys state
else glfwPollEvents(); // Poll input events: keyboard/mouse/window events (callbacks) -> Update keys state
CORE.Window.shouldClose = glfwWindowShouldClose(platform.handle);
@ -1686,6 +1705,14 @@ int InitPlatform(void)
return -1;
}
#if defined(__APPLE__)
// AppKit can constrain the requested window size to the visible work area during creation
int windowWidth = 0;
int windowHeight = 0;
glfwGetWindowSize(platform.handle, &windowWidth, &windowHeight);
if ((windowWidth > 0) && (windowHeight > 0)) CORE.Window.screen = (Size){ windowWidth, windowHeight };
#endif
// NOTE: Not considering scale factor now, considered below
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height;
@ -1832,7 +1859,7 @@ int InitPlatform(void)
{
CORE.Input.Gamepad.ready[i] = true;
CORE.Input.Gamepad.axisCount[i] = GLFW_GAMEPAD_AXIS_LAST + 1;
strncpy(CORE.Input.Gamepad.name[i], glfwGetJoystickName(i), MAX_GAMEPAD_NAME_LENGTH - 1);
snprintf(CORE.Input.Gamepad.name[i], MAX_GAMEPAD_NAME_LENGTH, "%s", glfwGetJoystickName(i));
}
}
//----------------------------------------------------------------------------
@ -2047,7 +2074,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++)
{
CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
strncpy(CORE.Window.dropFilepaths[i], paths[i], MAX_FILEPATH_LENGTH - 1);
snprintf(CORE.Window.dropFilepaths[i], MAX_FILEPATH_LENGTH, "%s", paths[i]);
}
}
}
@ -2170,10 +2197,18 @@ static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffs
}
// GLFW3: Cursor ennter callback, when cursor enters the window
static void CursorEnterCallback(GLFWwindow *window, int enter)
static void CursorEnterCallback(GLFWwindow *window, int entered)
{
if (enter) CORE.Input.Mouse.cursorOnScreen = true;
else CORE.Input.Mouse.cursorOnScreen = false;
if (entered)
{
// NOTE: Mouse position updated by MouseCursorPosCallback()
CORE.Input.Mouse.cursorOnScreen = true;
}
else
{
CORE.Input.Mouse.cursorOnScreen = false;
CORE.Input.Mouse.currentPosition = (Vector2){ 0 };
}
}
// GLFW3: Joystick connected/disconnected callback
@ -2186,7 +2221,7 @@ static void JoystickCallback(int jid, int event)
// WARNING: If glfwGetJoystickName() is longer than MAX_GAMEPAD_NAME_LENGTH,
// only copy up to (MAX_GAMEPAD_NAME_LENGTH -1) to destination string
memset(CORE.Input.Gamepad.name[jid], 0, MAX_GAMEPAD_NAME_LENGTH);
strncpy(CORE.Input.Gamepad.name[jid], glfwGetJoystickName(jid), MAX_GAMEPAD_NAME_LENGTH - 1);
snprintf(CORE.Input.Gamepad.name[jid], MAX_GAMEPAD_NAME_LENGTH, "%s", glfwGetJoystickName(jid));
}
else if (event == GLFW_DISCONNECTED)
{

File diff suppressed because it is too large Load diff

View file

@ -56,6 +56,13 @@
#include "SDL3/SDL.h"
#elif defined(USING_SDL2_PROJECT)
#include "SDL2/SDL.h"
// WARNING: On Linux, this header includes Xlib.h, which defines Font
// To prevent a conflict with raylib's own Font type, we temporarily
// rename it to FontX11
#define Font FontX11
#include "SDL2/SDL_syswm.h" // Required to get window handlers
#undef Font
#else
#include "SDL.h"
#endif
@ -101,6 +108,13 @@ typedef struct {
SDL_GameController *gamepad[MAX_GAMEPADS];
SDL_JoystickID gamepadId[MAX_GAMEPADS]; // Joystick instance ids, they do not start from 0
SDL_Cursor *cursor;
#if defined(__linux__)
// Local storage for the window handle (X11)
// NOTE: On SDL is not possible to know windowing backend at compile time, so,
// just in case, avoiding X11 specific types here
unsigned long windowHandleX11; // Underlying type for: XID, Window
#endif
} PlatformData;
//----------------------------------------------------------------------------------
@ -456,12 +470,11 @@ bool WindowShouldClose(void)
void ToggleFullscreen(void)
{
const int monitor = SDL_GetWindowDisplayIndex(platform.window);
const int monitorCount = SDL_GetNumVideoDisplays();
#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid
#else
if ((monitor >= 0) && (monitor < monitorCount))
if ((monitor >= 0) && (monitor < SDL_GetNumVideoDisplays()))
#endif
{
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
@ -482,12 +495,11 @@ void ToggleFullscreen(void)
void ToggleBorderlessWindowed(void)
{
const int monitor = SDL_GetWindowDisplayIndex(platform.window);
const int monitorCount = SDL_GetNumVideoDisplays();
#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid
#else
if ((monitor >= 0) && (monitor < monitorCount))
if ((monitor >= 0) && (monitor < SDL_GetNumVideoDisplays()))
#endif
{
if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE))
@ -539,12 +551,11 @@ void SetWindowState(unsigned int flags)
if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE))
{
const int monitor = SDL_GetWindowDisplayIndex(platform.window);
const int monitorCount = SDL_GetNumVideoDisplays();
#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid
#else
if ((monitor >= 0) && (monitor < monitorCount))
if ((monitor >= 0) && (monitor < SDL_GetNumVideoDisplays()))
#endif
{
SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN);
@ -601,12 +612,11 @@ void SetWindowState(unsigned int flags)
if (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE))
{
const int monitor = SDL_GetWindowDisplayIndex(platform.window);
const int monitorCount = SDL_GetNumVideoDisplays();
#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid
#else
if ((monitor >= 0) && (monitor < monitorCount))
if ((monitor >= 0) && (monitor < SDL_GetNumVideoDisplays()))
#endif
{
SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN_DESKTOP);
@ -823,11 +833,10 @@ void SetWindowPosition(int x, int y)
// Set monitor for the current window
void SetWindowMonitor(int monitor)
{
const int monitorCount = SDL_GetNumVideoDisplays();
#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid
#else
if ((monitor >= 0) && (monitor < monitorCount))
if ((monitor >= 0) && (monitor < SDL_GetNumVideoDisplays()))
#endif
{
// NOTE 1: SDL started supporting moving exclusive fullscreen windows between displays on SDL3,
@ -855,7 +864,7 @@ void SetWindowMonitor(int monitor)
// ending up positioned partly outside the target display
// NOTE 2: The workaround for that is, previously to moving the window,
// setting the window size to the target display size, so they match
// NOTE 3: It wasn't done here because it can not bee assumed that changing
// NOTE 3: It wasn't done here because it can not be assumed that changing
// the window size automatically is acceptable behavior by the user
SDL_SetWindowPosition(platform.window, usableBounds.x, usableBounds.y);
CORE.Window.position.x = usableBounds.x;
@ -920,40 +929,82 @@ void SetWindowFocused(void)
}
// Get native window handle
// NOTE: Handle type depends on OS and windowing system
void *GetWindowHandle(void)
{
return (void *)platform.window;
void *handle = NULL;
#if defined(USING_SDL3_PROJECT)
// REF: https://github.com/libsdl-org/SDL/blob/main/include/SDL3/SDL_video.h#L1590
SDL_PropertiesID props = SDL_GetWindowProperties(platform.window);
#if defined(_WIN32)
handle = (void *)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); // Type: HWND
#elif defined(__linux__)
unsigned long windowId = (unsigned long)SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); // Type: unsigned long (XID, Window)
if (windowId != 0)
{
// X11 window ID
platform.windowHandleX11 = windowId;
handle = &platform.windowHandleX11;
}
else
{
// Wayland, get display surface pointer
// NOTE: Alternative SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER
handle = (void *)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, NULL); // Type: struct wl_surface*
}
#elif defined(__APPLE__)
handle = (void *)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL); // Type: NSWindow*
#endif
#elif defined(USING_SDL2_PROJECT)
SDL_SysWMinfo wmInfo = { 0 };
SDL_VERSION(&wmInfo.version);
if (SDL_GetWindowWMInfo(platform.window, &wmInfo))
{
#if defined(_WIN32)
handle = (void *)wmInfo.info.win.window; // Type: HWND
#elif defined(__linux__)
if (wmInfo.subsystem == SDL_SYSWM_X11)
{
// X11, get window ID (unsigned long)
platform.windowHandleX11 = (unsigned long)wmInfo.info.x11.window;
handle = &platform.windowHandleX11;
}
else if (wmInfo.subsystem == SDL_SYSWM_WAYLAND)
{
// Wayland, get display surface pointer
// NOTE: Alternative: wmInfo.info.wl.display
handle = (void *)wmInfo.info.wl.surface; // Type: struct wl_surface*
}
#elif defined(__APPLE__)
handle = (void *)wmInfo.info.cocoa.window; // Type: NSWindow*
#endif
}
#endif
return handle;
}
// Get number of monitors
int GetMonitorCount(void)
{
int monitorCount = 0;
monitorCount = SDL_GetNumVideoDisplays();
return monitorCount;
return SDL_GetNumVideoDisplays();
}
// Get current monitor where window is placed
int GetCurrentMonitor(void)
{
int currentMonitor = 0;
// Be aware that this returns an ID in SDL3 and a Index in SDL2
currentMonitor = SDL_GetWindowDisplayIndex(platform.window);
return currentMonitor;
return SDL_GetWindowDisplayIndex(platform.window);
}
// Get selected monitor position
Vector2 GetMonitorPosition(int monitor)
{
const int monitorCount = SDL_GetNumVideoDisplays();
#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid
#else
if ((monitor >= 0) && (monitor < monitorCount))
if ((monitor >= 0) && (monitor < SDL_GetNumVideoDisplays()))
#endif
{
SDL_Rect displayBounds;
@ -977,11 +1028,10 @@ int GetMonitorWidth(int monitor)
{
int width = 0;
const int monitorCount = SDL_GetNumVideoDisplays();
#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid
#else
if ((monitor >= 0) && (monitor < monitorCount))
if ((monitor >= 0) && (monitor < SDL_GetNumVideoDisplays()))
#endif
{
SDL_DisplayMode mode;
@ -998,11 +1048,10 @@ int GetMonitorHeight(int monitor)
{
int height = 0;
const int monitorCount = SDL_GetNumVideoDisplays();
#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid
#else
if ((monitor >= 0) && (monitor < monitorCount))
if ((monitor >= 0) && (monitor < SDL_GetNumVideoDisplays()))
#endif
{
SDL_DisplayMode mode;
@ -1019,11 +1068,10 @@ int GetMonitorPhysicalWidth(int monitor)
{
int width = 0;
const int monitorCount = SDL_GetNumVideoDisplays();
#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid
#else
if ((monitor >= 0) && (monitor < monitorCount))
if ((monitor >= 0) && (monitor < SDL_GetNumVideoDisplays()))
#endif
{
float ddpi = 0.0f;
@ -1043,11 +1091,10 @@ int GetMonitorPhysicalHeight(int monitor)
{
int height = 0;
const int monitorCount = SDL_GetNumVideoDisplays();
#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid
#else
if ((monitor >= 0) && (monitor < monitorCount))
if ((monitor >= 0) && (monitor < SDL_GetNumVideoDisplays()))
#endif
{
float ddpi = 0.0f;
@ -1067,11 +1114,10 @@ int GetMonitorRefreshRate(int monitor)
{
int refresh = 0;
const int monitorCount = SDL_GetNumVideoDisplays();
#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid
#else
if ((monitor >= 0) && (monitor < monitorCount))
if ((monitor >= 0) && (monitor < SDL_GetNumVideoDisplays()))
#endif
{
SDL_DisplayMode mode;
@ -1086,12 +1132,10 @@ int GetMonitorRefreshRate(int monitor)
// Get the human-readable, UTF-8 encoded name of the selected monitor
const char *GetMonitorName(int monitor)
{
const int monitorCount = SDL_GetNumVideoDisplays();
#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid
#else
if ((monitor >= 0) && (monitor < monitorCount))
if ((monitor >= 0) && (monitor < SDL_GetNumVideoDisplays()))
#endif
{
return SDL_GetDisplayName(monitor);
@ -1144,7 +1188,7 @@ const char *GetClipboardText(void)
char *clipboard = SDL_GetClipboardText();
int clipboardSize = snprintf(buffer, sizeof(buffer), "%s", clipboard);
int clipboardSize = snprintf(buffer, MAX_CLIPBOARD_BUFFER_LENGTH, "%s", clipboard);
if (clipboardSize >= MAX_CLIPBOARD_BUFFER_LENGTH)
{
char *truncate = buffer + MAX_CLIPBOARD_BUFFER_LENGTH - 4;
@ -1196,12 +1240,14 @@ Image GetClipboardImage(void)
for (int i = 0; i < SDL_arraysize(imageFormats); i++)
{
// NOTE: This pointer should be free with SDL_free() at some point
fileData = SDL_GetClipboardData(imageFormats[i], &dataSize);
if (fileData)
{
image = LoadImageFromMemory(imageExtensions[i], fileData, (int)dataSize);
SDL_free(fileData);
if (IsImageValid(image))
{
TRACELOG(LOG_INFO, "Clipboard: Got image from clipboard successfully: %s", imageExtensions[i]);
@ -1227,7 +1273,7 @@ void ShowCursor(void)
CORE.Input.Mouse.cursorHidden = false;
}
// Hides mouse cursor
// Hide mouse cursor
void HideCursor(void)
{
#if defined(USING_VERSION_SDL3)
@ -1238,7 +1284,7 @@ void HideCursor(void)
CORE.Input.Mouse.cursorHidden = true;
}
// Enables cursor (unlock cursor)
// Enable cursor (unlock cursor)
void EnableCursor(void)
{
SDL_SetRelativeMouseMode(SDL_FALSE);
@ -1247,7 +1293,7 @@ void EnableCursor(void)
CORE.Input.Mouse.cursorLocked = false;
}
// Disables cursor (lock cursor)
// Disable cursor (lock cursor)
void DisableCursor(void)
{
SDL_SetRelativeMouseMode(SDL_TRUE);
@ -1282,14 +1328,22 @@ double GetTime(void)
}
// Open URL with default system browser (if available)
// NOTE: This function is only safe to use if the provided URL is safe
// A user could craft a malicious string performing another action
// Avoid calling this function with user input non-validated strings
// REF: https://github.com/raysan5/raylib/issues/686
// WARNING: This function is only safe to use if you control the URL given,
// a user could craft a malicious string to perform and undesired action
// NOTE: Some safety checks have been added to mitigate security issues
void OpenURL(const char *url)
{
// Security check to (partially) avoid malicious code
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
if ((strchr(url, '\'') != NULL) || (strchr(url, '\"') != NULL))
{
// Filter characters: ' and "
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'\"] characters");
}
else if ((strncmp(url, "http://", 7) != 0) && (strncmp(url, "https://", 8) != 0))
{
// Only allow URL starting with "http://" or "https://" protocols
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols");
}
else SDL_OpenURL(url);
}
@ -1342,7 +1396,6 @@ void SetMousePosition(int x, int y)
SDL_WarpMouseInWindow(platform.window, x, y);
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
}
// Set mouse cursor
@ -1453,9 +1506,9 @@ void PollInputEvents(void)
// Event memory is now managed by SDL, so it should not be freed in SDL_EVENT_DROP_FILE,
// in case data needs to be hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events,
// a copy is required, SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed
strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data, MAX_FILEPATH_LENGTH - 1);
snprintf(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], MAX_FILEPATH_LENGTH, "%s", event.drop.data);
#else
strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file, MAX_FILEPATH_LENGTH - 1);
snprintf(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], MAX_FILEPATH_LENGTH, "%s", event.drop.file);
SDL_free(event.drop.file);
#endif
@ -1466,9 +1519,9 @@ void PollInputEvents(void)
CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
#if defined(USING_VERSION_SDL3)
strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data, MAX_FILEPATH_LENGTH - 1);
snprintf(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], MAX_FILEPATH_LENGTH, "%s", event.drop.data);
#else
strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file, MAX_FILEPATH_LENGTH - 1);
snprintf(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], MAX_FILEPATH_LENGTH, "%s", event.drop.file);
SDL_free(event.drop.file);
#endif
@ -1584,7 +1637,7 @@ void PollInputEvents(void)
} break;
#endif
// Keyboard events
// Check keyboard events
case SDL_KEYDOWN:
{
#if defined(USING_VERSION_SDL3)
@ -1612,10 +1665,8 @@ void PollInputEvents(void)
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey]) CORE.Window.shouldClose = true;
} break;
case SDL_KEYUP:
{
#if defined(USING_VERSION_SDL3)
KeyboardKey key = ConvertScancodeToKey(event.key.scancode);
#else
@ -1623,7 +1674,6 @@ void PollInputEvents(void)
#endif
if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 0;
} break;
case SDL_TEXTINPUT:
{
// NOTE: event.text.text data comes an UTF-8 text sequence but register codepoints (int)
@ -1632,7 +1682,6 @@ void PollInputEvents(void)
if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE)
{
// Add character (codepoint) to the queue
#if defined(USING_VERSION_SDL3)
size_t textLen = strlen(event.text.text);
unsigned int codepoint = (unsigned int)SDL_StepUTF8(&event.text.text, &textLen);
@ -1675,8 +1724,13 @@ void PollInputEvents(void)
} break;
case SDL_MOUSEWHEEL:
{
CORE.Input.Mouse.currentWheelMove.x = (float)event.wheel.x;
CORE.Input.Mouse.currentWheelMove.y = (float)event.wheel.y;
#if defined(USING_VERSION_SDL3)
CORE.Input.Mouse.currentWheelMove.x = event.wheel.x;
CORE.Input.Mouse.currentWheelMove.y = event.wheel.y;
#else
CORE.Input.Mouse.currentWheelMove.x = event.wheel.preciseX;
CORE.Input.Mouse.currentWheelMove.y = event.wheel.preciseY;
#endif
} break;
case SDL_MOUSEMOTION:
{
@ -1696,6 +1750,7 @@ void PollInputEvents(void)
touchAction = 2;
} break;
// Check Touch events
case SDL_FINGERDOWN:
{
UpdateTouchPointsSDL(event.tfinger);
@ -1715,24 +1770,21 @@ void PollInputEvents(void)
realTouch = true;
} break;
// Check gamepad events
// Check Gamepad events
case SDL_JOYDEVICEADDED:
{
int jid = event.jdevice.which; // Joystick device index
// check if already added at InitPlatform
// Check if already added at InitPlatform
for (int i = 0; i < MAX_GAMEPADS; i++)
{
if (jid == platform.gamepadId[i])
{
return;
}
if (jid == platform.gamepadId[i]) return;
}
int nextAvailableSlot = 0;
while (nextAvailableSlot < MAX_GAMEPADS && CORE.Input.Gamepad.ready[nextAvailableSlot])
{
++nextAvailableSlot;
nextAvailableSlot++;
}
if ((nextAvailableSlot < MAX_GAMEPADS) && !CORE.Input.Gamepad.ready[nextAvailableSlot])
@ -1748,8 +1800,8 @@ void PollInputEvents(void)
CORE.Input.Gamepad.axisState[nextAvailableSlot][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
memset(CORE.Input.Gamepad.name[nextAvailableSlot], 0, MAX_GAMEPAD_NAME_LENGTH);
const char *controllerName = SDL_GameControllerNameForIndex(nextAvailableSlot);
if (controllerName != NULL) strncpy(CORE.Input.Gamepad.name[nextAvailableSlot], controllerName, MAX_GAMEPAD_NAME_LENGTH - 1);
else strncpy(CORE.Input.Gamepad.name[nextAvailableSlot], "noname", 6);
if (controllerName != NULL) snprintf(CORE.Input.Gamepad.name[nextAvailableSlot], MAX_GAMEPAD_NAME_LENGTH, "%s", controllerName);
else memcpy(CORE.Input.Gamepad.name[nextAvailableSlot], "noname", 6);
}
else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());
}
@ -2100,11 +2152,20 @@ int InitPlatform(void)
platform.gamepadId[i] = -1; // Set all gamepad initial instance ids as invalid to not conflict with instance id zero
}
#if defined(USING_VERSION_SDL3)
int numJoysticks;
SDL_JoystickID *joysticks = SDL_GetJoysticks(&numJoysticks);
#else
int numJoysticks = SDL_NumJoysticks();
#endif
for (int i = 0; (i < numJoysticks) && (i < MAX_GAMEPADS); i++)
{
#if defined(USING_VERSION_SDL3)
platform.gamepad[i] = SDL_OpenGamepad(joysticks[i]);
#else
platform.gamepad[i] = SDL_GameControllerOpen(i);
#endif
platform.gamepadId[i] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[i]));
if (platform.gamepad[i])
@ -2113,7 +2174,12 @@ int InitPlatform(void)
CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[i]));
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
strncpy(CORE.Input.Gamepad.name[i], SDL_GameControllerNameForIndex(i), MAX_GAMEPAD_NAME_LENGTH - 1);
#if defined(USING_VERSION_SDL3)
const char *joystickName = SDL_GetJoystickNameForID(joysticks[i]);
#else
const char *joystickName = SDL_GameControllerNameForIndex(i);
#endif
snprintf(CORE.Input.Gamepad.name[i], MAX_GAMEPAD_NAME_LENGTH, "%s", joystickName);
CORE.Input.Gamepad.name[i][MAX_GAMEPAD_NAME_LENGTH - 1] = '\0';
}
else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());

View file

@ -566,100 +566,100 @@ static KeyboardKey GetKeyFromWparam(WPARAM wparam)
case 'X': return KEY_X;
case 'Y': return KEY_Y;
case 'Z': return KEY_Z;
/* case VK_LWIN: return KEY_; */
/* case VK_RWIN: return KEY_; */
/* case VK_APPS: return KEY_; */
/* case VK_SLEEP: return KEY_; */
/* case VK_NUMPAD0: return KEY_; */
/* case VK_NUMPAD1: return KEY_; */
/* case VK_NUMPAD2: return KEY_; */
/* case VK_NUMPAD3: return KEY_; */
/* case VK_NUMPAD4: return KEY_; */
/* case VK_NUMPAD5: return KEY_; */
/* case VK_NUMPAD6: return KEY_; */
/* case VK_NUMPAD7: return KEY_; */
/* case VK_NUMPAD8: return KEY_; */
/* case VK_NUMPAD9: return KEY_; */
/* case VK_MULTIPLY: return KEY_; */
/* case VK_ADD: return KEY_; */
/* case VK_SEPARATOR: return KEY_; */
/* case VK_SUBTRACT: return KEY_; */
/* case VK_DECIMAL: return KEY_; */
/* case VK_DIVIDE: return KEY_; */
/* case VK_F1: return KEY_; */
/* case VK_F2: return KEY_; */
/* case VK_F3: return KEY_; */
/* case VK_F4: return KEY_; */
/* case VK_F5: return KEY_; */
/* case VK_F6: return KEY_; */
/* case VK_F7: return KEY_; */
/* case VK_F8: return KEY_; */
/* case VK_F9: return KEY_; */
/* case VK_F10: return KEY_; */
/* case VK_F11: return KEY_; */
/* case VK_F12: return KEY_; */
/* case VK_F13: return KEY_; */
/* case VK_F14: return KEY_; */
/* case VK_F15: return KEY_; */
/* case VK_F16: return KEY_; */
/* case VK_F17: return KEY_; */
/* case VK_F18: return KEY_; */
/* case VK_F19: return KEY_; */
/* case VK_F20: return KEY_; */
/* case VK_F21: return KEY_; */
/* case VK_F22: return KEY_; */
/* case VK_F23: return KEY_; */
/* case VK_F24: return KEY_; */
/* case VK_NUMLOCK: return KEY_; */
/* case VK_SCROLL: return KEY_; */
/* case VK_LSHIFT: return KEY_; */
/* case VK_RSHIFT: return KEY_; */
/* case VK_LCONTROL: return KEY_; */
/* case VK_RCONTROL: return KEY_; */
/* case VK_LMENU: return KEY_; */
/* case VK_RMENU: return KEY_; */
/* case VK_BROWSER_BACK: return KEY_; */
/* case VK_BROWSER_FORWARD: return KEY_; */
/* case VK_BROWSER_REFRESH: return KEY_; */
/* case VK_BROWSER_STOP: return KEY_; */
/* case VK_BROWSER_SEARCH: return KEY_; */
/* case VK_BROWSER_FAVORITES: return KEY_; */
/* case VK_BROWSER_HOME: return KEY_; */
/* case VK_VOLUME_MUTE: return KEY_; */
/* case VK_VOLUME_DOWN: return KEY_; */
/* case VK_VOLUME_UP: return KEY_; */
/* case VK_MEDIA_NEXT_TRACK: return KEY_; */
/* case VK_MEDIA_PREV_TRACK: return KEY_; */
/* case VK_MEDIA_STOP: return KEY_; */
/* case VK_MEDIA_PLAY_PAUSE: return KEY_; */
/* case VK_LAUNCH_MAIL: return KEY_; */
/* case VK_LAUNCH_MEDIA_SELECT: return KEY_; */
/* case VK_LAUNCH_APP1: return KEY_; */
/* case VK_LAUNCH_APP2: return KEY_; */
/* case VK_OEM_1: return KEY_; */
/* case VK_OEM_PLUS: return KEY_; */
/* case VK_OEM_COMMA: return KEY_; */
/* case VK_OEM_MINUS: return KEY_; */
/* case VK_OEM_PERIOD: return KEY_; */
/* case VK_OEM_2: return KEY_; */
/* case VK_OEM_3: return KEY_; */
/* case VK_OEM_4: return KEY_; */
/* case VK_OEM_5: return KEY_; */
/* case VK_OEM_6: return KEY_; */
/* case VK_OEM_7: return KEY_; */
/* case VK_OEM_8: return KEY_; */
/* case VK_OEM_102: return KEY_; */
/* case VK_PROCESSKEY: return KEY_; */
/* case VK_PACKET: return KEY_; */
/* case VK_ATTN: return KEY_; */
/* case VK_CRSEL: return KEY_; */
/* case VK_EXSEL: return KEY_; */
/* case VK_EREOF: return KEY_; */
/* case VK_PLAY: return KEY_; */
/* case VK_ZOOM: return KEY_; */
/* case VK_NONAME: return KEY_; */
/* case VK_PA1: return KEY_; */
/* case VK_OEM_CLEAR: return KEY_; */
//case VK_LWIN: return KEY_;
//case VK_RWIN: return KEY_;
//case VK_APPS: return KEY_;
//case VK_SLEEP: return KEY_;
//case VK_NUMPAD0: return KEY_;
//case VK_NUMPAD1: return KEY_;
//case VK_NUMPAD2: return KEY_;
//case VK_NUMPAD3: return KEY_;
//case VK_NUMPAD4: return KEY_;
//case VK_NUMPAD5: return KEY_;
//case VK_NUMPAD6: return KEY_;
//case VK_NUMPAD7: return KEY_;
//case VK_NUMPAD8: return KEY_;
//case VK_NUMPAD9: return KEY_;
//case VK_MULTIPLY: return KEY_;
//case VK_ADD: return KEY_;
//case VK_SEPARATOR: return KEY_;
//case VK_SUBTRACT: return KEY_;
//case VK_DECIMAL: return KEY_;
//case VK_DIVIDE: return KEY_;
//case VK_F1: return KEY_;
//case VK_F2: return KEY_;
//case VK_F3: return KEY_;
//case VK_F4: return KEY_;
//case VK_F5: return KEY_;
//case VK_F6: return KEY_;
//case VK_F7: return KEY_;
//case VK_F8: return KEY_;
//case VK_F9: return KEY_;
//case VK_F10: return KEY_;
//case VK_F11: return KEY_;
//case VK_F12: return KEY_;
//case VK_F13: return KEY_;
//case VK_F14: return KEY_;
//case VK_F15: return KEY_;
//case VK_F16: return KEY_;
//case VK_F17: return KEY_;
//case VK_F18: return KEY_;
//case VK_F19: return KEY_;
//case VK_F20: return KEY_;
//case VK_F21: return KEY_;
//case VK_F22: return KEY_;
//case VK_F23: return KEY_;
//case VK_F24: return KEY_;
//case VK_NUMLOCK: return KEY_;
//case VK_SCROLL: return KEY_;
//case VK_LSHIFT: return KEY_;
//case VK_RSHIFT: return KEY_;
//case VK_LCONTROL: return KEY_;
//case VK_RCONTROL: return KEY_;
//case VK_LMENU: return KEY_;
//case VK_RMENU: return KEY_;
//case VK_BROWSER_BACK: return KEY_;
//case VK_BROWSER_FORWARD: return KEY_;
//case VK_BROWSER_REFRESH: return KEY_;
//case VK_BROWSER_STOP: return KEY_;
//case VK_BROWSER_SEARCH: return KEY_;
//case VK_BROWSER_FAVORITES: return KEY_;
//case VK_BROWSER_HOME: return KEY_;
//case VK_VOLUME_MUTE: return KEY_;
//case VK_VOLUME_DOWN: return KEY_;
//case VK_VOLUME_UP: return KEY_;
//case VK_MEDIA_NEXT_TRACK: return KEY_;
//case VK_MEDIA_PREV_TRACK: return KEY_;
//case VK_MEDIA_STOP: return KEY_;
//case VK_MEDIA_PLAY_PAUSE: return KEY_;
//case VK_LAUNCH_MAIL: return KEY_;
//case VK_LAUNCH_MEDIA_SELECT: return KEY_;
//case VK_LAUNCH_APP1: return KEY_;
//case VK_LAUNCH_APP2: return KEY_;
//case VK_OEM_1: return KEY_;
//case VK_OEM_PLUS: return KEY_;
//case VK_OEM_COMMA: return KEY_;
//case VK_OEM_MINUS: return KEY_;
//case VK_OEM_PERIOD: return KEY_;
//case VK_OEM_2: return KEY_;
//case VK_OEM_3: return KEY_;
//case VK_OEM_4: return KEY_;
//case VK_OEM_5: return KEY_;
//case VK_OEM_6: return KEY_;
//case VK_OEM_7: return KEY_;
//case VK_OEM_8: return KEY_;
//case VK_OEM_102: return KEY_;
//case VK_PROCESSKEY: return KEY_;
//case VK_PACKET: return KEY_;
//case VK_ATTN: return KEY_;
//case VK_CRSEL: return KEY_;
//case VK_EXSEL: return KEY_;
//case VK_EREOF: return KEY_;
//case VK_PLAY: return KEY_;
//case VK_ZOOM: return KEY_;
//case VK_NONAME: return KEY_;
//case VK_PA1: return KEY_;
//case VK_OEM_CLEAR: return KEY_;
default: return KEY_NULL;
}
}
@ -1023,7 +1023,7 @@ void SetWindowFocused(void)
// Get native window handle
void *GetWindowHandle(void)
{
return platform.hwnd;
return (void *)platform.hwnd;
}
int GetMonitorCount(void)
@ -1129,12 +1129,37 @@ const char *GetClipboardText(void)
return NULL;
}
#if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES
#define WIN32_CLIPBOARD_IMPLEMENTATION
#define WINUSER_ALREADY_INCLUDED
#define WINBASE_ALREADY_INCLUDED
#define WINGDI_ALREADY_INCLUDED
#include "../external/win32_clipboard.h"
#endif
// Get clipboard image
Image GetClipboardImage(void)
{
Image image = { 0 };
TRACELOG(LOG_WARNING, "GetClipboardText not implemented");
#if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES
unsigned int dataSize = 0;
void *fileData = NULL;
int width = 0;
int height = 0;
fileData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize);
if (fileData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data.");
else
{
image = LoadImageFromMemory(".bmp", (const unsigned char*)fileData, (int)dataSize);
RL_FREE(fileData);
}
#else
TRACELOG(LOG_WARNING, "Clipboard image: SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_MODULE_RTEXTURES to work properly");
#endif // SUPPORT_CLIPBOARD_IMAGE
return image;
}
@ -1146,7 +1171,7 @@ void ShowCursor(void)
CORE.Input.Mouse.cursorHidden = false;
}
// Hides mouse cursor
// Hide mouse cursor
void HideCursor(void)
{
// NOTE: Using SetCursor() instead of ShowCursor() because
@ -1155,7 +1180,7 @@ void HideCursor(void)
CORE.Input.Mouse.cursorHidden = true;
}
// Enables cursor (unlock cursor)
// Enable cursor (unlock cursor)
void EnableCursor(void)
{
if (CORE.Input.Mouse.cursorLocked)
@ -1247,18 +1272,28 @@ double GetTime(void)
}
// Open URL with default system browser (if available)
// NOTE: This function is only safe to use if the provided URL is safe
// A user could craft a malicious string performing another action
// Avoid calling this function with user input non-validated strings
// REF: https://github.com/raysan5/raylib/issues/686
// WARNING: This function is only safe to use if you control the URL given,
// a user could craft a malicious string to perform and undesired action
// NOTE: Some safety checks have been added to mitigate security issues
void OpenURL(const char *url)
{
// Security check to (partially) avoid malicious code on target platform
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
// Security check to (partially) avoid malicious code
if ((strchr(url, '\'') != NULL) || (strchr(url, '\"') != NULL))
{
// Filter characters: ' and "
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'\"] characters");
}
else if ((strncmp(url, "http://", 7) != 0) && (strncmp(url, "https://", 8) != 0))
{
// Only allow URL starting with "http://" or "https://" protocols
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols");
}
else
{
char *cmd = (char *)RL_CALLOC(strlen(url) + 32, sizeof(char));
sprintf(cmd, "explorer \"%s\"", url);
int len = strlen(url) + 16;
char *cmd = (char *)RL_CALLOC(len, sizeof(char));
snprintf(cmd, len, "explorer \"%s\"", url);
int result = system(cmd);
if (result == -1) TRACELOG(LOG_WARNING, "OpenURL() child process could not be created");
RL_FREE(cmd);
@ -1289,8 +1324,8 @@ void SetMousePosition(int x, int y)
if (!CORE.Input.Mouse.cursorLocked)
{
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
TRACELOG(LOG_WARNING, "SetMousePosition not implemented");
TRACELOG(LOG_WARNING, "SetMousePosition not implemented at platform level");
}
else TRACELOG(LOG_WARNING, "INPUT: MOUSE: Cursor not enabled");
}
@ -1526,7 +1561,6 @@ int InitPlatform(void)
if (hr < 0) TRACELOG(LOG_ERROR, "%s failed, hresult=0x%lx", "SetProcessDpiAwareness", (DWORD)hr);
}
*/
HINSTANCE hInstance = GetModuleHandleW(0);
// Define window class
@ -1775,9 +1809,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
// WARNING: Don't trust the docs, they say this message can not be obtained if not calling DefWindowProc()
// in response to WM_WINDOWPOSCHANGED but looks like when a window is created,
// this message can be obtained without getting WM_WINDOWPOSCHANGED
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
// WARNING: Waiting two frames before resizing because software-renderer backend is initilized with swInit() later
// WARNING: Waiting two frames before resizing because software-renderer backend is initilized with swInit() later
// than InitPlatform(), that triggers WM_SIZE, so avoid crashing
if (CORE.Time.frameCounter > 2) HandleWindowResize(hwnd, &platform.appScreenWidth, &platform.appScreenHeight);
#else
@ -2034,7 +2068,7 @@ static void HandleKey(WPARAM wparam, LPARAM lparam, char state)
{
CORE.Input.Keyboard.currentKeyState[key] = state;
if ((key == KEY_ESCAPE) && (state == 1)) CORE.Window.shouldClose = true;
if ((key == CORE.Input.Keyboard.exitKey) && (state == 1)) CORE.Window.shouldClose = true;
}
else TRACELOG(LOG_WARNING, "INPUT: Unknown (or currently unhandled) virtual keycode %d (0x%x)", wparam, wparam);
@ -2053,8 +2087,11 @@ static void HandleMouseButton(int button, char state)
static void HandleRawInput(LPARAM lparam)
{
RAWINPUT input = { 0 };
UINT inputSize = 0;
if (GetRawInputData((HRAWINPUT)lparam, RID_INPUT, NULL, &inputSize, sizeof(RAWINPUTHEADER)) != 0) return;
if (inputSize > sizeof(input)) return;
UINT inputSize = sizeof(input);
UINT size = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &input, &inputSize, sizeof(RAWINPUTHEADER));
if (size == (UINT)-1) TRACELOG(LOG_ERROR, "WIN32: Failed to get raw input data [ERROR: %lu]", GetLastError());
@ -2210,7 +2247,7 @@ static unsigned SanitizeFlags(int mode, unsigned flags)
//
// This design takes care of many odd corner cases. For example, in case of restoring
// a window that was previously maximized AND minimized and those two flags need to be removed,
// ShowWindow with SW_RESTORE twice need to bee actually calleed. Another example is
// ShowWindow with SW_RESTORE twice need to be actually calleed. Another example is
// wheen having a maximized window, if the undecorated flag is modified then the window style
// needs to be updated, but updating the style would mean the window size would change
// causing the window to lose its Maximized state which would mean the window size
@ -2271,4 +2308,4 @@ static bool IsWglExtensionAvailable(HDC hdc, const char *extension)
}
return result;
}
}

View file

@ -79,7 +79,11 @@
#include <poll.h> // Required for: drmHandleEvent() poll
#include <errno.h> // Required for: EBUSY, EAGAIN
#define MAX_DRM_CACHED_BUFFERS 3
// NOTE: Some drivers rotate more buffers than others, mesa uses 3 but the
// ARM Mali blob on RK3326 uses 4. A buffer beyond this count can not get a
// framebuffer and the display stops updating for good, so this must not be
// lower than any driver in use
#define MAX_DRM_CACHED_BUFFERS 4
#endif
#ifndef EGL_OPENGL_ES3_BIT
@ -110,6 +114,9 @@ typedef struct {
drmModeCrtc *crtc; // CRT Controller
int modeIndex; // Index of the used mode of connector->modes
uint32_t prevFB; // Previous DRM framebufer (during frame swapping)
#if defined(SUPPORT_DRM_CACHE)
bool fbCacheFullReported; // Framebuffer cache exhaustion already reported
#endif
#if !defined(GRAPHICS_API_OPENGL_SOFTWARE)
struct gbm_device *gbmDevice; // GBM device
@ -266,9 +273,12 @@ static void PollKeyboardEvents(void); // Process evdev keyboard events
static void PollGamepadEvents(void); // Process evdev gamepad events
static void PollMouseEvents(void); // Process evdev mouse events
// Not used by software rendering.
#if !defined(GRAPHICS_API_OPENGL_SOFTWARE)
static int FindMatchingConnectorMode(const drmModeConnector *connector, const drmModeModeInfo *mode); // Search matching DRM mode in connector's mode list
static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list
static int FindNearestConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search the nearest matching DRM connector mode in connector's list
#endif
static void SetupFramebuffer(int width, int height); // Setup main framebuffer (required by InitPlatform())
@ -561,13 +571,13 @@ void ShowCursor(void)
CORE.Input.Mouse.cursorHidden = false;
}
// Hides mouse cursor
// Hide mouse cursor
void HideCursor(void)
{
CORE.Input.Mouse.cursorHidden = true;
}
// Enables cursor (unlock cursor)
// Enable cursor (unlock cursor)
void EnableCursor(void)
{
// Set cursor position in the middle
@ -577,7 +587,7 @@ void EnableCursor(void)
CORE.Input.Mouse.cursorLocked = false;
}
// Disables cursor (lock cursor)
// Disable cursor (lock cursor)
void DisableCursor(void)
{
// Set cursor position in the middle
@ -621,7 +631,18 @@ static uint32_t GetOrCreateFbForBo(struct gbm_bo *bo)
}
// Create new entry if cache not full
if (fbCacheCount >= MAX_DRM_CACHED_BUFFERS) return 0; // FB cache full
if (fbCacheCount >= MAX_DRM_CACHED_BUFFERS)
{
// NOTE: Once this happens no page flip is ever scheduled again and the
// screen freezes while the game keeps running, so say it out loud once
if (!platform.fbCacheFullReported)
{
platform.fbCacheFullReported = true;
TRACELOG(LOG_WARNING, "DISPLAY: DRM: Framebuffer cache full (%i buffers), display will stop updating", MAX_DRM_CACHED_BUFFERS);
}
return 0; // FB cache full
}
uint32_t handle = gbm_bo_get_handle(bo).u32;
uint32_t stride = gbm_bo_get_stride(bo);
@ -1003,17 +1024,16 @@ double GetTime(void)
double time = 0.0;
struct timespec ts = { 0 };
clock_gettime(CLOCK_MONOTONIC, &ts);
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
unsigned long long nanoSeconds = (unsigned long long)ts.tv_sec*1000000000LLU + (unsigned long long)ts.tv_nsec;
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
return time;
}
// Open URL with default system browser (if available)
// NOTE: This function is only safe to use if the provided URL is safe
// A user could craft a malicious string performing another action
// Avoid calling this function with user input non-validated strings
// WARNING: This function is only safe to use if you control the URL given,
// a user could craft a malicious string to perform and undesired action
void OpenURL(const char *url)
{
TRACELOG(LOG_WARNING, "OpenURL() not implemented on target platform");
@ -1040,7 +1060,6 @@ void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float d
void SetMousePosition(int x, int y)
{
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
}
// Set mouse cursor
@ -1070,7 +1089,7 @@ void PollInputEvents(void)
CORE.Input.Keyboard.charPressedQueueCount = 0;
// Reset last gamepad button/axis registered state
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
//CORE.Input.Gamepad.axisCount = 0;
// Register previous keys states
@ -1117,7 +1136,7 @@ void PollInputEvents(void)
// NOTE: For DRM touchscreen devices, this mapping is disabled to avoid false touch detection
// CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
// Handle the mouse/touch/gestures events:
// Handle the mouse/touch/gestures events
PollMouseEvents();
}
@ -1443,7 +1462,9 @@ int InitPlatform(void)
return -1;
}
if (!eglChooseConfig(platform.device, NULL, NULL, 0, &numConfigs))
// WARNING: Providing framebufferAttribs is not logically necessary,
// but it may prevent segfaults on some nvidia drivers
if (!eglChooseConfig(platform.device, framebufferAttribs, NULL, 0, &numConfigs))
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get EGL config count: 0x%x", eglGetError());
return -1;
@ -1818,7 +1839,7 @@ static void ProcessKeyboard(void)
if (bufferByteCount == 1) CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] = 1;
else
{
if (keysBuffer[i + 1] == 0x5b) // Special function key
if (keysBuffer[i + 1] == 0x5b) // Special function key
{
if ((keysBuffer[i + 2] == 0x5b) || (keysBuffer[i + 2] == 0x31) || (keysBuffer[i + 2] == 0x32))
{
@ -1935,7 +1956,8 @@ static void InitEvdevInput(void)
(strncmp("mouse", entity->d_name, strlen("mouse")) == 0)) // Search for devices named "mouse*"
{
snprintf(path, MAX_FILEPATH_LENGTH, "%s%s", DEFAULT_EVDEV_PATH, entity->d_name);
ConfigureEvdevDevice(path); // Configure the device if appropriate
ConfigureEvdevDevice(path); // Configure the device if appropriate
}
}
@ -2560,6 +2582,7 @@ static void PollMouseEvents(void)
}
}
#if !defined(GRAPHICS_API_OPENGL_SOFTWARE)
// Search matching DRM mode in connector's mode list
static int FindMatchingConnectorMode(const drmModeConnector *connector, const drmModeModeInfo *mode)
{
@ -2648,6 +2671,7 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
return nearestIndex;
}
#endif
// Compute framebuffer size relative to screen size and display size
// NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified
@ -2727,4 +2751,4 @@ static void SetupFramebuffer(int width, int height)
}
}
// EOF
// EOF

View file

@ -91,7 +91,7 @@ bool InitGraphicsDevice(void); // Initialize graphics device
// Module Internal Functions Declaration
//----------------------------------------------------------------------------------
#if !defined(_WIN32)
static int kbhit(void); // Check if a key has been pressed
static int kbhit(void); // Check if key has been pressed
static char getch(void) { return getchar(); } // Get pressed character
#endif
@ -324,13 +324,13 @@ void ShowCursor(void)
CORE.Input.Mouse.cursorHidden = false;
}
// Hides mouse cursor
// Hide mouse cursor
void HideCursor(void)
{
CORE.Input.Mouse.cursorHidden = true;
}
// Enables cursor (unlock cursor)
// Enable cursor (unlock cursor)
void EnableCursor(void)
{
// Set cursor position in the middle
@ -339,7 +339,7 @@ void EnableCursor(void)
CORE.Input.Mouse.cursorHidden = false;
}
// Disables cursor (lock cursor)
// Disable cursor (lock cursor)
void DisableCursor(void)
{
// Set cursor position in the middle
@ -364,14 +364,18 @@ double GetTime(void)
{
double time = 0.0;
#if defined(_WIN32)
LARGE_INTEGER now = { 0 };
QueryPerformanceCounter(&now);
return (double)(now.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart;
LARGE_INTEGER currentTicks = { 0 };
QueryPerformanceCounter(&currentTicks);
time = (double)(currentTicks.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart;
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__)
struct timespec ts = { 0 };
clock_gettime(CLOCK_MONOTONIC, &ts);
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
unsigned long long nanoSeconds = (unsigned long long)ts.tv_sec*1000000000LLU + (unsigned long long)ts.tv_nsec;
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
#elif defined(PICO_RP2350)
time = (double)to_ms_since_boot(get_absolute_time())/1000.0;
#endif
return time;
}
@ -416,7 +420,6 @@ void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float d
void SetMousePosition(int x, int y)
{
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
}
// Set mouse cursor
@ -474,7 +477,7 @@ void PollInputEvents(void)
if (kbhit())
{
int key = getch();
if (key == 27) CORE.Window.shouldClose = true; // KEY_SCAPE
if (key == 27) CORE.Window.shouldClose = true; // KEY_ESCAPE
}
}
@ -558,7 +561,7 @@ void ClosePlatform(void)
// Module Internal Functions Definition
//----------------------------------------------------------------------------------
#if !defined(_WIN32)
// Check if a key has been pressed
// Check if key has been pressed
static int kbhit(void)
{
struct termios oldt = { 0 };

View file

@ -303,13 +303,13 @@ void ShowCursor(void)
CORE.Input.Mouse.cursorHidden = false;
}
// Hides mouse cursor
// Hide mouse cursor
void HideCursor(void)
{
CORE.Input.Mouse.cursorHidden = true;
}
// Enables cursor (unlock cursor)
// Enable cursor (unlock cursor)
void EnableCursor(void)
{
// Set cursor position in the middle
@ -318,7 +318,7 @@ void EnableCursor(void)
CORE.Input.Mouse.cursorHidden = false;
}
// Disables cursor (lock cursor)
// Disable cursor (lock cursor)
void DisableCursor(void)
{
// Set cursor position in the middle
@ -341,23 +341,33 @@ void SwapScreenBuffer(void)
double GetTime(void)
{
double time = 0.0;
struct timespec ts = { 0 };
clock_gettime(CLOCK_MONOTONIC, &ts);
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
unsigned long long nanoSeconds = (unsigned long long)ts.tv_sec*1000000000LLU + (unsigned long long)ts.tv_nsec;
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
return time;
}
// Open URL with default system browser (if available)
// NOTE: This function is only safe to use if you control the URL given.
// A user could craft a malicious string performing another action.
// Only call this function yourself not with user input or make sure to check the string yourself.
// Ref: https://github.com/raysan5/raylib/issues/686
// WARNING: This function is only safe to use if you control the URL given,
// a user could craft a malicious string to perform and undesired action
// NOTE: Some safety checks have been added to mitigate security issues
void OpenURL(const char *url)
{
// Security check to (partially) avoid malicious code on target platform
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
// Security check to (partially) avoid malicious code
if ((strchr(url, '\'') != NULL) || (strchr(url, '\"') != NULL))
{
// Filter characters: ' and "
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'\"] characters");
}
else if ((strncmp(url, "http://", 7) != 0) && (strncmp(url, "https://", 8) != 0))
{
// Only allow URL starting with "http://" or "https://" protocols
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols");
}
else
{
// TODO: Load url using default browser
@ -385,7 +395,6 @@ void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float d
void SetMousePosition(int x, int y)
{
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
}
// Set mouse cursor

View file

@ -76,7 +76,6 @@ typedef struct {
char canvasId[64]; // Keep current canvas id where wasm app is running
// NOTE: Useful when trying to run multiple wasms in different canvases in same webpage
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
unsigned int *pixels; // Pointer to pixel data buffer (RGBA 32bit format)
#endif
@ -913,7 +912,7 @@ void ShowCursor(void)
}
}
// Hides mouse cursor
// Hide mouse cursor
void HideCursor(void)
{
if (!CORE.Input.Mouse.cursorHidden)
@ -924,7 +923,7 @@ void HideCursor(void)
}
}
// Enables cursor (unlock cursor)
// Enable cursor (unlock cursor)
void EnableCursor(void)
{
emscripten_exit_pointerlock();
@ -935,7 +934,7 @@ void EnableCursor(void)
// NOTE: CORE.Input.Mouse.cursorLocked handled by EmscriptenPointerlockCallback()
}
// Disables cursor (lock cursor)
// Disable cursor (lock cursor)
void DisableCursor(void)
{
emscripten_request_pointerlock(platform.canvasId, 1);
@ -1048,7 +1047,6 @@ void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float d
void SetMousePosition(int x, int y)
{
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
if (CORE.Input.Mouse.cursorLocked) CORE.Input.Mouse.lockedPosition = CORE.Input.Mouse.currentPosition;
@ -1088,7 +1086,7 @@ void PollInputEvents(void)
CORE.Input.Keyboard.charPressedQueueCount = 0;
// Reset last gamepad button/axis registered state
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
//CORE.Input.Gamepad.axisCount = 0;
// Keyboard/Mouse input polling (automatically managed by GLFW3 through callback)
@ -1130,7 +1128,7 @@ void PollInputEvents(void)
// Register previous gamepad button states
for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k];
EmscriptenGamepadEvent gamepadState;
EmscriptenGamepadEvent gamepadState = { 0 };
int result = emscripten_get_gamepad_status(i, &gamepadState);
@ -1163,7 +1161,7 @@ void PollInputEvents(void)
default: break;
}
if (button + 1 != 0) // Check for valid button
if (button + 1 != 0) // Check for valid button
{
if (gamepadState.digitalButton[j] == 1)
{
@ -1580,7 +1578,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++)
{
CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
strncpy(CORE.Window.dropFilepaths[i], paths[i], MAX_FILEPATH_LENGTH - 1);
snprintf(CORE.Window.dropFilepaths[i], MAX_FILEPATH_LENGTH, "%s", paths[i]);
}
}
}

View file

@ -42,6 +42,7 @@
**********************************************************************************************/
#include <emscripten/emscripten.h> // Emscripten functionality for C
#include <emscripten/dom_pk_codes.h> // Emscripten physical keyboard codes
#include <emscripten/html5.h> // Emscripten HTML5 library
#include <sys/time.h> // Required for: timespec, nanosleep(), select() - POSIX
@ -54,6 +55,9 @@
#define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext.
#endif
#define DOM_PK_CODE_MAPPED_NUM 128
#define DOM_PK_CODE_EXTENDED_OFFSET 0xE000
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
@ -70,9 +74,121 @@ extern CoreData CORE; // Global CORE state context
static PlatformData platform = { 0 }; // Platform specific data
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
static const KeyboardKey mapDomCodeToKey[DOM_PK_CODE_MAPPED_NUM] = {
[DOM_PK_ESCAPE] = KEY_ESCAPE,
[DOM_PK_0] = KEY_ZERO,
[DOM_PK_1] = KEY_ONE,
[DOM_PK_2] = KEY_TWO,
[DOM_PK_3] = KEY_THREE,
[DOM_PK_4] = KEY_FOUR,
[DOM_PK_5] = KEY_FIVE,
[DOM_PK_6] = KEY_SIX,
[DOM_PK_7] = KEY_SEVEN,
[DOM_PK_8] = KEY_EIGHT,
[DOM_PK_9] = KEY_NINE,
[DOM_PK_MINUS] = KEY_MINUS,
[DOM_PK_EQUAL] = KEY_EQUAL,
[DOM_PK_BACKSPACE] = KEY_BACKSPACE,
[DOM_PK_TAB] = KEY_TAB,
[DOM_PK_Q] = KEY_Q,
[DOM_PK_W] = KEY_W,
[DOM_PK_E] = KEY_E,
[DOM_PK_R] = KEY_R,
[DOM_PK_T] = KEY_T,
[DOM_PK_Y] = KEY_Y,
[DOM_PK_U] = KEY_U,
[DOM_PK_I] = KEY_I,
[DOM_PK_O] = KEY_O,
[DOM_PK_P] = KEY_P,
[DOM_PK_BRACKET_LEFT] = KEY_LEFT_BRACKET,
[DOM_PK_BRACKET_RIGHT] = KEY_RIGHT_BRACKET,
[DOM_PK_ENTER] = KEY_ENTER,
[DOM_PK_CONTROL_LEFT] = KEY_LEFT_CONTROL,
[DOM_PK_A] = KEY_A,
[DOM_PK_S] = KEY_S,
[DOM_PK_D] = KEY_D,
[DOM_PK_F] = KEY_F,
[DOM_PK_G] = KEY_G,
[DOM_PK_H] = KEY_H,
[DOM_PK_J] = KEY_J,
[DOM_PK_K] = KEY_K,
[DOM_PK_L] = KEY_L,
[DOM_PK_SEMICOLON] = KEY_SEMICOLON,
[DOM_PK_QUOTE] = KEY_APOSTROPHE,
[DOM_PK_BACKQUOTE] = KEY_GRAVE,
[DOM_PK_SHIFT_LEFT] = KEY_LEFT_SHIFT,
[DOM_PK_BACKSLASH] = KEY_BACKSLASH,
[DOM_PK_Z] = KEY_Z,
[DOM_PK_X] = KEY_X,
[DOM_PK_C] = KEY_C,
[DOM_PK_V] = KEY_V,
[DOM_PK_B] = KEY_B,
[DOM_PK_N] = KEY_N,
[DOM_PK_M] = KEY_M,
[DOM_PK_COMMA] = KEY_COMMA,
[DOM_PK_PERIOD] = KEY_PERIOD,
[DOM_PK_SLASH] = KEY_SLASH,
[DOM_PK_SHIFT_RIGHT] = KEY_RIGHT_SHIFT,
[DOM_PK_NUMPAD_MULTIPLY] = KEY_KP_MULTIPLY,
[DOM_PK_ALT_LEFT] = KEY_LEFT_ALT,
[DOM_PK_SPACE] = KEY_SPACE,
[DOM_PK_CAPS_LOCK] = KEY_CAPS_LOCK,
[DOM_PK_F1] = KEY_F1,
[DOM_PK_F2] = KEY_F2,
[DOM_PK_F3] = KEY_F3,
[DOM_PK_F4] = KEY_F4,
[DOM_PK_F5] = KEY_F5,
[DOM_PK_F6] = KEY_F6,
[DOM_PK_F7] = KEY_F7,
[DOM_PK_F8] = KEY_F8,
[DOM_PK_F9] = KEY_F9,
[DOM_PK_F10] = KEY_F10,
[DOM_PK_PAUSE] = KEY_PAUSE,
[DOM_PK_SCROLL_LOCK] = KEY_SCROLL_LOCK,
[DOM_PK_NUMPAD_7] = KEY_KP_7,
[DOM_PK_NUMPAD_8] = KEY_KP_8,
[DOM_PK_NUMPAD_9] = KEY_KP_9,
[DOM_PK_NUMPAD_SUBTRACT] = KEY_KP_SUBTRACT,
[DOM_PK_NUMPAD_4] = KEY_KP_4,
[DOM_PK_NUMPAD_5] = KEY_KP_5,
[DOM_PK_NUMPAD_6] = KEY_KP_6,
[DOM_PK_NUMPAD_ADD] = KEY_KP_ADD,
[DOM_PK_NUMPAD_1] = KEY_KP_1,
[DOM_PK_NUMPAD_2] = KEY_KP_2,
[DOM_PK_NUMPAD_3] = KEY_KP_3,
[DOM_PK_NUMPAD_0] = KEY_KP_0,
[DOM_PK_NUMPAD_DECIMAL] = KEY_KP_DECIMAL,
[DOM_PK_PRINT_SCREEN] = KEY_PRINT_SCREEN,
[DOM_PK_F11] = KEY_F11,
[DOM_PK_F12] = KEY_F12,
[DOM_PK_NUMPAD_EQUAL] = KEY_KP_EQUAL,
[DOM_PK_NUMPAD_COMMA] = KEY_KP_DECIMAL
};
// Emscripten places keys with extended scan codes (right-side modifiers, navigation and some keypad keys) in the 0xE0xx range
static const KeyboardKey mapDomCodeToKeyExtended[DOM_PK_CODE_MAPPED_NUM] = {
[DOM_PK_NUMPAD_ENTER - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_KP_ENTER,
[DOM_PK_CONTROL_RIGHT - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_RIGHT_CONTROL,
[DOM_PK_AUDIO_VOLUME_DOWN - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_VOLUME_DOWN,
[DOM_PK_AUDIO_VOLUME_UP - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_VOLUME_UP,
[DOM_PK_NUMPAD_DIVIDE - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_KP_DIVIDE,
[DOM_PK_ALT_RIGHT - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_RIGHT_ALT,
[DOM_PK_NUM_LOCK - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_NUM_LOCK,
[DOM_PK_HOME - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_HOME,
[DOM_PK_ARROW_UP - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_UP,
[DOM_PK_PAGE_UP - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_PAGE_UP,
[DOM_PK_ARROW_LEFT - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_LEFT,
[DOM_PK_ARROW_RIGHT - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_RIGHT,
[DOM_PK_END - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_END,
[DOM_PK_ARROW_DOWN - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_DOWN,
[DOM_PK_PAGE_DOWN - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_PAGE_DOWN,
[DOM_PK_INSERT - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_INSERT,
[DOM_PK_DELETE - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_DELETE,
[DOM_PK_META_LEFT - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_LEFT_SUPER,
[DOM_PK_META_RIGHT - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_RIGHT_SUPER,
[DOM_PK_CONTEXT_MENU - DOM_PK_CODE_EXTENDED_OFFSET] = KEY_KB_MENU
};
static const char cursorLUT[11][12] = {
"default", // 0 MOUSE_CURSOR_DEFAULT
"default", // 1 MOUSE_CURSOR_ARROW
@ -110,6 +226,8 @@ static EM_BOOL EmscriptenPointerlockCallback(int eventType, const EmscriptenPoin
static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData);
static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData);
static KeyboardKey ConvertKeyboardEventToKey(const EmscriptenKeyboardEvent *keyboardEvent);
// JS: Set the canvas id provided by the module configuration
EM_JS(void, SetCanvasIdJs, (char *out, int outSize), {
var canvasId = "#" + Module.canvas.id;
@ -633,7 +751,7 @@ void SetWindowSize(int width, int height)
// When resizing the canvas, several elements must be considered:
// - CSS canvas size: Web layout size, logical pixels
// - Canvas contained framebuffer resolution
// * Browser monitor, device pixel ratio (HighDPI)
// - Browser monitor, device pixel ratio (HighDPI)
double canvasCssWidth = 0.0;
double canvasCssHeight = 0.0;
@ -891,7 +1009,7 @@ void ShowCursor(void)
}
}
// Hides mouse cursor
// Hide mouse cursor
void HideCursor(void)
{
if (!CORE.Input.Mouse.cursorHidden)
@ -902,7 +1020,7 @@ void HideCursor(void)
}
}
// Enables cursor (unlock cursor)
// Enable cursor (unlock cursor)
void EnableCursor(void)
{
emscripten_exit_pointerlock();
@ -913,7 +1031,7 @@ void EnableCursor(void)
// NOTE: CORE.Input.Mouse.cursorLocked handled by EmscriptenPointerlockCallback()
}
// Disables cursor (lock cursor)
// Disable cursor (lock cursor)
void DisableCursor(void)
{
emscripten_request_pointerlock(platform.canvasId, 1);
@ -962,19 +1080,28 @@ void SwapScreenBuffer(void)
// Get elapsed time measure in seconds since InitTimer()
double GetTime(void)
{
double time = emscripten_get_now()*1000.0;
double time = emscripten_get_now()/1000.0;
return time;
}
// Open URL with default system browser (if available)
// NOTE: This function is only safe to use if the provided URL is safe
// A user could craft a malicious string performing another action
// Avoid calling this function with user input non-validated strings
// WARNING: This function is only safe to use if you control the URL given,
// a user could craft a malicious string to perform and undesired action
// NOTE: Some safety checks have been added to mitigate security issues
void OpenURL(const char *url)
{
// Security check to (partially) avoid malicious code on target platform
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
// Security check to (partially) avoid malicious code
if ((strchr(url, '\'') != NULL) || (strchr(url, '\"') != NULL))
{
// Filter characters: ' and "
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'\"] characters");
}
else if ((strncmp(url, "http://", 7) != 0) && (strncmp(url, "https://", 8) != 0))
{
// Only allow URL starting with "http://" or "https://" protocols
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols");
}
else emscripten_run_script(TextFormat("window.open('%s', '_blank')", url));
}
@ -1054,7 +1181,7 @@ void PollInputEvents(void)
CORE.Input.Keyboard.charPressedQueueCount = 0;
// Reset last gamepad button/axis registered state
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
//CORE.Input.Gamepad.axisCount = 0;
// Keyboard/Mouse input polling (automatically managed by GLFW3 through callback)
@ -1125,7 +1252,7 @@ void PollInputEvents(void)
default: break;
}
if (button + 1 != 0) // Check for valid button
if (button + 1 != 0) // Check for valid button
{
if (gamepadState.digitalButton[j] == 1)
{
@ -1382,7 +1509,11 @@ static EM_BOOL EmscriptenFocusCallback(int eventType, const EmscriptenFocusEvent
switch (eventType)
{
case EMSCRIPTEN_EVENT_BLUR: FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); break;
case EMSCRIPTEN_EVENT_BLUR:
{
FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED);
memset(CORE.Input.Keyboard.currentKeyState, 0, sizeof(CORE.Input.Keyboard.currentKeyState));
} break;
case EMSCRIPTEN_EVENT_FOCUS: FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); break;
default: consumed = 0; break;
}
@ -1439,58 +1570,81 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++)
{
CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
strncpy(CORE.Window.dropFilepaths[i], paths[i], MAX_FILEPATH_LENGTH - 1);
snprintf(CORE.Window.dropFilepaths[i], MAX_FILEPATH_LENGTH, "%s", paths[i]);
}
}
}
*/
// Emscripten keyboard event to raylib key mapping
static KeyboardKey ConvertKeyboardEventToKey(const EmscriptenKeyboardEvent *keyboardEvent)
{
DOM_PK_CODE_TYPE code = emscripten_compute_dom_pk_code(keyboardEvent->code);
KeyboardKey key = KEY_NULL;
if ((code > DOM_PK_UNKNOWN) && (code < DOM_PK_CODE_MAPPED_NUM)) key = mapDomCodeToKey[code];
else if ((code >= DOM_PK_CODE_EXTENDED_OFFSET) && (code < (DOM_PK_CODE_EXTENDED_OFFSET + DOM_PK_CODE_MAPPED_NUM)))
{
key = mapDomCodeToKeyExtended[code - DOM_PK_CODE_EXTENDED_OFFSET];
}
return key;
}
// Emscripten: Called on key events
// TODO: keyCodes should be mapped to raylib/GLFW3 Key values
static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboardEvent *keyboardEvent, void *userData)
{
KeyboardKey key = ConvertKeyboardEventToKey(keyboardEvent);
EM_BOOL preventDefault = 1;
switch (eventType)
{
case EMSCRIPTEN_EVENT_KEYPRESS:
{
if (keyboardEvent->repeat) CORE.Input.Keyboard.keyRepeatInFrame[keyboardEvent->keyCode] = 1;
} break;
case EMSCRIPTEN_EVENT_KEYDOWN:
{
CORE.Input.Keyboard.currentKeyState[keyboardEvent->keyCode] = 1;
if (key != KEY_NULL)
{
// Check if there is space available in the key queue
if ((!keyboardEvent->repeat) && (CORE.Input.Keyboard.currentKeyState[key] == 0) &&
(CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE))
{
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = key;
CORE.Input.Keyboard.keyPressedQueueCount++;
}
CORE.Input.Keyboard.currentKeyState[key] = 1;
if (keyboardEvent->repeat) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
// Check the exit key to set close window
if ((key == CORE.Input.Keyboard.exitKey) && !keyboardEvent->repeat) CORE.Window.shouldClose = true;
}
// Allow printable keydown events so the browser can emit the keypress event used to collect characters
preventDefault = ((key == KEY_BACKSPACE) || (key == KEY_TAB) ||
(key == KEY_INSERT) || (key == KEY_DELETE) ||
(key == KEY_HOME) || (key == KEY_END) ||
(key == KEY_PAGE_UP) || (key == KEY_PAGE_DOWN) ||
(key == KEY_LEFT) || (key == KEY_RIGHT) ||
(key == KEY_UP) || (key == KEY_DOWN) ||
((key >= KEY_F1) && (key <= KEY_F12)) || keyboardEvent->ctrlKey);
} break;
case EMSCRIPTEN_EVENT_KEYUP:
{
CORE.Input.Keyboard.currentKeyState[keyboardEvent->keyCode] = 0;
if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 0;
} break;
case EMSCRIPTEN_EVENT_KEYPRESS:
{
// Check if there is space available in the queue for characters to be added
if ((keyboardEvent->charCode > 0) && (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE))
{
CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = keyboardEvent->charCode;
CORE.Input.Keyboard.charPressedQueueCount++;
}
} break;
default: break;
}
// TODO: Add char codes
//unsigned int charCode
// Check if there is space available in the queue for characters to be added
/*
if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE)
{
// Add character to the queue
CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = keyboardEvent->charCode;
CORE.Input.Keyboard.charPressedQueueCount++;
}
*/
/*
// Check if there is space available in the key queue
if ((CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE) && (eventType == EMSCRIPTEN_EVENT_KEYPRESS))
{
// Add character to the queue
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keyboardEvent->keyCode;
CORE.Input.Keyboard.keyPressedQueueCount++;
}
// Check the exit key to set close window
//if ((keyboardEvent->keyCode == CORE.Input.Keyboard.exitKey) && (eventType == EMSCRIPTEN_EVENT_KEYPRESS)) CORE.Window.shouldClose = true;
*/
return 1; // The event was consumed by the callback handler
return preventDefault;
}
// Emscripten: Called on mouse input events
@ -1498,8 +1652,16 @@ static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent
{
switch (eventType)
{
case EMSCRIPTEN_EVENT_MOUSEENTER: CORE.Input.Mouse.cursorOnScreen = true; break;
case EMSCRIPTEN_EVENT_MOUSELEAVE: CORE.Input.Mouse.cursorOnScreen = false; break;
case EMSCRIPTEN_EVENT_MOUSEENTER: {
// NOTE: Mouse position updated by EmscriptenMouseMoveCallback(),
// EmscriptenPointerlockCallback(), and EmscriptenTouchCallback()
CORE.Input.Mouse.cursorOnScreen = true;
} break;
case EMSCRIPTEN_EVENT_MOUSELEAVE:
{
CORE.Input.Mouse.cursorOnScreen = false;
CORE.Input.Mouse.currentPosition = (Vector2){ 0 };
} break;
case EMSCRIPTEN_EVENT_MOUSEDOWN:
{
// NOTE: Emscripten and raylib buttons indices are not aligned
@ -1546,7 +1708,8 @@ static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent
if (GetMouseX() != 0 || GetMouseY() != 0) ProcessGestureEvent(gestureEvent);
#endif
return 1; // The event was consumed by the callback handler
// Don't prevent default to allow focusing on canvas
return 0;
}
// Emscripten: Called on mouse move events
@ -1560,32 +1723,18 @@ static EM_BOOL EmscriptenMouseMoveCallback(int eventType, const EmscriptenMouseE
else
{
// Get mouse position in canvas CSS pixels
float mouseCssX = (float)mouseEvent->canvasX;
float mouseCssY = (float)mouseEvent->canvasY;
float mouseCssX = (float)mouseEvent->targetX;
float mouseCssY = (float)mouseEvent->targetY;
// Get canvas sizes
double cssWidth = 0.0;
double cssHeight = 0.0;
emscripten_get_element_css_size(platform.canvasId, &cssWidth, &cssHeight);
int fbWidth = 0;
int fbHeight = 0;
emscripten_get_canvas_element_size(platform.canvasId, &fbWidth, &fbHeight);
// Convert CSS to framebuffer coordinates
float scaleX = (float)fbWidth/(float)cssWidth;
float scaleY = (float)fbHeight/(float)cssHeight;
int mouseX = (int)(mouseCssX*scaleX);
int mouseY = (int)(mouseCssY*scaleY);
CORE.Input.Mouse.currentPosition.x = mouseX;//(float)mouseEvent->canvasX;
CORE.Input.Mouse.currentPosition.y = mouseY;//(float)mouseEvent->canvasY;
// Shorter alternative:
//double dpr = emscripten_get_device_pixel_ratio();
//int mouseX = (int)(e->canvasX*dpr);
//int mouseY = (int)(e->canvasY*dpr);
float normalizedX = mouseCssX/(float)cssWidth;
float normalizedY = mouseCssY/(float)cssHeight;
CORE.Input.Mouse.currentPosition.x = normalizedX*(float)CORE.Window.screen.width;
CORE.Input.Mouse.currentPosition.y = normalizedY*(float)CORE.Window.screen.height;
CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
}
@ -1622,7 +1771,7 @@ static EM_BOOL EmscriptenMouseWheelCallback(int eventType, const EmscriptenWheel
if (eventType == EMSCRIPTEN_EVENT_WHEEL)
{
CORE.Input.Mouse.currentWheelMove.x = (float)wheelEvent->deltaX;
CORE.Input.Mouse.currentWheelMove.y = (float)wheelEvent->deltaY;
CORE.Input.Mouse.currentWheelMove.y = -(float)wheelEvent->deltaY;
}
return 1; // The event was consumed by the callback handler

View file

@ -344,7 +344,7 @@ typedef enum {
// Audio buffer struct
struct rAudioBuffer {
ma_data_converter converter; // Audio data converter
unsigned char* converterResidual; // Cached residual input frames for use by the converter
unsigned char *converterResidual; // Cached residual input frames for use by the converter
unsigned int converterResidualCount; // The number of valid frames sitting in converterResidual
AudioCallback callback; // Audio buffer callback for buffer filling on audio threads
@ -378,7 +378,7 @@ struct rAudioProcessor {
rAudioProcessor *prev; // Previous audio processor on the list
};
#define AudioBuffer rAudioBuffer // HACK: To avoid CoreAudio (macOS) symbol collision
#define AudioBuffer rAudioBuffer // WARNING: Renamed to avoid symbol collision with CoreAudio (macOS) AudioBuffer type
// Audio data context
typedef struct AudioData {
@ -434,6 +434,7 @@ static const char *GetFileName(const char *filePath); // Get point
static const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string)
static unsigned char *LoadFileData(const char *fileName, int *dataSize); // Load file data as byte array (read)
static void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData()
static bool SaveFileData(const char *fileName, void *data, int dataSize); // Save data to file from byte array (write)
static bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated
#endif
@ -532,8 +533,9 @@ void CloseAudioDevice(void)
{
if (AUDIO.System.isReady)
{
ma_mutex_uninit(&AUDIO.System.lock);
// Stop the device first (joins the callback thread) before destroying the mutex it locks
ma_device_uninit(&AUDIO.System.device);
ma_mutex_uninit(&AUDIO.System.lock);
ma_context_uninit(&AUDIO.System.context);
AUDIO.System.isReady = false;
@ -821,7 +823,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
wave.sampleRate = wav.sampleRate;
wave.sampleSize = 16;
wave.channels = wav.channels;
wave.data = (short *)RL_MALLOC((size_t)wave.frameCount*wave.channels*sizeof(short));
wave.data = (short *)RL_CALLOC((size_t)wave.frameCount*wave.channels, sizeof(short));
// NOTE: Forcing conversion to 16bit sample size on reading
drwav_read_pcm_frames_s16(&wav, wave.frameCount, (drwav_int16 *)wave.data);
@ -844,7 +846,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
wave.sampleSize = 16; // By default, ogg data is 16 bit per sample (short)
wave.channels = info.channels;
wave.frameCount = (unsigned int)stb_vorbis_stream_length_in_samples(oggData); // NOTE: It returns frames!
wave.data = (short *)RL_MALLOC(wave.frameCount*wave.channels*sizeof(short));
wave.data = (short *)RL_CALLOC(wave.frameCount*wave.channels, sizeof(short));
// NOTE: Get the number of samples to process (be careful! asking for number of shorts, not bytes!)
stb_vorbis_get_samples_short_interleaved(oggData, info.channels, (short *)wave.data, wave.frameCount*wave.channels);
@ -857,7 +859,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
else if ((strcmp(fileType, ".mp3") == 0) || (strcmp(fileType, ".MP3") == 0))
{
drmp3_config config = { 0 };
unsigned long long int totalFrameCount = 0;
unsigned long long totalFrameCount = 0;
// NOTE: Forcing conversion to 32bit float sample size on reading
wave.data = drmp3_open_memory_and_read_pcm_frames_f32(fileData, dataSize, &config, &totalFrameCount, NULL);
@ -867,7 +869,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
{
wave.channels = config.channels;
wave.sampleRate = config.sampleRate;
wave.frameCount = (int)totalFrameCount;
wave.frameCount = (unsigned int)totalFrameCount; // WARNING: Potential loss of data
}
else TRACELOG(LOG_WARNING, "WAVE: Failed to load MP3 data");
@ -895,13 +897,13 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
#if SUPPORT_FILEFORMAT_FLAC
else if ((strcmp(fileType, ".flac") == 0) || (strcmp(fileType, ".FLAC") == 0))
{
unsigned long long int totalFrameCount = 0;
unsigned long long totalFrameCount = 0;
// NOTE: Forcing conversion to 16bit sample size on reading
wave.data = drflac_open_memory_and_read_pcm_frames_s16(fileData, dataSize, &wave.channels, &wave.sampleRate, &totalFrameCount, NULL);
wave.sampleSize = 16;
if (wave.data != NULL) wave.frameCount = (unsigned int)totalFrameCount;
if (wave.data != NULL) wave.frameCount = (unsigned int)totalFrameCount; // WARNING: Potential loss of data
else TRACELOG(LOG_WARNING, "WAVE: Failed to load FLAC data");
}
#endif
@ -912,7 +914,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
return wave;
}
// Checks if wave data is valid (data loaded and parameters)
// Check if wave data is valid (data loaded and parameters)
bool IsWaveValid(Wave wave)
{
bool result = false;
@ -980,7 +982,7 @@ Sound LoadSoundFromWave(Wave wave)
return sound;
}
// Clone sound from existing sound data, clone does not own wave data
// Load sound alias, clone sound from existing sound data, clone does not own wave data
// NOTE: Wave data must be unallocated manually and will be shared across all clones
Sound LoadSoundAlias(Sound source)
{
@ -1012,7 +1014,7 @@ Sound LoadSoundAlias(Sound source)
return sound;
}
// Checks if a sound is valid (data loaded and buffers initialized)
// Check if sound is valid (data loaded and buffers initialized)
bool IsSoundValid(Sound sound)
{
bool result = false;
@ -1047,6 +1049,7 @@ void UnloadSoundAlias(Sound alias)
{
UntrackAudioBuffer(alias.stream.buffer);
ma_data_converter_uninit(&alias.stream.buffer->converter, NULL);
RL_FREE(alias.stream.buffer->converterResidual);
RL_FREE(alias.stream.buffer);
}
}
@ -1152,7 +1155,7 @@ bool ExportWaveAsCode(Wave wave, const char *fileName)
// Get file name from path and convert variable name to uppercase
char varFileName[256] = { 0 };
strncpy(varFileName, GetFileNameWithoutExt(fileName), 256 - 1);
snprintf(varFileName, 256, "%s", GetFileNameWithoutExt(fileName)); // NOTE: Using function provided by [rcore] module
for (int i = 0; varFileName[i] != '\0'; i++) if (varFileName[i] >= 'a' && varFileName[i] <= 'z') { varFileName[i] = varFileName[i] - 32; }
// Add wave information
@ -1213,7 +1216,7 @@ void StopSound(Sound sound)
StopAudioBuffer(sound.stream.buffer);
}
// Check if a sound is playing
// Check if sound is playing
bool IsSoundPlaying(Sound sound)
{
bool result = false;
@ -1256,7 +1259,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
return;
}
void *data = RL_MALLOC(frameCount*channels*(sampleSize/8));
void *data = RL_CALLOC(frameCount*channels*(sampleSize/8), 1);
frameCount = (ma_uint32)ma_convert_frames(data, frameCount, formatOut, channels, sampleRate, wave->data, frameCountIn, formatIn, wave->channels, wave->sampleRate);
if (frameCount == 0)
@ -1749,7 +1752,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
return music;
}
// Checks if a music stream is valid (context and buffers initialized)
// Check if music stream is valid (context and buffers initialized)
bool IsMusicValid(Music music)
{
return ((music.ctxData != NULL) && // Validate context loaded
@ -1770,7 +1773,7 @@ void UnloadMusicStream(Music music)
{
if (false) { }
#if SUPPORT_FILEFORMAT_WAV
else if (music.ctxType == MUSIC_AUDIO_WAV) drwav_uninit((drwav *)music.ctxData);
else if (music.ctxType == MUSIC_AUDIO_WAV) { drwav_uninit((drwav *)music.ctxData); RL_FREE(music.ctxData); }
#endif
#if SUPPORT_FILEFORMAT_OGG
else if (music.ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close((stb_vorbis *)music.ctxData);
@ -1782,7 +1785,7 @@ void UnloadMusicStream(Music music)
else if (music.ctxType == MUSIC_AUDIO_QOA) qoaplay_close((qoaplay_desc *)music.ctxData);
#endif
#if SUPPORT_FILEFORMAT_FLAC
else if (music.ctxType == MUSIC_AUDIO_FLAC) { drflac_close((drflac *)music.ctxData); drflac_free((drflac *)music.ctxData, NULL); }
else if (music.ctxType == MUSIC_AUDIO_FLAC) drflac_close((drflac *)music.ctxData);
#endif
#if SUPPORT_FILEFORMAT_XM
else if (music.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)music.ctxData);
@ -2066,7 +2069,7 @@ void SetMusicPitch(Music music, float pitch)
SetAudioBufferPitch(music.stream.buffer, pitch);
}
// Set pan for a music
// Set pan for music
void SetMusicPan(Music music, float pan)
{
SetAudioBufferPan(music.stream.buffer, pan);
@ -2154,7 +2157,7 @@ AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
return stream;
}
// Checks if an audio stream is valid (buffers initialized)
// Check if an audio stream is valid (buffers initialized)
bool IsAudioStreamValid(AudioStream stream)
{
return ((stream.buffer != NULL) && // Validate stream buffer
@ -2658,7 +2661,7 @@ static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 fr
const float localVolume = buffer->volume;
const ma_uint32 channels = AUDIO.System.device.playback.channels;
if (channels == 2) // Consider panning
if (channels == 2) // Consider panning
{
const float right = (buffer->pan + 1.0f)/2.0f; // Normalize: [-1..1] -> [0..1]
const float left = 1.0f - right;
@ -2825,7 +2828,7 @@ static const char *GetFileNameWithoutExt(const char *filePath)
static char fileName[MAX_FILENAMEWITHOUTEXT_LENGTH] = { 0 };
memset(fileName, 0, MAX_FILENAMEWITHOUTEXT_LENGTH);
if (filePath != NULL) strncpy(fileName, GetFileName(filePath), MAX_FILENAMEWITHOUTEXT_LENGTH - 1); // Get filename with extension
if (filePath != NULL) snprintf(fileName, MAX_FILENAMEWITHOUTEXT_LENGTH, "%s", GetFileName(filePath));
int fileNameLength = (int)strlen(fileName); // Get size in bytes
@ -2882,6 +2885,12 @@ static unsigned char *LoadFileData(const char *fileName, int *dataSize)
return data;
}
// Unload file data allocated by LoadFileData()
static void UnloadFileData(unsigned char *data)
{
RL_FREE(data);
}
// Save data to file from buffer
static bool SaveFileData(const char *fileName, void *data, int dataSize)
{

View file

@ -1,6 +1,6 @@
/**********************************************************************************************
*
* raylib v6.0 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
* raylib v6.1-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
*
* FEATURES:
* - NO external dependencies, all required libraries included with raylib
@ -87,9 +87,9 @@
#include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback
#define RAYLIB_VERSION_MAJOR 6
#define RAYLIB_VERSION_MINOR 0
#define RAYLIB_VERSION_MINOR 1
#define RAYLIB_VERSION_PATCH 0
#define RAYLIB_VERSION "6.0"
#define RAYLIB_VERSION "6.1-dev"
// Function specifiers in case library is build/used as a shared library
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
@ -203,12 +203,14 @@
// Types and Structures Definition
//----------------------------------------------------------------------------------
// Boolean type
#if !defined(__cplusplus)
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
#include <stdbool.h>
#elif !defined(__cplusplus) && !defined(bool)
#elif !defined(bool)
typedef enum bool { false = 0, true = !false } bool;
#define RL_BOOL_TYPE
#endif
#endif
// Vector2, 2 components
typedef struct Vector2 {
@ -407,7 +409,7 @@ typedef struct BoneInfo {
// Skeleton, animation bones hierarchy
typedef struct ModelSkeleton {
int boneCount; // Number of bones
unsigned int boneCount; // Number of bones
BoneInfo *bones; // Bones information (skeleton)
ModelAnimPose bindPose; // Bones base transformation (Transform[])
} ModelSkeleton;
@ -434,7 +436,7 @@ typedef struct Model {
typedef struct ModelAnimation {
char name[32]; // Animation name
int boneCount; // Number of bones (per pose)
unsigned int boneCount; // Number of bones (per pose)
int keyframeCount; // Number of animation key frames
ModelAnimPose *keyframePoses; // Animation sequence keyframe poses [keyframe][pose]
} ModelAnimation;
@ -963,10 +965,10 @@ typedef enum {
// Callbacks to hook some internal functions
// WARNING: These callbacks are intended for advanced users
typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages
typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data
typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, int dataSize); // FileIO: Save binary data
typedef char *(*LoadFileTextCallback)(const char *fileName); // FileIO: Load text data
typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages
typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data
typedef bool (*SaveFileDataCallback)(const char *fileName, const void *data, int dataSize); // FileIO: Save binary data
typedef char *(*LoadFileTextCallback)(const char *fileName); // FileIO: Load text data
typedef bool (*SaveFileTextCallback)(const char *fileName, const char *text); // FileIO: Save text data
//------------------------------------------------------------------------------------
@ -1034,23 +1036,23 @@ RLAPI void EnableEventWaiting(void); // Enable wait
RLAPI void DisableEventWaiting(void); // Disable waiting for events on EndDrawing(), automatic events polling
// Cursor-related functions
RLAPI void ShowCursor(void); // Shows cursor
RLAPI void HideCursor(void); // Hides cursor
RLAPI void ShowCursor(void); // Show cursor
RLAPI void HideCursor(void); // Hide cursor
RLAPI bool IsCursorHidden(void); // Check if cursor is not visible
RLAPI void EnableCursor(void); // Enables cursor (unlock cursor)
RLAPI void DisableCursor(void); // Disables cursor (lock cursor)
RLAPI void EnableCursor(void); // Enable cursor (unlock cursor)
RLAPI void DisableCursor(void); // Disable cursor (lock cursor)
RLAPI bool IsCursorOnScreen(void); // Check if cursor is on the screen
// Drawing-related functions
RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color)
RLAPI void BeginDrawing(void); // Setup canvas (framebuffer) to start drawing
RLAPI void EndDrawing(void); // End canvas drawing and swap buffers (double buffering)
RLAPI void ClearBackground(Color color); // Clear background (framebuffer) to color
RLAPI void BeginDrawing(void); // Begin canvas (framebuffer) drawing
RLAPI void EndDrawing(void); // End canvas (framebuffer) drawing and swap buffers (double buffering)
RLAPI void BeginMode2D(Camera2D camera); // Begin 2D mode with custom camera (2D)
RLAPI void EndMode2D(void); // Ends 2D mode with custom camera
RLAPI void EndMode2D(void); // End 2D mode with custom camera
RLAPI void BeginMode3D(Camera3D camera); // Begin 3D mode with custom camera (3D)
RLAPI void EndMode3D(void); // Ends 3D mode and returns to default 2D orthographic mode
RLAPI void EndMode3D(void); // End 3D mode and returns to default 2D orthographic mode
RLAPI void BeginTextureMode(RenderTexture2D target); // Begin drawing to render texture
RLAPI void EndTextureMode(void); // Ends drawing to render texture
RLAPI void EndTextureMode(void); // End drawing to render texture
RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing
RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader)
RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied, subtract, custom)
@ -1068,7 +1070,7 @@ RLAPI void UnloadVrStereoConfig(VrStereoConfig config); // Unload VR s
// NOTE: Shader functionality is not available on OpenGL 1.1
RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations
RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations
RLAPI bool IsShaderValid(Shader shader); // Check if a shader is valid (loaded on GPU)
RLAPI bool IsShaderValid(Shader shader); // Check if shader is valid (loaded on GPU)
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location
RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value
@ -1078,13 +1080,12 @@ RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture)
RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
// Screen-space-related functions
#define GetMouseRay GetScreenToWorldRay // Compatibility hack for previous raylib versions
RLAPI Ray GetScreenToWorldRay(Vector2 position, Camera camera); // Get a ray trace from screen position (i.e mouse)
RLAPI Ray GetScreenToWorldRayEx(Vector2 position, Camera camera, int width, int height); // Get a ray trace from screen position (i.e mouse) in a viewport
RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Get the screen space position for a 3d world space position
RLAPI Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height); // Get size position for a 3d world space position
RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get the screen space position for a 2d camera world space position
RLAPI Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera); // Get the world space position for a 2d camera screen space position
RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Get screen space position for a 3d world space position
RLAPI Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height); // Get sized screen space position for a 3d world space position
RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get screen space position for a 2d camera world space position
RLAPI Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera); // Get world space position for a 2d camera screen space position
RLAPI Matrix GetCameraMatrix(Camera camera); // Get camera transform matrix (view matrix)
RLAPI Matrix GetCameraMatrix2D(Camera2D camera); // Get camera 2d transform matrix
@ -1110,7 +1111,7 @@ RLAPI void UnloadRandomSequence(int *sequence); // Unload random values
// Misc. functions
RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (filename extension defines format)
RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS)
RLAPI void SetConfigFlags(unsigned int flags); // Set up init configuration flags (view FLAGS)
RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available)
// Logging system
@ -1126,7 +1127,7 @@ RLAPI void MemFree(void *ptr); // Internal memo
// File system management functions
RLAPI unsigned char *LoadFileData(const char *fileName, int *dataSize); // Load file data as byte array (read)
RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData()
RLAPI bool SaveFileData(const char *fileName, void *data, int dataSize); // Save data to file from byte array (write), returns true on success
RLAPI bool SaveFileData(const char *fileName, const void *data, int dataSize); // Save data to file from byte array (write), returns true on success
RLAPI bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName); // Export data to code (.h), returns true on success
RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string
RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText()
@ -1139,32 +1140,34 @@ RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custo
RLAPI void SetLoadFileTextCallback(LoadFileTextCallback callback); // Set custom file text data loader
RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom file text data saver
RLAPI int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists)
RLAPI int FileRemove(const char *fileName); // Remove file (if exists)
RLAPI int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist
RLAPI int FileMove(const char *srcPath, const char *dstPath); // Move file from one directory to another, dstPath created if it doesn't exist
RLAPI int FileTextReplace(const char *fileName, const char *search, const char *replacement); // Replace text in an existing file
RLAPI int FileTextFindIndex(const char *fileName, const char *search); // Find text in existing file
RLAPI int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists), returns 0 on success
RLAPI int FileRemove(const char *fileName); // Remove file (if exists), returns 0 on success
RLAPI int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist, returns 0 on success
RLAPI int FileMove(const char *srcPath, const char *dstPath); // Move file from one directory to another, dstPath created if it doesn't exist, returns 0 on success
RLAPI int FileTextReplace(const char *fileName, const char *search, const char *replacement); // Replace text in an existing file, returns 0 on success
RLAPI int FileTextFindIndex(const char *fileName, const char *search); // Find text in existing file, returns -1 if index not found or index otherwise
RLAPI bool FileExists(const char *fileName); // Check if file exists
RLAPI bool DirectoryExists(const char *dirPath); // Check if a directory path exists
RLAPI bool DirectoryExists(const char *dirPath); // Check if directory path exists
RLAPI bool IsFileExtension(const char *fileName, const char *ext); // Check file extension (recommended include point: .png, .wav)
RLAPI int GetFileLength(const char *fileName); // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h)
RLAPI long GetFileModTime(const char *fileName); // Get file modification time (last write time)
RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png')
RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string
RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string)
RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a given fileName with path (uses static string)
RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string)
RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a provided fileName with path (uses static string)
RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a provided path (uses static string)
RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string)
RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string)
RLAPI int MakeDirectory(const char *dirPath); // Create directories (including full path requested), returns 0 on success
RLAPI bool ChangeDirectory(const char *dirPath); // Change working directory, return true on success
RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory
RLAPI int ChangeDirectory(const char *dirPath); // Change working directory, returns 0 on success
RLAPI bool IsPathFile(const char *path); // Check if provided path points to a file
RLAPI bool IsPathDirectory(const char *path); // Check if provided path points to a directory
RLAPI bool IsPathAbsolute(const char *path); // Check if provided path is an absolute path
RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS
RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths, files and directories, no subdirs scan
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and subdir scan; some filters available: '*.*','FILES*','DIRS*'
RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths
RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
RLAPI bool IsFileDropped(void); // Check if file has been dropped into window
RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths
RLAPI void UnloadDroppedFiles(FilePathList files); // Unload dropped filepaths
RLAPI unsigned int GetDirectoryFileCount(const char *dirPath); // Get the file count in a directory
@ -1175,10 +1178,10 @@ RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string (includes NULL terminator), memory must be MemFree()
RLAPI unsigned char *DecodeDataBase64(const char *text, int *outputSize); // Decode Base64 string (expected NULL terminated), memory must be MemFree()
RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
RLAPI unsigned int *ComputeSHA256(unsigned char *data, int dataSize); // Compute SHA256 hash code, returns static int[8] (32 bytes)
RLAPI unsigned int ComputeCRC32(const unsigned char *data, int dataSize); // Compute CRC32 hash code
RLAPI unsigned int *ComputeMD5(const unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
RLAPI unsigned int *ComputeSHA1(const unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
RLAPI unsigned int *ComputeSHA256(const unsigned char *data, int dataSize); // Compute SHA256 hash code, returns static int[8] (32 bytes)
// Automation events functionality
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
@ -1195,23 +1198,23 @@ RLAPI void PlayAutomationEvent(AutomationEvent event); // Play a reco
//------------------------------------------------------------------------------------
// Input-related functions: keyboard
RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once
RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again
RLAPI bool IsKeyDown(int key); // Check if a key is being pressed
RLAPI bool IsKeyReleased(int key); // Check if a key has been released once
RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed
RLAPI bool IsKeyPressed(int key); // Check if key has been pressed once
RLAPI bool IsKeyPressedRepeat(int key); // Check if key has been pressed again
RLAPI bool IsKeyDown(int key); // Check if key is being pressed
RLAPI bool IsKeyReleased(int key); // Check if key has been released once
RLAPI bool IsKeyUp(int key); // Check if key is NOT being pressed
RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty
RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty
RLAPI const char *GetKeyName(int key); // Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard)
RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
// Input-related functions: gamepads
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available
RLAPI bool IsGamepadAvailable(int gamepad); // Check if gamepad is available
RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if gamepad button has been pressed once
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if gamepad button is being pressed
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if gamepad button has been released once
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if gamepad button is NOT being pressed
RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
RLAPI int GetGamepadAxisCount(int gamepad); // Get axis count for a gamepad
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get movement value for a gamepad axis
@ -1219,10 +1222,10 @@ RLAPI int SetGamepadMappings(const char *mappings); // Set internal ga
RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration); // Set gamepad vibration for both motors (duration in seconds)
// Input-related functions: mouse
RLAPI bool IsMouseButtonPressed(int button); // Check if a mouse button has been pressed once
RLAPI bool IsMouseButtonDown(int button); // Check if a mouse button is being pressed
RLAPI bool IsMouseButtonReleased(int button); // Check if a mouse button has been released once
RLAPI bool IsMouseButtonUp(int button); // Check if a mouse button is NOT being pressed
RLAPI bool IsMouseButtonPressed(int button); // Check if mouse button has been pressed once
RLAPI bool IsMouseButtonDown(int button); // Check if mouse button is being pressed
RLAPI bool IsMouseButtonReleased(int button); // Check if mouse button has been released once
RLAPI bool IsMouseButtonUp(int button); // Check if mouse button is NOT being pressed
RLAPI int GetMouseX(void); // Get mouse position X
RLAPI int GetMouseY(void); // Get mouse position Y
RLAPI Vector2 GetMousePosition(void); // Get mouse position XY
@ -1238,14 +1241,14 @@ RLAPI void SetMouseCursor(int cursor); // Set mouse curso
RLAPI int GetTouchX(void); // Get touch position X for touch point 0 (relative to screen size)
RLAPI int GetTouchY(void); // Get touch position Y for touch point 0 (relative to screen size)
RLAPI Vector2 GetTouchPosition(int index); // Get touch position XY for a touch point index (relative to screen size)
RLAPI int GetTouchPointId(int index); // Get touch point identifier for given index
RLAPI int GetTouchPointId(int index); // Get touch point identifier for provided index
RLAPI int GetTouchPointCount(void); // Get number of touch points
//------------------------------------------------------------------------------------
// Gestures and Touch Handling Functions (Module: rgestures)
//------------------------------------------------------------------------------------
RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if gesture has been detected
RLAPI int GetGestureDetected(void); // Get latest detected gesture
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in seconds
RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
@ -1265,7 +1268,7 @@ RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, f
// Set texture and rectangle to be used on shapes drawing
// NOTE: It can be useful when using basic shapes and one single font,
// defining a font char white rectangle would allow drawing everything in a single draw call
RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing
RLAPI void SetShapesTexture(Texture2D texture, Rectangle rec); // Set texture and rectangle to be used on shapes drawing
RLAPI Texture2D GetShapesTexture(void); // Get texture that is used for shapes drawing
RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing
@ -1278,38 +1281,44 @@ RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color
RLAPI void DrawLineStrip(const Vector2 *points, int pointCount, Color color); // Draw lines sequence (using gl lines)
RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw line segment cubic-bezier in-out interpolation
RLAPI void DrawLineDashed(Vector2 startPos, Vector2 endPos, int dashSize, int spaceSize, Color color); // Draw a dashed line
RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
RLAPI void DrawCircleGradient(Vector2 center, float radius, Color inner, Color outer); // Draw a gradient-filled circle
RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle
RLAPI void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline
RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
RLAPI void DrawCircleLinesV(Vector2 center, float radius, Color color); // Draw circle outline (Vector version)
RLAPI void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse
RLAPI void DrawEllipseV(Vector2 center, float radiusH, float radiusV, Color color); // Draw ellipse (Vector version)
RLAPI void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse outline
RLAPI void DrawEllipseLinesV(Vector2 center, float radiusH, float radiusV, Color color); // Draw ellipse outline (Vector version)
RLAPI void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring
RLAPI void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring outline
RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle, counter-clockwise vertex order
RLAPI void DrawTriangleGradient(Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3); // Draw triangle with interpolated colors, counter-clockwise vertex/color order
RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline, counter-clockwise vertex order
RLAPI void DrawTriangleLinesEx(Vector2 v1, Vector2 v2, Vector2 v3, float thick, Color color); // Draw triangle outline with line thickness, counter-clockwise vertex order
RLAPI void DrawTriangleFan(const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center)
RLAPI void DrawTriangleStrip(const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters
RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color top, Color bottom); // Draw a vertical-gradient-filled rectangle
RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color left, Color right); // Draw a horizontal-gradient-filled rectangle
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color topLeft, Color bottomLeft, Color bottomRight, Color topRight); // Draw a gradient-filled rectangle with custom vertex colors
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors, counter-clockwise color order
RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
RLAPI void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color); // Draw rectangle outline with extended parameters
RLAPI void DrawRectangleLinesEx(Rectangle rec, float thick, Color color); // Draw rectangle outline with line thickness
RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges
RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle lines with rounded edges
RLAPI void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline
RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!)
RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!)
RLAPI void DrawTriangleFan(const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center)
RLAPI void DrawTriangleStrip(const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
RLAPI void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float thick, Color color); // Draw rectangle lines with rounded edges outline and line thickness
RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon of n sides
RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides
RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters
RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float thick, Color color); // Draw a polygon outline of n sides with line thickness
RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
RLAPI void DrawCircleGradient(Vector2 center, float radius, Color inner, Color outer); // Draw a gradient-filled circle
RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle
RLAPI void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline
RLAPI void DrawCircleSectorLinesEx(Vector2 center, float radius, float startAngle, float endAngle, int segments, float thick, Color color); // Draw circle sector outline with thickness
RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
RLAPI void DrawCircleLinesV(Vector2 center, float radius, Color color); // Draw circle outline (Vector version)
RLAPI void DrawCircleLinesEx(Vector2 center, float radius, float thick, Color color); // Draw circle outline with line thickness
RLAPI void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse
RLAPI void DrawEllipseV(Vector2 center, float radiusH, float radiusV, Color color); // Draw ellipse (Vector version)
RLAPI void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse outline
RLAPI void DrawEllipseLinesV(Vector2 center, float radiusH, float radiusV, Color color); // Draw ellipse outline (Vector version)
RLAPI void DrawEllipseLinesEx(Vector2 center, float radiusH, float radiusV, float thick, Color color); // Draw ellipse outline with line thickness
RLAPI void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring
RLAPI void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring outline
RLAPI void DrawRingLinesEx(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, float thick, Color color); // Draw ring outline with line thickness
// Splines drawing functions
RLAPI void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points
@ -1323,18 +1332,18 @@ RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vecto
RLAPI void DrawSplineSegmentBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float thick, Color color); // Draw spline segment: Quadratic Bezier, 2 points, 1 control point
RLAPI void DrawSplineSegmentBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float thick, Color color); // Draw spline segment: Cubic Bezier, 2 points, 2 control points
// Spline segment point evaluation functions, for a given t [0.0f .. 1.0f]
// Spline segment point evaluation functions, for a provided t [0.0f .. 1.0f]
RLAPI Vector2 GetSplinePointLinear(Vector2 startPos, Vector2 endPos, float t); // Get (evaluate) spline point: Linear
RLAPI Vector2 GetSplinePointBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: B-Spline
RLAPI Vector2 GetSplinePointCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: Catmull-Rom
RLAPI Vector2 GetSplinePointBezierQuad(Vector2 p1, Vector2 c2, Vector2 p3, float t); // Get (evaluate) spline point: Quadratic Bezier
RLAPI Vector2 GetSplinePointBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float t); // Get (evaluate) spline point: Quadratic Bezier
RLAPI Vector2 GetSplinePointBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float t); // Get (evaluate) spline point: Cubic Bezier
// Basic shapes collision detection functions
RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created betweeen two points [p1] and [p2]
RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created between two points [p1] and [p2]
RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
@ -1355,7 +1364,7 @@ RLAPI Image LoadImageAnim(const char *fileName, int *frames);
RLAPI Image LoadImageAnimFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int *frames); // Load image sequence from memory buffer
RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png'
RLAPI Image LoadImageFromTexture(Texture2D texture); // Load image from GPU texture data
RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer and (screenshot)
RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer (screenshot)
RLAPI bool IsImageValid(Image image); // Check if an image is valid (data and parameters)
RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success
@ -1401,7 +1410,7 @@ RLAPI void ImageRotateCCW(Image *image);
RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint
RLAPI void ImageColorInvert(Image *image); // Modify image color: invert
RLAPI void ImageColorGrayscale(Image *image); // Modify image color: grayscale
RLAPI void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100)
RLAPI void ImageColorContrast(Image *image, int contrast); // Modify image color: contrast (-100 to 100)
RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255)
RLAPI void ImageColorReplace(Image *image, Color color, Color replace); // Modify image color: replace color
RLAPI Color *LoadImageColors(Image image); // Load color data from image as a Color array (RGBA - 32bit)
@ -1413,28 +1422,38 @@ RLAPI Color GetImageColor(Image image, int x, int y);
// Image drawing functions
// NOTE: Image software-rendering functions (CPU)
RLAPI void ImageClearBackground(Image *dst, Color color); // Clear image background with given color
RLAPI void ImageClearBackground(Image *dst, Color color); // Clear image background with provided color
RLAPI void ImageDrawPixel(Image *dst, int posX, int posY, Color color); // Draw pixel within an image
RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version)
RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image
RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version)
RLAPI void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color color); // Draw a line defining thickness within an image
RLAPI void ImageDrawLineStrip(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a lines sequence within an image
RLAPI void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle within an image
RLAPI void ImageDrawTriangleGradient(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3); // Draw triangle with interpolated colors within an image
RLAPI void ImageDrawTriangleLines(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline within an image
RLAPI void ImageDrawTriangleFan(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points within an image (first vertex is the center)
RLAPI void ImageDrawTriangleStrip(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points within an image
RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image
RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version)
RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image
RLAPI void ImageDrawRectanglePro(Image *dst, Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters within and image
RLAPI void ImageDrawRectangleLines(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle lines within an image
RLAPI void ImageDrawRectangleLinesEx(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image with line thickness
RLAPI void ImageDrawRectangleGradientEx(Image *dst, Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw rectangle with gradient colors within an image, counter-clockwise color order
RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color); // Draw a filled circle within an image
RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw a filled circle within an image (Vector version)
RLAPI void ImageDrawCircleLines(Image *dst, int centerX, int centerY, int radius, Color color); // Draw circle outline within an image
RLAPI void ImageDrawCircleLinesV(Image *dst, Vector2 center, int radius, Color color); // Draw circle outline within an image (Vector version)
RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image
RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version)
RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image
RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image
RLAPI void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle within an image
RLAPI void ImageDrawTriangleEx(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3); // Draw triangle with interpolated colors within an image
RLAPI void ImageDrawTriangleLines(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline within an image
RLAPI void ImageDrawTriangleFan(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points within an image (first vertex is the center)
RLAPI void ImageDrawTriangleStrip(Image *dst, const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points within an image
RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source)
RLAPI void ImageDrawCircleGradient(Image *dst, Vector2 center, float radius, Color inner, Color outer); // Draw a gradient-filled circle within an image
RLAPI void ImageDrawImage(Image *dst, Image src, int posX, int posY, Color tint); // Draw an image within an image
RLAPI void ImageDrawImageEx(Image *dst, Image src, Vector2 position, float rotation, float scale, Color tint); // Draw an image with scaling and rotation within an image
RLAPI void ImageDrawImageRec(Image *dst, Image src, Rectangle srcRec, Vector2 position, Color tint); // Draw a part of an image defined by a rectangle within an image
RLAPI void ImageDrawImagePro(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Vector2 origin, float rotation, Color tint); // Draw a part of an image defined by a rectangle into destination rectangle, with scaling and rotation, within an image
RLAPI void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination)
RLAPI void ImageDrawTextEx(Image *dst, Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text (custom sprite font) within an image (destination)
RLAPI void ImageDrawTextPro(Image *dst, Font font, const char *text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint); // Draw text using Font and pro parameters (rotation)
// Texture loading functions
// NOTE: These functions require GPU access
@ -1442,9 +1461,9 @@ RLAPI Texture2D LoadTexture(const char *fileName);
RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data
RLAPI TextureCubemap LoadTextureCubemap(Image image, int layout); // Load cubemap from image, multiple image cubemap layouts supported
RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer)
RLAPI bool IsTextureValid(Texture2D texture); // Check if a texture is valid (loaded in GPU)
RLAPI bool IsTextureValid(Texture2D texture); // Check if texture is valid (loaded in GPU)
RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM)
RLAPI bool IsRenderTextureValid(RenderTexture2D target); // Check if a render texture is valid (loaded in GPU)
RLAPI bool IsRenderTextureValid(RenderTexture2D target); // Check if render texture is valid (loaded in GPU)
RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM)
RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data (pixels should be able to fill texture)
RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data (pixels and rec should fit in texture)
@ -1457,10 +1476,10 @@ RLAPI void SetTextureWrap(Texture2D texture, int wrap);
// Texture drawing functions
RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
RLAPI void DrawTextureRec(Texture2D texture, Rectangle source, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
RLAPI void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a rectangle with 'pro' parameters
RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draws a texture (or part of it) that stretches or shrinks nicely
RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with rotation and scale
RLAPI void DrawTextureRec(Texture2D texture, Rectangle rec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
RLAPI void DrawTexturePro(Texture2D texture, Rectangle srcrec, Rectangle dstrec, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a source rectangle to destination rectangle, with scaling and rotation
RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dstrec, Vector2 origin, float rotation, Color tint); // Draw a texture (or part of it) that stretches or shrinks nicely
// Color/pixel related functions
RLAPI bool ColorIsEqual(Color col1, Color col2); // Check if two colors are equal
@ -1477,7 +1496,7 @@ RLAPI Color ColorAlpha(Color color, float alpha); // G
RLAPI Color ColorAlphaBlend(Color dst, Color src, Color tint); // Get src alpha-blended into dst color with tint
RLAPI Color ColorLerp(Color color1, Color color2, float factor); // Get color lerp interpolation between two colors, factor [0.0f..1.0f]
RLAPI Color GetColor(unsigned int hexValue); // Get Color structure from hexadecimal value
RLAPI Color GetPixelColor(void *srcPtr, int format); // Get Color from a source pixel pointer of certain format
RLAPI Color GetPixelColor(const void *srcPtr, int format); // Get Color from a source pixel pointer of certain format
RLAPI void SetPixelColor(void *dstPtr, Color color, int format); // Set color formatted into destination pixel pointer
RLAPI int GetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes for certain format
@ -1488,10 +1507,10 @@ RLAPI int GetPixelDataSize(int width, int height, int format); // G
// Font loading/unloading functions
RLAPI Font GetFontDefault(void); // Get the default Font
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
RLAPI Font LoadFontEx(const char *fileName, int fontSize, const int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height
RLAPI Font LoadFontEx(const char *fileName, int fontSize, const int *codepoints, int codepointCount); // Load font from file with defined codepoints and generation size, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height
RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style)
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, const int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
RLAPI bool IsFontValid(Font font); // Check if a font is valid (font data loaded, WARNING: GPU texture not checked)
RLAPI bool IsFontValid(Font font); // Check if font is valid (font data loaded, WARNING: GPU texture not checked)
RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, const int *codepoints, int codepointCount, int type, int *glyphCount); // Load font data for further use
RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info
RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount); // Unload font chars info data (RAM)
@ -1504,7 +1523,7 @@ RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color co
RLAPI void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters
RLAPI void DrawTextPro(Font font, const char *text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint); // Draw text using Font and pro parameters (rotation)
RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint)
RLAPI void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple character (codepoint)
RLAPI void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple characters (codepoint)
// Text font info functions
RLAPI void SetTextLineSpacing(int spacing); // Set vertical line spacing when drawing with line-breaks
@ -1532,7 +1551,7 @@ RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size);
RLAPI char **LoadTextLines(const char *text, int *count); // Load text as separate lines ('\n')
RLAPI void UnloadTextLines(char **text, int lineCount); // Unload text lines
RLAPI int TextCopy(char *dst, const char *src); // Copy one string to another, returns bytes copied
RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal
RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text strings are equal
RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending
RLAPI const char *TextFormat(const char *text, ...); // Text formatting with variables (sprintf() style)
RLAPI const char *TextSubtext(const char *text, int position, int length); // Get a piece of a text string
@ -1564,21 +1583,21 @@ RLAPI float TextToFloat(const char *text);
RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space
RLAPI void DrawPoint3D(Vector3 position, Color color); // Draw a point in 3D space, actually a small line
RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space
RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!)
RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle, counter-clockwise vertex order
RLAPI void DrawTriangleStrip3D(const Vector3 *points, int pointCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube
RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires
RLAPI void DrawCubeWiresV(Vector3 position, Vector3 size, Color color); // Draw cube wires (Vector version)
RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with defined rings and slices
RLAPI void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int sides, Color color); // Draw a cylinder/cone
RLAPI void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder with base at startPos and top at endPos
RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int sides, Color color); // Draw a cylinder/cone wires
RLAPI void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder wires with base at startPos and top at endPos
RLAPI void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw a capsule with the center of its sphere caps at startPos and endPos
RLAPI void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw capsule wireframe with the center of its sphere caps at startPos and endPos
RLAPI void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int rings, int slices, Color color); // Draw a capsule with the center of its sphere caps at startPos and endPos
RLAPI void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int rings, int slices, Color color); // Draw capsule wireframe with the center of its sphere caps at startPos and endPos
RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line
RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
@ -1590,19 +1609,19 @@ RLAPI void DrawGrid(int slices, float spacing);
// Model management functions
RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials)
RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material)
RLAPI bool IsModelValid(Model model); // Check if a model is valid (loaded in GPU, VAO/VBOs)
RLAPI bool IsModelValid(Model model); // Check if model is valid (loaded in GPU, VAO/VBOs)
RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM)
RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes)
// Model drawing functions
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with custom transform
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires with custom transform
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a billboard texture
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle rec, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by rectangle
RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle rec, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source rectangle with scaling and rotation
// Mesh management functions
RLAPI void UploadMesh(Mesh *mesh, bool dynamic); // Upload mesh vertex data in GPU and provide VAO/VBO ids
@ -1631,7 +1650,7 @@ RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
// Material loading/unloading functions
RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file
RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
RLAPI bool IsMaterialValid(Material material); // Check if a material is valid (shader assigned, map textures loaded in GPU)
RLAPI bool IsMaterialValid(Material material); // Check if material is valid (shader assigned, map textures loaded in GPU)
RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...)
RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh
@ -1668,15 +1687,15 @@ RLAPI float GetMasterVolume(void); // Get mas
// Wave/Sound loading/unloading functions
RLAPI Wave LoadWave(const char *fileName); // Load wave data from file
RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav'
RLAPI bool IsWaveValid(Wave wave); // Checks if wave data is valid (data loaded and parameters)
RLAPI bool IsWaveValid(Wave wave); // Check if wave data is valid (data loaded and parameters)
RLAPI Sound LoadSound(const char *fileName); // Load sound from file
RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
RLAPI Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data
RLAPI bool IsSoundValid(Sound sound); // Checks if a sound is valid (data loaded and buffers initialized)
RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data (default data format: 32 bit float, stereo)
RLAPI Sound LoadSoundAlias(Sound source); // Load sound alias, new sound that shares the same sample data as the source sound, does not own the sound data
RLAPI bool IsSoundValid(Sound sound); // Check if sound is valid (data loaded and buffers initialized)
RLAPI void UpdateSound(Sound sound, const void *data, int frameCount); // Update sound buffer with new data (default data format: 32 bit float, stereo)
RLAPI void UnloadWave(Wave wave); // Unload wave data
RLAPI void UnloadSound(Sound sound); // Unload sound
RLAPI void UnloadSoundAlias(Sound alias); // Unload a sound alias (does not deallocate sample data)
RLAPI void UnloadSoundAlias(Sound alias); // Unload sound alias (does not deallocate sample data)
RLAPI bool ExportWave(Wave wave, const char *fileName); // Export wave data to file, returns true on success
RLAPI bool ExportWaveAsCode(Wave wave, const char *fileName); // Export wave sample data to code (.h), returns true on success
@ -1685,7 +1704,7 @@ RLAPI void PlaySound(Sound sound); // Play a
RLAPI void StopSound(Sound sound); // Stop playing a sound
RLAPI void PauseSound(Sound sound); // Pause a sound
RLAPI void ResumeSound(Sound sound); // Resume a paused sound
RLAPI bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
RLAPI bool IsSoundPlaying(Sound sound); // Check if sound is currently playing
RLAPI void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
RLAPI void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
RLAPI void SetSoundPan(Sound sound, float pan); // Set pan for a sound (-1.0 left, 0.0 center, 1.0 right)
@ -1698,24 +1717,24 @@ RLAPI void UnloadWaveSamples(float *samples); // Unload
// Music management functions
RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file
RLAPI Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize); // Load music stream from data
RLAPI bool IsMusicValid(Music music); // Checks if a music stream is valid (context and buffers initialized)
RLAPI bool IsMusicValid(Music music); // Check if music stream is valid (context and buffers initialized)
RLAPI void UnloadMusicStream(Music music); // Unload music stream
RLAPI void PlayMusicStream(Music music); // Start music playing
RLAPI bool IsMusicStreamPlaying(Music music); // Check if music is playing
RLAPI void UpdateMusicStream(Music music); // Updates buffers for music streaming
RLAPI void UpdateMusicStream(Music music); // Update buffers for music streaming
RLAPI void StopMusicStream(Music music); // Stop music playing
RLAPI void PauseMusicStream(Music music); // Pause music playing
RLAPI void ResumeMusicStream(Music music); // Resume playing paused music
RLAPI void SeekMusicStream(Music music, float position); // Seek music to a position (in seconds)
RLAPI void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level)
RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level)
RLAPI void SetMusicPan(Music music, float pan); // Set pan for a music (-1.0 left, 0.0 center, 1.0 right)
RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for music (1.0 is base level)
RLAPI void SetMusicPan(Music music, float pan); // Set pan for music (-1.0 left, 0.0 center, 1.0 right)
RLAPI float GetMusicTimeLength(Music music); // Get music time length (in seconds)
RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
// AudioStream management functions
RLAPI AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data)
RLAPI bool IsAudioStreamValid(AudioStream stream); // Checks if an audio stream is valid (buffers initialized)
RLAPI bool IsAudioStreamValid(AudioStream stream); // Check if an audio stream is valid (buffers initialized)
RLAPI void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory
RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int frameCount); // Update audio stream buffers with data
RLAPI bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
@ -1726,7 +1745,7 @@ RLAPI bool IsAudioStreamPlaying(AudioStream stream); // Check i
RLAPI void StopAudioStream(AudioStream stream); // Stop audio stream
RLAPI void SetAudioStreamVolume(AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level)
RLAPI void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level)
RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan for audio stream (-1.0 to 1.0 range, 0.0 is centered)
RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan for audio stream (-1.0 left, 0.0 center, 1.0 right)
RLAPI void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams
RLAPI void SetAudioStreamCallback(AudioStream stream, AudioCallback callback); // Audio thread callback to request new data

View file

@ -1,6 +1,6 @@
/**********************************************************************************************
*
* raymath v2.0 - Math functions to work with Vector2, Vector3, Matrix and Quaternions
* raymath v2.0 - Math functions to work with Vector2, Vector3, Vector4, Matrix and Quaternions
*
* CONVENTIONS:
* - Matrix structure is defined as row-major (memory layout) but parameters naming AND all
@ -2714,13 +2714,13 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
stabilizer = fmaxf(stabilizer, fabsf(matColumns[i].y));
stabilizer = fmaxf(stabilizer, fabsf(matColumns[i].z));
}
matColumns[0] = Vector3Scale(matColumns[0], 1.0f / stabilizer);
matColumns[1] = Vector3Scale(matColumns[1], 1.0f / stabilizer);
matColumns[2] = Vector3Scale(matColumns[2], 1.0f / stabilizer);
matColumns[0] = Vector3Scale(matColumns[0], 1.0f/stabilizer);
matColumns[1] = Vector3Scale(matColumns[1], 1.0f/stabilizer);
matColumns[2] = Vector3Scale(matColumns[2], 1.0f/stabilizer);
// X Scale
scl.x = Vector3Length(matColumns[0]);
if (scl.x > eps) matColumns[0] = Vector3Scale(matColumns[0], 1.0f / scl.x);
if (scl.x > eps) matColumns[0] = Vector3Scale(matColumns[0], 1.0f/scl.x);
// Compute XY shear and make col2 orthogonal
shear[0] = Vector3DotProduct(matColumns[0], matColumns[1]);
@ -2730,7 +2730,7 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
scl.y = Vector3Length(matColumns[1]);
if (scl.y > eps)
{
matColumns[1] = Vector3Scale(matColumns[1], 1.0f / scl.y);
matColumns[1] = Vector3Scale(matColumns[1], 1.0f/scl.y);
shear[0] /= scl.y; // Correct XY shear
}
@ -2744,7 +2744,7 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
scl.z = Vector3Length(matColumns[2]);
if (scl.z > eps)
{
matColumns[2] = Vector3Scale(matColumns[2], 1.0f / scl.z);
matColumns[2] = Vector3Scale(matColumns[2], 1.0f/scl.z);
shear[1] /= scl.z; // Correct XZ shear
shear[2] /= scl.z; // Correct YZ shear
}
@ -2802,6 +2802,11 @@ inline const Vector2& operator -= (Vector2& lhs, const Vector2& rhs)
return lhs;
}
inline Vector2 operator * (const float& lhs, const Vector2& rhs)
{
return Vector2Scale(rhs, lhs);
}
inline Vector2 operator * (const Vector2& lhs, const float& rhs)
{
return Vector2Scale(lhs, rhs);
@ -2896,6 +2901,11 @@ inline const Vector3& operator -= (Vector3& lhs, const Vector3& rhs)
return lhs;
}
inline Vector3 operator * (const float& lhs, const Vector3& rhs)
{
return Vector3Scale(rhs, lhs);
}
inline Vector3 operator * (const Vector3& lhs, const float& rhs)
{
return Vector3Scale(lhs, rhs);
@ -2991,6 +3001,11 @@ inline const Vector4& operator -= (Vector4& lhs, const Vector4& rhs)
return lhs;
}
inline Vector4 operator * (const float& lhs, const Vector4& rhs)
{
return Vector4Scale(rhs, lhs);
}
inline Vector4 operator * (const Vector4& lhs, const float& rhs)
{
return Vector4Scale(lhs, rhs);

View file

@ -106,11 +106,16 @@
#include "config.h" // Defines module configuration flags
#include <stdlib.h> // Required for: srand(), rand(), atexit(), exit()
#include <stdlib.h> // Required for: srand(), rand(), exit()
#include <stdio.h> // Required for: FILE, fopen(), fseek(), ftell(), fread(), fwrite(), fprintf(), vprintf(), fclose(), sprintf() [Used in OpenURL()]
#include <string.h> // Required for: strlen(), strncpy(), strcmp(), strrchr(), memset(), strcat()
#include <string.h> // Required for: strlen(), strcmp(), strrchr(), memset(), memcpy(), strcat()
#include <stdarg.h> // Required for: va_list, va_start(), va_end() [Used in TraceLog()]
#ifndef PICO_RP2350
#include <time.h> // Required for: time() [Used in InitTimer()]
#else
#include "pico/rand.h" // Pico doesn't implement time, and will implement its own hardware timer elsewhere. However, we need something to get a random seed from...
#endif
#include <math.h> // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()]
#if defined(PLATFORM_MEMORY) || defined(PLATFORM_WEB)
@ -385,7 +390,7 @@ typedef struct CoreData {
double draw; // Time measure for frame draw (seconds)
double frame; // Time measure for one frame (seconds)
double target; // Desired time for one frame, if 0 not applied (seconds)
unsigned long long int base; // Base time measure for hi-res timer (ticks or nanoseconds)
unsigned long long base; // Base time measure for hi-res timer (ticks or nanoseconds)
unsigned int frameCounter; // Frame counter (frames)
} Time;
@ -442,18 +447,6 @@ typedef enum AutomationEventType {
ACTION_SETTARGETFPS // param[0]: fps
} AutomationEventType;
// Event type to config events flags
// WARNING: Not used at the moment
typedef enum {
EVENT_INPUT_KEYBOARD = 0,
EVENT_INPUT_MOUSE = 1,
EVENT_INPUT_GAMEPAD = 2,
EVENT_INPUT_TOUCH = 4,
EVENT_INPUT_GESTURE = 8,
EVENT_WINDOW = 16,
EVENT_CUSTOM = 32
} EventType;
// Event type name strings, required for export
static const char *autoEventTypeName[] = {
"EVENT_NONE",
@ -482,16 +475,6 @@ static const char *autoEventTypeName[] = {
"ACTION_SETTARGETFPS"
};
/*
// Automation event (24 bytes)
// NOTE: Opaque struct, internal to raylib
struct AutomationEvent {
unsigned int frame; // Event frame
unsigned int type; // Event type (AutomationEventType)
int params[4]; // Event parameters (if required)
};
*/
static AutomationEventList *currentEventList = NULL; // Current automation events list, set by user, keep internal pointer
static bool automationEventRecording = false; // Recording automation events flag
//static short automationEventEnabled = 0b0000001111111111; // TODO: Automation events enabled for recording/playing
@ -528,11 +511,11 @@ __declspec(dllimport) void __stdcall Sleep(unsigned long msTimeout); // Required
const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
#endif
// NOTE: PLATFORM_DESKTOP defaults to GLFW backend
#if defined(PLATFORM_DESKTOP)
#define PLATFORM_DESKTOP_GLFW
#endif
// Include platform-specific submodules
#if defined(PLATFORM_DESKTOP_GLFW)
#include "platforms/rcore_desktop_glfw.c"
@ -735,8 +718,12 @@ void InitWindow(int width, int height, const char *title)
CORE.Time.frameCounter = 0;
CORE.Window.shouldClose = false;
// Initialize random seed
// Initialize random seed using available timer source instead of standard time() on embedded platforms
#ifndef PICO_RP2350
SetRandomSeed((unsigned int)time(NULL));
#else
SetRandomSeed(get_rand_32());
#endif
TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", GetWorkingDirectory());
}
@ -869,14 +856,14 @@ bool IsCursorOnScreen(void)
// Module Functions Definition: Screen Drawing
//----------------------------------------------------------------------------------
// Set background color (framebuffer clear color)
// Clear background (framebuffer) to color
void ClearBackground(Color color)
{
rlClearColor(color.r, color.g, color.b, color.a); // Set clear color
rlClearScreenBuffers(); // Clear current framebuffers
}
// Setup canvas (framebuffer) to start drawing
// Begin canvas (framebuffer) drawing
void BeginDrawing(void)
{
// WARNING: Previously to BeginDrawing() other render textures drawing could happen,
@ -893,7 +880,7 @@ void BeginDrawing(void)
// NOTE: Not required with OpenGL 3.3+
}
// End canvas drawing and swap buffers (double buffering)
// End canvas (framebuffer) drawing and swap buffers (double buffering)
void EndDrawing(void)
{
rlDrawRenderBatchActive(); // Update and draw internal render batch
@ -949,7 +936,7 @@ void BeginMode2D(Camera2D camera)
rlMultMatrixf(MatrixToFloat(GetCameraMatrix2D(camera)));
}
// Ends 2D mode with custom camera
// End 2D mode with custom camera
void EndMode2D(void)
{
rlDrawRenderBatchActive(); // Update and draw internal render batch
@ -998,7 +985,7 @@ void BeginMode3D(Camera camera)
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
}
// Ends 3D mode and returns to default 2D orthographic mode
// End 3D mode and returns to default 2D orthographic mode
void EndMode3D(void)
{
rlDrawRenderBatchActive(); // Update and draw internal render batch
@ -1045,7 +1032,7 @@ void BeginTextureMode(RenderTexture2D target)
CORE.Window.usingFbo = true;
}
// Ends drawing to render texture
// End drawing to render texture
void EndTextureMode(void)
{
rlDrawRenderBatchActive(); // Update and draw internal render batch
@ -1315,7 +1302,7 @@ Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
return shader;
}
// Check if a shader is valid (loaded on GPU)
// Check if shader is valid (loaded on GPU)
bool IsShaderValid(Shader shader)
{
return ((shader.id > 0) && // Validate shader id (GPU loaded successfully)
@ -1514,7 +1501,7 @@ Matrix GetCameraMatrix2D(Camera2D camera)
return matTransform;
}
// Get the screen space position from a 3d world space position
// Get screen space position from a 3d world space position
Vector2 GetWorldToScreen(Vector3 position, Camera camera)
{
Vector2 screenPosition = GetWorldToScreenEx(position, camera, GetScreenWidth(), GetScreenHeight());
@ -1522,7 +1509,7 @@ Vector2 GetWorldToScreen(Vector3 position, Camera camera)
return screenPosition;
}
// Get size position for a 3d world space position (useful for texture drawing)
// Get sized screen space position for a 3d world space position (useful for texture drawing)
Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height)
{
// Calculate projection matrix (from perspective instead of frustum
@ -1564,7 +1551,7 @@ Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int heigh
return screenPosition;
}
// Get the screen space position for a 2d camera world space position
// Get screen space position for a 2d camera world space position
Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera)
{
Matrix matCamera = GetCameraMatrix2D(camera);
@ -1573,7 +1560,7 @@ Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera)
return (Vector2){ transform.x, transform.y };
}
// Get the world space position for a 2d camera screen space position
// Get world space position for a 2d camera screen space position
Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera)
{
Matrix invMatCamera = MatrixInvert(GetCameraMatrix2D(camera));
@ -1757,9 +1744,9 @@ int GetRandomValue(int min, int max)
else
{
// Rejection sampling to get a uniform integer in [min, max]
unsigned long c = (unsigned long)RAND_MAX + 1UL; // number of possible rand() results
unsigned long m = (unsigned long)range; // size of the target interval
unsigned long t = c - (c%m); // largest multiple of m <= c
unsigned long c = (unsigned long)RAND_MAX + 1UL; // Number of possible results
unsigned long m = (unsigned long)range; // Size of the target interval
unsigned long t = c - (c%m); // Largest multiple of m <= c
unsigned long r = 0;
for (;;)
@ -1826,7 +1813,6 @@ void UnloadRandomSequence(int *sequence)
}
// Takes a screenshot of current screen
// NOTE: Provided fileName should not contain paths, saving to working directory
void TakeScreenshot(const char *fileName)
{
#if SUPPORT_MODULE_RTEXTURES
@ -1841,7 +1827,8 @@ void TakeScreenshot(const char *fileName)
Image image = { imgData, (int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y), 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
char path[MAX_FILEPATH_LENGTH] = { 0 };
strncpy(path, TextFormat("%s/%s", CORE.Storage.basePath, fileName), MAX_FILEPATH_LENGTH - 1);
if (!IsPathAbsolute(fileName)) snprintf(path, MAX_FILEPATH_LENGTH, "%s", TextFormat("%s/%s", CORE.Storage.basePath, fileName));
else snprintf(path, MAX_FILEPATH_LENGTH, "%s", fileName);
ExportImage(image, path); // WARNING: Module required: rtextures
RL_FREE(imgData);
@ -1853,7 +1840,7 @@ void TakeScreenshot(const char *fileName)
#endif
}
// Setup window configuration flags (view FLAGS)
// Set up window configuration flags (view FLAGS)
// NOTE: This function is expected to be called before window creation,
// because it sets up some flags for the window creation process
// To configure window states after creation, use SetWindowState()
@ -1866,8 +1853,6 @@ void SetConfigFlags(unsigned int flags)
FLAG_SET(CORE.Window.flags, flags);
}
// void OpenURL(const char *url); // Defined per platform
//----------------------------------------------------------------------------------
// Module Functions Definition: Logging system
//----------------------------------------------------------------------------------
@ -1907,12 +1892,12 @@ void TraceLog(int logType, const char *text, ...)
switch (logType)
{
case LOG_TRACE: strncpy(buffer, "TRACE: ", 8); break;
case LOG_DEBUG: strncpy(buffer, "DEBUG: ", 8); break;
case LOG_INFO: strncpy(buffer, "INFO: ", 7); break;
case LOG_WARNING: strncpy(buffer, "WARNING: ", 10); break;
case LOG_ERROR: strncpy(buffer, "ERROR: ", 8); break;
case LOG_FATAL: strncpy(buffer, "FATAL: ", 8); break;
case LOG_TRACE: memcpy(buffer, "TRACE: ", 7); break;
case LOG_DEBUG: memcpy(buffer, "DEBUG: ", 7); break;
case LOG_INFO: memcpy(buffer, "INFO: ", 6); break;
case LOG_WARNING: memcpy(buffer, "WARNING: ", 9); break;
case LOG_ERROR: memcpy(buffer, "ERROR: ", 7); break;
case LOG_FATAL: memcpy(buffer, "FATAL: ", 7); break;
default: break;
}
@ -1992,7 +1977,7 @@ unsigned char *LoadFileData(const char *fileName, int *dataSize)
size_t count = fread(data, sizeof(unsigned char), size, file);
// WARNING: fread() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation)
// dataSize is unified along raylib as a 'int' type, so, for file-sizes > INT_MAX (2147483647 bytes) there is a limitation
// dataSize is unified along raylib as a 'int' type, so, for file-sizes >INT_MAX (2147483647 bytes) there is a limitation
if (count > 2147483647)
{
TRACELOG(LOG_WARNING, "FILEIO: [%s] File is bigger than 2147483647 bytes, avoid using LoadFileData()", fileName);
@ -2004,7 +1989,7 @@ unsigned char *LoadFileData(const char *fileName, int *dataSize)
{
*dataSize = (int)count;
if ((*dataSize) != size) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially loaded (%i bytes out of %i)", fileName, dataSize, count);
if ((*dataSize) != size) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially loaded (%i bytes out of %i)", fileName, *dataSize, size);
else TRACELOG(LOG_INFO, "FILEIO: [%s] File loaded successfully", fileName);
}
}
@ -2028,7 +2013,7 @@ void UnloadFileData(unsigned char *data)
}
// Save data to file from buffer
bool SaveFileData(const char *fileName, void *data, int dataSize)
bool SaveFileData(const char *fileName, const void *data, int dataSize)
{
bool result = false;
@ -2085,7 +2070,7 @@ bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileN
// Get file name from path
char varFileName[256] = { 0 };
strncpy(varFileName, GetFileNameWithoutExt(fileName), 256 - 1);
snprintf(varFileName, 256, "%s", GetFileNameWithoutExt(fileName));
for (int i = 0; varFileName[i] != '\0'; i++)
{
// Convert variable name to uppercase
@ -2227,13 +2212,12 @@ void SetSaveFileTextCallback(SaveFileTextCallback callback)
// NOTE: Only rename file name required, not full path
int FileRename(const char *fileName, const char *fileRename)
{
int result = 0;
int result = -1;
if (FileExists(fileName))
{
result = rename(fileName, fileRename);
}
else result = -1;
return result;
}
@ -2241,13 +2225,12 @@ int FileRename(const char *fileName, const char *fileRename)
// Remove file (if exists)
int FileRemove(const char *fileName)
{
int result = 0;
int result = -1;
if (FileExists(fileName))
{
result = remove(fileName);
}
else result = -1;
return result;
}
@ -2256,18 +2239,21 @@ int FileRemove(const char *fileName)
// NOTE: If destination path does not exist, it is created!
int FileCopy(const char *srcPath, const char *dstPath)
{
int result = 0;
int result = -1;
int srcDataSize = 0;
unsigned char *srcFileData = LoadFileData(srcPath, &srcDataSize);
// Create required paths if they do not exist
if (!DirectoryExists(GetDirectoryPath(dstPath)))
result = MakeDirectory(GetDirectoryPath(dstPath));
if (DirectoryExists(GetDirectoryPath(dstPath))) result = 0; // Already exists
else result = MakeDirectory(GetDirectoryPath(dstPath));
if (result == 0) // Directory created successfully (or already exists)
if (result == 0) // Directory created successfully or already exists
{
if ((srcFileData != NULL) && (srcDataSize > 0))
result = SaveFileData(dstPath, srcFileData, srcDataSize);
{
bool saved = SaveFileData(dstPath, srcFileData, srcDataSize);
if (saved) result = 0;
}
}
UnloadFileData(srcFileData);
@ -2283,8 +2269,18 @@ int FileMove(const char *srcPath, const char *dstPath)
if (FileExists(srcPath))
{
if (FileCopy(srcPath, dstPath) == 0) result = FileRemove(srcPath);
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to copy file to [%s]", srcPath, dstPath);
result = FileCopy(srcPath, dstPath);
if (result == 0)
{
// Make sure file has been correctly copied before removing
if (FileExists(dstPath) && (GetFileLength(srcPath) == GetFileLength(dstPath)))
{
result = FileRemove(srcPath);
if (result != 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to remove source file after copy", srcPath);
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to copy file to [%s]", srcPath, dstPath);
}
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Source file does not exist", srcPath);
@ -2295,16 +2291,18 @@ int FileMove(const char *srcPath, const char *dstPath)
// WARNING: DEPENDENCY: [rtext] module
int FileTextReplace(const char *fileName, const char *search, const char *replacement)
{
int result = 0;
int result = -1;
#if SUPPORT_MODULE_RTEXT
char *fileText = NULL;
char *fileTextUpdated = { 0 };
#if SUPPORT_MODULE_RTEXT
if (FileExists(fileName))
{
fileText = LoadFileText(fileName);
fileTextUpdated = TextReplaceAlloc(fileText, search, replacement);
result = SaveFileText(fileName, fileTextUpdated);
bool saved = SaveFileText(fileName, fileTextUpdated);
if (saved) result = 0;
MemFree(fileTextUpdated);
UnloadFileText(fileText);
}
@ -2337,7 +2335,7 @@ bool FileExists(const char *fileName)
{
bool result = false;
if (ACCESS(fileName) != -1) result = true;
if ((fileName != NULL) && (ACCESS(fileName) != -1)) result = true;
// NOTE: Alternatively, stat() can be used instead of access()
//#include <sys/stat.h>
@ -2362,8 +2360,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
{
int fileExtLength = (int)strlen(fileExt);
char fileExtLower[16] = { 0 };
char *fileExtLowerPtr = fileExtLower;
for (int i = 0; (i < fileExtLength) && (i < 16); i++)
for (int i = 0; (i < fileExtLength) && (i < 15); i++)
{
// Copy and convert to lower-case
if ((fileExt[i] >= 'A') && (fileExt[i] <= 'Z')) fileExtLower[i] = fileExt[i] + 32;
@ -2374,7 +2371,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
int extLength = (int)strlen(ext);
char *extList = (char *)RL_CALLOC(extLength + 1, 1);
char *extListPtrs[MAX_FILE_EXTENSIONS] = { 0 };
strncpy(extList, ext, extLength);
memcpy(extList, ext, extLength);
extListPtrs[0] = extList;
for (int i = 0; i < extLength; i++)
@ -2383,11 +2380,15 @@ bool IsFileExtension(const char *fileName, const char *ext)
if ((extList[i] >= 'A') && (extList[i] <= 'Z')) extList[i] += 32;
// Get pointer to next extension and add null-terminator
if ((extList[i] == ';') && (extCount < (MAX_FILE_EXTENSIONS - 1)))
if (extList[i] == ';')
{
extList[i] = '\0';
extListPtrs[extCount] = extList + i + 1;
extCount++;
if (extCount < MAX_FILE_EXTENSIONS)
{
extListPtrs[extCount] = extList + i + 1;
extCount++;
}
}
}
@ -2395,7 +2396,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
{
// Consider the case where extension provided
// does not start with the '.'
fileExtLowerPtr = fileExtLower;
char *fileExtLowerPtr = fileExtLower;
if (extListPtrs[i][0] != '.') fileExtLowerPtr++;
if (strcmp(fileExtLowerPtr, extListPtrs[i]) == 0)
@ -2411,7 +2412,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
return result;
}
// Check if a directory path exists
// Check if directory path exists
bool DirectoryExists(const char *dirPath)
{
bool result = false;
@ -2513,7 +2514,7 @@ const char *GetFileNameWithoutExt(const char *filePath)
if (filePath != NULL)
{
strncpy(fileName, GetFileName(filePath), MAX_FILENAME_LENGTH - 1); // Get filename.ext without path
snprintf(fileName, MAX_FILENAME_LENGTH, "%s", GetFileName(filePath)); // Get filename.ext without path
int fileNameLength = (int)strlen(fileName); // Get size in bytes
for (int i = fileNameLength; i > 0; i--) // Reverse search '.'
@ -2530,7 +2531,7 @@ const char *GetFileNameWithoutExt(const char *filePath)
return fileName;
}
// Get directory for a given filePath
// Get directory for a provided filePath
const char *GetDirectoryPath(const char *filePath)
{
/*
@ -2567,7 +2568,6 @@ const char *GetDirectoryPath(const char *filePath)
}
else
{
// NOTE: Be careful, strncpy() is not safe, it does not care about '\0'
char *dirPathPtr = dirPath;
if ((filePath[1] != ':') && (filePath[0] != '\\') && (filePath[0] != '/')) dirPathPtr += 2; // Skip drive letter, "C:"
memcpy(dirPathPtr, filePath, strlen(filePath) - (strlen(lastSlash) - 1));
@ -2578,24 +2578,32 @@ const char *GetDirectoryPath(const char *filePath)
return dirPath;
}
// Get previous directory path for a given path
// Get previous directory path for a provided path
const char *GetPrevDirectoryPath(const char *dirPath)
{
static char prevDirPath[MAX_FILEPATH_LENGTH] = { 0 };
memset(prevDirPath, 0, MAX_FILEPATH_LENGTH);
int dirPathLength = (int)strlen(dirPath);
if (dirPathLength <= 3) strncpy(prevDirPath, dirPath, MAX_FILEPATH_LENGTH - 1);
for (int i = (dirPathLength - 1); (i >= 0) && (dirPathLength > 3); i--)
const int lastIndex = (int)strlen(dirPath) - 1;
bool isFile = IsPathFile(dirPath);
for (int i = lastIndex; i >= 0; i--)
{
// If the character is a path separator.
if ((dirPath[i] == '\\') || (dirPath[i] == '/'))
{
// Check for root: "C:\" or "/"
if (((i == 2) && (dirPath[1] ==':')) || (i == 0)) i++;
// If this character is a leading '/' (e.g. the '/' in "/usr") or
// part of a drive root (e.g. "C:\"), include it with the result.
if ((i == 0) || ((i == 2) && (dirPath[1] == ':'))) i += 1;
// If this character is a trailing path separator (e.g. the last
// '/' in "/usr/bin/" or the last '\' in "C:\raylib\"), continue.
else if (i == lastIndex) continue;
strncpy(prevDirPath, dirPath, i);
break;
if (!isFile)
{
memcpy(prevDirPath, dirPath, i);
break;
}
else isFile = false;
}
}
@ -2608,7 +2616,7 @@ const char *GetWorkingDirectory(void)
static char currentDir[MAX_FILEPATH_LENGTH] = { 0 };
memset(currentDir, 0, MAX_FILEPATH_LENGTH);
char *path = GETCWD(currentDir, MAX_FILEPATH_LENGTH - 1);
char *path = GETCWD(currentDir, MAX_FILEPATH_LENGTH);
return path;
}
@ -2816,23 +2824,61 @@ int MakeDirectory(const char *dirPath)
}
// Change working directory, returns true on success
bool ChangeDirectory(const char *dirPath)
int ChangeDirectory(const char *dirPath)
{
bool result = CHDIR(dirPath);
// NOTE: On success, CHDIR() return 0; on error, returns -1 and errno is set to indicate the error,
// depending on the filesystem, other errors can be returned
int result = CHDIR(dirPath);
if (result != 0) TRACELOG(LOG_WARNING, "SYSTEM: Failed to change to directory: %s", dirPath);
else TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", dirPath);
return (result == 0);
return result;
}
// Check if a given path point to a file
// Check if provided path point to a file
bool IsPathFile(const char *path)
{
struct stat result = { 0 };
stat(path, &result);
bool result = false;
return S_ISREG(result.st_mode);
struct stat info = { 0 };
stat(path, &info);
if (S_ISREG(info.st_mode)) result = true;
return result;
}
// Check if provided path point to a directory
bool IsPathDirectory(const char *path)
{
bool result = false;
if (!IsPathFile(path)) result = true;
return result;
}
// Check if provided path is an absolute path
bool IsPathAbsolute(const char *path)
{
int result = false;
if ((path != NULL) && (path[0] != '\0'))
{
#if defined(_WIN32)
// Check UNC path (\\server\share)
if ((path[0] == '\\') && (path[1] == '\\')) result = true;
// Check path starts with a drive letter (e.g. C:\ or D:/)
else if ((((path[0] >= 'A') && (path[0] <= 'Z')) || ((path[0] >= 'a') && (path[0] <= 'z'))) &&
(path[1] != '\0') && (path[1] == ':') && (path[2] != '\0') && ((path[2] == '\\') || (path[2] == '/'))) result = true;
#else
// Check POSIX path, must start with /
if (path[0] == '/') result = true;
#endif
}
return result;
}
// Check if fileName is valid for the platform/OS
@ -2891,7 +2937,7 @@ bool IsFileNameValid(const char *fileName)
return valid;
}
// Check if a file has been dropped into window
// Check if file has been dropped into window
bool IsFileDropped(void)
{
bool result = false;
@ -2955,9 +3001,9 @@ unsigned int GetDirectoryFileCountEx(const char *basePath, const char *filter, b
{
// Construct new path from our base path
#if defined(_WIN32)
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s\\%s", basePath, entity->d_name);
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH, "%s\\%s", basePath, entity->d_name);
#else
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s/%s", basePath, entity->d_name);
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH, "%s/%s", basePath, entity->d_name);
#endif
// Don't add to count if path too long
if ((pathLength < 0) || (pathLength >= MAX_FILEPATH_LENGTH))
@ -3160,7 +3206,7 @@ unsigned char *DecodeDataBase64(const char *text, int *outputSize)
}
// Compute CRC32 hash code
unsigned int ComputeCRC32(unsigned char *data, int dataSize)
unsigned int ComputeCRC32(const unsigned char *data, int dataSize)
{
static unsigned int crcTable[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
@ -3206,7 +3252,7 @@ unsigned int ComputeCRC32(unsigned char *data, int dataSize)
// Compute MD5 hash code
// NOTE: Returns a static int[4] array (16 bytes)
unsigned int *ComputeMD5(unsigned char *data, int dataSize)
unsigned int *ComputeMD5(const unsigned char *data, int dataSize)
{
#define ROTATE_LEFT(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
@ -3266,7 +3312,7 @@ unsigned int *ComputeMD5(unsigned char *data, int dataSize)
memcpy(msg + newDataSize, &bitsLen, 4); // Append the len in bits at the end of the buffer
// Process the message in successive 512-bit chunks for each 512-bit chunk of message
for (int offset = 0; offset < newDataSize; offset += (512/8))
for (int offset = 0; offset < newDataSize; offset += 64) // 512/8
{
// Break chunk into sixteen 32-bit words w[j], 0 <= j <= 15
unsigned int *w = (unsigned int *)(msg + offset);
@ -3324,7 +3370,7 @@ unsigned int *ComputeMD5(unsigned char *data, int dataSize)
// Compute SHA-1 hash code
// NOTE: Returns a static int[5] array (20 bytes)
unsigned int *ComputeSHA1(unsigned char *data, int dataSize)
unsigned int *ComputeSHA1(const unsigned char *data, int dataSize)
{
#define SHA1_ROTATE_LEFT(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
@ -3352,27 +3398,27 @@ unsigned int *ComputeSHA1(unsigned char *data, int dataSize)
memcpy(msg, data, dataSize);
msg[dataSize] = 128; // Write the '1' bit
unsigned long long bitsLen = 8ULL * dataSize;
msg[newDataSize-1] = (unsigned char)(bitsLen);
msg[newDataSize-2] = (unsigned char)(bitsLen >> 8);
msg[newDataSize-3] = (unsigned char)(bitsLen >> 16);
msg[newDataSize-4] = (unsigned char)(bitsLen >> 24);
msg[newDataSize-5] = (unsigned char)(bitsLen >> 32);
msg[newDataSize-6] = (unsigned char)(bitsLen >> 40);
msg[newDataSize-7] = (unsigned char)(bitsLen >> 48);
msg[newDataSize-8] = (unsigned char)(bitsLen >> 56);
unsigned long long bitsLen = 8ULL*dataSize;
msg[newDataSize - 1] = (unsigned char)(bitsLen);
msg[newDataSize - 2] = (unsigned char)(bitsLen >> 8);
msg[newDataSize - 3] = (unsigned char)(bitsLen >> 16);
msg[newDataSize - 4] = (unsigned char)(bitsLen >> 24);
msg[newDataSize - 5] = (unsigned char)(bitsLen >> 32);
msg[newDataSize - 6] = (unsigned char)(bitsLen >> 40);
msg[newDataSize - 7] = (unsigned char)(bitsLen >> 48);
msg[newDataSize - 8] = (unsigned char)(bitsLen >> 56);
// Process the message in successive 512-bit chunks
for (int offset = 0; offset < newDataSize; offset += (512/8))
for (int offset = 0; offset < newDataSize; offset += 64) // 512/8
{
// Break chunk into sixteen 32-bit words w[j], 0 <= j <= 15
unsigned int w[80] = { 0 };
for (int i = 0; i < 16; i++)
{
w[i] = (msg[offset + (i*4) + 0] << 24) |
(msg[offset + (i*4) + 1] << 16) |
(msg[offset + (i*4) + 2] << 8) |
(msg[offset + (i*4) + 3]);
w[i] = ((unsigned int)msg[offset + (i*4) + 0] << 24) |
((unsigned int)msg[offset + (i*4) + 1] << 16) |
((unsigned int)msg[offset + (i*4) + 2] << 8) |
((unsigned int)msg[offset + (i*4) + 3]);
}
// Message schedule: extend the sixteen 32-bit words into eighty 32-bit words:
@ -3434,7 +3480,7 @@ unsigned int *ComputeSHA1(unsigned char *data, int dataSize)
// Compute SHA-256 hash code
// NOTE: Returns a static int[8] array (32 bytes)
unsigned int *ComputeSHA256(unsigned char *data, int dataSize)
unsigned int *ComputeSHA256(const unsigned char *data, int dataSize)
{
#define SHA256_ROTATE_RIGHT(x, c) ((x >> c) | (x << ((sizeof(unsigned int)*8) - c)))
#define SHA256_A0(x) (SHA256_ROTATE_RIGHT(x, 7) ^ SHA256_ROTATE_RIGHT(x, 18) ^ (x >> 3))
@ -3469,8 +3515,8 @@ unsigned int *ComputeSHA256(unsigned char *data, int dataSize)
hash[6] = 0x1f83d9ab;
hash[7] = 0x5be0cd19;
const unsigned long long int bitLen = ((unsigned long long int)dataSize)*8;
unsigned long long int paddedSize = dataSize + sizeof(dataSize);
const unsigned long long bitLen = 8ULL*dataSize;
unsigned long long paddedSize = dataSize + sizeof(dataSize);
paddedSize += (64 - (paddedSize%64));
unsigned char *buffer = (unsigned char *)RL_CALLOC(paddedSize, sizeof(unsigned char));
@ -3481,7 +3527,7 @@ unsigned int *ComputeSHA256(unsigned char *data, int dataSize)
buffer[(paddedSize - sizeof(bitLen)) + (i - 1)] = (bitLen >> (8*(sizeof(bitLen) - i))) & 0xFF;
}
for (unsigned long long int blockN = 0; blockN < paddedSize/64; blockN++)
for (unsigned long long blockN = 0; blockN < paddedSize/64; blockN++)
{
unsigned int a = hash[0];
unsigned int b = hash[1];
@ -3503,7 +3549,7 @@ unsigned int *ComputeSHA256(unsigned char *data, int dataSize)
}
for (int t = 16; t < 64; t++) w[t] = SHA256_A1(w[t - 2]) + w[t - 7] + SHA256_A0(w[t - 15]) + w[t - 16];
for (unsigned long long int t = 0; t < 64; t++)
for (int t = 0; t < 64; t++)
{
unsigned int e1 = (SHA256_ROTATE_RIGHT(e, 6) ^ SHA256_ROTATE_RIGHT(e, 11) ^ SHA256_ROTATE_RIGHT(e, 25));
unsigned int ch = ((e & f) ^ (~e & g));
@ -3594,10 +3640,14 @@ AutomationEventList LoadAutomationEventList(const char *fileName)
case 'c': sscanf(buffer, "c %i", &list.count); break;
case 'e':
{
sscanf(buffer, "e %d %d %d %d %d %d %[^\n]s", &list.events[counter].frame, &list.events[counter].type,
&list.events[counter].params[0], &list.events[counter].params[1], &list.events[counter].params[2], &list.events[counter].params[3], eventDesc);
if (counter < list.capacity)
{
sscanf(buffer, "e %d %d %d %d %d %d %63[^\n]s", &list.events[counter].frame, &list.events[counter].type,
&list.events[counter].params[0], &list.events[counter].params[1], &list.events[counter].params[2], &list.events[counter].params[3], eventDesc);
counter++;
counter++;
}
else TRACELOG(LOG_WARNING, "AUTOMATION: Event goes beyond automated list capacity (MAX: %u): %s", list.capacity, buffer);
} break;
default: break;
}
@ -3802,7 +3852,7 @@ void PlayAutomationEvent(AutomationEvent event)
// Module Functions Definition: Input Handling: Keyboard
//----------------------------------------------------------------------------------
// Check if a key has been pressed once
// Check if key has been pressed once
bool IsKeyPressed(int key)
{
bool pressed = false;
@ -3815,7 +3865,7 @@ bool IsKeyPressed(int key)
return pressed;
}
// Check if a key has been pressed again
// Check if key has been pressed again
bool IsKeyPressedRepeat(int key)
{
bool repeat = false;
@ -3828,7 +3878,7 @@ bool IsKeyPressedRepeat(int key)
return repeat;
}
// Check if a key is being pressed (key held down)
// Check if key is being pressed (key held down)
bool IsKeyDown(int key)
{
bool down = false;
@ -3841,7 +3891,7 @@ bool IsKeyDown(int key)
return down;
}
// Check if a key has been released once
// Check if key has been released once
bool IsKeyReleased(int key)
{
bool released = false;
@ -3854,7 +3904,7 @@ bool IsKeyReleased(int key)
return released;
}
// Check if a key is NOT being pressed (key not held down)
// Check if key is NOT being pressed (key not held down)
bool IsKeyUp(int key)
{
bool up = false;
@ -3925,12 +3975,12 @@ void SetExitKey(int key)
// NOTE: Functions with a platform-specific implementation on rcore_<platform>.c
//int SetGamepadMappings(const char *mappings)
// Check if a gamepad is available
// Check if gamepad is available
bool IsGamepadAvailable(int gamepad)
{
bool result = false;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad]) result = true;
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad]) result = true;
return result;
}
@ -3938,15 +3988,19 @@ bool IsGamepadAvailable(int gamepad)
// Get gamepad internal name id
const char *GetGamepadName(int gamepad)
{
return CORE.Input.Gamepad.name[gamepad];
const char *name = NULL;
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS)) name = CORE.Input.Gamepad.name[gamepad];
return name;
}
// Check if a gamepad button has been pressed once
// Check if gamepad button has been pressed once
bool IsGamepadButtonPressed(int gamepad, int button)
{
bool pressed = false;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
{
if ((CORE.Input.Gamepad.previousButtonState[gamepad][button] == 0) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1)) pressed = true;
}
@ -3954,12 +4008,12 @@ bool IsGamepadButtonPressed(int gamepad, int button)
return pressed;
}
// Check if a gamepad button is being pressed
// Check if gamepad button is being pressed
bool IsGamepadButtonDown(int gamepad, int button)
{
bool down = false;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
{
if (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1) down = true;
}
@ -3967,12 +4021,12 @@ bool IsGamepadButtonDown(int gamepad, int button)
return down;
}
// Check if a gamepad button has NOT been pressed once
// Check if gamepad button has NOT been pressed once
bool IsGamepadButtonReleased(int gamepad, int button)
{
bool released = false;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
{
if ((CORE.Input.Gamepad.previousButtonState[gamepad][button] == 1) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0)) released = true;
}
@ -3980,12 +4034,12 @@ bool IsGamepadButtonReleased(int gamepad, int button)
return released;
}
// Check if a gamepad button is NOT being pressed
// Check if gamepad button is NOT being pressed
bool IsGamepadButtonUp(int gamepad, int button)
{
bool up = false;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
{
if (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0) up = true;
}
@ -4003,7 +4057,11 @@ int GetGamepadButtonPressed(void)
// Get gamepad axis count
int GetGamepadAxisCount(int gamepad)
{
return CORE.Input.Gamepad.axisCount[gamepad];
int result = 0;
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS)) result = CORE.Input.Gamepad.axisCount[gamepad];
return result;
}
// Get axis movement vector for a gamepad
@ -4011,7 +4069,7 @@ float GetGamepadAxisMovement(int gamepad, int axis)
{
float value = ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER))? -1.0f : 0.0f;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXES))
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXES))
{
float movement = (value < 0.0f)? CORE.Input.Gamepad.axisState[gamepad][axis] : fabsf(CORE.Input.Gamepad.axisState[gamepad][axis]);
@ -4029,7 +4087,7 @@ float GetGamepadAxisMovement(int gamepad, int axis)
//void SetMousePosition(int x, int y)
//void SetMouseCursor(int cursor)
// Check if a mouse button has been pressed once
// Check if mouse button has been pressed once
bool IsMouseButtonPressed(int button)
{
bool pressed = false;
@ -4045,7 +4103,7 @@ bool IsMouseButtonPressed(int button)
return pressed;
}
// Check if a mouse button is being pressed
// Check if mouse button is being pressed
bool IsMouseButtonDown(int button)
{
bool down = false;
@ -4061,7 +4119,7 @@ bool IsMouseButtonDown(int button)
return down;
}
// Check if a mouse button has been released once
// Check if mouse button has been released once
bool IsMouseButtonReleased(int button)
{
bool released = false;
@ -4077,7 +4135,7 @@ bool IsMouseButtonReleased(int button)
return released;
}
// Check if a mouse button is NOT being pressed
// Check if mouse button is NOT being pressed
bool IsMouseButtonUp(int button)
{
bool up = false;
@ -4195,7 +4253,7 @@ Vector2 GetTouchPosition(int index)
return position;
}
// Get touch point identifier for given index
// Get touch point identifier for provided index
int GetTouchPointId(int index)
{
int id = -1;
@ -4235,7 +4293,7 @@ void InitTimer(void)
if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) // Success
{
CORE.Time.base = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec;
CORE.Time.base = (unsigned long long)now.tv_sec*1000000000LLU + (unsigned long long)now.tv_nsec;
}
else TRACELOG(LOG_WARNING, "TIMER: Hi-resolution timer not available");
#endif
@ -4283,9 +4341,9 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const
{
// Construct new path from our base path
#if defined(_WIN32)
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s\\%s", basePath, dp->d_name);
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH, "%s\\%s", basePath, dp->d_name);
#else
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s/%s", basePath, dp->d_name);
int pathLength = snprintf(path, MAX_FILEPATH_LENGTH, "%s/%s", basePath, dp->d_name);
#endif
if ((pathLength < 0) || (pathLength >= MAX_FILEPATH_LENGTH))
@ -4297,7 +4355,7 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const
if ((filter == NULL) || (strstr(filter, FILE_FILTER_TAG_ALL) != NULL) ||
(strstr(filter, FILE_FILTER_TAG_FILE_ONLY) != NULL) || IsFileExtension(path, filter))
{
strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1);
memcpy(files->paths[files->count], path, pathLength);
files->count++;
}
}
@ -4305,7 +4363,7 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const
{
if ((filter != NULL) && ((strstr(filter, FILE_FILTER_TAG_DIR_ONLY) != NULL) || (strstr(filter, FILE_FILTER_TAG_ALL) != NULL)))
{
strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1);
memcpy(files->paths[files->count], path, pathLength);
files->count++;
}

View file

@ -59,10 +59,13 @@
// NOTE: Below types are required for standalone usage
//----------------------------------------------------------------------------------
// Boolean type
#if !defined(__cplusplus)
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
#include <stdbool.h>
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
#elif !defined(bool)
typedef enum bool { false = 0, true = !false } bool;
#define RL_BOOL_TYPE
#endif
#endif
#if !defined(RL_VECTOR2_TYPE)
@ -124,7 +127,7 @@ void UpdateGestures(void); // Update gestures detec
#if defined(RGESTURES_STANDALONE)
void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
bool IsGestureDetected(int gesture); // Check if a gesture has been detected
bool IsGestureDetected(int gesture); // Check if gesture has been detected
int GetGestureDetected(void); // Get latest detected gesture
float GetGestureHoldDuration(void); // Get gesture hold time in seconds
@ -154,8 +157,8 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang
extern "C" { // Prevents name mangling of functions
#endif
// Functions required to query time on Windows
int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
int __stdcall QueryPerformanceCounter(unsigned long long *lpPerformanceCount);
int __stdcall QueryPerformanceFrequency(unsigned long long *lpFrequency);
#if defined(__cplusplus)
}
#endif
@ -254,7 +257,7 @@ void SetGesturesEnabled(unsigned int flags)
GESTURES.enabledFlags = flags;
}
// Check if a gesture have been detected
// Check if gesture have been detected
bool IsGestureDetected(unsigned int gesture)
{
if ((GESTURES.enabledFlags & GESTURES.current) == gesture) return true;
@ -350,7 +353,7 @@ void ProcessGestureEvent(GestureEvent event)
GESTURES.Drag.vector.y = GESTURES.Touch.moveDownPositionA.y - GESTURES.Touch.downDragPosition.y;
}
}
else if (GESTURES.Touch.pointCount == 2) // Two touch points
else if (GESTURES.Touch.pointCount == 2)
{
if (event.touchAction == TOUCH_ACTION_DOWN)
{
@ -515,37 +518,36 @@ static double rgGetCurrentTime(void)
time = GetTime();
#else
#if defined(_WIN32)
unsigned long long int clockFrequency, currentTime;
unsigned long long clockFrequency = 0;
unsigned long long currentClockTicks = 0;
QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation!
QueryPerformanceCounter(&currentTime);
QueryPerformanceCounter(&currentClockTicks);
time = (double)currentTime/clockFrequency; // Time in seconds
time = (double)currentClockTicks/clockFrequency; // Time in seconds
#endif
#if defined(__linux__)
// NOTE: Only for Linux-based systems
struct timespec now;
struct timespec now = { 0 };
clock_gettime(CLOCK_MONOTONIC, &now);
unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds
unsigned long long nanoSeconds = (unsigned long long)now.tv_sec*1000000000LLU + (unsigned long long)now.tv_nsec;
time = ((double)nowTime*1e-9); // Time in seconds
time = ((double)nanoSeconds*1e-9); // Time in seconds
#endif
#if defined(__APPLE__)
//#define CLOCK_REALTIME CALENDAR_CLOCK // returns UTC time since 1970-01-01
//#define CLOCK_MONOTONIC SYSTEM_CLOCK // returns the time since boot time
clock_serv_t cclock;
mach_timespec_t now;
clock_serv_t cclock = { 0 };
mach_timespec_t now = { 0 };
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
// NOTE: OS X does not have clock_gettime(), using clock_get_time()
clock_get_time(cclock, &now);
mach_port_deallocate(mach_task_self(), cclock);
unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds
unsigned long long nanoSeconds = (unsigned long long)now.tv_sec*1000000000LLU + (unsigned long long)now.tv_nsec;
time = ((double)nowTime*1e-9); // Time in seconds
time = ((double)nanoSeconds*1e-9); // Time in seconds
#endif
#endif

View file

@ -77,6 +77,15 @@
#include "external/glfw/src/window.c"
#include "external/glfw/src/input.c"
#include "external/glfw/src/vulkan.c"
#include "external/glfw/src/egl_context.c"
#include "external/glfw/src/osmesa_context.c"
//We need to define this function because GLFW calls it even though raylib does
//not use GLFW's Null platform
GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
{
return GLFW_FALSE;
}
#if defined(_WIN32) || defined(__CYGWIN__)
#include "external/glfw/src/win32_init.c"
@ -87,9 +96,6 @@
#include "external/glfw/src/win32_time.c"
#include "external/glfw/src/win32_thread.c"
#include "external/glfw/src/wgl_context.c"
#include "external/glfw/src/egl_context.c"
#include "external/glfw/src/osmesa_context.c"
#endif
#if defined(__linux__)
@ -100,19 +106,42 @@
#include "external/glfw/src/linux_joystick.c"
#include "external/glfw/src/xkb_unicode.c"
#include "external/glfw/src/egl_context.c"
#include "external/glfw/src/osmesa_context.c"
#if defined(_GLFW_WAYLAND)
//These functions need to be temporarily renamed because including
//source files for both Wayland and X11 results in pairs of functions
//with the same name and thus a build error
#define createKeyTables createKeyTablesWayland
#define translateKey translateKeyWayland
#define acquireMonitor acquireMonitorWayland
#define releaseMonitor releaseMonitorWayland
#include "external/glfw/src/wl_init.c"
#include "external/glfw/src/wl_monitor.c"
#include "external/glfw/src/wl_window.c"
#undef createKeyTables
#undef translateKey
#undef acquireMonitor
#undef releaseMonitor
#endif
#if defined(_GLFW_X11)
//These functions need to be temporarily renamed because including
//source files for both Wayland and X11 results in pairs of functions
//with the same name and thus a build error
#define createKeyTables createKeyTablesX11
#define translateKey translateKeyX11
#define acquireMonitor acquireMonitorX11
#define releaseMonitor releaseMonitorX11
#include "external/glfw/src/x11_init.c"
#include "external/glfw/src/x11_monitor.c"
#include "external/glfw/src/x11_window.c"
#include "external/glfw/src/glx_context.c"
#undef createKeyTables
#undef translateKey
#undef acquireMonitor
#undef releaseMonitor
#endif
#endif
@ -128,9 +157,6 @@
#include "external/glfw/src/x11_monitor.c"
#include "external/glfw/src/x11_window.c"
#include "external/glfw/src/glx_context.c"
#include "external/glfw/src/egl_context.c"
#include "external/glfw/src/osmesa_context.c"
#endif
#if defined(__APPLE__)
@ -140,9 +166,6 @@
#include "external/glfw/src/cocoa_joystick.m"
#include "external/glfw/src/cocoa_monitor.m"
#include "external/glfw/src/cocoa_window.m"
#include "external/glfw/src/cocoa_time.c"
#include "external/glfw/src/macos_time.c"
#include "external/glfw/src/nsgl_context.m"
#include "external/glfw/src/egl_context.c"
#include "external/glfw/src/osmesa_context.c"
#endif

View file

@ -56,8 +56,8 @@
* #define RL_CULL_DISTANCE_NEAR 0.05 // Default projection matrix near cull distance
* #define RL_CULL_DISTANCE_FAR 4000.0 // Default projection matrix far cull distance
*
* When loading a shader, the following vertex attributes and uniform
* location names are tried to be set automatically:
* When loading a shader, the following vertex attributes and uniform location names are tried to be set automatically:
* WARNING: Pre-defined names can not be changed, they are used by default shaders and all raylib examples shaders, they are just listed here for reference
*
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD
@ -67,6 +67,8 @@
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES "vertexBoneIndices" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM "instanceTransform" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM
*
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
@ -74,6 +76,7 @@
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)))
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES "boneMatrices" // bone matrices
*
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
@ -324,6 +327,7 @@
#define RL_DRAW_FRAMEBUFFER 0x8CA9 // GL_DRAW_FRAMEBUFFER
// Default shader vertex attribute locations
// NOTE: Locations can be redefined by user if required
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION 0
#endif
@ -358,11 +362,13 @@
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
#if !defined(__cplusplus)
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
#include <stdbool.h>
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
// Boolean type
typedef enum bool { false = 0, true = !false } bool;
#elif !defined(bool)
typedef enum bool { false = 0, true = !false } bool;
#define RL_BOOL_TYPE
#endif
#endif
#if !defined(RL_MATRIX_TYPE)
@ -841,11 +847,11 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#define SW_CALLOC(n,sz) RL_CALLOC(n, sz)
#define SW_REALLOC(ptr, newSz) RL_REALLOC(ptr, newSz)
#define SW_FREE(ptr) RL_FREE(ptr)
#include "external/rlsw.h" // OpenGL 1.1 software implementation
#include "external/rlsw.h" // OpenGL 1.1 software implementation
#else
#if defined(__APPLE__)
#include <OpenGL/gl.h> // OpenGL 1.1 library for OSX
#include <OpenGL/glext.h> // OpenGL extensions library
#include <OpenGL/gl.h> // OpenGL 1.1 library for OSX
#include <OpenGL/glext.h> // OpenGL extensions library
#else
// APIENTRY for OpenGL function pointer declarations is required
#if !defined(APIENTRY)
@ -860,7 +866,7 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#define WINGDIAPI __declspec(dllimport)
#endif
#include <GL/gl.h> // OpenGL 1.1 library
#include <GL/gl.h> // OpenGL 1.1 library
#endif
#endif
#endif
@ -894,16 +900,17 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
// It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi
// provided headers (despite being defined in official Khronos GLES2 headers)
// TODO: Avoid raylib platform-dependent code on rlgl, it should be a completely portable library
#if defined(PLATFORM_DRM)
#if defined(PLATFORM_DRM) // Use CONFIG_DRM?
typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor);
#endif
#endif
#include <stdlib.h> // Required for: calloc(), free()
#include <string.h> // Required for: strcmp(), strlen() [Used in rlglInit(), on extensions loading]
#include <math.h> // Required for: sqrtf(), sinf(), cosf(), floor(), log()
#include <stdlib.h> // Required for: calloc(), free()
#include <string.h> // Required for: strcmp(), strlen() [Used in rlglInit(), on extensions loading]
#include <math.h> // Required for: sqrtf(), sinf(), cosf(), floor(), log()
#include <limits.h> // Required for: INT_MAX
//----------------------------------------------------------------------------------
// Defines and Macros
@ -991,65 +998,28 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#endif
// Default shader vertex attribute names to set location points
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION
#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
#endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD
#endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL
#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL
#endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR
#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR
#endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT
#endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2
#endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES "vertexBoneIndices" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES
#endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
#endif
// WARNING: Pre-defined names can not be changed, they are used by default shaders and all raylib examples shaders, they are just listed here for reference
#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD
#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL
#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES "vertexBoneIndices" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
#define RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM "instanceTransform" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM
#define RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM "instanceTransform" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM
#endif
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix
#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))
#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
#define RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES "boneMatrices" // bone matrices (required for GPU skinning)
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
#endif
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW
#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
#endif
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION
#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
#endif
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix
#endif
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL
#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))
#endif
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR
#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
#endif
#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
#endif
#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
#endif
#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
#endif
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES
#define RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES "boneMatrices" // bone matrices (required for GPU skinning)
#endif
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
//----------------------------------------------------------------------------------
// Module Types and Structures Definition
@ -1235,7 +1205,11 @@ void rlMatrixMode(int mode)
// Push the current matrix into RLGL.State.stack
void rlPushMatrix(void)
{
if (RLGL.State.stackCounter >= RL_MAX_MATRIX_STACK_SIZE) TRACELOG(RL_LOG_ERROR, "RLGL: Matrix stack overflow (RL_MAX_MATRIX_STACK_SIZE)");
if (RLGL.State.stackCounter >= RL_MAX_MATRIX_STACK_SIZE)
{
TRACELOG(RL_LOG_ERROR, "RLGL: Matrix stack overflow (RL_MAX_MATRIX_STACK_SIZE)");
return;
}
if (RLGL.State.currentMatrixMode == RL_MODELVIEW)
{
@ -2403,7 +2377,7 @@ void rlglClose(void)
// NOTE: External loader function must be provided
void rlLoadExtensions(void *loader)
{
#if defined(GRAPHICS_API_OPENGL_33) // Also defined for GRAPHICS_API_OPENGL_21
#if defined(GRAPHICS_API_OPENGL_33) // Also defined for GRAPHICS_API_OPENGL_21
// NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions)
if (gladLoadGL((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
@ -2496,7 +2470,7 @@ void rlLoadExtensions(void *loader)
// NOTE: String duplication rquired because glGetString() returns a const string
int extensionsLength = (int)strlen(extensions); // Get extensions string size in bytes
char *extensionsDup = (char *)RL_CALLOC(extensionsLength + 1, sizeof(char)); // Allocate space for copy with additional EOL byte
strncpy(extensionsDup, extensions, extensionsLength);
snprintf(extensionsDup, extensionsLength, "%s", extensions);
extList[numExt] = extensionsDup;
for (int i = 0; i < extensionsLength; i++)
@ -2534,7 +2508,7 @@ void rlLoadExtensions(void *loader)
}
// Check instanced rendering support
if (strstr(extList[i], (const char *)"instanced_arrays") != NULL) // Broad check for instanced_arrays
if (strstr(extList[i], (const char *)"instanced_arrays") != NULL) // Broad check for instanced_arrays
{
// Specific check
if (strcmp(extList[i], (const char *)"GL_ANGLE_instanced_arrays") == 0) // ANGLE
@ -3016,7 +2990,7 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
// NOTE: glMapBuffer() causes sync issue
// If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job
// To avoid waiting (idle), glBufferData() can bee called first with NULL pointer before glMapBuffer()
// To avoid waiting (idle), glBufferData() can be called first with NULL pointer before glMapBuffer()
// Doing that, the previous data in PBO will be discarded and glMapBuffer() returns a new
// allocated pointer immediately even if GPU is still working with the previous data
@ -3366,8 +3340,15 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format,
// Texture parameters configuration
// NOTE: glTexParameteri does NOT affect texture uploading
#if defined(GRAPHICS_API_OPENGL_ES2)
// Check if texture is power-of-two (POT)
bool texIsPOT = false;
if (((width > 0) && ((width & (width - 1)) == 0)) &&
((height > 0) && ((height & (height - 1)) == 0))) texIsPOT = true;
// NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used
if (RLGL.ExtSupported.texNPOT)
if ((texIsPOT) || (RLGL.ExtSupported.texNPOT))
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis
@ -3638,7 +3619,7 @@ void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned
case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_HALF_FLOAT_ARB; break;
case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT_ARB; break;
case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT_ARB; break;
#else // defined(GRAPHICS_API_OPENGL_ES2)
#else // GRAPHICS_API_OPENGL_ES2
case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float
case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float
case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float
@ -3768,9 +3749,17 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format)
// Attach our texture to FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0);
#if defined(FBO_READ_TEXTURE_AS_RGBA)
// Reading data as RGBA because FBO texture is configured as RGBA, despite binding another texture format
pixels = RL_CALLOC(rlGetPixelDataSize(width, height, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8), 1);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
#else
// Reading data as original texture format, in some platforms (RPI, Wasm) it works
pixels = (unsigned char *)RL_MALLOC(rlGetPixelDataSize(width, height, format));
unsigned int glInternalFormat = 0, glFormat = 0, glType = 0;
rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType);
glReadPixels(0, 0, width, height, glFormat, glType, pixels);
#endif
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -3804,6 +3793,10 @@ unsigned char *rlReadScreenPixels(int width, int height)
{
unsigned char *imgData = (unsigned char *)RL_CALLOC(width*height*4, sizeof(unsigned char));
// NOTE: Buffer retrieved is GL_FRONT in single-buffered configurations
// and GL_BACK in double-buffered configurations, make sure to call it at the end of frame
//glReadBuffer(GL_BACK);
// NOTE: glReadPixels() returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer
// WARNING: Getting alpha channel! Be careful, it can be transparent if not cleared properly!
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imgData);
@ -5248,7 +5241,9 @@ static int rlGetPixelDataSize(int width, int height, int format)
{
int blockWidth = (width + 3)/4;
int blockHeight = (height + 3)/4;
dataSize = blockWidth*blockHeight*8;
unsigned long long dataSizeBytes = (unsigned long long)blockWidth*blockHeight*8;
if (dataSizeBytes < INT_MAX) dataSize = (int)dataSizeBytes;
} break;
case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA:
case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA:
@ -5257,13 +5252,17 @@ static int rlGetPixelDataSize(int width, int height, int format)
{
int blockWidth = (width + 3)/4;
int blockHeight = (height + 3)/4;
dataSize = blockWidth*blockHeight*16;
unsigned long long dataSizeBytes = (unsigned long long)blockWidth*blockHeight*16;
if (dataSizeBytes < INT_MAX) dataSize = (int)dataSizeBytes;
} break;
case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 4 bytes per each 4x4 block
{
int blockWidth = (width + 3)/4;
int blockHeight = (height + 3)/4;
dataSize = blockWidth*blockHeight*4;
unsigned long long dataSizeBytes = (unsigned long long)blockWidth*blockHeight*4;
if (dataSizeBytes < INT_MAX) dataSize = (int)dataSizeBytes;
} break;
default: break;
}
@ -5272,10 +5271,12 @@ static int rlGetPixelDataSize(int width, int height, int format)
if ((format >= RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) &&
(format <= RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16))
{
double bytesPerPixel = (double)bpp/8.0;
dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes
unsigned long long dataSizeBytes = ((unsigned long long)width*height*bpp) >> 3; // Get size in bytes (dividing by 8)
if (dataSizeBytes < INT_MAX) dataSize = (int)dataSizeBytes;
}
if (dataSize == 0) TRACELOG(LOG_WARNING, "Requested image size is larger than 2GB, it can not be allocated");
return dataSize;
}

Some files were not shown because too many files have changed in this diff Show more