mirror of
				https://github.com/raysan5/raylib.git
				synced 2025-11-04 01:34:19 +00:00 
			
		
		
		
	[rcore] Clipboard Image Support (#4459)
* [rcore] add 'GetClipboardImage' for windows * [rcore] GetClipboardImage removed some unneeded defines * [rcore] PLATFORM_SDL: create a compatility layer for SDL3 * external: add win32_clipboard.h header only lib * [rcore] using win32_clipboard on platforms rlfw and rgfw * [rcore] fix warnings in SDL3 compatibility layer * Makefile: Allow specifying SDL_LIBRARIES to link, this helps with SDL3 * Makefile: examples makefile now compile others/rlgl_standalone only when TARGET_PLATFORM is PLATFORM_DESKTOP_GFLW * Makefile: examples makefile now compile others/rlgl_standalone only when TARGET_PLATFORM is PLATFORM_DESKTOP_GFLW * [rcore]: PLATFORM_SDL: improve clipboard data retrieval * external: remove unused function from win32_clipboard.h * Makefile: allow for extra flags necessary when compiling for SDL3 * [rcore]: fix string typo * [rcore]: Properly handle NULL dpi passing. As is allowed in SDL2 * external: fix arch finding on win32_clipboard.h to allow compilation on msvc cmake CI * [rcore]: PLATFORM_SDL: Treat monitor as an ID in SDL3 as opposed to an index as in SDL2 * [rcore]: typo
This commit is contained in:
		@@ -87,6 +87,8 @@ USE_EXTERNAL_GLFW     ?= FALSE
 | 
			
		||||
# WARNING: Library is not included in raylib, it MUST be configured by users
 | 
			
		||||
SDL_INCLUDE_PATH      ?= $(RAYLIB_SRC_PATH)/external/SDL2/include
 | 
			
		||||
SDL_LIBRARY_PATH      ?= $(RAYLIB_SRC_PATH)/external/SDL2/lib
 | 
			
		||||
SDL_LIBRARIES         ?= -lSDL2 -lSDL2main
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Use Wayland display server protocol on Linux desktop (by default it uses X11 windowing system)
 | 
			
		||||
# NOTE: This variable is only used for PLATFORM_OS: LINUX
 | 
			
		||||
@@ -263,9 +265,9 @@ endif
 | 
			
		||||
# Define include paths for required headers: INCLUDE_PATHS
 | 
			
		||||
# NOTE: Some external/extras libraries could be required (stb, easings...)
 | 
			
		||||
#------------------------------------------------------------------------------------------------
 | 
			
		||||
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external
 | 
			
		||||
 | 
			
		||||
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external $(EXTRA_INCLUDE_PATHS)
 | 
			
		||||
# Define additional directories containing required header files
 | 
			
		||||
 | 
			
		||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
 | 
			
		||||
    ifeq ($(PLATFORM_OS),BSD)
 | 
			
		||||
        INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH) -I/usr/pkg/include -I/usr/X11R7/include
 | 
			
		||||
@@ -415,12 +417,12 @@ endif
 | 
			
		||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
 | 
			
		||||
    ifeq ($(PLATFORM_OS),WINDOWS)
 | 
			
		||||
        # Libraries for Windows desktop compilation
 | 
			
		||||
        LDLIBS = -lraylib -lSDL2 -lSDL2main -lopengl32 -lgdi32
 | 
			
		||||
        LDLIBS = -lraylib $(SDL_LIBRARIES) -lopengl32 -lgdi32
 | 
			
		||||
    endif
 | 
			
		||||
    ifeq ($(PLATFORM_OS),LINUX)
 | 
			
		||||
        # Libraries for Debian GNU/Linux desktop compiling
 | 
			
		||||
        # NOTE: Required packages: libegl1-mesa-dev
 | 
			
		||||
        LDLIBS = -lraylib -lSDL2 -lSDL2main -lGL -lm -lpthread -ldl -lrt
 | 
			
		||||
        LDLIBS = -lraylib $(SDL_LIBRARIES) -lGL -lm -lpthread -ldl -lrt
 | 
			
		||||
 | 
			
		||||
        # On X11 requires also below libraries
 | 
			
		||||
        LDLIBS += -lX11
 | 
			
		||||
@@ -646,8 +648,12 @@ OTHERS = \
 | 
			
		||||
    others/embedded_files_loading \
 | 
			
		||||
    others/raylib_opengl_interop \
 | 
			
		||||
    others/raymath_vector_angle \
 | 
			
		||||
    others/rlgl_compute_shader \
 | 
			
		||||
    others/rlgl_standalone
 | 
			
		||||
    others/rlgl_compute_shader
 | 
			
		||||
 | 
			
		||||
ifeq ($(TARGET_PLATFORM), PLATFORM_DESKTOP_GFLW)
 | 
			
		||||
    OTHERS += others/rlgl_standalone
 | 
			
		||||
endif
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
CURRENT_MAKEFILE = $(lastword $(MAKEFILE_LIST))
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -118,6 +118,8 @@ GLFW_LINUX_ENABLE_X11      ?= TRUE
 | 
			
		||||
# WARNING: Library is not included in raylib, it MUST be configured by users
 | 
			
		||||
SDL_INCLUDE_PATH      ?= $(RAYLIB_SRC_PATH)/external/SDL2/include
 | 
			
		||||
SDL_LIBRARY_PATH      ?= $(RAYLIB_SRC_PATH)/external/SDL2/lib
 | 
			
		||||
SDL_LIBRARIES         ?= -lSDL2 -lSDL2main
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Determine if the file has root access (only required to install raylib)
 | 
			
		||||
# "whoami" prints the name of the user that calls him (so, if it is the root user, "whoami" prints "root")
 | 
			
		||||
@@ -460,7 +462,7 @@ CFLAGS += $(CUSTOM_CFLAGS)
 | 
			
		||||
# Define include paths for required headers: INCLUDE_PATHS
 | 
			
		||||
# NOTE: Several external required libraries (stb and others)
 | 
			
		||||
#------------------------------------------------------------------------------------------------
 | 
			
		||||
INCLUDE_PATHS = -I. 
 | 
			
		||||
INCLUDE_PATHS = -I. $(EXTRA_INCLUDE_PATHS)
 | 
			
		||||
 | 
			
		||||
# Define additional directories containing required header files
 | 
			
		||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
 | 
			
		||||
@@ -586,7 +588,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
 | 
			
		||||
            LDLIBS += -lX11
 | 
			
		||||
        endif
 | 
			
		||||
    endif
 | 
			
		||||
    LDLIBS += -lSDL2 -lSDL2main
 | 
			
		||||
    LDLIBS += $(SDL_LIBRARIES)
 | 
			
		||||
endif
 | 
			
		||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW)
 | 
			
		||||
    ifeq ($(PLATFORM_OS),WINDOWS)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								src/config.h
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								src/config.h
									
									
									
									
									
								
							@@ -71,6 +71,7 @@
 | 
			
		||||
// Enabling this flag allows manual control of the frame processes, use at your own risk
 | 
			
		||||
//#define SUPPORT_CUSTOM_FRAME_CONTROL    1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// rcore: Configuration values
 | 
			
		||||
//------------------------------------------------------------------------------------
 | 
			
		||||
#define MAX_FILEPATH_CAPACITY        8192       // Maximum file paths capacity
 | 
			
		||||
@@ -272,4 +273,31 @@
 | 
			
		||||
