winebus.sys: Add a PID effect control output report.

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-10-04 09:51:31 +02:00 committed by Alexandre Julliard
parent 4310b5accf
commit 3b3228e9c7
5 changed files with 111 additions and 0 deletions

View File

@ -444,6 +444,14 @@ static NTSTATUS sdl_device_physical_device_control(struct unix_device *iface, US
return STATUS_NOT_SUPPORTED;
}
static NTSTATUS sdl_device_physical_effect_control(struct unix_device *iface, BYTE index,
USAGE control, BYTE iterations)
{
FIXME("iface %p, index %u, control %04x, iterations %u stub!\n", iface, index, control, iterations);
return STATUS_NOT_IMPLEMENTED;
}
static const struct hid_device_vtbl sdl_device_vtbl =
{
sdl_device_destroy,
@ -451,6 +459,7 @@ static const struct hid_device_vtbl sdl_device_vtbl =
sdl_device_stop,
sdl_device_haptics_start,
sdl_device_physical_device_control,
sdl_device_physical_effect_control,
};
static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *event)

View File

@ -868,6 +868,14 @@ static NTSTATUS lnxev_device_physical_device_control(struct unix_device *iface,
return STATUS_NOT_SUPPORTED;
}
static NTSTATUS lnxev_device_physical_effect_control(struct unix_device *iface, BYTE index,
USAGE control, BYTE iterations)
{
FIXME("iface %p, index %u, control %04x, iterations %u stub!\n", iface, index, control, iterations);
return STATUS_NOT_IMPLEMENTED;
}
static const struct hid_device_vtbl lnxev_device_vtbl =
{
lnxev_device_destroy,
@ -875,6 +883,7 @@ static const struct hid_device_vtbl lnxev_device_vtbl =
lnxev_device_stop,
lnxev_device_haptics_start,
lnxev_device_physical_device_control,
lnxev_device_physical_effect_control,
};
#endif /* HAS_PROPER_INPUT_HEADER */

View File

