[PATCH 4/6] winebus.sys: Introduce a new raw_device / hid_device abstraction.

Rémi Bernon rbernon at codeweavers.com
Wed Sep 22 03:12:58 CDT 2021


For any device which requires building HID reports.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winebus.sys/bus_iohid.c    |   4 +-
 dlls/winebus.sys/bus_sdl.c      |  70 ++++++++------------
 dlls/winebus.sys/bus_udev.c     |  46 +++++--------
 dlls/winebus.sys/hid.c          | 113 ++++++++++++++++++++++++--------
 dlls/winebus.sys/unix_private.h |  51 ++++++++------
 dlls/winebus.sys/unixlib.c      |  70 ++++----------------
 6 files changed, 174 insertions(+), 180 deletions(-)

diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c
index 9b32289a1f6..2dadcc793b1 100644
--- a/dlls/winebus.sys/bus_iohid.c
+++ b/dlls/winebus.sys/bus_iohid.c
@@ -256,7 +256,7 @@ static void iohid_device_set_feature_report(struct unix_device *iface, HID_XFER_
     }
 }
 
-static const struct unix_device_vtbl iohid_device_vtbl =
+static const struct raw_device_vtbl iohid_device_vtbl =
 {
     iohid_device_destroy,
     iohid_device_start,
@@ -343,7 +343,7 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
 
     TRACE("dev %p, desc %s.\n", IOHIDDevice, debugstr_device_desc(&desc));
 
-    if (!(impl = unix_device_create(&iohid_device_vtbl, sizeof(struct iohid_device)))) return;
+    if (!(impl = raw_device_create(&iohid_device_vtbl, sizeof(struct iohid_device)))) return;
     list_add_tail(&device_list, &impl->unix_device.entry);
     impl->device = IOHIDDevice;
     impl->buffer = NULL;
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index eaa0ed9329e..908b6614287 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -128,8 +128,6 @@ struct sdl_device
     int ball_start;
     int hat_start;
 
-    struct hid_descriptor desc;
-
     int buffer_length;
     BYTE *report_buffer;
 
@@ -219,7 +217,7 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl)
         {
             pSDL_HapticStopAll(impl->sdl_haptic);
             pSDL_HapticRumbleInit(impl->sdl_haptic);
-            if (!hid_descriptor_add_haptics(&impl->desc))
+            if (!hid_device_add_haptics(&impl->unix_device))
                 return FALSE;
             impl->haptic_effect_id = -1;
         }
@@ -233,7 +231,7 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl)
     return TRUE;
 }
 
-static NTSTATUS build_joystick_report_descriptor(struct sdl_device *impl)
+static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
 {
     static const USAGE joystick_usages[] =
     {
@@ -247,7 +245,7 @@ static NTSTATUS build_joystick_report_descriptor(struct sdl_device *impl)
         HID_USAGE_GENERIC_DIAL,
         HID_USAGE_GENERIC_WHEEL
     };
-
+    struct sdl_device *impl = impl_from_unix_device(iface);
     int i, report_size = 1;
     int button_count, axis_count, ball_count, hat_count;
 
@@ -280,27 +278,27 @@ static NTSTATUS build_joystick_report_descriptor(struct sdl_device *impl)
 
     TRACE("Report will be %i bytes\n", report_size);
 
-    if (!hid_descriptor_begin(&impl->desc, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_JOYSTICK))
+    if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_JOYSTICK))
         return STATUS_NO_MEMORY;
 
-    if (axis_count && !hid_descriptor_add_axes(&impl->desc, axis_count, HID_USAGE_PAGE_GENERIC,
-                                               joystick_usages, FALSE, -32768, 32767))
+    if (axis_count && !hid_device_add_axes(iface, axis_count, HID_USAGE_PAGE_GENERIC,
+                                           joystick_usages, FALSE, -32768, 32767))
         return STATUS_NO_MEMORY;
 
-    if (ball_count && !hid_descriptor_add_axes(&impl->desc, ball_count * 2, HID_USAGE_PAGE_GENERIC,
-                                               &joystick_usages[axis_count], TRUE, INT32_MIN, INT32_MAX))
+    if (ball_count && !hid_device_add_axes(iface, ball_count * 2, HID_USAGE_PAGE_GENERIC,
+                                           &joystick_usages[axis_count], TRUE, INT32_MIN, INT32_MAX))
         return STATUS_NO_MEMORY;
 
-    if (hat_count && !hid_descriptor_add_hatswitch(&impl->desc, hat_count))
+    if (hat_count && !hid_device_add_hatswitch(iface, hat_count))
         return STATUS_NO_MEMORY;
 
