From: Rémi Bernon rbernon@codeweavers.com
To avoid exposing it with the other buttons, the XUSB / GIP frontends don't expose it to applications (for instance in Windows.Gaming.Input). --- dlls/dinput/joystick_hid.c | 2 +- dlls/winebus.sys/bus_sdl.c | 30 ++++++++++++++++-------------- dlls/winebus.sys/bus_udev.c | 18 ++++++++++-------- dlls/winebus.sys/hid.c | 3 ++- dlls/xinput1_3/main.c | 6 +++++- 5 files changed, 34 insertions(+), 25 deletions(-)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 27d08fd2af2..e492fa51bbf 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -1288,7 +1288,7 @@ static HRESULT hid_joystick_read( IDirectInputDevice8W *iface ) { usages = impl->usages_buf + count; if (usages->UsagePage != HID_USAGE_PAGE_BUTTON) - FIXME( "unimplemented usage page %x.\n", usages->UsagePage ); + WARN( "unimplemented usage page %x.\n", usages->UsagePage ); else if (usages->Usage >= 128) FIXME( "ignoring extraneous button %d.\n", usages->Usage ); else diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index a9d28fb28ac..0529b35fbea 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -856,29 +856,31 @@ static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event SDL_ControllerButtonEvent *ie = &event->cbutton; int button;
- switch ((button = ie->button)) + switch (ie->button) { - case SDL_CONTROLLER_BUTTON_DPAD_UP: - hid_device_move_hatswitch(iface, 0, 0, ie->state ? -1 : +1); - break; - case SDL_CONTROLLER_BUTTON_DPAD_DOWN: - hid_device_move_hatswitch(iface, 0, 0, ie->state ? +1 : -1); - break; - case SDL_CONTROLLER_BUTTON_DPAD_LEFT: - hid_device_move_hatswitch(iface, 0, ie->state ? -1 : +1, 0); - break; - case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: - hid_device_move_hatswitch(iface, 0, ie->state ? +1 : -1, 0); - break; + case SDL_CONTROLLER_BUTTON_A: button = 0; break; + case SDL_CONTROLLER_BUTTON_B: button = 1; break; + case SDL_CONTROLLER_BUTTON_X: button = 2; break; + case SDL_CONTROLLER_BUTTON_Y: button = 3; break; case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: button = 4; break; case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: button = 5; break; case SDL_CONTROLLER_BUTTON_BACK: button = 6; break; case SDL_CONTROLLER_BUTTON_START: button = 7; break; case SDL_CONTROLLER_BUTTON_LEFTSTICK: button = 8; break; case SDL_CONTROLLER_BUTTON_RIGHTSTICK: button = 9; break; - case SDL_CONTROLLER_BUTTON_GUIDE: button = 10; break; + case SDL_CONTROLLER_BUTTON_DPAD_UP: button = 10; break; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: button = 11; break; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: button = 12; break; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: button = 13; break; + case SDL_CONTROLLER_BUTTON_GUIDE: button = 16; break; + default: button = -1; break; }
+ if (button == -1) break; + if (button == 10) hid_device_move_hatswitch(iface, 0, 0, ie->state ? -1 : +1); + if (button == 11) hid_device_move_hatswitch(iface, 0, 0, ie->state ? +1 : -1); + if (button == 12) hid_device_move_hatswitch(iface, 0, ie->state ? -1 : +1, 0); + if (button == 13) hid_device_move_hatswitch(iface, 0, ie->state ? +1 : -1, 0); hid_device_set_button(iface, button, ie->state); bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); break; diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index f83b0998f27..65cabff09e4 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -529,8 +529,8 @@ static void set_abs_axis_value(struct unix_device *iface, int code, int value) if (!(code = impl->hat_map[code - ABS_HAT0X])) return; if (impl->is_gamepad) { - hid_device_set_button(iface, 11, value < 0); - hid_device_set_button(iface, 12, value > 0); + hid_device_set_button(iface, 10, value < 0); + hid_device_set_button(iface, 11, value > 0); } hid_device_set_hatswitch_y(iface, code - 1, value); } @@ -539,8 +539,8 @@ static void set_abs_axis_value(struct unix_device *iface, int code, int value) if (!(code = impl->hat_map[code - ABS_HAT0X])) return; if (impl->is_gamepad) { - hid_device_set_button(iface, 13, value < 0); - hid_device_set_button(iface, 14, value > 0); + hid_device_set_button(iface, 12, value < 0); + hid_device_set_button(iface, 13, value > 0); } hid_device_set_hatswitch_x(iface, code - 1, value); } @@ -675,10 +675,10 @@ static BOOL set_report_from_event(struct unix_device *iface, struct input_event if (!(button = impl->button_map[ie->code])) return FALSE; if (impl->is_gamepad && !impl->hat_count) { - if (button == 12) hid_device_set_hatswitch_y(iface, 0, -1); - if (button == 13) hid_device_set_hatswitch_y(iface, 0, +1); - if (button == 14) hid_device_set_hatswitch_x(iface, 0, -1); - if (button == 15) hid_device_set_hatswitch_x(iface, 0, +1); + if (button == 11) hid_device_set_hatswitch_y(iface, 0, -1); + if (button == 12) hid_device_set_hatswitch_y(iface, 0, +1); + if (button == 13) hid_device_set_hatswitch_x(iface, 0, -1); + if (button == 14) hid_device_set_hatswitch_x(iface, 0, +1); } hid_device_set_button(iface, button - 1, ie->value); return FALSE; @@ -1301,6 +1301,7 @@ static NTSTATUS lnxev_device_create(struct udev_device *dev, int fd, const char if (!test_bit(info.key, button)) continue; if (impl->button_count > (impl->hat_count ? 10 : 14)) break; impl->button_map[button] = ++impl->button_count; + if (impl->hat_count && impl->button_count == 11) impl->button_map[button] = 17; }
for (int i = BTN_MISC; i < KEY_MAX; i++) @@ -1309,6 +1310,7 @@ static NTSTATUS lnxev_device_create(struct udev_device *dev, int fd, const char if (impl->button_count > (impl->hat_count ? 10 : 14)) break; if (!test_bit(info.key, i)) continue; impl->button_map[i] = ++impl->button_count; + if (impl->hat_count && impl->button_count == 11) impl->button_map[i] = 17; } }
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index a6318143342..46ad0c69065 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -357,7 +357,8 @@ BOOL hid_device_add_gamepad(struct unix_device *iface) if (!hid_device_add_axes(iface, 1, HID_USAGE_PAGE_GENERIC, <, FALSE, 0, 32767)) return FALSE; if (!hid_device_add_axes(iface, 1, HID_USAGE_PAGE_GENERIC, &rt, FALSE, 0, 32767)) return FALSE; if (!hid_device_add_hatswitch(iface, 1)) return FALSE; - if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, 15)) return FALSE; + if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, 14)) return FALSE; + if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_VENDOR_DEFINED_BEGIN, 1, 8)) return FALSE; if (!hid_device_end_input_report(iface)) return FALSE;
return TRUE; diff --git a/dlls/xinput1_3/main.c b/dlls/xinput1_3/main.c index b9971a11e1f..831874dea73 100644 --- a/dlls/xinput1_3/main.c +++ b/dlls/xinput1_3/main.c @@ -597,10 +597,14 @@ static void read_controller_state(struct xinput_controller *controller) case 8: state.Gamepad.wButtons |= XINPUT_GAMEPAD_START; break; case 9: state.Gamepad.wButtons |= XINPUT_GAMEPAD_LEFT_THUMB; break; case 10: state.Gamepad.wButtons |= XINPUT_GAMEPAD_RIGHT_THUMB; break; - case 11: state.Gamepad.wButtons |= XINPUT_GAMEPAD_GUIDE; break; } }
+ button_length = ARRAY_SIZE(buttons); + status = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_VENDOR_DEFINED_BEGIN, 0, buttons, &button_length, controller->hid.preparsed, report_buf, report_len); + if (status != HIDP_STATUS_SUCCESS) WARN("HidP_GetUsages HID_USAGE_PAGE_VENDOR_DEFINED_BEGIN returned %#lx\n", status); + if (button_length) state.Gamepad.wButtons |= XINPUT_GAMEPAD_GUIDE; + status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, &value, controller->hid.preparsed, report_buf, report_len); if (status != HIDP_STATUS_SUCCESS) WARN("HidP_GetUsageValue HID_USAGE_PAGE_GENERIC / HID_USAGE_GENERIC_HATSWITCH returned %#lx\n", status); else switch (value)