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:
parent
0e18098bd5
commit
fa3905bafa
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue