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