Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_sdl.c | 16 ++++++++- dlls/winebus.sys/bus_udev.c | 9 ++++- dlls/winebus.sys/hid.c | 59 +++++++++++++++++++++++++++++++++ dlls/winebus.sys/unix_private.h | 8 +++++ 4 files changed, 90 insertions(+), 2 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 14546467863..4fb91e4dc6d 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -213,6 +213,7 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl) if (impl->effect_support & SDL_HAPTIC_INERTIA) usages[count++] = PID_USAGE_ET_INERTIA; if (impl->effect_support & SDL_HAPTIC_FRICTION) usages[count++] = PID_USAGE_ET_FRICTION; if (impl->effect_support & SDL_HAPTIC_CONSTANT) usages[count++] = PID_USAGE_ET_CONSTANT_FORCE; + if (impl->effect_support & SDL_HAPTIC_RAMP) usages[count++] = PID_USAGE_ET_RAMP;
if (!hid_device_add_physical(&impl->unix_device, usages, count)) return FALSE; @@ -610,8 +611,21 @@ static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYT break;
case PID_USAGE_ET_RAMP: - FIXME("not implemented!"); + effect.ramp.length = params->duration; + effect.ramp.delay = params->start_delay; + effect.ramp.button = params->trigger_button; + effect.ramp.interval = params->trigger_repeat_interval; + effect.ramp.direction.type = SDL_HAPTIC_SPHERICAL; + effect.ramp.direction.dir[0] = params->direction[0] * 36000 / 256; + effect.ramp.direction.dir[1] = params->direction[1] * 36000 / 256; + effect.ramp.start = params->ramp_force.ramp_start; + effect.ramp.end = params->ramp_force.ramp_end; + effect.ramp.attack_length = params->envelope.attack_time; + effect.ramp.attack_level = params->envelope.attack_level; + effect.ramp.fade_length = params->envelope.fade_time; + effect.ramp.fade_level = params->envelope.fade_level; break; + case PID_USAGE_ET_CUSTOM_FORCE_DATA: FIXME("not implemented!"); break; diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 6067500117c..cc54d6490be 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -677,6 +677,7 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d if (test_bit(ffbits, FF_INERTIA)) usages[count++] = PID_USAGE_ET_INERTIA; if (test_bit(ffbits, FF_FRICTION)) usages[count++] = PID_USAGE_ET_FRICTION; 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)) return STATUS_NO_MEMORY; @@ -1048,8 +1049,14 @@ static NTSTATUS lnxev_device_physical_effect_update(struct unix_device *iface, B break;
case PID_USAGE_ET_RAMP: - FIXME("not implemented!"); + effect.u.ramp.start_level = params->ramp_force.ramp_start; + effect.u.ramp.end_level = params->ramp_force.ramp_end; + effect.u.ramp.envelope.attack_length = params->envelope.attack_time; + effect.u.ramp.envelope.attack_level = params->envelope.attack_level; + effect.u.ramp.envelope.fade_length = params->envelope.fade_time; + effect.u.ramp.envelope.fade_level = params->envelope.fade_level; break; + case PID_USAGE_ET_CUSTOM_FORCE_DATA: FIXME("not implemented!"); break; diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index 4c55367e78d..a0f07f66392 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -477,6 +477,12 @@ struct pid_set_constant_force UINT16 magnitude; };
+struct pid_set_ramp_force +{ + BYTE index; + BYTE ramp_start; + BYTE ramp_end; +}; #include "poppack.h"
static BOOL hid_descriptor_add_set_periodic(struct unix_device *iface) @@ -675,6 +681,40 @@ static BOOL hid_descriptor_add_set_constant_force(struct unix_device *iface) return hid_report_descriptor_append(desc, template, sizeof(template)); }
+static BOOL hid_descriptor_add_set_ramp_force(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[] = + { + /* Ramp Force Report Definition */ + USAGE(1, PID_USAGE_SET_RAMP_FORCE_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_RAMP_START), + USAGE(1, PID_USAGE_RAMP_END), + LOGICAL_MINIMUM(1, 0x80), + LOGICAL_MAXIMUM(1, 0x7f), + PHYSICAL_MINIMUM(2, -10000), + PHYSICAL_MAXIMUM(2, +10000), + REPORT_SIZE(1, 8), + REPORT_COUNT(1, 2), + OUTPUT(1, Data|Var|Abs), + END_COLLECTION, + }; + + iface->hid_physical.set_ramp_force_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; @@ -829,6 +869,7 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co BOOL envelope = FALSE; BOOL condition = FALSE; BOOL constant_force = FALSE; + BOOL ramp_force = FALSE; ULONG i;
if (!hid_report_descriptor_append(desc, device_control_header, sizeof(device_control_header))) @@ -876,6 +917,8 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co condition = TRUE; if (usages[i] == PID_USAGE_ET_CONSTANT_FORCE) envelope = constant_force = TRUE; + if (usages[i] == PID_USAGE_ET_RAMP) + envelope = ramp_force = TRUE; }
if (periodic && !hid_descriptor_add_set_periodic(iface)) @@ -886,6 +929,8 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co return FALSE; if (constant_force && !hid_descriptor_add_set_constant_force(iface)) return FALSE; + if (ramp_force && !hid_descriptor_add_set_ramp_force(iface)) + return FALSE;
/* HID nary collection indexes start at 1 */ memcpy(iface->hid_physical.effect_types + 1, usages, count * sizeof(*usages)); @@ -1082,6 +1127,20 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC else params->constant_force.magnitude = report->magnitude; } + else if (packet->reportId == physical->set_ramp_force_report) + { + struct pid_set_ramp_force *report = (struct pid_set_ramp_force *)(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->ramp_force.ramp_start = report->ramp_start; + params->ramp_force.ramp_end = report->ramp_end; + } + } else { io->Information = 0; diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index bd0e3272593..61c6dbb1deb 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -60,6 +60,12 @@ struct effect_constant_force UINT16 magnitude; };
+struct effect_ramp_force +{ + BYTE ramp_start; + BYTE ramp_end; +}; + struct effect_params { USAGE effect_type; @@ -80,6 +86,7 @@ struct effect_params struct effect_periodic periodic; struct effect_condition condition[2]; struct effect_constant_force constant_force; + struct effect_ramp_force ramp_force; }; };
@@ -156,6 +163,7 @@ struct hid_physical BYTE set_envelope_report; BYTE set_condition_report; BYTE set_constant_force_report; + BYTE set_ramp_force_report; };
struct hid_device_state