Merge branch 'raysan5:master' into master
This commit is contained in:
commit
619ee0b557
|
|
@ -148,6 +148,7 @@ int main(void)
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadRenderTexture(observerTarget);
|
UnloadRenderTexture(observerTarget);
|
||||||
UnloadRenderTexture(subjectTarget);
|
UnloadRenderTexture(subjectTarget);
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
103
src/external/win32_clipboard.h
vendored
103
src/external/win32_clipboard.h
vendored
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#ifndef WIN32_CLIPBOARD_
|
#ifndef WIN32_CLIPBOARD_
|
||||||
#define 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 long long int *dataSize);
|
||||||
#endif // WIN32_CLIPBOARD_
|
#endif // WIN32_CLIPBOARD_
|
||||||
|
|
||||||
#ifdef WIN32_CLIPBOARD_IMPLEMENTATION
|
#ifdef WIN32_CLIPBOARD_IMPLEMENTATION
|
||||||
|
|
@ -92,7 +92,6 @@ unsigned char* Win32GetClipboardImageData(int* width, int* height, unsigned long
|
||||||
|
|
||||||
typedef int WINBOOL;
|
typedef int WINBOOL;
|
||||||
|
|
||||||
|
|
||||||
#if !defined(_WINUSER_) || !defined(WINUSER_ALREADY_INCLUDED)
|
#if !defined(_WINUSER_) || !defined(WINUSER_ALREADY_INCLUDED)
|
||||||
WINUSERAPI WINBOOL WINAPI OpenClipboard(HWND hWndNewOwner);
|
WINUSERAPI WINBOOL WINAPI OpenClipboard(HWND hWndNewOwner);
|
||||||
WINUSERAPI WINBOOL WINAPI CloseClipboard(VOID);
|
WINUSERAPI WINBOOL WINAPI CloseClipboard(VOID);
|
||||||
|
|
@ -170,8 +169,7 @@ typedef struct tagRGBQUAD {
|
||||||
} RGBQUAD, *LPRGBQUAD;
|
} RGBQUAD, *LPRGBQUAD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// REF: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wmf/4e588f70-bd92-4a6f-b77f-35d0feaf7a57
|
||||||
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wmf/4e588f70-bd92-4a6f-b77f-35d0feaf7a57
|
|
||||||
#define BI_RGB 0x0000
|
#define BI_RGB 0x0000
|
||||||
#define BI_RLE8 0x0001
|
#define BI_RLE8 0x0001
|
||||||
#define BI_RLE4 0x0002
|
#define BI_RLE4 0x0002
|
||||||
|
|
@ -184,10 +182,10 @@ typedef struct tagRGBQUAD {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// https://learn.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats
|
// REF: https://learn.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats
|
||||||
#define CF_DIB 8
|
#define CF_DIB 8
|
||||||
|
|
||||||
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setsystemcursor
|
// REF: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setsystemcursor
|
||||||
// #define OCR_NORMAL 32512 // Normal select
|
// #define OCR_NORMAL 32512 // Normal select
|
||||||
// #define OCR_IBEAM 32513 // Text select
|
// #define OCR_IBEAM 32513 // Text select
|
||||||
// #define OCR_WAIT 32514 // Busy
|
// #define OCR_WAIT 32514 // Busy
|
||||||
|
|
@ -202,36 +200,37 @@ typedef struct tagRGBQUAD {
|
||||||
// #define OCR_HAND 32649 // Link select
|
// #define OCR_HAND 32649 // Link select
|
||||||
// #define OCR_APPSTARTING 32650 //
|
// #define OCR_APPSTARTING 32650 //
|
||||||
|
|
||||||
|
static BOOL OpenClipboardRetrying(HWND handle); // Open clipboard with a number of retries
|
||||||
|
static int GetPixelDataOffset(BITMAPINFOHEADER bih);
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Declaration
|
// Module Internal Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long long int *dataSize)
|
||||||
|
|
||||||
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
|
HWND win = NULL; // Get from somewhere but is doesnt seem to matter
|
||||||
const char* msgString = "";
|
const char *msgString = "";
|
||||||
int severity = LOG_INFO;
|
int severity = LOG_INFO;
|
||||||
BYTE* bmpData = NULL;
|
BYTE *bmpData = NULL;
|
||||||
if (!OpenClipboardRetrying(win)) {
|
|
||||||
|
if (!OpenClipboardRetrying(win))
|
||||||
|
{
|
||||||
severity = LOG_ERROR;
|
severity = LOG_ERROR;
|
||||||
msgString = "Couldn't open clipboard";
|
msgString = "Couldn't open clipboard";
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
HGLOBAL clipHandle = (HGLOBAL)GetClipboardData(CF_DIB);
|
HGLOBAL clipHandle = (HGLOBAL)GetClipboardData(CF_DIB);
|
||||||
if (!clipHandle) {
|
if (!clipHandle)
|
||||||
|
{
|
||||||
severity = LOG_ERROR;
|
severity = LOG_ERROR;
|
||||||
msgString = "Clipboard data is not an Image";
|
msgString = "Clipboard data is not an Image";
|
||||||
goto close;
|
goto close;
|
||||||
}
|
}
|
||||||
|
|
||||||
BITMAPINFOHEADER *bmpInfoHeader = (BITMAPINFOHEADER *)GlobalLock(clipHandle);
|
BITMAPINFOHEADER *bmpInfoHeader = (BITMAPINFOHEADER *)GlobalLock(clipHandle);
|
||||||
if (!bmpInfoHeader) {
|
if (!bmpInfoHeader)
|
||||||
|
{
|
||||||
// Mapping from HGLOBAL to our local *address space* failed
|
// Mapping from HGLOBAL to our local *address space* failed
|
||||||
severity = LOG_ERROR;
|
severity = LOG_ERROR;
|
||||||
msgString = "Clipboard data failed to be locked";
|
msgString = "Clipboard data failed to be locked";
|
||||||
|
|
@ -242,7 +241,8 @@ unsigned char* Win32GetClipboardImageData(int* width, int* height, unsigned long
|
||||||
*height = bmpInfoHeader->biHeight;
|
*height = bmpInfoHeader->biHeight;
|
||||||
|
|
||||||
SIZE_T clipDataSize = GlobalSize(clipHandle);
|
SIZE_T clipDataSize = GlobalSize(clipHandle);
|
||||||
if (clipDataSize < sizeof(BITMAPINFOHEADER)) {
|
if (clipDataSize < sizeof(BITMAPINFOHEADER))
|
||||||
|
{
|
||||||
// Format CF_DIB needs space for BITMAPINFOHEADER struct.
|
// Format CF_DIB needs space for BITMAPINFOHEADER struct.
|
||||||
msgString = "Clipboard has Malformed data";
|
msgString = "Clipboard has Malformed data";
|
||||||
severity = LOG_ERROR;
|
severity = LOG_ERROR;
|
||||||
|
|
@ -259,30 +259,28 @@ unsigned char* Win32GetClipboardImageData(int* width, int* height, unsigned long
|
||||||
//
|
//
|
||||||
//--------------------------------------------------------------------------------//
|
//--------------------------------------------------------------------------------//
|
||||||
|
|
||||||
BITMAPFILEHEADER bmpFileHeader = {0};
|
BITMAPFILEHEADER bmpFileHeader = { 0 };
|
||||||
SIZE_T bmpFileSize = sizeof(bmpFileHeader) + clipDataSize;
|
SIZE_T bmpFileSize = sizeof(bmpFileHeader) + clipDataSize;
|
||||||
*dataSize = bmpFileSize;
|
*dataSize = bmpFileSize;
|
||||||
|
|
||||||
bmpFileHeader.bfType = 0x4D42; //https://stackoverflow.com/questions/601430/multibyte-character-constants-and-bitmap-file-header-type-constants#601536
|
bmpFileHeader.bfType = 0x4D42; // REF: 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.bfSize = (DWORD)bmpFileSize; // Up to 4GB works fine
|
||||||
bmpFileHeader.bfOffBits = sizeof(bmpFileHeader) + pixelOffset;
|
bmpFileHeader.bfOffBits = sizeof(bmpFileHeader) + pixelOffset;
|
||||||
|
|
||||||
//
|
// WARNING: Each process has a default heap provided by the system
|
||||||
// Each process has a default heap provided by the system
|
|
||||||
// Memory objects allocated by GlobalAlloc and LocalAlloc are in private,
|
// Memory objects allocated by GlobalAlloc and LocalAlloc are in private,
|
||||||
// committed pages with read/write access that cannot be accessed by other processes.
|
// 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
|
// 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
|
// that may cause heap corruption. We could create a FreeImage function
|
||||||
//
|
bmpData = (BYTE *)RL_MALLOC(sizeof(bmpFileHeader) + clipDataSize);
|
||||||
bmpData = (BYTE *)malloc(sizeof(bmpFileHeader) + clipDataSize);
|
|
||||||
// First we add the header for a bmp file
|
// First we add the header for a bmp file
|
||||||
memcpy(bmpData, &bmpFileHeader, sizeof(bmpFileHeader));
|
memcpy(bmpData, &bmpFileHeader, sizeof(bmpFileHeader)); // Add BMP file header data
|
||||||
// Then we add the header for the bmp itself + the pixel data
|
// Then we add the header for the bmp itself + the pixel data
|
||||||
memcpy(bmpData + sizeof(bmpFileHeader), bmpInfoHeader, clipDataSize);
|
memcpy(bmpData + sizeof(bmpFileHeader), bmpInfoHeader, clipDataSize); // Add BMP info header data
|
||||||
msgString = "Clipboad image acquired successfully";
|
|
||||||
|
|
||||||
|
msgString = "Clipboad image acquired successfully";
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
GlobalUnlock(clipHandle);
|
GlobalUnlock(clipHandle);
|
||||||
|
|
@ -291,6 +289,7 @@ close:
|
||||||
end:
|
end:
|
||||||
|
|
||||||
TRACELOG(severity, msgString);
|
TRACELOG(severity, msgString);
|
||||||
|
|
||||||
return bmpData;
|
return bmpData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -298,65 +297,57 @@ static BOOL OpenClipboardRetrying(HWND hWnd)
|
||||||
{
|
{
|
||||||
static const int maxTries = 20;
|
static const int maxTries = 20;
|
||||||
static const int sleepTimeMS = 60;
|
static const int sleepTimeMS = 60;
|
||||||
for (int _ = 0; _ < maxTries; ++_)
|
|
||||||
|
for (int i = 0; i < maxTries; i++)
|
||||||
{
|
{
|
||||||
// Might be being hold by another process
|
// Might be being hold by another process
|
||||||
// Or yourself forgot to CloseClipboard
|
// Or yourself forgot to CloseClipboard
|
||||||
if (OpenClipboard(hWnd)) {
|
if (OpenClipboard(hWnd)) return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Sleep(sleepTimeMS);
|
Sleep(sleepTimeMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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)
|
// Get the byte offset where does the pixels data start (from a packed DIB)
|
||||||
|
// REF: https://stackoverflow.com/questions/30552255/how-to-read-a-bitmap-from-the-windows-clipboard#30552856
|
||||||
|
// REF: https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader
|
||||||
static int GetPixelDataOffset(BITMAPINFOHEADER bih)
|
static int GetPixelDataOffset(BITMAPINFOHEADER bih)
|
||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
const unsigned int rgbaSize = sizeof(RGBQUAD);
|
const unsigned int rgbaSize = sizeof(RGBQUAD);
|
||||||
|
|
||||||
// biSize Specifies the number of bytes required by the structure
|
// NOTE: biSize specifies the number of bytes required by the structure
|
||||||
// We expect to always be 40 because it should be packed
|
// We expect to always be 40 because it should be packed
|
||||||
if (40 == bih.biSize && 40 == sizeof(BITMAPINFOHEADER))
|
if ((40 == bih.biSize) && (40 == sizeof(BITMAPINFOHEADER)))
|
||||||
{
|
{
|
||||||
//
|
// NOTE: biBitCount specifies the number of bits per pixel.
|
||||||
// biBitCount Specifies the number of bits per pixel.
|
|
||||||
// Might exist some bit masks *after* the header and *before* the pixel offset
|
// Might exist some bit masks *after* the header and *before* the pixel offset
|
||||||
// we're looking, but only if we have more than
|
// we're looking, but only if we have more than
|
||||||
// 8 bits per pixel, so we need to ajust for that
|
// 8 bits per pixel, so we need to ajust for that
|
||||||
//
|
|
||||||
if (bih.biBitCount > 8)
|
if (bih.biBitCount > 8)
|
||||||
{
|
{
|
||||||
// if bih.biCompression is RBG we should NOT offset more
|
// if bih.biCompression is RBG we should NOT offset more
|
||||||
|
|
||||||
if (bih.biCompression == BI_BITFIELDS)
|
if (bih.biCompression == BI_BITFIELDS) offset += 3*rgbaSize;
|
||||||
|
else if (bih.biCompression == 6) // BI_ALPHABITFIELDS
|
||||||
{
|
{
|
||||||
offset += 3 * rgbaSize;
|
// Not widely supported, but valid
|
||||||
} else if (bih.biCompression == 6 /* BI_ALPHABITFIELDS */)
|
offset += 4*rgbaSize;
|
||||||
{
|
|
||||||
// Not widely supported, but valid.
|
|
||||||
offset += 4 * rgbaSize;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// NOTE: biClrUsed specifies the number of color indices in the color table that are actually used by the bitmap
|
||||||
// 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
|
// 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.
|
// 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
|
// If biClrUsed is nonzero and the biBitCount member is less than 16
|
||||||
// the biClrUsed member specifies the actual number of colors
|
// the biClrUsed member specifies the actual number of colors
|
||||||
//
|
if (bih.biClrUsed > 0) offset += bih.biClrUsed*rgbaSize;
|
||||||
if (bih.biClrUsed > 0) {
|
else
|
||||||
offset += bih.biClrUsed * rgbaSize;
|
{
|
||||||
} else {
|
if (bih.biBitCount < 16) offset = offset + (rgbaSize << bih.biBitCount);
|
||||||
if (bih.biBitCount < 16)
|
|
||||||
{
|
|
||||||
offset = offset + (rgbaSize << bih.biBitCount);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return bih.biSize + offset;
|
return bih.biSize + offset;
|
||||||
|
|
|
||||||
|
|
@ -1049,14 +1049,14 @@ Image GetClipboardImage(void)
|
||||||
#if defined(SUPPORT_CLIPBOARD_IMAGE)
|
#if defined(SUPPORT_CLIPBOARD_IMAGE)
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
unsigned long long int dataSize = 0;
|
unsigned long long int dataSize = 0;
|
||||||
void *fileData = NULL;
|
void *bmpData = NULL;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
|
|
||||||
fileData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize);
|
bmpData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize);
|
||||||
|
|
||||||
if (fileData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data.");
|
if (bmpData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data.");
|
||||||
else image = LoadImageFromMemory(".bmp", (const unsigned char *)fileData, (int)dataSize);
|
else image = LoadImageFromMemory(".bmp", (const unsigned char *)bmpData, (int)dataSize);
|
||||||
#else
|
#else
|
||||||
TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform");
|
TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform");
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1469,7 +1469,7 @@ int InitPlatform(void)
|
||||||
if (!eglChooseConfig(platform.device, framebufferAttribs, configs, numConfigs, &matchingNumConfigs))
|
if (!eglChooseConfig(platform.device, framebufferAttribs, configs, numConfigs, &matchingNumConfigs))
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to choose EGL config: 0x%x", eglGetError());
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to choose EGL config: 0x%x", eglGetError());
|
||||||
free(configs);
|
RL_FREE(configs);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,14 @@
|
||||||
* - Linux (X11/Wayland desktop mode)
|
* - Linux (X11/Wayland desktop mode)
|
||||||
* - macOS/OSX (x64, arm64)
|
* - macOS/OSX (x64, arm64)
|
||||||
* - Others (not tested)
|
* - Others (not tested)
|
||||||
* > PLATFORM_WEB_RGFW:
|
* > PLATFORM_DESKTOP_WIN32 (native Win32):
|
||||||
|
* - Windows (Win32, Win64)
|
||||||
* > PLATFORM_WEB (GLFW + Emscripten):
|
* > PLATFORM_WEB (GLFW + Emscripten):
|
||||||
* - HTML5 (WebAssembly)
|
* - HTML5 (WebAssembly)
|
||||||
* > PLATFORM_WEB_EMSCRIPTEN (Emscripten):
|
* > PLATFORM_WEB_EMSCRIPTEN (Emscripten):
|
||||||
* - HTML5 (WebAssembly)
|
* - HTML5 (WebAssembly)
|
||||||
|
* > PLATFORM_WEB_RGFW (Emscripten):
|
||||||
|
* - HTML5 (WebAssembly)
|
||||||
* > PLATFORM_DRM (native DRM):
|
* > PLATFORM_DRM (native DRM):
|
||||||
* - Raspberry Pi 0-5 (DRM/KMS)
|
* - Raspberry Pi 0-5 (DRM/KMS)
|
||||||
* - Linux DRM subsystem (KMS mode)
|
* - Linux DRM subsystem (KMS mode)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user