[PATCH 6/6] winebus.sys: Use the computed element offsets to create reports.

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


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winebus.sys/bus_sdl.c      | 70 +++++++++---------------
 dlls/winebus.sys/bus_udev.c     | 94 ++++++++++++++-------------------
 dlls/winebus.sys/hid.c          |  1 +
 dlls/winebus.sys/unix_private.h |  1 +
 4 files changed, 67 insertions(+), 99 deletions(-)

diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index 908b6614287..e6b67fae3c0 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -123,11 +123,6 @@ struct sdl_device
     SDL_GameController *sdl_controller;
     SDL_JoystickID id;
 
-    int button_start;
-    int axis_start;
-    int ball_start;
-    int hat_start;
-
     int buffer_length;
     BYTE *report_buffer;
 
@@ -152,40 +147,44 @@ static struct sdl_device *find_device_from_id(SDL_JoystickID id)
 
 static void set_button_value(struct sdl_device *impl, int index, int value)
 {
-    int byte_index = impl->button_start + index / 8;
+    struct hid_device_state *state = &impl->unix_device.hid_device_state;
+    USHORT offset = state->button_start;
+    int byte_index = offset + index / 8;
     int bit_index = index % 8;
     BYTE mask = 1 << bit_index;
-
-    if (value)
-    {
-        impl->report_buffer[byte_index] = impl->report_buffer[byte_index] | mask;
-    }
-    else
-    {
-        mask = ~mask;
-        impl->report_buffer[byte_index] = impl->report_buffer[byte_index] & mask;
-    }
+    if (index >= state->button_count) return;
+    if (value) impl->report_buffer[byte_index] |= mask;
+    else impl->report_buffer[byte_index] &= ~mask;
 }
 
 static void set_axis_value(struct sdl_device *impl, int index, short value)
 {
-    DWORD *report = (DWORD *)(impl->report_buffer + impl->axis_start);
-    report[index] = LE_DWORD(value);
+    struct hid_device_state *state = &impl->unix_device.hid_device_state;
+    USHORT offset = state->abs_axis_start;
+    if (index >= state->abs_axis_count) return;
+    offset += index * sizeof(DWORD);
+    *(DWORD *)&impl->report_buffer[offset] = LE_DWORD(value);
 }
 
 static void set_ball_value(struct sdl_device *impl, int index, int value1, int value2)
 {
-    int offset;
-    offset = impl->ball_start + (index * sizeof(DWORD));
+    struct hid_device_state *state = &impl->unix_device.hid_device_state;
+    USHORT offset = state->rel_axis_start;
+    if (index >= state->rel_axis_count) return;
+    offset += index * sizeof(DWORD);
     *(DWORD *)&impl->report_buffer[offset] = LE_DWORD(value1);
     *(DWORD *)&impl->report_buffer[offset + sizeof(DWORD)] = LE_DWORD(value2);
 }
 
 static void set_hat_value(struct sdl_device *impl, int index, int value)
 {
-    int byte = impl->hat_start + index;
+    struct hid_device_state *state = &impl->unix_device.hid_device_state;
+    USHORT offset = state->hatswitch_start;
     unsigned char val;
 
+    if (index >= state->hatswitch_count) return;
+    offset += index;
+
     switch (value)
     {
         /* 8 1 2
@@ -203,7 +202,7 @@ static void set_hat_value(struct sdl_device *impl, int index, int value)
         default: return;
     }
 
-    impl->report_buffer[byte] = val;
+    impl->report_buffer[offset] = val;
 }
 
 static BOOL descriptor_add_haptic(struct sdl_device *impl)
@@ -246,8 +245,7 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
         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;
+    int i, button_count, axis_count, ball_count, hat_count;
 
     axis_count = pSDL_JoystickNumAxes(impl->sdl_joystick);
     if (axis_count > 6)
@@ -255,8 +253,6 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
         FIXME("Clamping joystick to 6 axis\n");
         axis_count = 6;
     }
-    impl->axis_start = report_size;
-    report_size += (sizeof(DWORD) * axis_count);
 
     ball_count = pSDL_JoystickNumBalls(impl->sdl_joystick);
     if (axis_count + ball_count * 2 > ARRAY_SIZE(joystick_usages))
@@ -264,19 +260,9 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
         FIXME("Capping ball + axis at 9\n");
         ball_count = (ARRAY_SIZE(joystick_usages) - axis_count) / 2;
     }
-    impl->ball_start = report_size;
-    report_size += (sizeof(DWORD) * 2 * ball_count);
 
     hat_count = pSDL_JoystickNumHats(impl->sdl_joystick);
-    impl->hat_start = report_size;
-    report_size += hat_count;
-
-    /* For now lump all buttons just into incremental usages, Ignore Keys */
     button_count = pSDL_JoystickNumButtons(impl->sdl_joystick);
-    impl->button_start = report_size;
-    report_size += (button_count + 7) / 8;
-
-    TRACE("Report will be %i bytes\n", report_size);
 
     if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_JOYSTICK))
         return STATUS_NO_MEMORY;
