[PATCH 3/4] hid: Implement HidP_UnsetUsages.
Rémi Bernon
rbernon at codeweavers.com
Wed Aug 25 11:08:32 CDT 2021
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/hid/hid.spec | 2 +-
dlls/hid/hidp.c | 59 ++++++++++++++++++++++++++++++
dlls/ntoskrnl.exe/tests/ntoskrnl.c | 12 +++++-
include/ddk/hidpi.h | 1 +
4 files changed, 71 insertions(+), 3 deletions(-)
diff --git a/dlls/hid/hid.spec b/dlls/hid/hid.spec
index edfdb004fd0..5d4706e3727 100644
--- a/dlls/hid/hid.spec
+++ b/dlls/hid/hid.spec
@@ -40,5 +40,5 @@
@ stdcall HidP_SetUsageValueArray(long long long long ptr long ptr ptr long)
@ stdcall HidP_SetUsages(long long long ptr ptr ptr ptr long)
@ stdcall HidP_TranslateUsagesToI8042ScanCodes(ptr long long ptr ptr ptr)
-@ stub HidP_UnsetUsages
+@ stdcall HidP_UnsetUsages(long long long ptr ptr ptr ptr long)
@ stub HidP_UsageListDifference
diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c
index 31f1b85f14a..8c43d27f252 100644
--- a/dlls/hid/hidp.c
+++ b/dlls/hid/hidp.c
@@ -481,6 +481,65 @@ NTSTATUS WINAPI HidP_SetUsages( HIDP_REPORT_TYPE report_type, USAGE usage_page,
return HIDP_STATUS_SUCCESS;
}
+struct unset_usage_params
+{
+ USAGE usage;
+ char *report_buf;
+ BOOL found;
+};
+
+static NTSTATUS unset_usage( const struct hid_value_caps *caps, void *user )
+{
+ struct unset_usage_params *params = user;
+ ULONG bit, index, last;
+
+ if (HID_VALUE_CAPS_IS_ARRAY( caps ))
+ {
+ for (bit = caps->start_bit, last = bit + caps->report_count * caps->bit_size - 1; bit <= last; bit += 8)
+ {
+ index = caps->start_index + params->usage - caps->usage_min;
+ if (params->report_buf[bit / 8] != index) continue;
+ params->report_buf[bit / 8] = 0;
+ params->found = TRUE;
+ break;
+ }
+
+ return HIDP_STATUS_NULL;
+ }
+
+ bit = caps->start_bit + params->usage - caps->usage_min;
+ if (params->report_buf[bit / 8] & (1 << (bit % 8))) params->found = TRUE;
+ params->report_buf[bit / 8] &= ~(1 << (bit % 8));
+ return HIDP_STATUS_NULL;
+}
+
+NTSTATUS WINAPI HidP_UnsetUsages( HIDP_REPORT_TYPE report_type, USAGE usage_page, USHORT collection, USAGE *usages,
+ ULONG *usage_count, PHIDP_PREPARSED_DATA preparsed_data, char *report_buf, ULONG report_len )
+{
+ struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)preparsed_data;
+ struct unset_usage_params params = {.report_buf = report_buf, .found = FALSE};
+ struct caps_filter filter = {.buttons = TRUE, .usage_page = usage_page, .collection = collection};
+ NTSTATUS status;
+ USHORT limit = 1;
+ ULONG i, count = *usage_count;
+
+ TRACE( "report_type %d, usage_page %x, collection %d, usages %p, usage_count %p, preparsed_data %p, "
+ "report_buf %p, report_len %u.\n",
+ report_type, usage_page, collection, usages, usage_count, preparsed_data, report_buf, report_len );
+
+ if (!report_len) return HIDP_STATUS_INVALID_REPORT_LENGTH;
+
+ filter.report_id = report_buf[0];
+ for (i = 0; i < count; ++i)
+ {
+ params.usage = filter.usage = usages[i];
+ status = enum_value_caps( preparsed, report_type, report_len, &filter, unset_usage, ¶ms, &limit );
+ if (status != HIDP_STATUS_SUCCESS) return status;
+ }
+
+ if (!params.found) return HIDP_STATUS_BUTTON_NOT_PRESSED;
+ return HIDP_STATUS_SUCCESS;
+}
NTSTATUS WINAPI HidP_TranslateUsagesToI8042ScanCodes(USAGE *ChangedUsageList,
ULONG UsageListLength, HIDP_KEYBOARD_DIRECTION KeyAction,
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
index 7f4874d1f9e..34491500423 100644
--- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
@@ -2344,8 +2344,16 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled
report[caps.InputReportByteLength - 2]);
ok(report[caps.InputReportByteLength - 1] == 4, "unexpected usage index %d, expected 4\n",
report[caps.InputReportByteLength - 1]);
- report[caps.InputReportByteLength - 2] = 0;
- report[caps.InputReportByteLength - 1] = 0;
+ status = HidP_UnsetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data,
+ report, caps.InputReportByteLength);
+ ok(status == HIDP_STATUS_SUCCESS, "HidP_UnsetUsages returned %#x\n", status);
+ ok(report[caps.InputReportByteLength - 2] == 0, "unexpected usage index %d, expected 0\n",
+ report[caps.InputReportByteLength - 2]);
+ ok(report[caps.InputReportByteLength - 1] == 0, "unexpected usage index %d, expected 0\n",
+ report[caps.InputReportByteLength - 1]);
+ status = HidP_UnsetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data,
+ report, caps.InputReportByteLength);
+ ok(status == HIDP_STATUS_BUTTON_NOT_PRESSED, "HidP_UnsetUsages returned %#x\n", status);
value = 1;
usages[0] = 0x8c;
status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data,
diff --git a/include/ddk/hidpi.h b/include/ddk/hidpi.h
index 6dfe5919b4f..305c38a95d3 100644
--- a/include/ddk/hidpi.h
+++ b/include/ddk/hidpi.h
@@ -209,6 +209,7 @@ NTSTATUS WINAPI HidP_SetUsageValueArray( HIDP_REPORT_TYPE ReportType, USAGE Usag
NTSTATUS WINAPI HidP_SetUsages(HIDP_REPORT_TYPE ReportType, USAGE UsagePage,
USHORT LinkCollection, PUSAGE UsageList, PULONG UsageLength,
PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength);
+NTSTATUS WINAPI HidP_UnsetUsages(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, PUSAGE UsageList, PULONG UsageLength, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength);
NTSTATUS WINAPI HidP_TranslateUsagesToI8042ScanCodes(USAGE *ChangedUsageList, ULONG UsageListLength, HIDP_KEYBOARD_DIRECTION KeyAction, HIDP_KEYBOARD_MODIFIER_STATE *ModifierState, PHIDP_INSERT_SCANCODES InsertCodesProcedure, VOID *InsertCodesContext);
NTSTATUS WINAPI HidP_GetSpecificButtonCaps(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE Usage, HIDP_BUTTON_CAPS *ButtonCaps, USHORT *ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
NTSTATUS WINAPI HidP_GetSpecificValueCaps(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE Usage, HIDP_VALUE_CAPS *ValueCaps, USHORT *ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
--
2.33.0
More information about the wine-devel
mailing list