From cad0fc343d17311f4b8793aaade1773c3018bc9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Panzenb=C3=B6ck?= Date: Sun, 23 Feb 2014 16:50:47 +0100 Subject: [PATCH] also use libudev for enumerating joypad devices --- README.md | 14 ++++++------ src/layout.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index aa39286..db2435e 100644 --- a/README.md +++ b/README.md @@ -686,14 +686,14 @@ Just replace these files and restart QJoyPad. ### Why do I have to tell QJoyPad to "update joystick devices"? Why can't it do that on its own? -Supporting on the fly detection of new gamepads using -[libudev](http://www.signal11.us/oss/udev/) is on the TODO list. -However, this would mean yet another dependency and then QJoyPad -won't run on distributions without UDev anymore. I don't know -if such distributions even exist, though. +If you compile with `-DWITH_LIBUDEV=ON` (the default) then UDev +is used to automatically update the joypad list. If automatically +updating of the joypad list still does not work compile with +`-DCMAKE_BUILD_TYPE=Debug` and post the output on the [GitHub +bug tracker](https://github.com/panzi/qjoypad/issues). -Currently you can let QJoyPad rescan your joypads using the menu -or by running `qjoypad --update`. +You can force QJoyPad to rescan your joypads at any time using the +menu or by running `qjoypad --update`. ### When QJoyPad checks for new joysticks, it doesn't find mine! diff --git a/src/layout.cpp b/src/layout.cpp index e2b09e6..2766b66 100644 --- a/src/layout.cpp +++ b/src/layout.cpp @@ -22,7 +22,7 @@ LayoutManager::LayoutManager( bool useTrayIcon, const QString &devdir, const QSt monitor = 0; if (!initUDev()) { - errorBox("UDev Error", "Error creating udev monitor. " + errorBox("UDev Error", "Error creating UDev monitor. " "QJoyPad will still work, but it won't automatically update the joypad device list."); } #endif @@ -91,7 +91,7 @@ bool LayoutManager::initUDev() { monitor, "input", NULL); if (errnum != 0) { debug_mesg("udev_monitor_filter_add_match_subsystem_devtype: %s\n", - strerror(errnum)); + strerror(-errnum)); udev_monitor_unref(monitor); udev_unref(udev); monitor = 0; @@ -102,7 +102,7 @@ bool LayoutManager::initUDev() { errnum = udev_monitor_enable_receiving(monitor); if (errnum != 0) { debug_mesg("udev_monitor_enable_receiving: %s\n", - strerror(errnum)); + strerror(-errnum)); udev_monitor_unref(monitor); udev_unref(udev); monitor = 0; @@ -489,10 +489,56 @@ void LayoutManager::updateJoyDevs() { //clear out the list of previously available joysticks available.clear(); + QRegExp devicename("/js(\\d+)$"); + +#ifdef WITH_LIBUDEV + // try to enumerate devices using udev, if compiled with udev support + bool udev_ok = false; + if (udev) { + struct udev_enumerate *enumerate = udev_enumerate_new(udev); + + if (enumerate) { + int errnum = udev_enumerate_add_match_subsystem(enumerate, "input"); + + if (errnum == 0) { + errnum = udev_enumerate_scan_devices(enumerate); + + if (errnum == 0) { + struct udev_list_entry *devices, *dev_list_entry; + devices = udev_enumerate_get_list_entry(enumerate); + + udev_list_entry_foreach(dev_list_entry, devices) { + QString devpath = udev_list_entry_get_name(dev_list_entry); + if (devicename.indexIn(devpath) >= 0) { + int index = devicename.cap(1).toInt(); + addJoyPad(index, devpath); + } + } + + udev_ok = true; + } + else { + debug_mesg("udev_enumerate_scan_devices: %s\n", + strerror(-errnum)); + } + } + else { + debug_mesg("udev_enumerate_add_match_subsystem: %s\n", + strerror(-errnum)); + } + + udev_enumerate_unref(enumerate); + } + } + + // but if udev failed still try "ls $devdir/js*" + if (!udev_ok) { + debug_mesg("udev enumeration failed. retry with \"ls $devdir/js*\"\n"); +#endif + //set all joydevs anew (create new JoyPad's if necesary) QDir deviceDir(devdir); QStringList devices = deviceDir.entryList(QStringList("js*"), QDir::System); - QRegExp devicename("js(\\d+)"); //for every joystick device in the directory listing... //(note, with devfs, only available devices are listed) foreach (const QString &device, devices) { @@ -502,6 +548,10 @@ void LayoutManager::updateJoyDevs() { addJoyPad(index, devpath); } } + +#ifdef WITH_LIBUDEV + } +#endif //when it's all done, rebuild the popup menu so it displays the correct //information. fillPopup();