ソースを参照

FIX SDL_GetJoystickSerial() always returning NULL on Linux (UDEV) (#14454)

pmx 1 ヶ月 前
コミット
54f129f765

+ 37 - 0
src/core/linux/SDL_udev.c

@@ -302,6 +302,43 @@ bool SDL_UDEV_GetProductInfo(const char *device_path, struct input_id *inpid, in
     return true;
     return true;
 }
 }
 
 
+bool SDL_UDEV_GetProductSerial(const char *device_path, const char **serial)
+{
+    struct stat statbuf;
+    char type;
+    struct udev_device *dev;
+    const char *val;
+
+    if (!_this) {
+        return false;
+    }
+
+    if (stat(device_path, &statbuf) < 0) {
+        return false;
+    }
+
+    if (S_ISBLK(statbuf.st_mode)) {
+        type = 'b';
+    } else if (S_ISCHR(statbuf.st_mode)) {
+        type = 'c';
+    } else {
+        return false;
+    }
+
+    dev = _this->syms.udev_device_new_from_devnum(_this->udev, type, statbuf.st_rdev);
+    if (!dev) {
+        return false;
+    }
+
+    val = _this->syms.udev_device_get_property_value(dev, "ID_SERIAL_SHORT");
+    if (val) {
+        *serial = val;
+        return true;
+    }
+
+    return false;
+}
+
 void SDL_UDEV_UnloadLibrary(void)
 void SDL_UDEV_UnloadLibrary(void)
 {
 {
     if (!_this) {
     if (!_this) {

+ 1 - 0
src/core/linux/SDL_udev.h

@@ -105,6 +105,7 @@ extern bool SDL_UDEV_LoadLibrary(void);
 extern void SDL_UDEV_Poll(void);
 extern void SDL_UDEV_Poll(void);
 extern bool SDL_UDEV_Scan(void);
 extern bool SDL_UDEV_Scan(void);
 extern bool SDL_UDEV_GetProductInfo(const char *device_path, struct input_id *inpid, int *class, char **driver);
 extern bool SDL_UDEV_GetProductInfo(const char *device_path, struct input_id *inpid, int *class, char **driver);
+extern bool SDL_UDEV_GetProductSerial(const char *device_path, const char **serial);
 extern bool SDL_UDEV_AddCallback(SDL_UDEV_Callback cb);
 extern bool SDL_UDEV_AddCallback(SDL_UDEV_Callback cb);
 extern void SDL_UDEV_DelCallback(SDL_UDEV_Callback cb);
 extern void SDL_UDEV_DelCallback(SDL_UDEV_Callback cb);
 extern const SDL_UDEV_Symbols *SDL_UDEV_GetUdevSyms(void);
 extern const SDL_UDEV_Symbols *SDL_UDEV_GetUdevSyms(void);

+ 7 - 0
src/joystick/linux/SDL_sysjoystick.c

@@ -1608,6 +1608,13 @@ static bool LINUX_JoystickOpen(SDL_Joystick *joystick, int device_index)
         item_sensor->hwdata = joystick->hwdata;
         item_sensor->hwdata = joystick->hwdata;
     }
     }
 
 
+#ifdef SDL_USE_LIBUDEV
+    const char *serial = NULL;
+    if (SDL_UDEV_GetProductSerial(item->path, &serial)) {
+        joystick->serial = SDL_strdup(serial);
+    }
+#endif
+
     // mark joystick as fresh and ready
     // mark joystick as fresh and ready
     joystick->hwdata->fresh = true;
     joystick->hwdata->fresh = true;