[PATCH 2/5] winebus.sys: Build device reports for linux event devices

Sebastian Lackner sebastian at fds-team.de
Mon Feb 27 10:07:34 CST 2017


On 27.02.2017 16:09, Aric Stewart wrote:
> Signed-off-by: Aric Stewart <aric at codeweavers.com>
> ---
>  dlls/winebus.sys/bus_udev.c | 437 +++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 435 insertions(+), 2 deletions(-)
> 
> 
> 
> 0002-winebus.sys-Build-device-reports-for-linux-event-devic.txt
> 
> 
> diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
> index 2dcc7fb442..e2a475ccd8 100644
> --- a/dlls/winebus.sys/bus_udev.c
> +++ b/dlls/winebus.sys/bus_udev.c
> @@ -63,6 +63,10 @@
>  #include "wine/debug.h"
>  #include "wine/unicode.h"
>  
> +#ifdef HAS_PROPER_INPUT_HEADER
> +# include "hidusage.h"
> +#endif
> +
>  #include "bus.h"
>  
>  WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
> @@ -97,6 +101,418 @@ static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *de
>      return (struct platform_private *)get_platform_private(device);
>  }
>  
> +#ifdef HAS_PROPER_INPUT_HEADER
> +static const BYTE report_header[] = {
> +    0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
> +    0x09, 0x00, /* USAGE (??) */
> +    0xa1, 0x01, /* COLLECTION (Application) */
> +    0x09, 0x01, /*   USAGE () */
> +    0xa1, 0x00, /*   COLLECTION (Physical) */
> +};
> +
> +#define IDX_HEADER_PAGE 1
> +#define IDX_HEADER_USAGE 3
> +
> +static const BYTE report_buttons[] = {
> +    0x05, 0x09, /* USAGE_PAGE (Button) */
> +    0x19, 0x01, /* USAGE_MINIMUM (Button 1) */
> +    0x29, 0x03, /* USAGE_MAXIMUM (Button 3) */
> +    0x15, 0x00, /* LOGICAL_MINIMUM (0) */
> +    0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
> +    0x35, 0x00, /* LOGICAL_MINIMUM (0) */
> +    0x45, 0x01, /* LOGICAL_MAXIMUM (1) */
> +    0x95, 0x03, /* REPORT_COUNT (3) */
> +    0x75, 0x01, /* REPORT_SIZE (1) */
> +    0x81, 0x02, /* INPUT (Data,Var,Abs) */
> +};
> +#define IDX_BUTTON_MIN_USAGE 3
> +#define IDX_BUTTON_MAX_USAGE 5
> +#define IDX_BUTTON_COUNT 11
> +
> +static const BYTE report_padding[] = {
> +    0x95, 0x03, /* REPORT_COUNT (3) */
> +    0x75, 0x01, /* REPORT_SIZE (1) */
> +    0x81, 0x03, /* INPUT (Cnst,Var,Abs) */
> +};
> +#define IDX_PADDING_BIT_COUNT 1
> +
> +static const BYTE report_axis_header[] = {
> +    0x05, 0x01,  /* USAGE_PAGE (Generic Desktop) */
> +};
> +#define IDX_AXIS_PAGE 1
> +
> +
> +static const BYTE report_axis_usage[] = {
> +    0x09, 0x30,  /* USAGE (X) */
> +};
> +#define IDX_AXIS_USAGE 1
> +
> +static const BYTE report_abs_axis_tail[] = {
> +    0x16, 0x00, 0x00,   /* LOGICAL_MINIMUM (0) */
> +    0x26, 0xff, 0x00,   /* LOGICAL_MAXIMUM (0xff) */
> +    0x35, 0x00,         /* PHYSICAL_MINIMUM (0) */
> +    0x46, 0xff, 0x00,   /* PHYSICAL_MAXIMUM (256) */
> +    0x75, 0x10,         /* REPORT_SIZE (16) */
> +    0x95, 0x00,         /* REPORT_COUNT (2) */
> +    0x81, 0x02,         /* INPUT (Data,Var,Abs) */
> +};
> +#define IDX_ABS_AXIS_COUNT 14
> +
> +static const BYTE report_rel_axis_tail[] = {
> +    0x15, 0x81,    /* LOGICAL_MINIMUM (0) */
> +    0x25, 0x7f,    /* LOGICAL_MAXIMUM (0xffff) */
> +    0x75, 0x08,    /* REPORT_SIZE (16) */
> +    0x95, 0x02,    /* REPORT_COUNT (2) */
> +    0x81, 0x06,    /* INPUT (Data,Var,Rel) */
> +};
> +#define IDX_REL_AXIS_COUNT 7
> +
> +static const BYTE report_hatswitch[] = {
> +    0x05, 0x01,  /* USAGE_PAGE (Generic Desktop) */
> +    0x09, 0x39,  /* USAGE (Hatswitch) */
> +    0x15, 0x00,  /* LOGICAL_MINIMUM (0) */
> +    0x25, 0x08,  /* LOGICAL_MAXIMUM (0x08) */
> +    0x35, 0x00,  /* PHYSICAL_MINIMUM (0) */
> +    0x45, 0x08,  /* PHYSICAL_MAXIMUM (8) */
> +    0x75, 0x08,  /* REPORT_SIZE (8) */
> +    0x95, 0x01,  /* REPORT_COUNT (1) */
> +    0x81, 0x02,  /* INPUT (Data,Var,Abs) */
> +};
> +#define IDX_HATSWITCH_COUNT 15
> +
> +static const BYTE report_tail[] = {
> +    0xc0, /*   END_COLLECTION */
> +    0xc0  /* END_COLLECTION */
> +};
> +
> +static const BYTE ABS_to_HID_map[][2] = {
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_X},              /*ABS_X*/
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_Y},              /*ABS_Y*/
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_Z},              /*ABS_Z*/
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_RX},             /*ABS_RX*/
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_RY},             /*ABS_RY*/
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_RZ},             /*ABS_RZ*/
> +    {HID_USAGE_PAGE_SIMULATION, HID_USAGE_SIMULATION_THROTTLE}, /*ABS_THROTTLE*/
> +    {HID_USAGE_PAGE_SIMULATION, HID_USAGE_SIMULATION_RUDDER},   /*ABS_RUDDER*/
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_WHEEL},          /*ABS_WHEEL*/
> +    {HID_USAGE_PAGE_SIMULATION, 0xC4},                          /*ABS_GAS*/
> +    {HID_USAGE_PAGE_SIMULATION, 0xC5},                          /*ABS_BRAKE*/
> +    {0,0},                                                      /*ABS_HAT0X*/
> +    {0,0},                                                      /*ABS_HAT0Y*/
> +    {0,0},                                                      /*ABS_HAT1X*/
> +    {0,0},                                                      /*ABS_HAT1Y*/
> +    {0,0},                                                      /*ABS_HAT2X*/
> +    {0,0},                                                      /*ABS_HAT2Y*/
> +    {0,0},                                                      /*ABS_HAT3X*/
> +    {0,0},                                                      /*ABS_HAT3Y*/
> +    {HID_USAGE_PAGE_DIGITIZER, 0x30},                           /*ABS_PRESSURE*/
> +    {0, 0},                                                     /*ABS_DISTANCE*/
> +    {HID_USAGE_PAGE_DIGITIZER, 0x3D},                           /*ABS_TILT_X*/
> +    {HID_USAGE_PAGE_DIGITIZER, 0x3F},                           /*ABS_TILT_Y*/
> +    {0, 0},                                                     /*ABS_TOOL_WIDTH*/
> +    {0, 0},
> +    {0, 0},
> +    {0, 0},
> +    {HID_USAGE_PAGE_CONSUMER, 0xE0}                             /*ABS_VOLUME*/
> +};
> +#define HID_ABS_MAX (ABS_VOLUME+1)
> +#define TOP_ABS_PAGE (HID_USAGE_PAGE_DIGITIZER+1)
> +
> +static const BYTE REL_to_HID_map[][2] = {
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_X},     /* REL_X */
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_Y},     /* REL_Y */
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_Z},     /* REL_Z */
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_RX},    /* REL_RX */
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_RY},    /* REL_RY */
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_RZ},    /* REL_RZ */
> +    {0, 0},                                            /* REL_HWHEEL */
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_DIAL},  /* REL_DIAL */
> +    {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_WHEEL}, /* REL_WHEEL */
> +    {0, 0}                                             /* REL_MISC */
> +};
> +
> +#define HID_REL_MAX (REL_MISC+1)
> +#define TOP_REL_PAGE (HID_USAGE_PAGE_CONSUMER+1)
> +
> +struct wine_input_absinfo {
> +    struct input_absinfo info;
> +    BYTE report_index;
> +};
> +
> +struct wine_input_private {
> +    struct platform_private base;
> +
> +    int report_descriptor_size;
> +    BYTE *report_descriptor;
> +
> +    BYTE button_map[KEY_MAX];
> +    BYTE rel_map[HID_REL_MAX];
> +    BYTE hat_map[8];
> +    int hat_values[8];
> +    struct wine_input_absinfo abs_map[HID_ABS_MAX];
> +};
> +
> +#define test_bit(arr,bit) (((BYTE*)(arr))[(bit)>>3]&(1<<((bit)&7)))
> +
> +static BYTE *add_button_block(BYTE* report_ptr, BYTE usage_min, BYTE usage_max)
> +{
> +    memcpy(report_ptr, report_buttons, sizeof(report_buttons));
> +    report_ptr[IDX_BUTTON_MIN_USAGE] = usage_min;
> +    report_ptr[IDX_BUTTON_MAX_USAGE] = usage_max;
> +    report_ptr[IDX_BUTTON_COUNT] = (usage_max - usage_min) + 1;
> +    return report_ptr + sizeof(report_buttons);
> +}
> +
> +static BYTE *add_axis_block(BYTE *report_ptr, BYTE count, BYTE page, BYTE *usages, BOOL absolute)
> +{
> +    int i;
> +    memcpy(report_ptr, report_axis_header, sizeof(report_axis_header));
> +    report_ptr[IDX_AXIS_PAGE] = page;
> +    report_ptr += sizeof(report_axis_header);
> +    for (i = 0; i < count; i++)
> +    {
> +        memcpy(report_ptr, report_axis_usage, sizeof(report_axis_usage));
> +        report_ptr[IDX_AXIS_USAGE] = usages[i];
> +        report_ptr += sizeof(report_axis_usage);
> +    }
> +    if (absolute)
> +    {
> +        memcpy(report_ptr, report_abs_axis_tail, sizeof(report_abs_axis_tail));
> +        report_ptr[IDX_ABS_AXIS_COUNT] = count;
> +        report_ptr += sizeof(report_abs_axis_tail);
> +    }
> +    else
> +    {
> +        memcpy(report_ptr, report_rel_axis_tail, sizeof(report_rel_axis_tail));
> +        report_ptr[IDX_REL_AXIS_COUNT] = count;
> +        report_ptr += sizeof(report_rel_axis_tail);
> +    }
> +    return report_ptr;
> +}
> +
> +static BYTE *add_padding_block(BYTE *report_ptr, BYTE bitcount)
> +{
> +    memcpy(report_ptr, report_padding, sizeof(report_padding));
> +    report_ptr[IDX_PADDING_BIT_COUNT] = bitcount;
> +    return report_ptr + sizeof(report_padding);
> +}
> +
> +static BYTE *add_hatswitch(BYTE *report_ptr, INT count)
> +{
> +    memcpy(report_ptr, report_hatswitch, sizeof(report_hatswitch));
> +    report_ptr[IDX_HATSWITCH_COUNT] = count;
> +    return report_ptr + sizeof(report_hatswitch);
> +}
> +
> +static const BYTE* what_am_I(struct udev_device *dev)
> +{
> +    static const BYTE Unknown[2]     = {HID_USAGE_PAGE_GENERIC, 0};
> +    static const BYTE Mouse[2]       = {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_MOUSE};
> +    static const BYTE Keyboard[2]    = {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_KEYBOARD};
> +    static const BYTE Gamepad[2]     = {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_GAMEPAD};
> +    static const BYTE Keypad[2]      = {HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_KEYPAD};
> +    static const BYTE Tablet[2]      = {HID_USAGE_PAGE_DIGITIZER, 0x2};
> +    static const BYTE Touchscreen[2] = {HID_USAGE_PAGE_DIGITIZER, 0x4};
> +    static const BYTE Touchpad[2]    = {HID_USAGE_PAGE_DIGITIZER, 0x5};
> +
> +    struct udev_device *parent = dev;
> +
> +    /* Look to the parents until we get a clue */
> +    while (parent)
> +    {
> +        if (udev_device_get_property_value(parent, "ID_INPUT_MOUSE"))
> +            return Mouse;
> +        else if (udev_device_get_property_value(parent, "ID_INPUT_KEYBOARD"))
> +            return Keyboard;
> +        else if (udev_device_get_property_value(parent, "ID_INPUT_JOYSTICK"))
> +            return Gamepad;
> +        else if (udev_device_get_property_value(parent, "ID_INPUT_KEY"))
> +            return Keypad;
> +        else if (udev_device_get_property_value(parent, "ID_INPUT_TOUCHPAD"))
> +            return Touchpad;
> +        else if (udev_device_get_property_value(parent, "ID_INPUT_TOUCHSCREEN"))
> +            return Touchscreen;
> +        else if (udev_device_get_property_value(parent, "ID_INPUT_TABLET"))
> +            return Tablet;
> +
> +        parent = udev_device_get_parent_with_subsystem_devtype(parent, "input", NULL);
> +    }
> +    return Unknown;
> +}
> +
> +static VOID build_report_descriptor(struct wine_input_private *ext, struct udev_device *dev)
> +{
> +    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];
> +    BYTE keybits[(KEY_MAX+7)/8];
> +    BYTE *report_ptr;
> +    INT i, descript_size;
> +    INT report_size;
> +    INT button_count, abs_count, rel_count, hat_count;
> +    const BYTE *device_usage = what_am_I(dev);
> +
> +    if (ioctl(ext->base.device_fd, EVIOCGBIT(EV_REL, sizeof(relbits)), relbits) == -1)
> +    {
> +        WARN("ioctl(EVIOCGBIT, EV_REL) failed: %d %s\n", errno, strerror(errno));
> +        return;
> +    }
> +    if (ioctl(ext->base.device_fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits) == -1)
> +    {
> +        WARN("ioctl(EVIOCGBIT, EV_ABS) failed: %d %s\n", errno, strerror(errno));
> +        return;
> +    }
> +    if (ioctl(ext->base.device_fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits) == -1)
> +    {
> +        WARN("ioctl(EVIOCGBIT, EV_KEY) failed: %d %s\n", errno, strerror(errno));
> +        return;
> +    }
> +
> +    descript_size = sizeof(report_header) + sizeof(report_tail);
> +    report_size = 0;
> +
> +    /* For now lump all buttons just into incremental usages, Ignore Keys */
> +    button_count = 0;
> +    for (i = BTN_MISC; i < KEY_MAX; i++)
> +    {
> +        if (test_bit(keybits, i))
> +        {
> +            ext->button_map[i] = button_count;
> +            button_count++;
> +        }
> +    }
> +    if (button_count)
> +    {
> +        descript_size += sizeof(report_buttons);
> +        if (button_count % 8)
> +            descript_size += sizeof(report_padding);
> +        report_size = (button_count + 7) / 8;
> +    }
> +
> +    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;
> +
> +            ioctl(ext->base.device_fd, EVIOCGABS(i), &(ext->abs_map[i]));
> +            if (abs_pages[ABS_to_HID_map[i][0]][0] == 1)
> +            {
> +                descript_size += sizeof(report_axis_header);
> +                descript_size += sizeof(report_abs_axis_tail);
> +            }
> +        }
> +    /* Skip page 0, aka HID_USAGE_PAGE_UNDEFINED */
> +    for (i = 1; i < TOP_ABS_PAGE; i++)
> +        if (abs_pages[i][0] > 0)
> +        {
> +            int j;
> +            descript_size += sizeof(report_axis_usage) * abs_pages[i][0];
> +            for (j = 1; j <= abs_pages[i][0]; j++)
> +            {
> +                ext->abs_map[abs_pages[i][j]].report_index = report_size;
> +                report_size+=2;
> +            }
> +            abs_count++;
> +        }
> +
> +    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;
> +            if (rel_pages[REL_to_HID_map[i][0]][0] == 1)
> +            {
> +                descript_size += sizeof(report_axis_header);
> +                descript_size += sizeof(report_rel_axis_tail);
> +            }
> +        }
> +    /* Skip page 0, aka HID_USAGE_PAGE_UNDEFINED */
> +    for (i = 1; i < TOP_REL_PAGE; i++)
> +        if (rel_pages[i][0] > 0)
> +        {
> +            int j;
> +            descript_size += sizeof(report_axis_usage) * rel_pages[i][0];
> +            for (j = 1; j <= rel_pages[i][0]; j++)
> +            {
> +                ext->rel_map[rel_pages[i][j]] = report_size;
> +                report_size++;
> +            }
> +            rel_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 Descriptor will be %i bytes\n", descript_size);
> +    TRACE("Report will be %i bytes\n", report_size);
> +
> +    ext->report_descriptor = HeapAlloc(GetProcessHeap(), 0, descript_size);
> +    report_ptr = ext->report_descriptor;
> +
> +    memcpy(report_ptr, report_header, sizeof(report_header));
> +    report_ptr[IDX_HEADER_PAGE] = device_usage[0];
> +    report_ptr[IDX_HEADER_USAGE] = device_usage[1];
> +    report_ptr += sizeof(report_header);
> +    if (button_count)
> +    {
> +        report_ptr = add_button_block(report_ptr, 1, button_count);
> +        if (button_count % 8)
> +        {
> +            BYTE padding = 8 - (button_count % 8);
> +            report_ptr = add_padding_block(report_ptr, padding);
> +        }
> +    }
> +    if (abs_count)
> +    {
> +        for (i = 1; i < TOP_ABS_PAGE; i++)
> +        {
> +            if (abs_pages[i][0])
> +            {
> +                BYTE 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];
> +                report_ptr = add_axis_block(report_ptr, abs_pages[i][0], i, usages, TRUE);
> +            }
> +        }
> +    }
> +    if (rel_count)
> +    {
> +        for (i = 1; i < TOP_REL_PAGE; i++)
> +        {
> +            if (rel_pages[i][0])
> +            {
> +                BYTE 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];
> +                report_ptr = add_axis_block(report_ptr, rel_pages[i][0], i, usages, FALSE);
> +            }
> +        }
> +    }
> +    if (hat_count)
> +        report_ptr = add_hatswitch(report_ptr, hat_count);
> +
> +    memcpy(report_ptr, report_tail, sizeof(report_tail));
> +
> +    ext->report_descriptor_size = descript_size;
> +}
> +#endif
> +
>  static inline WCHAR *strdupAtoW(const char *src)
>  {
>      WCHAR *dst;
> @@ -406,9 +822,23 @@ static const platform_vtbl hidraw_vtbl =
>  
>  #ifdef HAS_PROPER_INPUT_HEADER
>  
> +static inline struct wine_input_private *input_impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device)
> +{
> +    return (struct wine_input_private*)get_platform_private(device);
> +}
> +
>  static NTSTATUS lnxev_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length)
>  {
> -    return STATUS_NOT_IMPLEMENTED;
> +    struct wine_input_private *ext = input_impl_from_DEVICE_OBJECT(device);
> +
> +    *out_length = ext->report_descriptor_size;
> +
> +    if (length < ext->report_descriptor_size)
> +        return STATUS_BUFFER_TOO_SMALL;
> +
> +    memcpy(buffer, ext->report_descriptor, ext->report_descriptor_size);
> +
> +    return STATUS_SUCCESS;
>  }
>  
>  static NTSTATUS lnxev_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length)
> @@ -511,7 +941,7 @@ static void try_add_device(struct udev_device *dev)
>  #ifdef HAS_PROPER_INPUT_HEADER
>      else if (strcmp(subsystem, "input") == 0)
>      {
> -        device = bus_create_hid_device(udev_driver_obj, lnxev_busidW, vid, pid, version, 0, serial, (gamepad != NULL), &GUID_DEVCLASS_LINUXEVENT, &lnxev_vtbl, sizeof(struct platform_private));
> +        device = bus_create_hid_device(udev_driver_obj, lnxev_busidW, vid, pid, version, 0, serial, (gamepad != NULL), &GUID_DEVCLASS_LINUXEVENT, &lnxev_vtbl, sizeof(struct wine_input_private));
>      }
>  #endif
>  
> @@ -520,6 +950,9 @@ static void try_add_device(struct udev_device *dev)
>          struct platform_private *private = impl_from_DEVICE_OBJECT(device);
>          private->udev_device = udev_device_ref(dev);
>          private->device_fd = fd;
> +#ifdef HAS_PROPER_INPUT_HEADER
> +        build_report_descriptor((struct wine_input_private*)private, dev);

I don't think you want this code to be executed for hidraw devices.

> +#endif
>          IoInvalidateDeviceRelations(device, BusRelations);
>      }
>      else
> 
> 
> 




More information about the wine-devel mailing list