Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_sdl.c | 7 +++--- dlls/winebus.sys/bus_udev.c | 7 +++--- dlls/winebus.sys/hid.c | 44 +++++++++++++++++++++++++++++++-- dlls/winebus.sys/unix_private.h | 5 +++- dlls/winebus.sys/unixlib.c | 6 +++-- 5 files changed, 58 insertions(+), 11 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index aedef50d3f7..aab629de5da 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -432,13 +432,14 @@ static void sdl_device_stop(struct unix_device *iface) }
static NTSTATUS sdl_device_haptics_start(struct unix_device *iface, UINT duration_ms, - USHORT rumble_intensity, USHORT buzz_intensity) + USHORT rumble_intensity, USHORT buzz_intensity, + USHORT left_intensity, USHORT right_intensity) { struct sdl_device *impl = impl_from_unix_device(iface); SDL_HapticEffect effect;
- TRACE("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u.\n", iface, duration_ms, - rumble_intensity, buzz_intensity); + TRACE("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u, left_intensity %u, right_intensity %u.\n", + iface, duration_ms, rumble_intensity, buzz_intensity, left_intensity, right_intensity);
if (!(impl->effect_support & EFFECT_SUPPORT_HAPTICS)) return STATUS_NOT_SUPPORTED;
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index db173b63fb5..6b4bf09a773 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -867,7 +867,8 @@ static void lnxev_device_read_report(struct unix_device *iface) }
static NTSTATUS lnxev_device_haptics_start(struct unix_device *iface, UINT duration_ms, - USHORT rumble_intensity, USHORT buzz_intensity) + USHORT rumble_intensity, USHORT buzz_intensity, + USHORT left_intensity, USHORT right_intensity) { struct lnxev_device *impl = lnxev_impl_from_unix_device(iface); struct ff_effect effect = @@ -877,8 +878,8 @@ static NTSTATUS lnxev_device_haptics_start(struct unix_device *iface, UINT durat }; struct input_event event;
- TRACE("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u.\n", iface, - duration_ms, rumble_intensity, buzz_intensity); + TRACE("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u, left_intensity %u, right_intensity %u.\n", + iface, duration_ms, rumble_intensity, buzz_intensity, left_intensity, right_intensity);
effect.replay.length = duration_ms; effect.u.rumble.strong_magnitude = rumble_intensity; diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index 5b18da5d8ed..de0c3bb0848 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -335,6 +335,8 @@ struct hid_haptics_intensity { UINT16 rumble_intensity; UINT16 buzz_intensity; + UINT16 left_intensity; + UINT16 right_intensity; }; #include "poppack.h"
@@ -389,6 +391,15 @@ BOOL hid_device_add_haptics(struct unix_device *iface) OUTPUT(1, Data|Var|Abs), END_COLLECTION, }; + const BYTE trigger_template_begin[] = + { + USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), + COLLECTION(1, Physical), + }; + const BYTE trigger_template_end[] = + { + END_COLLECTION, + };
iface->hid_haptics.features_report = haptics_features_report; iface->hid_haptics.intensity_report = haptics_intensity_report; @@ -398,12 +409,36 @@ BOOL hid_device_add_haptics(struct unix_device *iface) iface->hid_haptics.features.buzz.waveform = HID_USAGE_HAPTICS_WAVEFORM_BUZZ; iface->hid_haptics.features.buzz.duration = 0; iface->hid_haptics.features.buzz.cutoff_time_ms = 1000; + iface->hid_haptics.features.left.waveform = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE; + iface->hid_haptics.features.left.duration = 0; + iface->hid_haptics.features.left.cutoff_time_ms = 1000; + iface->hid_haptics.features.right.waveform = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE; + iface->hid_haptics.features.right.duration = 0; + iface->hid_haptics.features.right.cutoff_time_ms = 1000;
if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template))) return FALSE; if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template))) return FALSE;
+ if (!hid_report_descriptor_append_usage(desc, HID_USAGE_GENERIC_Z)) + return FALSE; + if (!hid_report_descriptor_append(desc, trigger_template_begin, sizeof(trigger_template_begin))) + return FALSE; + if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template))) + return FALSE; + if (!hid_report_descriptor_append(desc, trigger_template_end, sizeof(trigger_template_end))) + return FALSE; + + if (!hid_report_descriptor_append_usage(desc, HID_USAGE_GENERIC_RZ)) + return FALSE; + if (!hid_report_descriptor_append(desc, trigger_template_begin, sizeof(trigger_template_begin))) + return FALSE; + if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template))) + return FALSE; + if (!hid_report_descriptor_append(desc, trigger_template_end, sizeof(trigger_template_end))) + return FALSE; + return TRUE; }
@@ -1071,12 +1106,15 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC io->Information = sizeof(*report) + 1; assert(packet->reportBufferLen == io->Information);
- if (!report->rumble_intensity && !report->buzz_intensity) + if (!report->rumble_intensity && !report->buzz_intensity && !report->left_intensity && !report->right_intensity) io->Status = iface->hid_vtbl->haptics_stop(iface); else { duration_ms = min(haptics->features.rumble.cutoff_time_ms, haptics->features.buzz.cutoff_time_ms); - io->Status = iface->hid_vtbl->haptics_start(iface, duration_ms, report->rumble_intensity, report->buzz_intensity); + duration_ms = min(duration_ms, haptics->features.left.cutoff_time_ms); + duration_ms = min(duration_ms, haptics->features.right.cutoff_time_ms); + io->Status = iface->hid_vtbl->haptics_start(iface, duration_ms, report->rumble_intensity, report->buzz_intensity, + report->left_intensity, report->right_intensity); } } else if (packet->reportId == physical->device_control_report) @@ -1287,6 +1325,8 @@ static void hid_device_set_feature_report(struct unix_device *iface, HID_XFER_PA
haptics->features.rumble.cutoff_time_ms = features->rumble.cutoff_time_ms; haptics->features.buzz.cutoff_time_ms = features->buzz.cutoff_time_ms; + haptics->features.left.cutoff_time_ms = features->left.cutoff_time_ms; + haptics->features.right.cutoff_time_ms = features->right.cutoff_time_ms; io->Status = STATUS_SUCCESS; } else diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index 0763d084823..ab8060611a4 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -107,7 +107,8 @@ struct hid_device_vtbl NTSTATUS (*start)(struct unix_device *iface); void (*stop)(struct unix_device *iface); NTSTATUS (*haptics_start)(struct unix_device *iface, UINT duration_ms, - USHORT rumble_intensity, USHORT buzz_intensity); + USHORT rumble_intensity, USHORT buzz_intensity, + USHORT left_intensity, USHORT right_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); @@ -135,6 +136,8 @@ struct hid_haptics_features { struct hid_haptics_feature rumble; struct hid_haptics_feature buzz; + struct hid_haptics_feature left; + struct hid_haptics_feature right; }; #include "poppack.h"
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c index 88cc513125a..1edd90627e5 100644 --- a/dlls/winebus.sys/unixlib.c +++ b/dlls/winebus.sys/unixlib.c @@ -103,7 +103,8 @@ static void mouse_stop(struct unix_device *iface) }
static NTSTATUS mouse_haptics_start(struct unix_device *iface, UINT duration, - USHORT rumble_intensity, USHORT buzz_intensity) + USHORT rumble_intensity, USHORT buzz_intensity, + USHORT left_intensity, USHORT right_intensity) { return STATUS_NOT_SUPPORTED; } @@ -193,7 +194,8 @@ static void keyboard_stop(struct unix_device *iface) }
static NTSTATUS keyboard_haptics_start(struct unix_device *iface, UINT duration, - USHORT rumble_intensity, USHORT buzz_intensity) + USHORT rumble_intensity, USHORT buzz_intensity, + USHORT left_intensity, USHORT right_intensity) { return STATUS_NOT_SUPPORTED; }