Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_sdl.c | 29 +++++++++++++++++------------ dlls/winebus.sys/bus_udev.c | 24 ++++++++++++++++++++++++ dlls/winebus.sys/hid.c | 10 +++++++--- dlls/winebus.sys/unix_private.h | 1 + dlls/winebus.sys/unixlib.c | 12 ++++++++++++ 5 files changed, 61 insertions(+), 15 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 7fc95b54f95..93ba58ec9d6 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -417,18 +417,6 @@ NTSTATUS sdl_device_haptics_start(struct unix_device *iface, UINT duration_ms, effect.leftright.large_magnitude = rumble_intensity; effect.leftright.small_magnitude = buzz_intensity;
- if (!effect.leftright.large_magnitude && !effect.leftright.small_magnitude) - { - if (impl->effect_support & SDL_HAPTIC_LEFTRIGHT) - pSDL_HapticStopAll(impl->sdl_haptic); - else if (impl->effect_support & WINE_SDL_HAPTIC_RUMBLE) - pSDL_HapticRumbleStop(impl->sdl_haptic); - else if (impl->effect_support & WINE_SDL_JOYSTICK_RUMBLE) - pSDL_JoystickRumble(impl->sdl_joystick, 0, 0, 0); - - return STATUS_SUCCESS; - } - if (impl->effect_support & SDL_HAPTIC_LEFTRIGHT) { if (impl->haptic_effect_id >= 0) @@ -451,6 +439,22 @@ NTSTATUS sdl_device_haptics_start(struct unix_device *iface, UINT duration_ms, return STATUS_SUCCESS; }
+NTSTATUS sdl_device_haptics_stop(struct unix_device *iface) +{ + struct sdl_device *impl = impl_from_unix_device(iface); + + TRACE("iface %p.\n", iface); + + if (impl->effect_support & SDL_HAPTIC_LEFTRIGHT) + pSDL_HapticStopAll(impl->sdl_haptic); + else if (impl->effect_support & WINE_SDL_HAPTIC_RUMBLE) + pSDL_HapticRumbleStop(impl->sdl_haptic); + else if (impl->effect_support & WINE_SDL_JOYSTICK_RUMBLE) + pSDL_JoystickRumble(impl->sdl_joystick, 0, 0, 0); + + return STATUS_SUCCESS; +} + static NTSTATUS sdl_device_physical_device_control(struct unix_device *iface, USAGE control) { struct sdl_device *impl = impl_from_unix_device(iface); @@ -695,6 +699,7 @@ static const struct hid_device_vtbl sdl_device_vtbl = sdl_device_start, sdl_device_stop, sdl_device_haptics_start, + sdl_device_haptics_stop, sdl_device_physical_device_control, sdl_device_physical_device_set_gain, sdl_device_physical_effect_control, diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 9881b625086..08034c8a07e 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -906,6 +906,29 @@ static NTSTATUS lnxev_device_haptics_start(struct unix_device *iface, UINT durat return STATUS_SUCCESS; }
+static NTSTATUS lnxev_device_haptics_stop(struct unix_device *iface) +{ + struct lnxev_device *impl = lnxev_impl_from_unix_device(iface); + struct ff_effect effect = + { + .id = impl->haptic_effect_id, + .type = FF_RUMBLE, + }; + struct input_event event; + + TRACE("iface %p.\n", iface); + + if (effect.id == -1) return STATUS_SUCCESS; + + event.type = EV_FF; + event.code = effect.id; + event.value = 0; + if (write(impl->base.device_fd, &event, sizeof(event)) == -1) + WARN("couldn't stop haptics rumble effect: %d %s\n", errno, strerror(errno)); + + return STATUS_SUCCESS; +} + static NTSTATUS lnxev_device_physical_effect_run(struct lnxev_device *impl, BYTE index, int iterations) { @@ -1185,6 +1208,7 @@ static const struct hid_device_vtbl lnxev_device_vtbl = lnxev_device_start, lnxev_device_stop, lnxev_device_haptics_start, + lnxev_device_haptics_stop, lnxev_device_physical_device_control, lnxev_device_physical_device_set_gain, lnxev_device_physical_effect_control, diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index ec2250fbe80..529ca97aa7a 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -1050,12 +1050,16 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC else { if (waveform->manual_trigger == HAPTICS_WAVEFORM_STOP_ORDINAL) + { memset(haptics->waveforms, 0, sizeof(haptics->waveforms)); + io->Status = iface->hid_vtbl->haptics_stop(iface); + } else + { haptics->waveforms[waveform->manual_trigger] = *waveform; - - duration_ms = haptics->features.waveform_cutoff_time_ms; - io->Status = iface->hid_vtbl->haptics_start(iface, duration_ms, rumble->intensity, buzz->intensity); + duration_ms = haptics->features.waveform_cutoff_time_ms; + io->Status = iface->hid_vtbl->haptics_start(iface, duration_ms, rumble->intensity, buzz->intensity); + } } } else if (packet->reportId == physical->device_control_report) diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index 74c1f4c092a..6b498c46ad7 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -107,6 +107,7 @@ struct hid_device_vtbl void (*stop)(struct unix_device *iface); NTSTATUS (*haptics_start)(struct unix_device *iface, UINT duration_ms, USHORT rumble_intensity, USHORT buzz_intensity); + NTSTATUS (*haptics_stop)(struct unix_device *iface); NTSTATUS (*physical_device_control)(struct unix_device *iface, USAGE control); NTSTATUS (*physical_device_set_gain)(struct unix_device *iface, BYTE percent); NTSTATUS (*physical_effect_control)(struct unix_device *iface, BYTE index, USAGE control, BYTE iterations); diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c index 96bd41e67f7..f251e8e6af7 100644 --- a/dlls/winebus.sys/unixlib.c +++ b/dlls/winebus.sys/unixlib.c @@ -107,6 +107,11 @@ static NTSTATUS mouse_haptics_start(struct unix_device *iface, UINT duration, return STATUS_NOT_SUPPORTED; }
+static NTSTATUS mouse_haptics_stop(struct unix_device *iface) +{ + return STATUS_NOT_SUPPORTED; +} + static NTSTATUS mouse_physical_device_control(struct unix_device *iface, USAGE control) { return STATUS_NOT_SUPPORTED; @@ -135,6 +140,7 @@ static const struct hid_device_vtbl mouse_vtbl = mouse_start, mouse_stop, mouse_haptics_start, + mouse_haptics_stop, mouse_physical_device_control, mouse_physical_device_set_gain, mouse_physical_effect_control, @@ -190,6 +196,11 @@ static NTSTATUS keyboard_haptics_start(struct unix_device *iface, UINT duration, return STATUS_NOT_SUPPORTED; }
+static NTSTATUS keyboard_haptics_stop(struct unix_device *iface) +{ + return STATUS_NOT_SUPPORTED; +} + static NTSTATUS keyboard_physical_device_control(struct unix_device *iface, USAGE control) { return STATUS_NOT_SUPPORTED; @@ -218,6 +229,7 @@ static const struct hid_device_vtbl keyboard_vtbl = keyboard_start, keyboard_stop, keyboard_haptics_start, + keyboard_haptics_stop, keyboard_physical_device_control, keyboard_physical_device_set_gain, keyboard_physical_effect_control,