winebus.sys: Introduce a new raw_device / hid_device abstraction.

For any device which requires building HID reports.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-09-22 10:30:42 +02:00 committed by Alexandre Julliard
parent 0e18098bd5
commit fa3905bafa
6 changed files with 177 additions and 183 deletions

View File

@ -249,7 +249,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,
@ -336,7 +336,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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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 unix_device
struct hid_device_vtbl
{
const struct unix_device_vtbl *vtbl;
struct list entry;
LONG ref;
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);
};
extern void *unix_device_create(const struct unix_device_vtbl *vtbl, SIZE_T size) DECLSPEC_HIDDEN;
struct hid_report_descriptor
{
BYTE *data;
SIZE_T size;
SIZE_T max_size;
};
struct unix_device
{
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 *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_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_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_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_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_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;

View File

@ -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;