[Commits] SDL: Fixed bug 4267 - linkage failure with --enable-hidapi becau...

libsdl.org revision control commits-owner at libsdl.org
Mon Sep 24 16:33:21 PDT 2018


details:   https://hg.libsdl.org/SDL/rev/b527a6a49bfd
changeset: 12203:b527a6a49bfd
user:      Sam Lantinga <slouken at libsdl.org>
date:      Mon Sep 24 16:33:14 2018 -0700
description:
Fixed bug 4267 - linkage failure with --enable-hidapi because of missing libudev symbols

Ozkan Sezer

hidapi dynamic udev initial patch

diffstat:

 src/core/linux/SDL_udev.c                |  80 +++++++++++++++++++------------
 src/core/linux/SDL_udev.h                |  28 ++++++----
 src/joystick/hidapi/SDL_hidapijoystick.c |  27 +++++++---
 3 files changed, 83 insertions(+), 52 deletions(-)

diffs (333 lines):

diff -r 453f55c56b16 -r b527a6a49bfd src/core/linux/SDL_udev.c
--- a/src/core/linux/SDL_udev.c	Mon Sep 24 11:53:04 2018 -0700
+++ b/src/core/linux/SDL_udev.c	Mon Sep 24 16:33:14 2018 -0700
@@ -63,7 +63,7 @@
 {
     /* cast funcs to char* first, to please GCC's strict aliasing rules. */
     #define SDL_UDEV_SYM(x) \
-        if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->x)) return -1
+        if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->syms.x)) return -1
 
     SDL_UDEV_SYM(udev_device_get_action);
     SDL_UDEV_SYM(udev_device_get_devnode);
@@ -100,7 +100,7 @@
 SDL_UDEV_hotplug_update_available(void)
 {
     if (_this->udev_mon != NULL) {
-        const int fd = _this->udev_monitor_get_fd(_this->udev_mon);
+        const int fd = _this->syms.udev_monitor_get_fd(_this->udev_mon);
         if (SDL_IOReady(fd, SDL_FALSE, 0)) {
             return SDL_TRUE;
         }
@@ -130,21 +130,21 @@
          * Listen for input devices (mouse, keyboard, joystick, etc) and sound devices
          */
         
-        _this->udev = _this->udev_new();
+        _this->udev = _this->syms.udev_new();
         if (_this->udev == NULL) {
             SDL_UDEV_Quit();
             return SDL_SetError("udev_new() failed");
         }
 
-        _this->udev_mon = _this->udev_monitor_new_from_netlink(_this->udev, "udev");
+        _this->udev_mon = _this->syms.udev_monitor_new_from_netlink(_this->udev, "udev");
         if (_this->udev_mon == NULL) {
             SDL_UDEV_Quit();
             return SDL_SetError("udev_monitor_new_from_netlink() failed");
         }
         
-        _this->udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL);
-        _this->udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL);
-        _this->udev_monitor_enable_receiving(_this->udev_mon);
+        _this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL);
+        _this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL);
+        _this->syms.udev_monitor_enable_receiving(_this->udev_mon);
         
         /* Do an initial scan of existing devices */
         SDL_UDEV_Scan();
@@ -170,11 +170,11 @@
     if (_this->ref_count < 1) {
         
         if (_this->udev_mon != NULL) {
-            _this->udev_monitor_unref(_this->udev_mon);
+            _this->syms.udev_monitor_unref(_this->udev_mon);
             _this->udev_mon = NULL;
         }
         if (_this->udev != NULL) {
-            _this->udev_unref(_this->udev);
+            _this->syms.udev_unref(_this->udev);
             _this->udev = NULL;
         }
         
@@ -202,28 +202,28 @@
         return;
     }
    
-    enumerate = _this->udev_enumerate_new(_this->udev);
+    enumerate = _this->syms.udev_enumerate_new(_this->udev);
     if (enumerate == NULL) {
         SDL_UDEV_Quit();
         SDL_SetError("udev_enumerate_new() failed");
         return;
     }
     
-    _this->udev_enumerate_add_match_subsystem(enumerate, "input");
-    _this->udev_enumerate_add_match_subsystem(enumerate, "sound");
+    _this->syms.udev_enumerate_add_match_subsystem(enumerate, "input");
+    _this->syms.udev_enumerate_add_match_subsystem(enumerate, "sound");
     
-    _this->udev_enumerate_scan_devices(enumerate);
-    devs = _this->udev_enumerate_get_list_entry(enumerate);
-    for (item = devs; item; item = _this->udev_list_entry_get_next(item)) {
-        const char *path = _this->udev_list_entry_get_name(item);
-        struct udev_device *dev = _this->udev_device_new_from_syspath(_this->udev, path);
+    _this->syms.udev_enumerate_scan_devices(enumerate);
+    devs = _this->syms.udev_enumerate_get_list_entry(enumerate);
+    for (item = devs; item; item = _this->syms.udev_list_entry_get_next(item)) {
+        const char *path = _this->syms.udev_list_entry_get_name(item);
+        struct udev_device *dev = _this->syms.udev_device_new_from_syspath(_this->udev, path);
         if (dev != NULL) {
             device_event(SDL_UDEV_DEVICEADDED, dev);
-            _this->udev_device_unref(dev);
+            _this->syms.udev_device_unref(dev);
         }
     }
 
-    _this->udev_enumerate_unref(enumerate);
+    _this->syms.udev_enumerate_unref(enumerate);
 }
 
 
