[PATCH 5/5] winebus.sys: Handle feature and output reports in hid_device.

Rémi Bernon rbernon at codeweavers.com
Thu Sep 23 01:55:30 CDT 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winebus.sys/bus_sdl.c      | 51 ++++++++++----------------------
 dlls/winebus.sys/bus_udev.c     | 23 ++++-----------
 dlls/winebus.sys/hid.c          | 25 ++++++++++++----
 dlls/winebus.sys/unix_private.h | 13 ++++++---
 dlls/winebus.sys/unixlib.c      | 52 +++++----------------------------
 5 files changed, 58 insertions(+), 106 deletions(-)

diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index c6d58635382..31915a9fa0d 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -128,7 +128,6 @@ struct sdl_device
     DWORD effect_support;
     SDL_Haptic *sdl_haptic;
     int haptic_effect_id;
-    BYTE vendor_rumble_report_id;
 };
 
 static inline struct sdl_device *impl_from_unix_device(struct unix_device *iface)
@@ -187,7 +186,7 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl)
 
     if (impl->effect_support & EFFECT_SUPPORT_HAPTICS)
     {
-        if (!hid_device_add_haptics(&impl->unix_device, &impl->vendor_rumble_report_id))
+        if (!hid_device_add_haptics(&impl->unix_device))
             return FALSE;
     }
 
@@ -348,36 +347,28 @@ static void sdl_device_stop(struct unix_device *iface)
     pthread_mutex_unlock(&sdl_cs);
 }
 
-static void sdl_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+NTSTATUS sdl_device_haptics_start(struct unix_device *iface, DWORD duration_ms,
+                                  USHORT rumble_intensity, USHORT buzz_intensity)
 {
     struct sdl_device *impl = impl_from_unix_device(iface);
     SDL_HapticEffect effect;
 
-    if (packet->reportId == impl->vendor_rumble_report_id)
-    {
-        WORD left = packet->reportBuffer[2] * 128;
-        WORD right = packet->reportBuffer[3] * 128;
+    TRACE("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u.\n", iface, duration_ms,
+          rumble_intensity, buzz_intensity);
 
-        pSDL_memset(&effect, 0, sizeof(SDL_HapticEffect));
-        effect.type = SDL_HAPTIC_LEFTRIGHT;
-        effect.leftright.length = -1;
-        effect.leftright.large_magnitude = left;
-        effect.leftright.small_magnitude = right;
+    if (!(impl->effect_support & EFFECT_SUPPORT_HAPTICS)) return STATUS_NOT_SUPPORTED;
 
-        io->Information = packet->reportBufferLen;
-        io->Status = STATUS_SUCCESS;
-    }
-    else
-    {
-        io->Information = 0;
-        io->Status = STATUS_NOT_IMPLEMENTED;
-        return;
-    }
+    memset(&effect, 0, sizeof(SDL_HapticEffect));
+    effect.type = SDL_HAPTIC_LEFTRIGHT;
+    effect.leftright.length = duration_ms;
+    effect.leftright.large_magnitude = rumble_intensity;
+    effect.leftright.small_magnitude = buzz_intensity;
 
     if (impl->sdl_haptic) pSDL_HapticStopAll(impl->sdl_haptic);
     if (impl->effect_support & WINE_SDL_JOYSTICK_RUMBLE)
         pSDL_JoystickRumble(impl->sdl_joystick, 0, 0, 0);
-    if (!effect.leftright.large_magnitude && !effect.leftright.small_magnitude) return;
+    if (!effect.leftright.large_magnitude && !effect.leftright.small_magnitude)
+        return STATUS_SUCCESS;
 
     if (impl->effect_support & SDL_HAPTIC_LEFTRIGHT)
     {
@@ -397,18 +388,8 @@ static void sdl_device_set_output_report(struct unix_device *iface, HID_XFER_PAC
         pSDL_JoystickRumble(impl->sdl_joystick, effect.leftright.large_magnitude,
                             effect.leftright.small_magnitude, -1);
     }
-}
-
-static void sdl_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
-{
-    io->Information = 0;
-    io->Status = STATUS_NOT_IMPLEMENTED;
-}
 
-static void sdl_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
-{
-    io->Information = 0;
-    io->Status = STATUS_NOT_IMPLEMENTED;
+    return STATUS_SUCCESS;
 }
 
 static const struct hid_device_vtbl sdl_device_vtbl =
@@ -416,9 +397,7 @@ static const struct hid_device_vtbl sdl_device_vtbl =
     sdl_device_destroy,
     sdl_device_start,
     sdl_device_stop,
-    sdl_device_set_output_report,
-    sdl_device_get_feature_report,
-    sdl_device_set_feature_report,
+    sdl_device_haptics_start,
 };
 
 static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *event)
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 508614d2c04..8bc9b4bf64d 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -734,22 +734,13 @@ static void lnxev_device_read_report(struct unix_device *iface)
         bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
 }
 
