SDL: Include the child serial numbers in the serial number for a HIDAPI combined device

From d90c0d41ccee22ad5b2ad658c0513136b52ebe4c Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Tue, 9 Aug 2022 09:00:29 -0700
Subject: [PATCH] Include the child serial numbers in the serial number for a
 HIDAPI combined device

---
 src/joystick/hidapi/SDL_hidapi_combined.c | 31 ++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/src/joystick/hidapi/SDL_hidapi_combined.c b/src/joystick/hidapi/SDL_hidapi_combined.c
index a0ed2fe5204..6ccbcbf482b 100644
--- a/src/joystick/hidapi/SDL_hidapi_combined.c
+++ b/src/joystick/hidapi/SDL_hidapi_combined.c
@@ -27,7 +27,7 @@
 #include "SDL_joystick.h"
 #include "SDL_gamecontroller.h"
 #include "SDL_hidapijoystick_c.h"
-
+#include "../SDL_sysjoystick.h"
 
 static SDL_bool
 HIDAPI_DriverCombined_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
@@ -63,6 +63,8 @@ static SDL_bool
 HIDAPI_DriverCombined_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
 {
     int i;
+    char *serial = NULL, *new_serial;
+    size_t serial_length = 0, new_length;
 
     for (i = 0; i < device->num_children; ++i) {
         SDL_HIDAPI_Device *child = device->children[i];
@@ -71,9 +73,36 @@ HIDAPI_DriverCombined_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys
                 child = device->children[i];
                 child->driver->CloseJoystick(child, joystick);
             }
+            if (serial) {
+                SDL_free(serial);
+            }
             return SDL_FALSE;
         }
+
+        /* Extend the serial number with the child serial number */
+        if (joystick->serial) {
+            new_length = serial_length + 1 + SDL_strlen(joystick->serial);
+            new_serial = (char *)SDL_realloc(serial, new_length);
+            if (new_serial) {
+                if (serial) {
+                    SDL_strlcat(new_serial, ",", new_length);
+                    SDL_strlcat(new_serial, joystick->serial, new_length);
+                } else {
+                    SDL_strlcpy(new_serial, joystick->serial, new_length);
+                }
+                SDL_free(serial);
+                serial = new_serial;
+                serial_length = new_length;
+            }
+        }
+    }
+
+    /* Update the joystick with the combined serial numbers */
+    if (joystick->serial) {
+        SDL_free(joystick->serial);
     }
+    joystick->serial = serial;
+
     return SDL_TRUE;
 }