@@ -305,7 +305,7 @@
     unsigned long v;
 
     SDL_memset(bitmask, 0, bitmask_len*sizeof(*bitmask));
-    value = _this->udev_device_get_sysattr_value(pdev, attr);
+    value = _this->syms.udev_device_get_sysattr_value(pdev, attr);
     if (!value) {
         return;
     }
@@ -340,8 +340,8 @@
     /* walk up the parental chain until we find the real input device; the
      * argument is very likely a subdevice of this, like eventN */
     pdev = dev;
-    while (pdev && !_this->udev_device_get_sysattr_value(pdev, "capabilities/ev")) {
-        pdev = _this->udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL);
+    while (pdev && !_this->syms.udev_device_get_sysattr_value(pdev, "capabilities/ev")) {
+        pdev = _this->syms.udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL);
     }
     if (!pdev) {
         return 0;
@@ -405,28 +405,28 @@
     const char *path;
     SDL_UDEV_CallbackList *item;
     
-    path = _this->udev_device_get_devnode(dev);
+    path = _this->syms.udev_device_get_devnode(dev);
     if (path == NULL) {
         return;
     }
     
-    subsystem = _this->udev_device_get_subsystem(dev);
+    subsystem = _this->syms.udev_device_get_subsystem(dev);
     if (SDL_strcmp(subsystem, "sound") == 0) {
         devclass = SDL_UDEV_DEVICE_SOUND;
     } else if (SDL_strcmp(subsystem, "input") == 0) {
         /* udev rules reference: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c */
         
-        val = _this->udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK");
+        val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK");
         if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
             devclass |= SDL_UDEV_DEVICE_JOYSTICK;
         }
         
-        val = _this->udev_device_get_property_value(dev, "ID_INPUT_MOUSE");
+        val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_MOUSE");
         if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
             devclass |= SDL_UDEV_DEVICE_MOUSE;
         }
         
-        val = _this->udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN");
+        val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN");
         if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
             devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN;
         }
@@ -437,14 +437,14 @@
            
            Ref: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c#n183
         */
-        val = _this->udev_device_get_property_value(dev, "ID_INPUT_KEY");
+        val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_KEY");
         if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
             devclass |= SDL_UDEV_DEVICE_KEYBOARD;
         }
 
         if (devclass == 0) {
             /* Fall back to old style input classes */
-            val = _this->udev_device_get_property_value(dev, "ID_CLASS");
+            val = _this->syms.udev_device_get_property_value(dev, "ID_CLASS");
             if (val != NULL) {
                 if (SDL_strcmp(val, "joystick") == 0) {
                     devclass = SDL_UDEV_DEVICE_JOYSTICK;
@@ -481,11 +481,11 @@
     }
 
     while (SDL_UDEV_hotplug_update_available()) {
-        dev = _this->udev_monitor_receive_device(_this->udev_mon);
+        dev = _this->syms.udev_monitor_receive_device(_this->udev_mon);
         if (dev == NULL) {
             break;
         }
-        action = _this->udev_device_get_action(dev);
+        action = _this->syms.udev_device_get_action(dev);
 
         if (SDL_strcmp(action, "add") == 0) {
             /* Wait for the device to finish initialization */
@@ -496,7 +496,7 @@
             device_event(SDL_UDEV_DEVICEREMOVED, dev);
         }
         
-        _this->udev_device_unref(dev);
+        _this->syms.udev_device_unref(dev);
     }
 }
 
@@ -547,6 +547,22 @@
     
 }
 
+const SDL_UDEV_Symbols *
+SDL_UDEV_GetUdevSyms(void)
+{
+    if (SDL_UDEV_Init() < 0) {
+        SDL_SetError("Could not initialize UDEV");
+        return NULL;
+    }
+
+    return &_this->syms;
+}
+
+void
+SDL_UDEV_ReleaseUdevSyms(void)
+{
+    SDL_UDEV_Quit();
+}
 
 #endif /* SDL_USE_LIBUDEV */
 
diff -r 453f55c56b16 -r b527a6a49bfd src/core/linux/SDL_udev.h
--- a/src/core/linux/SDL_udev.h	Mon Sep 24 11:53:04 2018 -0700
+++ b/src/core/linux/SDL_udev.h	Mon Sep 24 16:33:14 2018 -0700
@@ -64,16 +64,7 @@
     struct SDL_UDEV_CallbackList *next;
 } SDL_UDEV_CallbackList;
 