//------------------------------------------------------------------------------------
 | 
			
		||||
#define MAX_TRACELOG_MSG_LENGTH       256       // Max length of one trace-log message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Enable partial support for clipboard image, only working on SDL3 or
 | 
			
		||||
// being on both Windows OS + GLFW or Windows OS + RGFW
 | 
			
		||||
#define SUPPORT_CLIPBOARD_IMAGE    1
 | 
			
		||||
 | 
			
		||||
#if defined(SUPPORT_CLIPBOARD_IMAGE)
 | 
			
		||||
    #ifndef STBI_REQUIRED
 | 
			
		||||
        #define STBI_REQUIRED
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #ifndef SUPPORT_FILEFORMAT_BMP // For clipboard image on Windows
 | 
			
		||||
        #define SUPPORT_FILEFORMAT_BMP 1
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #ifndef SUPPORT_FILEFORMAT_PNG // Wayland uses png for prints, at least it was on 22 LTS ubuntu
 | 
			
		||||
        #define SUPPORT_FILEFORMAT_PNG 1
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #ifndef SUPPORT_FILEFORMAT_JPG
 | 
			
		||||
        #define SUPPORT_FILEFORMAT_JPG 1
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #ifndef SUPPORT_MODULE_RTEXTURES
 | 
			
		||||
        #define SUPPORT_MODULE_RTEXTURES 1
 | 
			
		||||
    #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // CONFIG_H
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										374
									
								
								src/external/win32_clipboard.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										374
									
								
								src/external/win32_clipboard.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,374 @@
 | 
			
		||||
#if !defined(_WIN32)
 | 
			
		||||
#   error "This module is only made for Windows OS"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32_CLIPBOARD_
 | 
			
		||||
#define WIN32_CLIPBOARD_
 | 
			
		||||
unsigned char* Win32GetClipboardImageData(int* width, int* height, unsigned long long int *dataSize);
 | 
			
		||||
#endif // WIN32_CLIPBOARD_
 | 
			
		||||
 | 
			
		||||
#ifdef WIN32_CLIPBOARD_IMPLEMENTATION
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
// NOTE: These search for architecture is taken from "Windows.h", and it's necessary if we really don't wanna import 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.
 | 
			
		||||
#if !defined(_X86_) && !defined(_68K_) && !defined(_MPPC_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_IX86)
 | 
			
		||||
#define _X86_
 | 
			
		||||
#if !defined(_CHPE_X86_ARM64_) && defined(_M_HYBRID)
 | 
			
		||||
#define _CHPE_X86_ARM64_
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(_AMD64_) && !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && (defined(_M_AMD64) || defined(_M_ARM64EC))
 | 
			
		||||
#define _AMD64_
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(_ARM_) && !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_ARM)
 | 
			
		||||
#define _ARM_
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(_ARM64_) && !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64EC_) && defined(_M_ARM64)
 | 
			
		||||
#define _ARM64_
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_ARM_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_ARM64EC)
 | 
			
		||||
#define _ARM64EC_
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_M68K)
 | 
			
		||||
#define _68K_
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_MPPC)
 | 
			
		||||
#define _MPPC_
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(_IA64_) && !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_M_IX86) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_IA64)
 | 
			
		||||
#define _IA64_
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define WIN32_LEAN_AND_MEAN
 | 
			
		||||
// #include <sdkddkver.h>
 | 
			
		||||
// #include <windows.h>
 | 
			
		||||
// #include <winuser.h>
 | 
			
		||||
#include <minwindef.h>
 | 
			
		||||
// #include <minwinbase.h>
 | 
			
		||||
 | 
			
		||||
#ifndef WINAPI
 | 
			
		||||
#if defined(_ARM_)
 | 
			
		||||
#define WINAPI
 | 
			
		||||
#else
 | 
			
		||||
#define WINAPI __stdcall
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef WINAPI
 | 
			
		||||
#if defined(_ARM_)
 | 
			
		||||
#define WINAPI
 | 
			
		||||
#else
 | 
			
		||||
#define WINAPI __stdcall
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef WINBASEAPI
 | 
			
		||||
#ifndef _KERNEL32_
 | 
			
		||||
#define WINBASEAPI DECLSPEC_IMPORT
 | 
			
		||||
#else
 | 
			
		||||
#define WINBASEAPI
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef WINUSERAPI
 | 
			
		||||
#ifndef _USER32_
 | 
			
		||||
#define WINUSERAPI __declspec (dllimport)
 | 
			
		||||
#else
 | 
			
		||||
#define WINUSERAPI
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef int WINBOOL;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// typedef HANDLE HGLOBAL;
 | 
			
		||||
 | 
			
		||||
#ifndef HWND
 | 
			
		||||
#define HWND void*
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if !defined(_WINUSER_) || !defined(WINUSER_ALREADY_INCLUDED)
 | 
			
		||||
WINUSERAPI WINBOOL WINAPI OpenClipboard(HWND hWndNewOwner);
 | 
			
		||||
WINUSERAPI WINBOOL WINAPI CloseClipboard(VOID);
 | 
			
		||||
WINUSERAPI DWORD   WINAPI GetClipboardSequenceNumber(VOID);
 | 
			
		||||
WINUSERAPI HWND    WINAPI GetClipboardOwner(VOID);
 | 
			
		||||
WINUSERAPI HWND    WINAPI SetClipboardViewer(HWND hWndNewViewer);
 | 
			
		||||
WINUSERAPI HWND    WINAPI GetClipboardViewer(VOID);
 | 
			
		||||
WINUSERAPI WINBOOL WINAPI ChangeClipboardChain(HWND hWndRemove, HWND hWndNewNext);
 | 
			
		||||
WINUSERAPI HANDLE  WINAPI SetClipboardData(UINT uFormat, HANDLE hMem);
 | 
			
		||||
WINUSERAPI HANDLE  WINAPI GetClipboardData(UINT uFormat);
 | 
			
		||||
WINUSERAPI UINT    WINAPI RegisterClipboardFormatA(LPCSTR  lpszFormat);
 | 
			
		||||
WINUSERAPI UINT    WINAPI RegisterClipboardFormatW(LPCWSTR lpszFormat);
 | 
			
		||||
WINUSERAPI int     WINAPI CountClipboardFormats(VOID);
 | 
			
		||||
WINUSERAPI UINT    WINAPI EnumClipboardFormats(UINT format);
 | 
			
		||||
WINUSERAPI int     WINAPI GetClipboardFormatNameA(UINT format, LPSTR  lpszFormatName, int cchMaxCount);
 | 
			
		||||
WINUSERAPI int     WINAPI GetClipboardFormatNameW(UINT format, LPWSTR lpszFormatName, int cchMaxCount);
 | 
			
		||||
WINUSERAPI WINBOOL WINAPI EmptyClipboard(VOID);
 | 
			
		||||
WINUSERAPI WINBOOL WINAPI IsClipboardFormatAvailable(UINT format);
 | 
			
		||||
WINUSERAPI int     WINAPI GetPriorityClipboardFormat(UINT *paFormatPriorityList, int cFormats);
 | 
			
		||||
WINUSERAPI HWND    WINAPI GetOpenClipboardWindow(VOID);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef HGLOBAL
 | 
			
		||||
#define HGLOBAL void*
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(_WINBASE_) || !defined(WINBASE_ALREADY_INCLUDED)
 | 
			
		||||
