Instead of having the waveforms combined. This better matches what Windows.Gaming.Input and Windows.Devices.Haptics are exposing, with one SimpleHapticsController for each motor.
This will also simplify the declaration of left/right trigger motors.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/hid.c | 89 +++++++++++++++++++++++++++++++-- dlls/winebus.sys/unix_private.h | 12 +++++ 2 files changed, 98 insertions(+), 3 deletions(-)
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index 3e83a05cdf6..46336716a70 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -337,6 +337,11 @@ struct hid_haptics_waveform BYTE manual_trigger; BYTE repeat_count; }; +struct hid_haptics_intensity +{ + UINT16 rumble_intensity; + UINT16 buzz_intensity; +}; #include "poppack.h"
BOOL hid_device_add_haptics(struct unix_device *iface) @@ -344,7 +349,8 @@ BOOL hid_device_add_haptics(struct unix_device *iface) struct hid_report_descriptor *desc = &iface->hid_report_descriptor; const BYTE haptics_features_report = ++desc->next_report_id[HidP_Feature]; const BYTE haptics_waveform_report = ++desc->next_report_id[HidP_Output]; - const BYTE haptics_template[] = + const BYTE haptics_intensity_report = ++desc->next_report_id[HidP_Output]; + const BYTE waveforms_template[] = { USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS), USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER), @@ -404,16 +410,75 @@ BOOL hid_device_add_haptics(struct unix_device *iface) OUTPUT(1, Data|Var|Abs), END_COLLECTION, }; + const BYTE haptics_template[] = + { + USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS), + USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER), + COLLECTION(1, Logical), + REPORT_ID(1, haptics_features_report), + + USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_LIST), + COLLECTION(1, NamedArray), + USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|3), + REPORT_SIZE(1, 16), + REPORT_COUNT(1, 1), + FEATURE(1, Data|Var|Abs|Null), + END_COLLECTION, + + USAGE(1, HID_USAGE_HAPTICS_DURATION_LIST), + COLLECTION(1, NamedArray), + USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|3), + REPORT_SIZE(1, 16), + REPORT_COUNT(1, 1), + FEATURE(1, Data|Var|Abs|Null), + END_COLLECTION, + + USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME), + UNIT(2, 0x1001), /* seconds */ + UNIT_EXPONENT(1, -3), /* 10^-3 */ + LOGICAL_MINIMUM(4, 0x00000000), + LOGICAL_MAXIMUM(4, 0x7fffffff), + REPORT_SIZE(1, 32), + REPORT_COUNT(1, 1), + FEATURE(1, Data|Var|Abs), + /* reset global items */ + UNIT(1, 0), /* None */ + UNIT_EXPONENT(1, 0), + + REPORT_ID(1, haptics_intensity_report), + USAGE(1, HID_USAGE_HAPTICS_INTENSITY), + LOGICAL_MINIMUM(4, 0x00000000), + LOGICAL_MAXIMUM(4, 0x0000ffff), + REPORT_SIZE(1, 16), + REPORT_COUNT(1, 1), + OUTPUT(1, Data|Var|Abs), + END_COLLECTION, + };
iface->hid_haptics.features_report = haptics_features_report; iface->hid_haptics.waveform_report = haptics_waveform_report; + iface->hid_haptics.intensity_report = haptics_intensity_report; iface->hid_haptics.features.waveform_list[0] = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE; iface->hid_haptics.features.waveform_list[1] = HID_USAGE_HAPTICS_WAVEFORM_BUZZ; iface->hid_haptics.features.duration_list[0] = 0; iface->hid_haptics.features.duration_list[1] = 0; iface->hid_haptics.features.waveform_cutoff_time_ms = 1000; + iface->hid_haptics.features.rumble.waveform = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE; + iface->hid_haptics.features.rumble.duration = 0; + iface->hid_haptics.features.rumble.cutoff_time_ms = 1000; + iface->hid_haptics.features.buzz.waveform = HID_USAGE_HAPTICS_WAVEFORM_BUZZ; + iface->hid_haptics.features.buzz.duration = 0; + iface->hid_haptics.features.buzz.cutoff_time_ms = 1000;
- return hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)); + if (!hid_report_descriptor_append(desc, waveforms_template, sizeof(waveforms_template))) + return FALSE; + + if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template))) + return FALSE; + if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template))) + return FALSE; + + return TRUE; }
#include "pshpack1.h" @@ -1072,7 +1137,23 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC struct hid_physical *physical = &iface->hid_physical; struct hid_haptics *haptics = &iface->hid_haptics;
- if (packet->reportId == haptics->waveform_report) + if (packet->reportId == haptics->intensity_report) + { + struct hid_haptics_intensity *report = (struct hid_haptics_intensity *)(packet->reportBuffer + 1); + ULONG duration_ms; + + io->Information = sizeof(*report) + 1; + assert(packet->reportBufferLen == io->Information); + + if (!report->rumble_intensity && !report->buzz_intensity) + io->Status = iface->hid_vtbl->haptics_stop(iface); + else + { + duration_ms = min(haptics->features.rumble.cutoff_time_ms, haptics->features.buzz.cutoff_time_ms); + io->Status = iface->hid_vtbl->haptics_start(iface, duration_ms, report->rumble_intensity, report->buzz_intensity); + } + } + else if (packet->reportId == haptics->waveform_report) { struct hid_haptics_waveform *report = (struct hid_haptics_waveform *)(packet->reportBuffer + 1); UINT16 *rumble_intensity = haptics->waveform_intensity + HAPTICS_WAVEFORM_RUMBLE_ORDINAL; @@ -1307,6 +1388,8 @@ static void hid_device_set_feature_report(struct unix_device *iface, HID_XFER_PA assert(packet->reportBufferLen == io->Information);
haptics->features.waveform_cutoff_time_ms = features->waveform_cutoff_time_ms; + haptics->features.rumble.cutoff_time_ms = features->rumble.cutoff_time_ms; + haptics->features.buzz.cutoff_time_ms = features->buzz.cutoff_time_ms; io->Status = STATUS_SUCCESS; } else diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index 553631e40fb..081e57dc53d 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -138,12 +138,23 @@ enum haptics_waveform_ordinal HAPTICS_WAVEFORM_LAST_ORDINAL = HAPTICS_WAVEFORM_BUZZ_ORDINAL, };
+#include "pshpack1.h" +struct hid_haptics_feature +{ + WORD waveform; + WORD duration; + UINT cutoff_time_ms; +}; + struct hid_haptics_features { WORD waveform_list[HAPTICS_WAVEFORM_LAST_ORDINAL - HAPTICS_WAVEFORM_FIRST_ORDINAL + 1]; WORD duration_list[HAPTICS_WAVEFORM_LAST_ORDINAL - HAPTICS_WAVEFORM_FIRST_ORDINAL + 1]; UINT waveform_cutoff_time_ms; + struct hid_haptics_feature rumble; + struct hid_haptics_feature buzz; }; +#include "poppack.h"
struct hid_haptics { @@ -151,6 +162,7 @@ struct hid_haptics UINT16 waveform_intensity[HAPTICS_WAVEFORM_LAST_ORDINAL + 1]; BYTE features_report; BYTE waveform_report; + BYTE intensity_report; };
/* must match the order and number of usages in the
With individual waveform intensity caps, instead of a complicated waveform manual trigger. Also ignore collections with Z/RZ physical usages, later used to describe trigger haptics controllers.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/xinput1_3/main.c | 224 ++++++++++++++++++------------------------ 1 file changed, 93 insertions(+), 131 deletions(-)
diff --git a/dlls/xinput1_3/main.c b/dlls/xinput1_3/main.c index 909ef9e7dfd..112fa5b436d 100644 --- a/dlls/xinput1_3/main.c +++ b/dlls/xinput1_3/main.c @@ -81,10 +81,8 @@ struct xinput_controller char *feature_report_buf;
BYTE haptics_report; - BYTE haptics_none_ordinal; - BYTE haptics_stop_ordinal; - BYTE haptics_rumble_ordinal; - BYTE haptics_buzz_ordinal; + HIDP_VALUE_CAPS haptics_rumble_caps; + HIDP_VALUE_CAPS haptics_buzz_caps; } hid; };
@@ -153,16 +151,74 @@ static void check_value_caps(struct xinput_controller *controller, USHORT usage, } }
+static void check_waveform_caps(struct xinput_controller *controller, HANDLE device, PHIDP_PREPARSED_DATA preparsed, + HIDP_LINK_COLLECTION_NODE *collections, HIDP_VALUE_CAPS *caps) +{ + USHORT count, report_len = controller->hid.caps.FeatureReportByteLength; + char *report_buf = controller->hid.feature_report_buf; + ULONG parent = caps->LinkCollection, waveform = 0; + HIDP_VALUE_CAPS value_caps; + USAGE_AND_PAGE phy_usages; + NTSTATUS status; + + while (collections[parent].LinkUsagePage != HID_USAGE_PAGE_HAPTICS || + collections[parent].LinkUsage != HID_USAGE_HAPTICS_SIMPLE_CONTROLLER) + if (!(parent = collections[parent].Parent)) break; + + if (collections[parent].LinkUsagePage != HID_USAGE_PAGE_HAPTICS || + collections[parent].LinkUsage != HID_USAGE_HAPTICS_SIMPLE_CONTROLLER) + { + WARN("Failed to find haptics simple controller collection\n"); + return; + } + phy_usages.UsagePage = collections[collections[parent].Parent].LinkUsagePage; + phy_usages.Usage = collections[collections[parent].Parent].LinkUsage; + + status = HidP_InitializeReportForID(HidP_Feature, caps->ReportID, preparsed, report_buf, report_len); + if (status != HIDP_STATUS_SUCCESS) WARN("HidP_InitializeReportForID returned %#lx\n", status); + if (!HidD_GetFeature(device, report_buf, report_len)) + { + WARN("Failed to get waveform list report, error %lu\n", GetLastError()); + return; + } + + status = HidP_GetUsageValue(HidP_Feature, caps->UsagePage, caps->LinkCollection, caps->NotRange.Usage, + &waveform, preparsed, report_buf, report_len); + if (status != HIDP_STATUS_SUCCESS) WARN("HidP_GetUsageValue returned %#lx\n", status); + + count = 1; + status = HidP_GetSpecificValueCaps(HidP_Output, HID_USAGE_PAGE_HAPTICS, parent, HID_USAGE_HAPTICS_INTENSITY, + &value_caps, &count, preparsed); + if (status != HIDP_STATUS_SUCCESS || !count) WARN("Failed to get waveform intensity caps, status %#lx\n", status); + else if (phy_usages.UsagePage == HID_USAGE_PAGE_GENERIC && phy_usages.Usage == HID_USAGE_GENERIC_Z) + TRACE( "Ignoring left rumble caps\n" ); + else if (phy_usages.UsagePage == HID_USAGE_PAGE_GENERIC && phy_usages.Usage == HID_USAGE_GENERIC_RZ) + TRACE( "Ignoring right rumble caps\n" ); + else if (waveform == HID_USAGE_HAPTICS_WAVEFORM_RUMBLE) + { + TRACE("Found rumble caps, report %u collection %u\n", value_caps.ReportID, value_caps.LinkCollection); + controller->hid.haptics_report = value_caps.ReportID; + controller->hid.haptics_rumble_caps = value_caps; + } + else if (waveform == HID_USAGE_HAPTICS_WAVEFORM_BUZZ) + { + TRACE("Found buzz caps, report %u collection %u\n", value_caps.ReportID, value_caps.LinkCollection); + controller->hid.haptics_report = value_caps.ReportID; + controller->hid.haptics_buzz_caps = value_caps; + } + else FIXME("Unsupported waveform type %#lx\n", waveform); +} + static BOOL controller_check_caps(struct xinput_controller *controller, HANDLE device, PHIDP_PREPARSED_DATA preparsed) { - ULONG collections_count = 0, report_len = controller->hid.caps.FeatureReportByteLength; - char *report_buf = controller->hid.feature_report_buf; + USHORT caps_count = 0, waveform_caps_count = 0; XINPUT_CAPABILITIES *caps = &controller->caps; - HIDP_VALUE_CAPS *value_caps, waveform_cap; - int i, u, waveform_list, button_count = 0; HIDP_LINK_COLLECTION_NODE *collections; + HIDP_VALUE_CAPS waveform_caps[8]; HIDP_BUTTON_CAPS *button_caps; - USHORT caps_count = 0; + ULONG collections_count = 0; + HIDP_VALUE_CAPS *value_caps; + int i, u, button_count = 0; NTSTATUS status;
/* Count buttons */ @@ -220,61 +276,23 @@ static BOOL controller_check_caps(struct xinput_controller *controller, HANDLE d else for (i = 0; i < collections_count; ++i) { if (collections[i].LinkUsagePage != HID_USAGE_PAGE_HAPTICS) continue; - if (collections[i].LinkUsage == HID_USAGE_HAPTICS_WAVEFORM_LIST) break; + if (collections[i].LinkUsage == HID_USAGE_HAPTICS_WAVEFORM_LIST) + { + caps_count = ARRAY_SIZE(waveform_caps) - waveform_caps_count; + value_caps = waveform_caps + waveform_caps_count; + status = HidP_GetSpecificValueCaps(HidP_Feature, HID_USAGE_PAGE_ORDINAL, i, 0, value_caps, &caps_count, preparsed); + if (status == HIDP_STATUS_SUCCESS) waveform_caps_count += caps_count; + } } + for (i = 0; i < waveform_caps_count; ++i) check_waveform_caps(controller, device, preparsed, collections, waveform_caps + i); free(collections); - if (status != HIDP_STATUS_SUCCESS || i == collections_count) - { - WARN("could not find haptics waveform list collection\n"); - return TRUE; - } - waveform_list = i;
- caps_count = 1; - status = HidP_GetSpecificValueCaps(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, &waveform_cap, &caps_count, preparsed); - if (status != HIDP_STATUS_SUCCESS || !caps_count) - { - WARN("could not find haptics waveform list report id, status %#lx\n", status); - return TRUE; - } - - status = HidP_InitializeReportForID(HidP_Feature, waveform_cap.ReportID, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_InitializeReportForID returned %#lx\n", status); - if (!HidD_GetFeature(device, report_buf, report_len)) - { - WARN("failed to get waveform list report, error %lu\n", GetLastError()); - return TRUE; - } - - controller->hid.haptics_none_ordinal = 1; /* implicit None waveform ordinal, from the HID spec */ - controller->hid.haptics_stop_ordinal = 2; /* implicit Stop waveform ordinal, from the HID spec */ - controller->hid.haptics_buzz_ordinal = 0; - controller->hid.haptics_rumble_ordinal = 0; - for (i = 3; status == HIDP_STATUS_SUCCESS; ++i) - { - ULONG waveform = 0; - status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, - i, &waveform, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_GetUsageValue returned %#lx\n", status); - else if (waveform == HID_USAGE_HAPTICS_WAVEFORM_BUZZ) controller->hid.haptics_buzz_ordinal = i; - else if (waveform == HID_USAGE_HAPTICS_WAVEFORM_RUMBLE) controller->hid.haptics_rumble_ordinal = i; - } - - if (!controller->hid.haptics_buzz_ordinal) WARN("haptics buzz not supported\n"); - if (!controller->hid.haptics_rumble_ordinal) WARN("haptics rumble not supported\n"); - if (!controller->hid.haptics_rumble_ordinal && !controller->hid.haptics_buzz_ordinal) return TRUE; - - caps_count = 1; - status = HidP_GetSpecificValueCaps(HidP_Output, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_MANUAL_TRIGGER, - &waveform_cap, &caps_count, preparsed); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_GetSpecificValueCaps MANUAL_TRIGGER returned %#lx\n", status); - else if (!caps_count) WARN("haptics manual trigger not supported\n"); - else + if (controller->hid.haptics_rumble_caps.UsagePage || + controller->hid.haptics_buzz_caps.UsagePage) { caps->Flags |= XINPUT_CAPS_FFB_SUPPORTED; caps->Vibration.wLeftMotorSpeed = 255; caps->Vibration.wRightMotorSpeed = 255; - controller->hid.haptics_report = waveform_cap.ReportID; }
return TRUE; @@ -285,9 +303,10 @@ static DWORD HID_set_state(struct xinput_controller *controller, XINPUT_VIBRATIO ULONG report_len = controller->hid.caps.OutputReportByteLength; PHIDP_PREPARSED_DATA preparsed = controller->hid.preparsed; char *report_buf = controller->hid.output_report_buf; - BYTE report_id = controller->hid.haptics_report; - BOOL update_rumble, update_buzz; + BOOL ret, update_rumble, update_buzz; + USHORT collection; NTSTATUS status; + BYTE report_id;
if (!(controller->caps.Flags & XINPUT_CAPS_FFB_SUPPORTED)) return ERROR_SUCCESS;
@@ -297,82 +316,25 @@ static DWORD HID_set_state(struct xinput_controller *controller, XINPUT_VIBRATIO controller->vibration.wRightMotorSpeed = state->wRightMotorSpeed;
if (!controller->enabled) return ERROR_SUCCESS; + if (!update_rumble && !update_buzz) return ERROR_SUCCESS;
- if (!state->wLeftMotorSpeed && !state->wRightMotorSpeed) - { - status = HidP_InitializeReportForID(HidP_Output, report_id, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_InitializeReportForID returned %#lx\n", status); - status = HidP_SetUsageValue(HidP_Output, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_MANUAL_TRIGGER, - controller->hid.haptics_stop_ordinal, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_SetUsageValue MANUAL_TRIGGER returned %#lx\n", status); - if (!HidD_SetOutputReport(controller->device, report_buf, report_len)) - { - WARN("HidD_SetOutputReport failed with error %lu\n", GetLastError()); - return GetLastError(); - } + report_id = controller->hid.haptics_report; + status = HidP_InitializeReportForID(HidP_Output, report_id, preparsed, report_buf, report_len); + if (status != HIDP_STATUS_SUCCESS) WARN("HidP_InitializeReportForID returned %#lx\n", status);
- return 0; - } + collection = controller->hid.haptics_rumble_caps.LinkCollection; + status = HidP_SetUsageValue(HidP_Output, HID_USAGE_PAGE_HAPTICS, collection, HID_USAGE_HAPTICS_INTENSITY, + state->wLeftMotorSpeed, preparsed, report_buf, report_len); + if (status != HIDP_STATUS_SUCCESS) WARN("HidP_SetUsageValue INTENSITY returned %#lx\n", status);
- if (update_rumble) - { - /* send haptics rumble report (left motor) */ - status = HidP_InitializeReportForID(HidP_Output, report_id, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_InitializeReportForID returned %#lx\n", status); - status = HidP_SetUsageValue(HidP_Output, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_INTENSITY, - state->wLeftMotorSpeed, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_SetUsageValue INTENSITY returned %#lx\n", status); - status = HidP_SetUsageValue(HidP_Output, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_MANUAL_TRIGGER, - controller->hid.haptics_rumble_ordinal, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_SetUsageValue MANUAL_TRIGGER returned %#lx\n", status); - status = HidP_SetUsageValue(HidP_Output, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_REPEAT_COUNT, - 0, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_SetUsageValue REPEAT_COUNT returned %#lx\n", status); - if (!HidD_SetOutputReport(controller->device, report_buf, report_len)) - { - WARN("HidD_SetOutputReport failed with error %lu\n", GetLastError()); - return GetLastError(); - } - } + collection = controller->hid.haptics_buzz_caps.LinkCollection; + status = HidP_SetUsageValue(HidP_Output, HID_USAGE_PAGE_HAPTICS, collection, HID_USAGE_HAPTICS_INTENSITY, + state->wRightMotorSpeed, preparsed, report_buf, report_len); + if (status != HIDP_STATUS_SUCCESS) WARN("HidP_SetUsageValue INTENSITY returned %#lx\n", status);
- if (update_buzz) - { - /* send haptics buzz report (right motor) */ - status = HidP_InitializeReportForID(HidP_Output, report_id, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_InitializeReportForID returned %#lx\n", status); - status = HidP_SetUsageValue(HidP_Output, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_INTENSITY, - state->wRightMotorSpeed, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_SetUsageValue INTENSITY returned %#lx\n", status); - status = HidP_SetUsageValue(HidP_Output, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_MANUAL_TRIGGER, - controller->hid.haptics_buzz_ordinal, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_SetUsageValue MANUAL_TRIGGER returned %#lx\n", status); - status = HidP_SetUsageValue(HidP_Output, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_REPEAT_COUNT, - 0, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_SetUsageValue REPEAT_COUNT returned %#lx\n", status); - if (!HidD_SetOutputReport(controller->device, report_buf, report_len)) - { - WARN("HidD_SetOutputReport failed with error %lu\n", GetLastError()); - return GetLastError(); - } - } - - if (update_rumble || update_buzz) - { - /* trigger haptics waveforms */ - status = HidP_InitializeReportForID(HidP_Output, report_id, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_InitializeReportForID returned %#lx\n", status); - status = HidP_SetUsageValue(HidP_Output, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_MANUAL_TRIGGER, - controller->hid.haptics_none_ordinal, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_SetUsageValue MANUAL_TRIGGER returned %#lx\n", status); - status = HidP_SetUsageValue(HidP_Output, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_REPEAT_COUNT, - 1, preparsed, report_buf, report_len); - if (status != HIDP_STATUS_SUCCESS) WARN("HidP_SetUsageValue REPEAT_COUNT returned %#lx\n", status); - if (!HidD_SetOutputReport(controller->device, report_buf, report_len)) - { - WARN("HidD_SetOutputReport failed with error %lu\n", GetLastError()); - return GetLastError(); - } - } + ret = HidD_SetOutputReport(controller->device, report_buf, report_len); + if (!ret) WARN("HidD_SetOutputReport failed with error %lu\n", GetLastError()); + return 0;
return ERROR_SUCCESS; }
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/hid.c | 107 +------------------------------- dlls/winebus.sys/unix_private.h | 20 ------ 2 files changed, 2 insertions(+), 125 deletions(-)
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index 46336716a70..5b18da5d8ed 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -331,12 +331,6 @@ BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usage_page }
#include "pshpack1.h" -struct hid_haptics_waveform -{ - UINT16 intensity; - BYTE manual_trigger; - BYTE repeat_count; -}; struct hid_haptics_intensity { UINT16 rumble_intensity; @@ -348,68 +342,7 @@ BOOL hid_device_add_haptics(struct unix_device *iface) { struct hid_report_descriptor *desc = &iface->hid_report_descriptor; const BYTE haptics_features_report = ++desc->next_report_id[HidP_Feature]; - const BYTE haptics_waveform_report = ++desc->next_report_id[HidP_Output]; const BYTE haptics_intensity_report = ++desc->next_report_id[HidP_Output]; - const BYTE waveforms_template[] = - { - USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS), - USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER), - COLLECTION(1, Logical), - REPORT_ID(1, haptics_features_report), - - USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_LIST), - COLLECTION(1, NamedArray), - USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|HAPTICS_WAVEFORM_RUMBLE_ORDINAL), /* HID_USAGE_HAPTICS_WAVEFORM_RUMBLE */ - USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|HAPTICS_WAVEFORM_BUZZ_ORDINAL), /* HID_USAGE_HAPTICS_WAVEFORM_BUZZ */ - REPORT_COUNT(1, 2), - REPORT_SIZE(1, 16), - FEATURE(1, Data|Var|Abs|Null), - END_COLLECTION, - - USAGE(1, HID_USAGE_HAPTICS_DURATION_LIST), - COLLECTION(1, NamedArray), - USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|HAPTICS_WAVEFORM_RUMBLE_ORDINAL), /* 0 (HID_USAGE_HAPTICS_WAVEFORM_RUMBLE) */ - USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|HAPTICS_WAVEFORM_BUZZ_ORDINAL), /* 0 (HID_USAGE_HAPTICS_WAVEFORM_BUZZ) */ - REPORT_COUNT(1, 2), - REPORT_SIZE(1, 16), - FEATURE(1, Data|Var|Abs|Null), - END_COLLECTION, - - USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME), - UNIT(2, 0x1001), /* seconds */ - UNIT_EXPONENT(1, -3), /* 10^-3 */ - LOGICAL_MINIMUM(4, 0x00000000), - LOGICAL_MAXIMUM(4, 0x7fffffff), - REPORT_SIZE(1, 32), - REPORT_COUNT(1, 1), - FEATURE(1, Data|Var|Abs), - /* reset global items */ - UNIT(1, 0), /* None */ - UNIT_EXPONENT(1, 0), - - REPORT_ID(1, haptics_waveform_report), - USAGE(1, HID_USAGE_HAPTICS_INTENSITY), - LOGICAL_MINIMUM(4, 0x00000000), - LOGICAL_MAXIMUM(4, 0x0000ffff), - REPORT_SIZE(1, 16), - REPORT_COUNT(1, 1), - OUTPUT(1, Data|Var|Abs), - - USAGE(1, HID_USAGE_HAPTICS_MANUAL_TRIGGER), - LOGICAL_MINIMUM(1, HAPTICS_WAVEFORM_NONE_ORDINAL), - LOGICAL_MAXIMUM(1, HAPTICS_WAVEFORM_LAST_ORDINAL), - REPORT_SIZE(1, 8), - REPORT_COUNT(1, 1), - OUTPUT(1, Data|Var|Abs), - - USAGE(1, HID_USAGE_HAPTICS_REPEAT_COUNT), - LOGICAL_MINIMUM(1, 0), - LOGICAL_MAXIMUM(1, 1), - REPORT_SIZE(1, 8), - REPORT_COUNT(1, 1), - OUTPUT(1, Data|Var|Abs), - END_COLLECTION, - }; const BYTE haptics_template[] = { USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS), @@ -419,6 +352,7 @@ BOOL hid_device_add_haptics(struct unix_device *iface)
USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_LIST), COLLECTION(1, NamedArray), + /* ordinal 1 and 2 are reserved for implicit waveforms */ USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|3), REPORT_SIZE(1, 16), REPORT_COUNT(1, 1), @@ -427,6 +361,7 @@ BOOL hid_device_add_haptics(struct unix_device *iface)
USAGE(1, HID_USAGE_HAPTICS_DURATION_LIST), COLLECTION(1, NamedArray), + /* ordinal 1 and 2 are reserved for implicit waveforms */ USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|3), REPORT_SIZE(1, 16), REPORT_COUNT(1, 1), @@ -456,13 +391,7 @@ BOOL hid_device_add_haptics(struct unix_device *iface) };
iface->hid_haptics.features_report = haptics_features_report; - iface->hid_haptics.waveform_report = haptics_waveform_report; iface->hid_haptics.intensity_report = haptics_intensity_report; - iface->hid_haptics.features.waveform_list[0] = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE; - iface->hid_haptics.features.waveform_list[1] = HID_USAGE_HAPTICS_WAVEFORM_BUZZ; - iface->hid_haptics.features.duration_list[0] = 0; - iface->hid_haptics.features.duration_list[1] = 0; - iface->hid_haptics.features.waveform_cutoff_time_ms = 1000; iface->hid_haptics.features.rumble.waveform = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE; iface->hid_haptics.features.rumble.duration = 0; iface->hid_haptics.features.rumble.cutoff_time_ms = 1000; @@ -470,9 +399,6 @@ BOOL hid_device_add_haptics(struct unix_device *iface) iface->hid_haptics.features.buzz.duration = 0; iface->hid_haptics.features.buzz.cutoff_time_ms = 1000;
- if (!hid_report_descriptor_append(desc, waveforms_template, sizeof(waveforms_template))) - return FALSE; - if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template))) return FALSE; if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template))) @@ -1153,34 +1079,6 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC io->Status = iface->hid_vtbl->haptics_start(iface, duration_ms, report->rumble_intensity, report->buzz_intensity); } } - else if (packet->reportId == haptics->waveform_report) - { - struct hid_haptics_waveform *report = (struct hid_haptics_waveform *)(packet->reportBuffer + 1); - UINT16 *rumble_intensity = haptics->waveform_intensity + HAPTICS_WAVEFORM_RUMBLE_ORDINAL; - UINT16 *buzz_intensity = haptics->waveform_intensity + HAPTICS_WAVEFORM_BUZZ_ORDINAL; - ULONG duration_ms; - - io->Information = sizeof(*report) + 1; - assert(packet->reportBufferLen == io->Information); - - if (report->manual_trigger == 0 || report->manual_trigger > HAPTICS_WAVEFORM_LAST_ORDINAL) - io->Status = STATUS_INVALID_PARAMETER; - else - { - if (report->manual_trigger == HAPTICS_WAVEFORM_STOP_ORDINAL) - { - memset(haptics->waveform_intensity, 0, sizeof(haptics->waveform_intensity)); - io->Status = iface->hid_vtbl->haptics_stop(iface); - } - else - { - haptics->waveform_intensity[report->manual_trigger] = report->intensity; - duration_ms = haptics->features.waveform_cutoff_time_ms; - if (!report->repeat_count) io->Status = STATUS_SUCCESS; - else io->Status = iface->hid_vtbl->haptics_start(iface, duration_ms, *rumble_intensity, *buzz_intensity); - } - } - } else if (packet->reportId == physical->device_control_report) { struct pid_device_control *report = (struct pid_device_control *)(packet->reportBuffer + 1); @@ -1387,7 +1285,6 @@ static void hid_device_set_feature_report(struct unix_device *iface, HID_XFER_PA io->Information = sizeof(*features) + 1; assert(packet->reportBufferLen == io->Information);
- haptics->features.waveform_cutoff_time_ms = features->waveform_cutoff_time_ms; haptics->features.rumble.cutoff_time_ms = features->rumble.cutoff_time_ms; haptics->features.buzz.cutoff_time_ms = features->buzz.cutoff_time_ms; io->Status = STATUS_SUCCESS; diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index 081e57dc53d..0763d084823 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -123,21 +123,6 @@ struct hid_report_descriptor BYTE next_report_id[3]; };
-/* HID spec uses None / Stop names for the first two implicit waveforms, - * where Windows SDK headers use STOP / NULL for the corresponding HID - * usage constants. We're not actually using the usages anyway are we - * stick to the HID spec here. - */ -enum haptics_waveform_ordinal -{ - HAPTICS_WAVEFORM_NONE_ORDINAL = 1, /* implicit, not included in waveform_list / duration_list */ - HAPTICS_WAVEFORM_STOP_ORDINAL = 2, /* implicit, not included in waveform_list / duration_list */ - HAPTICS_WAVEFORM_RUMBLE_ORDINAL = 3, - HAPTICS_WAVEFORM_BUZZ_ORDINAL = 4, - HAPTICS_WAVEFORM_FIRST_ORDINAL = HAPTICS_WAVEFORM_RUMBLE_ORDINAL, - HAPTICS_WAVEFORM_LAST_ORDINAL = HAPTICS_WAVEFORM_BUZZ_ORDINAL, -}; - #include "pshpack1.h" struct hid_haptics_feature { @@ -148,9 +133,6 @@ struct hid_haptics_feature
struct hid_haptics_features { - WORD waveform_list[HAPTICS_WAVEFORM_LAST_ORDINAL - HAPTICS_WAVEFORM_FIRST_ORDINAL + 1]; - WORD duration_list[HAPTICS_WAVEFORM_LAST_ORDINAL - HAPTICS_WAVEFORM_FIRST_ORDINAL + 1]; - UINT waveform_cutoff_time_ms; struct hid_haptics_feature rumble; struct hid_haptics_feature buzz; }; @@ -159,9 +141,7 @@ struct hid_haptics_features struct hid_haptics { struct hid_haptics_features features; - UINT16 waveform_intensity[HAPTICS_WAVEFORM_LAST_ORDINAL + 1]; BYTE features_report; - BYTE waveform_report; BYTE intensity_report; };