Rémi Bernon : hid: Rewrite HidP_GetUsages using enum_value_caps.

Alexandre Julliard julliard at winehq.org
Thu Jun 24 16:16:45 CDT 2021


Module: wine
Branch: master
Commit: 1184afb6404b8d817c0bb5974ffc4094d4fa102c
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1184afb6404b8d817c0bb5974ffc4094d4fa102c

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Thu Jun 24 10:05:58 2021 +0200

hid: Rewrite HidP_GetUsages using enum_value_caps.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/hid/hidp.c                    | 98 +++++++++++++-------------------------
 dlls/ntoskrnl.exe/tests/ntoskrnl.c |  3 --
 2 files changed, 33 insertions(+), 68 deletions(-)

diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c
index 6197e30c4da..4889a1e4014 100644
--- a/dlls/hid/hidp.c
+++ b/dlls/hid/hidp.c
@@ -420,82 +420,50 @@ NTSTATUS WINAPI HidP_GetUsageValueArray(HIDP_REPORT_TYPE ReportType, USAGE Usage
 }
 
 
-NTSTATUS WINAPI HidP_GetUsages(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection,
-                               PUSAGE UsageList, PULONG UsageLength, PHIDP_PREPARSED_DATA PreparsedData,
-                               PCHAR Report, ULONG ReportLength)
+struct get_usage_params
 {
-    PWINE_HIDP_PREPARSED_DATA data = (PWINE_HIDP_PREPARSED_DATA)PreparsedData;
-    WINE_HID_ELEMENT *elems = HID_ELEMS(data);
-    WINE_HID_REPORT *report = NULL;
-    BOOL found = FALSE;
-    USHORT b_count = 0, r_count = 0;
-    int i,uCount;
+    USAGE *usages;
+    USAGE *usages_end;
+    char *report_buf;
+};
 
-    TRACE("(%i, %x, %i, %p, %p, %p, %p, %i)\n", ReportType, UsagePage, LinkCollection, UsageList,
-          UsageLength, PreparsedData, Report, ReportLength);
+static NTSTATUS get_usage( const struct hid_value_caps *caps, void *user )
+{
+    struct get_usage_params *params = user;
+    ULONG bit, last;
 
-    if (data->magic != HID_MAGIC)
+    for (bit = caps->start_bit, last = bit + caps->usage_max - caps->usage_min; bit <= last; ++bit)
     {
-        *UsageLength = 0;
-        return HIDP_STATUS_INVALID_PREPARSED_DATA;
+        if (!(params->report_buf[bit / 8] & (1 << (bit % 8)))) continue;
+        if (params->usages < params->usages_end) *params->usages = caps->usage_min + bit - caps->start_bit;
+        params->usages++;
     }
 
-    switch(ReportType)
-    {
-        case HidP_Input:
-            b_count = data->caps.NumberInputButtonCaps;
-            break;
-        case HidP_Output:
-            b_count = data->caps.NumberOutputButtonCaps;
-            break;
-        case HidP_Feature:
-            b_count = data->caps.NumberFeatureButtonCaps;
-            break;
-        default:
-            return HIDP_STATUS_INVALID_REPORT_TYPE;
-    }
-    r_count = data->reportCount[ReportType];
-    report = &data->reports[data->reportIdx[ReportType][(BYTE)Report[0]]];
-
-    if (!r_count || !b_count)
-        return HIDP_STATUS_USAGE_NOT_FOUND;
+    return HIDP_STATUS_SUCCESS;
+}
 
-    if (report->reportID && report->reportID != Report[0])
-        return HIDP_STATUS_REPORT_DOES_NOT_EXIST;
+NTSTATUS WINAPI HidP_GetUsages( HIDP_REPORT_TYPE report_type, USAGE usage_page, USHORT collection, USAGE *usages,
+                                ULONG *usages_len, PHIDP_PREPARSED_DATA preparsed_data, char *report_buf, ULONG report_len )
+{
+    WINE_HIDP_PREPARSED_DATA *preparsed = (WINE_HIDP_PREPARSED_DATA *)preparsed_data;
+    struct get_usage_params params = {.usages = usages, .usages_end = usages + *usages_len, .report_buf = report_buf};
+    struct caps_filter filter = {.buttons = TRUE, .usage_page = usage_page, .collection = collection};
+    NTSTATUS status;
+    USHORT limit = -1;
 
-    uCount = 0;
-    for (i = 0; i < report->elementCount && uCount < *UsageLength; i++)
-    {
-        if (elems[report->elementIdx + i].caps.BitSize == 1 &&
-            elems[report->elementIdx + i].caps.UsagePage == UsagePage)
-        {
-            int k;
-            WINE_HID_ELEMENT *element = &elems[report->elementIdx + i];
-            for (k=0; k < element->bitCount; k++)
-            {
-                UINT v = 0;
-                NTSTATUS rc = get_report_data((BYTE*)Report, ReportLength,
-                                element->valueStartBit + k, 1, &v);
-                if (rc != HIDP_STATUS_SUCCESS)
-                    return rc;
-                found = TRUE;
-                if (v)
-                {
-                    if (uCount == *UsageLength)
-                        return HIDP_STATUS_BUFFER_TOO_SMALL;
-                    UsageList[uCount] = element->caps.Range.UsageMin + k;
-                    uCount++;
-                }
-            }
-        }
-    }
+    TRACE( "report_type %d, collection %d, usages %p, usages_len %p, preparsed_data %p, report_buf %p, report_len %u.\n",
+           report_type, collection, usages, usages_len, preparsed_data, report_buf, report_len );
 
-    *UsageLength = uCount;
+    if (!report_len) return HIDP_STATUS_INVALID_REPORT_LENGTH;
 
-    if (!found)
-        return HIDP_STATUS_USAGE_NOT_FOUND;
+    filter.report_id = report_buf[0];
+    status = enum_value_caps( preparsed, report_type, report_len, &filter, get_usage, &params, &limit );
+    *usages_len = params.usages - usages;
+    if (status != HIDP_STATUS_SUCCESS) return status;
 
-    return HIDP_STATUS_SUCCESS;
+    if (*usages_len == 0) return HIDP_STATUS_USAGE_NOT_FOUND;
+    if (params.usages > params.usages_end) return HIDP_STATUS_BUFFER_TOO_SMALL;
+    return status;
 }
 
 NTSTATUS WINAPI HidP_GetValueCaps( HIDP_REPORT_TYPE report_type, HIDP_VALUE_CAPS *caps, USHORT *caps_count,
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
index 8777880fd9d..b455fe650f1 100644
--- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
@@ -2190,7 +2190,6 @@ static void test_hidp(HANDLE file, int report_id)
     status = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usages, &value,
                             preparsed_data, report, caps.InputReportByteLength);
     ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetUsages returned %#x\n", status);
-    todo_wine
     ok(value == 2, "got usage count %d, expected %d\n", value, 2);
     value = ARRAY_SIZE(usages);
     memset(usages, 0xcd, sizeof(usages));
@@ -2207,9 +2206,7 @@ static void test_hidp(HANDLE file, int report_id)
                             report, caps.InputReportByteLength);
     ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsages returned %#x\n", status);
     ok(value == 2, "got usage count %d, expected %d\n", value, 2);
-    todo_wine
     ok(usages[0] == 6, "got usages[0] %x, expected %x\n", usages[0], 6);
-    todo_wine
     ok(usages[1] == 4, "got usages[1] %x, expected %x\n", usages[1], 4);
 
     value = ARRAY_SIZE(usage_and_pages);




More information about the wine-cvs mailing list