@@ -301,8 +287,8 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
     if (!hid_device_end_report_descriptor(iface))
         return STATUS_NO_MEMORY;
 
-    impl->buffer_length = report_size;
-    if (!(impl->report_buffer = calloc(1, report_size))) goto failed;
+    impl->buffer_length = iface->hid_device_state.report_len;
+    if (!(impl->report_buffer = calloc(1, impl->buffer_length))) goto failed;
 
     /* Initialize axis in the report */
     for (i = 0; i < axis_count; i++)
@@ -353,13 +339,6 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface)
     ULONG i, button_count = SDL_CONTROLLER_BUTTON_MAX - 1;
     C_ASSERT(SDL_CONTROLLER_AXIS_MAX == 6);
 
-    impl->axis_start = 0;
-    impl->hat_start = SDL_CONTROLLER_AXIS_MAX * sizeof(DWORD);
-    impl->button_start = impl->hat_start + 1;
-    impl->buffer_length = impl->button_start + (button_count + 7) / 8;
-
-    TRACE("Report will be %i bytes\n", impl->buffer_length);
-
     if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_GAMEPAD))
         return STATUS_NO_MEMORY;
 
@@ -387,6 +366,7 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface)
     if (!hid_device_end_report_descriptor(iface))
         return STATUS_NO_MEMORY;
 
+    impl->buffer_length = impl->unix_device.hid_device_state.report_len;
     if (!(impl->report_buffer = calloc(1, impl->buffer_length))) goto failed;
 
     /* Initialize axis in the report */
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 0aa3094d348..9f3b731364d 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -127,12 +127,11 @@ struct lnxev_device
     BYTE *current_report_buffer;
     enum { FIRST, NORMAL, DROPPED } report_state;
 
-    int button_start;
-    BYTE button_map[KEY_MAX];
+    BYTE abs_map[HID_ABS_MAX];
     BYTE rel_map[HID_REL_MAX];
     BYTE hat_map[8];
+    BYTE button_map[KEY_MAX];
     int hat_values[8];
-    int abs_map[HID_ABS_MAX];
 };
 
 static inline struct base_device *impl_from_unix_device(struct unix_device *iface)
@@ -331,25 +330,22 @@ static const BYTE* what_am_I(struct udev_device *dev)
     return Unknown;
 }
 
-static void set_button_value(int index, int value, BYTE* buffer)
+static void set_button_value(struct lnxev_device *impl, int index, int value)
 {
-    int bindex = index / 8;
-    int b = index % 8;
-    BYTE mask;
-
-    mask = 1<<b;
-    if (value)
-        buffer[bindex] = buffer[bindex] | mask;
-    else
-    {
-        mask = ~mask;
-        buffer[bindex] = buffer[bindex] & mask;
-    }
+    struct hid_device_state *state = &impl->base.unix_device.hid_device_state;
+    USHORT offset = state->button_start;
+    int byte_index = offset + index / 8;
+    int bit_index = index % 8;
+    BYTE mask = 1 << bit_index;
+    if (index >= state->button_count) return;
+    if (value) impl->current_report_buffer[byte_index] |= mask;
+    else impl->current_report_buffer[byte_index] &= ~mask;
 }
 
 static void set_abs_axis_value(struct lnxev_device *impl, int code, int value)
 {
-    int index;
+    struct hid_device_state *state = &impl->base.unix_device.hid_device_state;
+    USHORT offset, index;
     /* check for hatswitches */
     if (code <= ABS_HAT3Y && code >= ABS_HAT0X)
     {
@@ -387,22 +383,33 @@ static void set_abs_axis_value(struct lnxev_device *impl, int code, int value)
             else
                 value = 6;
         }
-        impl->current_report_buffer[impl->hat_map[index]] = value;
+        index = impl->hat_map[index];
+        offset = state->hatswitch_start;
+        if (index >= state->hatswitch_count) return;
+        offset += index;
+        impl->current_report_buffer[offset] = value;
     }
     else if (code < HID_ABS_MAX && ABS_TO_HID_MAP[code][0] != 0)
     {
         index = impl->abs_map[code];
-        *((DWORD*)&impl->current_report_buffer[index]) = LE_DWORD(value);
+        offset = state->abs_axis_start;
+        if (index >= state->abs_axis_count) return;
+        offset += index * sizeof(DWORD);
+        *(DWORD *)&impl->current_report_buffer[offset] = LE_DWORD(value);
     }
 }
 
 static void set_rel_axis_value(struct lnxev_device *impl, int code, int value)
 {
-    int index;
+    struct hid_device_state *state = &impl->base.unix_device.hid_device_state;
+    USHORT offset, index;
     if (code < HID_REL_MAX && REL_TO_HID_MAP[code][0] != 0)
     {
         index = impl->rel_map[code];
-        *(DWORD *)&impl->current_report_buffer[index] = LE_DWORD(value);
+        offset = state->rel_axis_start;
+        if (index >= state->rel_axis_count) return;
+        offset += index * sizeof(DWORD);
+        *(DWORD *)&impl->current_report_buffer[offset] = LE_DWORD(value);
     }
 }
 
