From: Tomasz Pakuła tomasz.pakula.oficjalny@gmail.com
Allow the PID descriptor building function to create up to PID_AXES_MAX FFB-enabled axes. This will allow better effect handling and support for devices with more than two FFB axis.
Devices with only one axis, can be actually presented as such. --- dlls/winebus.sys/bus_sdl.c | 2 +- dlls/winebus.sys/bus_udev.c | 5 ++- dlls/winebus.sys/hid.c | 63 +++++++++++++++++++++++++++------ dlls/winebus.sys/unix_private.h | 2 +- 4 files changed, 58 insertions(+), 14 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index e050742ca66..29a0d2cf8d2 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -238,7 +238,7 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl, BOOL force) if (force || (impl->effect_support & SDL_HAPTIC_CONSTANT)) usages[count++] = PID_USAGE_ET_CONSTANT_FORCE; if (force || (impl->effect_support & SDL_HAPTIC_RAMP)) usages[count++] = PID_USAGE_ET_RAMP;
- if (!hid_device_add_physical(&impl->unix_device, usages, count)) + if (!hid_device_add_physical(&impl->unix_device, usages, count, 2)) return FALSE; }
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 561f0cdc0e4..f9646d8d6b4 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -648,7 +648,10 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d if (test_bit(ffbits, FF_CONSTANT)) usages[count++] = PID_USAGE_ET_CONSTANT_FORCE; if (test_bit(ffbits, FF_RAMP)) usages[count++] = PID_USAGE_ET_RAMP;
- if (!hid_device_add_physical(iface, usages, count)) + /* Hardcode 2 for now until Linux FF api exposes number of FFB axes + * (previously hardcoded number of PID axes in Wine) + */ + if (!hid_device_add_physical(iface, usages, count, 2)) return STATUS_NO_MEMORY; }
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index 1fdeb88038c..2aa3aabb9c5 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -800,11 +800,36 @@ static BOOL hid_descriptor_add_set_ramp_force(struct unix_device *iface) return hid_report_descriptor_append(desc, template, sizeof(template)); }
-BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT count) +static BOOL hid_descriptor_add_physical_axis_enable(struct unix_device *iface, USHORT i) +{ + struct hid_report_descriptor *desc = &iface->hid_report_descriptor; + USAGE_AND_PAGE uap = iface->hid_device_state.abs_axis_usages[i]; + const BYTE template[] = + { + USAGE(4, (uap.UsagePage<<16)|uap.Usage), + }; + + return hid_report_descriptor_append(desc, template, sizeof(template)); +} + +static BOOL hid_descriptor_add_physical_direction(struct unix_device *iface, USHORT i) +{ + struct hid_report_descriptor *desc = &iface->hid_report_descriptor; + const BYTE template[] = + { + USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|(i+1)), + }; + + return hid_report_descriptor_append(desc, template, sizeof(template)); +} + +BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT count, USHORT num_axes) { 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; + USHORT pid_axes = num_axes > PID_AXES_MAX ? PID_AXES_MAX : num_axes; + const BYTE device_control_header[] = { USAGE_PAGE(1, HID_USAGE_PAGE_PID), @@ -901,7 +926,7 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co USAGE(1, PID_USAGE_EFFECT_TYPE), COLLECTION(1, Logical), }; - const BYTE effect_update_footer[] = + const BYTE effect_update_middle1[] = { LOGICAL_MINIMUM(1, 1), LOGICAL_MAXIMUM(1, count), @@ -939,30 +964,32 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co
USAGE(1, PID_USAGE_AXES_ENABLE), COLLECTION(1, Logical), - USAGE(4, (state->abs_axis_usages[0].UsagePage<<16)|state->abs_axis_usages[0].Usage), - USAGE(4, (state->abs_axis_usages[1].UsagePage<<16)|state->abs_axis_usages[1].Usage), + }; + const BYTE effect_update_middle2[] = + { LOGICAL_MINIMUM(1, 0), LOGICAL_MAXIMUM(1, 1), REPORT_SIZE(1, 1), - REPORT_COUNT(1, 2), + REPORT_COUNT(1, pid_axes), 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 */ + REPORT_COUNT(1, 7 - pid_axes), + OUTPUT(1, Cnst|Var|Abs), /* (8 - pid_axes - direction_enable) 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), + }; + const BYTE effect_update_footer[] = + { UNIT(1, 0x14), /* Eng Rot:Angular Pos */ UNIT_EXPONENT(1, -2), LOGICAL_MINIMUM(1, 0), LOGICAL_MAXIMUM(4, 35900), REPORT_SIZE(1, 16), - REPORT_COUNT(1, 2), + REPORT_COUNT(1, pid_axes), OUTPUT(1, Data|Var|Abs), END_COLLECTION, UNIT_EXPONENT(1, 0), @@ -1033,6 +1060,20 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co if (!hid_report_descriptor_append_usage(desc, usages[i])) return FALSE; } + if (!hid_report_descriptor_append(desc, effect_update_middle1, sizeof(effect_update_middle1))) + return FALSE; + + for (i = 0; i < pid_axes; ++i) { + if (!hid_descriptor_add_physical_axis_enable(iface, i)) + return FALSE; + } + if (!hid_report_descriptor_append(desc, effect_update_middle2, sizeof(effect_update_middle2))) + return FALSE; + + for (i = 0; i < pid_axes; ++i) { + if (!hid_descriptor_add_physical_direction(iface, i)) + return FALSE; + } if (!hid_report_descriptor_append(desc, effect_update_footer, sizeof(effect_update_footer))) return FALSE;
@@ -1076,7 +1117,7 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co iface->hid_physical.device_gain_report = device_gain_report; iface->hid_physical.effect_control_report = effect_control_report; iface->hid_physical.effect_update_report = effect_update_report; - iface->hid_physical.num_axes = 2; + iface->hid_physical.num_axes = pid_axes;
effect_state->id = effect_state_report; effect_state->report_len = sizeof(struct pid_effect_state) + 1; diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index 637e975d068..5d83379dce9 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -255,7 +255,7 @@ extern BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usa const USAGE *usages, BOOL rel, LONG min, LONG max);
extern BOOL hid_device_add_haptics(struct unix_device *iface); -extern BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT count); +extern BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT count, USHORT num_axes);
extern BOOL hid_device_set_abs_axis(struct unix_device *iface, ULONG index, LONG value); extern BOOL hid_device_set_rel_axis(struct unix_device *iface, ULONG index, LONG value);