-    if (button_count && !hid_descriptor_add_buttons(&impl->desc, HID_USAGE_PAGE_BUTTON, 1, button_count))
+    if (button_count && !hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, button_count))
         return STATUS_NO_MEMORY;
 
     if (!descriptor_add_haptic(impl))
         return STATUS_NO_MEMORY;
 
-    if (!hid_descriptor_end(&impl->desc))
+    if (!hid_device_end_report_descriptor(iface))
         return STATUS_NO_MEMORY;
 
     impl->buffer_length = report_size;
@@ -316,7 +314,6 @@ static NTSTATUS build_joystick_report_descriptor(struct sdl_device *impl)
 
 failed:
     free(impl->report_buffer);
-    hid_descriptor_free(&impl->desc);
     return STATUS_NO_MEMORY;
 }
 
@@ -347,11 +344,12 @@ static SHORT compose_dpad_value(SDL_GameController *joystick)
     return SDL_HAT_CENTERED;
 }
 
-static NTSTATUS build_controller_report_descriptor(struct sdl_device *impl)
+static NTSTATUS build_controller_report_descriptor(struct unix_device *iface)
 {
     static const USAGE left_axis_usages[] = {HID_USAGE_GENERIC_X, HID_USAGE_GENERIC_Y};
     static const USAGE right_axis_usages[] = {HID_USAGE_GENERIC_RX, HID_USAGE_GENERIC_RY};
     static const USAGE trigger_axis_usages[] = {HID_USAGE_GENERIC_Z, HID_USAGE_GENERIC_RZ};
+    struct sdl_device *impl = impl_from_unix_device(iface);
     ULONG i, button_count = SDL_CONTROLLER_BUTTON_MAX - 1;
     C_ASSERT(SDL_CONTROLLER_AXIS_MAX == 6);
 
@@ -362,31 +360,31 @@ static NTSTATUS build_controller_report_descriptor(struct sdl_device *impl)
 
     TRACE("Report will be %i bytes\n", impl->buffer_length);
 
-    if (!hid_descriptor_begin(&impl->desc, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_GAMEPAD))
+    if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_GAMEPAD))
         return STATUS_NO_MEMORY;
 
-    if (!hid_descriptor_add_axes(&impl->desc, 2, HID_USAGE_PAGE_GENERIC, left_axis_usages,
-                                 FALSE, -32768, 32767))
+    if (!hid_device_add_axes(iface, 2, HID_USAGE_PAGE_GENERIC, left_axis_usages,
+                             FALSE, -32768, 32767))
         return STATUS_NO_MEMORY;
 
-    if (!hid_descriptor_add_axes(&impl->desc, 2, HID_USAGE_PAGE_GENERIC, right_axis_usages,
-                                 FALSE, -32768, 32767))
+    if (!hid_device_add_axes(iface, 2, HID_USAGE_PAGE_GENERIC, right_axis_usages,
+                             FALSE, -32768, 32767))
         return STATUS_NO_MEMORY;
 
-    if (!hid_descriptor_add_axes(&impl->desc, 2, HID_USAGE_PAGE_GENERIC, trigger_axis_usages,
-                                 FALSE, 0, 32767))
+    if (!hid_device_add_axes(iface, 2, HID_USAGE_PAGE_GENERIC, trigger_axis_usages,
+                             FALSE, 0, 32767))
         return STATUS_NO_MEMORY;
 
-    if (!hid_descriptor_add_hatswitch(&impl->desc, 1))
+    if (!hid_device_add_hatswitch(iface, 1))
         return STATUS_NO_MEMORY;
 
-    if (!hid_descriptor_add_buttons(&impl->desc, HID_USAGE_PAGE_BUTTON, 1, button_count))
+    if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, button_count))
         return STATUS_NO_MEMORY;
 
     if (!descriptor_add_haptic(impl))
         return STATUS_NO_MEMORY;
 
-    if (!hid_descriptor_end(&impl->desc))
+    if (!hid_device_end_report_descriptor(iface))
         return STATUS_NO_MEMORY;
 
     if (!(impl->report_buffer = calloc(1, impl->buffer_length))) goto failed;
@@ -400,7 +398,6 @@ static NTSTATUS build_controller_report_descriptor(struct sdl_device *impl)
 
 failed:
     free(impl->report_buffer);
-    hid_descriptor_free(&impl->desc);
     return STATUS_NO_MEMORY;
 }
 
@@ -411,8 +408,8 @@ static void sdl_device_destroy(struct unix_device *iface)
 static NTSTATUS sdl_device_start(struct unix_device *iface)
 {
     struct sdl_device *impl = impl_from_unix_device(iface);
-    if (impl->sdl_controller) return build_controller_report_descriptor(impl);
-    return build_joystick_report_descriptor(impl);
+    if (impl->sdl_controller) return build_controller_report_descriptor(iface);
+    return build_joystick_report_descriptor(iface);
 }
 
 static void sdl_device_stop(struct unix_device *iface)
