diff --git a/include/SDL3/SDL_clipboard.h b/include/SDL3/SDL_clipboard.h index 0ec724ac5b..afd3bb56a6 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 84cc539b30..c9d06105eb 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 d0707e7db9..b0f3250e4a 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 a25e2cbdc7..88274b6f72 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 5e6e042299..1953550543 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();