winebus.sys: Use report ids in crafted 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
9cf1e8353c
commit
04b19a969b
|
@ -46,6 +46,7 @@
|
|||
#include "winternl.h"
|
||||
#include "ddk/wdm.h"
|
||||
#include "ddk/hidtypes.h"
|
||||
#include "ddk/hidsdi.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "hidusage.h"
|
||||
|
@ -119,6 +120,7 @@ struct sdl_device
|
|||
|
||||
SDL_Haptic *sdl_haptic;
|
||||
int haptic_effect_id;
|
||||
BYTE vendor_rumble_report_id;
|
||||
};
|
||||
|
||||
static inline struct sdl_device *impl_from_unix_device(struct unix_device *iface)
|
||||
|
@ -166,7 +168,7 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl)
|
|||
{
|
||||
pSDL_HapticStopAll(impl->sdl_haptic);
|
||||
pSDL_HapticRumbleInit(impl->sdl_haptic);
|
||||
if (!hid_device_add_haptics(&impl->unix_device))
|
||||
if (!hid_device_add_haptics(&impl->unix_device, &impl->vendor_rumble_report_id))
|
||||
return FALSE;
|
||||
impl->haptic_effect_id = -1;
|
||||
}
|
||||
|
@ -217,6 +219,9 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
|
|||
if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_JOYSTICK))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
if (!hid_device_begin_input_report(iface))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
if (axis_count && !hid_device_add_axes(iface, axis_count, HID_USAGE_PAGE_GENERIC,
|
||||
joystick_usages, FALSE, -32768, 32767))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
@ -231,6 +236,9 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
|
|||
if (button_count && !hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, button_count))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
if (!hid_device_end_input_report(iface))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
if (!descriptor_add_haptic(impl))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
|
@ -258,6 +266,9 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface)
|
|||
if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_GAMEPAD))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
if (!hid_device_begin_input_report(iface))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
if (!hid_device_add_axes(iface, 2, HID_USAGE_PAGE_GENERIC, left_axis_usages,
|
||||
FALSE, -32768, 32767))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
@ -276,6 +287,9 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface)
|
|||
if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, button_count))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
if (!hid_device_end_input_report(iface))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
if (!descriptor_add_haptic(impl))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
|
@ -325,7 +339,7 @@ static void sdl_device_set_output_report(struct unix_device *iface, HID_XFER_PAC
|
|||
{
|
||||
struct sdl_device *impl = impl_from_unix_device(iface);
|
||||
|
||||
if (impl->sdl_haptic && packet->reportId == 0)
|
||||
if (impl->sdl_haptic && packet->reportId == impl->vendor_rumble_report_id)
|
||||
{
|
||||
WORD left = packet->reportBuffer[2] * 128;
|
||||
WORD right = packet->reportBuffer[3] * 128;
|
||||
|
|
|
@ -391,6 +391,9 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
|
|||
if (!hid_device_begin_report_descriptor(iface, device_usage[0], device_usage[1]))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
if (!hid_device_begin_input_report(iface))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
abs_count = 0;
|
||||
for (i = 0; i < HID_ABS_MAX; i++)
|
||||
{
|
||||
|
@ -437,6 +440,9 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
|
|||
if (button_count && !hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, button_count))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
if (!hid_device_end_input_report(iface))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
if (!hid_device_end_report_descriptor(iface))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "winioctl.h"
|
||||
#include "hidusage.h"
|
||||
#include "ddk/wdm.h"
|
||||
#include "ddk/hidsdi.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -87,6 +88,39 @@ 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;
|
||||
static const BYTE template[] =
|
||||
{
|
||||
END_COLLECTION,
|
||||
};
|
||||
|
||||
return hid_report_descriptor_append(desc, template, sizeof(template));
|
||||
}
|
||||
|
||||
BOOL hid_device_begin_input_report(struct unix_device *iface)
|
||||
{
|
||||
struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
|
||||
struct hid_device_state *state = &iface->hid_device_state;
|
||||
const BYTE report_id = ++desc->next_report_id[HidP_Input];
|
||||
const BYTE template[] =
|
||||
{
|
||||
COLLECTION(1, Report),
|
||||
REPORT_ID(1, report_id),
|
||||
};
|
||||
|
||||
if (state->report_len)
|
||||
{
|
||||
ERR("input report already created\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
state->id = report_id;
|
||||
state->bit_size += 8;
|
||||
return hid_report_descriptor_append(desc, template, sizeof(template));
|
||||
}
|
||||
|
||||
BOOL hid_device_end_input_report(struct unix_device *iface)
|
||||
{
|
||||
struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
|
||||
struct hid_device_state *state = &iface->hid_device_state;
|
||||
|
@ -98,6 +132,9 @@ BOOL hid_device_end_report_descriptor(struct unix_device *iface)
|
|||
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;
|
||||
|
||||
state->report_buf[0] = state->id;
|
||||
state->last_report_buf[0] = state->id;
|
||||
return hid_report_descriptor_append(desc, template, sizeof(template));
|
||||
}
|
||||
|
||||
|
@ -276,31 +313,36 @@ BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usage_page
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL hid_device_add_haptics(struct unix_device *iface)
|
||||
BOOL hid_device_add_haptics(struct unix_device *iface, BYTE *id)
|
||||
{
|
||||
struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
|
||||
static const BYTE template[] =
|
||||
const BYTE report_id = ++desc->next_report_id[HidP_Output];
|
||||
const BYTE template[] =
|
||||
{
|
||||
USAGE_PAGE(2, HID_USAGE_PAGE_VENDOR_DEFINED_BEGIN),
|
||||
USAGE(1, 0x01),
|
||||
/* padding */
|
||||
REPORT_COUNT(1, 0x02),
|
||||
REPORT_SIZE(1, 0x08),
|
||||
OUTPUT(1, Data|Var|Abs),
|
||||
/* actuators */
|
||||
LOGICAL_MINIMUM(1, 0x00),
|
||||
LOGICAL_MAXIMUM(1, 0xff),
|
||||
PHYSICAL_MINIMUM(1, 0x00),
|
||||
PHYSICAL_MAXIMUM(1, 0xff),
|
||||
REPORT_SIZE(1, 0x08),
|
||||
REPORT_COUNT(1, 0x02),
|
||||
OUTPUT(1, Data|Var|Abs),
|
||||
/* padding */
|
||||
REPORT_COUNT(1, 0x02),
|
||||
REPORT_SIZE(1, 0x08),
|
||||
OUTPUT(1, Data|Var|Abs),
|
||||
COLLECTION(1, Report),
|
||||
REPORT_ID(1, report_id),
|
||||
/* padding */
|
||||
REPORT_COUNT(1, 0x02),
|
||||
REPORT_SIZE(1, 0x08),
|
||||
OUTPUT(1, Data|Var|Abs),
|
||||
/* actuators */
|
||||
USAGE(1, 0x01),
|
||||
LOGICAL_MINIMUM(1, 0x00),
|
||||
LOGICAL_MAXIMUM(1, 0xff),
|
||||
PHYSICAL_MINIMUM(1, 0x00),
|
||||
PHYSICAL_MAXIMUM(1, 0xff),
|
||||
REPORT_SIZE(1, 0x08),
|
||||
REPORT_COUNT(1, 0x02),
|
||||
OUTPUT(1, Data|Var|Abs),
|
||||
/* padding */
|
||||
REPORT_COUNT(1, 0x02),
|
||||
REPORT_SIZE(1, 0x08),
|
||||
OUTPUT(1, Data|Var|Abs),
|
||||
END_COLLECTION,
|
||||
};
|
||||
|
||||
*id = report_id;
|
||||
return hid_report_descriptor_append(desc, template, sizeof(template));
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ struct hid_report_descriptor
|
|||
BYTE *data;
|
||||
SIZE_T size;
|
||||
SIZE_T max_size;
|
||||
BYTE next_report_id[3];
|
||||
};
|
||||
|
||||
struct hid_device_state
|
||||
|
@ -72,6 +73,7 @@ struct hid_device_state
|
|||
BYTE *report_buf;
|
||||
BYTE *last_report_buf;
|
||||
BOOL dropped;
|
||||
BYTE id;
|
||||
};
|
||||
|
||||
struct unix_device
|
||||
|
@ -111,13 +113,15 @@ extern BOOL bus_event_queue_pop(struct list *queue, struct bus_event *event) DEC
|
|||
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_device_begin_input_report(struct unix_device *iface) DECLSPEC_HIDDEN;
|
||||
extern BOOL hid_device_end_input_report(struct unix_device *iface) 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_device_add_haptics(struct unix_device *iface) DECLSPEC_HIDDEN;
|
||||
extern BOOL hid_device_add_haptics(struct unix_device *iface, BYTE *id) DECLSPEC_HIDDEN;
|
||||
|
||||
extern BOOL hid_device_set_abs_axis(struct unix_device *iface, ULONG index, LONG value) DECLSPEC_HIDDEN;
|
||||
extern BOOL hid_device_set_rel_axis(struct unix_device *iface, ULONG index, LONG value) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -233,7 +233,7 @@ static DWORD HID_set_state(struct xinput_controller *controller, XINPUT_VIBRATIO
|
|||
if (controller->enabled)
|
||||
{
|
||||
memset(output_report_buf, 0, output_report_len);
|
||||
output_report_buf[0] = /* report id */ 0;
|
||||
output_report_buf[0] = 1;
|
||||
output_report_buf[1] = 0x8;
|
||||
output_report_buf[3] = (BYTE)(state->wLeftMotorSpeed / 256);
|
||||
output_report_buf[4] = (BYTE)(state->wRightMotorSpeed / 256);
|
||||
|
|
Loading…
Reference in New Issue