Signed-off-by: Rémi Bernon rbernon@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