Rémi Bernon : winebus.sys: Add a PID effect control output report.

Alexandre Julliard julliard at winehq.org
Mon Oct 4 15:42:17 CDT 2021


Module: wine
Branch: master
Commit: 3b3228e9c7fd2f618fe570795750629fdb563a71
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=3b3228e9c7fd2f618fe570795750629fdb563a71

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Mon Oct  4 09:51:31 2021 +0200

winebus.sys: Add a PID effect control output report.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winebus.sys/bus_sdl.c      |  9 +++++
 dlls/winebus.sys/bus_udev.c     |  9 +++++
 dlls/winebus.sys/hid.c          | 77 +++++++++++++++++++++++++++++++++++++++++
 dlls/winebus.sys/unix_private.h |  2 ++
 dlls/winebus.sys/unixlib.c      | 14 ++++++++
 5 files changed, 111 insertions(+)

diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index 772ee092c83..bcdfd7a9c15 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -444,6 +444,14 @@ static NTSTATUS sdl_device_physical_device_control(struct unix_device *iface, US
     return STATUS_NOT_SUPPORTED;
 }
 
+static NTSTATUS sdl_device_physical_effect_control(struct unix_device *iface, BYTE index,
+                                                   USAGE control, BYTE iterations)
+{
+    FIXME("iface %p, index %u, control %04x, iterations %u stub!\n", iface, index, control, iterations);
+
+    return STATUS_NOT_IMPLEMENTED;
+}
+
 static const struct hid_device_vtbl sdl_device_vtbl =
 {
     sdl_device_destroy,
@@ -451,6 +459,7 @@ static const struct hid_device_vtbl sdl_device_vtbl =
     sdl_device_stop,
     sdl_device_haptics_start,
     sdl_device_physical_device_control,
+    sdl_device_physical_effect_control,
 };
 
 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 454ab3ea870..5eca64e8317 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -868,6 +868,14 @@ static NTSTATUS lnxev_device_physical_device_control(struct unix_device *iface,
     return STATUS_NOT_SUPPORTED;
 }
 
+static NTSTATUS lnxev_device_physical_effect_control(struct unix_device *iface, BYTE index,
+                                                     USAGE control, BYTE iterations)
+{
+    FIXME("iface %p, index %u, control %04x, iterations %u stub!\n", iface, index, control, iterations);
+
+    return STATUS_NOT_IMPLEMENTED;
+}
+
 static const struct hid_device_vtbl lnxev_device_vtbl =
 {
     lnxev_device_destroy,
@@ -875,6 +883,7 @@ static const struct hid_device_vtbl lnxev_device_vtbl =
     lnxev_device_stop,
     lnxev_device_haptics_start,
     lnxev_device_physical_device_control,
+    lnxev_device_physical_effect_control,
 };
 #endif /* HAS_PROPER_INPUT_HEADER */
 
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c
index 12db1706ede..4ddee27cff9 100644
--- a/dlls/winebus.sys/hid.c
+++ b/dlls/winebus.sys/hid.c
@@ -411,6 +411,21 @@ static const USAGE pid_device_control_usages[] =
     PID_USAGE_DC_DEVICE_PAUSE,
     PID_USAGE_DC_DEVICE_CONTINUE,
 };
+
+struct pid_effect_control
+{
+    BYTE index;
+    BYTE control_index;
+    BYTE iterations;
+};
+
+static const USAGE pid_effect_control_usages[] =
+{
+    0, /* HID nary collection indexes start at 1 */
+    PID_USAGE_OP_EFFECT_START,
+    PID_USAGE_OP_EFFECT_START_SOLO,
+    PID_USAGE_OP_EFFECT_STOP,
+};
 #include "poppack.h"
 
 BOOL hid_device_add_physical(struct unix_device *iface)
@@ -437,6 +452,42 @@ BOOL hid_device_add_physical(struct unix_device *iface)
             END_COLLECTION,
         END_COLLECTION,
     };
+
+    const BYTE effect_control_report = ++desc->next_report_id[HidP_Output];
+    const BYTE effect_control_header[] =
+    {
+        /* Control effect state */
+        USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT),
+        COLLECTION(1, Logical),
+            REPORT_ID(1, effect_control_report),
+
+            USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
+            LOGICAL_MAXIMUM(1, 0x7f),
+            LOGICAL_MINIMUM(1, 0x00),
+            REPORT_SIZE(1, 8),
+            REPORT_COUNT(1, 1),
+            OUTPUT(1, Data|Var|Abs),
+
+            USAGE(1, PID_USAGE_EFFECT_OPERATION),
+            COLLECTION(1, Logical),
+    };
+    const BYTE effect_control_footer[] =
+    {
+                LOGICAL_MINIMUM(1, 1),
+                LOGICAL_MAXIMUM(1, 3),
+                REPORT_SIZE(1, 8),
+                REPORT_COUNT(1, 1),
+                OUTPUT(1, Data|Ary|Abs),
+            END_COLLECTION,
+
+            USAGE(1, PID_USAGE_LOOP_COUNT),
+            LOGICAL_MINIMUM(1, 0),
+            LOGICAL_MAXIMUM(2, 0x00ff),
+            REPORT_SIZE(1, 8),
+            REPORT_COUNT(1, 1),
+            OUTPUT(1, Data|Var|Abs),
+        END_COLLECTION,
+    };
     ULONG i;
 
     if (!hid_report_descriptor_append(desc, device_control_header, sizeof(device_control_header)))
