Module: wine Branch: master Commit: 6f2e66963ca5e2780a664a7bbc962a08b77585d7 URL: https://source.winehq.org/git/wine.git/?a=commit;h=6f2e66963ca5e2780a664a7bb...
Author: Rémi Bernon rbernon@codeweavers.com Date: Fri Oct 8 09:50:19 2021 +0200
winebus.sys: Add a PID set periodic output report.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/winebus.sys/bus_sdl.c | 4 ++ dlls/winebus.sys/bus_udev.c | 4 ++ dlls/winebus.sys/hid.c | 107 ++++++++++++++++++++++++++++++++++++++++ dlls/winebus.sys/unix_private.h | 13 +++++ 4 files changed, 128 insertions(+)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 4eab51b5cb2..1bec3661757 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -549,6 +549,10 @@ static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYT effect.periodic.direction.type = SDL_HAPTIC_SPHERICAL; effect.periodic.direction.dir[0] = params->direction[0] * 36000 / 256; effect.periodic.direction.dir[1] = params->direction[1] * 36000 / 256; + effect.periodic.period = params->periodic.period; + effect.periodic.magnitude = params->periodic.magnitude * 128; + effect.periodic.offset = params->periodic.offset; + effect.periodic.phase = params->periodic.phase; break;
case PID_USAGE_ET_SPRING: diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index f780aac2785..e60891c2244 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -1001,6 +1001,10 @@ static NTSTATUS lnxev_device_physical_effect_update(struct unix_device *iface, B 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; break;
case PID_USAGE_ET_SPRING: diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index 72d358e6ad7..10e9316eb6c 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -440,8 +440,85 @@ struct pid_effect_update BYTE enable_bits; BYTE direction[2]; }; + +struct pid_set_periodic +{ + BYTE index; + BYTE magnitude; + BYTE offset; + BYTE phase; + UINT16 period; +}; #include "poppack.h"
+static BOOL hid_descriptor_add_set_periodic(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[] = + { + /* Periodic Report Definition */ + USAGE(1, PID_USAGE_SET_PERIODIC_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_MAGNITUDE), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(2, 0x00ff), + PHYSICAL_MINIMUM(1, 0), + PHYSICAL_MAXIMUM(2, 10000), + REPORT_SIZE(1, 8), + REPORT_COUNT(1, 1), + OUTPUT(1, Data|Var|Abs), + + USAGE(1, PID_USAGE_OFFSET), + LOGICAL_MINIMUM(1, 0x80), + LOGICAL_MAXIMUM(1, 0x7f), + PHYSICAL_MINIMUM(2, -10000), + PHYSICAL_MAXIMUM(2, 10000), + REPORT_SIZE(1, 8), + REPORT_COUNT(1, 1), + OUTPUT(1, Data|Var|Abs), + + USAGE(1, PID_USAGE_PHASE), + UNIT(1, 0x14), /* Eng Rot:Angular Pos */ + UNIT_EXPONENT(1, -2), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(2, 0xff), + PHYSICAL_MINIMUM(1, 0), + PHYSICAL_MAXIMUM(4, 36000), + REPORT_SIZE(1, 8), + REPORT_COUNT(1, 1), + OUTPUT(1, Data|Var|Abs), + + USAGE(1, PID_USAGE_PERIOD), + 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, 1), + OUTPUT(1, Data|Var|Abs), + + PHYSICAL_MAXIMUM(1, 0), + UNIT_EXPONENT(1, 0), + UNIT(1, 0), /* None */ + END_COLLECTION, + }; + + iface->hid_physical.set_periodic_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; @@ -592,6 +669,7 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co UNIT(1, 0), /* None */ END_COLLECTION, }; + BOOL periodic = FALSE; ULONG i;
if (!hid_report_descriptor_append(desc, device_control_header, sizeof(device_control_header))) @@ -624,6 +702,19 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co if (!hid_report_descriptor_append(desc, effect_update_footer, sizeof(effect_update_footer))) return FALSE;
+ for (i = 0; i < count; ++i) + { + if (usages[i] == PID_USAGE_ET_SINE || + usages[i] == PID_USAGE_ET_SQUARE || + usages[i] == PID_USAGE_ET_TRIANGLE || + usages[i] == PID_USAGE_ET_SAWTOOTH_UP || + usages[i] == PID_USAGE_ET_SAWTOOTH_DOWN) + periodic = TRUE; + } + + if (periodic && !hid_descriptor_add_set_periodic(iface)) + return FALSE; + /* HID nary collection indexes start at 1 */ memcpy(iface->hid_physical.effect_types + 1, usages, count * sizeof(*usages));
@@ -751,6 +842,22 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC io->Status = iface->hid_vtbl->physical_effect_update(iface, report->index, params); } } + else if (packet->reportId == physical->set_periodic_report) + { + struct pid_set_periodic *report = (struct pid_set_periodic *)(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->periodic.magnitude = report->magnitude; + params->periodic.offset = report->offset; + params->periodic.phase = report->phase; + params->periodic.period = report->period; + } + } else { io->Information = 0; diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index 125ee600eb6..5962de7fb10 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -29,6 +29,14 @@
#include "wine/list.h"
+struct effect_periodic +{ + BYTE magnitude; + BYTE offset; + BYTE phase; + UINT16 period; +}; + struct effect_params { USAGE effect_type; @@ -41,6 +49,10 @@ struct effect_params BOOL axis_enabled[2]; BOOL direction_enabled; BYTE direction[2]; + union + { + struct effect_periodic periodic; + }; };
struct raw_device_vtbl @@ -112,6 +124,7 @@ struct hid_physical BYTE device_control_report; BYTE effect_control_report; BYTE effect_update_report; + BYTE set_periodic_report; };
struct hid_device_state