-typedef struct SDL_UDEV_PrivateData
-{
-    const char *udev_library;
-    void *udev_handle;
-    struct udev *udev;
-    struct udev_monitor *udev_mon;
-    int ref_count;
-    SDL_UDEV_CallbackList *first, *last;
-    
-    /* Function pointers */
+typedef struct SDL_UDEV_Symbols {
     const char *(*udev_device_get_action)(struct udev_device *);
     const char *(*udev_device_get_devnode)(struct udev_device *);
     const char *(*udev_device_get_subsystem)(struct udev_device *);
@@ -100,6 +91,19 @@
     void (*udev_unref)(struct udev *);
     struct udev_device * (*udev_device_new_from_devnum)(struct udev *udev, char type, dev_t devnum);
     dev_t (*udev_device_get_devnum) (struct udev_device *udev_device);
+} SDL_UDEV_Symbols;
+
+typedef struct SDL_UDEV_PrivateData
+{
+    const char *udev_library;
+    void *udev_handle;
+    struct udev *udev;
+    struct udev_monitor *udev_mon;
+    int ref_count;
+    SDL_UDEV_CallbackList *first, *last;
+    
+    /* Function pointers */
+    SDL_UDEV_Symbols syms;
 } SDL_UDEV_PrivateData;
 
 extern int SDL_UDEV_Init(void);
@@ -110,8 +114,8 @@
 extern void SDL_UDEV_Scan(void);
 extern int SDL_UDEV_AddCallback(SDL_UDEV_Callback cb);
 extern void SDL_UDEV_DelCallback(SDL_UDEV_Callback cb);
-
-
+extern const SDL_UDEV_Symbols *SDL_UDEV_GetUdevSyms(void);
+extern void SDL_UDEV_ReleaseUdevSyms(void);
 
 
 #endif /* HAVE_LIBUDEV_H */
diff -r 453f55c56b16 -r b527a6a49bfd src/joystick/hidapi/SDL_hidapijoystick.c
--- a/src/joystick/hidapi/SDL_hidapijoystick.c	Mon Sep 24 11:53:04 2018 -0700
+++ b/src/joystick/hidapi/SDL_hidapijoystick.c	Mon Sep 24 16:33:14 2018 -0700
@@ -97,6 +97,10 @@
 static SDL_HIDAPI_Device *SDL_HIDAPI_devices;
 static int SDL_HIDAPI_numjoysticks = 0;
 
+#if defined(SDL_USE_LIBUDEV)
+static const SDL_UDEV_Symbols * usyms = NULL;
+#endif
+
 static struct
 {
     SDL_bool m_bHaveDevicesChanged;
@@ -272,12 +276,15 @@
     SDL_HIDAPI_discovery.m_pUdevMonitor = NULL;
     SDL_HIDAPI_discovery.m_nUdevFd = -1;
 
-    SDL_HIDAPI_discovery.m_pUdev = udev_new();
+    usyms = SDL_UDEV_GetUdevSyms();
+    if (usyms) {
+        SDL_HIDAPI_discovery.m_pUdev = usyms->udev_new();
+    }
     if (SDL_HIDAPI_discovery.m_pUdev) {
-        SDL_HIDAPI_discovery.m_pUdevMonitor = udev_monitor_new_from_netlink(SDL_HIDAPI_discovery.m_pUdev, "udev");
+        SDL_HIDAPI_discovery.m_pUdevMonitor = usyms->udev_monitor_new_from_netlink(SDL_HIDAPI_discovery.m_pUdev, "udev");
         if (SDL_HIDAPI_discovery.m_pUdevMonitor) {
-            udev_monitor_enable_receiving(SDL_HIDAPI_discovery.m_pUdevMonitor);
-            SDL_HIDAPI_discovery.m_nUdevFd = udev_monitor_get_fd(SDL_HIDAPI_discovery.m_pUdevMonitor);
+            usyms->udev_monitor_enable_receiving(SDL_HIDAPI_discovery.m_pUdevMonitor);
+            SDL_HIDAPI_discovery.m_nUdevFd = usyms->udev_monitor_get_fd(SDL_HIDAPI_discovery.m_pUdevMonitor);
             SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE;
         }
     }
@@ -339,9 +346,9 @@
 
             SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE;
 
-            pUdevDevice = udev_monitor_receive_device(SDL_HIDAPI_discovery.m_pUdevMonitor);
+            pUdevDevice = usyms->udev_monitor_receive_device(SDL_HIDAPI_discovery.m_pUdevMonitor);
             if (pUdevDevice) {
-                udev_device_unref(pUdevDevice);
+                usyms->udev_device_unref(pUdevDevice);
             }
         }
     }
@@ -370,10 +377,14 @@
 
 #if defined(SDL_USE_LIBUDEV)
     if (SDL_HIDAPI_discovery.m_pUdevMonitor) {
-        udev_monitor_unref(SDL_HIDAPI_discovery.m_pUdevMonitor);
+        usyms->udev_monitor_unref(SDL_HIDAPI_discovery.m_pUdevMonitor);
     }
     if (SDL_HIDAPI_discovery.m_pUdev) {
-        udev_unref(SDL_HIDAPI_discovery.m_pUdev);
+        usyms->udev_unref(SDL_HIDAPI_discovery.m_pUdev);
+    }
+    if (usyms) {
+        SDL_UDEV_ReleaseUdevSyms();
+        usyms = NULL;
     }
 #endif
 }


More information about the commits mailing list