From a2ab55381843d642582fc9c3ae4fbdfc8a956ee2 Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Fri, 23 Nov 2018 15:09:34 -0600 Subject: [PATCH] hid: Implement HidP_SetUsageValue. Signed-off-by: Aric Stewart Signed-off-by: Alexandre Julliard --- dlls/hid/hid.spec | 2 +- dlls/hid/hidp.c | 65 +++++++++++++++++++++++++++++++++++++++++++++ include/ddk/hidpi.h | 1 + 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/dlls/hid/hid.spec b/dlls/hid/hid.spec index cbae14c8cf5..e4d42023149 100644 --- a/dlls/hid/hid.spec +++ b/dlls/hid/hid.spec @@ -36,7 +36,7 @@ @ stdcall HidP_MaxUsageListLength(long long ptr) @ stub HidP_SetData @ stub HidP_SetScaledUsageValue -@ stub HidP_SetUsageValue +@ stdcall HidP_SetUsageValue(long long long long long ptr ptr long) @ stub HidP_SetUsageValueArray @ stub HidP_SetUsages @ stdcall HidP_TranslateUsagesToI8042ScanCodes(ptr long long ptr ptr ptr) diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c index d6d143e899e..f9978038e39 100644 --- a/dlls/hid/hidp.c +++ b/dlls/hid/hidp.c @@ -81,6 +81,49 @@ static NTSTATUS get_report_data(BYTE *report, INT reportLength, INT startBit, IN return HIDP_STATUS_SUCCESS; } +static NTSTATUS set_report_data(BYTE *report, INT reportLength, INT startBit, INT valueSize, ULONG value) +{ + if ((startBit + valueSize) / 8 > reportLength) + return HIDP_STATUS_INVALID_REPORT_LENGTH; + + if (valueSize == 1) + { + ULONG byte_index = startBit / 8; + ULONG bit_index = startBit - (byte_index * 8); + if (value) + report[byte_index] |= (1 << bit_index); + else + report[byte_index] &= ~(1 << bit_index); + } + else + { + ULONG byte_index = (startBit + valueSize - 1) / 8; + ULONG data = value; + ULONG remainingBits = valueSize; + while (remainingBits) + { + BYTE subvalue = data & 0xff; + + data >>= 8; + + if (remainingBits >= 8) + { + report[byte_index] = subvalue; + byte_index --; + remainingBits -= 8; + } + else if (remainingBits > 0) + { + BYTE mask = (0xff << (8-remainingBits)) & subvalue; + report[byte_index] |= mask; + remainingBits = 0; + } + } + } + return HIDP_STATUS_SUCCESS; +} + + NTSTATUS WINAPI HidP_GetButtonCaps(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData) { @@ -528,6 +571,28 @@ ULONG WINAPI HidP_MaxUsageListLength(HIDP_REPORT_TYPE ReportType, USAGE UsagePag return count; } +NTSTATUS WINAPI HidP_SetUsageValue(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, + USAGE Usage, ULONG UsageValue, PHIDP_PREPARSED_DATA PreparsedData, + CHAR *Report, ULONG ReportLength) +{ + WINE_HID_ELEMENT *element; + NTSTATUS rc; + + TRACE("(%i, %x, %i, %i, %i, %p, %p, %i)\n", ReportType, UsagePage, LinkCollection, Usage, UsageValue, + PreparsedData, Report, ReportLength); + + rc = find_value(ReportType, UsagePage, LinkCollection, Usage, PreparsedData, Report, &element); + + if (rc == HIDP_STATUS_SUCCESS) + { + return set_report_data((BYTE*)Report, ReportLength, + element->valueStartBit, element->bitCount, UsageValue); + } + + return rc; +} + + NTSTATUS WINAPI HidP_TranslateUsagesToI8042ScanCodes(USAGE *ChangedUsageList, ULONG UsageListLength, HIDP_KEYBOARD_DIRECTION KeyAction, HIDP_KEYBOARD_MODIFIER_STATE *ModifierState, diff --git a/include/ddk/hidpi.h b/include/ddk/hidpi.h index 0f69a03a646..1df789ffea6 100644 --- a/include/ddk/hidpi.h +++ b/include/ddk/hidpi.h @@ -186,6 +186,7 @@ NTSTATUS WINAPI HidP_GetValueCaps(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS NTSTATUS WINAPI HidP_InitializeReportForID(HIDP_REPORT_TYPE ReportType, UCHAR ReportID, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength); ULONG WINAPI HidP_MaxUsageListLength(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, PHIDP_PREPARSED_DATA PreparsedData); NTSTATUS WINAPI HidP_GetScaledUsageValue(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE Usage, PLONG UsageValue, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength); +NTSTATUS WINAPI HidP_SetUsageValue(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE Usage, ULONG UsageValue, PHIDP_PREPARSED_DATA PreparsedData, CHAR *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);