@@ -455,9 +462,7 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
     BYTE absbits[(ABS_MAX+7)/8];
     BYTE relbits[(REL_MAX+7)/8];
     USAGE_AND_PAGE usage;
-    INT i;
-    INT report_size;
-    INT button_count, abs_count, rel_count, hat_count;
+    INT i, 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);
 
@@ -472,8 +477,6 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
         memset(absbits, 0, sizeof(absbits));
     }
 
-    report_size = 0;
-
     if (!hid_device_begin_report_descriptor(iface, device_usage[0], device_usage[1]))
         return STATUS_NO_MEMORY;
 
@@ -490,9 +493,7 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
                                  LE_DWORD(abs_info[i].minimum), LE_DWORD(abs_info[i].maximum)))
             return STATUS_NO_MEMORY;
 
-        impl->abs_map[i] = report_size;
-        report_size += 4;
-        abs_count++;
+        impl->abs_map[i] = abs_count++;
     }
 
     rel_count = 0;
@@ -506,47 +507,32 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
                                  INT32_MIN, INT32_MAX))
             return STATUS_NO_MEMORY;
 
-        impl->rel_map[i] = report_size;
-        report_size += 4;
-        rel_count++;
+        impl->rel_map[i] = rel_count++;
     }
 
     hat_count = 0;
     for (i = ABS_HAT0X; i <=ABS_HAT3X; i+=2)
     {
         if (!test_bit(absbits, i)) continue;
-        impl->hat_map[i - ABS_HAT0X] = report_size;
+        impl->hat_map[i - ABS_HAT0X] = hat_count++;
         impl->hat_values[i - ABS_HAT0X] = 0;
         impl->hat_values[i - ABS_HAT0X + 1] = 0;
-        report_size++;
-        hat_count++;
     }
 
-    if (hat_count)
-    {
-        if (!hid_device_add_hatswitch(iface, hat_count))
-            return STATUS_NO_MEMORY;
-    }
+    if (hat_count && !hid_device_add_hatswitch(iface, hat_count))
+        return STATUS_NO_MEMORY;
 
     /* For now lump all buttons just into incremental usages, Ignore Keys */
-    impl->button_start = report_size;
     button_count = count_buttons(impl->base.device_fd, impl->button_map);
-    if (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 (button_count && !hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, button_count))
+        return STATUS_NO_MEMORY;
 
     if (!hid_device_end_report_descriptor(iface))
         return STATUS_NO_MEMORY;
 
-    TRACE("Report will be %i bytes\n", report_size);
-
-    impl->buffer_length = report_size;
-    if (!(impl->current_report_buffer = calloc(1, report_size))) goto failed;
-    if (!(impl->last_report_buffer = calloc(1, report_size))) goto failed;
+    impl->buffer_length = iface->hid_device_state.report_len;
+    if (!(impl->current_report_buffer = calloc(1, impl->buffer_length))) goto failed;
+    if (!(impl->last_report_buffer = calloc(1, impl->buffer_length))) goto failed;
     impl->report_state = FIRST;
 
     /* Initialize axis in the report */
@@ -594,7 +580,7 @@ static BOOL set_report_from_event(struct lnxev_device *impl, struct input_event
             return FALSE;
 #endif
         case EV_KEY:
-            set_button_value(impl->button_start * 8 + impl->button_map[ie->code], ie->value, impl->current_report_buffer);
+            set_button_value(impl, impl->button_map[ie->code], ie->value);
             return FALSE;
         case EV_ABS:
             set_abs_axis_value(impl, ie->code, ie->value);
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c
index 6d3dae5690d..acf0c52cfa8 100644
--- a/dlls/winebus.sys/hid.c
+++ b/dlls/winebus.sys/hid.c
@@ -94,6 +94,7 @@ BOOL hid_device_end_report_descriptor(struct unix_device *iface)
         END_COLLECTION,
     };
 
+    iface->hid_device_state.report_len = (iface->hid_device_state.bit_size + 7) / 8;
     return hid_report_descriptor_append(desc, template, sizeof(template));
 }
 
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h
index acb2f45aca3..ec0568faa6f 100644
--- a/dlls/winebus.sys/unix_private.h
+++ b/dlls/winebus.sys/unix_private.h
@@ -68,6 +68,7 @@ struct hid_device_state
     USHORT hatswitch_count;
     USHORT button_start;
     USHORT button_count;
+    USHORT report_len;
 };
 
 struct unix_device
-- 
2.33.0




More information about the wine-devel mailing list