WINBASEAPI SIZE_T  WINAPI GlobalSize (HGLOBAL hMem);
 | 
			
		||||
WINBASEAPI LPVOID  WINAPI GlobalLock (HGLOBAL hMem);
 | 
			
		||||
WINBASEAPI WINBOOL WINAPI GlobalUnlock (HGLOBAL hMem);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if !defined(_WINGDI_) || !defined(WINGDI_ALREADY_INCLUDED)
 | 
			
		||||
#ifndef BITMAPINFOHEADER_ALREADY_DEFINED
 | 
			
		||||
#define BITMAPINFOHEADER_ALREADY_DEFINED
 | 
			
		||||
// Does this header need to be packed ? by the windowps header it doesnt seem to be
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
typedef struct tagBITMAPINFOHEADER {
 | 
			
		||||
    DWORD biSize;
 | 
			
		||||
    LONG biWidth;
 | 
			
		||||
    LONG biHeight;
 | 
			
		||||
    WORD biPlanes;
 | 
			
		||||
    WORD biBitCount;
 | 
			
		||||
    DWORD biCompression;
 | 
			
		||||
    DWORD biSizeImage;
 | 
			
		||||
    LONG biXPelsPerMeter;
 | 
			
		||||
    LONG biYPelsPerMeter;
 | 
			
		||||
    DWORD biClrUsed;
 | 
			
		||||
    DWORD biClrImportant;
 | 
			
		||||
} BITMAPINFOHEADER,*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef BITMAPFILEHEADER_ALREADY_DEFINED
 | 
			
		||||
#define BITMAPFILEHEADER_ALREADY_DEFINED
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
typedef struct tagBITMAPFILEHEADER {
 | 
			
		||||
    WORD bfType;
 | 
			
		||||
    DWORD bfSize;
 | 
			
		||||
    WORD bfReserved1;
 | 
			
		||||
    WORD bfReserved2;
 | 
			
		||||
    DWORD bfOffBits;
 | 
			
		||||
} BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef RGBQUAD_ALREADY_DEFINED
 | 
			
		||||
#define RGBQUAD_ALREADY_DEFINED
 | 
			
		||||
typedef struct tagRGBQUAD {
 | 
			
		||||
  BYTE rgbBlue;
 | 
			
		||||
  BYTE rgbGreen;
 | 
			
		||||
  BYTE rgbRed;
 | 
			
		||||
  BYTE rgbReserved;
 | 
			
		||||
} RGBQUAD, *LPRGBQUAD;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wmf/4e588f70-bd92-4a6f-b77f-35d0feaf7a57
 | 
			
		||||
#define BI_RGB       0x0000
 | 
			
		||||
#define BI_RLE8      0x0001
 | 
			
		||||
#define BI_RLE4      0x0002
 | 
			
		||||
#define BI_BITFIELDS 0x0003
 | 
			
		||||
#define BI_JPEG      0x0004
 | 
			
		||||
#define BI_PNG       0x0005
 | 
			
		||||
#define BI_CMYK      0x000B
 | 
			
		||||
#define BI_CMYKRLE8  0x000C
 | 
			
		||||
#define BI_CMYKRLE4  0x000D
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats
 | 
			
		||||
#define CF_DIB 8
 | 
			
		||||
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setsystemcursor
 | 
			
		||||
// #define OCR_NORMAL      32512 // Normal     select
 | 
			
		||||
// #define OCR_IBEAM       32513 // Text       select
 | 
			
		||||
// #define OCR_WAIT        32514 // Busy
 | 
			
		||||
// #define OCR_CROSS       32515 // Precision  select
 | 
			
		||||
// #define OCR_UP          32516 // Alternate  select
 | 
			
		||||
// #define OCR_SIZENWSE    32642 // Diagonal   resize 1
 | 
			
		||||
// #define OCR_SIZENESW    32643 // Diagonal   resize 2
 | 
			
		||||
// #define OCR_SIZEWE      32644 // Horizontal resize
 | 
			
		||||
// #define OCR_SIZENS      32645 // Vertical   resize
 | 
			
		||||
// #define OCR_SIZEALL     32646 // Move
 | 
			
		||||
// #define OCR_NO          32648 // Unavailable
 | 
			
		||||
// #define OCR_HAND        32649 // Link       select
 | 
			
		||||
// #define OCR_APPSTARTING 32650 //
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Module Internal Functions Declaration
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static BOOL           OpenClipboardRetrying(HWND handle); // Open clipboard with a number of retries
 | 
			
		||||
static int            GetPixelDataOffset(BITMAPINFOHEADER bih);
 | 
			
		||||
 | 
			
		||||
unsigned char* Win32GetClipboardImageData(int* width, int* height, unsigned long long int *dataSize)
 | 
			
		||||
{
 | 
			
		||||
    HWND win = NULL; // Get from somewhere but is doesnt seem to matter
 | 
			
		||||
    const char* msgString = "";
 | 
			
		||||
    int severity = LOG_INFO;
 | 
			
		||||
    BYTE* bmpData = NULL;
 | 
			
		||||
    if (!OpenClipboardRetrying(win)) {
 | 
			
		||||
        severity = LOG_ERROR;
 | 
			
		||||
        msgString = "Couldn't open clipboard";
 | 
			
		||||
        goto end;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    HGLOBAL clipHandle = (HGLOBAL)GetClipboardData(CF_DIB);
 | 
			
		||||
    if (!clipHandle) {
 | 
			
		||||
        severity = LOG_ERROR;
 | 
			
		||||
        msgString = "Clipboard data is not an Image";
 | 
			
		||||
        goto close;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BITMAPINFOHEADER *bmpInfoHeader = (BITMAPINFOHEADER *)GlobalLock(clipHandle);
 | 
			
		||||
    if (!bmpInfoHeader) {
 | 
			
		||||
        // Mapping from HGLOBAL to our local *address space* failed
 | 
			
		||||
        severity = LOG_ERROR;
 | 
			
		||||
        msgString = "Clipboard data failed to be locked";
 | 
			
		||||
        goto unlock;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *width = bmpInfoHeader->biWidth;
 | 
			
		||||
    *height = bmpInfoHeader->biHeight;
 | 
			
		||||
 | 
			
		||||
    SIZE_T clipDataSize = GlobalSize(clipHandle);
 | 
			
		||||
    if (clipDataSize < sizeof(BITMAPINFOHEADER)) {
 | 
			
		||||
        // Format CF_DIB needs space for BITMAPINFOHEADER struct.
 | 
			
		||||
        msgString = "Clipboard has Malformed data";
 | 
			
		||||
        severity = LOG_ERROR;
 | 
			
		||||
        goto unlock;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Denotes where the pixel data starts from the bmpInfoHeader pointer
 | 
			
		||||
    int pixelOffset = GetPixelDataOffset(*bmpInfoHeader);
 | 
			
		||||
 | 
			
		||||
    //--------------------------------------------------------------------------------//
 | 
			
		||||
    //
 | 
			
		||||
    // The rest of the section is about create the bytes for a correct BMP file
 | 
			
		||||
    // Then we copy the data and to a pointer
 | 
			
		||||
    //
 | 
			
		||||
    //--------------------------------------------------------------------------------//
 | 
			
		||||
 | 
			
		||||
    BITMAPFILEHEADER bmpFileHeader = {0};
 | 
			
		||||
    SIZE_T bmpFileSize = sizeof(bmpFileHeader) + clipDataSize;
 | 
			
		||||
    *dataSize = bmpFileSize;
 | 
			
		||||
 | 
			
		||||
    bmpFileHeader.bfType = 0x4D42; //https://stackoverflow.com/questions/601430/multibyte-character-constants-and-bitmap-file-header-type-constants#601536
 | 
			
		||||
 | 
			
		||||
    bmpFileHeader.bfSize = (DWORD)bmpFileSize; // Up to 4GB works fine
 | 
			
		||||
    bmpFileHeader.bfOffBits = sizeof(bmpFileHeader) + pixelOffset;
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Each process has a default heap provided by the system
 | 
			
		||||
    // Memory objects allocated by GlobalAlloc and LocalAlloc are in private,
 | 
			
		||||
    // committed pages with read/write access that cannot be accessed by other processes.
 | 
			
		||||
    //
 | 
			
		||||
    // This may be wrong since we might be allocating in a DLL and freeing from another module, the main application
 | 
			
		||||
    // that may cause heap corruption. We could create a FreeImage function
 | 
			
		||||
    //
 | 
			
		||||
    bmpData = malloc(sizeof(bmpFileHeader) + clipDataSize);
 | 
			
		||||
    // First we add the header for a bmp file
 | 
			
		||||
    memcpy(bmpData, &bmpFileHeader, sizeof(bmpFileHeader));
 | 
			
		||||
    // Then we add the header for the bmp itself + the pixel data
 | 
			
		||||
    memcpy(bmpData + sizeof(bmpFileHeader), bmpInfoHeader, clipDataSize);
 | 
			
		||||
    msgString = "Clipboad image acquired successfully";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unlock:
 | 
			
		||||
    GlobalUnlock(clipHandle);
 | 
			
		||||
close:
 | 
			
		||||
    CloseClipboard();
 | 
			
		||||
end:
 | 
			
		||||
 | 
			
		||||
    TRACELOG(severity, msgString);
 | 
			
		||||
    return bmpData;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BOOL OpenClipboardRetrying(HWND hWnd)
 | 
			
		||||
{
 | 
			
		||||
    static const int maxTries = 20;
 | 
			
		||||
    static const int sleepTimeMS = 60;
 | 
			
		||||
    for (int _ = 0; _ < maxTries; ++_)
 | 
			
		||||
    {
 | 
			
		||||
        // Might be being hold by another process
 | 
			
		||||
        // Or yourself forgot to CloseClipboard
 | 
			
		||||
        if (OpenClipboard(hWnd)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        Sleep(sleepTimeMS);
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Based off of researching microsoft docs and reponses from this question https://stackoverflow.com/questions/30552255/how-to-read-a-bitmap-from-the-windows-clipboard#30552856
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader
 | 
			
		||||
// Get the byte offset where does the pixels data start (from a packed DIB)
 | 
			
		||||
static int GetPixelDataOffset(BITMAPINFOHEADER bih)
 | 
			
		||||
{
 | 
			
		||||
    int offset = 0;
 | 
			
		||||
    const unsigned int rgbaSize = sizeof(RGBQUAD);
 | 
			
		||||
 | 
			
		||||
    // biSize Specifies the number of bytes required by the structure
 | 
			
		||||
    // We expect to always be 40 because it should be packed
 | 
			
		||||
    if (40 == bih.biSize && 40 == sizeof(BITMAPINFOHEADER))
 | 
			
		||||
    {
 | 
			
		||||
        //
 | 
			
		||||
        // biBitCount Specifies the number of bits per pixel.
 | 
			
		||||
        // Might exist some bit masks *after* the header and *before* the pixel offset
 | 
			
		||||
        // we're looking, but only if we have more than
 | 
			
		||||
        // 8 bits per pixel, so we need to ajust for that
 | 
			
		||||
        //
 | 
			
		||||
        if (bih.biBitCount > 8)
 | 
			
		||||
        {
 | 
			
		||||
            // if bih.biCompression is RBG we should NOT offset more
 | 
			
		||||
 | 
			
		||||
            if (bih.biCompression == BI_BITFIELDS)
 | 
			
		||||
            {
 | 
			
		||||
                offset += 3 * rgbaSize;
 | 
			
		||||
            } else if (bih.biCompression == 6 /* BI_ALPHABITFIELDS */)
 | 
			
		||||
            {
 | 
			
		||||
                // Not widely supported, but valid.
 | 
			
		||||
                offset += 4 * rgbaSize;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // biClrUsed Specifies the number of color indices in the color table that are actually used by the bitmap.
 | 
			
		||||
    // If this value is zero, the bitmap uses the maximum number of colors
 | 
			
		||||
    // corresponding to the value of the biBitCount member for the compression mode specified by biCompression.
 | 
			
		||||
    // If biClrUsed is nonzero and the biBitCount member is less than 16
 | 
			
		||||
    // the biClrUsed member specifies the actual number of colors
 | 
			
		||||
    //
 | 
			
		||||
    if (bih.biClrUsed > 0) {
 | 
			
		||||
        offset += bih.biClrUsed * rgbaSize;
 | 
			
		||||
    } else {
 | 
			
		||||
        if (bih.biBitCount < 16)
 | 
			
		||||
        {
 | 
			
		||||
            offset = offset + (rgbaSize << bih.biBitCount);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return bih.biSize + offset;
 | 
			
		||||
}
 | 
			
		||||
#endif // WIN32_CLIPBOARD_IMPLEMENTATION
 | 
			
		||||
// EOF
 | 
			
		||||
 | 
			
		||||
@@ -58,6 +58,7 @@
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
    typedef void *PVOID;
 | 
			
		||||
    typedef PVOID HANDLE;
 | 
			
		||||
    #include "../external/win32_clipboard.h"
 | 
			
		||||
    typedef HANDLE HWND;
 | 
			
		||||
    #define GLFW_EXPOSE_NATIVE_WIN32
 | 
			
		||||
    #define GLFW_NATIVE_INCLUDE_NONE // To avoid some symbols re-definition in windows.h
 | 
			
		||||
@@ -966,6 +967,33 @@ const char *GetClipboardText(void)
 | 
			
		||||
    return glfwGetClipboardString(platform.handle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(SUPPORT_CLIPBOARD_IMAGE)
 | 
			
		||||
// Get clipboard image
 | 
			
		||||
Image GetClipboardImage(void)
 | 
			
		||||
{
 | 
			
		||||
    Image image = {0};
 | 
			
		||||
    unsigned long long int dataSize = 0;
 | 
			
		||||
    void* fileData = NULL;
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
    int width, height;
 | 
			
		||||
    fileData  = (void*)Win32GetClipboardImageData(&width, &height, &dataSize);
 | 
			
		||||
#else
 | 
			
		||||
    TRACELOG(LOG_WARNING, "Clipboard image: PLATFORM_DESKTOP_GLFW doesn't implement `GetClipboardImage` for this OS");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (fileData == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data.");
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        image = LoadImageFromMemory(".bmp", fileData, dataSize);
 | 
			
		||||
    }
 | 
			
		||||
    return image;
 | 
			
		||||
}
 | 
			
		||||
#endif // SUPPORT_CLIPBOARD_IMAGE
 | 
			
		||||
 | 
			
		||||
// Show mouse cursor
 | 
			
		||||
void ShowCursor(void)
 | 
			
		||||
{
 | 
			
		||||
@@ -1898,4 +1926,8 @@ static void JoystickCallback(int jid, int event)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#   define WIN32_CLIPBOARD_IMPLEMENTATION
 | 
			
		||||
#   include "../external/win32_clipboard.h"
 | 
			
		||||
#endif
 | 
			
		||||
// EOF
 | 
			
		||||
 
 | 
			
		||||
@@ -664,6 +664,43 @@ const char *GetClipboardText(void)
 | 
			
		||||
    return RGFW_readClipboard(NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(SUPPORT_CLIPBOARD_IMAGE)
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#   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};
 | 
			
		||||
    unsigned long long int dataSize = 0;
 | 
			
		||||
    void* fileData = NULL;
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
    int width, height;
 | 
			
		||||
    fileData  = (void*)Win32GetClipboardImageData(&width, &height, &dataSize);
 | 
			
		||||
#else
 | 
			
		||||
    TRACELOG(LOG_WARNING, "Clipboard image: PLATFORM_DESKTOP_RGFW doesn't implement `GetClipboardImage` for this OS");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (fileData == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data.");
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        image = LoadImageFromMemory(".bmp", fileData, dataSize);
 | 
			
		||||
    }
 | 
			
		||||
    return image;
 | 
			
		||||
}
 | 
			
		||||
#endif // SUPPORT_CLIPBOARD_IMAGE
 | 
			
		||||
 | 
			
		||||
// Show mouse cursor
 | 
			
		||||
void ShowCursor(void)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
*           Custom flag for rcore on target platform -not used-
 | 
			
		||||
*
 | 
			
		||||
*   DEPENDENCIES:
 | 
			
		||||
*       - SDL 2 (main library): Windowing and inputs management
 | 
			
		||||
*       - SDL 2 or SLD 3 (main library): Windowing and inputs management
 | 
			
		||||
*       - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs)
 | 
			
		||||
*
 | 
			
		||||
*
 | 
			
		||||
@@ -48,6 +48,10 @@
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef SDL_ENABLE_OLD_NAMES
 | 
			
		||||
    #define SDL_ENABLE_OLD_NAMES    // Just in case we're on SDL3, we need some in-between compatibily
 | 
			
		||||
#endif
 | 
			
		||||
#include "SDL.h"                // SDL base library (window/rendered, input, timing... functionality)
 | 
			
		||||
 | 
			
		||||
#if defined(GRAPHICS_API_OPENGL_ES2)
 | 
			
		||||
@@ -64,6 +68,13 @@
 | 
			
		||||
    #define MAX_CLIPBOARD_BUFFER_LENGTH 1024 // Size of the clipboard buffer used on GetClipboardText()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ((defined(SDL_MAJOR_VERSION) && SDL_MAJOR_VERSION == 3) && (defined(SDL_MINOR_VERSION) && SDL_MINOR_VERSION >= 1))
 | 
			
		||||
    #ifndef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
        #define PLATFORM_DESKTOP_SDL3
 | 
			
		||||
    #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Types and Structures Definition
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
@@ -227,6 +238,190 @@ static const int CursorsLUT[] = {
 | 
			
		||||
    //SDL_SYSTEM_CURSOR_WAITARROW, // No equivalent implemented on MouseCursor enum on raylib.h
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// SDL3 Migration Layer made to avoid `ifdefs` inside functions when we can.
 | 
			
		||||
#ifdef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
 | 
			
		||||
// SDL3 Migration:
 | 
			
		||||
//     SDL_WINDOW_FULLSCREEN_DESKTOP has been removed,
 | 
			
		||||
//     and you can call SDL_GetWindowFullscreenMode()
 | 
			
		||||
//     to see whether an exclusive fullscreen mode will be used 
 | 
			
		||||
//     or the borderless fullscreen desktop mode will be used
 | 
			
		||||
#define SDL_WINDOW_FULLSCREEN_DESKTOP SDL_WINDOW_FULLSCREEN
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define SDL_IGNORE  false
 | 
			
		||||
#define SDL_DISABLE false
 | 
			
		||||
#define SDL_ENABLE  true
 | 
			
		||||
 | 
			
		||||
// SDL3 Migration: SDL_INIT_TIMER - no longer needed before calling SDL_AddTimer()
 | 
			
		||||
#define SDL_INIT_TIMER 0x0 // It's a flag, so no problem in setting it to zero if we use in a bitor (|)
 | 
			
		||||
 | 
			
		||||
// SDL3 Migration: The SDL_WINDOW_SHOWN flag has been removed. Windows are shown by default and can be created hidden by using the SDL_WINDOW_HIDDEN flag.
 | 
			
		||||
#define SDL_WINDOW_SHOWN 0x0 // It's a flag, so no problem in setting it to zero if we use in a bitor (|)
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// SDL3 Migration: Renamed
 | 
			
		||||
// IMPORTANT:
 | 
			
		||||
// Might need to call SDL_CleanupEvent somewhere see :https://github.com/libsdl-org/SDL/issues/3540#issuecomment-1793449852
 | 
			
		||||
//
 | 
			
		||||
#define SDL_DROPFILE  SDL_EVENT_DROP_FILE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const char* SDL_GameControllerNameForIndex(int joystickIndex)
 | 
			
		||||
{
 | 
			
		||||
    // NOTE: SDL3 uses the IDs itself (SDL_JoystickID) instead of SDL2 joystick_index
 | 
			
		||||
    const char* name = NULL;
 | 
			
		||||
    int numJoysticks = 0;
 | 
			
		||||
    SDL_JoystickID *joysticks = SDL_GetJoysticks(&numJoysticks);
 | 
			
		||||
    if (joysticks) {
 | 
			
		||||
        if (joystickIndex < numJoysticks) {
 | 
			
		||||
            SDL_JoystickID instance_id = joysticks[joystickIndex];
 | 
			
		||||
            name = SDL_GetGamepadNameForID(instance_id);
 | 
			
		||||
        }
 | 
			
		||||
        SDL_free(joysticks);
 | 
			
		||||
    }
 | 
			
		||||
    return name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SDL_GetNumVideoDisplays(void)
 | 
			
		||||
{
 | 
			
		||||
    int monitorCount = 0;
 | 
			
		||||
    SDL_DisplayID *displays = SDL_GetDisplays(&monitorCount);
 | 
			
		||||
    // Safe because If `mem` is NULL, SDL_free does nothing.
 | 
			
		||||
    SDL_free(displays);
 | 
			
		||||
 | 
			
		||||
    return monitorCount;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// SLD3 Migration:
 | 
			
		||||
//    To emulate SDL2 this function should return `SDL_DISABLE` or `SDL_ENABLE`
 | 
			
		||||
//    representing the *processing state* of the event before this function makes any changes to it.
 | 
			
		||||
Uint8 SDL_EventState(Uint32 type, int state) {
 | 
			
		||||
 | 
			
		||||
    Uint8 stateBefore = SDL_EventEnabled(type);
 | 
			
		||||
    switch (state)
 | 
			
		||||
    {
 | 
			
		||||
        case SDL_DISABLE: SDL_SetEventEnabled(type, false); break;
 | 
			
		||||
        case SDL_ENABLE: SDL_SetEventEnabled(type, true); break;
 | 
			
		||||
        default: TRACELOG(LOG_WARNING, "Event sate: unknow type");
 | 
			
		||||
    }
 | 
			
		||||
    return stateBefore;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SDL_GetCurrentDisplayMode_Adapter(SDL_DisplayID displayID, SDL_DisplayMode* mode)
 | 
			
		||||
{
 | 
			
		||||
    const SDL_DisplayMode* currMode = SDL_GetCurrentDisplayMode(displayID);
 | 
			
		||||
    if (currMode == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        TRACELOG(LOG_WARNING, "No current display mode");
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        *mode = *currMode;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SDL3 Migration: Renamed
 | 
			
		||||
#define SDL_GetCurrentDisplayMode SDL_GetCurrentDisplayMode_Adapter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
 | 
			
		||||
{
 | 
			
		||||
    return SDL_CreateSurface(width, height, SDL_GetPixelFormatForMasks(depth, Rmask, Gmask, Bmask, Amask));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SDL3 Migration:
 | 
			
		||||
//     SDL_GetDisplayDPI() -
 | 
			
		||||
//     not reliable across platforms, approximately replaced by multiplying
 | 
			
		||||
//     SDL_GetWindowDisplayScale() times 160 on iPhone and Android, and 96 on other platforms.
 | 
			
		||||
// returns 0 on success or a negative error code on failure
 | 
			
		||||
int SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi) {
 | 
			
		||||
    float dpi = SDL_GetWindowDisplayScale(platform.window) * 96.0;
 | 
			
		||||
    if (ddpi != NULL) *ddpi = dpi;
 | 
			
		||||
    if (hdpi != NULL) *hdpi = dpi;
 | 
			
		||||
    if (vdpi != NULL) *vdpi = dpi;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SDL_Surface *SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, Uint32 format)
 | 
			
		||||
{
 | 
			
		||||
    return SDL_CreateSurface(width, height, format);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
 | 
			
		||||
{
 | 
			
		||||
    return SDL_CreateSurfaceFrom(width, height, SDL_GetPixelFormatForMasks(depth, Rmask, Gmask, Bmask, Amask), pixels, pitch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SDL_Surface *SDL_CreateRGBSurfaceWithFormatFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 format)
 | 
			
		||||
{
 | 
			
		||||
    return SDL_CreateSurfaceFrom(width, height, format, pixels, pitch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SDL_NumJoysticks(void)
 | 
			
		||||
{
 | 
			
		||||
    int numJoysticks;
 | 
			
		||||
    SDL_JoystickID *joysticks = SDL_GetJoysticks(&numJoysticks);
 | 
			
		||||
    SDL_free(joysticks);
 | 
			
		||||
    return numJoysticks;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// SDL_SetRelativeMouseMode
 | 
			
		||||
// returns 0 on success or a negative error code on failure
 | 
			
		||||
// If relative mode is not supported, this returns -1.
 | 
			
		||||
int SDL_SetRelativeMouseMode_Adapter(SDL_bool enabled)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // SDL_SetWindowRelativeMouseMode(SDL_Window *window, bool enabled)
 | 
			
		||||
    // \returns true on success or false on failure; call SDL_GetError() for more
 | 
			
		||||
    //
 | 
			
		||||
    if (SDL_SetWindowRelativeMouseMode(platform.window, enabled))
 | 
			
		||||
    {
 | 
			
		||||
        return 0; // success
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return -1; // failure
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define SDL_SetRelativeMouseMode SDL_SetRelativeMouseMode_Adapter
 | 
			
		||||
 | 
			
		||||
bool SDL_GetRelativeMouseMode_Adapter(void)
 | 
			
		||||
{
 | 
			
		||||
    return SDL_GetWindowRelativeMouseMode(platform.window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define SDL_GetRelativeMouseMode SDL_GetRelativeMouseMode_Adapter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int SDL_GetNumTouchFingers(SDL_TouchID touchID)
 | 
			
		||||
{
 | 
			
		||||
    // SDL_Finger **SDL_GetTouchFingers(SDL_TouchID touchID, int *count)
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    SDL_Finger **fingers = SDL_GetTouchFingers(touchID, &count);
 | 
			
		||||
    SDL_free(fingers);
 | 
			
		||||
    return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else // We're on SDL2
 | 
			
		||||
 | 
			
		||||
// Since SDL2 doesn't have this function we leave a stub
 | 
			
		||||
// SDL_GetClipboardData function is available since SDL 3.1.3. (e.g. SDL3)
 | 
			
		||||
void* SDL_GetClipboardData(const char *mime_type, size_t *size) {
 | 
			
		||||
    TRACELOG(LOG_WARNING, "Getting clipboard data that is not text is only available in SDL3");
 | 
			
		||||
    // We could possibly implement it ourselves in this case for some easier platforms
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // PLATFORM_DESKTOP_SDL3
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Module Internal Functions Declaration
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
@@ -256,7 +451,12 @@ void ToggleFullscreen(void)
 | 
			
		||||
{
 | 
			
		||||
    const int monitor = SDL_GetWindowDisplayIndex(platform.window);
 | 
			
		||||
    const int monitorCount = SDL_GetNumVideoDisplays();
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_DESKTOP_SDL3 // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
 | 
			
		||||
    if ((monitor > 0) && (monitor <= monitorCount))
 | 
			
		||||
#else
 | 
			
		||||
    if ((monitor >= 0) && (monitor < monitorCount))
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0)
 | 
			
		||||
        {
 | 
			
		||||
@@ -279,7 +479,11 @@ void ToggleBorderlessWindowed(void)
 | 
			
		||||
{
 | 
			
		||||
    const int monitor = SDL_GetWindowDisplayIndex(platform.window);
 | 
			
		||||
    const int monitorCount = SDL_GetNumVideoDisplays();
 | 
			
		||||
#ifdef PLATFORM_DESKTOP_SDL3 // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
 | 
			
		||||
    if ((monitor > 0) && (monitor <= monitorCount))
 | 
			
		||||
#else
 | 
			
		||||
    if ((monitor >= 0) && (monitor < monitorCount))
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        if ((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0)
 | 
			
		||||
        {
 | 
			
		||||
@@ -328,7 +532,11 @@ void SetWindowState(unsigned int flags)
 | 
			
		||||
    {
 | 
			
		||||
        const int monitor = SDL_GetWindowDisplayIndex(platform.window);
 | 
			
		||||
        const int monitorCount = SDL_GetNumVideoDisplays();
 | 
			
		||||
    #ifdef PLATFORM_DESKTOP_SDL3 // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
 | 
			
		||||
        if ((monitor > 0) && (monitor <= monitorCount))
 | 
			
		||||
    #else
 | 
			
		||||
        if ((monitor >= 0) && (monitor < monitorCount))
 | 
			
		||||
    #endif
 | 
			
		||||
        {
 | 
			
		||||
            SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN);
 | 
			
		||||
            CORE.Window.fullscreen = true;
 | 
			
		||||
@@ -387,7 +595,11 @@ void SetWindowState(unsigned int flags)
 | 
			
		||||
    {
 | 
			
		||||
        const int monitor = SDL_GetWindowDisplayIndex(platform.window);
 | 
			
		||||
        const int monitorCount = SDL_GetNumVideoDisplays();
 | 
			
		||||
    #ifdef PLATFORM_DESKTOP_SDL3 // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
 | 
			
		||||
        if ((monitor > 0) && (monitor <= monitorCount))
 | 
			
		||||
    #else
 | 
			
		||||
        if ((monitor >= 0) && (monitor < monitorCount))
 | 
			
		||||
    #endif
 | 
			
		||||
        {
 | 
			
		||||
            SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN_DESKTOP);
 | 
			
		||||
        }
 | 
			
		||||
@@ -606,7 +818,11 @@ void SetWindowMonitor(int monitor)
 | 
			
		||||
        const int screenWidth = CORE.Window.screen.width;
 | 
			
		||||
        const int screenHeight = CORE.Window.screen.height;
 | 
			
		||||
        SDL_Rect usableBounds;
 | 
			
		||||
    #ifdef PLATFORM_DESKTOP_SDL3 // Different style for success checking
 | 
			
		||||
        if (SDL_GetDisplayUsableBounds(monitor, &usableBounds))
 | 
			
		||||
    #else
 | 
			
		||||
        if (SDL_GetDisplayUsableBounds(monitor, &usableBounds) == 0)
 | 
			
		||||
    #endif
 | 
			
		||||
        {
 | 
			
		||||
            if (wasFullscreen == 1) ToggleFullscreen(); // Leave fullscreen.
 | 
			
		||||
 | 
			
		||||
@@ -704,6 +920,7 @@ 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;
 | 
			
		||||
@@ -716,7 +933,11 @@ Vector2 GetMonitorPosition(int monitor)
 | 
			
		||||
    if ((monitor >= 0) && (monitor < monitorCount))
 | 
			
		||||
    {
 | 
			
		||||
        SDL_Rect displayBounds;
 | 
			
		||||
    #ifdef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
        if (SDL_GetDisplayUsableBounds(monitor, &displayBounds))
 | 
			
		||||
    #else
 | 
			
		||||
        if (SDL_GetDisplayUsableBounds(monitor, &displayBounds) == 0)
 | 
			
		||||
    #endif
 | 
			
		||||
        {
 | 
			
		||||
            return (Vector2){ (float)displayBounds.x, (float)displayBounds.y };
 | 
			
		||||
        }
 | 
			
		||||
@@ -844,10 +1065,16 @@ Vector2 GetWindowScaleDPI(void)
 | 
			
		||||
{
 | 
			
		||||
    Vector2 scale = { 1.0f, 1.0f };
 | 
			
		||||
 | 
			
		||||
#ifndef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
    // NOTE: SDL_GetWindowDisplayScale was only added on SDL3
 | 
			
		||||
    //       see https://wiki.libsdl.org/SDL3/SDL_GetWindowDisplayScale
 | 
			
		||||
    // TODO: Implement the window scale factor calculation manually.
 | 
			
		||||
    TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform");
 | 
			
		||||
#else
 | 
			
		||||
    scale.x = SDL_GetWindowDisplayScale(platform.window);
 | 
			
		||||
    scale.y = scale.x;
 | 
			
		||||
    TRACELOG(LOG_INFO, "WindowScaleDPI is %f", scale.x);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return scale;
 | 
			
		||||
}
 | 
			
		||||
@@ -877,19 +1104,68 @@ const char *GetClipboardText(void)
 | 
			
		||||
    return buffer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(SUPPORT_CLIPBOARD_IMAGE)
 | 
			
		||||
// Get clipboard image
 | 
			
		||||
Image GetClipboardImage(void)
 | 
			
		||||
{
 | 
			
		||||
    // Let's hope compiler put these arrays in static memory
 | 
			
		||||
    const char *image_formats[] = {
 | 
			
		||||
        "image/bmp",
 | 
			
		||||
        "image/png",
 | 
			
		||||
        "image/jpg",
 | 
			
		||||
        "image/tiff",
 | 
			
		||||
    };
 | 
			
		||||
    const char *image_extensions[] = {
 | 
			
		||||
        ".bmp",
 | 
			
		||||
        ".png",
 | 
			
		||||
        ".jpg",
 | 
			
		||||
        ".tiff",
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Image image = {0};
 | 
			
		||||
    size_t dataSize = 0;
 | 
			
		||||
    void  *fileData = NULL;
 | 
			
		||||
    for (int i = 0; i < SDL_arraysize(image_formats); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        // NOTE: This pointer should be free with SDL_free() at some point.
 | 
			
		||||
        fileData = SDL_GetClipboardData(image_formats[i], &dataSize);
 | 
			
		||||
        if (fileData) {
 | 
			
		||||
            image = LoadImageFromMemory(image_extensions[i], fileData, dataSize);
 | 
			
		||||
            if (IsImageValid(image))
 | 
			
		||||
            {
 | 
			
		||||
                TRACELOG(LOG_INFO, "Clipboard image: Got image from clipboard as a `%s` successfully", image_extensions[i]);
 | 
			
		||||
                return image;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data. %s", SDL_GetError());
 | 
			
		||||
    return image;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Show mouse cursor
 | 
			
		||||
void ShowCursor(void)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
    SDL_ShowCursor();
 | 
			
		||||
#else
 | 
			
		||||
    SDL_ShowCursor(SDL_ENABLE);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    CORE.Input.Mouse.cursorHidden = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Hides mouse cursor
 | 
			
		||||
void HideCursor(void)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
    SDL_HideCursor();
 | 
			
		||||
#else
 | 
			
		||||
    SDL_ShowCursor(SDL_DISABLE);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    CORE.Input.Mouse.cursorHidden = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -897,7 +1173,13 @@ void HideCursor(void)
 | 
			
		||||
void EnableCursor(void)
 | 
			
		||||
{
 | 
			
		||||
    SDL_SetRelativeMouseMode(SDL_FALSE);
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
    // SDL_ShowCursor() has been split into three functions: SDL_ShowCursor(), SDL_HideCursor(), and SDL_CursorVisible()
 | 
			
		||||
    SDL_ShowCursor();
 | 
			
		||||
#else
 | 
			
		||||
    SDL_ShowCursor(SDL_ENABLE);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    platform.cursorRelative = false;
 | 
			
		||||
    CORE.Input.Mouse.cursorHidden = false;
 | 
			
		||||
@@ -993,6 +1275,22 @@ const char *GetKeyName(int key)
 | 
			
		||||
 | 
			
		||||
static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_DESKTOP_SDL3 // SDL3
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    SDL_Finger **fingers = SDL_GetTouchFingers(event.touchID, &count);
 | 
			
		||||
    CORE.Input.Touch.pointCount = count;
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < CORE.Input.Touch.pointCount; i++)
 | 
			
		||||
    {
 | 
			
		||||
        SDL_Finger *finger = fingers[i];
 | 
			
		||||
        CORE.Input.Touch.pointId[i] = finger->id;
 | 
			
		||||
        CORE.Input.Touch.position[i].x = finger->x*CORE.Window.screen.width;
 | 
			
		||||
        CORE.Input.Touch.position[i].y = finger->y*CORE.Window.screen.height;
 | 
			
		||||
        CORE.Input.Touch.currentTouchState[i] = 1;
 | 
			
		||||
    }
 | 
			
		||||
    SDL_free(fingers);
 | 
			
		||||
#else // SDL2
 | 
			
		||||
 | 
			
		||||
    CORE.Input.Touch.pointCount = SDL_GetNumTouchFingers(event.touchId);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < CORE.Input.Touch.pointCount; i++)
 | 
			
		||||
@@ -1003,6 +1301,7 @@ static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event)
 | 
			
		||||
        CORE.Input.Touch.position[i].y = finger->y*CORE.Window.screen.height;
 | 
			
		||||
        CORE.Input.Touch.currentTouchState[i] = 1;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    for (int i = CORE.Input.Touch.pointCount; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.currentTouchState[i] = 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1094,16 +1393,26 @@ void PollInputEvents(void)
 | 
			
		||||
                    CORE.Window.dropFilepaths = (char **)RL_CALLOC(1024, sizeof(char *));
 | 
			
		||||
 | 
			
		||||
                    CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
 | 
			
		||||
                #ifdef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
                    // const char *data;   /**< The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events */
 | 
			
		||||
                    // Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE, and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events, you should make a copy of it. SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed.
 | 
			
		||||
                    strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data);
 | 
			
		||||
                #else
 | 
			
		||||
                    strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file);
 | 
			
		||||
                    SDL_free(event.drop.file);
 | 
			
		||||
                #endif
 | 
			
		||||
 | 
			
		||||
                    CORE.Window.dropFileCount++;
 | 
			
		||||
                }
 | 
			
		||||
                else if (CORE.Window.dropFileCount < 1024)
 | 
			
		||||
                {
 | 
			
		||||
                    CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
 | 
			
		||||
                #ifdef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
                    strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data);
 | 
			
		||||
                #else
 | 
			
		||||
                    strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file);
 | 
			
		||||
                    SDL_free(event.drop.file);
 | 
			
		||||
                #endif
 | 
			
		||||
 | 
			
		||||
                    CORE.Window.dropFileCount++;
 | 
			
		||||
                }
 | 
			
		||||
@@ -1112,10 +1421,18 @@ void PollInputEvents(void)
 | 
			
		||||
            } break;
 | 
			
		||||
 | 
			
		||||
            // Window events are also polled (Minimized, maximized, close...)
 | 
			
		||||
 | 
			
		||||
        #ifndef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
            // SDL3 states:
 | 
			
		||||
            //     The SDL_WINDOWEVENT_* events have been moved to top level events,
 | 
			
		||||
            //     and SDL_WINDOWEVENT has been removed.
 | 
			
		||||
            //     In general, handling this change just means checking for the individual events instead of first checking for SDL_WINDOWEVENT
 | 
			
		||||
            //     and then checking for window events. You can compare the event >= SDL_EVENT_WINDOW_FIRST and <= SDL_EVENT_WINDOW_LAST if you need to see whether it's a window event.
 | 
			
		||||
            case SDL_WINDOWEVENT:
 | 
			
		||||
            {
 | 
			
		||||
                switch (event.window.event)
 | 
			
		||||
                {
 | 
			
		||||
        #endif
 | 
			
		||||
                    case SDL_WINDOWEVENT_RESIZED:
 | 
			
		||||
                    case SDL_WINDOWEVENT_SIZE_CHANGED:
 | 
			
		||||
                    {
 | 
			
		||||
@@ -1143,14 +1460,23 @@ void PollInputEvents(void)
 | 
			
		||||
                    case SDL_WINDOWEVENT_FOCUS_GAINED:
 | 
			
		||||
                    case SDL_WINDOWEVENT_MAXIMIZED:
 | 
			
		||||
                    case SDL_WINDOWEVENT_RESTORED:
 | 
			
		||||
            #ifdef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
                        break;
 | 
			
		||||
            #else
 | 
			
		||||
                    default: break;
 | 
			
		||||
                }
 | 
			
		||||
            } break;
 | 
			
		||||
            #endif
 | 
			
		||||
 | 
			
		||||
            // Keyboard events
 | 
			
		||||
            case SDL_KEYDOWN:
 | 
			
		||||
            {
 | 
			
		||||
            #ifdef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
                // SDL3 Migration: The following structures have been removed: * SDL_Keysym
 | 
			
		||||
                KeyboardKey key = ConvertScancodeToKey(event.key.scancode);
 | 
			
		||||
            #else
 | 
			
		||||
                KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode);
 | 
			
		||||
            #endif
 | 
			
		||||
 | 
			
		||||
                if (key != KEY_NULL)
 | 
			
		||||
                {
 | 
			
		||||
@@ -1175,7 +1501,12 @@ void PollInputEvents(void)
 | 
			
		||||
 | 
			
		||||
            case SDL_KEYUP:
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
            #ifdef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
                KeyboardKey key = ConvertScancodeToKey(event.key.scancode);
 | 
			
		||||
            #else
 | 
			
		||||
                KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode);
 | 
			
		||||
            #endif
 | 
			
		||||
                if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 0;
 | 
			
		||||
            } break;
 | 
			
		||||
 | 
			
		||||
@@ -1527,7 +1858,11 @@ int InitPlatform(void)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Init window
 | 
			
		||||
#ifdef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
    platform.window = SDL_CreateWindow(CORE.Window.title, CORE.Window.screen.width, CORE.Window.screen.height, flags);
 | 
			
		||||
#else
 | 
			
		||||
    platform.window = SDL_CreateWindow(CORE.Window.title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, CORE.Window.screen.width, CORE.Window.screen.height, flags);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // Init OpenGL context
 | 
			
		||||
    platform.glContext = SDL_GL_CreateContext(platform.window);
 | 
			
		||||
@@ -1611,7 +1946,12 @@ int InitPlatform(void)
 | 
			
		||||
    CORE.Storage.basePath = SDL_GetBasePath(); // Alternative: GetWorkingDirectory();
 | 
			
		||||
    //----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_DESKTOP_SDL3
 | 
			
		||||
    TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (SDL3): Initialized successfully");
 | 
			
		||||
#else
 | 
			
		||||
    TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (SDL): Initialized successfully");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1011,6 +1011,7 @@ RLAPI Vector2 GetWindowScaleDPI(void);                            // Get window
 | 
			
		||||
RLAPI const char *GetMonitorName(int monitor);                    // Get the human-readable, UTF-8 encoded name of the specified monitor
 | 
			
		||||
RLAPI void SetClipboardText(const char *text);                    // Set clipboard text content
 | 
			
		||||
RLAPI const char *GetClipboardText(void);                         // Get clipboard text content
 | 
			
		||||
RLAPI Image GetClipboardImage(void);                              // Get clipboard image
 | 
			
		||||
RLAPI void EnableEventWaiting(void);                              // Enable waiting for events on EndDrawing(), no automatic event polling
 | 
			
		||||
RLAPI void DisableEventWaiting(void);                             // Disable waiting for events on EndDrawing(), automatic events polling
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -512,6 +512,12 @@ const char *TextFormat(const char *text, ...);              // Formatting of tex
 | 
			
		||||
    #define PLATFORM_DESKTOP_GLFW
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(SUPPORT_CLIPBOARD_IMAGE)
 | 
			
		||||
    #if !defined(SUPPORT_FILEFORMAT_BMP) || !defined(STBI_REQUIRED) || !defined(SUPPORT_MODULE_RTEXTURES)
 | 
			
		||||
        #error "To enabled SUPPORT_CLIPBOARD_IMAGE, it also needs SUPPORT_FILEFORMAT_BMP, SUPPORT_MODULE_RTEXTURES and STBI_REQUIRED to be defined. It should have been defined earlier"
 | 
			
		||||
    #endif
 | 
			
		||||
#endif // SUPPORT_CLIPBOARD_IMAGE
 | 
			
		||||
 | 
			
		||||
// Include platform-specific submodules
 | 
			
		||||
#if defined(PLATFORM_DESKTOP_GLFW)
 | 
			
		||||
    #include "platforms/rcore_desktop_glfw.c"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user