[PATCH 1/5] winebus.sys: Factor out HID report buffers allocation.

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


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winebus.sys/bus_sdl.c      | 44 ++++++++-----------------
 dlls/winebus.sys/bus_udev.c     | 58 ++++++++-------------------------
 dlls/winebus.sys/hid.c          | 27 ++++++++++++++-
 dlls/winebus.sys/unix_private.h |  6 ++++
 4 files changed, 59 insertions(+), 76 deletions(-)

diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index e6b67fae3c0..6adb0fe913d 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -123,9 +123,6 @@ struct sdl_device
     SDL_GameController *sdl_controller;
     SDL_JoystickID id;
 
-    int buffer_length;
-    BYTE *report_buffer;
-
     SDL_Haptic *sdl_haptic;
     int haptic_effect_id;
 };
@@ -153,8 +150,8 @@ static void set_button_value(struct sdl_device *impl, int index, int value)
     int bit_index = index % 8;
     BYTE mask = 1 << bit_index;
     if (index >= state->button_count) return;
-    if (value) impl->report_buffer[byte_index] |= mask;
-    else impl->report_buffer[byte_index] &= ~mask;
+    if (value) state->report_buf[byte_index] |= mask;
+    else state->report_buf[byte_index] &= ~mask;
 }
 
 static void set_axis_value(struct sdl_device *impl, int index, short value)
@@ -163,7 +160,7 @@ static void set_axis_value(struct sdl_device *impl, int index, short value)
     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);
+    *(DWORD *)&state->report_buf[offset] = LE_DWORD(value);
 }
 
 static void set_ball_value(struct sdl_device *impl, int index, int value1, int value2)
@@ -172,8 +169,8 @@ static void set_ball_value(struct sdl_device *impl, int index, int value1, int v
     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);
+    *(DWORD *)&state->report_buf[offset] = LE_DWORD(value1);
+    *(DWORD *)&state->report_buf[offset + sizeof(DWORD)] = LE_DWORD(value2);
 }
 
 static void set_hat_value(struct sdl_device *impl, int index, int value)
@@ -202,7 +199,7 @@ static void set_hat_value(struct sdl_device *impl, int index, int value)
         default: return;
     }
 
-    impl->report_buffer[offset] = val;
+    state->report_buf[offset] = val;
 }
 
 static BOOL descriptor_add_haptic(struct sdl_device *impl)
@@ -287,9 +284,6 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
     if (!hid_device_end_report_descriptor(iface))
         return STATUS_NO_MEMORY;
 
-    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++)
         set_axis_value(impl, i, pSDL_JoystickGetAxis(impl->sdl_joystick, i));
@@ -297,10 +291,6 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
         set_hat_value(impl, i, pSDL_JoystickGetHat(impl->sdl_joystick, i));
 
     return STATUS_SUCCESS;
-
-failed:
-    free(impl->report_buffer);
-    return STATUS_NO_MEMORY;
 }
 
 static SHORT compose_dpad_value(SDL_GameController *joystick)
@@ -366,19 +356,12 @@ 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 */
     for (i = SDL_CONTROLLER_AXIS_LEFTX; i < SDL_CONTROLLER_AXIS_MAX; i++)
         set_axis_value(impl, i, pSDL_GameControllerGetAxis(impl->sdl_controller, i));
     set_hat_value(impl, 0, compose_dpad_value(impl->sdl_controller));
 
     return STATUS_SUCCESS;
-
-failed:
-    free(impl->report_buffer);
-    return STATUS_NO_MEMORY;
 }
 
 static void sdl_device_destroy(struct unix_device *iface)
@@ -477,6 +460,7 @@ static const struct hid_device_vtbl sdl_device_vtbl =
 static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *event)
 {
     struct unix_device *iface = &impl->unix_device;
+    struct hid_device_state *state = &iface->hid_device_state;
 
     if (impl->sdl_controller) return TRUE; /* use controller events instead */
 
@@ -488,8 +472,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e
             SDL_JoyButtonEvent *ie = &event->jbutton;
 
             set_button_value(impl, ie->button, ie->state);
-
-            bus_event_queue_input_report(&event_queue, iface, impl->report_buffer, impl->buffer_length);
+            bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
             break;
         }
         case SDL_JOYAXISMOTION:
@@ -499,7 +482,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e
             if (ie->axis < 6)
             {
                 set_axis_value(impl, ie->axis, ie->value);
-                bus_event_queue_input_report(&event_queue, iface, impl->report_buffer, impl->buffer_length);
+                bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
             }
             break;
         }
@@ -508,7 +491,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e
             SDL_JoyBallEvent *ie = &event->jball;
 
             set_ball_value(impl, ie->ball, ie->xrel, ie->yrel);
