Rémi Bernon : winebus.sys: Declare multiple HID simple haptics controller collections.
Alexandre Julliard
julliard at winehq.org
Mon Mar 14 17:47:37 CDT 2022
Module: wine
Branch: master
Commit: e651f56e795e089f2e418ef0cbf21ab216b5f882
URL: https://source.winehq.org/git/wine.git/?a=commit;h=e651f56e795e089f2e418ef0cbf21ab216b5f882
Author: Rémi Bernon <rbernon at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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
More information about the wine-cvs
mailing list