XInput and HID - architecture

Roderick Colenbrander thunderbird2k at gmail.com
Wed Mar 23 10:36:50 CDT 2016


On Wed, Mar 23, 2016 at 5:21 AM, Aric Stewart <aric at codeweavers.com> wrote:
> On 3/23/16 12:20 AM, Roderick Colenbrander wrote:
>> On Tue, Mar 22, 2016 at 5:35 AM, Aric Stewart <aric at codeweavers.com> wrote:
>>> On 3/21/16 7:27 PM, Roderick Colenbrander wrote:
>>>> On Sat, Mar 19, 2016 at 10:59 AM, Juan Jose Gonzalez <juanj.gh at gmail.com> wrote:
>>>>> Hi,
>>>>>
>>>>> On 03/16/2016 02:45 AM, Roderick Colenbrander wrote:
>>>>>> Hi Juan,
>>>>>>
>>>>>> Let me reply to the start of the thread before diving into the
>>>>>> specifics on calibration.
>>>>>>
>>>>>> In my opinion, I'm not sure what the best way would be to handle
>>>>>> passing of HID data to xinput. The main thing to consider as part of
>>>>>> this is handling of non-native xinput devices (e.g. DS4 or
>>>>>> SteamController) provided we want to support this. Aside from passing
>>>>>> up the HID data the other challenge for xinput devices is the
>>>>>> enumeration part, which many (older) games do through a mixture of
>>>>>> WMI, dinput and xinput. For this to work we need to report an actual
>>>>>> xinput gamepad.
>>>>> Wine is supposed to mimic Windows' behavior as well as possible. Thus,
>>>>> the proper way to implement xinput would be to access the USB devices
>>>>> directly. The hid->xinput mapping is already non-compliant with the
>>>>> windows behavior, but currently necessary. However, in my opinion, we
>>>>> should only try to parse those HID descriptors that correspond to XInput
>>>>> devices, as provided by common XInput->HID drivers on different host
>>>>> OSs. Nevertheless, once wine's HID->Xinput backend is finished, the
>>>>> end-users can (locally) add their own mappings for any HID controller
>>>>> they want to use. I just wouldn't add those mappings to the wine repo.
>>>>> I would like to get some input on that, however. Do you think we should
>>>>> add mappings for non-xinput devices?
>>>>>
>>>>> Thank you for pointing out the enumeration process. The reason I
>>>>> implemented Xinput was to play a game that didn't support any other
>>>>> input method, so until now, I hadn't given it much thought. According to
>>>>> https://msdn.microsoft.com/en-us/library/windows/desktop/ee417014%28v=vs.85%29.aspx
>>>>> , an XInput device shows up in DInput with an ID containing "IG_", which
>>>>> is what developers should use to filter them out. This might make things
>>>>> a bit difficult, since in Wine, both DInput and XInput devices are
>>>>> supposed to be created from a common HID base, so Wine's DInput cannot
>>>>> know anything about whether a device is an XInput device or not.
>>>>>>
>>>>>> My feeling would be for xinput to be quite stupid like it is on
>>>>>> Windows and feed it xbox controller compatible HID reports with the
>>>>>> same axes ranges, rumble ranges as the xbox controller. For more
>>>>>> custom devices you may want to support special handling e.g. button
>>>>>> emulation using touchpad on DS4 or maybe even on SteamController.
>>>>> The problem is that there is not a unique HID descriptor set for XInput.
>>>>> Each driver on each OS maps the xinput controls to a different layout,
>>>>> so we need some logic on the Wine XInput driver to tell those apart and
>>>>> map them back to XInput controls.
>>>>
>>>> Nonetheless a mapping is needed from evdev, optionally Linux hidraw
>>>> and whatever backend other OSes use. HID is nice in theory, but in
>>>> practice it is quite messy (many buggy devices, spec abuses, custom
>>>> HID requests to enable a device..). My feeling is to handle the
>>>> mapping to x360 at a level below xinput to avoid the mapping issues in
>>>> xinput. Depending on what other non-native xinput devices we may want
>>>> to handle (ds3, ds4, wii u controller, steam controller are all easy)
>>>> you may want more control at a lower level to handle custom
>>>> functionality, which could optionally need handling through many
>>>> different fields in the HID descriptor (e.g. touch).
>>>>
>>>
>>> The grand hope is that we can move all the platform specific code to HID and not have it reproduces in 3 different locations. We write dinput, winmm and Xinput to all be HID clients.
>>>
>>> You give a number of reasons that HID is messy, but I assume you are talking about windows native HID? Since right now we would be going through our own hid and hid minidrivers we are able to avoid a lot of that messiness.
>>
>> The main concern with HID is the way it is implemented by different
>> devices. Spec abuse, custom initialization logic for different devices
>> through device specific features requests, power management handling.
>> Among places I would recommend to have a look at the many HID drivers
>> in the Linux kernel patching up HID descriptors, doing custom device
>> initialization (power management, wireless pairing).
>>
>> My main worry is the amount of device specific code needed in Wine to
>> make HID useful for input and interpretation of HID data. For some of
>> the popular devices it will be like writing a custom driver. I
>> understand the desire for HID as maybe a way to avoid drivers e.g. on
>> OSX where there is a decent layer but many people don't install
>> gamepad drivers.
>>
>>> What are the specific areas that HID will be insufficient for xinput? Having specific examples will be helpful in figuring out a course of action.
>>
>> I see HID as a fine transport layer from xinput down to some lower
>> layer (I think for the xinput use case we need to standardize on a
>> certain layout). I'm worried about using it for the layers underneath
>> as I will explain below mostly because I expect we will need much
>> device specific code.
>
>
> Right now, and for the foreseeable future, we control all the code from hid.dll down to the platform. So that includes hid.dll, hidclass.sys, the minidrivers and the plug and play driver/implementation. So HID is being used as a transport layer from xinput(dinput, winmm) down to the lower layer.
>
> On Linux I have written both a evdev and hidraw connection, mostly because the hidraw one was very easy. Now that the evdev one is working pretty well if you feel the hidraw one would be nothing but heart ache then I can drop that.
>

Even though I'm not a big fan of hidraw for gamepads, I would
recommend keeping it. The main reason is not for input, but for custom
devices. A lot of custom embedded / industrial devices these days use
HID, while previously they used RS232 or an equivalent interface. For
these devices HID is very simple and doesn't require drivers.
Typically applications directly talk to these devices to the HID API
or a helper dll using the HID API.



More information about the wine-devel mailing list