summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2013-10-25 12:49:25 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-28 20:00:34 +0100
commit36321b9aaeedef1232d464d3dd7d03f39b7f7f37 (patch)
tree0d531d8c8f76c815f5083d038b474ad0ae8ed884 /Source/WebCore/platform
parent42f59b187d5a5d75b3fccdc26358777b0e6a08fc (diff)
Load libudev at run-time
Changes the usage of libudev from linking at compile time to loading at runtime. Task-number: QTBUG-34176 Change-Id: I7feb91ed3ee1c21dbb3ab508cb7ad6d69c73cc01 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'Source/WebCore/platform')
-rw-r--r--Source/WebCore/platform/qt/GamepadsQt.cpp123
1 files changed, 116 insertions, 7 deletions
diff --git a/Source/WebCore/platform/qt/GamepadsQt.cpp b/Source/WebCore/platform/qt/GamepadsQt.cpp
index dc4f16a7a..60ff317cb 100644
--- a/Source/WebCore/platform/qt/GamepadsQt.cpp
+++ b/Source/WebCore/platform/qt/GamepadsQt.cpp
@@ -30,19 +30,23 @@
#include "GamepadDeviceLinux.h"
#include "GamepadList.h"
+#include <QLibrary>
#include <QObject>
#include <QSocketNotifier>
-extern "C" {
-#include <libudev.h>
-}
-
#include <unistd.h>
#include <wtf/HashMap.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringHash.h>
+// Forward declarations for libudev, they are all used opaque so we don't need the definitions.
+struct udev;
+struct udev_device;
+struct udev_monitor;
+struct udev_enumerate;
+struct udev_list_entry;
+
namespace WebCore {
class GamepadDeviceLinuxQt : public QObject, public GamepadDeviceLinux {
@@ -87,7 +91,107 @@ bool GamepadDeviceLinuxQt::readCallback()
return true;
}
-class GamepadsQt : public QObject {
+class LibUdevWrapper {
+public:
+ LibUdevWrapper() : m_loaded(false)
+ {
+ load();
+ }
+
+ virtual ~LibUdevWrapper()
+ {
+ m_libUdev.unload();
+ }
+
+ bool isLoaded() const { return m_loaded; }
+
+private:
+ QLibrary m_libUdev;
+ bool m_loaded;
+ bool load()
+ {
+ m_libUdev.setLoadHints(QLibrary::ResolveAllSymbolsHint);
+ m_libUdev.setFileNameAndVersion(QStringLiteral("udev"), 1);
+ m_loaded = m_libUdev.load();
+ if (resolveMethods())
+ return true;
+
+ m_libUdev.setFileNameAndVersion(QStringLiteral("udev"), 0);
+ m_loaded = m_libUdev.load();
+ return resolveMethods();
+ }
+
+ QFunctionPointer resolve(const char* name)
+ {
+ QFunctionPointer ptr = m_libUdev.resolve(name);
+ if (!ptr) {
+ qWarning("libudev could not resolve expected symbol %s", name);
+ m_loaded = false;
+ }
+ return ptr;
+ }
+
+ bool resolveMethods()
+ {
+ if (!m_loaded)
+ return false;
+ udev_new = (udev* (*)())resolve("udev_new");
+ udev_unref = (void (*)(udev*))resolve("udev_unref");
+ udev_monitor_new_from_netlink = (udev_monitor* (*)(udev*, const char*))resolve("udev_monitor_new_from_netlink");
+ udev_monitor_unref = (void (*)(udev_monitor*))resolve("udev_monitor_unref");
+ udev_monitor_enable_receiving = (int (*)(udev_monitor*))resolve("udev_monitor_enable_receiving");
+ udev_monitor_get_fd = (int (*)(udev_monitor*))resolve("udev_monitor_get_fd");
+ udev_monitor_filter_add_match_subsystem_devtype = (int (*)(udev_monitor*, const char*, const char*))resolve("udev_monitor_filter_add_match_subsystem_devtype");
+ udev_monitor_receive_device = (udev_device* (*)(udev_monitor*))resolve("udev_monitor_receive_device");
+ udev_enumerate_new = (udev_enumerate* (*)(udev*))resolve("udev_enumerate_new");
+ udev_enumerate_unref = (void (*)(udev_enumerate*))resolve("udev_enumerate_unref");
+ udev_enumerate_add_match_subsystem = (int (*)(udev_enumerate*, const char*))resolve("udev_enumerate_add_match_subsystem");
+ udev_enumerate_add_match_property = (int (*)(udev_enumerate*, const char*, const char*))resolve("udev_enumerate_add_match_property");
+ udev_enumerate_scan_devices = (int (*)(udev_enumerate*))resolve("udev_enumerate_scan_devices");
+ udev_enumerate_get_list_entry = (udev_list_entry* (*)(udev_enumerate*))resolve("udev_enumerate_get_list_entry");
+ udev_list_entry_get_next = (udev_list_entry* (*)(udev_list_entry*))resolve("udev_list_entry_get_next");
+ udev_list_entry_get_name = (const char* (*)(udev_list_entry*))resolve("udev_list_entry_get_name");
+ udev_device_new_from_syspath = (udev_device* (*)(udev*, const char*))resolve("udev_device_new_from_syspath");
+ udev_device_unref = (void (*)(udev_device*))resolve("udev_device_unref");
+ udev_device_get_syspath = (const char* (*)(udev_device*))resolve("udev_device_get_syspath");
+ udev_device_get_devnode = (const char* (*)(udev_device*))resolve("udev_device_get_devnode");
+ udev_device_get_property_value = (const char* (*)(udev_device*, const char*))resolve("udev_device_get_property_value");
+ udev_device_get_action = (const char* (*)(udev_device*))resolve("udev_device_get_action");
+
+ return m_loaded;
+ }
+
+public:
+ struct udev* (*udev_new)();
+ void (*udev_unref)(struct udev*);
+
+ struct udev_monitor* (*udev_monitor_new_from_netlink)(struct udev*, const char *name);
+ void (*udev_monitor_unref)(struct udev_monitor*);
+ int (*udev_monitor_enable_receiving)(struct udev_monitor*);
+ int (*udev_monitor_get_fd)(struct udev_monitor*);
+ int (*udev_monitor_filter_add_match_subsystem_devtype)(struct udev_monitor*, const char *subsystem, const char *devtype);
+ struct udev_device* (*udev_monitor_receive_device)(struct udev_monitor*);
+
+ struct udev_enumerate* (*udev_enumerate_new)(struct udev*);
+ void (*udev_enumerate_unref)(struct udev_enumerate*);
+ int (*udev_enumerate_add_match_subsystem)(struct udev_enumerate*, const char *subsystem);
+ int (*udev_enumerate_add_match_property)(struct udev_enumerate*, const char *property, const char *value);
+ int (*udev_enumerate_scan_devices)(struct udev_enumerate*);
+ struct udev_list_entry* (*udev_enumerate_get_list_entry)(struct udev_enumerate*);
+
+ struct udev_list_entry* (*udev_list_entry_get_next)(struct udev_list_entry*);
+ const char* (*udev_list_entry_get_name)(struct udev_list_entry*);
+
+ struct udev_device* (*udev_device_new_from_syspath)(struct udev *udev, const char *syspath);
+ void (*udev_device_unref)(struct udev_device *udev_device);
+ const char* (*udev_device_get_syspath)(struct udev_device *udev_device);
+ const char* (*udev_device_get_devnode)(struct udev_device *udev_device);
+ const char* (*udev_device_get_property_value)(struct udev_device *udev_device, const char *key);
+ const char* (*udev_device_get_action)(struct udev_device *udev_device);
+};
+
+
+class GamepadsQt : public QObject, protected LibUdevWrapper {
Q_OBJECT
public:
GamepadsQt(unsigned);
@@ -114,8 +218,12 @@ private:
GamepadsQt::GamepadsQt(unsigned length)
: QObject()
+ , LibUdevWrapper()
, m_slots(length)
{
+ if (!LibUdevWrapper::isLoaded())
+ return;
+
m_udev = udev_new();
m_gamepadsMonitor = udev_monitor_new_from_netlink(m_udev, "udev");
udev_monitor_enable_receiving(m_gamepadsMonitor);
@@ -129,8 +237,7 @@ GamepadsQt::GamepadsQt(unsigned length)
udev_enumerate_scan_devices(enumerate);
struct udev_list_entry* cur;
struct udev_list_entry* devs = udev_enumerate_get_list_entry(enumerate);
- udev_list_entry_foreach(cur, devs)
- {
+ for (cur = devs; cur != NULL; cur = udev_list_entry_get_next(cur)) {
const char* devname = udev_list_entry_get_name(cur);
struct udev_device* device = udev_device_new_from_syspath(m_udev, devname);
if (isGamepadDevice(device))
@@ -142,6 +249,8 @@ GamepadsQt::GamepadsQt(unsigned length)
GamepadsQt::~GamepadsQt()
{
+ if (!LibUdevWrapper::isLoaded())
+ return;
udev_unref(m_udev);
udev_monitor_unref(m_gamepadsMonitor);
}