On 8/18/21 5:52 PM, Zebediah Figura (she/her) wrote:
I have a few questions:
- How will dinput (or winmm) expose these devices?
For dinput, it should enumerate the HID device interface class, so for XInput compatible devices, it will enumerate the bogus "&IG_" devices, in addition to non-XInput compatible devices. Applications are expected to check this marker to de-duplicate the XInput gamepads, as described in [1].
I don't know about winmm, but if it can be implemented on top of HID then it'll be the same.
Both will then be limited by the XInput bogus HID support, like on Windows. And they won't have force-feedback support for them for instance (although XInput, using the internal device, will have it).
We could decide to overcome that limitation by enumerating the XINPUT device interface class, but I don't think it's how it's supposed to work.
- How will we expose composite vs. non-composite devices from winebus?
I don't know, is there going to be any?
On winebus.sys I think composite devices are just going to be enumerated on the unix bus level as separate devices, with different "input" numbers. So we should see a "&MI_00", "&MI_01", "&MI_02" winebus.sys device and so on.
If one of those is supposed to be XInput compatible, the xinput.sys driver should match the compatible ID, and take it over instead of winehid.sys, create a corresponding "&IG_00" (or "&IG_01", etc) HID device, and an internal device on the XINPUT\ bus.
- What potential need is there to duplicate winebus devices that you
refer to? As far as I understand we don't currently duplicate anything.
We don't, but then we have to decide whether a device is exposed as a "mapped" gamepad, or not. The "mapped" version is supposed to mimic the XInput bogus HID devices, in order for applications to be happy when the look at the HID capabilities and reports.
Because of this, the "mapped" devices are limited, possibly not exposing all their axes and buttons in the HID report descriptor, and changing anything there may break applications.
Duplicating the devices, or forking them like done here, let us have a full featured HID device for internal use, while exposing the same bogus thing native exposes publicly (and not use it ourselves).
- And perhaps more generally: from my time working on Proton, although I
haven't worked on controller support recently, I vaguely understand/remember that some games are very picky about what is and isn't reported as an xinput device, and also whether the same device is reported via dinput. Would it be possible for you to summarize the relevant problems there, so that we have that additional context?
Well as far as I could see there's all sorts of issues, starting with SDL enabling various hacks when they detect XInput devices. I believe they support the XInput API, but not only, and they also have support for the XInput HID devices through WM_INPUT messages.
They are trying very hard to support their bogus HID reports, and I think we can expect other input middleware to do as well.
More specifically, they try to workaround two issues:
* The guide button of the XBox controller, which is not supposed to be exposed on the bogus HID reports, but should be obviously supported internally by XInput.
* The two triggers axes, which are supposed to be combined together in the bogus HID report, in a single Z axis. This allows compatibility for XBox gamepads with old games still using DInput, and where the triggers were effectively combined in a single DInput axis.
However, XInput needs to have the two separate triggers internally, so we already report them separately, as an incompatible hack, and implementing our DInput on top of that would break such old games which depend on the triggers to be combined.
- In this patch specifically, is there any reason to keep the old
hardware IDs around?
The internal bus hardware IDs are probably not really useful, and I intend to replace them with a common "WINEBUS\VID_xxxx&PID_xxxx" hardware IDs later on, in order to match these in xinput.sys and remove the need to check for XBox gamepad VID/PID in winebus.sys.
The internal bus names in the device IDs may be helpful to determine which bus a device comes from, although I don't really think it matters. I was kind of going to keep them around though.
[1] https://docs.microsoft.com/en-us/windows/win32/xinput/xinput-and-directinput