mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-03 00:28:29 +00:00
hid: Rewrite HidP_GetUsages using enum_value_caps.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8f5b49c0c4
commit
1184afb640
106
dlls/hid/hidp.c
106
dlls/hid/hidp.c
|
@ -420,84 +420,52 @@ NTSTATUS WINAPI HidP_GetUsageValueArray(HIDP_REPORT_TYPE ReportType, USAGE Usage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS WINAPI HidP_GetUsages(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection,
|
struct get_usage_params
|
||||||
PUSAGE UsageList, PULONG UsageLength, PHIDP_PREPARSED_DATA PreparsedData,
|
|
||||||
PCHAR Report, ULONG ReportLength)
|
|
||||||
{
|
{
|
||||||
PWINE_HIDP_PREPARSED_DATA data = (PWINE_HIDP_PREPARSED_DATA)PreparsedData;
|
USAGE *usages;
|
||||||
WINE_HID_ELEMENT *elems = HID_ELEMS(data);
|
USAGE *usages_end;
|
||||||
WINE_HID_REPORT *report = NULL;
|
char *report_buf;
|
||||||
BOOL found = FALSE;
|
};
|
||||||
USHORT b_count = 0, r_count = 0;
|
|
||||||
int i,uCount;
|
|
||||||
|
|
||||||
TRACE("(%i, %x, %i, %p, %p, %p, %p, %i)\n", ReportType, UsagePage, LinkCollection, UsageList,
|
static NTSTATUS get_usage( const struct hid_value_caps *caps, void *user )
|
||||||
UsageLength, PreparsedData, Report, ReportLength);
|
{
|
||||||
|
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;
|
if (!(params->report_buf[bit / 8] & (1 << (bit % 8)))) continue;
|
||||||
return HIDP_STATUS_INVALID_PREPARSED_DATA;
|
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;
|
|
||||||
|
|
||||||
if (report->reportID && report->reportID != Report[0])
|
|
||||||
return HIDP_STATUS_REPORT_DOES_NOT_EXIST;
|
|
||||||
|
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*UsageLength = uCount;
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
return HIDP_STATUS_USAGE_NOT_FOUND;
|
|
||||||
|
|
||||||
return HIDP_STATUS_SUCCESS;
|
return HIDP_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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 );
|
||||||
|
|
||||||
|
if (!report_len) return HIDP_STATUS_INVALID_REPORT_LENGTH;
|
||||||
|
|
||||||
|
filter.report_id = report_buf[0];
|
||||||
|
status = enum_value_caps( preparsed, report_type, report_len, &filter, get_usage, ¶ms, &limit );
|
||||||
|
*usages_len = params.usages - usages;
|
||||||
|
if (status != HIDP_STATUS_SUCCESS) return status;
|
||||||
|
|
||||||
|
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,
|
NTSTATUS WINAPI HidP_GetValueCaps( HIDP_REPORT_TYPE report_type, HIDP_VALUE_CAPS *caps, USHORT *caps_count,
|
||||||
PHIDP_PREPARSED_DATA preparsed_data )
|
PHIDP_PREPARSED_DATA preparsed_data )
|
||||||
{
|
{
|
||||||
|
|
|
@ -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,
|
status = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usages, &value,
|
||||||
preparsed_data, report, caps.InputReportByteLength);
|
preparsed_data, report, caps.InputReportByteLength);
|
||||||
ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetUsages returned %#x\n", status);
|
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);
|
ok(value == 2, "got usage count %d, expected %d\n", value, 2);
|
||||||
value = ARRAY_SIZE(usages);
|
value = ARRAY_SIZE(usages);
|
||||||
memset(usages, 0xcd, sizeof(usages));
|
memset(usages, 0xcd, sizeof(usages));
|
||||||
|
@ -2207,9 +2206,7 @@ static void test_hidp(HANDLE file, int report_id)
|
||||||
report, caps.InputReportByteLength);
|
report, caps.InputReportByteLength);
|
||||||
ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsages returned %#x\n", status);
|
ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsages returned %#x\n", status);
|
||||||
ok(value == 2, "got usage count %d, expected %d\n", value, 2);
|
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);
|
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);
|
ok(usages[1] == 4, "got usages[1] %x, expected %x\n", usages[1], 4);
|
||||||
|
|
||||||
value = ARRAY_SIZE(usage_and_pages);
|
value = ARRAY_SIZE(usage_and_pages);
|
||||||
|
|
Loading…
Reference in a new issue