[PATCH 3/7] winebus.sys: Report lnxev axes individually in the descriptor.

Rémi Bernon rbernon at codeweavers.com
Fri Aug 13 02:46:14 CDT 2021


Fixing invalid axis range when they differ between two axis of the same
usage page.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winebus.sys/bus_udev.c | 140 +++++++++++++-----------------------
 1 file changed, 48 insertions(+), 92 deletions(-)

diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 4a494abac09..816adcc6539 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -62,6 +62,7 @@
 #include "winternl.h"
 #include "ddk/wdm.h"
 #include "ddk/hidtypes.h"
+#include "ddk/hidsdi.h"
 #include "wine/debug.h"
 #include "wine/heap.h"
 #include "wine/unicode.h"
@@ -345,10 +346,9 @@ static INT count_abs_axis(int device_fd)
 static BOOL build_report_descriptor(struct wine_input_private *ext, struct udev_device *dev)
 {
     struct input_absinfo abs_info[HID_ABS_MAX];
-    int abs_pages[TOP_ABS_PAGE][HID_ABS_MAX+1];
-    int rel_pages[TOP_REL_PAGE][HID_REL_MAX+1];
     BYTE absbits[(ABS_MAX+7)/8];
     BYTE relbits[(REL_MAX+7)/8];
+    USAGE_AND_PAGE usage;
     INT i;
     INT report_size;
     INT button_count, abs_count, rel_count, hat_count;
@@ -367,106 +367,46 @@ static BOOL build_report_descriptor(struct wine_input_private *ext, struct udev_
 
     report_size = 0;
 
+    if (!hid_descriptor_begin(&ext->desc, device_usage[0], device_usage[1]))
+        return FALSE;
+
     abs_count = 0;
-    memset(abs_pages, 0, sizeof(abs_pages));
     for (i = 0; i < HID_ABS_MAX; i++)
-        if (test_bit(absbits, i))
-        {
-            abs_pages[ABS_TO_HID_MAP[i][0]][0]++;
-            abs_pages[ABS_TO_HID_MAP[i][0]][abs_pages[ABS_TO_HID_MAP[i][0]][0]] = i;
+    {
+        if (!test_bit(absbits, i)) continue;
+        ioctl(ext->base.device_fd, EVIOCGABS(i), abs_info + i);
 
-            ioctl(ext->base.device_fd, EVIOCGABS(i), abs_info + i);
-        }
-    /* Skip page 0, aka HID_USAGE_PAGE_UNDEFINED */
-    for (i = 1; i < TOP_ABS_PAGE; i++)
-        if (abs_pages[i][0] > 0)
-        {
-            int j;
-            for (j = 1; j <= abs_pages[i][0]; j++)
-            {
-                ext->abs_map[abs_pages[i][j]] = report_size;
-                report_size+=4;
-            }
-            abs_count++;
-        }
+        if (!(usage.UsagePage = ABS_TO_HID_MAP[i][0])) continue;
+        if (!(usage.Usage = ABS_TO_HID_MAP[i][1])) continue;
 
-    rel_count = 0;
-    memset(rel_pages, 0, sizeof(rel_pages));
-    for (i = 0; i < HID_REL_MAX; i++)
-        if (test_bit(relbits, i))
-        {
-            rel_pages[REL_TO_HID_MAP[i][0]][0]++;
-            rel_pages[REL_TO_HID_MAP[i][0]][rel_pages[REL_TO_HID_MAP[i][0]][0]] = i;
-        }
-    /* Skip page 0, aka HID_USAGE_PAGE_UNDEFINED */
-    for (i = 1; i < TOP_REL_PAGE; i++)
-        if (rel_pages[i][0] > 0)
-        {
-            int j;
-            for (j = 1; j <= rel_pages[i][0]; j++)
-            {
-                ext->rel_map[rel_pages[i][j]] = report_size;
-                report_size++;
-            }
-            rel_count++;
-        }
+        if (!hid_descriptor_add_axes(&ext->desc, 1, usage.UsagePage, &usage.Usage, FALSE, 32,
+                                     LE_DWORD(abs_info[i].minimum), LE_DWORD(abs_info[i].maximum)))
+            return FALSE;
 
-    /* For now lump all buttons just into incremental usages, Ignore Keys */
-    ext->button_start = report_size;
-    button_count = count_buttons(ext->base.device_fd, ext->button_map);
-    if (button_count)
-    {
-        report_size += (button_count + 7) / 8;
+        ext->abs_map[i] = report_size;
+        report_size += 4;
+        abs_count++;
     }
 
-    hat_count = 0;
-    for (i = ABS_HAT0X; i <=ABS_HAT3X; i+=2)
-        if (test_bit(absbits, i))
-        {
-            ext->hat_map[i - ABS_HAT0X] = report_size;
-            ext->hat_values[i - ABS_HAT0X] = 0;
-            ext->hat_values[i - ABS_HAT0X + 1] = 0;
-            report_size++;
-            hat_count++;
-        }
-
-    TRACE("Report will be %i bytes\n", report_size);
+    rel_count = 0;
+    for (i = 0; i < HID_REL_MAX; i++)
+    {
+        if (!test_bit(relbits, i)) continue;
+        if (!(usage.UsagePage = REL_TO_HID_MAP[i][0])) continue;
+        if (!(usage.Usage = REL_TO_HID_MAP[i][1])) continue;
 
-    if (!hid_descriptor_begin(&ext->desc, device_usage[0], device_usage[1]))
-        return FALSE;
+        if (!hid_descriptor_add_axes(&ext->desc, 1, usage.UsagePage, &usage.Usage, TRUE, 8,
+                                     0x81, 0x7f))
+            return FALSE;
 
-    if (abs_count)
-    {
-        for (i = 1; i < TOP_ABS_PAGE; i++)
-        {
-            if (abs_pages[i][0])
-            {
-                USAGE usages[HID_ABS_MAX];
-                int j;
-                for (j = 0; j < abs_pages[i][0]; j++)
-                    usages[j] = ABS_TO_HID_MAP[abs_pages[i][j+1]][1];
-                if (!hid_descriptor_add_axes(&ext->desc, abs_pages[i][0], i, usages, FALSE, 32,
-                                             LE_DWORD(abs_info[abs_pages[i][1]].minimum),
-                                             LE_DWORD(abs_info[abs_pages[i][1]].maximum)))
-                    return FALSE;
-            }
-        }
-    }
-    if (rel_count)
-    {
-        for (i = 1; i < TOP_REL_PAGE; i++)
-        {
-            if (rel_pages[i][0])
-            {
-                USAGE usages[HID_REL_MAX];
-                int j;
-                for (j = 0; j < rel_pages[i][0]; j++)
-                    usages[j] = REL_TO_HID_MAP[rel_pages[i][j+1]][1];
-                if (!hid_descriptor_add_axes(&ext->desc, rel_pages[i][0], i, usages, TRUE, 8, 0x81, 0x7f))
-                    return FALSE;
-            }
-        }
+        ext->rel_map[i] = report_size;
+        report_size++;
+        rel_count++;
     }
+
+    /* For now lump all buttons just into incremental usages, Ignore Keys */
+    ext->button_start = report_size;
+    button_count = count_buttons(ext->base.device_fd, ext->button_map);
     if (button_count)
     {
         if (!hid_descriptor_add_buttons(&ext->desc, HID_USAGE_PAGE_BUTTON, 1, button_count))
@@ -478,7 +418,21 @@ static BOOL build_report_descriptor(struct wine_input_private *ext, struct udev_
             if (!hid_descriptor_add_padding(&ext->desc, padding))
                 return FALSE;
         }
+
+        report_size += (button_count + 7) / 8;
     }
+
+    hat_count = 0;
+    for (i = ABS_HAT0X; i <=ABS_HAT3X; i+=2)
+    {
+        if (!test_bit(absbits, i)) continue;
+        ext->hat_map[i - ABS_HAT0X] = report_size;
+        ext->hat_values[i - ABS_HAT0X] = 0;
+        ext->hat_values[i - ABS_HAT0X + 1] = 0;
+        report_size++;
+        hat_count++;
+    }
+
     if (hat_count)
     {
         if (!hid_descriptor_add_hatswitch(&ext->desc, hat_count))
@@ -488,6 +442,8 @@ static BOOL build_report_descriptor(struct wine_input_private *ext, struct udev_
     if (!hid_descriptor_end(&ext->desc))
         return FALSE;
 
+    TRACE("Report will be %i bytes\n", report_size);
+
     ext->buffer_length = report_size;
     if (!(ext->current_report_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, report_size)))
         goto failed;
-- 
2.32.0




More information about the wine-devel mailing list