winebus.sys: Use the computed element offsets to create reports.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
de050c974b
commit
9d5e9b5f42
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ struct hid_device_state
|
|||
USHORT hatswitch_count;
|
||||
USHORT button_start;
|
||||
USHORT button_count;
|
||||
USHORT report_len;
|
||||
};
|
||||
|
||||
struct unix_device
|
||||
|
|
Loading…
Reference in New Issue