@@ -428,18 +425,6 @@ static void sdl_device_stop(struct unix_device *iface)
     pthread_mutex_unlock(&sdl_cs);
 }
 
-static NTSTATUS sdl_device_get_reportdescriptor(struct unix_device *iface, BYTE *buffer,
-                                                DWORD length, DWORD *out_length)
-{
-    struct sdl_device *impl = impl_from_unix_device(iface);
-
-    *out_length = impl->desc.size;
-    if (length < impl->desc.size) return STATUS_BUFFER_TOO_SMALL;
-
-    memcpy(buffer, impl->desc.data, impl->desc.size);
-    return STATUS_SUCCESS;
-}
-
 static void sdl_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     struct sdl_device *impl = impl_from_unix_device(iface);
@@ -499,12 +484,11 @@ static void sdl_device_set_feature_report(struct unix_device *iface, HID_XFER_PA
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-static const struct unix_device_vtbl sdl_device_vtbl =
+static const struct hid_device_vtbl sdl_device_vtbl =
 {
     sdl_device_destroy,
     sdl_device_start,
     sdl_device_stop,
-    sdl_device_get_reportdescriptor,
     sdl_device_set_output_report,
     sdl_device_get_feature_report,
     sdl_device_set_feature_report,
@@ -664,7 +648,7 @@ static void sdl_add_device(unsigned int index)
 
     TRACE("%s id %d, desc %s.\n", controller ? "controller" : "joystick", id, debugstr_device_desc(&desc));
 
-    if (!(impl = unix_device_create(&sdl_device_vtbl, sizeof(struct sdl_device)))) return;
+    if (!(impl = hid_device_create(&sdl_device_vtbl, sizeof(struct sdl_device)))) return;
     list_add_tail(&device_list, &impl->unix_device.entry);
     impl->sdl_joystick = joystick;
     impl->sdl_controller = controller;
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 09b00e177a4..0aa3094d348 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -127,8 +127,6 @@ struct lnxev_device
     BYTE *current_report_buffer;
     enum { FIRST, NORMAL, DROPPED } report_state;
 
-    struct hid_descriptor desc;
-
     int button_start;
     BYTE button_map[KEY_MAX];
     BYTE rel_map[HID_REL_MAX];
@@ -451,7 +449,7 @@ static INT count_abs_axis(int device_fd)
     return abs_count;
 }
 
-static NTSTATUS build_report_descriptor(struct lnxev_device *impl, struct udev_device *dev)
+static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_device *dev)
 {
     struct input_absinfo abs_info[HID_ABS_MAX];
     BYTE absbits[(ABS_MAX+7)/8];
@@ -461,6 +459,7 @@ static NTSTATUS build_report_descriptor(struct lnxev_device *impl, struct udev_d
     INT report_size;
     INT button_count, abs_count, rel_count, hat_count;
     const BYTE *device_usage = what_am_I(dev);
+    struct lnxev_device *impl = lnxev_impl_from_unix_device(iface);
 
     if (ioctl(impl->base.device_fd, EVIOCGBIT(EV_REL, sizeof(relbits)), relbits) == -1)
     {
@@ -475,7 +474,7 @@ static NTSTATUS build_report_descriptor(struct lnxev_device *impl, struct udev_d
 
     report_size = 0;
 
-    if (!hid_descriptor_begin(&impl->desc, device_usage[0], device_usage[1]))
+    if (!hid_device_begin_report_descriptor(iface, device_usage[0], device_usage[1]))
         return STATUS_NO_MEMORY;
 
     abs_count = 0;
@@ -487,8 +486,8 @@ static NTSTATUS build_report_descriptor(struct lnxev_device *impl, struct udev_d
         if (!(usage.UsagePage = ABS_TO_HID_MAP[i][0])) continue;
         if (!(usage.Usage = ABS_TO_HID_MAP[i][1])) continue;
 
-        if (!hid_descriptor_add_axes(&impl->desc, 1, usage.UsagePage, &usage.Usage, FALSE,
-                                     LE_DWORD(abs_info[i].minimum), LE_DWORD(abs_info[i].maximum)))
+        if (!hid_device_add_axes(iface, 1, usage.UsagePage, &usage.Usage, FALSE,
+                                 LE_DWORD(abs_info[i].minimum), LE_DWORD(abs_info[i].maximum)))
             return STATUS_NO_MEMORY;
 
         impl->abs_map[i] = report_size;
@@ -503,8 +502,8 @@ static NTSTATUS build_report_descriptor(struct lnxev_device *impl, struct udev_d
         if (!(usage.UsagePage = REL_TO_HID_MAP[i][0])) continue;
         if (!(usage.Usage = REL_TO_HID_MAP[i][1])) continue;
 
-        if (!hid_descriptor_add_axes(&impl->desc, 1, usage.UsagePage, &usage.Usage, TRUE,
-                                     INT32_MIN, INT32_MAX))
+        if (!hid_device_add_axes(iface, 1, usage.UsagePage, &usage.Usage, TRUE,
+                                 INT32_MIN, INT32_MAX))
             return STATUS_NO_MEMORY;
 
         impl->rel_map[i] = report_size;
@@ -525,7 +524,7 @@ static NTSTATUS build_report_descriptor(struct lnxev_device *impl, struct udev_d
 
     if (hat_count)
     {
-        if (!hid_descriptor_add_hatswitch(&impl->desc, hat_count))
+        if (!hid_device_add_hatswitch(iface, hat_count))
             return STATUS_NO_MEMORY;
     }
 
@@ -534,13 +533,13 @@ static NTSTATUS build_report_descriptor(struct lnxev_device *impl, struct udev_d
     button_count = count_buttons(impl->base.device_fd, impl->button_map);
     if (button_count)
     {
-        if (!hid_descriptor_add_buttons(&impl->desc, HID_USAGE_PAGE_BUTTON, 1, button_count))
+        if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, button_count))
             return STATUS_NO_MEMORY;
 
         report_size += (button_count + 7) / 8;
     }
 
-    if (!hid_descriptor_end(&impl->desc))
+    if (!hid_device_end_report_descriptor(iface))
         return STATUS_NO_MEMORY;
 
     TRACE("Report will be %i bytes\n", report_size);
@@ -560,7 +559,6 @@ static NTSTATUS build_report_descriptor(struct lnxev_device *impl, struct udev_d
 failed:
     free(impl->current_report_buffer);
     free(impl->last_report_buffer);
-    hid_descriptor_free(&impl->desc);
     return STATUS_NO_MEMORY;
 }
 
@@ -785,7 +783,7 @@ static void hidraw_device_set_feature_report(struct unix_device *iface, HID_XFER
 #endif
 }
 
-static const struct unix_device_vtbl hidraw_device_vtbl =
+static const struct raw_device_vtbl hidraw_device_vtbl =
 {
     hidraw_device_destroy,
     hidraw_device_start,
@@ -804,7 +802,6 @@ static void lnxev_device_destroy(struct unix_device *iface)
 
     free(impl->current_report_buffer);
     free(impl->last_report_buffer);
-    hid_descriptor_free(&impl->desc);
 
     udev_device_unref(impl->base.udev_device);
 }
@@ -814,7 +811,7 @@ static NTSTATUS lnxev_device_start(struct unix_device *iface)
     struct lnxev_device *impl = lnxev_impl_from_unix_device(iface);
     NTSTATUS status;
 
-    if ((status = build_report_descriptor(impl, impl->base.udev_device)))
+    if ((status = build_report_descriptor(iface, impl->base.udev_device)))
         return status;
 
     pthread_mutex_lock(&udev_cs);
@@ -833,18 +830,6 @@ static void lnxev_device_stop(struct unix_device *iface)
     pthread_mutex_unlock(&udev_cs);
 }
 
-static NTSTATUS lnxev_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer,
-                                                   DWORD length, DWORD *out_length)
-{
-    struct lnxev_device *impl = lnxev_impl_from_unix_device(iface);
-
-    *out_length = impl->desc.size;
-    if (length < impl->desc.size) return STATUS_BUFFER_TOO_SMALL;
-
-    memcpy(buffer, impl->desc.data, impl->desc.size);
-    return STATUS_SUCCESS;
-}
-
 static void lnxev_device_read_report(struct unix_device *iface)
 {
     struct lnxev_device *impl = lnxev_impl_from_unix_device(iface);
@@ -881,12 +866,11 @@ static void lnxev_device_set_feature_report(struct unix_device *iface, HID_XFER_
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-static const struct unix_device_vtbl lnxev_device_vtbl =
+static const struct hid_device_vtbl lnxev_device_vtbl =
 {
     lnxev_device_destroy,
     lnxev_device_start,
     lnxev_device_stop,
-    lnxev_device_get_report_descriptor,
     lnxev_device_set_output_report,
     lnxev_device_get_feature_report,
     lnxev_device_set_feature_report,
@@ -1032,7 +1016,7 @@ static void udev_add_device(struct udev_device *dev)
 
     if (strcmp(subsystem, "hidraw") == 0)
     {
-        if (!(impl = unix_device_create(&hidraw_device_vtbl, sizeof(struct hidraw_device)))) return;
+        if (!(impl = raw_device_create(&hidraw_device_vtbl, sizeof(struct hidraw_device)))) return;
         list_add_tail(&device_list, &impl->unix_device.entry);
         impl->read_report = hidraw_device_read_report;
         impl->udev_device = udev_device_ref(dev);
@@ -1043,7 +1027,7 @@ static void udev_add_device(struct udev_device *dev)
 #ifdef HAS_PROPER_INPUT_HEADER
     else if (strcmp(subsystem, "input") == 0)
     {
-        if (!(impl = unix_device_create(&lnxev_device_vtbl, sizeof(struct lnxev_device)))) return;
+        if (!(impl = hid_device_create(&lnxev_device_vtbl, sizeof(struct lnxev_device)))) return;
         list_add_tail(&device_list, &impl->unix_device.entry);
         impl->read_report = lnxev_device_read_report;
         impl->udev_device = udev_device_ref(dev);
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c
index d2dff7e5a24..98eb5341a2e 100644
--- a/dlls/winebus.sys/hid.c
+++ b/dlls/winebus.sys/hid.c
@@ -34,7 +34,7 @@
 
 #include "unix_private.h"
 
-static BOOL hid_descriptor_append(struct hid_descriptor *desc, const BYTE *buffer, SIZE_T size)
+static BOOL hid_report_descriptor_append(struct hid_report_descriptor *desc, const BYTE *buffer, SIZE_T size)
 {
     BYTE *tmp = desc->data;
 
@@ -57,18 +57,19 @@ static BOOL hid_descriptor_append(struct hid_descriptor *desc, const BYTE *buffe
 
 #include "psh_hid_macros.h"
 
-static BOOL hid_descriptor_append_usage(struct hid_descriptor *desc, USAGE usage)
+static BOOL hid_report_descriptor_append_usage(struct hid_report_descriptor *desc, USAGE usage)
 {
     const BYTE template[] =
     {
         USAGE(2, usage),
     };
 
-    return hid_descriptor_append(desc, template, sizeof(template));
+    return hid_report_descriptor_append(desc, template, sizeof(template));
 }
 
-BOOL hid_descriptor_begin(struct hid_descriptor *desc, USAGE usage_page, USAGE usage)
+BOOL hid_device_begin_report_descriptor(struct unix_device *iface, USAGE usage_page, USAGE usage)
 {
+    struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
     const BYTE template[] =
     {
         USAGE_PAGE(2, usage_page),
@@ -78,27 +79,23 @@ BOOL hid_descriptor_begin(struct hid_descriptor *desc, USAGE usage_page, USAGE u
     };
 
     memset(desc, 0, sizeof(*desc));
-    return hid_descriptor_append(desc, template, sizeof(template));
+    return hid_report_descriptor_append(desc, template, sizeof(template));
 }
 
-BOOL hid_descriptor_end(struct hid_descriptor *desc)
+BOOL hid_device_end_report_descriptor(struct unix_device *iface)
 {
+    struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
     static const BYTE template[] =
     {
         END_COLLECTION,
     };
 
-    return hid_descriptor_append(desc, template, sizeof(template));
+    return hid_report_descriptor_append(desc, template, sizeof(template));
 }
 
-void hid_descriptor_free(struct hid_descriptor *desc)
-{
-    free(desc->data);
-}
-
-BOOL hid_descriptor_add_buttons(struct hid_descriptor *desc, USAGE usage_page,
-                                USAGE usage_min, USAGE usage_max)
+BOOL hid_device_add_buttons(struct unix_device *iface, USAGE usage_page, USAGE usage_min, USAGE usage_max)
 {
+    struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
     const USHORT count = usage_max - usage_min + 1;
     const BYTE template[] =
     {
@@ -120,17 +117,18 @@ BOOL hid_descriptor_add_buttons(struct hid_descriptor *desc, USAGE usage_page,
         INPUT(1, Cnst|Var|Abs),
     };
 
-    if (!hid_descriptor_append(desc, template, sizeof(template)))
+    if (!hid_report_descriptor_append(desc, template, sizeof(template)))
         return FALSE;
 
-    if ((count % 8) && !hid_descriptor_append(desc, template_pad, sizeof(template_pad)))
+    if ((count % 8) && !hid_report_descriptor_append(desc, template_pad, sizeof(template_pad)))
         return FALSE;
 
     return TRUE;
 }
 
-BOOL hid_descriptor_add_hatswitch(struct hid_descriptor *desc, INT count)
+BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count)
 {
+    struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
     const BYTE template[] =
     {
         USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
@@ -145,12 +143,13 @@ BOOL hid_descriptor_add_hatswitch(struct hid_descriptor *desc, INT count)
         INPUT(1, Data|Var|Abs|Null),
     };
 
-    return hid_descriptor_append(desc, template, sizeof(template));
+    return hid_report_descriptor_append(desc, template, sizeof(template));
 }
 
-BOOL hid_descriptor_add_axes(struct hid_descriptor *desc, BYTE count, USAGE usage_page,
-                             const USAGE *usages, BOOL rel, LONG min, LONG max)
+BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usage_page,
+                         const USAGE *usages, BOOL rel, LONG min, LONG max)
 {
+    struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
     const BYTE template_begin[] =
     {
         USAGE_PAGE(1, usage_page),
@@ -172,26 +171,27 @@ BOOL hid_descriptor_add_axes(struct hid_descriptor *desc, BYTE count, USAGE usag
     };
     int i;
 
-    if (!hid_descriptor_append(desc, template_begin, sizeof(template_begin)))
+    if (!hid_report_descriptor_append(desc, template_begin, sizeof(template_begin)))
         return FALSE;
 
     for (i = 0; i < count; i++)
     {
-        if (!hid_descriptor_append_usage(desc, usages[i]))
+        if (!hid_report_descriptor_append_usage(desc, usages[i]))
             return FALSE;
     }
 
-    if (!hid_descriptor_append(desc, template, sizeof(template)))
+    if (!hid_report_descriptor_append(desc, template, sizeof(template)))
         return FALSE;
 
-    if (!hid_descriptor_append(desc, template_end, sizeof(template_end)))
+    if (!hid_report_descriptor_append(desc, template_end, sizeof(template_end)))
         return FALSE;
 
     return TRUE;
 }
 
-BOOL hid_descriptor_add_haptics(struct hid_descriptor *desc)
+BOOL hid_device_add_haptics(struct unix_device *iface)
 {
+    struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
     static const BYTE template[] =
     {
         USAGE_PAGE(2, HID_USAGE_PAGE_VENDOR_DEFINED_BEGIN),
@@ -214,7 +214,68 @@ BOOL hid_descriptor_add_haptics(struct hid_descriptor *desc)
         OUTPUT(1, Data|Var|Abs),
     };
 
-    return hid_descriptor_append(desc, template, sizeof(template));
+    return hid_report_descriptor_append(desc, template, sizeof(template));
 }
 
 #include "pop_hid_macros.h"
+
+static void hid_device_destroy(struct unix_device *iface)
+{
+    iface->hid_vtbl->destroy(iface);
+    free(iface->hid_report_descriptor.data);
+}
+
+static NTSTATUS hid_device_start(struct unix_device *iface)
+{
+    return iface->hid_vtbl->start(iface);
+}
+
+static void hid_device_stop(struct unix_device *iface)
+{
+    iface->hid_vtbl->stop(iface);
+}
+
+NTSTATUS hid_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *out_length)
+{
+    *out_length = iface->hid_report_descriptor.size;
+    if (length < iface->hid_report_descriptor.size) return STATUS_BUFFER_TOO_SMALL;
+
+    memcpy(buffer, iface->hid_report_descriptor.data, iface->hid_report_descriptor.size);
+    return STATUS_SUCCESS;
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+static const struct raw_device_vtbl raw_device_vtbl =
+{
+    hid_device_destroy,
+    hid_device_start,
+    hid_device_stop,
+    hid_device_get_report_descriptor,
+    hid_device_set_output_report,
+    hid_device_get_feature_report,
+    hid_device_set_feature_report,
+};
+
+void *hid_device_create(const struct hid_device_vtbl *vtbl, SIZE_T size)
+{
+    struct unix_device *impl;
+
+    if (!(impl = raw_device_create(&raw_device_vtbl, size))) return NULL;
+    impl->hid_vtbl = vtbl;
+
+    return impl;
+}
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h
index cfb56d2d83e..d1d48737e67 100644
--- a/dlls/winebus.sys/unix_private.h
+++ b/dlls/winebus.sys/unix_private.h
@@ -29,7 +29,7 @@
 
 #include "wine/list.h"
 
-struct unix_device_vtbl
+struct raw_device_vtbl
 {
     void (*destroy)(struct unix_device *iface);
     NTSTATUS (*start)(struct unix_device *iface);
@@ -40,14 +40,35 @@ struct unix_device_vtbl
     void (*set_feature_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
 };
 
+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);
+};
+
+struct hid_report_descriptor
+{
+    BYTE *data;
+    SIZE_T size;
+    SIZE_T max_size;
+};
+
 struct unix_device
 {
-    const struct unix_device_vtbl *vtbl;
+    const struct raw_device_vtbl *vtbl;
     struct list entry;
     LONG ref;
+
+    const struct hid_device_vtbl *hid_vtbl;
+    struct hid_report_descriptor hid_report_descriptor;
 };
 
-extern void *unix_device_create(const struct unix_device_vtbl *vtbl, SIZE_T size) DECLSPEC_HIDDEN;
+extern void *raw_device_create(const struct raw_device_vtbl *vtbl, SIZE_T size) DECLSPEC_HIDDEN;
+extern void *hid_device_create(const struct hid_device_vtbl *vtbl, SIZE_T size) DECLSPEC_HIDDEN;
 
 extern NTSTATUS sdl_bus_init(void *) DECLSPEC_HIDDEN;
 extern NTSTATUS sdl_bus_wait(void *) DECLSPEC_HIDDEN;
@@ -69,24 +90,16 @@ extern BOOL bus_event_queue_input_report(struct list *queue, struct unix_device
                                          BYTE *report, USHORT length) DECLSPEC_HIDDEN;
 extern BOOL bus_event_queue_pop(struct list *queue, struct bus_event *event) DECLSPEC_HIDDEN;
 
-struct hid_descriptor
-{
-    BYTE *data;
-    SIZE_T size;
-    SIZE_T max_size;
-};
-
-extern BOOL hid_descriptor_begin(struct hid_descriptor *desc, USAGE usage_page, USAGE usage) DECLSPEC_HIDDEN;
-extern BOOL hid_descriptor_end(struct hid_descriptor *desc) DECLSPEC_HIDDEN;
-extern void hid_descriptor_free(struct hid_descriptor *desc) DECLSPEC_HIDDEN;
+extern BOOL hid_device_begin_report_descriptor(struct unix_device *iface, USAGE usage_page, USAGE usage) DECLSPEC_HIDDEN;
+extern BOOL hid_device_end_report_descriptor(struct unix_device *iface) DECLSPEC_HIDDEN;
 
-extern BOOL hid_descriptor_add_buttons(struct hid_descriptor *desc, USAGE usage_page,
-                                       USAGE usage_min, USAGE usage_max) DECLSPEC_HIDDEN;
-extern BOOL hid_descriptor_add_hatswitch(struct hid_descriptor *desc, INT count) DECLSPEC_HIDDEN;
-extern BOOL hid_descriptor_add_axes(struct hid_descriptor *desc, BYTE count, USAGE usage_page,
-                                    const USAGE *usages, BOOL rel, LONG min, LONG max) DECLSPEC_HIDDEN;
+extern BOOL hid_device_add_buttons(struct unix_device *iface, USAGE usage_page,
+                                   USAGE usage_min, USAGE usage_max) DECLSPEC_HIDDEN;
+extern BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count) DECLSPEC_HIDDEN;
+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_descriptor_add_haptics(struct hid_descriptor *desc) DECLSPEC_HIDDEN;
+extern BOOL hid_device_add_haptics(struct unix_device *iface) DECLSPEC_HIDDEN;
 
 BOOL is_xbox_gamepad(WORD vid, WORD pid) DECLSPEC_HIDDEN;
 
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c
index 893296e8ebb..8981dce7a55 100644
--- a/dlls/winebus.sys/unixlib.c
+++ b/dlls/winebus.sys/unixlib.c
@@ -62,29 +62,19 @@ BOOL is_xbox_gamepad(WORD vid, WORD pid)
 struct mouse_device
 {
     struct unix_device unix_device;
-    struct hid_descriptor desc;
 };
 
-static inline struct mouse_device *mouse_from_unix_device(struct unix_device *iface)
-{
-    return CONTAINING_RECORD(iface, struct mouse_device, unix_device);
-}
-
 static void mouse_destroy(struct unix_device *iface)
 {
-    struct mouse_device *impl = mouse_from_unix_device(iface);
-    hid_descriptor_free(&impl->desc);
 }
 
 static NTSTATUS mouse_start(struct unix_device *iface)
 {
-    struct mouse_device *impl = mouse_from_unix_device(iface);
-
-    if (!hid_descriptor_begin(&impl->desc, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_MOUSE))
+    if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_MOUSE))
         return STATUS_NO_MEMORY;
-    if (!hid_descriptor_add_buttons(&impl->desc, HID_USAGE_PAGE_BUTTON, 1, 3))
+    if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, 3))
         return STATUS_NO_MEMORY;
-    if (!hid_descriptor_end(&impl->desc))
+    if (!hid_device_end_report_descriptor(iface))
         return STATUS_NO_MEMORY;
 
     return STATUS_SUCCESS;
@@ -94,19 +84,6 @@ static void mouse_stop(struct unix_device *iface)
 {
 }
 
-static NTSTATUS mouse_get_report_descriptor(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *ret_length)
-{
-    struct mouse_device *impl = mouse_from_unix_device(iface);
-
-    TRACE("buffer %p, length %u.\n", buffer, length);
-
-    *ret_length = impl->desc.size;
-    if (length < impl->desc.size) return STATUS_BUFFER_TOO_SMALL;
-
-    memcpy(buffer, impl->desc.data, impl->desc.size);
-    return STATUS_SUCCESS;
-}
-
 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);
@@ -128,12 +105,11 @@ static void mouse_set_feature_report(struct unix_device *iface, HID_XFER_PACKET
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-static const struct unix_device_vtbl mouse_vtbl =
+static const struct hid_device_vtbl mouse_vtbl =
 {
     mouse_destroy,
     mouse_start,
     mouse_stop,
-    mouse_get_report_descriptor,
     mouse_set_output_report,
     mouse_get_feature_report,
     mouse_set_feature_report,
@@ -153,36 +129,26 @@ static NTSTATUS mouse_device_create(void *args)
 {
     struct device_create_params *params = args;
     params->desc = mouse_device_desc;
-    params->device = unix_device_create(&mouse_vtbl, sizeof(struct mouse_device));
+    params->device = hid_device_create(&mouse_vtbl, sizeof(struct mouse_device));
     return STATUS_SUCCESS;
 }
 
 struct keyboard_device
 {
     struct unix_device unix_device;
-    struct hid_descriptor desc;
 };
 
-static inline struct keyboard_device *keyboard_from_unix_device(struct unix_device *iface)
-{
-    return CONTAINING_RECORD(iface, struct keyboard_device, unix_device);
-}
-
 static void keyboard_destroy(struct unix_device *iface)
 {
-    struct keyboard_device *impl = keyboard_from_unix_device(iface);
-    hid_descriptor_free(&impl->desc);
 }
 
 static NTSTATUS keyboard_start(struct unix_device *iface)
 {
-    struct keyboard_device *impl = keyboard_from_unix_device(iface);
-
-    if (!hid_descriptor_begin(&impl->desc, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_KEYBOARD))
+    if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_KEYBOARD))
         return STATUS_NO_MEMORY;
-    if (!hid_descriptor_add_buttons(&impl->desc, HID_USAGE_PAGE_KEYBOARD, 0, 101))
+    if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_KEYBOARD, 0, 101))
         return STATUS_NO_MEMORY;
-    if (!hid_descriptor_end(&impl->desc))
+    if (!hid_device_end_report_descriptor(iface))
         return STATUS_NO_MEMORY;
 
     return STATUS_SUCCESS;
@@ -192,19 +158,6 @@ static void keyboard_stop(struct unix_device *iface)
 {
 }
 
-static NTSTATUS keyboard_get_report_descriptor(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *ret_length)
-{
-    struct keyboard_device *impl = keyboard_from_unix_device(iface);
-
-    TRACE("buffer %p, length %u.\n", buffer, length);
-
-    *ret_length = impl->desc.size;
-    if (length < impl->desc.size) return STATUS_BUFFER_TOO_SMALL;
-
-    memcpy(buffer, impl->desc.data, impl->desc.size);
-    return STATUS_SUCCESS;
-}
-
 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);
@@ -226,12 +179,11 @@ static void keyboard_set_feature_report(struct unix_device *iface, HID_XFER_PACK
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-static const struct unix_device_vtbl keyboard_vtbl =
+static const struct hid_device_vtbl keyboard_vtbl =
 {
     keyboard_destroy,
     keyboard_start,
     keyboard_stop,
-    keyboard_get_report_descriptor,
     keyboard_set_output_report,
     keyboard_get_feature_report,
     keyboard_set_feature_report,
@@ -251,11 +203,11 @@ static NTSTATUS keyboard_device_create(void *args)
 {
     struct device_create_params *params = args;
     params->desc = keyboard_device_desc;
-    params->device = unix_device_create(&keyboard_vtbl, sizeof(struct keyboard_device));
+    params->device = hid_device_create(&keyboard_vtbl, sizeof(struct keyboard_device));
     return STATUS_SUCCESS;
 }
 
-void *unix_device_create(const struct unix_device_vtbl *vtbl, SIZE_T size)
+void *raw_device_create(const struct raw_device_vtbl *vtbl, SIZE_T size)
 {
     struct unix_device *iface;
 
-- 
2.33.0




More information about the wine-devel mailing list