Kodi Community Forum

Full Version: implementing udev hotplug support / Wii U Pro Controller
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
hey there,

I'm currently playing around to get RetroPlayer working with the Wii U Pro Controller on Linux. I've already created a keymap with basic menu navigation and full gameplay support and it works quite well. Smile

Unfortunately I noticed that there is no hotplug support for joysticks, meaning I have to restart XBMC every time I connect the controller. As far as I understand the code, it is currently just enumerating all devices once on startup but doesn't actually watch for new devices.

I would love to try to implement this myself via udev (emphasis on try Wink ). My question is if it would even make sense for me to start working on this or if I would be wasting my time (because you are already working on it or currently still refactoring a lot etc...).

thanks for all your hard work. Smile

mus
Hi Mus,

Actually, I think that XBMC enumerates all devices every time the app loses and regains focus. Not too sure about this. Unfortunately, I'm pretty unfamiliar with udev. It was one of the major hurdles in my joystick pr (PR:2370, which I've since re-written). This might be a difficult first project to take on, but everyone has to start somewhere Smile

Much refactoring is still being done. The joystick api has some problems, and I think that implementing each button and axis as its own FSM will help bring the complexity down. I started down this road (you can see my progress here), but got distracted by another part of RetroPlayer.

Keep me informed of any progress you make. If you PR against my branch, I'll make sure your code gets reviewed and all fixes/features show up in the next version of RetroPlayer.

Regards,
Garrett
(2014-03-27, 01:19)garbear Wrote: [ -> ]Actually, I think that XBMC enumerates all devices every time the app loses and regains focus.
The only udev enumeration and hotplugging code I could find is in PeripheralBusUSBLibUdev.cpp, but as the name suggests, this is only about USB devices and I haven't quite figured out how everything fits together yet.

(2014-03-27, 01:19)garbear Wrote: [ -> ]It was one of the major hurdles in my joystick pr (PR:2370, which I've since re-written).
ah, I see someone already implemented udev enumeration, no hotplugging though.

(2014-03-27, 01:19)garbear Wrote: [ -> ]This might be a difficult first project to take on, but everyone has to start somewhere Smile
Well, it's not exactly my first XBMC project, but yes, this will probably a lot more difficult. Smile

(2014-03-27, 01:19)garbear Wrote: [ -> ]Much refactoring is still being done. The joystick api has some problems, and I think that implementing each button and axis as its own FSM will help bring the complexity down. I started down this road (you can see my progress here), but got distracted by another part of RetroPlayer.

Keep me informed of any progress you make. If you PR against my branch, I'll make sure your code gets reviewed and all fixes/features show up in the next version of RetroPlayer.
I already wrote a simple C program that printf's on joystick hotplug events. It was fairly straightforward, but I guess actually hooking this up into the existing XBMC code will be a hell of a lot more difficult, especially since I will have to do this in a separate thread and cannot just block.

Even if I can't get the udev stuff done, I will at least send a pull request for the Wii U Pro Gamepad keymap as soon as I implemented more of the menu navigation.
ok, It turns out I actually misunderstood a lot of things in the XBMC sources. I just figured out that there is not really much for me to implement, but there is a bug somewhere:

- CPeripheralBusUSBLibUdev actually reacts to all kind of udev events, not just USB devices.

- On a udev event, CPeripheralBusUSBLibUdev triggers CPeripheralBus::ScanForDevices() which in turns calls CPeripherals::NotifyObservers(), which should cause JoystickManager::Notify() to be called because it registers itself as an Observer to CPeripherals.

The problem is that JoystickManager::Notify() is never called. This is because in Oberserable::NotifyObservers() the variable m_bObservableChanged is always false and the notification is never triggered. If I remove the m_bObservableChanged check, hotplugging works perfectly fine (although in a pretty inefficient way since any udev event causes all joysticks to be reinitialized, but from my understanding this can't be fixed without a whole lot of refactoring and wouldn't bring that much benefit anyway).

Removing the check is obviously not the correct fix, so I'm currently trying to figure out why m_bObservableChanged is always false.
I've actually made this exact mistake in the past. Observables need to call SetChanged() or NotifyObservers() has no effect
CPeripherals::CreatePeripheral() bails out at this point:

Code:
/* check whether there's something mapped in peripherals.xml */
  if (!GetMappingForDevice(bus, mappedResult))
  {
    /* don't create instances for devices that aren't mapped in peripherals.xml */
    return NULL;
  }
The SetChanged() call happens after that, and since peripherals.xml only contains like 3 devices (whatever these are about), SetChanged() is pretty much never called. I don't know if just setting SetChanged() before this if() is the right fix (do you?).

Also there are a few other things seriously wrong with the code. The code that checks for new devices seems to be completely broken since every device (mouse, keyboard etc.) is considered "new" after every udev event.

Either way, it seems like this isn't related to RetroPlayer at all, so I will try to figure this stuff out and send a PR to the master branch. Feel free to close this topic, since it is kind of off-topic here. Wink

thanks for your help, anyway Smile
If anyone is interested, I opened a pull request for the Wii U Pro Controller on the master branch:

https://github.com/xbmc/xbmc/pull/4481

I think it makes sense to get basic support into master first, I will send a PR for RetroPlayer support if/when this is merged.
Trent merged it. When I rebase retroplayer on Gotham, it'll include this map. thanks!
(2014-03-28, 21:06)garbear Wrote: [ -> ]Trent merged it. When I rebase retroplayer on Gotham, it'll include this map. thanks!
great, I'll keep an eye on your repo and send a PR for the <FullscreenGame> mappings after the rebase.