Rémi Bernon : winebus.sys: Add a PID set periodic output report.
Alexandre Julliard
julliard at winehq.org
Fri Oct 8 14:12:25 CDT 2021
Module: wine
Branch: master
Commit: 6f2e66963ca5e2780a664a7bbc962a08b77585d7
URL: https://source.winehq.org/git/wine.git/?a=commit;h=6f2e66963ca5e2780a664a7bbc962a08b77585d7
Author: Rémi Bernon <rbernon at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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
More information about the wine-cvs
mailing list