@ -411,6 +411,21 @@ static const USAGE pid_device_control_usages[] =
PID_USAGE_DC_DEVICE_PAUSE,
PID_USAGE_DC_DEVICE_CONTINUE,
};
struct pid_effect_control
{
BYTE index;
BYTE control_index;
BYTE iterations;
};
static const USAGE pid_effect_control_usages[] =
{
0, /* HID nary collection indexes start at 1 */
PID_USAGE_OP_EFFECT_START,
PID_USAGE_OP_EFFECT_START_SOLO,
PID_USAGE_OP_EFFECT_STOP,
};
#include "poppack.h"
BOOL hid_device_add_physical(struct unix_device *iface)
@ -437,6 +452,42 @@ BOOL hid_device_add_physical(struct unix_device *iface)
END_COLLECTION,
END_COLLECTION,
};
const BYTE effect_control_report = ++desc->next_report_id[HidP_Output];
const BYTE effect_control_header[] =
{
/* Control effect state */
USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT),
COLLECTION(1, Logical),
REPORT_ID(1, effect_control_report),
USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
LOGICAL_MAXIMUM(1, 0x7f),
LOGICAL_MINIMUM(1, 0x00),
REPORT_SIZE(1, 8),
REPORT_COUNT(1, 1),
OUTPUT(1, Data|Var|Abs),
USAGE(1, PID_USAGE_EFFECT_OPERATION),
COLLECTION(1, Logical),
};
const BYTE effect_control_footer[] =
{
LOGICAL_MINIMUM(1, 1),
LOGICAL_MAXIMUM(1, 3),
REPORT_SIZE(1, 8),
REPORT_COUNT(1, 1),
OUTPUT(1, Data|Ary|Abs),
END_COLLECTION,
USAGE(1, PID_USAGE_LOOP_COUNT),
LOGICAL_MINIMUM(1, 0),
LOGICAL_MAXIMUM(2, 0x00ff),
REPORT_SIZE(1, 8),
REPORT_COUNT(1, 1),
OUTPUT(1, Data|Var|Abs),
END_COLLECTION,
};
ULONG i;
if (!hid_report_descriptor_append(desc, device_control_header, sizeof(device_control_header)))
@ -449,7 +500,18 @@ BOOL hid_device_add_physical(struct unix_device *iface)
if (!hid_report_descriptor_append(desc, device_control_footer, sizeof(device_control_footer)))
return FALSE;
if (!hid_report_descriptor_append(desc, effect_control_header, sizeof(effect_control_header)))
return FALSE;
for (i = 1; i < ARRAY_SIZE(pid_effect_control_usages); ++i)
{
if (!hid_report_descriptor_append_usage(desc, pid_effect_control_usages[i]))
return FALSE;
}
if (!hid_report_descriptor_append(desc, effect_control_footer, sizeof(effect_control_footer)))
return FALSE;
iface->hid_physical.device_control_report = device_control_report;
iface->hid_physical.effect_control_report = effect_control_report;
return TRUE;
}
@ -525,6 +587,21 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC
else
io->Status = iface->hid_vtbl->physical_device_control(iface, control);
}
else if (packet->reportId == physical->effect_control_report)
{
struct pid_effect_control *report = (struct pid_effect_control *)(packet->reportBuffer + 1);
USAGE control;
io->Information = sizeof(*report) + 1;
if (packet->reportBufferLen < io->Information)
io->Status = STATUS_BUFFER_TOO_SMALL;
else if (report->control_index >= ARRAY_SIZE(pid_effect_control_usages))
io->Status = STATUS_INVALID_PARAMETER;
else if (!(control = pid_effect_control_usages[report->control_index]))
io->Status = STATUS_INVALID_PARAMETER;
else
io->Status = iface->hid_vtbl->physical_effect_control(iface, report->index, control, report->iterations);
}
else
{
io->Information = 0;

View File

@ -48,6 +48,7 @@ struct hid_device_vtbl
NTSTATUS (*haptics_start)(struct unix_device *iface, DWORD duration_ms,
USHORT rumble_intensity, USHORT buzz_intensity);
NTSTATUS (*physical_device_control)(struct unix_device *iface, USAGE control);
NTSTATUS (*physical_effect_control)(struct unix_device *iface, BYTE index, USAGE control, BYTE iterations);
};
struct hid_report_descriptor
@ -91,6 +92,7 @@ struct hid_haptics
struct hid_physical
{
BYTE device_control_report;
BYTE effect_control_report;
};
struct hid_device_state

View File

@ -93,6 +93,12 @@ static NTSTATUS mouse_physical_device_control(struct unix_device *iface, USAGE c
return STATUS_NOT_SUPPORTED;
}
static NTSTATUS mouse_physical_effect_control(struct unix_device *iface, BYTE index,
USAGE control, BYTE iterations)
{
return STATUS_NOT_SUPPORTED;
}
static const struct hid_device_vtbl mouse_vtbl =
{
mouse_destroy,
@ -100,6 +106,7 @@ static const struct hid_device_vtbl mouse_vtbl =
mouse_stop,
mouse_haptics_start,
mouse_physical_device_control,
mouse_physical_effect_control,
};
static const struct device_desc mouse_device_desc =
@ -156,6 +163,12 @@ static NTSTATUS keyboard_physical_device_control(struct unix_device *iface, USAG
return STATUS_NOT_SUPPORTED;
}
static NTSTATUS keyboard_physical_effect_control(struct unix_device *iface, BYTE index,
USAGE control, BYTE iterations)
{
return STATUS_NOT_SUPPORTED;
}
static const struct hid_device_vtbl keyboard_vtbl =
{
keyboard_destroy,
@ -163,6 +176,7 @@ static const struct hid_device_vtbl keyboard_vtbl =
keyboard_stop,
keyboard_haptics_start,
keyboard_physical_device_control,
keyboard_physical_effect_control,
};
static const struct device_desc keyboard_device_desc =