SDL: Switched SDL_TouchID and SDL_FingerID to be Uint64 with 0 being an invalid value

From a31dc6dfcb8b3a50a9713702271aeaa7c5930131 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 18 Jan 2024 09:19:05 -0800
Subject: [PATCH] Switched SDL_TouchID and SDL_FingerID to be Uint64 with 0
 being an invalid value

---
 .../main/java/org/libsdl/app/SDLActivity.java | 12 +-----
 .../main/java/org/libsdl/app/SDLSurface.java  | 10 -----
 include/SDL3/SDL_touch.h                      |  6 +--
 src/core/linux/SDL_evdev.c                    | 24 +++++-------
 src/events/SDL_events.c                       |  6 +--
 src/events/SDL_touch.c                        |  4 ++
 src/test/SDL_test_common.c                    | 12 +++---
 src/video/android/SDL_androidtouch.c          | 11 +++++-
 src/video/cocoa/SDL_cocoawindow.m             |  6 +--
 src/video/emscripten/SDL_emscriptenevents.c   |  2 +-
 src/video/n3ds/SDL_n3dstouch.c                |  9 ++---
 src/video/uikit/SDL_uikitview.m               |  6 +--
 src/video/vita/SDL_vitatouch.c                | 37 ++++++-------------
 src/video/wayland/SDL_waylandevents.c         | 14 +++----
 src/video/windows/SDL_windowsevents.c         |  9 +++--
 src/video/winrt/SDL_winrtpointerinput.cpp     |  6 +--
 test/testpen.c                                |  2 +-
 17 files changed, 75 insertions(+), 101 deletions(-)

diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
index 0d2aeebfab1e..0b2526b4cdc8 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
@@ -1465,17 +1465,7 @@ public static void initTouch() {
             if (device != null && ((device.getSources() & InputDevice.SOURCE_TOUCHSCREEN) == InputDevice.SOURCE_TOUCHSCREEN
                     || device.isVirtual())) {
 
-                int touchDevId = device.getId();
-                /*
-                 * Prevent id to be -1, since it's used in SDL internal for synthetic events
-                 * Appears when using Android emulator, eg:
-                 *  adb shell input mouse tap 100 100
-                 *  adb shell input touchscreen tap 100 100
-                 */
-                if (touchDevId < 0) {
-                    touchDevId -= 1;
-                }
-                nativeAddTouch(touchDevId, device.getName());
+                nativeAddTouch(device.getId(), device.getName());
             }
         }
     }
diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java b/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java
index 6cd268659c2a..74ecaf5bf42e 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java
@@ -222,16 +222,6 @@ public boolean onTouch(View v, MotionEvent event) {
         int i = -1;
         float x,y,p;
 
-        /*
-         * Prevent id to be -1, since it's used in SDL internal for synthetic events
-         * Appears when using Android emulator, eg:
-         *  adb shell input mouse tap 100 100
-         *  adb shell input touchscreen tap 100 100
-         */
-        if (touchDevId < 0) {
-            touchDevId -= 1;
-        }
-
         // 12290 = Samsung DeX mode desktop mouse
         // 12290 = 0x3002 = 0x2002 | 0x1002 = SOURCE_MOUSE | SOURCE_TOUCHSCREEN
         // 0x2   = SOURCE_CLASS_POINTER
diff --git a/include/SDL3/SDL_touch.h b/include/SDL3/SDL_touch.h
index 4140668f39ec..ccdc2cf0953d 100644
--- a/include/SDL3/SDL_touch.h
+++ b/include/SDL3/SDL_touch.h
@@ -38,8 +38,8 @@
 extern "C" {
 #endif
 
-typedef Sint64 SDL_TouchID;
-typedef Sint64 SDL_FingerID;
+typedef Uint64 SDL_TouchID;
+typedef Uint64 SDL_FingerID;
 
 typedef enum
 {
@@ -61,7 +61,7 @@ typedef struct SDL_Finger
 #define SDL_TOUCH_MOUSEID ((Uint32)-1)
 
 /* Used as the SDL_TouchID for touch events simulated with mouse input */
-#define SDL_MOUSE_TOUCHID ((Sint64)-1)
+#define SDL_MOUSE_TOUCHID ((Uint64)-1)
 
 
 /**
diff --git a/src/core/linux/SDL_evdev.c b/src/core/linux/SDL_evdev.c
index f7e26b12deec..9a435db8d1d4 100644
--- a/src/core/linux/SDL_evdev.c
+++ b/src/core/linux/SDL_evdev.c
@@ -395,7 +395,7 @@ void SDL_EVDEV_Poll(void)
                             break;
                         }
                         if (event->value >= 0) {
-                            item->touchscreen_data->slots[item->touchscreen_data->current_slot].tracking_id = event->value;
+                            item->touchscreen_data->slots[item->touchscreen_data->current_slot].tracking_id = event->value + 1;
                             item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_DOWN;
                         } else {
                             item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_UP;
@@ -551,7 +551,7 @@ void SDL_EVDEV_Poll(void)
                                 break;
                             case EVDEV_TOUCH_SLOTDELTA_UP:
                                 SDL_SendTouch(SDL_EVDEV_GetEventTimestamp(event), item->fd, item->touchscreen_data->slots[j].tracking_id, NULL, SDL_FALSE, norm_x, norm_y, norm_pressure);
-                                item->touchscreen_data->slots[j].tracking_id = -1;
+                                item->touchscreen_data->slots[j].tracking_id = 0;
                                 item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE;
                                 break;
                             case EVDEV_TOUCH_SLOTDELTA_MOVE:
@@ -633,7 +633,7 @@ static int SDL_EVDEV_init_mouse(SDL_evdevlist_item *item, int udev_class)
 
 static int SDL_EVDEV_init_touchscreen(SDL_evdevlist_item *item, int udev_class)
 {
-    int ret, i;
+    int ret;
     unsigned long xreq, yreq;
     char name[64];
     struct input_absinfo abs_info;
@@ -715,10 +715,6 @@ static int SDL_EVDEV_init_touchscreen(SDL_evdevlist_item *item, int udev_class)
         return -1;
     }
 
-    for (i = 0; i < item->touchscreen_data->max_slots; i++) {
-        item->touchscreen_data->slots[i].tracking_id = -1;
-    }
-
     ret = SDL_AddTouch(item->fd, /* I guess our fd is unique enough */
                        (udev_class & SDL_UDEV_DEVICE_TOUCHPAD) ? SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE : SDL_TOUCH_DEVICE_DIRECT,
                        item->touchscreen_data->name);
@@ -792,13 +788,13 @@ static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item)
          * SDL_EVDEV_Poll to tell SDL, the current structure of this code doesn't
          * allow it. Lets just pray to God it doesn't happen.
          */
-        if (item->touchscreen_data->slots[i].tracking_id < 0 &&
+        if (item->touchscreen_data->slots[i].tracking_id == 0 &&
             mt_req_values[i] >= 0) {
-            item->touchscreen_data->slots[i].tracking_id = mt_req_values[i];
+            item->touchscreen_data->slots[i].tracking_id = mt_req_values[i] + 1;
             item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_DOWN;
-        } else if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
+        } else if (item->touchscreen_data->slots[i].tracking_id != 0 &&
                    mt_req_values[i] < 0) {
-            item->touchscreen_data->slots[i].tracking_id = -1;
+            item->touchscreen_data->slots[i].tracking_id = 0;
             item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_UP;
         }
     }
