From 1862a62b5d22c90323ddb257d75974348c3c807e Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
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 | 43 +++++++++++++++++++------------
src/video/cocoa/SDL_cocoawindow.m | 26 +++++++++++--------
7 files changed, 54 insertions(+), 59 deletions(-)
diff --git a/docs/README-migration.md b/docs/README-migration.md
index 4d5590e5084c6..38a7399882cc1 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 d7a6da4d0994b..12ac290a6fd8f 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 802f6954d4304..a018f095473fd 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 c45e30b7effa6..2c3200bf9f6d1 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 64e7d72a01afa..0104900d978b3 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 98975e9ca028f..04651f314a313 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;
+ SDL_Finger **fingers;
+ SDL_Finger *finger_data;
+
+ if (count) {
+ *count = 0;
}
- return 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 e18e4a3f0fdb6..01085419810be 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -1716,17 +1716,21 @@ - (void)touchesBeganWithEvent:(NSEvent *)theEvent
}
}
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);
}
}