Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_sdl.c | 18 +++++++- dlls/winebus.sys/bus_udev.c | 6 +++ dlls/winebus.sys/hid.c | 80 +++++++++++++++++++++++++-------- dlls/winebus.sys/unix_private.h | 6 ++- dlls/xinput1_3/main.c | 2 +- 5 files changed, 89 insertions(+), 23 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 7af5f13bcee..72cdf8ae605 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -46,6 +46,7 @@ #include "winternl.h" #include "ddk/wdm.h" #include "ddk/hidtypes.h" +#include "ddk/hidsdi.h" #include "wine/debug.h" #include "wine/unicode.h" #include "hidusage.h" @@ -119,6 +120,7 @@ struct sdl_device
SDL_Haptic *sdl_haptic; int haptic_effect_id; + BYTE vendor_rumble_report_id; };
static inline struct sdl_device *impl_from_unix_device(struct unix_device *iface) @@ -166,7 +168,7 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl) { pSDL_HapticStopAll(impl->sdl_haptic); pSDL_HapticRumbleInit(impl->sdl_haptic); - if (!hid_device_add_haptics(&impl->unix_device)) + if (!hid_device_add_haptics(&impl->unix_device, &impl->vendor_rumble_report_id)) return FALSE; impl->haptic_effect_id = -1; } @@ -217,6 +219,9 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface) if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_JOYSTICK)) return STATUS_NO_MEMORY;
+ if (!hid_device_begin_input_report(iface)) + return STATUS_NO_MEMORY; + if (axis_count && !hid_device_add_axes(iface, axis_count, HID_USAGE_PAGE_GENERIC, joystick_usages, FALSE, -32768, 32767)) return STATUS_NO_MEMORY; @@ -231,6 +236,9 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface) if (button_count && !hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, button_count)) return STATUS_NO_MEMORY;
+ if (!hid_device_end_input_report(iface)) + return STATUS_NO_MEMORY; + if (!descriptor_add_haptic(impl)) return STATUS_NO_MEMORY;
@@ -258,6 +266,9 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface) if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_GAMEPAD)) return STATUS_NO_MEMORY;
+ if (!hid_device_begin_input_report(iface)) + return STATUS_NO_MEMORY; + if (!hid_device_add_axes(iface, 2, HID_USAGE_PAGE_GENERIC, left_axis_usages, FALSE, -32768, 32767)) return STATUS_NO_MEMORY; @@ -276,6 +287,9 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface) if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, button_count)) return STATUS_NO_MEMORY;
+ if (!hid_device_end_input_report(iface)) + return STATUS_NO_MEMORY; + if (!descriptor_add_haptic(impl)) return STATUS_NO_MEMORY;
@@ -325,7 +339,7 @@ static void sdl_device_set_output_report(struct unix_device *iface, HID_XFER_PAC { struct sdl_device *impl = impl_from_unix_device(iface);
- if (impl->sdl_haptic && packet->reportId == 0) + if (impl->sdl_haptic && packet->reportId == impl->vendor_rumble_report_id) { WORD left = packet->reportBuffer[2] * 128; WORD right = packet->reportBuffer[3] * 128; diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index f4d27090109..508614d2c04 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -391,6 +391,9 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d if (!hid_device_begin_report_descriptor(iface, device_usage[0], device_usage[1])) return STATUS_NO_MEMORY;
+ if (!hid_device_begin_input_report(iface)) + return STATUS_NO_MEMORY; + abs_count = 0; for (i = 0; i < HID_ABS_MAX; i++) { @@ -437,6 +440,9 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d if (button_count && !hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, button_count)) return STATUS_NO_MEMORY;
+ if (!hid_device_end_input_report(iface)) + return STATUS_NO_MEMORY; + if (!hid_device_end_report_descriptor(iface)) return STATUS_NO_MEMORY;
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index 4a4295b9aa8..92d572355c2 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -31,6 +31,7 @@ #include "winioctl.h" #include "hidusage.h" #include "ddk/wdm.h" +#include "ddk/hidsdi.h"
#include "wine/debug.h"
@@ -87,6 +88,39 @@ BOOL hid_device_begin_report_descriptor(struct unix_device *iface, USAGE usage_p }
BOOL hid_device_end_report_descriptor(struct unix_device *iface) +{ + struct hid_report_descriptor *desc = &iface->hid_report_descriptor; + static const BYTE template[] = + { + END_COLLECTION, + }; + + return hid_report_descriptor_append(desc, template, sizeof(template)); +} + +BOOL hid_device_begin_input_report(struct unix_device *iface) +{ + struct hid_report_descriptor *desc = &iface->hid_report_descriptor; + struct hid_device_state *state = &iface->hid_device_state; + const BYTE report_id = ++desc->next_report_id[HidP_Input]; + const BYTE template[] = + { + COLLECTION(1, Report), + REPORT_ID(1, report_id), + }; + + if (state->report_len) + { + ERR("input report already created\n"); + return FALSE; + } + + state->id = report_id; + state->bit_size += 8; + return hid_report_descriptor_append(desc, template, sizeof(template)); +} + +BOOL hid_device_end_input_report(struct unix_device *iface) { struct hid_report_descriptor *desc = &iface->hid_report_descriptor; struct hid_device_state *state = &iface->hid_device_state; @@ -98,6 +132,9 @@ BOOL hid_device_end_report_descriptor(struct unix_device *iface) state->report_len = (state->bit_size + 7) / 8; if (!(state->report_buf = calloc(1, state->report_len))) return FALSE; if (!(state->last_report_buf = calloc(1, state->report_len))) return FALSE; + + state->report_buf[0] = state->id; + state->last_report_buf[0] = state->id; return hid_report_descriptor_append(desc, template, sizeof(template)); }
@@ -276,31 +313,36 @@ BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usage_page return TRUE; }
-BOOL hid_device_add_haptics(struct unix_device *iface) +BOOL hid_device_add_haptics(struct unix_device *iface, BYTE *id) { struct hid_report_descriptor *desc = &iface->hid_report_descriptor; - static const BYTE template[] = + const BYTE report_id = ++desc->next_report_id[HidP_Output]; + const BYTE template[] = { USAGE_PAGE(2, HID_USAGE_PAGE_VENDOR_DEFINED_BEGIN), - USAGE(1, 0x01), - /* padding */ - REPORT_COUNT(1, 0x02), - REPORT_SIZE(1, 0x08), - OUTPUT(1, Data|Var|Abs), - /* actuators */ - LOGICAL_MINIMUM(1, 0x00), - LOGICAL_MAXIMUM(1, 0xff), - PHYSICAL_MINIMUM(1, 0x00), - PHYSICAL_MAXIMUM(1, 0xff), - REPORT_SIZE(1, 0x08), - REPORT_COUNT(1, 0x02), - OUTPUT(1, Data|Var|Abs), - /* padding */ - REPORT_COUNT(1, 0x02), - REPORT_SIZE(1, 0x08), - OUTPUT(1, Data|Var|Abs), + COLLECTION(1, Report), + REPORT_ID(1, report_id), + /* padding */ + REPORT_COUNT(1, 0x02), + REPORT_SIZE(1, 0x08), + OUTPUT(1, Data|Var|Abs), + /* actuators */ + USAGE(1, 0x01), + LOGICAL_MINIMUM(1, 0x00), + LOGICAL_MAXIMUM(1, 0xff), + PHYSICAL_MINIMUM(1, 0x00), + PHYSICAL_MAXIMUM(1, 0xff), + REPORT_SIZE(1, 0x08), + REPORT_COUNT(1, 0x02), + OUTPUT(1, Data|Var|Abs), + /* padding */ + REPORT_COUNT(1, 0x02), + REPORT_SIZE(1, 0x08), + OUTPUT(1, Data|Var|Abs), + END_COLLECTION, };
+ *id = report_id; return hid_report_descriptor_append(desc, template, sizeof(template)); }
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index 543bfda9d79..b44bf503b45 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -55,6 +55,7 @@ struct hid_report_descriptor BYTE *data; SIZE_T size; SIZE_T max_size; + BYTE next_report_id[3]; };
struct hid_device_state @@ -72,6 +73,7 @@ struct hid_device_state BYTE *report_buf; BYTE *last_report_buf; BOOL dropped; + BYTE id; };
struct unix_device @@ -111,13 +113,15 @@ extern BOOL bus_event_queue_pop(struct list *queue, struct bus_event *event) DEC extern BOOL hid_device_begin_report_descriptor(struct unix_device *iface, USAGE usage_page, USAGE usage) DECLSPEC_HIDDEN; extern BOOL hid_device_end_report_descriptor(struct unix_device *iface) DECLSPEC_HIDDEN;
+extern BOOL hid_device_begin_input_report(struct unix_device *iface) DECLSPEC_HIDDEN; +extern BOOL hid_device_end_input_report(struct unix_device *iface) DECLSPEC_HIDDEN; extern BOOL hid_device_add_buttons(struct unix_device *iface, USAGE usage_page, USAGE usage_min, USAGE usage_max) DECLSPEC_HIDDEN; extern BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count) DECLSPEC_HIDDEN; extern BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usage_page, const USAGE *usages, BOOL rel, LONG min, LONG max) DECLSPEC_HIDDEN;
-extern BOOL hid_device_add_haptics(struct unix_device *iface) DECLSPEC_HIDDEN; +extern BOOL hid_device_add_haptics(struct unix_device *iface, BYTE *id) DECLSPEC_HIDDEN;
extern BOOL hid_device_set_abs_axis(struct unix_device *iface, ULONG index, LONG value) DECLSPEC_HIDDEN; extern BOOL hid_device_set_rel_axis(struct unix_device *iface, ULONG index, LONG value) DECLSPEC_HIDDEN; diff --git a/dlls/xinput1_3/main.c b/dlls/xinput1_3/main.c index 44493ddb2a1..d601c23f6f1 100644 --- a/dlls/xinput1_3/main.c +++ b/dlls/xinput1_3/main.c @@ -233,7 +233,7 @@ static DWORD HID_set_state(struct xinput_controller *controller, XINPUT_VIBRATIO if (controller->enabled) { memset(output_report_buf, 0, output_report_len); - output_report_buf[0] = /* report id */ 0; + output_report_buf[0] = 1; output_report_buf[1] = 0x8; output_report_buf[3] = (BYTE)(state->wLeftMotorSpeed / 256); output_report_buf[4] = (BYTE)(state->wRightMotorSpeed / 256);