From: Aric Stewart Subject: [5/11]hid: Implement HidP_GetUsageValue Message-Id: <55928E24.1070504@codeweavers.com> Date: Tue, 30 Jun 2015 07:40:04 -0500 --- dlls/hid/hid.spec | 2 +- dlls/hid/hidp.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ include/ddk/hidpi.h | 1 + 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/dlls/hid/hid.spec b/dlls/hid/hid.spec index 5b63267..b8b4e7f 100644 --- a/dlls/hid/hid.spec +++ b/dlls/hid/hid.spec @@ -26,7 +26,7 @@ @ stub HidP_GetScaledUsageValue @ stub HidP_GetSpecificButtonCaps @ stub HidP_GetSpecificValueCaps -@ stub HidP_GetUsageValue +@ stdcall HidP_GetUsageValue(long long long long ptr ptr ptr long) @ stub HidP_GetUsageValueArray @ stdcall HidP_GetUsages(long long long ptr ptr ptr ptr long) @ stub HidP_GetUsagesEx diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c index 1115160..ef81a4e 100644 --- a/dlls/hid/hidp.c +++ b/dlls/hid/hidp.c @@ -150,6 +150,68 @@ NTSTATUS WINAPI HidP_GetCaps(PHIDP_PREPARSED_DATA PreparsedData, } +NTSTATUS WINAPI HidP_GetUsageValue(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE Usage, PULONG UsageValue, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength) +{ + PWINE_HIDP_PREPARSED_DATA data = (PWINE_HIDP_PREPARSED_DATA)PreparsedData; + WINE_HID_REPORT *report = NULL; + USHORT v_count = 0, r_count = 0; + int i; + + TRACE("(%i, %x, %i, %i, %p, %p, %p, %i)\n", ReportType, UsagePage, LinkCollection, Usage, UsageValue, PreparsedData, Report, ReportLength); + + if (data->magic != HID_MAGIC) + return HIDP_STATUS_INVALID_PREPARSED_DATA; + + switch(ReportType) + { + case HidP_Input: + v_count = data->caps.NumberInputValueCaps; + r_count = data->dwInputReportCount; + report = HID_INPUT_REPORTS(data); + break; + case HidP_Output: + v_count = data->caps.NumberOutputValueCaps; + r_count = data->dwOutputReportCount; + report = HID_OUTPUT_REPORTS(data); + break; + case HidP_Feature: + v_count = data->caps.NumberFeatureValueCaps; + r_count = data->dwFeatureReportCount; + report = HID_FEATURE_REPORTS(data); + break; + default: + return HIDP_STATUS_INVALID_REPORT_TYPE; + } + + if (!r_count || !v_count || !report) + return HIDP_STATUS_USAGE_NOT_FOUND; + + for (i = 0; i < r_count; i++) + { + if (!report->reportID || report->reportID == Report[0]) + break; + report = HID_NEXT_REPORT(data, report); + } + + if (i == r_count) + return HIDP_STATUS_REPORT_DOES_NOT_EXIST; + + for (i = 0; i < report->elementCount; i++) + { + if (report->Elements[i].ElementType == ValueElement && + report->Elements[i].caps.value.UsagePage == UsagePage && + report->Elements[i].caps.value.u.NotRange.Usage == Usage) + { + return GetReportData((BYTE*)Report, ReportLength, + report->Elements[i].valueStartBit, + report->Elements[i].bitCount, UsageValue); + } + } + + return HIDP_STATUS_USAGE_NOT_FOUND; +} + + NTSTATUS WINAPI HidP_GetUsages(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, PUSAGE UsageList, PULONG UsageLength, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength) { PWINE_HIDP_PREPARSED_DATA data = (PWINE_HIDP_PREPARSED_DATA)PreparsedData; diff --git a/include/ddk/hidpi.h b/include/ddk/hidpi.h index fddfa02..45361d2 100644 --- a/include/ddk/hidpi.h +++ b/include/ddk/hidpi.h @@ -139,6 +139,7 @@ typedef struct _HIDP_CAPS NTSTATUS WINAPI HidP_GetButtonCaps(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData); NTSTATUS WINAPI HidP_GetCaps(PHIDP_PREPARSED_DATA PreparsedData, PHIDP_CAPS Capabilities); NTSTATUS WINAPI HidP_GetUsages(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, PUSAGE UsageList, PULONG UsageLength, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength); +NTSTATUS WINAPI HidP_GetUsageValue(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE Usage, PULONG UsageValue, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength); NTSTATUS WINAPI HidP_GetValueCaps(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData);