Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_sdl.c | 5 ++- dlls/winebus.sys/bus_udev.c | 5 ++- dlls/winebus.sys/hid.c | 79 ++++++++++++++++++++++++++++++++- dlls/winebus.sys/unix_private.h | 11 +++++ 4 files changed, 97 insertions(+), 3 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 1bec3661757..78de600fda6 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -541,7 +541,6 @@ static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYT case PID_USAGE_ET_TRIANGLE: case PID_USAGE_ET_SAWTOOTH_UP: case PID_USAGE_ET_SAWTOOTH_DOWN: - FIXME("periodic effect semi-stub!"); effect.periodic.length = params->duration; effect.periodic.delay = params->start_delay; effect.periodic.button = params->trigger_button; @@ -553,6 +552,10 @@ static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYT effect.periodic.magnitude = params->periodic.magnitude * 128; effect.periodic.offset = params->periodic.offset; effect.periodic.phase = params->periodic.phase; + effect.periodic.attack_length = params->envelope.attack_time; + effect.periodic.attack_level = params->envelope.attack_level; + effect.periodic.fade_length = params->envelope.fade_time; + effect.periodic.fade_level = params->envelope.fade_level; break;
case PID_USAGE_ET_SPRING: diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index e60891c2244..8a47b232148 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -1000,11 +1000,14 @@ static NTSTATUS lnxev_device_physical_effect_update(struct unix_device *iface, B case PID_USAGE_ET_TRIANGLE: case PID_USAGE_ET_SAWTOOTH_UP: case PID_USAGE_ET_SAWTOOTH_DOWN: - FIXME("periodic effect semi-stub!"); effect.u.periodic.period = params->periodic.period; effect.u.periodic.magnitude = params->periodic.magnitude * 128; effect.u.periodic.offset = params->periodic.offset; effect.u.periodic.phase = params->periodic.phase; + effect.u.periodic.envelope.attack_length = params->envelope.attack_time; + effect.u.periodic.envelope.attack_level = params->envelope.attack_level; + effect.u.periodic.envelope.fade_length = params->envelope.fade_time; + effect.u.periodic.envelope.fade_level = params->envelope.fade_level; break;
case PID_USAGE_ET_SPRING: diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index 10e9316eb6c..c25558a5ac4 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -449,6 +449,15 @@ struct pid_set_periodic BYTE phase; UINT16 period; }; + +struct pid_set_envelope +{ + BYTE index; + BYTE attack_level; + BYTE fade_level; + UINT16 attack_time; + UINT16 fade_time; +}; #include "poppack.h"
static BOOL hid_descriptor_add_set_periodic(struct unix_device *iface) @@ -519,6 +528,55 @@ static BOOL hid_descriptor_add_set_periodic(struct unix_device *iface) return hid_report_descriptor_append(desc, template, sizeof(template)); }
+static BOOL hid_descriptor_add_set_envelope(struct unix_device *iface) +{ + struct hid_report_descriptor *desc = &iface->hid_report_descriptor; + const BYTE report_id = ++desc->next_report_id[HidP_Output]; + const BYTE template[] = + { + /* Envelope Report Definition */ + USAGE(1, PID_USAGE_SET_ENVELOPE_REPORT), + COLLECTION(1, Logical), + REPORT_ID(1, report_id), + + 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_ATTACK_LEVEL), + USAGE(1, PID_USAGE_FADE_LEVEL), + LOGICAL_MINIMUM(1, 0x00), + LOGICAL_MAXIMUM(2, 0x00ff), + PHYSICAL_MINIMUM(1, 0), + PHYSICAL_MAXIMUM(2, 10000), + REPORT_SIZE(1, 8), + REPORT_COUNT(1, 2), + OUTPUT(1, Data|Var|Abs), + + USAGE(1, PID_USAGE_ATTACK_TIME), + USAGE(1, PID_USAGE_FADE_TIME), + UNIT(2, 0x1003), /* Eng Lin:Time */ + UNIT_EXPONENT(1, -3), + LOGICAL_MINIMUM(1, 0x00), + LOGICAL_MAXIMUM(2, 0x7fff), + PHYSICAL_MINIMUM(1, 0), + PHYSICAL_MAXIMUM(2, 0x7fff), + REPORT_SIZE(1, 16), + REPORT_COUNT(1, 2), + OUTPUT(1, Data|Var|Abs), + PHYSICAL_MAXIMUM(1, 0), + UNIT_EXPONENT(1, 0), + UNIT(1, 0), + END_COLLECTION, + }; + + iface->hid_physical.set_envelope_report = report_id; + return hid_report_descriptor_append(desc, template, sizeof(template)); +} + BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT count) { struct hid_report_descriptor *desc = &iface->hid_report_descriptor; @@ -670,6 +728,7 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co END_COLLECTION, }; BOOL periodic = FALSE; + BOOL envelope = FALSE; ULONG i;
if (!hid_report_descriptor_append(desc, device_control_header, sizeof(device_control_header))) @@ -709,11 +768,13 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co usages[i] == PID_USAGE_ET_TRIANGLE || usages[i] == PID_USAGE_ET_SAWTOOTH_UP || usages[i] == PID_USAGE_ET_SAWTOOTH_DOWN) - periodic = TRUE; + periodic = envelope = TRUE; }
if (periodic && !hid_descriptor_add_set_periodic(iface)) return FALSE; + if (envelope && !hid_descriptor_add_set_envelope(iface)) + return FALSE;
/* HID nary collection indexes start at 1 */ memcpy(iface->hid_physical.effect_types + 1, usages, count * sizeof(*usages)); @@ -858,6 +919,22 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC params->periodic.period = report->period; } } + else if (packet->reportId == physical->set_envelope_report) + { + struct pid_set_envelope *report = (struct pid_set_envelope *)(packet->reportBuffer + 1); + struct effect_params *params = iface->hid_physical.effect_params + report->index; + + io->Information = sizeof(*report) + 1; + if (packet->reportBufferLen < io->Information) + io->Status = STATUS_BUFFER_TOO_SMALL; + else + { + params->envelope.attack_level = report->attack_level; + params->envelope.fade_level = report->fade_level; + params->envelope.attack_time = report->attack_time; + params->envelope.fade_time = report->fade_time; + } + } else { io->Information = 0; diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index 5962de7fb10..71e6716c7fa 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -37,6 +37,14 @@ struct effect_periodic UINT16 period; };
+struct effect_envelope +{ + BYTE attack_level; + BYTE fade_level; + UINT16 attack_time; + UINT16 fade_time; +}; + struct effect_params { USAGE effect_type; @@ -49,6 +57,8 @@ struct effect_params BOOL axis_enabled[2]; BOOL direction_enabled; BYTE direction[2]; + /* only for periodic, constant or ramp forces */ + struct effect_envelope envelope; union { struct effect_periodic periodic; @@ -125,6 +135,7 @@ struct hid_physical BYTE effect_control_report; BYTE effect_update_report; BYTE set_periodic_report; + BYTE set_envelope_report; };
struct hid_device_state