-            bus_event_queue_input_report(&event_queue, iface, impl->report_buffer, impl->buffer_length);
+            bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
             break;
         }
         case SDL_JOYHATMOTION:
@@ -516,7 +499,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e
             SDL_JoyHatEvent *ie = &event->jhat;
 
             set_hat_value(impl, ie->hat, ie->value);
-            bus_event_queue_input_report(&event_queue, iface, impl->report_buffer, impl->buffer_length);
+            bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
             break;
         }
         default:
@@ -528,6 +511,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e
 static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event *event)
 {
     struct unix_device *iface = &impl->unix_device;
+    struct hid_device_state *state = &iface->hid_device_state;
 
     switch(event->type)
     {
@@ -555,7 +539,7 @@ static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event
             }
 
             set_button_value(impl, button, ie->state);
-            bus_event_queue_input_report(&event_queue, iface, impl->report_buffer, impl->buffer_length);
+            bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
             break;
         }
         case SDL_CONTROLLERAXISMOTION:
@@ -563,7 +547,7 @@ static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event
             SDL_ControllerAxisEvent *ie = &event->caxis;
 
             set_axis_value(impl, ie->axis, ie->value);
-            bus_event_queue_input_report(&event_queue, iface, impl->report_buffer, impl->buffer_length);
+            bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
             break;
         }
         default:
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 9f3b731364d..cd7eadf7ec0 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -122,11 +122,6 @@ struct lnxev_device
 {
     struct base_device base;
 
-    int buffer_length;
-    BYTE *last_report_buffer;
-    BYTE *current_report_buffer;
-    enum { FIRST, NORMAL, DROPPED } report_state;
-
     BYTE abs_map[HID_ABS_MAX];
     BYTE rel_map[HID_REL_MAX];
     BYTE hat_map[8];
@@ -338,8 +333,8 @@ static void set_button_value(struct lnxev_device *impl, int index, int value)
     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;
+    if (value) state->report_buf[byte_index] |= mask;
+    else state->report_buf[byte_index] &= ~mask;
 }
 
 static void set_abs_axis_value(struct lnxev_device *impl, int code, int value)
@@ -387,7 +382,7 @@ static void set_abs_axis_value(struct lnxev_device *impl, int code, int value)
         offset = state->hatswitch_start;
         if (index >= state->hatswitch_count) return;
         offset += index;
-        impl->current_report_buffer[offset] = value;
+        state->report_buf[offset] = value;
     }
     else if (code < HID_ABS_MAX && ABS_TO_HID_MAP[code][0] != 0)
     {
@@ -395,7 +390,7 @@ static void set_abs_axis_value(struct lnxev_device *impl, int code, int 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);
+        *(DWORD *)&state->report_buf[offset] = LE_DWORD(value);
     }
 }
 
@@ -409,7 +404,7 @@ static void set_rel_axis_value(struct lnxev_device *impl, int code, int 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);
+        *(DWORD *)&state->report_buf[offset] = LE_DWORD(value);
     }
 }
 
@@ -530,48 +525,25 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
     if (!hid_device_end_report_descriptor(iface))
         return STATUS_NO_MEMORY;
 
-    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 */
     for (i = 0; i < HID_ABS_MAX; i++)
         if (test_bit(absbits, i))
             set_abs_axis_value(impl, i, abs_info[i].value);
 
     return STATUS_SUCCESS;
-
-failed:
-    free(impl->current_report_buffer);
-    free(impl->last_report_buffer);
-    return STATUS_NO_MEMORY;
 }
 
