Module: wine Branch: master Commit: e651f56e795e089f2e418ef0cbf21ab216b5f882 URL: https://source.winehq.org/git/wine.git/?a=commit;h=e651f56e795e089f2e418ef0c...
Author: Rémi Bernon rbernon@codeweavers.com Date: Mon Mar 14 10:29:36 2022 +0100
winebus.sys: Declare multiple HID simple haptics controller collections.
Instead of having the waveforms combined. This better matches what Windows.Gaming.Input and Windows.Devices.Haptics are exposing, with one SimpleHapticsController for each motor.
This will also simplify the declaration of left/right trigger motors.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/winebus.sys/hid.c | 89 +++++++++++++++++++++++++++++++++++++++-- dlls/winebus.sys/unix_private.h | 12 ++++++ 2 files changed, 98 insertions(+), 3 deletions(-)
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index 3e83a05cdf6..46336716a70 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -337,6 +337,11 @@ struct hid_haptics_waveform BYTE manual_trigger; BYTE repeat_count; }; +struct hid_haptics_intensity +{ + UINT16 rumble_intensity; + UINT16 buzz_intensity; +}; #include "poppack.h"
BOOL hid_device_add_haptics(struct unix_device *iface) @@ -344,7 +349,8 @@ BOOL hid_device_add_haptics(struct unix_device *iface) struct hid_report_descriptor *desc = &iface->hid_report_descriptor; const BYTE haptics_features_report = ++desc->next_report_id[HidP_Feature]; const BYTE haptics_waveform_report = ++desc->next_report_id[HidP_Output]; - const BYTE haptics_template[] = + const BYTE haptics_intensity_report = ++desc->next_report_id[HidP_Output]; + const BYTE waveforms_template[] = { USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS), USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER), @@ -404,16 +410,75 @@ BOOL hid_device_add_haptics(struct unix_device *iface) OUTPUT(1, Data|Var|Abs), END_COLLECTION, }; + const BYTE haptics_template[] = + { + USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS), + USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER), + COLLECTION(1, Logical), + REPORT_ID(1, haptics_features_report), + + USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_LIST), + COLLECTION(1, NamedArray), + USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|3), + REPORT_SIZE(1, 16), + REPORT_COUNT(1, 1), + FEATURE(1, Data|Var|Abs|Null), + END_COLLECTION, + + USAGE(1, HID_USAGE_HAPTICS_DURATION_LIST), + COLLECTION(1, NamedArray), + USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|3), + REPORT_SIZE(1, 16), + REPORT_COUNT(1, 1), + FEATURE(1, Data|Var|Abs|Null), + END_COLLECTION, + + USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME), + UNIT(2, 0x1001), /* seconds */ + UNIT_EXPONENT(1, -3), /* 10^-3 */ + LOGICAL_MINIMUM(4, 0x00000000), + LOGICAL_MAXIMUM(4, 0x7fffffff), + REPORT_SIZE(1, 32), + REPORT_COUNT(1, 1), + FEATURE(1, Data|Var|Abs), + /* reset global items */ + UNIT(1, 0), /* None */ + UNIT_EXPONENT(1, 0), + + REPORT_ID(1, haptics_intensity_report), + USAGE(1, HID_USAGE_HAPTICS_INTENSITY), + LOGICAL_MINIMUM(4, 0x00000000), + LOGICAL_MAXIMUM(4, 0x0000ffff), + REPORT_SIZE(1, 16), + REPORT_COUNT(1, 1), + OUTPUT(1, Data|Var|Abs), + END_COLLECTION, + };
iface->hid_haptics.features_report = haptics_features_report; iface->hid_haptics.waveform_report = haptics_waveform_report; + iface->hid_haptics.intensity_report = haptics_intensity_report; iface->hid_haptics.features.waveform_list[0] = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE; iface->hid_haptics.features.waveform_list[1] = HID_USAGE_HAPTICS_WAVEFORM_BUZZ; iface->hid_haptics.features.duration_list[0] = 0; iface->hid_haptics.features.duration_list[1] = 0; iface->hid_haptics.features.waveform_cutoff_time_ms = 1000; + iface->hid_haptics.features.rumble.waveform = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE; + iface->hid_haptics.features.rumble.duration = 0; + iface->hid_haptics.features.rumble.cutoff_time_ms = 1000; + 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; + + if (!hid_report_descriptor_append(desc, waveforms_template, sizeof(waveforms_template))) + return FALSE;
- return hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)); + 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; + + return TRUE; }
#include "pshpack1.h" @@ -1072,7 +1137,23 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC struct hid_physical *physical = &iface->hid_physical; struct hid_haptics *haptics = &iface->hid_haptics;
- if (packet->reportId == haptics->waveform_report) + if (packet->reportId == haptics->intensity_report) + { + struct hid_haptics_intensity *report = (struct hid_haptics_intensity *)(packet->reportBuffer + 1); + ULONG duration_ms; + + io->Information = sizeof(*report) + 1; + assert(packet->reportBufferLen == io->Information); + + if (!report->rumble_intensity && !report->buzz_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); + } + } + else if (packet->reportId == haptics->waveform_report) { struct hid_haptics_waveform *report = (struct hid_haptics_waveform *)(packet->reportBuffer + 1); UINT16 *rumble_intensity = haptics->waveform_intensity + HAPTICS_WAVEFORM_RUMBLE_ORDINAL; @@ -1307,6 +1388,8 @@ static void hid_device_set_feature_report(struct unix_device *iface, HID_XFER_PA assert(packet->reportBufferLen == io->Information);
haptics->features.waveform_cutoff_time_ms = features->waveform_cutoff_time_ms; + haptics->features.rumble.cutoff_time_ms = features->rumble.cutoff_time_ms; + haptics->features.buzz.cutoff_time_ms = features->buzz.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 553631e40fb..081e57dc53d 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -138,12 +138,23 @@ enum haptics_waveform_ordinal HAPTICS_WAVEFORM_LAST_ORDINAL = HAPTICS_WAVEFORM_BUZZ_ORDINAL, };
+#include "pshpack1.h" +struct hid_haptics_feature +{ + WORD waveform; + WORD duration; + UINT cutoff_time_ms; +}; + struct hid_haptics_features { WORD waveform_list[HAPTICS_WAVEFORM_LAST_ORDINAL - HAPTICS_WAVEFORM_FIRST_ORDINAL + 1]; WORD duration_list[HAPTICS_WAVEFORM_LAST_ORDINAL - HAPTICS_WAVEFORM_FIRST_ORDINAL + 1]; UINT waveform_cutoff_time_ms; + struct hid_haptics_feature rumble; + struct hid_haptics_feature buzz; }; +#include "poppack.h"
struct hid_haptics { @@ -151,6 +162,7 @@ struct hid_haptics UINT16 waveform_intensity[HAPTICS_WAVEFORM_LAST_ORDINAL + 1]; BYTE features_report; BYTE waveform_report; + BYTE intensity_report; };
/* must match the order and number of usages in the