-static void lnxev_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static NTSTATUS lnxev_device_haptics_start(struct unix_device *iface, DWORD duration_ms,
+                                           USHORT rumble_intensity, USHORT buzz_intensity)
 {
-    io->Information = 0;
-    io->Status = STATUS_NOT_IMPLEMENTED;
-}
-
-static void lnxev_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
-{
-    io->Information = 0;
-    io->Status = STATUS_NOT_IMPLEMENTED;
-}
+    FIXME("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u stub!\n", iface,
+          duration_ms, rumble_intensity, buzz_intensity);
 
-static void lnxev_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
-{
-    io->Information = 0;
-    io->Status = STATUS_NOT_IMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 static const struct hid_device_vtbl lnxev_device_vtbl =
@@ -757,9 +748,7 @@ static const struct hid_device_vtbl lnxev_device_vtbl =
     lnxev_device_destroy,
     lnxev_device_start,
     lnxev_device_stop,
-    lnxev_device_set_output_report,
-    lnxev_device_get_feature_report,
-    lnxev_device_set_feature_report,
+    lnxev_device_haptics_start,
 };
 #endif
 
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c
index 92d572355c2..c1dd75f77c4 100644
--- a/dlls/winebus.sys/hid.c
+++ b/dlls/winebus.sys/hid.c
@@ -313,7 +313,7 @@ BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usage_page
     return TRUE;
 }
 
-BOOL hid_device_add_haptics(struct unix_device *iface, BYTE *id)
+BOOL hid_device_add_haptics(struct unix_device *iface)
 {
     struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
     const BYTE report_id = ++desc->next_report_id[HidP_Output];
@@ -342,7 +342,7 @@ BOOL hid_device_add_haptics(struct unix_device *iface, BYTE *id)
         END_COLLECTION,
     };
 
-    *id = report_id;
+    iface->hid_haptics.vendor_report = report_id;
     return hid_report_descriptor_append(desc, template, sizeof(template));
 }
 
@@ -377,17 +377,32 @@ NTSTATUS hid_device_get_report_descriptor(struct unix_device *iface, BYTE *buffe
 
 static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
-    return iface->hid_vtbl->set_output_report(iface, packet, io);
+    struct hid_haptics *haptics = &iface->hid_haptics;
+    if (packet->reportId == haptics->vendor_report)
+    {
+        WORD left = packet->reportBuffer[2] * 128;
+        WORD right = packet->reportBuffer[3] * 128;
+
+        io->Information = packet->reportBufferLen;
+        io->Status = iface->hid_vtbl->haptics_start(iface, -1, left, right);
+    }
+    else
+    {
+        io->Information = 0;
+        io->Status = STATUS_NOT_IMPLEMENTED;
+    }
 }
 
 static void hid_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
-    return iface->hid_vtbl->get_feature_report(iface, packet, io);
+    io->Information = 0;
+    io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
 static void hid_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
-    return iface->hid_vtbl->set_feature_report(iface, packet, io);
+    io->Information = 0;
+    io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
 static const struct raw_device_vtbl raw_device_vtbl =
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h
index b44bf503b45..9684ac47067 100644
--- a/dlls/winebus.sys/unix_private.h
+++ b/dlls/winebus.sys/unix_private.h
@@ -45,9 +45,8 @@ struct hid_device_vtbl
     void (*destroy)(struct unix_device *iface);
     NTSTATUS (*start)(struct unix_device *iface);
     void (*stop)(struct unix_device *iface);
