winebus.sys: Add a PID effect update output report.
Advertising support of the periodic effect types only for now. Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
19a6d409c0
commit
12d91995fd
|
@ -174,7 +174,8 @@ static void set_hat_value(struct unix_device *iface, int index, int value)
|
|||
|
||||
static BOOL descriptor_add_haptic(struct sdl_device *impl)
|
||||
{
|
||||
USHORT i;
|
||||
USHORT i, count = 0;
|
||||
USAGE usages[16];
|
||||
|
||||
if (!pSDL_JoystickIsHaptic(impl->sdl_joystick) ||
|
||||
!(impl->sdl_haptic = pSDL_HapticOpenFromJoystick(impl->sdl_joystick)))
|
||||
|
@ -200,7 +201,13 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl)
|
|||
|
||||
if ((impl->effect_support & EFFECT_SUPPORT_PHYSICAL))
|
||||
{
|
||||
if (!hid_device_add_physical(&impl->unix_device))
|
||||
/* SDL_HAPTIC_SQUARE doesn't exist */
|
||||
if (impl->effect_support & SDL_HAPTIC_SINE) usages[count++] = PID_USAGE_ET_SINE;
|
||||
if (impl->effect_support & SDL_HAPTIC_TRIANGLE) usages[count++] = PID_USAGE_ET_TRIANGLE;
|
||||
if (impl->effect_support & SDL_HAPTIC_SAWTOOTHUP) usages[count++] = PID_USAGE_ET_SAWTOOTH_UP;
|
||||
if (impl->effect_support & SDL_HAPTIC_SAWTOOTHDOWN) usages[count++] = PID_USAGE_ET_SAWTOOTH_DOWN;
|
||||
|
||||
if (!hid_device_add_physical(&impl->unix_device, usages, count))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -471,6 +478,14 @@ static NTSTATUS sdl_device_physical_effect_control(struct unix_device *iface, BY
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYTE index,
|
||||
struct effect_params *params)
|
||||
{
|
||||
FIXME("iface %p, index %u, params %p stub!\n", iface, index, params);
|
||||
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static const struct hid_device_vtbl sdl_device_vtbl =
|
||||
{
|
||||
sdl_device_destroy,
|
||||
|
@ -479,6 +494,7 @@ static const struct hid_device_vtbl sdl_device_vtbl =
|
|||
sdl_device_haptics_start,
|
||||
sdl_device_physical_device_control,
|
||||
sdl_device_physical_effect_control,
|
||||
sdl_device_physical_effect_update,
|
||||
};
|
||||
|
||||
static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *event)
|
||||
|
|
|
@ -567,6 +567,8 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
|
|||
BYTE ffbits[(FF_MAX+7)/8];
|
||||
struct ff_effect effect;
|
||||
USAGE_AND_PAGE usage;
|
||||
USHORT count = 0;
|
||||
USAGE usages[16];
|
||||
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);
|
||||
|
@ -664,7 +666,13 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
|
|||
for (i = 0; i < FF_MAX; ++i) if (test_bit(ffbits, i)) break;
|
||||
if (i != FF_MAX)
|
||||
{
|
||||
if (!hid_device_add_physical(iface))
|
||||
if (test_bit(ffbits, FF_SINE)) usages[count++] = PID_USAGE_ET_SINE;
|
||||
if (test_bit(ffbits, FF_SQUARE)) usages[count++] = PID_USAGE_ET_SQUARE;
|
||||
if (test_bit(ffbits, FF_TRIANGLE)) usages[count++] = PID_USAGE_ET_TRIANGLE;
|
||||
if (test_bit(ffbits, FF_SAW_UP)) usages[count++] = PID_USAGE_ET_SAWTOOTH_UP;
|
||||
if (test_bit(ffbits, FF_SAW_DOWN)) usages[count++] = PID_USAGE_ET_SAWTOOTH_DOWN;
|
||||
|
||||
if (!hid_device_add_physical(iface, usages, count))
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -916,6 +924,14 @@ static NTSTATUS lnxev_device_physical_effect_control(struct unix_device *iface,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS lnxev_device_physical_effect_update(struct unix_device *iface, BYTE index,
|
||||
struct effect_params *params)
|
||||
{
|
||||
FIXME("iface %p, index %u, params %p stub!\n", iface, index, params);
|
||||
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static const struct hid_device_vtbl lnxev_device_vtbl =
|
||||
{
|
||||
lnxev_device_destroy,
|
||||
|
@ -924,6 +940,7 @@ static const struct hid_device_vtbl lnxev_device_vtbl =
|
|||
lnxev_device_haptics_start,
|
||||
lnxev_device_physical_device_control,
|
||||
lnxev_device_physical_effect_control,
|
||||
lnxev_device_physical_effect_update,
|
||||
};
|
||||
#endif /* HAS_PROPER_INPUT_HEADER */
|
||||
|
||||
|
|
|
@ -426,12 +426,27 @@ static const USAGE pid_effect_control_usages[] =
|
|||
PID_USAGE_OP_EFFECT_START_SOLO,
|
||||
PID_USAGE_OP_EFFECT_STOP,
|
||||
};
|
||||
|
||||
struct pid_effect_update
|
||||
{
|
||||
BYTE index;
|
||||
BYTE type_index;
|
||||
UINT16 duration;
|
||||
UINT16 trigger_repeat_interval;
|
||||
UINT16 sample_period;
|
||||
UINT16 start_delay;
|
||||
BYTE gain;
|
||||
BYTE trigger_button;
|
||||
BYTE enable_bits;
|
||||
BYTE direction[2];
|
||||
};
|
||||
#include "poppack.h"
|
||||
|
||||
BOOL hid_device_add_physical(struct unix_device *iface)
|
||||
BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT count)
|
||||
{
|
||||
struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
|
||||
const BYTE device_control_report = ++desc->next_report_id[HidP_Output];
|
||||
struct hid_device_state *state = &iface->hid_device_state;
|
||||
const BYTE device_control_header[] =
|
||||
{
|
||||
USAGE_PAGE(1, HID_USAGE_PAGE_PID),
|
||||
|
@ -488,6 +503,95 @@ BOOL hid_device_add_physical(struct unix_device *iface)
|
|||
OUTPUT(1, Data|Var|Abs),
|
||||
END_COLLECTION,
|
||||
};
|
||||
|
||||
const BYTE effect_update_report = ++desc->next_report_id[HidP_Output];
|
||||
const BYTE effect_update_header[] =
|
||||
{
|
||||
/* Set effect properties */
|
||||
USAGE(1, PID_USAGE_SET_EFFECT_REPORT),
|
||||
COLLECTION(1, Logical),
|
||||
REPORT_ID(1, effect_update_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_TYPE),
|
||||
COLLECTION(1, Logical),
|
||||
};
|
||||
const BYTE effect_update_footer[] =
|
||||
{
|
||||
LOGICAL_MINIMUM(1, 1),
|
||||
LOGICAL_MAXIMUM(1, count),
|
||||
REPORT_SIZE(1, 8),
|
||||
OUTPUT(1, Data|Ary|Abs),
|
||||
END_COLLECTION,
|
||||
|
||||
USAGE(1, PID_USAGE_DURATION),
|
||||
USAGE(1, PID_USAGE_TRIGGER_REPEAT_INTERVAL),
|
||||
USAGE(1, PID_USAGE_SAMPLE_PERIOD),
|
||||
USAGE(1, PID_USAGE_START_DELAY),
|
||||
UNIT(2, 0x1003), /* Eng Lin:Time */
|
||||
UNIT_EXPONENT(1, -3), /* 10^-3 */
|
||||
LOGICAL_MINIMUM(1, 0),
|
||||
LOGICAL_MAXIMUM(2, 0x7fff),
|
||||
PHYSICAL_MINIMUM(1, 0),
|
||||
PHYSICAL_MAXIMUM(2, 0x7fff),
|
||||
REPORT_SIZE(1, 16),
|
||||
REPORT_COUNT(1, 4),
|
||||
OUTPUT(1, Data|Var|Abs),
|
||||
PHYSICAL_MAXIMUM(1, 0),
|
||||
UNIT_EXPONENT(1, 0),
|
||||
UNIT(1, 0), /* None */
|
||||
|
||||
USAGE(1, PID_USAGE_GAIN),
|
||||
LOGICAL_MAXIMUM(1, 0x7f),
|
||||
REPORT_SIZE(1, 8),
|
||||
REPORT_COUNT(1, 1),
|
||||
OUTPUT(1, Data|Var|Abs),
|
||||
|
||||
USAGE(1, PID_USAGE_TRIGGER_BUTTON),
|
||||
LOGICAL_MAXIMUM(2, state->button_count),
|
||||
REPORT_SIZE(1, 8),
|
||||
REPORT_COUNT(1, 1),
|
||||
OUTPUT(1, Data|Var|Abs|Null),
|
||||
|
||||
USAGE(1, PID_USAGE_AXES_ENABLE),
|
||||
COLLECTION(1, Logical),
|
||||
USAGE(4, (HID_USAGE_PAGE_GENERIC<<16)|HID_USAGE_GENERIC_X),
|
||||
USAGE(4, (HID_USAGE_PAGE_GENERIC<<16)|HID_USAGE_GENERIC_Y),
|
||||
LOGICAL_MAXIMUM(1, 1),
|
||||
REPORT_SIZE(1, 1),
|
||||
REPORT_COUNT(1, 2),
|
||||
OUTPUT(1, Data|Var|Abs),
|
||||
END_COLLECTION,
|
||||
USAGE(1, PID_USAGE_DIRECTION_ENABLE),
|
||||
REPORT_COUNT(1, 1),
|
||||
OUTPUT(1, Data|Var|Abs),
|
||||
REPORT_COUNT(1, 5),
|
||||
OUTPUT(1, Cnst|Var|Abs), /* 5-bit pad */
|
||||
|
||||
USAGE(1, PID_USAGE_DIRECTION),
|
||||
COLLECTION(1, Logical),
|
||||
USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|1),
|
||||
USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|2),
|
||||
UNIT(1, 0x14), /* Eng Rot:Angular Pos */
|
||||
UNIT_EXPONENT(1, -2),
|
||||
LOGICAL_MINIMUM(1, 0),
|
||||
LOGICAL_MAXIMUM(2, 0x00ff),
|
||||
PHYSICAL_MAXIMUM(4, 36000),
|
||||
REPORT_SIZE(1, 8),
|
||||
REPORT_COUNT(1, 2),
|
||||
OUTPUT(1, Data|Var|Abs),
|
||||
END_COLLECTION,
|
||||
PHYSICAL_MAXIMUM(1, 0),
|
||||
UNIT_EXPONENT(1, 0),
|
||||
UNIT(1, 0), /* None */
|
||||
END_COLLECTION,
|
||||
};
|
||||
ULONG i;
|
||||
|
||||
if (!hid_report_descriptor_append(desc, device_control_header, sizeof(device_control_header)))
|
||||
|
@ -510,8 +614,22 @@ BOOL hid_device_add_physical(struct unix_device *iface)
|
|||
if (!hid_report_descriptor_append(desc, effect_control_footer, sizeof(effect_control_footer)))
|
||||
return FALSE;
|
||||
|
||||
if (!hid_report_descriptor_append(desc, effect_update_header, sizeof(effect_update_header)))
|
||||
return FALSE;
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
if (!hid_report_descriptor_append_usage(desc, usages[i]))
|
||||
return FALSE;
|
||||
}
|
||||
if (!hid_report_descriptor_append(desc, effect_update_footer, sizeof(effect_update_footer)))
|
||||
return FALSE;
|
||||
|
||||
/* HID nary collection indexes start at 1 */
|
||||
memcpy(iface->hid_physical.effect_types + 1, usages, count * sizeof(*usages));
|
||||
|
||||
iface->hid_physical.device_control_report = device_control_report;
|
||||
iface->hid_physical.effect_control_report = effect_control_report;
|
||||
iface->hid_physical.effect_update_report = effect_update_report;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -602,6 +720,37 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC
|
|||
else
|
||||
io->Status = iface->hid_vtbl->physical_effect_control(iface, report->index, control, report->iterations);
|
||||
}
|
||||
else if (packet->reportId == physical->effect_update_report)
|
||||
{
|
||||
struct pid_effect_update *report = (struct pid_effect_update *)(packet->reportBuffer + 1);
|
||||
struct effect_params *params = iface->hid_physical.effect_params + report->index;
|
||||
USAGE effect_type;
|
||||
|
||||
io->Information = sizeof(*report) + 1;
|
||||
if (packet->reportBufferLen < io->Information)
|
||||
io->Status = STATUS_BUFFER_TOO_SMALL;
|
||||
else if (report->type_index >= ARRAY_SIZE(iface->hid_physical.effect_types))
|
||||
io->Status = STATUS_INVALID_PARAMETER;
|
||||
else if (!(effect_type = iface->hid_physical.effect_types[report->type_index]))
|
||||
io->Status = STATUS_INVALID_PARAMETER;
|
||||
else
|
||||
{
|
||||
params->effect_type = effect_type;
|
||||
params->duration = report->duration;
|
||||
params->trigger_repeat_interval = report->trigger_repeat_interval;
|
||||
params->sample_period = report->sample_period;
|
||||
params->start_delay = report->start_delay;
|
||||
params->gain = report->gain;
|
||||
params->trigger_button = report->trigger_button == 0xff ? 0 : report->trigger_button;
|
||||
params->axis_enabled[0] = (report->enable_bits & 1) != 0;
|
||||
params->axis_enabled[1] = (report->enable_bits & 2) != 0;
|
||||
params->direction_enabled = (report->enable_bits & 4) != 0;
|
||||
params->direction[0] = report->direction[0];
|
||||
params->direction[1] = report->direction[1];
|
||||
|
||||
io->Status = iface->hid_vtbl->physical_effect_update(iface, report->index, params);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
io->Information = 0;
|
||||
|
|
|
@ -29,6 +29,20 @@
|
|||
|
||||
#include "wine/list.h"
|
||||
|
||||
struct effect_params
|
||||
{
|
||||
USAGE effect_type;
|
||||
UINT16 duration;
|
||||
UINT16 trigger_repeat_interval;
|
||||
UINT16 sample_period;
|
||||
UINT16 start_delay;
|
||||
BYTE gain;
|
||||
BYTE trigger_button;
|
||||
BOOL axis_enabled[2];
|
||||
BOOL direction_enabled;
|
||||
BYTE direction[2];
|
||||
};
|
||||
|
||||
struct raw_device_vtbl
|
||||
{
|
||||
void (*destroy)(struct unix_device *iface);
|
||||
|
@ -49,6 +63,7 @@ struct hid_device_vtbl
|
|||
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);
|
||||
NTSTATUS (*physical_effect_update)(struct unix_device *iface, BYTE index, struct effect_params *params);
|
||||
};
|
||||
|
||||
struct hid_report_descriptor
|
||||
|
@ -91,8 +106,12 @@ struct hid_haptics
|
|||
|
||||
struct hid_physical
|
||||
{
|
||||
USAGE effect_types[32];
|
||||
struct effect_params effect_params[256];
|
||||
|
||||
BYTE device_control_report;
|
||||
BYTE effect_control_report;
|
||||
BYTE effect_update_report;
|
||||
};
|
||||
|
||||
struct hid_device_state
|
||||
|
@ -161,7 +180,7 @@ extern BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usa
|
|||
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_physical(struct unix_device *iface) DECLSPEC_HIDDEN;
|
||||
extern BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT count) 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;
|
||||
|
|
|
@ -99,6 +99,12 @@ static NTSTATUS mouse_physical_effect_control(struct unix_device *iface, BYTE in
|
|||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static NTSTATUS mouse_physical_effect_update(struct unix_device *iface, BYTE index,
|
||||
struct effect_params *params)
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static const struct hid_device_vtbl mouse_vtbl =
|
||||
{
|
||||
mouse_destroy,
|
||||
|
@ -107,6 +113,7 @@ static const struct hid_device_vtbl mouse_vtbl =
|
|||
mouse_haptics_start,
|
||||
mouse_physical_device_control,
|
||||
mouse_physical_effect_control,
|
||||
mouse_physical_effect_update,
|
||||
};
|
||||
|
||||
static const struct device_desc mouse_device_desc =
|
||||
|
@ -169,6 +176,12 @@ static NTSTATUS keyboard_physical_effect_control(struct unix_device *iface, BYTE
|
|||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static NTSTATUS keyboard_physical_effect_update(struct unix_device *iface, BYTE index,
|
||||
struct effect_params *params)
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static const struct hid_device_vtbl keyboard_vtbl =
|
||||
{
|
||||
keyboard_destroy,
|
||||
|
@ -177,6 +190,7 @@ static const struct hid_device_vtbl keyboard_vtbl =
|
|||
keyboard_haptics_start,
|
||||
keyboard_physical_device_control,
|
||||
keyboard_physical_effect_control,
|
||||
keyboard_physical_effect_update,
|
||||
};
|
||||
|
||||
static const struct device_desc keyboard_device_desc =
|
||||
|
|
Loading…
Reference in New Issue