@@ -449,7 +500,18 @@ BOOL hid_device_add_physical(struct unix_device *iface)
     if (!hid_report_descriptor_append(desc, device_control_footer, sizeof(device_control_footer)))
         return FALSE;
 
+    if (!hid_report_descriptor_append(desc, effect_control_header, sizeof(effect_control_header)))
+        return FALSE;
+    for (i = 1; i < ARRAY_SIZE(pid_effect_control_usages); ++i)
+    {
+        if (!hid_report_descriptor_append_usage(desc, pid_effect_control_usages[i]))
+            return FALSE;
+    }
+    if (!hid_report_descriptor_append(desc, effect_control_footer, sizeof(effect_control_footer)))
+        return FALSE;
+
     iface->hid_physical.device_control_report = device_control_report;
+    iface->hid_physical.effect_control_report = effect_control_report;
     return TRUE;
 }
 
@@ -525,6 +587,21 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC
         else
             io->Status = iface->hid_vtbl->physical_device_control(iface, control);
     }
+    else if (packet->reportId == physical->effect_control_report)
+    {
+        struct pid_effect_control *report = (struct pid_effect_control *)(packet->reportBuffer + 1);
+        USAGE control;
+
+        io->Information = sizeof(*report) + 1;
+        if (packet->reportBufferLen < io->Information)
+            io->Status = STATUS_BUFFER_TOO_SMALL;
+        else if (report->control_index >= ARRAY_SIZE(pid_effect_control_usages))
+            io->Status = STATUS_INVALID_PARAMETER;
+        else if (!(control = pid_effect_control_usages[report->control_index]))
+            io->Status = STATUS_INVALID_PARAMETER;
+        else
+            io->Status = iface->hid_vtbl->physical_effect_control(iface, report->index, control, report->iterations);
+    }
     else
     {
         io->Information = 0;
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h
index c62e4c9d0ab..2446b8de4a7 100644
--- a/dlls/winebus.sys/unix_private.h
+++ b/dlls/winebus.sys/unix_private.h
@@ -48,6 +48,7 @@ struct hid_device_vtbl
     NTSTATUS (*haptics_start)(struct unix_device *iface, DWORD duration_ms,
                               USHORT rumble_intensity, USHORT buzz_intensity);
     NTSTATUS (*physical_device_control)(struct unix_device *iface, USAGE control);
+    NTSTATUS (*physical_effect_control)(struct unix_device *iface, BYTE index, USAGE control, BYTE iterations);
 };
 
 struct hid_report_descriptor
@@ -91,6 +92,7 @@ struct hid_haptics
 struct hid_physical
 {
     BYTE device_control_report;
+    BYTE effect_control_report;
 };
 
 struct hid_device_state
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c
index 49a42ea04ad..177b8f5ba70 100644
--- a/dlls/winebus.sys/unixlib.c
+++ b/dlls/winebus.sys/unixlib.c
@@ -93,6 +93,12 @@ static NTSTATUS mouse_physical_device_control(struct unix_device *iface, USAGE c
     return STATUS_NOT_SUPPORTED;
 }
 
+static NTSTATUS mouse_physical_effect_control(struct unix_device *iface, BYTE index,
+                                              USAGE control, BYTE iterations)
+{
+    return STATUS_NOT_SUPPORTED;
+}
+
 static const struct hid_device_vtbl mouse_vtbl =
 {
     mouse_destroy,
@@ -100,6 +106,7 @@ static const struct hid_device_vtbl mouse_vtbl =
     mouse_stop,
     mouse_haptics_start,
     mouse_physical_device_control,
+    mouse_physical_effect_control,
 };
 
 static const struct device_desc mouse_device_desc =
@@ -156,6 +163,12 @@ static NTSTATUS keyboard_physical_device_control(struct unix_device *iface, USAG
     return STATUS_NOT_SUPPORTED;
 }
 
+static NTSTATUS keyboard_physical_effect_control(struct unix_device *iface, BYTE index,
+                                                 USAGE control, BYTE iterations)
+{
+    return STATUS_NOT_SUPPORTED;
+}
+
 static const struct hid_device_vtbl keyboard_vtbl =
 {
     keyboard_destroy,
@@ -163,6 +176,7 @@ static const struct hid_device_vtbl keyboard_vtbl =
     keyboard_stop,
     keyboard_haptics_start,
     keyboard_physical_device_control,
+    keyboard_physical_effect_control,
 };
 
 static const struct device_desc keyboard_device_desc =




More information about the wine-cvs mailing list