From 54c555e394668ad9f04de8298d3d1977ea99bd67 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 30 Dec 2024 21:38:57 -0800
Subject: [PATCH] Send supported mime types for external clipboard contents on
Windows
---
src/video/windows/SDL_windowsclipboard.c | 100 +++++++++++++----------
1 file changed, 59 insertions(+), 41 deletions(-)
diff --git a/src/video/windows/SDL_windowsclipboard.c b/src/video/windows/SDL_windowsclipboard.c
index dcb46bab597ba..2b6dea7a1b303 100644
--- a/src/video/windows/SDL_windowsclipboard.c
+++ b/src/video/windows/SDL_windowsclipboard.c
@@ -352,54 +352,75 @@ bool WIN_HasClipboardData(SDL_VideoDevice *_this, const char *mime_type)
return false;
}
+static int GetClipboardFormatMimeType(UINT format, char *name)
+{
+ static struct
+ {
+ UINT format;
+ const char *mime_type;
+ } mime_types[] = {
+ { TEXT_FORMAT, "text/plain;charset=utf-8" },
+ { IMAGE_FORMAT, IMAGE_MIME_TYPE },
+ };
+
+ for (int i = 0; i < SDL_arraysize(mime_types); ++i) {
+ if (format == mime_types[i].format) {
+ size_t len = SDL_strlen(mime_types[i].mime_type) + 1;
+ if (name) {
+ SDL_memcpy(name, mime_types[i].mime_type, len);
+ }
+ return (int)len;
+ }
+ }
+ return 0;
+}
+
static char **GetMimeTypes(int *pnformats)
{
- *pnformats = 0;
+ char **new_mime_types = NULL;
- int nformats = CountClipboardFormats();
- size_t allocSize = (nformats + 1) * sizeof(char*);
-
- UINT format = 0;
- int formatsSz = 0;
- int i;
- for (i = 0; i < nformats; i++) {
- format = EnumClipboardFormats(format);
- if (!format) {
- nformats = i;
- break;
- }
+ *pnformats = 0;
- char mimeType[200];
- int nchars = GetClipboardFormatNameA(format, mimeType, sizeof(mimeType));
- formatsSz += nchars + 1;
- }
+ if (WIN_OpenClipboard(SDL_GetVideoDevice())) {
+ int nformats = 0;
+ UINT format = 0;
+ int formatsSz = 0;
+ for ( ; ; ) {
+ format = EnumClipboardFormats(format);
+ if (!format) {
+ break;
+ }
- char **new_mime_types = SDL_AllocateTemporaryMemory(allocSize + formatsSz);
- if (!new_mime_types)
- return NULL;
-
- format = 0;
- char *strPtr = (char *)(new_mime_types + nformats + 1);
- int formatRemains = formatsSz;
- for (i = 0; i < nformats; i++) {
- format = EnumClipboardFormats(format);
- if (!format) {
- nformats = i;
- break;
+ int len = GetClipboardFormatMimeType(format, NULL);
+ if (len > 0) {
+ ++nformats;
+ formatsSz += len;
+ }
}
- new_mime_types[i] = strPtr;
+ new_mime_types = SDL_AllocateTemporaryMemory((nformats + 1) * sizeof(char *) + formatsSz);
+ if (new_mime_types) {
+ format = 0;
+ char *strPtr = (char *)(new_mime_types + nformats + 1);
+ int i = 0;
+ for ( ; ; ) {
+ format = EnumClipboardFormats(format);
+ if (!format) {
+ break;
+ }
- int nchars = GetClipboardFormatNameA(format, strPtr, formatRemains-1);
- strPtr += nchars;
- *strPtr = '\0';
- strPtr++;
+ int len = GetClipboardFormatMimeType(format, strPtr);
+ if (len > 0) {
+ new_mime_types[i++] = strPtr;
+ strPtr += len;
+ }
+ }
- formatRemains -= (nchars + 1);
+ new_mime_types[nformats] = NULL;
+ *pnformats = nformats;
+ }
+ WIN_CloseClipboard();
}
-
- new_mime_types[nformats] = NULL;
- *pnformats = nformats;
return new_mime_types;
}
@@ -412,10 +433,7 @@ void WIN_CheckClipboardUpdate(struct SDL_VideoData *data)
char **new_mime_types = GetMimeTypes(&nformats);
if (new_mime_types) {
SDL_SendClipboardUpdate(false, new_mime_types, nformats);
- } else {
- WIN_SetError("Couldn't get clipboard mime types");
}
-
}
data->clipboard_count = seq;