[PATCH 1/4] winebus.sys: Add HID haptics simple controllers for the triggers.

Rémi Bernon rbernon at codeweavers.com
Tue Mar 15 04:08:25 CDT 2022


Signed-off-by: Rémi Bernon <rbernon at 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;
 }
-- 
2.35.1




More information about the wine-devel mailing list