From 1862a62b5d22c90323ddb257d75974348c3c807e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 15 Apr 2024 12:04:26 -0700 Subject: [PATCH] Replaced SDL_GetNumTouchFingers() and SDL_GetTouchFinger() with SDL_GetTouchFingers() Fixes https://github.com/libsdl-org/SDL/issues/9484 --- docs/README-migration.md | 8 ++++-- include/SDL3/SDL_touch.h | 27 +++---------------- src/dynapi/SDL_dynapi.sym | 3 +-- src/dynapi/SDL_dynapi_overrides.h | 3 +-- src/dynapi/SDL_dynapi_procs.h | 3 +-- src/events/SDL_touch.c | 45 ++++++++++++++++++------------- src/video/cocoa/SDL_cocoawindow.m | 26 ++++++++++-------- 7 files changed, 55 insertions(+), 60 deletions(-) diff --git a/docs/README-migration.md b/docs/README-migration.md index 4d5590e50..38a739988 100644 --- a/docs/README-migration.md +++ b/docs/README-migration.md @@ -1631,15 +1631,19 @@ If you were using this macro for other things besides SDL ticks values, you can ## SDL_touch.h -SDL_GetNumTouchFingers() returns a negative error code if there was an error. - SDL_GetTouchName is replaced with SDL_GetTouchDeviceName(), which takes an SDL_TouchID instead of an index. SDL_TouchID and SDL_FingerID are now Uint64 with 0 being an invalid value. +Rather than iterating over touch devices using an index, there is a new function SDL_GetTouchDevices() to get the available devices. + +Rather than iterating over touch fingers using an index, there is a new function SDL_GetTouchFingers() to get the current set of active fingers. + The following functions have been removed: * SDL_GetNumTouchDevices() - replaced with SDL_GetTouchDevices() +* SDL_GetNumTouchFingers() - replaced with SDL_GetTouchFingers() * SDL_GetTouchDevice() - replaced with SDL_GetTouchDevices() +* SDL_GetTouchFinger() - replaced with SDL_GetTouchFingers() ## SDL_version.h diff --git a/include/SDL3/SDL_touch.h b/include/SDL3/SDL_touch.h index d7a6da4d0..12ac290a6 100644 --- a/include/SDL3/SDL_touch.h +++ b/include/SDL3/SDL_touch.h @@ -117,34 +117,15 @@ extern DECLSPEC const char* SDLCALL SDL_GetTouchDeviceName(SDL_TouchID touchID); extern DECLSPEC SDL_TouchDeviceType SDLCALL SDL_GetTouchDeviceType(SDL_TouchID touchID); /** - * Get the number of active fingers for a given touch device. + * Get a list of active fingers for a given touch device. * * \param touchID the ID of a touch device - * \returns the number of active fingers for a given touch device on success - * or a negative error code on failure; call SDL_GetError() for more - * information. + * \param count a pointer filled in with the number of fingers returned, can be NULL. + * \returns a NULL terminated array of SDL_Finger pointers which should be freed with SDL_free(), or NULL on error; call SDL_GetError() for more details. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_GetTouchFinger */ -extern DECLSPEC int SDLCALL SDL_GetNumTouchFingers(SDL_TouchID touchID); - -/** - * Get the finger object for specified touch device ID and finger index. - * - * The returned resource is owned by SDL and should not be deallocated. - * - * \param touchID the ID of the requested touch device - * \param index the index of the requested finger - * \returns a pointer to the SDL_Finger object or NULL if no object at the - * given ID and index could be found. - * - * \since This function is available since SDL 3.0.0. - * - * \sa SDL_GetNumTouchFingers - */ -extern DECLSPEC SDL_Finger * SDLCALL SDL_GetTouchFinger(SDL_TouchID touchID, int index); +extern DECLSPEC SDL_Finger **SDLCALL SDL_GetTouchFingers(SDL_TouchID touchID, int *count); /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index 802f6954d..a018f0954 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -346,7 +346,6 @@ SDL3_0.0.0 { SDL_GetNumJoystickButtons; SDL_GetNumJoystickHats; SDL_GetNumRenderDrivers; - SDL_GetNumTouchFingers; SDL_GetNumVideoDrivers; SDL_GetNumberProperty; SDL_GetOriginalMemoryFunctions; @@ -455,7 +454,7 @@ SDL3_0.0.0 { SDL_GetTouchDeviceName; SDL_GetTouchDeviceType; SDL_GetTouchDevices; - SDL_GetTouchFinger; + SDL_GetTouchFingers; SDL_GetUserFolder; SDL_GetVersion; SDL_GetVideoDriver; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index c45e30b7e..2c3200bf9 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -371,7 +371,6 @@ #define SDL_GetNumJoystickButtons SDL_GetNumJoystickButtons_REAL #define SDL_GetNumJoystickHats SDL_GetNumJoystickHats_REAL #define SDL_GetNumRenderDrivers SDL_GetNumRenderDrivers_REAL -#define SDL_GetNumTouchFingers SDL_GetNumTouchFingers_REAL #define SDL_GetNumVideoDrivers SDL_GetNumVideoDrivers_REAL #define SDL_GetNumberProperty SDL_GetNumberProperty_REAL #define SDL_GetOriginalMemoryFunctions SDL_GetOriginalMemoryFunctions_REAL @@ -480,7 +479,7 @@ #define SDL_GetTouchDeviceName SDL_GetTouchDeviceName_REAL #define SDL_GetTouchDeviceType SDL_GetTouchDeviceType_REAL #define SDL_GetTouchDevices SDL_GetTouchDevices_REAL -#define SDL_GetTouchFinger SDL_GetTouchFinger_REAL +#define SDL_GetTouchFingers SDL_GetTouchFingers_REAL #define SDL_GetUserFolder SDL_GetUserFolder_REAL #define SDL_GetVersion SDL_GetVersion_REAL #define SDL_GetVideoDriver SDL_GetVideoDriver_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 64e7d72a0..0104900d9 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -409,7 +409,6 @@ SDL_DYNAPI_PROC(int,SDL_GetNumJoystickBalls,(SDL_Joystick *a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetNumJoystickButtons,(SDL_Joystick *a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetNumJoystickHats,(SDL_Joystick *a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetNumRenderDrivers,(void),(),return) -SDL_DYNAPI_PROC(int,SDL_GetNumTouchFingers,(SDL_TouchID a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetNumVideoDrivers,(void),(),return) SDL_DYNAPI_PROC(Sint64,SDL_GetNumberProperty,(SDL_PropertiesID a, const char *b, Sint64 c),(a,b,c),return) SDL_DYNAPI_PROC(void,SDL_GetOriginalMemoryFunctions,(SDL_malloc_func *a, SDL_calloc_func *b, SDL_realloc_func *c, SDL_free_func *d),(a,b,c,d),) @@ -511,7 +510,7 @@ SDL_DYNAPI_PROC(Uint64,SDL_GetTicksNS,(void),(),return) SDL_DYNAPI_PROC(const char*,SDL_GetTouchDeviceName,(SDL_TouchID a),(a),return) SDL_DYNAPI_PROC(SDL_TouchDeviceType,SDL_GetTouchDeviceType,(SDL_TouchID a),(a),return) SDL_DYNAPI_PROC(SDL_TouchID*,SDL_GetTouchDevices,(int *a),(a),return) -SDL_DYNAPI_PROC(SDL_Finger*,SDL_GetTouchFinger,(SDL_TouchID a, int b),(a,b),return) +SDL_DYNAPI_PROC(SDL_Finger**,SDL_GetTouchFingers,(SDL_TouchID a, int *b),(a,b),return) SDL_DYNAPI_PROC(char*,SDL_GetUserFolder,(SDL_Folder a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetVersion,(SDL_Version *a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetVideoDriver,(int a),(a),return) diff --git a/src/events/SDL_touch.c b/src/events/SDL_touch.c index 98975e9ca..04651f314 100644 --- a/src/events/SDL_touch.c +++ b/src/events/SDL_touch.c @@ -131,26 +131,37 @@ static SDL_Finger *SDL_GetFinger(const SDL_Touch *touch, SDL_FingerID id) return touch->fingers[index]; } -int SDL_GetNumTouchFingers(SDL_TouchID touchID) +SDL_Finger **SDL_GetTouchFingers(SDL_TouchID touchID, int *count) { - SDL_Touch *touch = SDL_GetTouch(touchID); - if (touch) { - return touch->num_fingers; - } - return 0; -} + SDL_Finger **fingers; + SDL_Finger *finger_data; + + if (count) { + *count = 0; + } -SDL_Finger *SDL_GetTouchFinger(SDL_TouchID touchID, int index) -{ SDL_Touch *touch = SDL_GetTouch(touchID); if (!touch) { return NULL; } - if (index < 0 || index >= touch->num_fingers) { - SDL_SetError("Unknown touch finger"); + + /* Create a snapshot of the current finger state */ + fingers = (SDL_Finger **)SDL_malloc((touch->num_fingers + 1) * sizeof(*fingers) + touch->num_fingers * sizeof(**fingers)); + if (!fingers) { return NULL; } - return touch->fingers[index]; + finger_data = (SDL_Finger *)((Uint8 *)fingers + (touch->num_fingers + 1) * sizeof(*fingers)); + + for (int i = 0; i < touch->num_fingers; ++i) { + fingers[i] = &finger_data[i]; + SDL_copyp(fingers[i], touch->fingers[i]); + } + fingers[touch->num_fingers] = NULL; + + if (count) { + *count = touch->num_fingers; + } + return fingers; } int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name) @@ -224,17 +235,15 @@ static int SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float static int SDL_DelFinger(SDL_Touch *touch, SDL_FingerID fingerid) { - SDL_Finger *temp; - int index = SDL_GetFingerIndex(touch, fingerid); if (index < 0) { return -1; } - touch->num_fingers--; - temp = touch->fingers[index]; - touch->fingers[index] = touch->fingers[touch->num_fingers]; - touch->fingers[touch->num_fingers] = temp; + if (index < (touch->num_fingers - 1)) { + SDL_memmove(&touch->fingers[index], &touch->fingers[index + 1], (touch->num_fingers - index - 1) * sizeof(touch->fingers[index])); + } + --touch->num_fingers; return 0; } diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index e18e4a3f0..010854198 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -1716,17 +1716,21 @@ static int Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL_ } } if (existingTouchCount == 0) { - int numFingers = SDL_GetNumTouchFingers(touchID); - DLog("Reset Lost Fingers: %d", numFingers); - for (--numFingers; numFingers >= 0; --numFingers) { - SDL_Finger *finger = SDL_GetTouchFinger(touchID, numFingers); - /* trackpad touches have no window. If we really wanted one we could - * use the window that has mouse or keyboard focus. - * Sending a null window currently also prevents synthetic mouse - * events from being generated from touch events. - */ - SDL_Window *window = NULL; - SDL_SendTouch(Cocoa_GetEventTimestamp([theEvent timestamp]), touchID, finger->id, window, SDL_FALSE, 0, 0, 0); + int numFingers; + SDL_Finger **fingers = SDL_GetTouchFingers(touchID, &numFingers); + if (fingers) { + DLog("Reset Lost Fingers: %d", numFingers); + for (--numFingers; numFingers >= 0; --numFingers) { + SDL_Finger *finger = fingers[numFingers]; + /* trackpad touches have no window. If we really wanted one we could + * use the window that has mouse or keyboard focus. + * Sending a null window currently also prevents synthetic mouse + * events from being generated from touch events. + */ + SDL_Window *window = NULL; + SDL_SendTouch(Cocoa_GetEventTimestamp([theEvent timestamp]), touchID, finger->id, window, SDL_FALSE, 0, 0, 0); + } + SDL_free(fingers); } }