[PATCH 5/5] hidclass.sys: Factor HIDP_BUTTON_CAPS with HIDP_VALUE_CAPS.

Rémi Bernon rbernon at codeweavers.com
Fri Jun 4 04:30:35 CDT 2021


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 at codeweavers.com>
---
 dlls/hid/hidp.c                |  66 ++++++-------
 dlls/hidclass.sys/descriptor.c | 176 ++++++++++++++++-----------------
 dlls/user32/rawinput.c         |   2 +
 include/wine/hid.h             |  43 +++++++-
 4 files changed, 162 insertions(+), 125 deletions(-)

diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c
index 131a02af4eb..92c1442d048 100644
--- a/dlls/hid/hidp.c
+++ b/dlls/hid/hidp.c
@@ -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++;
diff --git a/dlls/hidclass.sys/descriptor.c b/dlls/hidclass.sys/descriptor.c
index c7687e400ef..9c52dee5fe1 100644
--- a/dlls/hidclass.sys/descriptor.c
+++ b/dlls/hidclass.sys/descriptor.c
@@ -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;
         }
     }
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index 4f9a63cfb88..e08d11bc20a 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -21,6 +21,8 @@
 
 #include <stdarg.h>
 
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
 #include "windef.h"
 #include "winbase.h"
 #include "wingdi.h"
diff --git a/include/wine/hid.h b/include/wine/hid.h
index 857dcae18fe..38d84bc96af 100644
--- a/include/wine/hid.h
+++ b/include/wine/hid.h
@@ -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;
-- 
2.31.0




More information about the wine-devel mailing list