From f32e96f5e281dffe0e2dca497effcdc16f9adb62 Mon Sep 17 00:00:00 2001
From: David Fort <[EMAIL REDACTED]>
Date: Fri, 27 Sep 2024 12:01:56 +0200
Subject: [PATCH] clipboard: add SDL_ClipboardMimeTypes
This function allows to retrieve the available mime types without doing any
synthesizing.
---
include/SDL3/SDL_clipboard.h | 14 +++++++++++
src/dynapi/SDL_dynapi.sym | 1 +
src/dynapi/SDL_dynapi_overrides.h | 3 ++-
src/dynapi/SDL_dynapi_procs.h | 1 +
src/video/SDL_clipboard.c | 40 +++++++++++++++++++++++++++++++
5 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/include/SDL3/SDL_clipboard.h b/include/SDL3/SDL_clipboard.h
index 0ec724ac5b1cf..afd3bb56a628e 100644
--- a/include/SDL3/SDL_clipboard.h
+++ b/include/SDL3/SDL_clipboard.h
@@ -42,6 +42,20 @@ extern "C" {
/* Function prototypes */
+/**
+ * Retrieve the list of mime types available in the clipboard.
+ *
+ * \param num_mime_types a pointer filled with the number of mime types. May be NULL.
+ * \returns a null terminated array of strings with mime types, or NULL on
+ * failure; call SDL_GetError() for more information. This should be
+ * freed with SDL_free() when it is no longer needed.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_SetClipboardData
+ */
+extern SDL_DECLSPEC char ** SDLCALL SDL_GetClipboardMimeTypes(size_t *num_mime_types);
+
/**
* Put UTF-8 text into the clipboard.
*
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index 84cc539b30b00..c9d06105eb7dc 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -248,6 +248,7 @@ SDL3_0.0.0 {
SDL_GetCameraSupportedFormats;
SDL_GetCameras;
SDL_GetClipboardData;
+ SDL_GetClipboardMimeTypes;
SDL_GetClipboardText;
SDL_GetClosestFullscreenDisplayMode;
SDL_GetCurrentAudioDriver;
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index d0707e7db9978..b0f3250e4a2fc 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -273,6 +273,7 @@
#define SDL_GetCameraSupportedFormats SDL_GetCameraSupportedFormats_REAL
#define SDL_GetCameras SDL_GetCameras_REAL
#define SDL_GetClipboardData SDL_GetClipboardData_REAL
+#define SDL_GetClipboardMimeTypes SDL_GetClipboardMimeTypes_REAL
#define SDL_GetClipboardText SDL_GetClipboardText_REAL
#define SDL_GetClosestFullscreenDisplayMode SDL_GetClosestFullscreenDisplayMode_REAL
#define SDL_GetCurrentAudioDriver SDL_GetCurrentAudioDriver_REAL
@@ -1033,7 +1034,7 @@
#define SDL_aligned_free SDL_aligned_free_REAL
#define SDL_asin SDL_asin_REAL
#define SDL_asinf SDL_asinf_REAL
-#define SDL_asprintf SDL_asprintf_REAL
+#define SDL_asprintf SDL_asprintf_REAL
#define SDL_atan SDL_atan_REAL
#define SDL_atan2 SDL_atan2_REAL
#define SDL_atan2f SDL_atan2f_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index a25e2cbdc7d2d..88274b6f720e0 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -294,6 +294,7 @@ SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetCameraProperties,(SDL_Camera *a),(a),ret
SDL_DYNAPI_PROC(SDL_CameraSpec**,SDL_GetCameraSupportedFormats,(SDL_CameraID a, int *b),(a,b),return)
SDL_DYNAPI_PROC(SDL_CameraID*,SDL_GetCameras,(int *a),(a),return)
SDL_DYNAPI_PROC(void*,SDL_GetClipboardData,(const char *a, size_t *b),(a,b),return)
+SDL_DYNAPI_PROC(char **,SDL_GetClipboardMimeTypes,(size_t *a),(a),return)
SDL_DYNAPI_PROC(char*,SDL_GetClipboardText,(void),(),return)
SDL_DYNAPI_PROC(bool,SDL_GetClosestFullscreenDisplayMode,(SDL_DisplayID a, int b, int c, float d, bool e, SDL_DisplayMode *f),(a,b,c,d,e,f),return)
SDL_DYNAPI_PROC(const char*,SDL_GetCurrentAudioDriver,(void),(),return)
diff --git a/src/video/SDL_clipboard.c b/src/video/SDL_clipboard.c
index 5e6e042299c78..1953550543ba3 100644
--- a/src/video/SDL_clipboard.c
+++ b/src/video/SDL_clipboard.c
@@ -53,6 +53,46 @@ void SDL_CancelClipboardData(Uint32 sequence)
_this->clipboard_userdata = NULL;
}
+char **SDL_GetClipboardMimeTypes(size_t *num_mime_types)
+{
+ SDL_VideoDevice *_this = SDL_GetVideoDevice();
+ if (!_this) {
+ SDL_SetError("Video subsystem must be initialized to query clipboard mime types");
+ return NULL;
+ }
+
+ size_t allocSize = sizeof(char *);
+ for (size_t i = 0; i < _this->num_clipboard_mime_types; i++) {
+ allocSize += strlen(_this->clipboard_mime_types[i]) + 1 + sizeof(char *);
+ }
+
+ char *ret = SDL_malloc(allocSize);
+ if (!ret)
+ return NULL;
+
+ char **pointers = (char **)ret;
+ ret += (_this->num_clipboard_mime_types + 1) * sizeof(char *);
+
+ for (size_t i = 0; i < _this->num_clipboard_mime_types; i++) {
+ pointers[i] = ret;
+
+ char *mime_type = _this->clipboard_mime_types[i];
+ /* copy the whole string including the terminating null char */
+ char c;
+ do {
+ c = *mime_type;
+ *ret = c;
+ ret++;
+ mime_type++;
+ } while (c != 0);
+ }
+
+ pointers[_this->num_clipboard_mime_types] = NULL;
+ if (num_mime_types)
+ *num_mime_types = _this->num_clipboard_mime_types;
+ return pointers;
+}
+
bool SDL_SetClipboardData(SDL_ClipboardDataCallback callback, SDL_ClipboardCleanupCallback cleanup, void *userdata, const char **mime_types, size_t num_mime_types)
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();