Hi,
I got a bit stuck and would like to hear your opinion on the XInput HID backend, specifically on the mappings, i.e. the code that "accepts" a certain device based on its properties and then maps its buttons and axes to XInput buttons and axes.
As long as the mappings are fixed, i.e. are not supposed to be extended or edited by the user, everything can be compiled into xinput1_3.dll. However, I would like to provide a "xinput.cpl" control panel node for xinput similar to "joy.cpl", where the user can not only test the XInput gamepads, but also manage the XInput-HID backend mappings. The first part can be accomplished by using xinput1_3.dll. However, in order to load and persist different mappings, the second part requires access to the functions that serialize and deserialize the mappings. It also needs some way of getting raw capabilities and changes in HID devices in order to be able to create new mappings.
Here are some possible ways of solving it:
* Extend xinput1_3.dll with the required management functions and add a "wine/xinput_hid_mgmt.h" or similar header that declares those methods. xinput.cpl could then simply use xinput1_3.dll to perform all management functions. I'm not sure if this would break anything due to the additional exports in the dll. * Extract the mapping load and store logic into a separate "xinputhid.dll" or similar. I this case both xinput1_3.dll and xinput.cpl would access this library to load and store mappings. * Move the xinput core and backends into a driver and let xinput1_3.dll access it via IOCTLs. I believe this is the way it works on windows, although there doesn't seem to be any freely available documentation regarding the internal architecture. The XInput-HID backend could then create its own kernel object as a management interface, which could be accessed by xinput.cpl. This would have the added effect of having a single instance managing the xinput devices if several programs are running at the same time, which mimics the behavior of windows.
What do you think would be the best option? Is there another way I haven't mentioned?
- Juan
The registry?
Would you be able to load mappings from the registry?
Then you could have a .cpl that allows a user to produce mappings for their controller, likely tagged by VendorId and ProductId, and then Xinput can load those mappings from the registry.
I think that is the cleanest and easiest way to store those. I would say something in HKCU/Software/wine/Xinput. I would venture so far as to say that even the default mapping for the Xbox controller could be maintained there, so that the default mapping can be overridden, because it is likely that the xbox controller on the Mac and the xbox controller on Linux may have different controller mappings, and on mac it may even vary based on what xbox controller driver the user has installed, though there is a single prominent one that most people have.
So this would be your option 2, using the windows registry as the separate logic.
-aric
On 3/3/16 2:39 AM, Juan Jose Gonzalez wrote:
Hi,
I got a bit stuck and would like to hear your opinion on the XInput HID backend, specifically on the mappings, i.e. the code that "accepts" a certain device based on its properties and then maps its buttons and axes to XInput buttons and axes.
As long as the mappings are fixed, i.e. are not supposed to be extended or edited by the user, everything can be compiled into xinput1_3.dll. However, I would like to provide a "xinput.cpl" control panel node for xinput similar to "joy.cpl", where the user can not only test the XInput gamepads, but also manage the XInput-HID backend mappings. The first part can be accomplished by using xinput1_3.dll. However, in order to load and persist different mappings, the second part requires access to the functions that serialize and deserialize the mappings. It also needs some way of getting raw capabilities and changes in HID devices in order to be able to create new mappings.
Here are some possible ways of solving it:
- Extend xinput1_3.dll with the required management functions and add a "wine/xinput_hid_mgmt.h" or similar header that declares those methods. xinput.cpl could then simply use xinput1_3.dll to perform all management functions. I'm not sure if this would break anything due to the additional exports in the dll.
- Extract the mapping load and store logic into a separate "xinputhid.dll" or similar. I this case both xinput1_3.dll and xinput.cpl would access this library to load and store mappings.
- Move the xinput core and backends into a driver and let xinput1_3.dll access it via IOCTLs. I believe this is the way it works on windows, although there doesn't seem to be any freely available documentation regarding the internal architecture. The XInput-HID backend could then create its own kernel object as a management interface, which could be accessed by xinput.cpl. This would have the added effect of having a single instance managing the xinput devices if several programs are running at the same time, which mimics the behavior of windows.
What do you think would be the best option? Is there another way I haven't mentioned?
- Juan
Thanks for your input.
On 03/03/2016 02:14 PM, Aric Stewart wrote:
The registry?
Would you be able to load mappings from the registry?
Sorry, I should have mentioned that. I was planning on storing the mappings in the registry in all three proposed solutions. My question was where to put the code that does the serialization and deserialization.
Then you could have a .cpl that allows a user to produce mappings for their controller, likely tagged by VendorId and ProductId, and then Xinput can load those mappings from the registry.
I think that is the cleanest and easiest way to store those. I would say something in HKCU/Software/wine/Xinput. I would venture so far as to say that even the default mapping for the Xbox controller could be maintained there, so that the default mapping can be overridden, because it is likely that the xbox controller on the Mac and the xbox controller on Linux may have different controller mappings, and on mac it may even vary based on what xbox controller driver the user has installed, though there is a single prominent one that most people have.
I planned to do binary serialization/deserialization, so manually creating registry entries would be a bit difficult. The idea was to ship some default mappings defined in the code and compiled into xinput, and allow new mappings and overrides from the registry. Those would have to be created with a tool (xinput.cpl). Of course, that tool can also be used to define the default mappings, we'd just have to get the generated binary blob into wine.
So this would be your option 2, using the windows registry as the separate logic.
The problem is that I need somewhere to put the code that does the serialization/deserialization. It's quite simple as long as the configuration can be stored as a binary blob, but it's still not trivial. If possible, I would like to avoid duplicating the code, hence the need for a common module.
-aric
On 3/3/16 2:39 AM, Juan Jose Gonzalez wrote:
Hi,
I got a bit stuck and would like to hear your opinion on the XInput HID backend, specifically on the mappings, i.e. the code that "accepts" a certain device based on its properties and then maps its buttons and axes to XInput buttons and axes.
As long as the mappings are fixed, i.e. are not supposed to be extended or edited by the user, everything can be compiled into xinput1_3.dll. However, I would like to provide a "xinput.cpl" control panel node for xinput similar to "joy.cpl", where the user can not only test the XInput gamepads, but also manage the XInput-HID backend mappings. The first part can be accomplished by using xinput1_3.dll. However, in order to load and persist different mappings, the second part requires access to the functions that serialize and deserialize the mappings. It also needs some way of getting raw capabilities and changes in HID devices in order to be able to create new mappings.
Here are some possible ways of solving it:
- Extend xinput1_3.dll with the required management functions and add a "wine/xinput_hid_mgmt.h" or similar header that declares those methods. xinput.cpl could then simply use xinput1_3.dll to perform all management functions. I'm not sure if this would break anything due to the additional exports in the dll.
- Extract the mapping load and store logic into a separate "xinputhid.dll" or similar. I this case both xinput1_3.dll and xinput.cpl would access this library to load and store mappings.
- Move the xinput core and backends into a driver and let xinput1_3.dll access it via IOCTLs. I believe this is the way it works on windows, although there doesn't seem to be any freely available documentation regarding the internal architecture. The XInput-HID backend could then create its own kernel object as a management interface, which could be accessed by xinput.cpl. This would have the added effect of having a single instance managing the xinput devices if several programs are running at the same time, which mimics the behavior of windows.
What do you think would be the best option? Is there another way I haven't mentioned?
- Juan
- Juan
On 3/3/16 7:52 AM, Juan Jose Gonzalez wrote:
Thanks for your input.
On 03/03/2016 02:14 PM, Aric Stewart wrote:
The registry?
Would you be able to load mappings from the registry?
Sorry, I should have mentioned that. I was planning on storing the mappings in the registry in all three proposed solutions. My question was where to put the code that does the serialization and deserialization.
Why store the mapping serialized? I think it would be far better to have the mapping be very clear and user editable in the registry.
Something like, this is just off the top of my head...
HKCU/Software/wine/Xinput/mapping/<VIDPID>/BTN_A Page=0x9 Usage=0x1 Released=0x0 Pressed=0x7fff Logic="VAL_TO_BTN_GT_ZERO"
HKCU/Software/wine/Xinput/mapping/<VIDPID>/BTN_B Page=0x9 Usage=0x2 Released=0x0 Pressed=0x7fff Logic="VAL_TO_BTN_GT_ZERO"
HKCU/Software/wine/Xinput/mapping/<VIDPID>/LTHUMB_X Page=0x1 Usage=0x30 Inverted=0
HKCU/Software/wine/Xinput/mapping/<VIDPID>/LTHUMB_Y Page=0x1 Usage=0x31 Inverted=1
Then a complete mapping would be required to have all the elements defined. And it would just be the process of loading the values from the registry to build your mapping.
I think that would be much cleaner than trying to store serialized mappings into the registry.
It also may be my imagination but I could have sworn that a linux user once told me that there is a big database of gamepad mapping for xbox controllers somewhere out there. If that does actually exist it would be convenient to be able to access that.
We do some mapping like this for dinput on linux already where in HKCU\Software\Wine\DirectInput you can setup <joystick name> = <axes mapping>
(https://wiki.winehq.org/Useful_Registry_Keys)
I think that would be insufficient for what you need, but has the spirit of what I feel like we should do.
-aric
Then you could have a .cpl that allows a user to produce mappings for their controller, likely tagged by VendorId and ProductId, and then Xinput can load those mappings from the registry.
I think that is the cleanest and easiest way to store those. I would say something in HKCU/Software/wine/Xinput. I would venture so far as to say that even the default mapping for the Xbox controller could be maintained there, so that the default mapping can be overridden, because it is likely that the xbox controller on the Mac and the xbox controller on Linux may have different controller mappings, and on mac it may even vary based on what xbox controller driver the user has installed, though there is a single prominent one that most people have.
I planned to do binary serialization/deserialization, so manually creating registry entries would be a bit difficult. The idea was to ship some default mappings defined in the code and compiled into xinput, and allow new mappings and overrides from the registry. Those would have to be created with a tool (xinput.cpl). Of course, that tool can also be used to define the default mappings, we'd just have to get the generated binary blob into wine.
So this would be your option 2, using the windows registry as the separate logic.
The problem is that I need somewhere to put the code that does the serialization/deserialization. It's quite simple as long as the configuration can be stored as a binary blob, but it's still not trivial. If possible, I would like to avoid duplicating the code, hence the need for a common module.
-aric
On 3/3/16 2:39 AM, Juan Jose Gonzalez wrote:
Hi,
I got a bit stuck and would like to hear your opinion on the XInput HID backend, specifically on the mappings, i.e. the code that "accepts" a certain device based on its properties and then maps its buttons and axes to XInput buttons and axes.
As long as the mappings are fixed, i.e. are not supposed to be extended or edited by the user, everything can be compiled into xinput1_3.dll. However, I would like to provide a "xinput.cpl" control panel node for xinput similar to "joy.cpl", where the user can not only test the XInput gamepads, but also manage the XInput-HID backend mappings. The first part can be accomplished by using xinput1_3.dll. However, in order to load and persist different mappings, the second part requires access to the functions that serialize and deserialize the mappings. It also needs some way of getting raw capabilities and changes in HID devices in order to be able to create new mappings.
Here are some possible ways of solving it:
- Extend xinput1_3.dll with the required management functions and add a "wine/xinput_hid_mgmt.h" or similar header that declares those methods. xinput.cpl could then simply use xinput1_3.dll to perform all management functions. I'm not sure if this would break anything due to the additional exports in the dll.
- Extract the mapping load and store logic into a separate "xinputhid.dll" or similar. I this case both xinput1_3.dll and xinput.cpl would access this library to load and store mappings.
- Move the xinput core and backends into a driver and let xinput1_3.dll access it via IOCTLs. I believe this is the way it works on windows, although there doesn't seem to be any freely available documentation regarding the internal architecture. The XInput-HID backend could then create its own kernel object as a management interface, which could be accessed by xinput.cpl. This would have the added effect of having a single instance managing the xinput devices if several programs are running at the same time, which mimics the behavior of windows.
What do you think would be the best option? Is there another way I haven't mentioned?
- Juan
- Juan
On 03/03/2016 03:15 PM, Aric Stewart wrote:
On 3/3/16 7:52 AM, Juan Jose Gonzalez wrote:
Thanks for your input.
On 03/03/2016 02:14 PM, Aric Stewart wrote:
The registry?
Would you be able to load mappings from the registry?
Sorry, I should have mentioned that. I was planning on storing the mappings in the registry in all three proposed solutions. My question was where to put the code that does the serialization and deserialization.
Why store the mapping serialized? I think it would be far better to have the mapping be very clear and user editable in the registry.
Something like, this is just off the top of my head...
HKCU/Software/wine/Xinput/mapping/<VIDPID>/BTN_A Page=0x9 Usage=0x1 Released=0x0 Pressed=0x7fff Logic="VAL_TO_BTN_GT_ZERO"
HKCU/Software/wine/Xinput/mapping/<VIDPID>/BTN_B Page=0x9 Usage=0x2 Released=0x0 Pressed=0x7fff Logic="VAL_TO_BTN_GT_ZERO"
HKCU/Software/wine/Xinput/mapping/<VIDPID>/LTHUMB_X Page=0x1 Usage=0x30 Inverted=0
HKCU/Software/wine/Xinput/mapping/<VIDPID>/LTHUMB_Y Page=0x1 Usage=0x31 Inverted=1
The axis/button mappings themselves are pretty easy to do with simple registry keys. The matching mechanism, however, is more complex. VID/PID isn't enough here, since the same VID and PID might need completely different mappings depending on which system you are on and even which driver you are using to emulate a HID device from an xbox controller. I've implemented a hierarchical structure which allows composite matches like the following: AND(VID = 0x45e, OR(PID = 0x28e, PID = ...), OR(Version = 0x110, ...), OR(NAME="Microsoft X-Box 360 pad", NAME="Microsoft X-Box 360 wireless pad"), HASUSAGE(0x01, 0x09, 0x30), ...)). Storing that in the registry in clear text is doable, but it seems like a bit of overhead to fill the registry with that. On the other hand, I have to admit it also feels weird to store configs as binary blobs in the registry.
I'll implement the clear text serializer/deserializer and see how a mapping looks for a real controller. I may be picturing it worse than it is.
Then a complete mapping would be required to have all the elements defined. And it would just be the process of loading the values from the registry to build your mapping.
I think that would be much cleaner than trying to store serialized mappings into the registry.
It also may be my imagination but I could have sworn that a linux user once told me that there is a big database of gamepad mapping for xbox controllers somewhere out there. If that does actually exist it would be convenient to be able to access that.
For linux, there aren't many driver choices (I'm aware of), so we can simply take a look at the xpad module's and xboxdrv's source code. I don't know where to look for default mappings for the available OSX drivers.
We do some mapping like this for dinput on linux already where in HKCU\Software\Wine\DirectInput you can setup <joystick name> = <axes mapping>
(https://wiki.winehq.org/Useful_Registry_Keys)
I think that would be insufficient for what you need, but has the spirit of what I feel like we should do.
-aric
There's still the problem with where to put the serialization/deserialization code. While xinput itself only needs to read the mappings, the config tool needs to be able to read, alter and write them, so we need to at least make the deserialization logic accessible to both modules. Especially for a text serializer, that is definitely not something we would want to duplicate.
Then you could have a .cpl that allows a user to produce mappings for their controller, likely tagged by VendorId and ProductId, and then Xinput can load those mappings from the registry.
I think that is the cleanest and easiest way to store those. I would say something in HKCU/Software/wine/Xinput. I would venture so far as to say that even the default mapping for the Xbox controller could be maintained there, so that the default mapping can be overridden, because it is likely that the xbox controller on the Mac and the xbox controller on Linux may have different controller mappings, and on mac it may even vary based on what xbox controller driver the user has installed, though there is a single prominent one that most people have.
I planned to do binary serialization/deserialization, so manually creating registry entries would be a bit difficult. The idea was to ship some default mappings defined in the code and compiled into xinput, and allow new mappings and overrides from the registry. Those would have to be created with a tool (xinput.cpl). Of course, that tool can also be used to define the default mappings, we'd just have to get the generated binary blob into wine.
So this would be your option 2, using the windows registry as the separate logic.
The problem is that I need somewhere to put the code that does the serialization/deserialization. It's quite simple as long as the configuration can be stored as a binary blob, but it's still not trivial. If possible, I would like to avoid duplicating the code, hence the need for a common module.
-aric
On 3/3/16 2:39 AM, Juan Jose Gonzalez wrote:
Hi,
I got a bit stuck and would like to hear your opinion on the XInput HID backend, specifically on the mappings, i.e. the code that "accepts" a certain device based on its properties and then maps its buttons and axes to XInput buttons and axes.
As long as the mappings are fixed, i.e. are not supposed to be extended or edited by the user, everything can be compiled into xinput1_3.dll. However, I would like to provide a "xinput.cpl" control panel node for xinput similar to "joy.cpl", where the user can not only test the XInput gamepads, but also manage the XInput-HID backend mappings. The first part can be accomplished by using xinput1_3.dll. However, in order to load and persist different mappings, the second part requires access to the functions that serialize and deserialize the mappings. It also needs some way of getting raw capabilities and changes in HID devices in order to be able to create new mappings.
Here are some possible ways of solving it:
- Extend xinput1_3.dll with the required management functions and add a "wine/xinput_hid_mgmt.h" or similar header that declares those methods. xinput.cpl could then simply use xinput1_3.dll to perform all management functions. I'm not sure if this would break anything due to the additional exports in the dll.
- Extract the mapping load and store logic into a separate "xinputhid.dll" or similar. I this case both xinput1_3.dll and xinput.cpl would access this library to load and store mappings.
- Move the xinput core and backends into a driver and let xinput1_3.dll access it via IOCTLs. I believe this is the way it works on windows, although there doesn't seem to be any freely available documentation regarding the internal architecture. The XInput-HID backend could then create its own kernel object as a management interface, which could be accessed by xinput.cpl. This would have the added effect of having a single instance managing the xinput devices if several programs are running at the same time, which mimics the behavior of windows.
What do you think would be the best option? Is there another way I haven't mentioned?
- Juan
- Juan
On 3 March 2016 at 16:10, Juan Jose Gonzalez juanj.gh@gmail.com wrote:
There's still the problem with where to put the serialization/deserialization code. While xinput itself only needs to read the mappings, the config tool needs to be able to read, alter and write them, so we need to at least make the deserialization logic accessible to both modules. Especially for a text serializer, that is definitely not something we would want to duplicate.
It's probably one of those things where it depends on how the actual code is going to look in the end, but if it's simple enough you could perhaps implement it as inline functions in some header under include/wine/.
On 03/03/2016 05:30 PM, Henri Verbeet wrote:
On 3 March 2016 at 16:10, Juan Jose Gonzalez juanj.gh@gmail.com wrote:
There's still the problem with where to put the serialization/deserialization code. While xinput itself only needs to read the mappings, the config tool needs to be able to read, alter and write them, so we need to at least make the deserialization logic accessible to both modules. Especially for a text serializer, that is definitely not something we would want to duplicate.
It's probably one of those things where it depends on how the actual code is going to look in the end, but if it's simple enough you could perhaps implement it as inline functions in some header under include/wine/.
I had though about that, but I think its going to be quite a bit of code. We need to access the correct registry keys, iterate over their values and sub-keys, and parse each item. It would feel like a big hack to put all that in a header.
On 3/3/16 9:10 AM, Juan Jose Gonzalez wrote:
The axis/button mappings themselves are pretty easy to do with simple registry keys. The matching mechanism, however, is more complex. VID/PID isn't enough here, since the same VID and PID might need completely different mappings depending on which system you are on and even which driver you are using to emulate a HID device from an xbox controller. I've implemented a hierarchical structure which allows composite matches like the following: AND(VID = 0x45e, OR(PID = 0x28e, PID = ...), OR(Version = 0x110, ...), OR(NAME="Microsoft X-Box 360 pad", NAME="Microsoft X-Box 360 wireless pad"), HASUSAGE(0x01, 0x09, 0x30), ...)). Storing that in the registry in clear text is doable, but it seems like a bit of overhead to fill the registry with that. On the other hand, I have to admit it also feels weird to store configs as binary blobs in the registry
Shouldn't VID and PID uniquely identify a device? Do companies reuse PID values frequently enough that we have to worry about that?
Now I know from Linux Input it can be hard/impossible to get the device VID and PID, if we ask for it we get things like 0001 and 0002. So having an alternate match, maybe on device name, would be needed.
I think getting too complicated on the matching logic is not really required, we could have everything as an AND, then we have this registry key:
[HKCU/Software/wine/Xinput/mapping] "VID=xxx,PID=yyy"="key1" "VID=xxx,PID=zzz"="key1" "NAME=aaa"="key2"
[HKCU/Software/wine/Xinput/mapping/key1] ...
[HKCU/Software/wine/Xinput/mapping/key2] ...
This lets OR logic be build into having multiple mapping values pointing to the same key.
I have been thinking of this and can see the value of having a number of built in mappings also, so that many controllers work without a custom registry mapping. But we would want the registry mapping to be able to override any built in map.
.
I'll implement the clear text serializer/deserializer and see how a mapping looks for a real controller. I may be picturing it worse than it is.
I feel like the logic should not be too complicated it is more a matter of identifying compatible controllers that may not match any knowing mapping.
There you would need to count buttons and axes and make sure there are enough and the right types.
-aric
Then a complete mapping would be required to have all the elements defined. And it would just be the process of loading the values from the registry to build your mapping.
I think that would be much cleaner than trying to store serialized mappings into the registry.
It also may be my imagination but I could have sworn that a linux user once told me that there is a big database of gamepad mapping for xbox controllers somewhere out there. If that does actually exist it would be convenient to be able to access that.
For linux, there aren't many driver choices (I'm aware of), so we can simply take a look at the xpad module's and xboxdrv's source code. I don't know where to look for default mappings for the available OSX drivers.
We do some mapping like this for dinput on linux already where in HKCU\Software\Wine\DirectInput you can setup <joystick name> = <axes mapping>
(https://wiki.winehq.org/Useful_Registry_Keys)
I think that would be insufficient for what you need, but has the spirit of what I feel like we should do.
-aric
There's still the problem with where to put the serialization/deserialization code. While xinput itself only needs to read the mappings, the config tool needs to be able to read, alter and write them, so we need to at least make the deserialization logic accessible to both modules. Especially for a text serializer, that is definitely not something we would want to duplicate.
Then you could have a .cpl that allows a user to produce mappings for their controller, likely tagged by VendorId and ProductId, and then Xinput can load those mappings from the registry.
I think that is the cleanest and easiest way to store those. I would say something in HKCU/Software/wine/Xinput. I would venture so far as to say that even the default mapping for the Xbox controller could be maintained there, so that the default mapping can be overridden, because it is likely that the xbox controller on the Mac and the xbox controller on Linux may have different controller mappings, and on mac it may even vary based on what xbox controller driver the user has installed, though there is a single prominent one that most people have.
I planned to do binary serialization/deserialization, so manually creating registry entries would be a bit difficult. The idea was to ship some default mappings defined in the code and compiled into xinput, and allow new mappings and overrides from the registry. Those would have to be created with a tool (xinput.cpl). Of course, that tool can also be used to define the default mappings, we'd just have to get the generated binary blob into wine.
So this would be your option 2, using the windows registry as the separate logic.
The problem is that I need somewhere to put the code that does the serialization/deserialization. It's quite simple as long as the configuration can be stored as a binary blob, but it's still not trivial. If possible, I would like to avoid duplicating the code, hence the need for a common module.
-aric
On 3/3/16 2:39 AM, Juan Jose Gonzalez wrote:
Hi,
I got a bit stuck and would like to hear your opinion on the XInput HID backend, specifically on the mappings, i.e. the code that "accepts" a certain device based on its properties and then maps its buttons and axes to XInput buttons and axes.
As long as the mappings are fixed, i.e. are not supposed to be extended or edited by the user, everything can be compiled into xinput1_3.dll. However, I would like to provide a "xinput.cpl" control panel node for xinput similar to "joy.cpl", where the user can not only test the XInput gamepads, but also manage the XInput-HID backend mappings. The first part can be accomplished by using xinput1_3.dll. However, in order to load and persist different mappings, the second part requires access to the functions that serialize and deserialize the mappings. It also needs some way of getting raw capabilities and changes in HID devices in order to be able to create new mappings.
Here are some possible ways of solving it:
* Extend xinput1_3.dll with the required management functions and add a "wine/xinput_hid_mgmt.h" or similar header that declares those methods. xinput.cpl could then simply use xinput1_3.dll to perform all management functions. I'm not sure if this would break anything due to the additional exports in the dll. * Extract the mapping load and store logic into a separate "xinputhid.dll" or similar. I this case both xinput1_3.dll and xinput.cpl would access this library to load and store mappings. * Move the xinput core and backends into a driver and let xinput1_3.dll access it via IOCTLs. I believe this is the way it works on windows, although there doesn't seem to be any freely available documentation regarding the internal architecture. The XInput-HID backend could then create its own kernel object as a management interface, which could be accessed by xinput.cpl. This would have the added effect of having a single instance managing the xinput devices if several programs are running at the same time, which mimics the behavior of windows.
What do you think would be the best option? Is there another way I haven't mentioned?
- Juan
- Juan
On 03/03/2016 06:33 PM, Aric Stewart wrote:
On 3/3/16 9:10 AM, Juan Jose Gonzalez wrote:
The axis/button mappings themselves are pretty easy to do with simple registry keys. The matching mechanism, however, is more complex. VID/PID isn't enough here, since the same VID and PID might need completely different mappings depending on which system you are on and even which driver you are using to emulate a HID device from an xbox controller. I've implemented a hierarchical structure which allows composite matches like the following: AND(VID = 0x45e, OR(PID = 0x28e, PID = ...), OR(Version = 0x110, ...), OR(NAME="Microsoft X-Box 360 pad", NAME="Microsoft X-Box 360 wireless pad"), HASUSAGE(0x01, 0x09, 0x30), ...)). Storing that in the registry in clear text is doable, but it seems like a bit of overhead to fill the registry with that. On the other hand, I have to admit it also feels weird to store configs as binary blobs in the registry
Shouldn't VID and PID uniquely identify a device? Do companies reuse PID values frequently enough that we have to worry about that?
Now I know from Linux Input it can be hard/impossible to get the device VID and PID, if we ask for it we get things like 0001 and 0002. So having an alternate match, maybe on device name, would be needed.
At the USB level, VID and PID [should] uniquely identify any xbox controller. The problem is that we're using drivers to simulate HID devices from those xbox controllers. Those devices don't officially exist as such, so the manufacturers are not recycling their PIDs, we are. On my machine, using xboxdrv, I am getting VID=0x045e and PID=0x028e for a controller mapped with "--mimic-xpad". I don't know if the PID actually matches a XBox 360 wired controller, but the VID is definitely Microsoft's. Basically, we're getting the same VID and PID, even though its probably a completely different device (when you look at its capabilities) than what an OSX HID driver would generate. Therefore, the matching logic needs to be able to check other factors, like which capabilities are reported or whether some string descriptor is available. I'm not sure this can be condensed into one flat "ANDed" line.
I think getting too complicated on the matching logic is not really required, we could have everything as an AND, then we have this registry key:
[HKCU/Software/wine/Xinput/mapping] "VID=xxx,PID=yyy"="key1" "VID=xxx,PID=zzz"="key1" "NAME=aaa"="key2"
[HKCU/Software/wine/Xinput/mapping/key1] ...
[HKCU/Software/wine/Xinput/mapping/key2] ...
This lets OR logic be build into having multiple mapping values pointing to the same key.
Good idea!
I have been thinking of this and can see the value of having a number of built in mappings also, so that many controllers work without a custom registry mapping. But we would want the registry mapping to be able to override any built in map.
Definitely! That's what i was going for.
I'll implement the clear text serializer/deserializer and see how a mapping looks for a real controller. I may be picturing it worse than it is.
I feel like the logic should not be too complicated it is more a matter of identifying compatible controllers that may not match any knowing mapping.
There you would need to count buttons and axes and make sure there are enough and the right types.
I'd rather not automatically infer mappings. I've had enough experiences with games doing really weird stuff by assuming they know which axes are which. I'd prefer to realize that my gamepad isn't working, go to the control panel and create a mapping.
- Juan
On 03/03/2016 07:04 PM, Juan Jose Gonzalez wrote:
On 03/03/2016 06:33 PM, Aric Stewart wrote:
On 3/3/16 9:10 AM, Juan Jose Gonzalez wrote:
The axis/button mappings themselves are pretty easy to do with simple registry keys. The matching mechanism, however, is more complex. VID/PID isn't enough here, since the same VID and PID might need completely different mappings depending on which system you are on and even which driver you are using to emulate a HID device from an xbox controller. I've implemented a hierarchical structure which allows composite matches like the following: AND(VID = 0x45e, OR(PID = 0x28e, PID = ...), OR(Version = 0x110, ...), OR(NAME="Microsoft X-Box 360 pad", NAME="Microsoft X-Box 360 wireless pad"), HASUSAGE(0x01, 0x09, 0x30), ...)). Storing that in the registry in clear text is doable, but it seems like a bit of overhead to fill the registry with that. On the other hand, I have to admit it also feels weird to store configs as binary blobs in the registry
Shouldn't VID and PID uniquely identify a device? Do companies reuse PID values frequently enough that we have to worry about that?
Now I know from Linux Input it can be hard/impossible to get the device VID and PID, if we ask for it we get things like 0001 and 0002. So having an alternate match, maybe on device name, would be needed.
At the USB level, VID and PID [should] uniquely identify any xbox controller. The problem is that we're using drivers to simulate HID devices from those xbox controllers. Those devices don't officially exist as such, so the manufacturers are not recycling their PIDs, we are. On my machine, using xboxdrv, I am getting VID=0x045e and PID=0x028e for a controller mapped with "--mimic-xpad". I don't know if the PID actually matches a XBox 360 wired controller, but the VID is definitely Microsoft's. Basically, we're getting the same VID and PID, even though its probably a completely different device (when you look at its capabilities) than what an OSX HID driver would generate. Therefore, the matching logic needs to be able to check other factors, like which capabilities are reported or whether some string descriptor is available. I'm not sure this can be condensed into one flat "ANDed" line.
What do you think having the winehidminidriver.sys evdev backend add the suffix " (evdev)" to the device name? This would allow us to easily identify the devices later on (in xinput and elsewhere). As I mentioned before, we're simulating new devices anyway, not passing original HID devices through, so altering the descriptors is justifiable. The only problem I see with this approach is the string length. I assume that the code issuing the IOCTL to the HID driver provides a buffer that exactly fits the 255 character maximum of HID. If we want to add a suffix, we'd have to reduce the amount of characters returned from the original device, possibly cutting the string (although I doubt any real device will have a 255 character long name).
- Juan
On 3/4/16 4:57 AM, Juan Jose Gonzalez wrote:
On 03/03/2016 07:04 PM, Juan Jose Gonzalez wrote:
On 03/03/2016 06:33 PM, Aric Stewart wrote:
On 3/3/16 9:10 AM, Juan Jose Gonzalez wrote:
The axis/button mappings themselves are pretty easy to do with simple registry keys. The matching mechanism, however, is more complex. VID/PID isn't enough here, since the same VID and PID might need completely different mappings depending on which system you are on and even which driver you are using to emulate a HID device from an xbox controller. I've implemented a hierarchical structure which allows composite matches like the following: AND(VID = 0x45e, OR(PID = 0x28e, PID = ...), OR(Version = 0x110, ...), OR(NAME="Microsoft X-Box 360 pad", NAME="Microsoft X-Box 360 wireless pad"), HASUSAGE(0x01, 0x09, 0x30), ...)). Storing that in the registry in clear text is doable, but it seems like a bit of overhead to fill the registry with that. On the other hand, I have to admit it also feels weird to store configs as binary blobs in the registry
Shouldn't VID and PID uniquely identify a device? Do companies reuse PID values frequently enough that we have to worry about that?
Now I know from Linux Input it can be hard/impossible to get the device VID and PID, if we ask for it we get things like 0001 and 0002. So having an alternate match, maybe on device name, would be needed.
At the USB level, VID and PID [should] uniquely identify any xbox controller. The problem is that we're using drivers to simulate HID devices from those xbox controllers. Those devices don't officially exist as such, so the manufacturers are not recycling their PIDs, we are. On my machine, using xboxdrv, I am getting VID=0x045e and PID=0x028e for a controller mapped with "--mimic-xpad". I don't know if the PID actually matches a XBox 360 wired controller, but the VID is definitely Microsoft's. Basically, we're getting the same VID and PID, even though its probably a completely different device (when you look at its capabilities) than what an OSX HID driver would generate. Therefore, the matching logic needs to be able to check other factors, like which capabilities are reported or whether some string descriptor is available. I'm not sure this can be condensed into one flat "ANDed" line.
What do you think having the winehidminidriver.sys evdev backend add the suffix " (evdev)" to the device name? This would allow us to easily identify the devices later on (in xinput and elsewhere). As I mentioned before, we're simulating new devices anyway, not passing original HID devices through, so altering the descriptors is justifiable. The only problem I see with this approach is the string length. I assume that the code issuing the IOCTL to the HID driver provides a buffer that exactly fits the 255 character maximum of HID. If we want to add a suffix, we'd have to reduce the amount of characters returned from the original device, possibly cutting the string (although I doubt any real device will have a 255 character long name).
Right now HID_STRING_ID_IMANUFACTURER, is blank because we do not have any way to get that from the device with an evdev device. So it would be easy to have the HID_STRING_ID_IMANUFACTURER string be something set to "evdev"
-aric
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.
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.
As you have seen the xbox controller lacks proper HID descriptors and on Windows the drivers fake descriptors to allow DirectInput to work as well. We would be doing something not to different. For the DirectInput I would report the real device name and the real ranges, similar if games use raw input (not sure if there are games which do this).
Thanks, Roderick
On Thu, Mar 3, 2016 at 12:39 AM, Juan Jose Gonzalez juanj.gh@gmail.com wrote:
Hi,
I got a bit stuck and would like to hear your opinion on the XInput HID backend, specifically on the mappings, i.e. the code that "accepts" a certain device based on its properties and then maps its buttons and axes to XInput buttons and axes.
As long as the mappings are fixed, i.e. are not supposed to be extended or edited by the user, everything can be compiled into xinput1_3.dll. However, I would like to provide a "xinput.cpl" control panel node for xinput similar to "joy.cpl", where the user can not only test the XInput gamepads, but also manage the XInput-HID backend mappings. The first part can be accomplished by using xinput1_3.dll. However, in order to load and persist different mappings, the second part requires access to the functions that serialize and deserialize the mappings. It also needs some way of getting raw capabilities and changes in HID devices in order to be able to create new mappings.
Here are some possible ways of solving it:
Extend xinput1_3.dll with the required management functions and add a "wine/xinput_hid_mgmt.h" or similar header that declares those methods. xinput.cpl could then simply use xinput1_3.dll to perform all management functions. I'm not sure if this would break anything due to the additional exports in the dll. Extract the mapping load and store logic into a separate "xinputhid.dll" or similar. I this case both xinput1_3.dll and xinput.cpl would access this library to load and store mappings. Move the xinput core and backends into a driver and let xinput1_3.dll access it via IOCTLs. I believe this is the way it works on windows, although there doesn't seem to be any freely available documentation regarding the internal architecture. The XInput-HID backend could then create its own kernel object as a management interface, which could be accessed by xinput.cpl. This would have the added effect of having a single instance managing the xinput devices if several programs are running at the same time, which mimics the behavior of windows.
What do you think would be the best option? Is there another way I haven't mentioned?
- Juan
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%... , 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.
As you have seen the xbox controller lacks proper HID descriptors and on Windows the drivers fake descriptors to allow DirectInput to work as well. We would be doing something not to different. For the DirectInput I would report the real device name and the real ranges, similar if games use raw input (not sure if there are games which do this).
On Wine, this would work the other way around. We would have raw (HID) devices as a base, and create DInput and XInput devices from those.
- Juan
Thanks, Roderick
On Thu, Mar 3, 2016 at 12:39 AM, Juan Jose Gonzalez juanj.gh@gmail.com wrote:
Hi,
I got a bit stuck and would like to hear your opinion on the XInput HID backend, specifically on the mappings, i.e. the code that "accepts" a certain device based on its properties and then maps its buttons and axes to XInput buttons and axes.
As long as the mappings are fixed, i.e. are not supposed to be extended or edited by the user, everything can be compiled into xinput1_3.dll. However, I would like to provide a "xinput.cpl" control panel node for xinput similar to "joy.cpl", where the user can not only test the XInput gamepads, but also manage the XInput-HID backend mappings. The first part can be accomplished by using xinput1_3.dll. However, in order to load and persist different mappings, the second part requires access to the functions that serialize and deserialize the mappings. It also needs some way of getting raw capabilities and changes in HID devices in order to be able to create new mappings.
Here are some possible ways of solving it:
Extend xinput1_3.dll with the required management functions and add a "wine/xinput_hid_mgmt.h" or similar header that declares those methods. xinput.cpl could then simply use xinput1_3.dll to perform all management functions. I'm not sure if this would break anything due to the additional exports in the dll. Extract the mapping load and store logic into a separate "xinputhid.dll" or similar. I this case both xinput1_3.dll and xinput.cpl would access this library to load and store mappings. Move the xinput core and backends into a driver and let xinput1_3.dll access it via IOCTLs. I believe this is the way it works on windows, although there doesn't seem to be any freely available documentation regarding the internal architecture. The XInput-HID backend could then create its own kernel object as a management interface, which could be accessed by xinput.cpl. This would have the added effect of having a single instance managing the xinput devices if several programs are running at the same time, which mimics the behavior of windows.
What do you think would be the best option? Is there another way I haven't mentioned?
- Juan
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?
I see no reason not to include mappings for devices with a layout matching that of xbox controllers, even if they are not accessible through xinput on Windows. We only have to do what Windows does when applications depend on it.
On 3/19/16 12:59 PM, Juan Jose Gonzalez wrote:
Hi,
On 03/16/2016 02:45 AM, Roderick Colenbrander wrote:
Hi Juan,
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%... , 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.
The IM_/IG_ device enumeration thing is done driver level. I have some super basic logic in my current set of patches that uses IG_ if i know the device is a gamepad device. We may in the future want to make that smarter in the future (Counting axis/buttons etc...)
-aric
On Sat, Mar 19, 2016 at 10:59 AM, Juan Jose Gonzalez juanj.gh@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%... , 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).
As you have seen the xbox controller lacks proper HID descriptors and on Windows the drivers fake descriptors to allow DirectInput to work as well. We would be doing something not to different. For the DirectInput I would report the real device name and the real ranges, similar if games use raw input (not sure if there are games which do this).
On Wine, this would work the other way around. We would have raw (HID) devices as a base, and create DInput and XInput devices from those.
I understand that part. What I meant is that Windows reports 2 different devices one with HID and one without. I was suggesting this as a way to potentially handle non-native xinput devices, e.g. the non-native device is made to appear like the xbox one on windows with the missing descriptors etcetera. Though this still wouldn't handle the enumeration situation for apps using wmi.
- Juan
Thanks, Roderick
On Thu, Mar 3, 2016 at 12:39 AM, Juan Jose Gonzalez juanj.gh@gmail.com wrote:
Hi,
I got a bit stuck and would like to hear your opinion on the XInput HID backend, specifically on the mappings, i.e. the code that "accepts" a certain device based on its properties and then maps its buttons and axes to XInput buttons and axes.
As long as the mappings are fixed, i.e. are not supposed to be extended or edited by the user, everything can be compiled into xinput1_3.dll. However, I would like to provide a "xinput.cpl" control panel node for xinput similar to "joy.cpl", where the user can not only test the XInput gamepads, but also manage the XInput-HID backend mappings. The first part can be accomplished by using xinput1_3.dll. However, in order to load and persist different mappings, the second part requires access to the functions that serialize and deserialize the mappings. It also needs some way of getting raw capabilities and changes in HID devices in order to be able to create new mappings.
Here are some possible ways of solving it:
Extend xinput1_3.dll with the required management functions and add a "wine/xinput_hid_mgmt.h" or similar header that declares those methods. xinput.cpl could then simply use xinput1_3.dll to perform all management functions. I'm not sure if this would break anything due to the additional exports in the dll. Extract the mapping load and store logic into a separate "xinputhid.dll" or similar. I this case both xinput1_3.dll and xinput.cpl would access this library to load and store mappings. Move the xinput core and backends into a driver and let xinput1_3.dll access it via IOCTLs. I believe this is the way it works on windows, although there doesn't seem to be any freely available documentation regarding the internal architecture. The XInput-HID backend could then create its own kernel object as a management interface, which could be accessed by xinput.cpl. This would have the added effect of having a single instance managing the xinput devices if several programs are running at the same time, which mimics the behavior of windows.
What do you think would be the best option? Is there another way I haven't mentioned?
- Juan
On 3/21/16 7:27 PM, Roderick Colenbrander wrote:
On Sat, Mar 19, 2016 at 10:59 AM, Juan Jose Gonzalez juanj.gh@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%... , 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.
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.
As you have seen the xbox controller lacks proper HID descriptors and on Windows the drivers fake descriptors to allow DirectInput to work as well. We would be doing something not to different. For the DirectInput I would report the real device name and the real ranges, similar if games use raw input (not sure if there are games which do this).
On Wine, this would work the other way around. We would have raw (HID) devices as a base, and create DInput and XInput devices from those.
I understand that part. What I meant is that Windows reports 2 different devices one with HID and one without. I was suggesting this as a way to potentially handle non-native xinput devices, e.g. the non-native device is made to appear like the xbox one on windows with the missing descriptors etcetera. Though this still wouldn't handle the enumeration situation for apps using wmi.
Can we just have the minidrivers for evdev / OSX / hidraw implement this? Do you have specs on what things they would need to report? What are the missing descriptors?
thanks! -aric
- Juan
Thanks, Roderick
On Thu, Mar 3, 2016 at 12:39 AM, Juan Jose Gonzalez juanj.gh@gmail.com wrote:
Hi,
I got a bit stuck and would like to hear your opinion on the XInput HID backend, specifically on the mappings, i.e. the code that "accepts" a certain device based on its properties and then maps its buttons and axes to XInput buttons and axes.
As long as the mappings are fixed, i.e. are not supposed to be extended or edited by the user, everything can be compiled into xinput1_3.dll. However, I would like to provide a "xinput.cpl" control panel node for xinput similar to "joy.cpl", where the user can not only test the XInput gamepads, but also manage the XInput-HID backend mappings. The first part can be accomplished by using xinput1_3.dll. However, in order to load and persist different mappings, the second part requires access to the functions that serialize and deserialize the mappings. It also needs some way of getting raw capabilities and changes in HID devices in order to be able to create new mappings.
Here are some possible ways of solving it:
Extend xinput1_3.dll with the required management functions and add a "wine/xinput_hid_mgmt.h" or similar header that declares those methods. xinput.cpl could then simply use xinput1_3.dll to perform all management functions. I'm not sure if this would break anything due to the additional exports in the dll. Extract the mapping load and store logic into a separate "xinputhid.dll" or similar. I this case both xinput1_3.dll and xinput.cpl would access this library to load and store mappings. Move the xinput core and backends into a driver and let xinput1_3.dll access it via IOCTLs. I believe this is the way it works on windows, although there doesn't seem to be any freely available documentation regarding the internal architecture. The XInput-HID backend could then create its own kernel object as a management interface, which could be accessed by xinput.cpl. This would have the added effect of having a single instance managing the xinput devices if several programs are running at the same time, which mimics the behavior of windows.
What do you think would be the best option? Is there another way I haven't mentioned?
- Juan
On Tue, Mar 22, 2016 at 5:35 AM, Aric Stewart aric@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@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%... , 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.
As you have seen the xbox controller lacks proper HID descriptors and on Windows the drivers fake descriptors to allow DirectInput to work as well. We would be doing something not to different. For the DirectInput I would report the real device name and the real ranges, similar if games use raw input (not sure if there are games which do this).
On Wine, this would work the other way around. We would have raw (HID) devices as a base, and create DInput and XInput devices from those.
I understand that part. What I meant is that Windows reports 2 different devices one with HID and one without. I was suggesting this as a way to potentially handle non-native xinput devices, e.g. the non-native device is made to appear like the xbox one on windows with the missing descriptors etcetera. Though this still wouldn't handle the enumeration situation for apps using wmi.
Can we just have the minidrivers for evdev / OSX / hidraw implement this? Do you have specs on what things they would need to report? What are the missing descriptors?
Depending on the design we could have the minidriver layer handle maybe mimicking the 2 devices and emulation for non-native devices.
For the x360 controller as I mentioned in this email, the report descriptors are missing and the device is not marked as a HID device and hence in general is not available through raw hid libraries (!). OS drivers can spoof the report descriptor and make the device be HID (not done on Linux for x360, not sure about FreeBSD or OSX). Provided an OS allows you to talk HID to it, Wine would have to spoof the report descriptors and white list all the x360 controllers, last time I checked the Linux xpad driver supported 100 devices for which we would have to embed list the vendor/product ids. In general I expect x360 access to require raw USB access e.g. through libusb. Also at least on Linux raw USB access or raw HID access requires additional permissions e.g. though udev rules, which can be considered a security risk.
After having dealt with input for quite a while, I'm not entirely sure how I would design Wine's input layer. A 'fake' HID layer is reasonable just as the layer just below xinput / dinput / winmm. For the layer underneath I would just use evdev and the other APIs supported on different OSes and probably skip HID, because I really expect it will be like writing many custom device drivers for within Wine. Though with the mini drivers doing a mapping back to HID is a little tricky since you can't get the exact report and different features need different device specific code paths (e.g. sysfs entries to set player LED states). Even for mini drivers I expect device specific code, which can't use sharing between different OSes. No matter what path is taken I think it will become very messy and I would urge to keep the mess to below dinput / xinput / winmm.
Thanks, Roderick
thanks! -aric
- Juan
Thanks, Roderick
On Thu, Mar 3, 2016 at 12:39 AM, Juan Jose Gonzalez juanj.gh@gmail.com wrote:
Hi,
I got a bit stuck and would like to hear your opinion on the XInput HID backend, specifically on the mappings, i.e. the code that "accepts" a certain device based on its properties and then maps its buttons and axes to XInput buttons and axes.
As long as the mappings are fixed, i.e. are not supposed to be extended or edited by the user, everything can be compiled into xinput1_3.dll. However, I would like to provide a "xinput.cpl" control panel node for xinput similar to "joy.cpl", where the user can not only test the XInput gamepads, but also manage the XInput-HID backend mappings. The first part can be accomplished by using xinput1_3.dll. However, in order to load and persist different mappings, the second part requires access to the functions that serialize and deserialize the mappings. It also needs some way of getting raw capabilities and changes in HID devices in order to be able to create new mappings.
Here are some possible ways of solving it:
Extend xinput1_3.dll with the required management functions and add a "wine/xinput_hid_mgmt.h" or similar header that declares those methods. xinput.cpl could then simply use xinput1_3.dll to perform all management functions. I'm not sure if this would break anything due to the additional exports in the dll. Extract the mapping load and store logic into a separate "xinputhid.dll" or similar. I this case both xinput1_3.dll and xinput.cpl would access this library to load and store mappings. Move the xinput core and backends into a driver and let xinput1_3.dll access it via IOCTLs. I believe this is the way it works on windows, although there doesn't seem to be any freely available documentation regarding the internal architecture. The XInput-HID backend could then create its own kernel object as a management interface, which could be accessed by xinput.cpl. This would have the added effect of having a single instance managing the xinput devices if several programs are running at the same time, which mimics the behavior of windows.
What do you think would be the best option? Is there another way I haven't mentioned?
- Juan
On 3/23/16 12:20 AM, Roderick Colenbrander wrote:
On Tue, Mar 22, 2016 at 5:35 AM, Aric Stewart aric@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@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%... , 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.
As you have seen the xbox controller lacks proper HID descriptors and on Windows the drivers fake descriptors to allow DirectInput to work as well. We would be doing something not to different. For the DirectInput I would report the real device name and the real ranges, similar if games use raw input (not sure if there are games which do this).
On Wine, this would work the other way around. We would have raw (HID) devices as a base, and create DInput and XInput devices from those.
I understand that part. What I meant is that Windows reports 2 different devices one with HID and one without. I was suggesting this as a way to potentially handle non-native xinput devices, e.g. the non-native device is made to appear like the xbox one on windows with the missing descriptors etcetera. Though this still wouldn't handle the enumeration situation for apps using wmi.
Can we just have the minidrivers for evdev / OSX / hidraw implement this? Do you have specs on what things they would need to report? What are the missing descriptors?
Depending on the design we could have the minidriver layer handle maybe mimicking the 2 devices and emulation for non-native devices.
For the x360 controller as I mentioned in this email, the report descriptors are missing and the device is not marked as a HID device and hence in general is not available through raw hid libraries (!). OS drivers can spoof the report descriptor and make the device be HID (not done on Linux for x360, not sure about FreeBSD or OSX). Provided an OS allows you to talk HID to it, Wine would have to spoof the report descriptors and white list all the x360 controllers, last time I checked the Linux xpad driver supported 100 devices for which we would have to embed list the vendor/product ids. In general I expect x360 access to require raw USB access e.g. through libusb. Also at least on Linux raw USB access or raw HID access requires additional permissions e.g. though udev rules, which can be considered a security risk.
My plan was to require support in the underlying OS. So yes, the x360 controller does not appear in hidraw, but it does appear in evdev so that is where we access it. Same on the mac, the user has to install a custom XBox controller driver for the xbox controller to appear to the IOHid layer.
After having dealt with input for quite a while, I'm not entirely sure how I would design Wine's input layer. A 'fake' HID layer is reasonable just as the layer just below xinput / dinput / winmm. For the layer underneath I would just use evdev and the other APIs supported on different OSes and probably skip HID, because I really expect it will be like writing many custom device drivers for within Wine. Though with the mini drivers doing a mapping back to HID is a little tricky since you can't get the exact report and different features need different device specific code paths (e.g. sysfs entries to set player LED states). Even for mini drivers I expect device specific code, which can't use sharing between different OSes. No matter what path is taken I think it will become very messy and I would urge to keep the mess to below dinput / xinput / winmm.
I think we are on the same page here actually. The HID layer is a layer below xinput / dinput / winmm but then connects to the platform via evdev, or IOHid on the mac. When I am talking about Minidrivers I am talking about the connection between win32 HID and the platform (evdev, etc...)
-aric
Thanks, Roderick
thanks! -aric
- Juan
Thanks, Roderick
On Thu, Mar 3, 2016 at 12:39 AM, Juan Jose Gonzalez juanj.gh@gmail.com wrote:
Hi,
I got a bit stuck and would like to hear your opinion on the XInput HID backend, specifically on the mappings, i.e. the code that "accepts" a certain device based on its properties and then maps its buttons and axes to XInput buttons and axes.
As long as the mappings are fixed, i.e. are not supposed to be extended or edited by the user, everything can be compiled into xinput1_3.dll. However, I would like to provide a "xinput.cpl" control panel node for xinput similar to "joy.cpl", where the user can not only test the XInput gamepads, but also manage the XInput-HID backend mappings. The first part can be accomplished by using xinput1_3.dll. However, in order to load and persist different mappings, the second part requires access to the functions that serialize and deserialize the mappings. It also needs some way of getting raw capabilities and changes in HID devices in order to be able to create new mappings.
Here are some possible ways of solving it:
Extend xinput1_3.dll with the required management functions and add a "wine/xinput_hid_mgmt.h" or similar header that declares those methods. xinput.cpl could then simply use xinput1_3.dll to perform all management functions. I'm not sure if this would break anything due to the additional exports in the dll. Extract the mapping load and store logic into a separate "xinputhid.dll" or similar. I this case both xinput1_3.dll and xinput.cpl would access this library to load and store mappings. Move the xinput core and backends into a driver and let xinput1_3.dll access it via IOCTLs. I believe this is the way it works on windows, although there doesn't seem to be any freely available documentation regarding the internal architecture. The XInput-HID backend could then create its own kernel object as a management interface, which could be accessed by xinput.cpl. This would have the added effect of having a single instance managing the xinput devices if several programs are running at the same time, which mimics the behavior of windows.
What do you think would be the best option? Is there another way I haven't mentioned?
- Juan
On 03/23/2016 07:21 AM, Aric Stewart wrote:
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.
Would this prevent RawInput from working? There are a number of games that use the x360 controller but require RawInput for e.g. the triggers, or such things. I've forgotten the details, but I can re-investigate if it would be helpful.
-- Nate
On 3/23/16 9:59 AM, Nathan Schulte wrote:
On 03/23/2016 07:21 AM, Aric Stewart wrote:
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.
Would this prevent RawInput from working? There are a number of games that use the x360 controller but require RawInput for e.g. the triggers, or such things. I've forgotten the details, but I can re-investigate if it would be helpful.
No, RawInput would be written on top of the win32 HID level. It has not been implemented but should not be too hard once the win32 HID level is in place as RawInput is pretty close to just raw HID.
My first HID test program was actually a RawInput test program that I just made very minor modifications to make it use hid.dll instead.
-aric
-- Nate
On Wed, Mar 23, 2016 at 5:21 AM, Aric Stewart aric@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@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@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%... , 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.
On 03/22/2016 01:27 AM, Roderick Colenbrander wrote:
As you have seen the xbox controller lacks proper HID descriptors and on Windows the drivers fake descriptors to allow DirectInput to work as well. We would be doing something not to different. For the DirectInput I would report the real device name and the real ranges, similar if games use raw input (not sure if there are games which do this).
On Wine, this would work the other way around. We would have raw (HID) devices as a base, and create DInput and XInput devices from those.
I understand that part. What I meant is that Windows reports 2 different devices one with HID and one without. I was suggesting this as a way to potentially handle non-native xinput devices, e.g. the non-native device is made to appear like the xbox one on windows with the missing descriptors etcetera.
I'm not sure I understand what you mean. The currently planned wine architecture uses the HID subsystem as a common base, allowing us to create a single minidriver per backend (evdev, hidraw, etc.), and then lets DInput and XInput access that. Are you suggesting putting all the XInput code (gamepad matching, control mapping) into the HID subsystem?
Though this still wouldn't handle the enumeration situation for apps using wmi.
Sorry, as you may have noticed, I'm not too savvy about Windows APIs. What is wmi?
- Juan
On Tue, Mar 22, 2016 at 12:18 PM, Juan Jose Gonzalez juanj.gh@gmail.com wrote:
On 03/22/2016 01:27 AM, Roderick Colenbrander wrote:
As you have seen the xbox controller lacks proper HID descriptors and on Windows the drivers fake descriptors to allow DirectInput to work as well. We would be doing something not to different. For the DirectInput I would report the real device name and the real ranges, similar if games use raw input (not sure if there are games which do this).
On Wine, this would work the other way around. We would have raw (HID) devices as a base, and create DInput and XInput devices from those.
I understand that part. What I meant is that Windows reports 2 different devices one with HID and one without. I was suggesting this as a way to potentially handle non-native xinput devices, e.g. the non-native device is made to appear like the xbox one on windows with the missing descriptors etcetera.
I'm not sure I understand what you mean.
The currently planned wine
architecture uses the HID subsystem as a common base, allowing us to create a single minidriver per backend (evdev, hidraw, etc.), and then lets DInput and XInput access that. Are you suggesting putting all the XInput code (gamepad matching, control mapping) into the HID subsystem?
I suggested maybe following the Windows 2 device approach for maybe dealing with xinput for non-native devices (the mapping is pretty much the same for steam / ds3 / ds4 / wii u gamepad, just slightly different ranges and button names). For such devices it could make sense to map them to a fixed mapping to simplify handling for xinput. Also I'm not sure how important remapping is normally for users since many games have configurable input.
Though this still wouldn't handle the enumeration situation for apps using wmi.
Sorry, as you may have noticed, I'm not too savvy about Windows APIs. What is wmi?
WMI is a subsystem let's say a bit comparable to /proc & /sys on Linux providing all sorts of information about the system. Through WMI you can provide information on e.g. CPU, USB devices, PCIe devices, network information etcetera. As a developer you provide an SQL-like query to request certain type of information.
For xinput, Microsoft directly provided the xbox API without really considering enumeration well (except for naive polling). One mechanism Microsoft recommended as a bit of an oversight in my opinion was to use WMI to enumerate input devices.
Also before I forget one other important thing for xinput are window messages. I forgot the exact message name but something like WM_DEVICECHANGED or something is important. Various applications listen for the message to detect hotplugging of input devices and then triggering a new device enumeration. For Linux this would require us to tap into udev (SDL2 does this too, the code can give some inspiration).
- Juan
On 3/23/16 12:37 AM, Roderick Colenbrander wrote:
On Tue, Mar 22, 2016 at 12:18 PM, Juan Jose Gonzalez juanj.gh@gmail.com wrote:
On 03/22/2016 01:27 AM, Roderick Colenbrander wrote:
As you have seen the xbox controller lacks proper HID descriptors and on Windows the drivers fake descriptors to allow DirectInput to work as well. We would be doing something not to different. For the DirectInput I would report the real device name and the real ranges, similar if games use raw input (not sure if there are games which do this).
On Wine, this would work the other way around. We would have raw (HID) devices as a base, and create DInput and XInput devices from those.
I understand that part. What I meant is that Windows reports 2 different devices one with HID and one without. I was suggesting this as a way to potentially handle non-native xinput devices, e.g. the non-native device is made to appear like the xbox one on windows with the missing descriptors etcetera.
I'm not sure I understand what you mean.
The currently planned wine
architecture uses the HID subsystem as a common base, allowing us to create a single minidriver per backend (evdev, hidraw, etc.), and then lets DInput and XInput access that. Are you suggesting putting all the XInput code (gamepad matching, control mapping) into the HID subsystem?
I suggested maybe following the Windows 2 device approach for maybe dealing with xinput for non-native devices (the mapping is pretty much the same for steam / ds3 / ds4 / wii u gamepad, just slightly different ranges and button names). For such devices it could make sense to map them to a fixed mapping to simplify handling for xinput. Also I'm not sure how important remapping is normally for users since many games have configurable input.
Though this still wouldn't handle the enumeration situation for apps using wmi.
Sorry, as you may have noticed, I'm not too savvy about Windows APIs. What is wmi?
WMI is a subsystem let's say a bit comparable to /proc & /sys on Linux providing all sorts of information about the system. Through WMI you can provide information on e.g. CPU, USB devices, PCIe devices, network information etcetera. As a developer you provide an SQL-like query to request certain type of information.
For xinput, Microsoft directly provided the xbox API without really considering enumeration well (except for naive polling). One mechanism Microsoft recommended as a bit of an oversight in my opinion was to use WMI to enumerate input devices.
I will have to investigate this. I will add it to my list of surrounding pieces to try to make work. Right now setupapi enumeration works and all my current test applications use that. I have not run into an application trying to use WMI yet. Dinput enumeration also happens but that should be able to be made to work easily.
Also before I forget one other important thing for xinput are window messages. I forgot the exact message name but something like WM_DEVICECHANGED or something is important. Various applications listen for the message to detect hotplugging of input devices and then triggering a new device enumeration. For Linux this would require us to tap into udev (SDL2 does this too, the code can give some inspiration).
Yes, WM_DEVICECHANGED and many of the device addition messages are missing. This is affecting any ability for the Plug and Play functionality to trick up to applications. It is on my list of things to work on along with IoRegisterPlugPlayNotifications and our plug and play facility comes into place.
-aric
- Juan