Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_sdl.c | 44 ++++++++----------------- dlls/winebus.sys/bus_udev.c | 58 ++++++++------------------------- dlls/winebus.sys/hid.c | 27 ++++++++++++++- dlls/winebus.sys/unix_private.h | 6 ++++ 4 files changed, 59 insertions(+), 76 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index e6b67fae3c0..6adb0fe913d 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -123,9 +123,6 @@ struct sdl_device SDL_GameController *sdl_controller; SDL_JoystickID id;
- int buffer_length; - BYTE *report_buffer; - SDL_Haptic *sdl_haptic; int haptic_effect_id; }; @@ -153,8 +150,8 @@ static void set_button_value(struct sdl_device *impl, int index, int value) int bit_index = index % 8; BYTE mask = 1 << bit_index; if (index >= state->button_count) return; - if (value) impl->report_buffer[byte_index] |= mask; - else impl->report_buffer[byte_index] &= ~mask; + if (value) state->report_buf[byte_index] |= mask; + else state->report_buf[byte_index] &= ~mask; }
static void set_axis_value(struct sdl_device *impl, int index, short value) @@ -163,7 +160,7 @@ static void set_axis_value(struct sdl_device *impl, int index, short value) USHORT offset = state->abs_axis_start; if (index >= state->abs_axis_count) return; offset += index * sizeof(DWORD); - *(DWORD *)&impl->report_buffer[offset] = LE_DWORD(value); + *(DWORD *)&state->report_buf[offset] = LE_DWORD(value); }
static void set_ball_value(struct sdl_device *impl, int index, int value1, int value2) @@ -172,8 +169,8 @@ static void set_ball_value(struct sdl_device *impl, int index, int value1, int v USHORT offset = state->rel_axis_start; if (index >= state->rel_axis_count) return; offset += index * sizeof(DWORD); - *(DWORD *)&impl->report_buffer[offset] = LE_DWORD(value1); - *(DWORD *)&impl->report_buffer[offset + sizeof(DWORD)] = LE_DWORD(value2); + *(DWORD *)&state->report_buf[offset] = LE_DWORD(value1); + *(DWORD *)&state->report_buf[offset + sizeof(DWORD)] = LE_DWORD(value2); }
static void set_hat_value(struct sdl_device *impl, int index, int value) @@ -202,7 +199,7 @@ static void set_hat_value(struct sdl_device *impl, int index, int value) default: return; }
- impl->report_buffer[offset] = val; + state->report_buf[offset] = val; }
static BOOL descriptor_add_haptic(struct sdl_device *impl) @@ -287,9 +284,6 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface) if (!hid_device_end_report_descriptor(iface)) return STATUS_NO_MEMORY;
- impl->buffer_length = iface->hid_device_state.report_len; - if (!(impl->report_buffer = calloc(1, impl->buffer_length))) goto failed; - /* Initialize axis in the report */ for (i = 0; i < axis_count; i++) set_axis_value(impl, i, pSDL_JoystickGetAxis(impl->sdl_joystick, i)); @@ -297,10 +291,6 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface) set_hat_value(impl, i, pSDL_JoystickGetHat(impl->sdl_joystick, i));
return STATUS_SUCCESS; - -failed: - free(impl->report_buffer); - return STATUS_NO_MEMORY; }
static SHORT compose_dpad_value(SDL_GameController *joystick) @@ -366,19 +356,12 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface) if (!hid_device_end_report_descriptor(iface)) return STATUS_NO_MEMORY;
- impl->buffer_length = impl->unix_device.hid_device_state.report_len; - if (!(impl->report_buffer = calloc(1, impl->buffer_length))) goto failed; - /* Initialize axis in the report */ for (i = SDL_CONTROLLER_AXIS_LEFTX; i < SDL_CONTROLLER_AXIS_MAX; i++) set_axis_value(impl, i, pSDL_GameControllerGetAxis(impl->sdl_controller, i)); set_hat_value(impl, 0, compose_dpad_value(impl->sdl_controller));
return STATUS_SUCCESS; - -failed: - free(impl->report_buffer); - return STATUS_NO_MEMORY; }
static void sdl_device_destroy(struct unix_device *iface) @@ -477,6 +460,7 @@ static const struct hid_device_vtbl sdl_device_vtbl = static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *event) { struct unix_device *iface = &impl->unix_device; + struct hid_device_state *state = &iface->hid_device_state;
if (impl->sdl_controller) return TRUE; /* use controller events instead */
@@ -488,8 +472,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e SDL_JoyButtonEvent *ie = &event->jbutton;
set_button_value(impl, ie->button, ie->state); - - bus_event_queue_input_report(&event_queue, iface, impl->report_buffer, impl->buffer_length); + bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); break; } case SDL_JOYAXISMOTION: @@ -499,7 +482,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e if (ie->axis < 6) { set_axis_value(impl, ie->axis, ie->value); - bus_event_queue_input_report(&event_queue, iface, impl->report_buffer, impl->buffer_length); + bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); } break; } @@ -508,7 +491,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e SDL_JoyBallEvent *ie = &event->jball;
set_ball_value(impl, ie->ball, ie->xrel, ie->yrel); - bus_event_queue_input_report(&event_queue, iface, impl->report_buffer, impl->buffer_length); + bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); break; } case SDL_JOYHATMOTION: @@ -516,7 +499,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e SDL_JoyHatEvent *ie = &event->jhat;
set_hat_value(impl, ie->hat, ie->value); - bus_event_queue_input_report(&event_queue, iface, impl->report_buffer, impl->buffer_length); + bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); break; } default: @@ -528,6 +511,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event *event) { struct unix_device *iface = &impl->unix_device; + struct hid_device_state *state = &iface->hid_device_state;
switch(event->type) { @@ -555,7 +539,7 @@ static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event }
set_button_value(impl, button, ie->state); - bus_event_queue_input_report(&event_queue, iface, impl->report_buffer, impl->buffer_length); + bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); break; } case SDL_CONTROLLERAXISMOTION: @@ -563,7 +547,7 @@ static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event SDL_ControllerAxisEvent *ie = &event->caxis;
set_axis_value(impl, ie->axis, ie->value); - bus_event_queue_input_report(&event_queue, iface, impl->report_buffer, impl->buffer_length); + bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); break; } default: diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 9f3b731364d..cd7eadf7ec0 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -122,11 +122,6 @@ struct lnxev_device { struct base_device base;
- int buffer_length; - BYTE *last_report_buffer; - BYTE *current_report_buffer; - enum { FIRST, NORMAL, DROPPED } report_state; - BYTE abs_map[HID_ABS_MAX]; BYTE rel_map[HID_REL_MAX]; BYTE hat_map[8]; @@ -338,8 +333,8 @@ static void set_button_value(struct lnxev_device *impl, int index, int value) int bit_index = index % 8; BYTE mask = 1 << bit_index; if (index >= state->button_count) return; - if (value) impl->current_report_buffer[byte_index] |= mask; - else impl->current_report_buffer[byte_index] &= ~mask; + if (value) state->report_buf[byte_index] |= mask; + else state->report_buf[byte_index] &= ~mask; }
static void set_abs_axis_value(struct lnxev_device *impl, int code, int value) @@ -387,7 +382,7 @@ static void set_abs_axis_value(struct lnxev_device *impl, int code, int value) offset = state->hatswitch_start; if (index >= state->hatswitch_count) return; offset += index; - impl->current_report_buffer[offset] = value; + state->report_buf[offset] = value; } else if (code < HID_ABS_MAX && ABS_TO_HID_MAP[code][0] != 0) { @@ -395,7 +390,7 @@ static void set_abs_axis_value(struct lnxev_device *impl, int code, int value) offset = state->abs_axis_start; if (index >= state->abs_axis_count) return; offset += index * sizeof(DWORD); - *(DWORD *)&impl->current_report_buffer[offset] = LE_DWORD(value); + *(DWORD *)&state->report_buf[offset] = LE_DWORD(value); } }
@@ -409,7 +404,7 @@ static void set_rel_axis_value(struct lnxev_device *impl, int code, int value) offset = state->rel_axis_start; if (index >= state->rel_axis_count) return; offset += index * sizeof(DWORD); - *(DWORD *)&impl->current_report_buffer[offset] = LE_DWORD(value); + *(DWORD *)&state->report_buf[offset] = LE_DWORD(value); } }
@@ -530,48 +525,25 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d if (!hid_device_end_report_descriptor(iface)) return STATUS_NO_MEMORY;
- impl->buffer_length = iface->hid_device_state.report_len; - if (!(impl->current_report_buffer = calloc(1, impl->buffer_length))) goto failed; - if (!(impl->last_report_buffer = calloc(1, impl->buffer_length))) goto failed; - impl->report_state = FIRST; - /* Initialize axis in the report */ for (i = 0; i < HID_ABS_MAX; i++) if (test_bit(absbits, i)) set_abs_axis_value(impl, i, abs_info[i].value);
return STATUS_SUCCESS; - -failed: - free(impl->current_report_buffer); - free(impl->last_report_buffer); - return STATUS_NO_MEMORY; }
-static BOOL set_report_from_event(struct lnxev_device *impl, struct input_event *ie) +static BOOL set_report_from_event(struct unix_device *iface, struct input_event *ie) { + struct lnxev_device *impl = lnxev_impl_from_unix_device(iface); switch(ie->type) { #ifdef EV_SYN case EV_SYN: switch (ie->code) { - case SYN_REPORT: - if (impl->report_state == NORMAL) - { - memcpy(impl->last_report_buffer, impl->current_report_buffer, impl->buffer_length); - return TRUE; - } - else - { - if (impl->report_state == DROPPED) - memcpy(impl->current_report_buffer, impl->last_report_buffer, impl->buffer_length); - impl->report_state = NORMAL; - } - break; - case SYN_DROPPED: - TRACE_(hid_report)("received SY_DROPPED\n"); - impl->report_state = DROPPED; + case SYN_REPORT: return hid_device_sync_report(iface); + case SYN_DROPPED: hid_device_drop_report(iface); break; } return FALSE; #endif @@ -785,10 +757,6 @@ static const struct raw_device_vtbl hidraw_device_vtbl = static void lnxev_device_destroy(struct unix_device *iface) { struct lnxev_device *impl = lnxev_impl_from_unix_device(iface); - - free(impl->current_report_buffer); - free(impl->last_report_buffer); - udev_device_unref(impl->base.udev_device); }
@@ -818,20 +786,20 @@ static void lnxev_device_stop(struct unix_device *iface)
static void lnxev_device_read_report(struct unix_device *iface) { + struct hid_device_state *state = &iface->hid_device_state; struct lnxev_device *impl = lnxev_impl_from_unix_device(iface); struct input_event ie; int size;
- if (!impl->current_report_buffer || impl->buffer_length == 0) - return; + if (!state->report_buf || !state->report_len) return;
size = read(impl->base.device_fd, &ie, sizeof(ie)); if (size == -1) TRACE_(hid_report)("Read failed. Likely an unplugged device\n"); else if (size == 0) TRACE_(hid_report)("Failed to read report\n"); - else if (set_report_from_event(impl, &ie)) - bus_event_queue_input_report(&event_queue, iface, impl->current_report_buffer, impl->buffer_length); + else if (set_report_from_event(iface, &ie)) + bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); }
static void lnxev_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index acf0c52cfa8..ba49c010532 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -89,12 +89,15 @@ 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; + struct hid_device_state *state = &iface->hid_device_state; static const BYTE template[] = { END_COLLECTION, };
- iface->hid_device_state.report_len = (iface->hid_device_state.bit_size + 7) / 8; + 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; return hid_report_descriptor_append(desc, template, sizeof(template)); }
@@ -307,6 +310,8 @@ static void hid_device_destroy(struct unix_device *iface) { iface->hid_vtbl->destroy(iface); free(iface->hid_report_descriptor.data); + free(iface->hid_device_state.report_buf); + free(iface->hid_device_state.last_report_buf); }
static NTSTATUS hid_device_start(struct unix_device *iface) @@ -363,3 +368,23 @@ void *hid_device_create(const struct hid_device_vtbl *vtbl, SIZE_T size)
return impl; } + +BOOL hid_device_sync_report(struct unix_device *iface) +{ + BOOL dropped; + + if (!(dropped = iface->hid_device_state.dropped)) + memcpy(iface->hid_device_state.last_report_buf, iface->hid_device_state.report_buf, + iface->hid_device_state.report_len); + else + memcpy(iface->hid_device_state.report_buf, iface->hid_device_state.last_report_buf, + iface->hid_device_state.report_len); + iface->hid_device_state.dropped = FALSE; + + return !dropped; +} + +void hid_device_drop_report(struct unix_device *iface) +{ + iface->hid_device_state.dropped = TRUE; +} diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index ec0568faa6f..dbec779c67e 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -69,6 +69,9 @@ struct hid_device_state USHORT button_start; USHORT button_count; USHORT report_len; + BYTE *report_buf; + BYTE *last_report_buf; + BOOL dropped; };
struct unix_device @@ -116,6 +119,9 @@ extern BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usa
extern BOOL hid_device_add_haptics(struct unix_device *iface) DECLSPEC_HIDDEN;
+extern BOOL hid_device_sync_report(struct unix_device *iface) DECLSPEC_HIDDEN; +extern void hid_device_drop_report(struct unix_device *iface) DECLSPEC_HIDDEN; + BOOL is_xbox_gamepad(WORD vid, WORD pid) DECLSPEC_HIDDEN;
#endif /* __WINEBUS_UNIX_PRIVATE_H */
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_sdl.c | 141 ++++++++--------------------- dlls/winebus.sys/bus_udev.c | 154 +++++++++----------------------- dlls/winebus.sys/hid.c | 87 ++++++++++++++++++ dlls/winebus.sys/unix_private.h | 6 ++ 4 files changed, 172 insertions(+), 216 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 6adb0fe913d..7af5f13bcee 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -50,12 +50,6 @@ #include "wine/unicode.h" #include "hidusage.h"
-#ifdef WORDS_BIGENDIAN -# define LE_DWORD(x) RtlUlongByteSwap(x) -#else -# define LE_DWORD(x) (x) -#endif - #include "unix_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay); @@ -142,64 +136,23 @@ static struct sdl_device *find_device_from_id(SDL_JoystickID id) return NULL; }
-static void set_button_value(struct sdl_device *impl, int index, int value) -{ - struct hid_device_state *state = &impl->unix_device.hid_device_state; - USHORT offset = state->button_start; - int byte_index = offset + index / 8; - int bit_index = index % 8; - BYTE mask = 1 << bit_index; - if (index >= state->button_count) return; - if (value) state->report_buf[byte_index] |= mask; - else state->report_buf[byte_index] &= ~mask; -} - -static void set_axis_value(struct sdl_device *impl, int index, short value) +static void set_hat_value(struct unix_device *iface, int index, int value) { - struct hid_device_state *state = &impl->unix_device.hid_device_state; - USHORT offset = state->abs_axis_start; - if (index >= state->abs_axis_count) return; - offset += index * sizeof(DWORD); - *(DWORD *)&state->report_buf[offset] = LE_DWORD(value); -} - -static void set_ball_value(struct sdl_device *impl, int index, int value1, int value2) -{ - struct hid_device_state *state = &impl->unix_device.hid_device_state; - USHORT offset = state->rel_axis_start; - if (index >= state->rel_axis_count) return; - offset += index * sizeof(DWORD); - *(DWORD *)&state->report_buf[offset] = LE_DWORD(value1); - *(DWORD *)&state->report_buf[offset + sizeof(DWORD)] = LE_DWORD(value2); -} - -static void set_hat_value(struct sdl_device *impl, int index, int value) -{ - struct hid_device_state *state = &impl->unix_device.hid_device_state; - USHORT offset = state->hatswitch_start; - unsigned char val; - - if (index >= state->hatswitch_count) return; - offset += index; - + LONG x = 0, y = 0; switch (value) { - /* 8 1 2 - * 7 0 3 - * 6 5 4 */ - case SDL_HAT_CENTERED: val = 0; break; - case SDL_HAT_UP: val = 1; break; - case SDL_HAT_RIGHTUP: val = 2; break; - case SDL_HAT_RIGHT: val = 3; break; - case SDL_HAT_RIGHTDOWN: val = 4; break; - case SDL_HAT_DOWN: val = 5; break; - case SDL_HAT_LEFTDOWN: val = 6; break; - case SDL_HAT_LEFT: val = 7; break; - case SDL_HAT_LEFTUP: val = 8; break; - default: return; + case SDL_HAT_CENTERED: break; + case SDL_HAT_UP: y = 1; break; + case SDL_HAT_RIGHTUP: y = x = 1; break; + case SDL_HAT_RIGHT: x = 1; break; + case SDL_HAT_RIGHTDOWN: x = 1; y = -1; break; + case SDL_HAT_DOWN: y = -1; break; + case SDL_HAT_LEFTDOWN: x = y = -1; break; + case SDL_HAT_LEFT: x = -1; break; + case SDL_HAT_LEFTUP: x = -1; y = 1; break; } - - state->report_buf[offset] = val; + hid_device_set_hatswitch_x(iface, index, x); + hid_device_set_hatswitch_y(iface, index, y); }
static BOOL descriptor_add_haptic(struct sdl_device *impl) @@ -286,40 +239,13 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
/* Initialize axis in the report */ for (i = 0; i < axis_count; i++) - set_axis_value(impl, i, pSDL_JoystickGetAxis(impl->sdl_joystick, i)); + hid_device_set_abs_axis(iface, i, pSDL_JoystickGetAxis(impl->sdl_joystick, i)); for (i = 0; i < hat_count; i++) - set_hat_value(impl, i, pSDL_JoystickGetHat(impl->sdl_joystick, i)); + set_hat_value(iface, i, pSDL_JoystickGetHat(impl->sdl_joystick, i));
return STATUS_SUCCESS; }
-static SHORT compose_dpad_value(SDL_GameController *joystick) -{ - if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP)) - { - if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) - return SDL_HAT_RIGHTUP; - if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT)) - return SDL_HAT_LEFTUP; - return SDL_HAT_UP; - } - - if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN)) - { - if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) - return SDL_HAT_RIGHTDOWN; - if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT)) - return SDL_HAT_LEFTDOWN; - return SDL_HAT_DOWN; - } - - if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) - return SDL_HAT_RIGHT; - if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT)) - return SDL_HAT_LEFT; - return SDL_HAT_CENTERED; -} - static NTSTATUS build_controller_report_descriptor(struct unix_device *iface) { static const USAGE left_axis_usages[] = {HID_USAGE_GENERIC_X, HID_USAGE_GENERIC_Y}; @@ -358,8 +284,15 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface)
/* Initialize axis in the report */ for (i = SDL_CONTROLLER_AXIS_LEFTX; i < SDL_CONTROLLER_AXIS_MAX; i++) - set_axis_value(impl, i, pSDL_GameControllerGetAxis(impl->sdl_controller, i)); - set_hat_value(impl, 0, compose_dpad_value(impl->sdl_controller)); + hid_device_set_abs_axis(iface, i, pSDL_GameControllerGetAxis(impl->sdl_controller, i)); + if (pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_UP)) + hid_device_set_hatswitch_y(iface, 0, -1); + if (pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN)) + hid_device_set_hatswitch_y(iface, 0, +1); + if (pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT)) + hid_device_set_hatswitch_x(iface, 0, -1); + if (pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) + hid_device_set_hatswitch_x(iface, 0, +1);
return STATUS_SUCCESS; } @@ -471,7 +404,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e { SDL_JoyButtonEvent *ie = &event->jbutton;
- set_button_value(impl, ie->button, ie->state); + hid_device_set_button(iface, ie->button, ie->state); bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); break; } @@ -479,18 +412,16 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e { SDL_JoyAxisEvent *ie = &event->jaxis;
- if (ie->axis < 6) - { - set_axis_value(impl, ie->axis, ie->value); - bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); - } + hid_device_set_abs_axis(iface, ie->axis, ie->value); + bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); break; } case SDL_JOYBALLMOTION: { SDL_JoyBallEvent *ie = &event->jball;
- set_ball_value(impl, ie->ball, ie->xrel, ie->yrel); + hid_device_set_rel_axis(iface, 2 * ie->ball, ie->xrel); + hid_device_set_rel_axis(iface, 2 * ie->ball + 1, ie->yrel); bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); break; } @@ -498,7 +429,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e { SDL_JoyHatEvent *ie = &event->jhat;
- set_hat_value(impl, ie->hat, ie->value); + set_hat_value(iface, ie->hat, ie->value); bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); break; } @@ -524,10 +455,16 @@ static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event switch ((button = ie->button)) { case SDL_CONTROLLER_BUTTON_DPAD_UP: + hid_device_set_hatswitch_y(iface, 0, ie->state ? -1 : 0); + break; case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + hid_device_set_hatswitch_y(iface, 0, ie->state ? +1 : 0); + break; case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + hid_device_set_hatswitch_x(iface, 0, ie->state ? -1 : 0); + break; case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: - set_hat_value(impl, 0, compose_dpad_value(impl->sdl_controller)); + hid_device_set_hatswitch_x(iface, 0, ie->state ? +1 : 0); break; case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: button = 4; break; case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: button = 5; break; @@ -538,7 +475,7 @@ static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event case SDL_CONTROLLER_BUTTON_GUIDE: button = 10; break; }
- set_button_value(impl, button, ie->state); + hid_device_set_button(iface, button, ie->state); bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); break; } @@ -546,7 +483,7 @@ static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event { SDL_ControllerAxisEvent *ie = &event->caxis;
- set_axis_value(impl, ie->axis, ie->value); + hid_device_set_abs_axis(iface, ie->axis, ie->value); 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 cd7eadf7ec0..f4d27090109 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -126,7 +126,6 @@ struct lnxev_device BYTE rel_map[HID_REL_MAX]; BYTE hat_map[8]; BYTE button_map[KEY_MAX]; - int hat_values[8]; };
static inline struct base_device *impl_from_unix_device(struct unix_device *iface) @@ -325,89 +324,6 @@ static const BYTE* what_am_I(struct udev_device *dev) return Unknown; }
-static void set_button_value(struct lnxev_device *impl, int index, int value) -{ - struct hid_device_state *state = &impl->base.unix_device.hid_device_state; - USHORT offset = state->button_start; - int byte_index = offset + index / 8; - int bit_index = index % 8; - BYTE mask = 1 << bit_index; - if (index >= state->button_count) return; - if (value) state->report_buf[byte_index] |= mask; - else state->report_buf[byte_index] &= ~mask; -} - -static void set_abs_axis_value(struct lnxev_device *impl, int code, int value) -{ - struct hid_device_state *state = &impl->base.unix_device.hid_device_state; - USHORT offset, index; - /* check for hatswitches */ - if (code <= ABS_HAT3Y && code >= ABS_HAT0X) - { - index = code - ABS_HAT0X; - impl->hat_values[index] = value; - if ((code - ABS_HAT0X) % 2) - index--; - /* 8 1 2 - * 7 0 3 - * 6 5 4 */ - if (impl->hat_values[index] == 0) - { - if (impl->hat_values[index+1] == 0) - value = 0; - else if (impl->hat_values[index+1] < 0) - value = 1; - else - value = 5; - } - else if (impl->hat_values[index] > 0) - { - if (impl->hat_values[index+1] == 0) - value = 3; - else if (impl->hat_values[index+1] < 0) - value = 2; - else - value = 4; - } - else - { - if (impl->hat_values[index+1] == 0) - value = 7; - else if (impl->hat_values[index+1] < 0) - value = 8; - else - value = 6; - } - index = impl->hat_map[index]; - offset = state->hatswitch_start; - if (index >= state->hatswitch_count) return; - offset += index; - state->report_buf[offset] = value; - } - else if (code < HID_ABS_MAX && ABS_TO_HID_MAP[code][0] != 0) - { - index = impl->abs_map[code]; - offset = state->abs_axis_start; - if (index >= state->abs_axis_count) return; - offset += index * sizeof(DWORD); - *(DWORD *)&state->report_buf[offset] = LE_DWORD(value); - } -} - -static void set_rel_axis_value(struct lnxev_device *impl, int code, int value) -{ - struct hid_device_state *state = &impl->base.unix_device.hid_device_state; - USHORT offset, index; - if (code < HID_REL_MAX && REL_TO_HID_MAP[code][0] != 0) - { - index = impl->rel_map[code]; - offset = state->rel_axis_start; - if (index >= state->rel_axis_count) return; - offset += index * sizeof(DWORD); - *(DWORD *)&state->report_buf[offset] = LE_DWORD(value); - } -} - static INT count_buttons(int device_fd, BYTE *map) { int i; @@ -506,12 +422,11 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d }
hat_count = 0; - for (i = ABS_HAT0X; i <=ABS_HAT3X; i+=2) + for (i = ABS_HAT0X; i <= ABS_HAT3X; i += 2) { if (!test_bit(absbits, i)) continue; - impl->hat_map[i - ABS_HAT0X] = hat_count++; - impl->hat_values[i - ABS_HAT0X] = 0; - impl->hat_values[i - ABS_HAT0X + 1] = 0; + impl->hat_map[i - ABS_HAT0X] = hat_count; + impl->hat_map[i - ABS_HAT0X + 1] = hat_count++; }
if (hat_count && !hid_device_add_hatswitch(iface, hat_count)) @@ -527,8 +442,15 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
/* Initialize axis in the report */ for (i = 0; i < HID_ABS_MAX; i++) - if (test_bit(absbits, i)) - set_abs_axis_value(impl, i, abs_info[i].value); + { + if (!test_bit(absbits, i)) continue; + if (i < ABS_HAT0X || i > ABS_HAT3Y) + hid_device_set_abs_axis(iface, impl->abs_map[i], abs_info[i].value); + else if ((i - ABS_HAT0X) % 2) + hid_device_set_hatswitch_y(iface, impl->hat_map[i - ABS_HAT0X], abs_info[i].value); + else + hid_device_set_hatswitch_x(iface, impl->hat_map[i - ABS_HAT0X], abs_info[i].value); + }
return STATUS_SUCCESS; } @@ -536,33 +458,39 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d static BOOL set_report_from_event(struct unix_device *iface, struct input_event *ie) { struct lnxev_device *impl = lnxev_impl_from_unix_device(iface); - switch(ie->type) + + switch (ie->type) { #ifdef EV_SYN - case EV_SYN: - switch (ie->code) - { - case SYN_REPORT: return hid_device_sync_report(iface); - case SYN_DROPPED: hid_device_drop_report(iface); break; - } - return FALSE; + case EV_SYN: + switch (ie->code) + { + case SYN_REPORT: return hid_device_sync_report(iface); + case SYN_DROPPED: hid_device_drop_report(iface); break; + } + return FALSE; #endif #ifdef EV_MSC - case EV_MSC: - return FALSE; + case EV_MSC: + return FALSE; #endif - case EV_KEY: - set_button_value(impl, impl->button_map[ie->code], ie->value); - return FALSE; - case EV_ABS: - set_abs_axis_value(impl, ie->code, ie->value); - return FALSE; - case EV_REL: - set_rel_axis_value(impl, ie->code, ie->value); - return FALSE; - default: - ERR("TODO: Process Report (%i, %i)\n",ie->type, ie->code); - return FALSE; + case EV_KEY: + hid_device_set_button(iface, impl->button_map[ie->code], ie->value); + return FALSE; + case EV_ABS: + if (ie->code < ABS_HAT0X || ie->code > ABS_HAT3Y) + hid_device_set_abs_axis(iface, impl->abs_map[ie->code], ie->value); + else if ((ie->code - ABS_HAT0X) % 2) + hid_device_set_hatswitch_y(iface, impl->hat_map[ie->code - ABS_HAT0X], ie->value); + else + hid_device_set_hatswitch_x(iface, impl->hat_map[ie->code - ABS_HAT0X], ie->value); + return FALSE; + case EV_REL: + hid_device_set_rel_axis(iface, impl->rel_map[ie->code], ie->value); + return FALSE; + default: + ERR("TODO: Process Report (%i, %i)\n",ie->type, ie->code); + return FALSE; } } #endif @@ -791,8 +719,6 @@ static void lnxev_device_read_report(struct unix_device *iface) struct input_event ie; int size;
- if (!state->report_buf || !state->report_len) return; - size = read(impl->base.device_fd, &ie, sizeof(ie)); if (size == -1) TRACE_(hid_report)("Read failed. Likely an unplugged device\n"); diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index ba49c010532..4a4295b9aa8 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -369,6 +369,93 @@ void *hid_device_create(const struct hid_device_vtbl *vtbl, SIZE_T size) return impl; }
+#ifdef WORDS_BIGENDIAN +# define LE_ULONG(x) RtlUlongByteSwap((ULONG)(x)) +#else +# define LE_ULONG(x) ((ULONG)(x)) +#endif + +BOOL hid_device_set_abs_axis(struct unix_device *iface, ULONG index, LONG value) +{ + struct hid_device_state *state = &iface->hid_device_state; + ULONG offset = state->abs_axis_start + index * 4; + if (index > state->abs_axis_count) return FALSE; + *(ULONG *)(state->report_buf + offset) = LE_ULONG(value); + return TRUE; +} + +BOOL hid_device_set_rel_axis(struct unix_device *iface, ULONG index, LONG value) +{ + struct hid_device_state *state = &iface->hid_device_state; + ULONG offset = state->rel_axis_start + index * 4; + if (index > state->rel_axis_count) return FALSE; + *(ULONG *)(state->report_buf + offset) = LE_ULONG(value); + return TRUE; +} + +BOOL hid_device_set_button(struct unix_device *iface, ULONG index, BOOL is_set) +{ + struct hid_device_state *state = &iface->hid_device_state; + ULONG offset = state->button_start + (index / 8); + BYTE mask = (1 << (index % 8)); + if (index > state->button_count) return FALSE; + if (is_set) state->report_buf[offset] |= mask; + else state->report_buf[offset] &= ~mask; + return TRUE; +} + +/* hatswitch x / y vs value: + * -1 x +1 + * +--------> + * -1 | 8 1 2 + * y | 7 0 3 + * +1 | 6 5 4 + * v + */ +static void hatswitch_decompose(BYTE value, LONG *x, LONG *y) +{ + *x = *y = 0; + if (value == 8 || value == 1 || value == 2) *y = -1; + if (value == 6 || value == 5 || value == 4) *y = +1; + if (value == 8 || value == 7 || value == 6) *x = -1; + if (value == 2 || value == 3 || value == 4) *x = +1; +} + +static void hatswitch_compose(LONG x, LONG y, BYTE *value) +{ + if (x == 0 && y == 0) *value = 0; + else if (x == 0 && y < 0) *value = 1; + else if (x > 0 && y < 0) *value = 2; + else if (x > 0 && y == 0) *value = 3; + else if (x > 0 && y > 0) *value = 4; + else if (x == 0 && y > 0) *value = 5; + else if (x < 0 && y > 0) *value = 6; + else if (x < 0 && y == 0) *value = 7; + else if (x < 0 && y < 0) *value = 8; +} + +BOOL hid_device_set_hatswitch_x(struct unix_device *iface, ULONG index, LONG new_x) +{ + struct hid_device_state *state = &iface->hid_device_state; + ULONG offset = state->hatswitch_start + index; + LONG x, y; + if (index > state->hatswitch_count) return FALSE; + hatswitch_decompose(state->report_buf[offset], &x, &y); + hatswitch_compose(new_x, y, &state->report_buf[offset]); + return TRUE; +} + +BOOL hid_device_set_hatswitch_y(struct unix_device *iface, ULONG index, LONG new_y) +{ + struct hid_device_state *state = &iface->hid_device_state; + ULONG offset = state->hatswitch_start + index; + LONG x, y; + if (index > state->hatswitch_count) return FALSE; + hatswitch_decompose(state->report_buf[offset], &x, &y); + hatswitch_compose(x, new_y, &state->report_buf[offset]); + return TRUE; +} + BOOL hid_device_sync_report(struct unix_device *iface) { BOOL dropped; diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index dbec779c67e..543bfda9d79 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -119,6 +119,12 @@ extern BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usa
extern BOOL hid_device_add_haptics(struct unix_device *iface) 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; +extern BOOL hid_device_set_button(struct unix_device *iface, ULONG index, BOOL is_set) DECLSPEC_HIDDEN; +extern BOOL hid_device_set_hatswitch_x(struct unix_device *iface, ULONG index, LONG new_x) DECLSPEC_HIDDEN; +extern BOOL hid_device_set_hatswitch_y(struct unix_device *iface, ULONG index, LONG new_y) DECLSPEC_HIDDEN; + extern BOOL hid_device_sync_report(struct unix_device *iface) DECLSPEC_HIDDEN; extern void hid_device_drop_report(struct unix_device *iface) DECLSPEC_HIDDEN;
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);
Some devices, such as the DualShock 4 only have support for haptics through the SDL_JoystickRumble API. Let's use it as a fallback if none of the more detailed API are supported.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_sdl.c | 108 +++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 45 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 72cdf8ae605..c6d58635382 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -102,6 +102,7 @@ MAKE_FUNCPTR(SDL_HapticRumbleSupported); MAKE_FUNCPTR(SDL_HapticRunEffect); MAKE_FUNCPTR(SDL_HapticStopAll); MAKE_FUNCPTR(SDL_JoystickIsHaptic); +MAKE_FUNCPTR(SDL_JoystickRumble); MAKE_FUNCPTR(SDL_memset); MAKE_FUNCPTR(SDL_GameControllerAddMapping); MAKE_FUNCPTR(SDL_RegisterEvents); @@ -110,6 +111,12 @@ static Uint16 (*pSDL_JoystickGetProduct)(SDL_Joystick * joystick); static Uint16 (*pSDL_JoystickGetProductVersion)(SDL_Joystick * joystick); static Uint16 (*pSDL_JoystickGetVendor)(SDL_Joystick * joystick);
+/* internal bits for extended rumble support, SDL_Haptic types are 16-bits */ +#define WINE_SDL_JOYSTICK_RUMBLE 0x40000000 /* using SDL_JoystickRumble API */ +#define WINE_SDL_HAPTIC_RUMBLE 0x80000000 /* using SDL_HapticRumble API */ + +#define EFFECT_SUPPORT_HAPTICS (SDL_HAPTIC_LEFTRIGHT|WINE_SDL_HAPTIC_RUMBLE|WINE_SDL_JOYSTICK_RUMBLE) + struct sdl_device { struct unix_device unix_device; @@ -118,6 +125,7 @@ struct sdl_device SDL_GameController *sdl_controller; SDL_JoystickID id;
+ DWORD effect_support; SDL_Haptic *sdl_haptic; int haptic_effect_id; BYTE vendor_rumble_report_id; @@ -159,26 +167,31 @@ static void set_hat_value(struct unix_device *iface, int index, int value)
static BOOL descriptor_add_haptic(struct sdl_device *impl) { - if (pSDL_JoystickIsHaptic(impl->sdl_joystick)) + unsigned int haptics_mask = SDL_HAPTIC_LEFTRIGHT; + + if (!pSDL_JoystickIsHaptic(impl->sdl_joystick) || + !(impl->sdl_haptic = pSDL_HapticOpenFromJoystick(impl->sdl_joystick))) + impl->effect_support = 0; + else { - impl->sdl_haptic = pSDL_HapticOpenFromJoystick(impl->sdl_joystick); - if (impl->sdl_haptic && - ((pSDL_HapticQuery(impl->sdl_haptic) & SDL_HAPTIC_LEFTRIGHT) != 0 || - pSDL_HapticRumbleSupported(impl->sdl_haptic))) - { - pSDL_HapticStopAll(impl->sdl_haptic); - pSDL_HapticRumbleInit(impl->sdl_haptic); - if (!hid_device_add_haptics(&impl->unix_device, &impl->vendor_rumble_report_id)) - return FALSE; - impl->haptic_effect_id = -1; - } - else - { - pSDL_HapticClose(impl->sdl_haptic); - impl->sdl_haptic = NULL; - } + impl->effect_support = pSDL_HapticQuery(impl->sdl_haptic) & haptics_mask; + if (pSDL_HapticRumbleSupported(impl->sdl_haptic)) + impl->effect_support |= WINE_SDL_HAPTIC_RUMBLE; + + pSDL_HapticStopAll(impl->sdl_haptic); + pSDL_HapticRumbleInit(impl->sdl_haptic); }
+ if (!pSDL_JoystickRumble(impl->sdl_joystick, 0, 0, 0)) + impl->effect_support |= WINE_SDL_JOYSTICK_RUMBLE; + + if (impl->effect_support & EFFECT_SUPPORT_HAPTICS) + { + if (!hid_device_add_haptics(&impl->unix_device, &impl->vendor_rumble_report_id)) + return FALSE; + } + + impl->haptic_effect_id = -1; return TRUE; }
@@ -338,39 +351,18 @@ static void sdl_device_stop(struct unix_device *iface) static void sdl_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) { struct sdl_device *impl = impl_from_unix_device(iface); + SDL_HapticEffect effect;
- if (impl->sdl_haptic && packet->reportId == impl->vendor_rumble_report_id) + if (packet->reportId == impl->vendor_rumble_report_id) { WORD left = packet->reportBuffer[2] * 128; WORD right = packet->reportBuffer[3] * 128;
- if (impl->haptic_effect_id >= 0) - { - pSDL_HapticDestroyEffect(impl->sdl_haptic, impl->haptic_effect_id); - impl->haptic_effect_id = -1; - } - pSDL_HapticStopAll(impl->sdl_haptic); - if (left != 0 || right != 0) - { - SDL_HapticEffect effect; - - pSDL_memset( &effect, 0, sizeof(SDL_HapticEffect) ); - effect.type = SDL_HAPTIC_LEFTRIGHT; - effect.leftright.length = -1; - effect.leftright.large_magnitude = left; - effect.leftright.small_magnitude = right; - - impl->haptic_effect_id = pSDL_HapticNewEffect(impl->sdl_haptic, &effect); - if (impl->haptic_effect_id >= 0) - { - pSDL_HapticRunEffect(impl->sdl_haptic, impl->haptic_effect_id, 1); - } - else - { - float i = (float)((left + right)/2.0) / 32767.0; - pSDL_HapticRumblePlay(impl->sdl_haptic, i, -1); - } - } + pSDL_memset(&effect, 0, sizeof(SDL_HapticEffect)); + effect.type = SDL_HAPTIC_LEFTRIGHT; + effect.leftright.length = -1; + effect.leftright.large_magnitude = left; + effect.leftright.small_magnitude = right;
io->Information = packet->reportBufferLen; io->Status = STATUS_SUCCESS; @@ -379,6 +371,31 @@ static void sdl_device_set_output_report(struct unix_device *iface, HID_XFER_PAC { io->Information = 0; io->Status = STATUS_NOT_IMPLEMENTED; + return; + } + + if (impl->sdl_haptic) pSDL_HapticStopAll(impl->sdl_haptic); + if (impl->effect_support & WINE_SDL_JOYSTICK_RUMBLE) + pSDL_JoystickRumble(impl->sdl_joystick, 0, 0, 0); + if (!effect.leftright.large_magnitude && !effect.leftright.small_magnitude) return; + + if (impl->effect_support & SDL_HAPTIC_LEFTRIGHT) + { + if (impl->haptic_effect_id >= 0) + pSDL_HapticDestroyEffect(impl->sdl_haptic, impl->haptic_effect_id); + impl->haptic_effect_id = pSDL_HapticNewEffect(impl->sdl_haptic, &effect); + if (impl->haptic_effect_id >= 0) + pSDL_HapticRunEffect(impl->sdl_haptic, impl->haptic_effect_id, 1); + } + else if (impl->effect_support & WINE_SDL_HAPTIC_RUMBLE) + { + float magnitude = (effect.leftright.large_magnitude + effect.leftright.small_magnitude) / 2.0 / 32767.0; + pSDL_HapticRumblePlay(impl->sdl_haptic, magnitude, effect.leftright.length); + } + else if (impl->effect_support & WINE_SDL_JOYSTICK_RUMBLE) + { + pSDL_JoystickRumble(impl->sdl_joystick, effect.leftright.large_magnitude, + effect.leftright.small_magnitude, -1); } }
@@ -662,6 +679,7 @@ NTSTATUS sdl_bus_init(void *args) LOAD_FUNCPTR(SDL_HapticRunEffect); LOAD_FUNCPTR(SDL_HapticStopAll); LOAD_FUNCPTR(SDL_JoystickIsHaptic); + LOAD_FUNCPTR(SDL_JoystickRumble); LOAD_FUNCPTR(SDL_memset); LOAD_FUNCPTR(SDL_GameControllerAddMapping); LOAD_FUNCPTR(SDL_RegisterEvents);
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_sdl.c | 51 ++++++++++---------------------- dlls/winebus.sys/bus_udev.c | 23 ++++----------- dlls/winebus.sys/hid.c | 25 ++++++++++++---- dlls/winebus.sys/unix_private.h | 13 ++++++--- dlls/winebus.sys/unixlib.c | 52 +++++---------------------------- 5 files changed, 58 insertions(+), 106 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index c6d58635382..31915a9fa0d 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -128,7 +128,6 @@ struct sdl_device DWORD effect_support; 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) @@ -187,7 +186,7 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl)
if (impl->effect_support & EFFECT_SUPPORT_HAPTICS) { - if (!hid_device_add_haptics(&impl->unix_device, &impl->vendor_rumble_report_id)) + if (!hid_device_add_haptics(&impl->unix_device)) return FALSE; }
@@ -348,36 +347,28 @@ static void sdl_device_stop(struct unix_device *iface) pthread_mutex_unlock(&sdl_cs); }
-static void sdl_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) +NTSTATUS sdl_device_haptics_start(struct unix_device *iface, DWORD duration_ms, + USHORT rumble_intensity, USHORT buzz_intensity) { struct sdl_device *impl = impl_from_unix_device(iface); SDL_HapticEffect effect;
- if (packet->reportId == impl->vendor_rumble_report_id) - { - WORD left = packet->reportBuffer[2] * 128; - WORD right = packet->reportBuffer[3] * 128; + TRACE("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u.\n", iface, duration_ms, + rumble_intensity, buzz_intensity);
- pSDL_memset(&effect, 0, sizeof(SDL_HapticEffect)); - effect.type = SDL_HAPTIC_LEFTRIGHT; - effect.leftright.length = -1; - effect.leftright.large_magnitude = left; - effect.leftright.small_magnitude = right; + if (!(impl->effect_support & EFFECT_SUPPORT_HAPTICS)) return STATUS_NOT_SUPPORTED;
- io->Information = packet->reportBufferLen; - io->Status = STATUS_SUCCESS; - } - else - { - io->Information = 0; - io->Status = STATUS_NOT_IMPLEMENTED; - return; - } + memset(&effect, 0, sizeof(SDL_HapticEffect)); + effect.type = SDL_HAPTIC_LEFTRIGHT; + effect.leftright.length = duration_ms; + effect.leftright.large_magnitude = rumble_intensity; + effect.leftright.small_magnitude = buzz_intensity;
if (impl->sdl_haptic) pSDL_HapticStopAll(impl->sdl_haptic); if (impl->effect_support & WINE_SDL_JOYSTICK_RUMBLE) pSDL_JoystickRumble(impl->sdl_joystick, 0, 0, 0); - if (!effect.leftright.large_magnitude && !effect.leftright.small_magnitude) return; + if (!effect.leftright.large_magnitude && !effect.leftright.small_magnitude) + return STATUS_SUCCESS;
if (impl->effect_support & SDL_HAPTIC_LEFTRIGHT) { @@ -397,18 +388,8 @@ static void sdl_device_set_output_report(struct unix_device *iface, HID_XFER_PAC pSDL_JoystickRumble(impl->sdl_joystick, effect.leftright.large_magnitude, effect.leftright.small_magnitude, -1); } -} - -static void sdl_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) -{ - io->Information = 0; - io->Status = STATUS_NOT_IMPLEMENTED; -}
-static void sdl_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) -{ - io->Information = 0; - io->Status = STATUS_NOT_IMPLEMENTED; + return STATUS_SUCCESS; }
static const struct hid_device_vtbl sdl_device_vtbl = @@ -416,9 +397,7 @@ static const struct hid_device_vtbl sdl_device_vtbl = sdl_device_destroy, sdl_device_start, sdl_device_stop, - sdl_device_set_output_report, - sdl_device_get_feature_report, - sdl_device_set_feature_report, + sdl_device_haptics_start, };
static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *event) diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 508614d2c04..8bc9b4bf64d 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -734,22 +734,13 @@ static void lnxev_device_read_report(struct unix_device *iface) bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len); }
-static void lnxev_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) +static NTSTATUS lnxev_device_haptics_start(struct unix_device *iface, DWORD duration_ms, + USHORT rumble_intensity, USHORT buzz_intensity) { - io->Information = 0; - io->Status = STATUS_NOT_IMPLEMENTED; -} - -static void lnxev_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) -{ - io->Information = 0; - io->Status = STATUS_NOT_IMPLEMENTED; -} + FIXME("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u stub!\n", iface, + duration_ms, rumble_intensity, buzz_intensity);
-static void lnxev_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) -{ - io->Information = 0; - io->Status = STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; }
static const struct hid_device_vtbl lnxev_device_vtbl = @@ -757,9 +748,7 @@ static const struct hid_device_vtbl lnxev_device_vtbl = lnxev_device_destroy, lnxev_device_start, lnxev_device_stop, - lnxev_device_set_output_report, - lnxev_device_get_feature_report, - lnxev_device_set_feature_report, + lnxev_device_haptics_start, }; #endif
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index 92d572355c2..c1dd75f77c4 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -313,7 +313,7 @@ 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, BYTE *id) +BOOL hid_device_add_haptics(struct unix_device *iface) { struct hid_report_descriptor *desc = &iface->hid_report_descriptor; const BYTE report_id = ++desc->next_report_id[HidP_Output]; @@ -342,7 +342,7 @@ BOOL hid_device_add_haptics(struct unix_device *iface, BYTE *id) END_COLLECTION, };
- *id = report_id; + iface->hid_haptics.vendor_report = report_id; return hid_report_descriptor_append(desc, template, sizeof(template)); }
@@ -377,17 +377,32 @@ NTSTATUS hid_device_get_report_descriptor(struct unix_device *iface, BYTE *buffe
static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) { - return iface->hid_vtbl->set_output_report(iface, packet, io); + struct hid_haptics *haptics = &iface->hid_haptics; + if (packet->reportId == haptics->vendor_report) + { + WORD left = packet->reportBuffer[2] * 128; + WORD right = packet->reportBuffer[3] * 128; + + io->Information = packet->reportBufferLen; + io->Status = iface->hid_vtbl->haptics_start(iface, -1, left, right); + } + else + { + io->Information = 0; + io->Status = STATUS_NOT_IMPLEMENTED; + } }
static void hid_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) { - return iface->hid_vtbl->get_feature_report(iface, packet, io); + io->Information = 0; + io->Status = STATUS_NOT_IMPLEMENTED; }
static void hid_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) { - return iface->hid_vtbl->set_feature_report(iface, packet, io); + io->Information = 0; + io->Status = STATUS_NOT_IMPLEMENTED; }
static const struct raw_device_vtbl raw_device_vtbl = diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index b44bf503b45..9684ac47067 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -45,9 +45,8 @@ struct hid_device_vtbl void (*destroy)(struct unix_device *iface); NTSTATUS (*start)(struct unix_device *iface); void (*stop)(struct unix_device *iface); - void (*set_output_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io); - void (*get_feature_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io); - void (*set_feature_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io); + NTSTATUS (*haptics_start)(struct unix_device *iface, DWORD duration_ms, + USHORT rumble_intensity, USHORT buzz_intensity); };
struct hid_report_descriptor @@ -58,6 +57,11 @@ struct hid_report_descriptor BYTE next_report_id[3]; };
+struct hid_haptics +{ + BYTE vendor_report; +}; + struct hid_device_state { ULONG bit_size; @@ -85,6 +89,7 @@ struct unix_device const struct hid_device_vtbl *hid_vtbl; struct hid_report_descriptor hid_report_descriptor; struct hid_device_state hid_device_state; + struct hid_haptics hid_haptics; };
extern void *raw_device_create(const struct raw_device_vtbl *vtbl, SIZE_T size) DECLSPEC_HIDDEN; @@ -121,7 +126,7 @@ extern BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count) DECLS 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, BYTE *id) DECLSPEC_HIDDEN; +extern BOOL hid_device_add_haptics(struct unix_device *iface) 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/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c index 8981dce7a55..5cf23badf88 100644 --- a/dlls/winebus.sys/unixlib.c +++ b/dlls/winebus.sys/unixlib.c @@ -38,8 +38,6 @@
#include "unix_private.h"
-WINE_DEFAULT_DEBUG_CHANNEL(plugplay); - BOOL is_xbox_gamepad(WORD vid, WORD pid) { if (vid != 0x045e) return FALSE; @@ -84,25 +82,10 @@ static void mouse_stop(struct unix_device *iface) { }
-static void mouse_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) -{ - FIXME("id %u, stub!\n", packet->reportId); - io->Information = 0; - io->Status = STATUS_NOT_IMPLEMENTED; -} - -static void mouse_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) -{ - FIXME("id %u, stub!\n", packet->reportId); - io->Information = 0; - io->Status = STATUS_NOT_IMPLEMENTED; -} - -static void mouse_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) +static NTSTATUS mouse_haptics_start(struct unix_device *iface, DWORD duration, + USHORT rumble_intensity, USHORT buzz_intensity) { - FIXME("id %u, stub!\n", packet->reportId); - io->Information = 0; - io->Status = STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_SUPPORTED; }
static const struct hid_device_vtbl mouse_vtbl = @@ -110,9 +93,7 @@ static const struct hid_device_vtbl mouse_vtbl = mouse_destroy, mouse_start, mouse_stop, - mouse_set_output_report, - mouse_get_feature_report, - mouse_set_feature_report, + mouse_haptics_start, };
static const struct device_desc mouse_device_desc = @@ -158,25 +139,10 @@ static void keyboard_stop(struct unix_device *iface) { }
-static void keyboard_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) -{ - FIXME("id %u, stub!\n", packet->reportId); - io->Information = 0; - io->Status = STATUS_NOT_IMPLEMENTED; -} - -static void keyboard_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) -{ - FIXME("id %u, stub!\n", packet->reportId); - io->Information = 0; - io->Status = STATUS_NOT_IMPLEMENTED; -} - -static void keyboard_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) +static NTSTATUS keyboard_haptics_start(struct unix_device *iface, DWORD duration, + USHORT rumble_intensity, USHORT buzz_intensity) { - FIXME("id %u, stub!\n", packet->reportId); - io->Information = 0; - io->Status = STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_SUPPORTED; }
static const struct hid_device_vtbl keyboard_vtbl = @@ -184,9 +150,7 @@ static const struct hid_device_vtbl keyboard_vtbl = keyboard_destroy, keyboard_start, keyboard_stop, - keyboard_set_output_report, - keyboard_get_feature_report, - keyboard_set_feature_report, + keyboard_haptics_start, };
static const struct device_desc keyboard_device_desc =