hidclass.sys: Factor HIDP_BUTTON_CAPS with HIDP_VALUE_CAPS.

Buttons are really just values with BitSize == 1, and having a union for
that makes the code more complicated than it needs.

We'll simplify the code a lot using HIDP_VALUE_CAPS everywhere, as the
two structure types are compatible.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-06-04 11:30:35 +02:00 committed by Alexandre Julliard
parent 3f3d445383
commit dc7547a84b
4 changed files with 162 additions and 125 deletions

View file

@ -204,7 +204,7 @@ NTSTATUS WINAPI HidP_GetButtonCaps(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAP
for (i = 0; i < report[j].elementCount && u < b_count; i++)
{
if (elems[report[j].elementIdx + i].ElementType == ButtonElement)
ButtonCaps[u++] = elems[report[j].elementIdx + i].caps.button;
ButtonCaps[u++] = *(HIDP_BUTTON_CAPS *)&elems[report[j].elementIdx + i].caps;
}
}
@ -268,7 +268,7 @@ static NTSTATUS find_usage(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT
for (i = 0; i < report->elementCount; i++)
{
HIDP_VALUE_CAPS *value = &elems[report->elementIdx + i].caps.value;
HIDP_VALUE_CAPS *value = &elems[report->elementIdx + i].caps;
if (elems[report->elementIdx + i].ElementType != ElementType ||
value->UsagePage != UsagePage)
@ -298,7 +298,7 @@ static LONG sign_extend(ULONG value, const WINE_HID_ELEMENT *element)
if ((value & (1 << (bit_count - 1)))
&& element->ElementType == ValueElement
&& element->caps.value.LogicalMin < 0)
&& element->caps.LogicalMin < 0)
{
value -= (1 << bit_count);
}
@ -307,12 +307,12 @@ static LONG sign_extend(ULONG value, const WINE_HID_ELEMENT *element)
static LONG logical_to_physical(LONG value, const WINE_HID_ELEMENT *element)
{
if (element->caps.value.PhysicalMin || element->caps.value.PhysicalMax)
if (element->caps.PhysicalMin || element->caps.PhysicalMax)
{
value = (((ULONGLONG)(value - element->caps.value.LogicalMin)
* (element->caps.value.PhysicalMax - element->caps.value.PhysicalMin))
/ (element->caps.value.LogicalMax - element->caps.value.LogicalMin))
+ element->caps.value.PhysicalMin;
value = (((ULONGLONG)(value - element->caps.LogicalMin)
* (element->caps.PhysicalMax - element->caps.PhysicalMin))
/ (element->caps.LogicalMax - element->caps.LogicalMin))
+ element->caps.PhysicalMin;
}
return value;
}
@ -378,11 +378,11 @@ NTSTATUS WINAPI HidP_GetUsageValueArray(HIDP_REPORT_TYPE ReportType, USAGE Usage
if (rc == HIDP_STATUS_SUCCESS)
{
if (element.caps.value.IsRange || element.caps.value.ReportCount <= 1 || !element.bitCount)
if (element.caps.IsRange || element.caps.ReportCount <= 1 || !element.bitCount)
return HIDP_STATUS_NOT_VALUE_ARRAY;
return get_report_data_array((BYTE*)Report, ReportLength, element.valueStartBit, element.bitCount,
element.caps.value.ReportCount, UsageValue, UsageValueByteLength);
element.caps.ReportCount, UsageValue, UsageValueByteLength);
}
return rc;
@ -436,7 +436,7 @@ NTSTATUS WINAPI HidP_GetUsages(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USH
for (i = 0; i < report->elementCount && uCount < *UsageLength; i++)
{
if (elems[report->elementIdx + i].ElementType == ButtonElement &&
elems[report->elementIdx + i].caps.button.UsagePage == UsagePage)
elems[report->elementIdx + i].caps.UsagePage == UsagePage)
{
int k;
WINE_HID_ELEMENT *element = &elems[report->elementIdx + i];
@ -452,7 +452,7 @@ NTSTATUS WINAPI HidP_GetUsages(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USH
{
if (uCount == *UsageLength)
return HIDP_STATUS_BUFFER_TOO_SMALL;
UsageList[uCount] = element->caps.button.Range.UsageMin + k;
UsageList[uCount] = element->caps.Range.UsageMin + k;
uCount++;
}
}
@ -515,7 +515,7 @@ NTSTATUS WINAPI HidP_GetValueCaps(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS
for (i = 0; i < report[j].elementCount && u < v_count; i++)
{
if (elems[report[j].elementIdx + i].ElementType == ValueElement)
ValueCaps[u++] = elems[report[j].elementIdx + i].caps.value;
ValueCaps[u++] = elems[report[j].elementIdx + i].caps;
}
}
@ -608,11 +608,11 @@ ULONG WINAPI HidP_MaxUsageListLength(HIDP_REPORT_TYPE ReportType, USAGE UsagePag
for (j = 0; j < report[i].elementCount; j++)
{
if (elems[report[i].elementIdx + j].ElementType == ButtonElement &&
(UsagePage == 0 || elems[report[i].elementIdx + j].caps.button.UsagePage == UsagePage))
(UsagePage == 0 || elems[report[i].elementIdx + j].caps.UsagePage == UsagePage))
{
if (elems[report[i].elementIdx + j].caps.button.IsRange)
count += (elems[report[i].elementIdx + j].caps.button.Range.UsageMax -
elems[report[i].elementIdx + j].caps.button.Range.UsageMin) + 1;
if (elems[report[i].elementIdx + j].caps.IsRange)
count += (elems[report[i].elementIdx + j].caps.Range.UsageMax -
elems[report[i].elementIdx + j].caps.Range.UsageMin) + 1;
else
count++;
}
@ -735,16 +735,16 @@ NTSTATUS WINAPI HidP_GetSpecificButtonCaps(HIDP_REPORT_TYPE ReportType,
for (i = 0; i < report[j].elementCount && u < b_count; i++)
{
if (elems[report[j].elementIdx + i].ElementType == ButtonElement &&
(UsagePage == 0 || UsagePage == elems[report[j].elementIdx + i].caps.button.UsagePage) &&
(LinkCollection == 0 || LinkCollection == elems[report[j].elementIdx + i].caps.button.LinkCollection) &&
(UsagePage == 0 || UsagePage == elems[report[j].elementIdx + i].caps.UsagePage) &&
(LinkCollection == 0 || LinkCollection == elems[report[j].elementIdx + i].caps.LinkCollection) &&
(Usage == 0 || (
(!elems[report[j].elementIdx + i].caps.button.IsRange &&
Usage == elems[report[j].elementIdx + i].caps.button.NotRange.Usage)) ||
(elems[report[j].elementIdx + i].caps.button.IsRange &&
Usage >= elems[report[j].elementIdx + i].caps.button.Range.UsageMin &&
Usage <= elems[report[j].elementIdx + i].caps.button.Range.UsageMax)))
(!elems[report[j].elementIdx + i].caps.IsRange &&
Usage == elems[report[j].elementIdx + i].caps.NotRange.Usage)) ||
(elems[report[j].elementIdx + i].caps.IsRange &&
Usage >= elems[report[j].elementIdx + i].caps.Range.UsageMin &&
Usage <= elems[report[j].elementIdx + i].caps.Range.UsageMax)))
{
ButtonCaps[u++] = elems[report[j].elementIdx + i].caps.button;
ButtonCaps[u++] = *(HIDP_BUTTON_CAPS *)&elems[report[j].elementIdx + i].caps;
}
}
}
@ -805,11 +805,11 @@ NTSTATUS WINAPI HidP_GetSpecificValueCaps(HIDP_REPORT_TYPE ReportType,
for (i = 0; i < report[j].elementCount && u < v_count; i++)
{
if (elems[report[j].elementIdx + i].ElementType == ValueElement &&
(UsagePage == 0 || UsagePage == elems[report[j].elementIdx + i].caps.value.UsagePage) &&
(LinkCollection == 0 || LinkCollection == elems[report[j].elementIdx + i].caps.value.LinkCollection) &&
(Usage == 0 || Usage == elems[report[j].elementIdx + i].caps.value.NotRange.Usage))
(UsagePage == 0 || UsagePage == elems[report[j].elementIdx + i].caps.UsagePage) &&
(LinkCollection == 0 || LinkCollection == elems[report[j].elementIdx + i].caps.LinkCollection) &&
(Usage == 0 || Usage == elems[report[j].elementIdx + i].caps.NotRange.Usage))
{
ValueCaps[u++] = elems[report[j].elementIdx + i].caps.value;
ValueCaps[u++] = elems[report[j].elementIdx + i].caps;
}
}
}
@ -876,8 +876,8 @@ NTSTATUS WINAPI HidP_GetUsagesEx(HIDP_REPORT_TYPE ReportType, USHORT LinkCollect
{
if (uCount < *UsageLength)
{
ButtonList[uCount].Usage = element->caps.button.Range.UsageMin + k;
ButtonList[uCount].UsagePage = element->caps.button.UsagePage;
ButtonList[uCount].Usage = element->caps.Range.UsageMin + k;
ButtonList[uCount].UsagePage = element->caps.UsagePage;
}
uCount++;
}
@ -959,7 +959,7 @@ NTSTATUS WINAPI HidP_GetData(HIDP_REPORT_TYPE ReportType, HIDP_DATA *DataList, U
{
if (uCount < *DataLength)
{
DataList[uCount].DataIndex = element->caps.button.Range.DataIndexMin + k;
DataList[uCount].DataIndex = element->caps.Range.DataIndexMin + k;
DataList[uCount].On = v;
}
uCount++;
@ -975,7 +975,7 @@ NTSTATUS WINAPI HidP_GetData(HIDP_REPORT_TYPE ReportType, HIDP_DATA *DataList, U
element->valueStartBit, element->bitCount, &v);
if (rc != HIDP_STATUS_SUCCESS)
return rc;
DataList[uCount].DataIndex = element->caps.value.NotRange.DataIndex;
DataList[uCount].DataIndex = element->caps.NotRange.DataIndex;
DataList[uCount].RawValue = v;
}
uCount++;

View file

@ -258,18 +258,18 @@ static void debug_collection(struct collection *collection)
static void debug_print_button_cap(const CHAR * type, WINE_HID_ELEMENT *wine_element)
{
if (!wine_element->caps.button.IsRange)
if (!wine_element->caps.IsRange)
TRACE("%s Button: 0x%x/0x%04x: ReportId %i, startBit %i/1\n" , type,
wine_element->caps.button.UsagePage,
wine_element->caps.button.NotRange.Usage,
wine_element->caps.value.ReportID,
wine_element->caps.UsagePage,
wine_element->caps.NotRange.Usage,
wine_element->caps.ReportID,
wine_element->valueStartBit);
else
TRACE("%s Button: 0x%x/[0x%04x-0x%04x]: ReportId %i, startBit %i/%i\n" ,type,
wine_element->caps.button.UsagePage,
wine_element->caps.button.Range.UsageMin,
wine_element->caps.button.Range.UsageMax,
wine_element->caps.value.ReportID,
wine_element->caps.UsagePage,
wine_element->caps.Range.UsageMin,
wine_element->caps.Range.UsageMax,
wine_element->caps.ReportID,
wine_element->valueStartBit,
wine_element->bitCount);
}
@ -280,19 +280,19 @@ static void debug_print_value_cap(const CHAR * type, WINE_HID_ELEMENT *wine_elem
"Bit Size %i, ReportCount %i, UnitsExp %i, Units %i, "
"LogicalMin %i, Logical Max %i, PhysicalMin %i, "
"PhysicalMax %i -- StartBit %i/%i\n", type,
wine_element->caps.value.UsagePage,
wine_element->caps.value.NotRange.Usage,
wine_element->caps.value.ReportID,
wine_element->caps.value.IsAbsolute,
wine_element->caps.value.HasNull,
wine_element->caps.value.BitSize,
wine_element->caps.value.ReportCount,
wine_element->caps.value.UnitsExp,
wine_element->caps.value.Units,
wine_element->caps.value.LogicalMin,
wine_element->caps.value.LogicalMax,
wine_element->caps.value.PhysicalMin,
wine_element->caps.value.PhysicalMax,
wine_element->caps.UsagePage,
wine_element->caps.NotRange.Usage,
wine_element->caps.ReportID,
wine_element->caps.IsAbsolute,
wine_element->caps.HasNull,
wine_element->caps.BitSize,
wine_element->caps.ReportCount,
wine_element->caps.UnitsExp,
wine_element->caps.Units,
wine_element->caps.LogicalMin,
wine_element->caps.LogicalMax,
wine_element->caps.PhysicalMin,
wine_element->caps.PhysicalMax,
wine_element->valueStartBit,
wine_element->bitCount);
}
@ -704,89 +704,89 @@ static void build_elements(WINE_HID_REPORT *wine_report, WINE_HID_ELEMENT *elems
if (feature->caps.BitSize == 1)
{
wine_element->ElementType = ButtonElement;
wine_element->caps.button.UsagePage = feature->caps.UsagePage;
wine_element->caps.button.ReportID = feature->caps.ReportID;
wine_element->caps.button.BitField = feature->BitField;
wine_element->caps.button.LinkCollection = feature->collection->index;
wine_element->caps.button.LinkUsage = feature->collection->caps.NotRange.Usage;
wine_element->caps.button.LinkUsagePage = feature->collection->caps.UsagePage;
wine_element->caps.button.IsRange = feature->caps.IsRange;
wine_element->caps.button.IsStringRange = feature->caps.IsStringRange;
wine_element->caps.button.IsDesignatorRange = feature->caps.IsDesignatorRange;
wine_element->caps.button.IsAbsolute = feature->IsAbsolute;
if (wine_element->caps.button.IsRange)
wine_element->caps.UsagePage = feature->caps.UsagePage;
wine_element->caps.ReportID = feature->caps.ReportID;
wine_element->caps.BitField = feature->BitField;
wine_element->caps.LinkCollection = feature->collection->index;
wine_element->caps.LinkUsage = feature->collection->caps.NotRange.Usage;
wine_element->caps.LinkUsagePage = feature->collection->caps.UsagePage;
wine_element->caps.IsRange = feature->caps.IsRange;
wine_element->caps.IsStringRange = feature->caps.IsStringRange;
wine_element->caps.IsDesignatorRange = feature->caps.IsDesignatorRange;
wine_element->caps.IsAbsolute = feature->IsAbsolute;
if (wine_element->caps.IsRange)
{
wine_element->caps.button.Range.UsageMin = feature->caps.Range.UsageMin;
wine_element->caps.button.Range.UsageMax = feature->caps.Range.UsageMax;
wine_element->caps.button.Range.StringMin = feature->caps.Range.StringMin;
wine_element->caps.button.Range.StringMax = feature->caps.Range.StringMax;
wine_element->caps.button.Range.DesignatorMin = feature->caps.Range.DesignatorMin;
wine_element->caps.button.Range.DesignatorMax = feature->caps.Range.DesignatorMax;
wine_element->caps.button.Range.DataIndexMin = *data_index;
wine_element->caps.button.Range.DataIndexMax = *data_index + wine_element->bitCount - 1;
wine_element->caps.Range.UsageMin = feature->caps.Range.UsageMin;
wine_element->caps.Range.UsageMax = feature->caps.Range.UsageMax;
wine_element->caps.Range.StringMin = feature->caps.Range.StringMin;
wine_element->caps.Range.StringMax = feature->caps.Range.StringMax;
wine_element->caps.Range.DesignatorMin = feature->caps.Range.DesignatorMin;
wine_element->caps.Range.DesignatorMax = feature->caps.Range.DesignatorMax;
wine_element->caps.Range.DataIndexMin = *data_index;
wine_element->caps.Range.DataIndexMax = *data_index + wine_element->bitCount - 1;
*data_index = *data_index + wine_element->bitCount;
}
else
{
wine_element->caps.button.NotRange.Usage = feature->caps.NotRange.Usage;
wine_element->caps.button.NotRange.Reserved1 = feature->caps.NotRange.Usage;
wine_element->caps.button.NotRange.StringIndex = feature->caps.NotRange.StringIndex;
wine_element->caps.button.NotRange.Reserved2 = feature->caps.NotRange.StringIndex;
wine_element->caps.button.NotRange.DesignatorIndex = feature->caps.NotRange.DesignatorIndex;
wine_element->caps.button.NotRange.Reserved3 = feature->caps.NotRange.DesignatorIndex;
wine_element->caps.button.NotRange.DataIndex = *data_index;
wine_element->caps.button.NotRange.Reserved4 = *data_index;
wine_element->caps.NotRange.Usage = feature->caps.NotRange.Usage;
wine_element->caps.NotRange.Reserved1 = feature->caps.NotRange.Usage;
wine_element->caps.NotRange.StringIndex = feature->caps.NotRange.StringIndex;
wine_element->caps.NotRange.Reserved2 = feature->caps.NotRange.StringIndex;
wine_element->caps.NotRange.DesignatorIndex = feature->caps.NotRange.DesignatorIndex;
wine_element->caps.NotRange.Reserved3 = feature->caps.NotRange.DesignatorIndex;
wine_element->caps.NotRange.DataIndex = *data_index;
wine_element->caps.NotRange.Reserved4 = *data_index;
*data_index = *data_index + 1;
}
}
else
{
wine_element->ElementType = ValueElement;
wine_element->caps.value.UsagePage = feature->caps.UsagePage;
wine_element->caps.value.ReportID = feature->caps.ReportID;
wine_element->caps.value.BitField = feature->BitField;
wine_element->caps.value.LinkCollection = feature->collection->index;
wine_element->caps.value.LinkUsage = feature->collection->caps.NotRange.Usage;
wine_element->caps.value.LinkUsagePage = feature->collection->caps.UsagePage;
wine_element->caps.value.IsRange = feature->caps.IsRange;
wine_element->caps.value.IsStringRange = feature->caps.IsStringRange;
wine_element->caps.value.IsDesignatorRange = feature->caps.IsDesignatorRange;
wine_element->caps.value.IsAbsolute = feature->IsAbsolute;
wine_element->caps.value.HasNull = feature->HasNull;
wine_element->caps.value.BitSize = feature->caps.BitSize;
wine_element->caps.value.ReportCount = feature->caps.ReportCount;
wine_element->caps.value.UnitsExp = feature->caps.UnitsExp;
wine_element->caps.value.Units = feature->caps.Units;
wine_element->caps.value.LogicalMin = feature->caps.LogicalMin;
wine_element->caps.value.LogicalMax = feature->caps.LogicalMax;
wine_element->caps.value.PhysicalMin = feature->caps.PhysicalMin;
wine_element->caps.value.PhysicalMax = feature->caps.PhysicalMax;
if (wine_element->caps.value.IsRange)
wine_element->caps.UsagePage = feature->caps.UsagePage;
wine_element->caps.ReportID = feature->caps.ReportID;
wine_element->caps.BitField = feature->BitField;
wine_element->caps.LinkCollection = feature->collection->index;
wine_element->caps.LinkUsage = feature->collection->caps.NotRange.Usage;
wine_element->caps.LinkUsagePage = feature->collection->caps.UsagePage;
wine_element->caps.IsRange = feature->caps.IsRange;
wine_element->caps.IsStringRange = feature->caps.IsStringRange;
wine_element->caps.IsDesignatorRange = feature->caps.IsDesignatorRange;
wine_element->caps.IsAbsolute = feature->IsAbsolute;
wine_element->caps.HasNull = feature->HasNull;
wine_element->caps.BitSize = feature->caps.BitSize;
wine_element->caps.ReportCount = feature->caps.ReportCount;
wine_element->caps.UnitsExp = feature->caps.UnitsExp;
wine_element->caps.Units = feature->caps.Units;
wine_element->caps.LogicalMin = feature->caps.LogicalMin;
wine_element->caps.LogicalMax = feature->caps.LogicalMax;
wine_element->caps.PhysicalMin = feature->caps.PhysicalMin;
wine_element->caps.PhysicalMax = feature->caps.PhysicalMax;
if (wine_element->caps.IsRange)
{
wine_element->caps.value.Range.UsageMin = feature->caps.Range.UsageMin;
wine_element->caps.value.Range.UsageMax = feature->caps.Range.UsageMax;
wine_element->caps.value.Range.StringMin = feature->caps.Range.StringMin;
wine_element->caps.value.Range.StringMax = feature->caps.Range.StringMax;
wine_element->caps.value.Range.DesignatorMin = feature->caps.Range.DesignatorMin;
wine_element->caps.value.Range.DesignatorMax = feature->caps.Range.DesignatorMax;
wine_element->caps.value.Range.DataIndexMin = *data_index;
wine_element->caps.value.Range.DataIndexMax = *data_index +
(wine_element->caps.value.Range.UsageMax -
wine_element->caps.value.Range.UsageMin);
wine_element->caps.Range.UsageMin = feature->caps.Range.UsageMin;
wine_element->caps.Range.UsageMax = feature->caps.Range.UsageMax;
wine_element->caps.Range.StringMin = feature->caps.Range.StringMin;
wine_element->caps.Range.StringMax = feature->caps.Range.StringMax;
wine_element->caps.Range.DesignatorMin = feature->caps.Range.DesignatorMin;
wine_element->caps.Range.DesignatorMax = feature->caps.Range.DesignatorMax;
wine_element->caps.Range.DataIndexMin = *data_index;
wine_element->caps.Range.DataIndexMax = *data_index +
(wine_element->caps.Range.UsageMax -
wine_element->caps.Range.UsageMin);
*data_index = *data_index +
(wine_element->caps.value.Range.UsageMax -
wine_element->caps.value.Range.UsageMin) + 1;
(wine_element->caps.Range.UsageMax -
wine_element->caps.Range.UsageMin) + 1;
}
else
{
wine_element->caps.value.NotRange.Usage = feature->caps.NotRange.Usage;
wine_element->caps.value.NotRange.Reserved1 = feature->caps.NotRange.Usage;
wine_element->caps.value.NotRange.StringIndex = feature->caps.NotRange.StringIndex;
wine_element->caps.value.NotRange.Reserved2 = feature->caps.NotRange.StringIndex;
wine_element->caps.value.NotRange.DesignatorIndex = feature->caps.NotRange.DesignatorIndex;
wine_element->caps.value.NotRange.Reserved3 = feature->caps.NotRange.DesignatorIndex;
wine_element->caps.value.NotRange.DataIndex = *data_index;
wine_element->caps.value.NotRange.Reserved4 = *data_index;
wine_element->caps.NotRange.Usage = feature->caps.NotRange.Usage;
wine_element->caps.NotRange.Reserved1 = feature->caps.NotRange.Usage;
wine_element->caps.NotRange.StringIndex = feature->caps.NotRange.StringIndex;
wine_element->caps.NotRange.Reserved2 = feature->caps.NotRange.StringIndex;
wine_element->caps.NotRange.DesignatorIndex = feature->caps.NotRange.DesignatorIndex;
wine_element->caps.NotRange.Reserved3 = feature->caps.NotRange.DesignatorIndex;
wine_element->caps.NotRange.DataIndex = *data_index;
wine_element->caps.NotRange.Reserved4 = *data_index;
*data_index = *data_index + 1;
}
}

View file

@ -21,6 +21,8 @@
#include <stdarg.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"

View file

@ -21,6 +21,14 @@
#ifndef __WINE_PARSE_H
#define __WINE_PARSE_H
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "hidusage.h"
#include "ddk/hidpi.h"
#define HID_MAGIC 0x8491759
typedef enum __WINE_ELEMENT_TYPE {
@ -34,12 +42,39 @@ typedef struct __WINE_ELEMENT
WINE_ELEMENT_TYPE ElementType;
UINT valueStartBit;
UINT bitCount;
union {
HIDP_VALUE_CAPS value;
HIDP_BUTTON_CAPS button;
} caps;
HIDP_VALUE_CAPS caps;
} WINE_HID_ELEMENT;
/* make sure HIDP_BUTTON_CAPS is a subset of HIDP_VALUE_CAPS */
C_ASSERT( sizeof(HIDP_BUTTON_CAPS) == sizeof(HIDP_VALUE_CAPS) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, UsagePage) == offsetof(HIDP_VALUE_CAPS, UsagePage) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, ReportID) == offsetof(HIDP_VALUE_CAPS, ReportID) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, IsAlias) == offsetof(HIDP_VALUE_CAPS, IsAlias) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, BitField) == offsetof(HIDP_VALUE_CAPS, BitField) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, LinkCollection) == offsetof(HIDP_VALUE_CAPS, LinkCollection) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, LinkUsage) == offsetof(HIDP_VALUE_CAPS, LinkUsage) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, LinkUsagePage) == offsetof(HIDP_VALUE_CAPS, LinkUsagePage) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, IsRange) == offsetof(HIDP_VALUE_CAPS, IsRange) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, IsStringRange) == offsetof(HIDP_VALUE_CAPS, IsStringRange) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, IsDesignatorRange) == offsetof(HIDP_VALUE_CAPS, IsDesignatorRange) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, IsAbsolute) == offsetof(HIDP_VALUE_CAPS, IsAbsolute) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, Range.UsageMin) == offsetof(HIDP_VALUE_CAPS, Range.UsageMin) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, Range.UsageMax) == offsetof(HIDP_VALUE_CAPS, Range.UsageMax) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, Range.StringMin) == offsetof(HIDP_VALUE_CAPS, Range.StringMin) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, Range.StringMax) == offsetof(HIDP_VALUE_CAPS, Range.StringMax) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, Range.DesignatorMin) == offsetof(HIDP_VALUE_CAPS, Range.DesignatorMin) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, Range.DesignatorMax) == offsetof(HIDP_VALUE_CAPS, Range.DesignatorMax) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, Range.DataIndexMin) == offsetof(HIDP_VALUE_CAPS, Range.DataIndexMin) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, Range.DataIndexMax) == offsetof(HIDP_VALUE_CAPS, Range.DataIndexMax) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, NotRange.Usage) == offsetof(HIDP_VALUE_CAPS, NotRange.Usage) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, NotRange.StringIndex) == offsetof(HIDP_VALUE_CAPS, NotRange.StringIndex) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, NotRange.DesignatorIndex) == offsetof(HIDP_VALUE_CAPS, NotRange.DesignatorIndex) );
C_ASSERT( offsetof(HIDP_BUTTON_CAPS, NotRange.DataIndex) == offsetof(HIDP_VALUE_CAPS, NotRange.DataIndex) );
typedef struct __WINE_HID_REPORT
{
UCHAR reportID;