From: Arkadiusz Hiler ahiler@codeweavers.com
The HID input report format is different between Linux (hid_logitech_hidpp) and Windows when it comes to axis HID usages.
To correct that we can use the device through SDL and craft our own HID mapping. --- dlls/winebus.sys/bus_sdl.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 0529b35fbea..b3b69a518b5 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -251,6 +251,13 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl, BOOL force) return TRUE; }
+static const USAGE_AND_PAGE g920_absolute_usages[] = +{ + {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_X}, /* wheel */ + {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_Y}, /* accelerator */ + {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_Z}, /* brake */ + {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_RZ}, /* clutch */ +}; static const USAGE_AND_PAGE absolute_axis_usages[] = { {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_X}, @@ -275,19 +282,34 @@ static const USAGE_AND_PAGE relative_axis_usages[] = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_WHEEL}, };
-static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface) +static int get_absolute_usages(const struct device_desc *desc, const USAGE_AND_PAGE **absolute_usages) +{ + if (desc->vid == 0x046d && desc->pid == 0xc262) + { + *absolute_usages = g920_absolute_usages; + return ARRAY_SIZE(g920_absolute_usages); + } + + *absolute_usages = absolute_axis_usages; + return ARRAY_SIZE(absolute_axis_usages); +} + +static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface, const struct device_desc *desc) { const USAGE_AND_PAGE device_usage = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_JOYSTICK}; struct sdl_device *impl = impl_from_unix_device(iface); int i, button_count, axis_count, ball_count, hat_count; USAGE_AND_PAGE physical_usage;
+ const USAGE_AND_PAGE *absolute_usages = NULL; + size_t absolute_usages_count = get_absolute_usages(desc, &absolute_usages); + axis_count = pSDL_JoystickNumAxes(impl->sdl_joystick); if (options->split_controllers) axis_count = min(6, axis_count - impl->axis_offset); - if (axis_count > ARRAY_SIZE(absolute_axis_usages)) + if (axis_count > absolute_usages_count) { - FIXME("More than %zu absolute axes found, ignoring.\n", ARRAY_SIZE(absolute_axis_usages)); - axis_count = ARRAY_SIZE(absolute_axis_usages); + FIXME("More than %zu absolute axes found, ignoring.\n", absolute_usages_count); + axis_count = absolute_usages_count; }
ball_count = pSDL_JoystickNumBalls(impl->sdl_joystick); @@ -343,8 +365,8 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
for (i = 0; i < axis_count; i++) { - if (!hid_device_add_axes(iface, 1, absolute_axis_usages[i].UsagePage, - &absolute_axis_usages[i].Usage, FALSE, -32768, 32767)) + if (!hid_device_add_axes(iface, 1, absolute_usages[i].UsagePage, + &absolute_usages[i].Usage, FALSE, -32768, 32767)) return STATUS_NO_MEMORY; }
@@ -993,7 +1015,7 @@ static void sdl_add_device(unsigned int index) impl->axis_offset = axis_offset;
if (impl->sdl_controller) status = build_controller_report_descriptor(&impl->unix_device); - else status = build_joystick_report_descriptor(&impl->unix_device); + else status = build_joystick_report_descriptor(&impl->unix_device, &desc); if (status) { list_remove(&impl->unix_device.entry);