@@ -810,7 +806,7 @@ static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item)
         return;
     }
     for (i = 0; i < item->touchscreen_data->max_slots; i++) {
-        if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
+        if (item->touchscreen_data->slots[i].tracking_id != 0 &&
             item->touchscreen_data->slots[i].x != mt_req_values[i]) {
             item->touchscreen_data->slots[i].x = mt_req_values[i];
             if (item->touchscreen_data->slots[i].delta ==
@@ -828,7 +824,7 @@ static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item)
         return;
     }
     for (i = 0; i < item->touchscreen_data->max_slots; i++) {
-        if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
+        if (item->touchscreen_data->slots[i].tracking_id != 0 &&
             item->touchscreen_data->slots[i].y != mt_req_values[i]) {
             item->touchscreen_data->slots[i].y = mt_req_values[i];
             if (item->touchscreen_data->slots[i].delta ==
@@ -846,7 +842,7 @@ static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item)
         return;
     }
     for (i = 0; i < item->touchscreen_data->max_slots; i++) {
-        if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
+        if (item->touchscreen_data->slots[i].tracking_id != 0 &&
             item->touchscreen_data->slots[i].pressure != mt_req_values[i]) {
             item->touchscreen_data->slots[i].pressure = mt_req_values[i];
             if (item->touchscreen_data->slots[i].delta ==
diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c
index 2a346f03c49a..3ba5376eb8c9 100644
--- a/src/events/SDL_events.c
+++ b/src/events/SDL_events.c
@@ -461,9 +461,9 @@ static void SDL_LogEvent(const SDL_Event *event)
         break;
 
 #define PRINT_FINGER_EVENT(event)                                                                                                                      \
-    (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u touchid=%" SDL_PRIs64 " fingerid=%" SDL_PRIs64 " x=%f y=%f dx=%f dy=%f pressure=%f)", \
-                       (uint)event->tfinger.timestamp, (long long)event->tfinger.touchId,                                                              \
-                       (long long)event->tfinger.fingerId, event->tfinger.x, event->tfinger.y,                                                         \
+    (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u touchid=%" SDL_PRIu64 " fingerid=%" SDL_PRIu64 " x=%f y=%f dx=%f dy=%f pressure=%f)", \
+                       (uint)event->tfinger.timestamp, event->tfinger.touchId,                                                              \
+                       event->tfinger.fingerId, event->tfinger.x, event->tfinger.y,                                                         \
                        event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure)
         SDL_EVENT_CASE(SDL_EVENT_FINGER_DOWN)
         PRINT_FINGER_EVENT(event);
diff --git a/src/events/SDL_touch.c b/src/events/SDL_touch.c
index 071fdff47279..9924b84e30a1 100644
--- a/src/events/SDL_touch.c
+++ b/src/events/SDL_touch.c
@@ -158,6 +158,8 @@ int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name
     SDL_Touch **touchDevices;
     int index;
 
+    SDL_assert(touchID != 0);
+
     index = SDL_GetTouchIndex(touchID);
     if (index >= 0) {
         return index;
@@ -196,6 +198,8 @@ static int SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float
 {
     SDL_Finger *finger;
 
+    SDL_assert(fingerid != 0);
+
     if (touch->num_fingers == touch->max_fingers) {
         SDL_Finger **new_fingers;
         new_fingers = (SDL_Finger **)SDL_realloc(touch->fingers, (touch->max_fingers + 1) * sizeof(*touch->fingers));
diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c
index 6668bd6f6f81..366e28da8db1 100644
--- a/src/test/SDL_test_common.c
+++ b/src/test/SDL_test_common.c
@@ -1883,18 +1883,18 @@ static void SDLTest_PrintEvent(const SDL_Event *event)
         break;
 
     case SDL_EVENT_FINGER_MOTION:
-        SDL_Log("SDL EVENT: Finger: motion touch=%ld, finger=%ld, x=%f, y=%f, dx=%f, dy=%f, pressure=%f",
-                (long)event->tfinger.touchId,
-                (long)event->tfinger.fingerId,
+        SDL_Log("SDL EVENT: Finger: motion touch=%" SDL_PRIu64 ", finger=%" SDL_PRIu64 ", x=%f, y=%f, dx=%f, dy=%f, pressure=%f",
+                event->tfinger.touchId,
+                event->tfinger.fingerId,
                 event->tfinger.x, event->tfinger.y,
                 event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure);
         break;
     case SDL_EVENT_FINGER_DOWN:
     case SDL_EVENT_FINGER_UP:
-        SDL_Log("SDL EVENT: Finger: %s touch=%ld, finger=%ld, x=%f, y=%f, dx=%f, dy=%f, pressure=%f",
+        SDL_Log("SDL EVENT: Finger: %s touch=%" SDL_PRIu64 ", finger=%" SDL_PRIu64 ", x=%f, y=%f, dx=%f, dy=%f, pressure=%f",
                 (event->type == SDL_EVENT_FINGER_DOWN) ? "down" : "up",
-                (long)event->tfinger.touchId,
-                (long)event->tfinger.fingerId,
+                event->tfinger.touchId,
+                event->tfinger.fingerId,
                 event->tfinger.x, event->tfinger.y,
                 event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure);
         break;
diff --git a/src/video/android/SDL_androidtouch.c b/src/video/android/SDL_androidtouch.c
index 6f56f6cb3e7e..bf8d7af34105 100644
--- a/src/video/android/SDL_androidtouch.c
+++ b/src/video/android/SDL_androidtouch.c
@@ -56,12 +56,19 @@ void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_fin
         return;
     }
 
-    touchDeviceId = (SDL_TouchID)touch_device_id_in;
+    /* Touch device -1 appears when using Android emulator, eg:
+     *  adb shell input mouse tap 100 100
+     *  adb shell input touchscreen tap 100 100
+     */
+    touchDeviceId = (SDL_TouchID)(touch_device_id_in + 2);
+
+    /* Finger ID should be greater than 0 */
+    fingerId = (SDL_FingerID)(pointer_finger_id_in + 1);
+
     if (SDL_AddTouch(touchDeviceId, SDL_TOUCH_DEVICE_DIRECT, "") < 0) {
         SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
     }
 
-    fingerId = (SDL_FingerID)pointer_finger_id_in;
     switch (action) {
     case ACTION_DOWN:
     case ACTION_POINTER_DOWN:
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index 09cd91870fc9..832906369483 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -1238,7 +1238,7 @@ - (void)windowDidFailToExitFullScreen:(NSNotification *)aNotification
     if (window->is_destroying) {
         return;
     }
-    
+
     SetWindowStyle(window, flags);
 
     isFullscreenSpace = YES;
@@ -1687,7 +1687,7 @@ - (void)handleTouches:(NSTouchPhase)phase withEvent:(NSEvent *)theEvent
     float x, y;
 
     for (NSTouch *touch in touches) {
-        const SDL_TouchID touchId = istrackpad ? SDL_MOUSE_TOUCHID : (SDL_TouchID)(intptr_t)[touch device];
+        const SDL_TouchID touchId = istrackpad ? SDL_MOUSE_TOUCHID : (SDL_TouchID)(uintptr_t)[touch device];
         SDL_TouchDeviceType devtype = SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE;
 
         /* trackpad touches have no window. If we really wanted one we could
@@ -1716,7 +1716,7 @@ - (void)handleTouches:(NSTouchPhase)phase withEvent:(NSEvent *)theEvent
             return;
         }
 
-        fingerId = (SDL_FingerID)(intptr_t)[touch identity];
+        fingerId = (SDL_FingerID)(uintptr_t)[touch identity];
         x = [touch normalizedPosition].x;
         y = [touch normalizedPosition].y;
         /* Make the origin the upper left instead of the lower left */
diff --git a/src/video/emscripten/SDL_emscriptenevents.c b/src/video/emscripten/SDL_emscriptenevents.c
index 271e870a7be6..a2f225850e94 100644
--- a/src/video/emscripten/SDL_emscriptenevents.c
+++ b/src/video/emscripten/SDL_emscriptenevents.c
@@ -743,7 +743,7 @@ static EM_BOOL Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent
     double client_w, client_h;
     int preventDefault = 0;
 
-    SDL_TouchID deviceId = 1;
+    const SDL_TouchID deviceId = 1;
     if (SDL_AddTouch(deviceId, SDL_TOUCH_DEVICE_DIRECT, "") < 0) {
         return 0;
     }
diff --git a/src/video/n3ds/SDL_n3dstouch.c b/src/video/n3ds/SDL_n3dstouch.c
index 96ef93bbf861..9d3b94596ab9 100644
--- a/src/video/n3ds/SDL_n3dstouch.c
+++ b/src/video/n3ds/SDL_n3dstouch.c
@@ -28,7 +28,8 @@
 #include "../../events/SDL_touch_c.h"
 #include "SDL_n3dstouch.h"
 
-#define N3DS_TOUCH_ID 0
+#define N3DS_TOUCH_ID 1
+#define N3DS_TOUCH_FINGER 1
 
 /*
   Factors used to convert touchscreen coordinates to
@@ -59,16 +60,14 @@ void N3DS_PollTouch(void)
 
     if (pressed != was_pressed) {
         was_pressed = pressed;
-        SDL_SendTouch(0, N3DS_TOUCH_ID,
-                      0,
+        SDL_SendTouch(0, N3DS_TOUCH_ID, N3DS_TOUCH_FINGER,
                       NULL,
                       pressed,
                       touch.px * TOUCHSCREEN_SCALE_X,
                       touch.py * TOUCHSCREEN_SCALE_Y,
                       pressed ? 1.0f : 0.0f);
     } else if (pressed) {
-        SDL_SendTouchMotion(0, N3DS_TOUCH_ID,
-                            0,
+        SDL_SendTouchMotion(0, N3DS_TOUCH_ID, N3DS_TOUCH_FINGER,
                             NULL,
                             touch.px * TOUCHSCREEN_SCALE_X,
                             touch.py * TOUCHSCREEN_SCALE_Y,
diff --git a/src/video/uikit/SDL_uikitview.m b/src/video/uikit/SDL_uikitview.m
index b159cca0e080..f24f0318c5b1 100644
--- a/src/video/uikit/SDL_uikitview.m
+++ b/src/video/uikit/SDL_uikitview.m
@@ -271,7 +271,7 @@ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 
             CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
             SDL_SendTouch(UIKit_GetEventTimestamp([event timestamp]),
-                          touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
+                          touchId, (SDL_FingerID)(uintptr_t)touch, sdlwindow,
                           SDL_TRUE, locationInView.x, locationInView.y, pressure);
         }
     }
@@ -327,7 +327,7 @@ - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
 
             CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
             SDL_SendTouch(UIKit_GetEventTimestamp([event timestamp]),
-                          touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
+                          touchId, (SDL_FingerID)(uintptr_t)touch, sdlwindow,
                           SDL_FALSE, locationInView.x, locationInView.y, pressure);
         }
     }
@@ -362,7 +362,7 @@ - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
 
             CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
             SDL_SendTouchMotion(UIKit_GetEventTimestamp([event timestamp]),
-                                touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
+                                touchId, (SDL_FingerID)(uintptr_t)touch, sdlwindow,
                                 locationInView.x, locationInView.y, pressure);
         }
     }
diff --git a/src/video/vita/SDL_vitatouch.c b/src/video/vita/SDL_vitatouch.c
index ae13c6d4940b..8106fd04d615 100644
--- a/src/video/vita/SDL_vitatouch.c
+++ b/src/video/vita/SDL_vitatouch.c
@@ -68,8 +68,8 @@ void VITA_InitTouch(void)
     }
 
     // Support passing both front and back touch devices in events
-    SDL_AddTouch((SDL_TouchID)0, SDL_TOUCH_DEVICE_DIRECT, "Front");
-    SDL_AddTouch((SDL_TouchID)1, SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE, "Back");
+    SDL_AddTouch(1, SDL_TOUCH_DEVICE_DIRECT, "Front");
+    SDL_AddTouch(2, SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE, "Back");
 }
 
 void VITA_QuitTouch(void)
@@ -80,7 +80,8 @@ void VITA_QuitTouch(void)
 
 void VITA_PollTouch(void)
 {
-    SDL_FingerID finger_id = 0;
+    SDL_TouchID touch_id;
+    SDL_FingerID finger_id;
     int port;
 
     // We skip polling touch if no window is created
@@ -96,6 +97,9 @@ void VITA_PollTouch(void)
             continue;
         }
         sceTouchPeek(port, &touch[port], 1);
+
+        touch_id = (SDL_TouchID)(port + 1);
+
         if (touch[port].reportNum > 0) {
             for (int i = 0; i < touch[port].reportNum; i++) {
                 // adjust coordinates and forces to return normalized values
@@ -116,27 +120,16 @@ void VITA_PollTouch(void)
                 }
 
                 VITA_ConvertTouchXYToSDLXY(&x, &y, touch[port].report[i].x, touch[port].report[i].y, port);
-                finger_id = (SDL_FingerID)touch[port].report[i].id;
+                finger_id = (SDL_FingerID)(touch[port].report[i].id + 1);
 
                 // Skip if finger was already previously down
                 if (!finger_down) {
                     // Send an initial touch
-                    SDL_SendTouch(0, (SDL_TouchID)port,
-                                  finger_id,
-                                  Vita_Window,
-                                  SDL_TRUE,
-                                  x,
-                                  y,
-                                  force);
+                    SDL_SendTouch(0, touch_id, finger_id, Vita_Window, SDL_TRUE, x, y, force);
                 }
 
                 // Always send the motion
-                SDL_SendTouchMotion(0, (SDL_TouchID)port,
-                                    finger_id,
-                                    Vita_Window,
-                                    x,
-                                    y,
-                                    force);
+                SDL_SendTouchMotion(0, touch_id, finger_id, Vita_Window, x, y, force);
             }
         }
 
@@ -156,15 +149,9 @@ void VITA_PollTouch(void)
                     float y = 0;
                     float force = (touch_old[port].report[i].force - force_info[port].min) / force_info[port].range;
                     VITA_ConvertTouchXYToSDLXY(&x, &y, touch_old[port].report[i].x, touch_old[port].report[i].y, port);
-                    finger_id = (SDL_FingerID)touch_old[port].report[i].id;
+                    finger_id = (SDL_FingerID)(touch_old[port].report[i].id + 1);
                     // Finger released from screen
-                    SDL_SendTouch(0, (SDL_TouchID)port,
-                                  finger_id,
-                                  Vita_Window,
-                                  SDL_FALSE,
-                                  x,
-                                  y,
-                                  force);
+                    SDL_SendTouch(0, touch_id, finger_id, Vita_Window, SDL_FALSE, x, y, force);
                 }
             }
         }
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index 42297290e916..3d85a5e2820b 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -999,8 +999,8 @@ static void touch_handler_down(void *data, struct wl_touch *touch, uint32_t seri
 
         SDL_SetMouseFocus(window_data->sdlwindow);
 
-        SDL_SendTouch(Wayland_GetTouchTimestamp(input, timestamp), (SDL_TouchID)(intptr_t)touch,
-                      (SDL_FingerID)id, window_data->sdlwindow, SDL_TRUE, x, y, 1.0f);
+        SDL_SendTouch(Wayland_GetTouchTimestamp(input, timestamp), (SDL_TouchID)(uintptr_t)touch,
+                      (SDL_FingerID)(id + 1), window_data->sdlwindow, SDL_TRUE, x, y, 1.0f);
     }
 }
 
@@ -1020,8 +1020,8 @@ static void touch_handler_up(void *data, struct wl_touch *touch, uint32_t serial
             const float x = wl_fixed_to_double(fx) / window_data->wl_window_width;
             const float y = wl_fixed_to_double(fy) / window_data->wl_window_height;
 
-            SDL_SendTouch(Wayland_GetTouchTimestamp(input, timestamp), (SDL_TouchID)(intptr_t)touch,
-                          (SDL_FingerID)id, window_data->sdlwindow, SDL_FALSE, x, y, 0.0f);
+            SDL_SendTouch(Wayland_GetTouchTimestamp(input, timestamp), (SDL_TouchID)(uintptr_t)touch,
+                          (SDL_FingerID)(id + 1), window_data->sdlwindow, SDL_FALSE, x, y, 0.0f);
 
             /* If the seat lacks pointer focus, the seat's keyboard focus is another window or NULL, this window curently
              * has mouse focus, and the surface has no active touch events, consider mouse focus to be lost.
@@ -1049,8 +1049,8 @@ static void touch_handler_motion(void *data, struct wl_touch *touch, uint32_t ti
             const float x = wl_fixed_to_double(fx) / window_data->wl_window_width;
             const float y = wl_fixed_to_double(fy) / window_data->wl_window_height;
 
-            SDL_SendTouchMotion(Wayland_GetPointerTimestamp(input, timestamp), (SDL_TouchID)(intptr_t)touch,
-                                (SDL_FingerID)id, window_data->sdlwindow, x, y, 1.0f);
+            SDL_SendTouchMotion(Wayland_GetPointerTimestamp(input, timestamp), (SDL_TouchID)(uintptr_t)touch,
+                                (SDL_FingerID)(id + 1), window_data->sdlwindow, x, y, 1.0f);
         }
     }
 }
@@ -1687,7 +1687,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *seat,
 
     if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) {
         input->touch = wl_seat_get_touch(seat);
-        SDL_AddTouch((SDL_TouchID)(intptr_t)input->touch, SDL_TOUCH_DEVICE_DIRECT, "wayland_touch");
+        SDL_AddTouch((SDL_TouchID)(uintptr_t)input->touch, SDL_TOUCH_DEVICE_DIRECT, "wayland_touch");
         wl_touch_set_user_data(input->touch, input);
         wl_touch_add_listener(input->touch, &touch_listener,
                               input);
diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index 179a7ad6db2b..19588af036d5 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -1325,7 +1325,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                     const int w = (rect.right - rect.left);
                     const int h = (rect.bottom - rect.top);
 
-                    const SDL_TouchID touchId = (SDL_TouchID)((size_t)input->hSource);
+                    const SDL_TouchID touchId = (SDL_TouchID)((uintptr_t)input->hSource);
+                    const SDL_FingerID fingerId = (input->dwID + 1);
 
                     /* TODO: Can we use GetRawInputDeviceInfo and HID info to
                        determine if this is a direct or indirect touch device?
@@ -1348,13 +1349,13 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
                     /* FIXME: Should we use the input->dwTime field for the tick source of the timestamp? */
                     if (input->dwFlags & TOUCHEVENTF_DOWN) {
-                        SDL_SendTouch(WIN_GetEventTimestamp(), touchId, input->dwID, data->window, SDL_TRUE, x, y, 1.0f);
+                        SDL_SendTouch(WIN_GetEventTimestamp(), touchId, fingerId, data->window, SDL_TRUE, x, y, 1.0f);
                     }
                     if (input->dwFlags & TOUCHEVENTF_MOVE) {
-                        SDL_SendTouchMotion(WIN_GetEventTimestamp(), touchId, input->dwID, data->window, x, y, 1.0f);
+                        SDL_SendTouchMotion(WIN_GetEventTimestamp(), touchId, fingerId, data->window, x, y, 1.0f);
                     }
                     if (input->dwFlags & TOUCHEVENTF_UP) {
-                        SDL_SendTouch(WIN_GetEventTimestamp(), touchId, input->dwID, data->window, SDL_FALSE, x, y, 1.0f);
+                        SDL_SendTouch(WIN_GetEventTimestamp(), touchId, fingerId, data->window, SDL_FALSE, x, y, 1.0f);
                     }
                 }
             }
diff --git a/src/video/winrt/SDL_winrtpointerinput.cpp b/src/video/winrt/SDL_winrtpointerinput.cpp
index 47dd3c255006..cca8ec01706c 100644
--- a/src/video/winrt/SDL_winrtpointerinput.cpp
+++ b/src/video/winrt/SDL_winrtpointerinput.cpp
@@ -227,7 +227,7 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po
 
         SDL_SendTouch(0,
             WINRT_TouchID,
-            (SDL_FingerID)pointerPoint->PointerId,
+            (SDL_FingerID)(pointerPoint->PointerId + 1),
             window,
             SDL_TRUE,
             normalizedPoint.X,
@@ -256,7 +256,7 @@ void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::Poin
     } else {
         SDL_SendTouchMotion(0,
             WINRT_TouchID,
-            (SDL_FingerID)pointerPoint->PointerId,
+            (SDL_FingerID)(pointerPoint->PointerId + 1),
             window,
             normalizedPoint.X,
             normalizedPoint.Y,
@@ -280,7 +280,7 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::P
 
         SDL_SendTouch(0,
             WINRT_TouchID,
-            (SDL_FingerID)pointerPoint->PointerId,
+            (SDL_FingerID)(pointerPoint->PointerId + 1),
             window,
             SDL_FALSE,
             normalizedPoint.X,
diff --git a/test/testpen.c b/test/testpen.c
index c0db56056eb2..434b929ddf25 100644
--- a/test/testpen.c
+++ b/test/testpen.c
@@ -468,7 +468,7 @@ static void process_event(SDL_Event event)
         last_button = 0;
         last_touching = (ev->type != SDL_EVENT_FINGER_UP);
 #if VERBOSE
-        SDL_Log("[%lu] finger %s: %s (touchId: %" SDL_PRIs64 ", fingerId: %" SDL_PRIs64 ") at (%.4f, %.4f); pressure=%.3f\n",
+        SDL_Log("[%lu] finger %s: %s (touchId: %" SDL_PRIu64 ", fingerId: %" SDL_PRIu64 ") at (%.4f, %.4f); pressure=%.3f\n",
                 (unsigned long) ev->timestamp,
                 ev->type == SDL_EVENT_FINGER_DOWN ? "down" : (ev->type == SDL_EVENT_FINGER_MOTION ? "motion" : "up"),
                 SDL_GetTouchDeviceName(ev->touchId),