-static BOOL set_report_from_event(struct lnxev_device *impl, struct input_event *ie)
+static BOOL set_report_from_event(struct unix_device *iface, struct input_event *ie)
 {
+    struct lnxev_device *impl = lnxev_impl_from_unix_device(iface);
     switch(ie->type)
     {
 #ifdef EV_SYN
         case EV_SYN:
             switch (ie->code)
             {
-                case SYN_REPORT:
-                    if (impl->report_state == NORMAL)
-                    {
-                        memcpy(impl->last_report_buffer, impl->current_report_buffer, impl->buffer_length);
-                        return TRUE;
-                    }
-                    else
-                    {
-                        if (impl->report_state == DROPPED)
-                            memcpy(impl->current_report_buffer, impl->last_report_buffer, impl->buffer_length);
-                        impl->report_state = NORMAL;
-                    }
-                    break;
-                case SYN_DROPPED:
-                    TRACE_(hid_report)("received SY_DROPPED\n");
-                    impl->report_state = DROPPED;
+            case SYN_REPORT: return hid_device_sync_report(iface);
+            case SYN_DROPPED: hid_device_drop_report(iface); break;
             }
             return FALSE;
 #endif
@@ -785,10 +757,6 @@ static const struct raw_device_vtbl hidraw_device_vtbl =
 static void lnxev_device_destroy(struct unix_device *iface)
 {
     struct lnxev_device *impl = lnxev_impl_from_unix_device(iface);
-
-    free(impl->current_report_buffer);
-    free(impl->last_report_buffer);
-
     udev_device_unref(impl->base.udev_device);
 }
 
@@ -818,20 +786,20 @@ static void lnxev_device_stop(struct unix_device *iface)
 
 static void lnxev_device_read_report(struct unix_device *iface)
 {
+    struct hid_device_state *state = &iface->hid_device_state;
     struct lnxev_device *impl = lnxev_impl_from_unix_device(iface);
     struct input_event ie;
     int size;
 
-    if (!impl->current_report_buffer || impl->buffer_length == 0)
-        return;
+    if (!state->report_buf || !state->report_len) return;
 
     size = read(impl->base.device_fd, &ie, sizeof(ie));
     if (size == -1)
         TRACE_(hid_report)("Read failed. Likely an unplugged device\n");
     else if (size == 0)
         TRACE_(hid_report)("Failed to read report\n");
-    else if (set_report_from_event(impl, &ie))
-        bus_event_queue_input_report(&event_queue, iface, impl->current_report_buffer, impl->buffer_length);
+    else if (set_report_from_event(iface, &ie))
+        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)
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c
index acf0c52cfa8..ba49c010532 100644
--- a/dlls/winebus.sys/hid.c
+++ b/dlls/winebus.sys/hid.c
@@ -89,12 +89,15 @@ BOOL hid_device_begin_report_descriptor(struct unix_device *iface, USAGE usage_p
 BOOL hid_device_end_report_descriptor(struct unix_device *iface)
 {
     struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
+    struct hid_device_state *state = &iface->hid_device_state;
     static const BYTE template[] =
     {
         END_COLLECTION,
     };
 
-    iface->hid_device_state.report_len = (iface->hid_device_state.bit_size + 7) / 8;
+    state->report_len = (state->bit_size + 7) / 8;
+    if (!(state->report_buf = calloc(1, state->report_len))) return FALSE;
+    if (!(state->last_report_buf = calloc(1, state->report_len))) return FALSE;
     return hid_report_descriptor_append(desc, template, sizeof(template));
 }
 
@@ -307,6 +310,8 @@ static void hid_device_destroy(struct unix_device *iface)
 {
     iface->hid_vtbl->destroy(iface);
     free(iface->hid_report_descriptor.data);
+    free(iface->hid_device_state.report_buf);
+    free(iface->hid_device_state.last_report_buf);
 }
 
 static NTSTATUS hid_device_start(struct unix_device *iface)
@@ -363,3 +368,23 @@ void *hid_device_create(const struct hid_device_vtbl *vtbl, SIZE_T size)
 
     return impl;
 }
+
+BOOL hid_device_sync_report(struct unix_device *iface)
+{
+    BOOL dropped;
+
+    if (!(dropped = iface->hid_device_state.dropped))
+        memcpy(iface->hid_device_state.last_report_buf, iface->hid_device_state.report_buf,
+               iface->hid_device_state.report_len);
+    else
+        memcpy(iface->hid_device_state.report_buf, iface->hid_device_state.last_report_buf,
+               iface->hid_device_state.report_len);
+    iface->hid_device_state.dropped = FALSE;
+
+    return !dropped;
+}
+
+void hid_device_drop_report(struct unix_device *iface)
+{
+    iface->hid_device_state.dropped = TRUE;
+}
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h
index ec0568faa6f..dbec779c67e 100644
--- a/dlls/winebus.sys/unix_private.h
+++ b/dlls/winebus.sys/unix_private.h
@@ -69,6 +69,9 @@ struct hid_device_state
     USHORT button_start;
     USHORT button_count;
     USHORT report_len;
+    BYTE *report_buf;
+    BYTE *last_report_buf;
+    BOOL dropped;
 };
 
 struct unix_device
@@ -116,6 +119,9 @@ extern BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usa
 
 extern BOOL hid_device_add_haptics(struct unix_device *iface) DECLSPEC_HIDDEN;
 
+extern BOOL hid_device_sync_report(struct unix_device *iface) DECLSPEC_HIDDEN;
+extern void hid_device_drop_report(struct unix_device *iface) DECLSPEC_HIDDEN;
+
 BOOL is_xbox_gamepad(WORD vid, WORD pid) DECLSPEC_HIDDEN;
 
 #endif /* __WINEBUS_UNIX_PRIVATE_H */
-- 
2.33.0




More information about the wine-devel mailing list