Send supported mime types for external clipboard contents on Windows

This commit is contained in:
Sam Lantinga
2024-12-30 21:38:57 -08:00
parent 8b155708ff
commit 54c555e394

View File

@@ -352,54 +352,75 @@ bool WIN_HasClipboardData(SDL_VideoDevice *_this, const char *mime_type)
return false; 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) static char **GetMimeTypes(int *pnformats)
{ {
char **new_mime_types = NULL;
*pnformats = 0; *pnformats = 0;
int nformats = CountClipboardFormats(); if (WIN_OpenClipboard(SDL_GetVideoDevice())) {
size_t allocSize = (nformats + 1) * sizeof(char*); int nformats = 0;
UINT format = 0;
int formatsSz = 0;
for ( ; ; ) {
format = EnumClipboardFormats(format);
if (!format) {
break;
}
UINT format = 0; int len = GetClipboardFormatMimeType(format, NULL);
int formatsSz = 0; if (len > 0) {
int i; ++nformats;
for (i = 0; i < nformats; i++) { formatsSz += len;
format = EnumClipboardFormats(format); }
if (!format) {
nformats = i;
break;
} }
char mimeType[200]; new_mime_types = SDL_AllocateTemporaryMemory((nformats + 1) * sizeof(char *) + formatsSz);
int nchars = GetClipboardFormatNameA(format, mimeType, sizeof(mimeType)); if (new_mime_types) {
formatsSz += nchars + 1; format = 0;
} char *strPtr = (char *)(new_mime_types + nformats + 1);
int i = 0;
for ( ; ; ) {
format = EnumClipboardFormats(format);
if (!format) {
break;
}
char **new_mime_types = SDL_AllocateTemporaryMemory(allocSize + formatsSz); int len = GetClipboardFormatMimeType(format, strPtr);
if (!new_mime_types) if (len > 0) {
return NULL; new_mime_types[i++] = strPtr;
strPtr += len;
}
}
format = 0; new_mime_types[nformats] = NULL;
char *strPtr = (char *)(new_mime_types + nformats + 1); *pnformats = nformats;
int formatRemains = formatsSz;
for (i = 0; i < nformats; i++) {
format = EnumClipboardFormats(format);
if (!format) {
nformats = i;
break;
} }
WIN_CloseClipboard();
new_mime_types[i] = strPtr;
int nchars = GetClipboardFormatNameA(format, strPtr, formatRemains-1);
strPtr += nchars;
*strPtr = '\0';
strPtr++;
formatRemains -= (nchars + 1);
} }
new_mime_types[nformats] = NULL;
*pnformats = nformats;
return new_mime_types; return new_mime_types;
} }
@@ -412,10 +433,7 @@ void WIN_CheckClipboardUpdate(struct SDL_VideoData *data)
char **new_mime_types = GetMimeTypes(&nformats); char **new_mime_types = GetMimeTypes(&nformats);
if (new_mime_types) { if (new_mime_types) {
SDL_SendClipboardUpdate(false, new_mime_types, nformats); SDL_SendClipboardUpdate(false, new_mime_types, nformats);
} else {
WIN_SetError("Couldn't get clipboard mime types");
} }
} }
data->clipboard_count = seq; data->clipboard_count = seq;