-    void (*set_output_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
-    void (*get_feature_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
-    void (*set_feature_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
+    NTSTATUS (*haptics_start)(struct unix_device *iface, DWORD duration_ms,
+                              USHORT rumble_intensity, USHORT buzz_intensity);
 };
 
 struct hid_report_descriptor
@@ -58,6 +57,11 @@ struct hid_report_descriptor
     BYTE next_report_id[3];
 };
 
+struct hid_haptics
+{
+    BYTE vendor_report;
+};
+
 struct hid_device_state
 {
     ULONG bit_size;
@@ -85,6 +89,7 @@ struct unix_device
     const struct hid_device_vtbl *hid_vtbl;
     struct hid_report_descriptor hid_report_descriptor;
     struct hid_device_state hid_device_state;
+    struct hid_haptics hid_haptics;
 };
 
 extern void *raw_device_create(const struct raw_device_vtbl *vtbl, SIZE_T size) DECLSPEC_HIDDEN;
@@ -121,7 +126,7 @@ extern BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count) DECLS
 extern BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usage_page,
                                 const USAGE *usages, BOOL rel, LONG min, LONG max) DECLSPEC_HIDDEN;
 
-extern BOOL hid_device_add_haptics(struct unix_device *iface, BYTE *id) DECLSPEC_HIDDEN;
+extern BOOL hid_device_add_haptics(struct unix_device *iface) DECLSPEC_HIDDEN;
 
 extern BOOL hid_device_set_abs_axis(struct unix_device *iface, ULONG index, LONG value) DECLSPEC_HIDDEN;
 extern BOOL hid_device_set_rel_axis(struct unix_device *iface, ULONG index, LONG value) DECLSPEC_HIDDEN;
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c
index 8981dce7a55..5cf23badf88 100644
--- a/dlls/winebus.sys/unixlib.c
+++ b/dlls/winebus.sys/unixlib.c
@@ -38,8 +38,6 @@
 
 #include "unix_private.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
-
 BOOL is_xbox_gamepad(WORD vid, WORD pid)
 {
     if (vid != 0x045e) return FALSE;
@@ -84,25 +82,10 @@ static void mouse_stop(struct unix_device *iface)
 {
 }
 
-static void mouse_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
-{
-    FIXME("id %u, stub!\n", packet->reportId);
-    io->Information = 0;
-    io->Status = STATUS_NOT_IMPLEMENTED;
-}
-
-static void mouse_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
-{
-    FIXME("id %u, stub!\n", packet->reportId);
-    io->Information = 0;
-    io->Status = STATUS_NOT_IMPLEMENTED;
-}
-
-static void mouse_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static NTSTATUS mouse_haptics_start(struct unix_device *iface, DWORD duration,
+                                    USHORT rumble_intensity, USHORT buzz_intensity)
 {
-    FIXME("id %u, stub!\n", packet->reportId);
-    io->Information = 0;
-    io->Status = STATUS_NOT_IMPLEMENTED;
+    return STATUS_NOT_SUPPORTED;
 }
 
 static const struct hid_device_vtbl mouse_vtbl =
@@ -110,9 +93,7 @@ static const struct hid_device_vtbl mouse_vtbl =
     mouse_destroy,
     mouse_start,
     mouse_stop,
-    mouse_set_output_report,
-    mouse_get_feature_report,
-    mouse_set_feature_report,
+    mouse_haptics_start,
 };
 
 static const struct device_desc mouse_device_desc =
@@ -158,25 +139,10 @@ static void keyboard_stop(struct unix_device *iface)
 {
 }
 
-static void keyboard_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
-{
-    FIXME("id %u, stub!\n", packet->reportId);
-    io->Information = 0;
-    io->Status = STATUS_NOT_IMPLEMENTED;
-}
-
-static void keyboard_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
-{
-    FIXME("id %u, stub!\n", packet->reportId);
-    io->Information = 0;
-    io->Status = STATUS_NOT_IMPLEMENTED;
-}
-
-static void keyboard_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static NTSTATUS keyboard_haptics_start(struct unix_device *iface, DWORD duration,
+                                       USHORT rumble_intensity, USHORT buzz_intensity)
 {
-    FIXME("id %u, stub!\n", packet->reportId);
-    io->Information = 0;
-    io->Status = STATUS_NOT_IMPLEMENTED;
+    return STATUS_NOT_SUPPORTED;
 }
 
 static const struct hid_device_vtbl keyboard_vtbl =
@@ -184,9 +150,7 @@ static const struct hid_device_vtbl keyboard_vtbl =
     keyboard_destroy,
     keyboard_start,
     keyboard_stop,
-    keyboard_set_output_report,
-    keyboard_get_feature_report,
-    keyboard_set_feature_report,
+    keyboard_haptics_start,
 };
 
 static const struct device_desc keyboard_device_desc =
-- 
2.33.0




More information about the wine-devel mailing list