From c4eac60000d6c0a3fdbe09aa8211d7cec66c408d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 19 Jul 2024 11:08:03 -0700 Subject: [PATCH] SDL_GetClipboardData() follows the SDL_GetStringRule --- include/SDL3/SDL_clipboard.h | 7 ++++--- src/dynapi/SDL_dynapi_procs.h | 2 +- src/test/SDL_test_common.c | 3 +-- src/video/SDL_clipboard.c | 29 ++++++++++++++--------------- test/testautomation_clipboard.c | 12 ++---------- 5 files changed, 22 insertions(+), 31 deletions(-) diff --git a/include/SDL3/SDL_clipboard.h b/include/SDL3/SDL_clipboard.h index 8d7a19087..504f75ffc 100644 --- a/include/SDL3/SDL_clipboard.h +++ b/include/SDL3/SDL_clipboard.h @@ -219,15 +219,16 @@ extern SDL_DECLSPEC int SDLCALL SDL_ClearClipboardData(void); * \param mime_type the mime type to read from the clipboard. * \param size a pointer filled in with the length of the returned data. * \returns the retrieved data buffer or NULL on failure; call SDL_GetError() - * for more information. Caller must call SDL_free() on the returned - * pointer when done with it. + * for more information. + * + * This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory(). * * \since This function is available since SDL 3.0.0. * * \sa SDL_HasClipboardData * \sa SDL_SetClipboardData */ -extern SDL_DECLSPEC void * SDLCALL SDL_GetClipboardData(const char *mime_type, size_t *size); +extern SDL_DECLSPEC const void * SDLCALL SDL_GetClipboardData(const char *mime_type, size_t *size); /** * Query whether there is data in the clipboard for the provided mime type. diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index db6e677a3..651e8a408 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -234,7 +234,7 @@ SDL_DYNAPI_PROC(SDL_CameraPosition,SDL_GetCameraPosition,(SDL_CameraID a),(a),re SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetCameraProperties,(SDL_Camera *a),(a),return) SDL_DYNAPI_PROC(const SDL_CameraSpec* const*,SDL_GetCameraSupportedFormats,(SDL_CameraID a, int *b),(a,b),return) SDL_DYNAPI_PROC(const 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(const void*,SDL_GetClipboardData,(const char *a, size_t *b),(a,b),return) SDL_DYNAPI_PROC(const char*,SDL_GetClipboardText,(void),(),return) SDL_DYNAPI_PROC(const SDL_DisplayMode*,SDL_GetClosestFullscreenDisplayMode,(SDL_DisplayID a, int b, int c, float d, SDL_bool e),(a,b,c,d,e),return) SDL_DYNAPI_PROC(const char*,SDL_GetCurrentAudioDriver,(void),(),return) diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index 307b3b03e..2de6b74c9 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -1996,7 +1996,7 @@ static void SDLTest_PasteScreenShot(void) for (i = 0; i < SDL_arraysize(image_formats); ++i) { size_t size; - void *data = SDL_GetClipboardData(image_formats[i], &size); + const void *data = SDL_GetClipboardData(image_formats[i], &size); if (data) { char filename[16]; SDL_IOStream *file; @@ -2008,7 +2008,6 @@ static void SDLTest_PasteScreenShot(void) SDL_WriteIO(file, data, size); SDL_CloseIO(file); } - SDL_free(data); return; } } diff --git a/src/video/SDL_clipboard.c b/src/video/SDL_clipboard.c index a0bd9e8f7..f89ef60f6 100644 --- a/src/video/SDL_clipboard.c +++ b/src/video/SDL_clipboard.c @@ -162,7 +162,7 @@ void *SDL_GetInternalClipboardData(SDL_VideoDevice *_this, const char *mime_type return data; } -void *SDL_GetClipboardData(const char *mime_type, size_t *size) +const void *SDL_GetClipboardData(const char *mime_type, size_t *size) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); @@ -184,16 +184,16 @@ void *SDL_GetClipboardData(const char *mime_type, size_t *size) *size = 0; if (_this->GetClipboardData) { - return _this->GetClipboardData(_this, mime_type, size); + return SDL_FreeLater(_this->GetClipboardData(_this, mime_type, size)); } else if (_this->GetClipboardText && SDL_IsTextMimeType(mime_type)) { - void *data = _this->GetClipboardText(_this); - if (data && *(char *)data == '\0') { - SDL_free(data); - data = NULL; + char *text = _this->GetClipboardText(_this); + if (text && *text == '\0') { + SDL_free(text); + text = NULL; } - return data; + return SDL_FreeLater(text); } else { - return SDL_GetInternalClipboardData(_this, mime_type, size); + return SDL_FreeLater(SDL_GetInternalClipboardData(_this, mime_type, size)); } } @@ -297,16 +297,15 @@ const char *SDL_GetClipboardText(void) text_mime_types = SDL_GetTextMimeTypes(_this, &num_mime_types); for (i = 0; i < num_mime_types; ++i) { - void *clipdata = SDL_GetClipboardData(text_mime_types[i], &length); + const void *clipdata = SDL_GetClipboardData(text_mime_types[i], &length); if (clipdata) { - text = (const char *) clipdata; - SDL_FreeLater(clipdata); // returned string follows the SDL_GetStringRule. + text = (const char *)clipdata; break; } } if (!text) { - text = ""; + text = SDL_CreateTemporaryString(""); } return text; } @@ -349,7 +348,7 @@ int SDL_SetPrimarySelectionText(const char *text) return -1; } } else { - SDL_FreeLater(_this->primary_selection_text); // SDL_GetPrimarySelectionText() returns this pointer. + SDL_free(_this->primary_selection_text); _this->primary_selection_text = SDL_strdup(text); } @@ -367,13 +366,13 @@ const char *SDL_GetPrimarySelectionText(void) } if (_this->GetPrimarySelectionText) { - return SDL_FreeLater(_this->GetPrimarySelectionText(_this)); // returned pointer follows the SDL_GetStringRule + return SDL_FreeLater(_this->GetPrimarySelectionText(_this)); } else { const char *text = _this->primary_selection_text; if (!text) { text = ""; } - return text; + return SDL_CreateTemporaryString(text); } } diff --git a/test/testautomation_clipboard.c b/test/testautomation_clipboard.c index 556802917..3af66c645 100644 --- a/test/testautomation_clipboard.c +++ b/test/testautomation_clipboard.c @@ -86,9 +86,9 @@ static int clipboard_testClipboardDataFunctions(void *arg) int last_clipboard_update_count; int last_clipboard_callback_count; int last_clipboard_cleanup_count; - void *data; + const void *data; size_t size; - char *text; + const char *text; const char *expected_text; TestClipboardData test_data1 = { @@ -186,7 +186,6 @@ static int clipboard_testClipboardDataFunctions(void *arg) size == SDL_strlen(expected_text), "Verify test text size, expected %d, got %d", (int)SDL_strlen(expected_text), (int)size); - SDL_free(text); expected_text = "CUSTOM"; boolResult = SDL_HasClipboardData(test_mime_types[TEST_MIME_TYPE_CUSTOM_TEXT]); @@ -206,7 +205,6 @@ static int clipboard_testClipboardDataFunctions(void *arg) size == SDL_strlen(expected_text), "Verify test text size, expected %d, got %d", (int)SDL_strlen(expected_text), (int)size); - SDL_free(text); boolResult = SDL_HasClipboardData(test_mime_types[TEST_MIME_TYPE_DATA]); SDLTest_AssertCheck( @@ -220,7 +218,6 @@ static int clipboard_testClipboardDataFunctions(void *arg) size == test_data1.data_size, "Verify test data size, expected %d, got %d", (int)test_data1.data_size, (int)size); - SDL_free(data); boolResult = SDL_HasClipboardData("test/invalid"); SDLTest_AssertCheck( @@ -235,7 +232,6 @@ static int clipboard_testClipboardDataFunctions(void *arg) size == 0, "Verify invalid data size, expected 0, got %d", (int)size); - SDL_free(data); #if 0 /* There's no guarantee how or when the callback is called */ SDLTest_AssertCheck( @@ -287,7 +283,6 @@ static int clipboard_testClipboardDataFunctions(void *arg) size == SDL_strlen(expected_text), "Verify test text size, expected %d, got %d", (int)SDL_strlen(expected_text), (int)size); - SDL_free(text); expected_text = "CUSTOM"; boolResult = SDL_HasClipboardData(test_mime_types[TEST_MIME_TYPE_CUSTOM_TEXT]); @@ -307,7 +302,6 @@ static int clipboard_testClipboardDataFunctions(void *arg) size == SDL_strlen(expected_text), "Verify test text size, expected %d, got %d", (int)SDL_strlen(expected_text), (int)size); - SDL_free(text); data = SDL_GetClipboardData(test_mime_types[TEST_MIME_TYPE_DATA], &size); SDLTest_AssertCheck( @@ -317,7 +311,6 @@ static int clipboard_testClipboardDataFunctions(void *arg) size == test_data2.data_size, "Verify test data size, expected %d, got %d", (int)test_data2.data_size, (int)size); - SDL_free(data); data = SDL_GetClipboardData("test/invalid", &size); SDLTest_AssertCheck( @@ -328,7 +321,6 @@ static int clipboard_testClipboardDataFunctions(void *arg) size == 0, "Verify invalid data size, expected 0, got %d", (int)size); - SDL_free(data); #if 0 /* There's no guarantee how or when the callback is called */ SDLTest_AssertCheck(