also use libudev for enumerating joypad devices

This commit is contained in:
Mathias Panzenböck
2014-02-23 16:50:47 +01:00
parent e19c4d7b95
commit cad0fc343d
2 changed files with 61 additions and 11 deletions

View File

@ -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? ### 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 If you compile with `-DWITH_LIBUDEV=ON` (the default) then UDev
[libudev](http://www.signal11.us/oss/udev/) is on the TODO list. is used to automatically update the joypad list. If automatically
However, this would mean yet another dependency and then QJoyPad updating of the joypad list still does not work compile with
won't run on distributions without UDev anymore. I don't know `-DCMAKE_BUILD_TYPE=Debug` and post the output on the [GitHub
if such distributions even exist, though. bug tracker](https://github.com/panzi/qjoypad/issues).
Currently you can let QJoyPad rescan your joypads using the menu You can force QJoyPad to rescan your joypads at any time using the
or by running `qjoypad --update`. menu or by running `qjoypad --update`.
### When QJoyPad checks for new joysticks, it doesn't find mine! ### When QJoyPad checks for new joysticks, it doesn't find mine!

View File

@ -22,7 +22,7 @@ LayoutManager::LayoutManager( bool useTrayIcon, const QString &devdir, const QSt
monitor = 0; monitor = 0;
if (!initUDev()) { 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."); "QJoyPad will still work, but it won't automatically update the joypad device list.");
} }
#endif #endif
@ -91,7 +91,7 @@ bool LayoutManager::initUDev() {
monitor, "input", NULL); monitor, "input", NULL);
if (errnum != 0) { if (errnum != 0) {
debug_mesg("udev_monitor_filter_add_match_subsystem_devtype: %s\n", debug_mesg("udev_monitor_filter_add_match_subsystem_devtype: %s\n",
strerror(errnum)); strerror(-errnum));
udev_monitor_unref(monitor); udev_monitor_unref(monitor);
udev_unref(udev); udev_unref(udev);
monitor = 0; monitor = 0;
@ -102,7 +102,7 @@ bool LayoutManager::initUDev() {
errnum = udev_monitor_enable_receiving(monitor); errnum = udev_monitor_enable_receiving(monitor);
if (errnum != 0) { if (errnum != 0) {
debug_mesg("udev_monitor_enable_receiving: %s\n", debug_mesg("udev_monitor_enable_receiving: %s\n",
strerror(errnum)); strerror(-errnum));
udev_monitor_unref(monitor); udev_monitor_unref(monitor);
udev_unref(udev); udev_unref(udev);
monitor = 0; monitor = 0;
@ -489,10 +489,56 @@ void LayoutManager::updateJoyDevs() {
//clear out the list of previously available joysticks //clear out the list of previously available joysticks
available.clear(); 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) //set all joydevs anew (create new JoyPad's if necesary)
QDir deviceDir(devdir); QDir deviceDir(devdir);
QStringList devices = deviceDir.entryList(QStringList("js*"), QDir::System); QStringList devices = deviceDir.entryList(QStringList("js*"), QDir::System);
QRegExp devicename("js(\\d+)");
//for every joystick device in the directory listing... //for every joystick device in the directory listing...
//(note, with devfs, only available devices are listed) //(note, with devfs, only available devices are listed)
foreach (const QString &device, devices) { foreach (const QString &device, devices) {
@ -502,6 +548,10 @@ void LayoutManager::updateJoyDevs() {
addJoyPad(index, devpath); addJoyPad(index, devpath);
} }
} }
#ifdef WITH_LIBUDEV
}
#endif
//when it's all done, rebuild the popup menu so it displays the correct //when it's all done, rebuild the popup menu so it displays the correct
//information. //information.
fillPopup(); fillPopup();