[PATCH 1/3] winebus.sys: Declare multiple HID simple haptics controller collections.
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(a)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 -- 2.35.1
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(a)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; } -- 2.35.1
Signed-off-by: Rémi Bernon <rbernon(a)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; }; -- 2.35.1
participants (1)
-
Rémi Bernon