Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/joystick_hid.c | 5 +++++ dlls/dinput/tests/joystick8.c | 9 --------- 2 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 80991e8c150..87e343bb47b 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -414,6 +414,11 @@ static const WCHAR *object_usage_to_string( DIDEVICEOBJECTINSTANCEW *instance ) case MAKELONG(PID_USAGE_TRIGGER_BUTTON, HID_USAGE_PAGE_PID): return L"Trigger Button";
case MAKELONG(HID_USAGE_SIMULATION_RUDDER, HID_USAGE_PAGE_SIMULATION): return L"Rudder"; + case MAKELONG(HID_USAGE_SIMULATION_THROTTLE, HID_USAGE_PAGE_SIMULATION): return L"Throttle"; + case MAKELONG(HID_USAGE_SIMULATION_ACCELERATOR, HID_USAGE_PAGE_SIMULATION): return L"Accelerator"; + case MAKELONG(HID_USAGE_SIMULATION_BRAKE, HID_USAGE_PAGE_SIMULATION): return L"Brake"; + case MAKELONG(HID_USAGE_SIMULATION_CLUTCH, HID_USAGE_PAGE_SIMULATION): return L"Clutch"; + case MAKELONG(HID_USAGE_SIMULATION_STEERING, HID_USAGE_PAGE_SIMULATION): return L"Steering"; default: return NULL; } } diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index e65e3ca9970..8899cbdfecf 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -2773,20 +2773,11 @@ static void test_driving_wheel_axes(void) .wUsage = HID_USAGE_GENERIC_JOYSTICK, }, }; - struct check_objects_todos object_todos[ARRAY_SIZE(expect_objects)] = - { - {.name = TRUE}, - {.name = TRUE}, - {.name = TRUE}, - {.name = TRUE}, - {.name = TRUE}, - }; struct check_objects_params check_objects_params = { .version = DIRECTINPUT_VERSION, .expect_count = ARRAY_SIZE(expect_objects), .expect_objs = expect_objects, - .todo_objs = object_todos, };
WCHAR cwd[MAX_PATH], tempdir[MAX_PATH];
Detecting main type first, then subtype.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/joystick_hid.c | 87 ++++++++++++++++++----------------- dlls/dinput/tests/joystick8.c | 2 - 2 files changed, 45 insertions(+), 44 deletions(-)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 87e343bb47b..1a39dfd6cab 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -1416,9 +1416,9 @@ static BOOL hid_joystick_device_try_open( UINT32 handle, const WCHAR *path, HAND PHIDP_PREPARSED_DATA *preparsed, HIDD_ATTRIBUTES *attrs, HIDP_CAPS *caps, DIDEVICEINSTANCEW *instance, DWORD version ) { - BOOL has_accelerator, has_brake, has_clutch; + BOOL has_accelerator, has_brake, has_clutch, has_z, has_pov; PHIDP_PREPARSED_DATA preparsed_data = NULL; - DWORD type = 0, button_count = 0; + DWORD type, button_count = 0; HIDP_BUTTON_CAPS buttons[10]; HIDP_VALUE_CAPS value; HANDLE device_file; @@ -1433,10 +1433,14 @@ static BOOL hid_joystick_device_try_open( UINT32 handle, const WCHAR *path, HAND if (!HidD_GetAttributes( device_file, attrs )) goto failed; if (HidP_GetCaps( preparsed_data, caps ) != HIDP_STATUS_SUCCESS) goto failed;
- if (caps->UsagePage == HID_USAGE_PAGE_GAME) FIXME( "game usage page not implemented!\n" ); - if (caps->UsagePage == HID_USAGE_PAGE_SIMULATION) FIXME( "simulation usage page not implemented!\n" ); - if (caps->UsagePage != HID_USAGE_PAGE_GENERIC) goto failed; - if (caps->Usage != HID_USAGE_GENERIC_GAMEPAD && caps->Usage != HID_USAGE_GENERIC_JOYSTICK) goto failed; + switch (MAKELONG( caps->Usage, caps->UsagePage )) + { + case MAKELONG( HID_USAGE_GENERIC_MOUSE, HID_USAGE_PAGE_GENERIC ): goto failed; + case MAKELONG( HID_USAGE_GENERIC_KEYBOARD, HID_USAGE_PAGE_GENERIC ): goto failed; + case MAKELONG( HID_USAGE_GENERIC_GAMEPAD, HID_USAGE_PAGE_GENERIC ): type = DI8DEVTYPE_GAMEPAD; break; + case MAKELONG( HID_USAGE_GENERIC_JOYSTICK, HID_USAGE_PAGE_GENERIC ): type = DI8DEVTYPE_JOYSTICK; break; + default: FIXME( "device usage %04x:%04x not implemented!\n", caps->UsagePage, caps->Usage); goto failed; + }
if (!HidD_GetProductString( device_file, instance->tszInstanceName, MAX_PATH * sizeof(WCHAR) )) goto failed; if (!HidD_GetProductString( device_file, instance->tszProductName, MAX_PATH * sizeof(WCHAR) )) goto failed; @@ -1464,52 +1468,47 @@ static BOOL hid_joystick_device_try_open( UINT32 handle, const WCHAR *path, HAND else button_count += buttons[count].Range.UsageMax - buttons[count].Range.UsageMin + 1; }
- switch (caps->Usage) - { - case HID_USAGE_GENERIC_GAMEPAD: - type = DI8DEVTYPE_GAMEPAD | DIDEVTYPE_HID; - if (button_count < 6) type |= DI8DEVTYPEGAMEPAD_LIMITED << 8; - else type |= DI8DEVTYPEGAMEPAD_STANDARD << 8; - break; - case HID_USAGE_GENERIC_JOYSTICK: - type = DI8DEVTYPE_JOYSTICK | DIDEVTYPE_HID; - if (button_count < 5) type |= DI8DEVTYPEJOYSTICK_LIMITED << 8; - else type |= DI8DEVTYPEJOYSTICK_STANDARD << 8; - - count = 1; - status = HidP_GetSpecificValueCaps( HidP_Input, HID_USAGE_PAGE_GENERIC, 0, - HID_USAGE_GENERIC_Z, &value, &count, preparsed_data ); - if (status != HIDP_STATUS_SUCCESS || !count) - type = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_LIMITED << 8) | DIDEVTYPE_HID; - - count = 1; - status = HidP_GetSpecificValueCaps( HidP_Input, HID_USAGE_PAGE_GENERIC, 0, - HID_USAGE_GENERIC_HATSWITCH, &value, &count, preparsed_data ); - if (status != HIDP_STATUS_SUCCESS || !count) - type = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_LIMITED << 8) | DIDEVTYPE_HID; - - break; - } - count = 1; status = HidP_GetSpecificValueCaps( HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, &value, &count, preparsed_data ); - if (status != HIDP_STATUS_SUCCESS || !count) - type = DI8DEVTYPE_SUPPLEMENTAL | (DI8DEVTYPESUPPLEMENTAL_UNKNOWN << 8) | DIDEVTYPE_HID; + if (status != HIDP_STATUS_SUCCESS || !count) type = DI8DEVTYPE_SUPPLEMENTAL;
count = 1; status = HidP_GetSpecificValueCaps( HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Y, &value, &count, preparsed_data ); - if (status != HIDP_STATUS_SUCCESS || !count) - type = DI8DEVTYPE_SUPPLEMENTAL | (DI8DEVTYPESUPPLEMENTAL_UNKNOWN << 8) | DIDEVTYPE_HID; + if (status != HIDP_STATUS_SUCCESS || !count) type = DI8DEVTYPE_SUPPLEMENTAL;
count = 1; status = HidP_GetSpecificValueCaps( HidP_Input, HID_USAGE_PAGE_SIMULATION, 0, HID_USAGE_SIMULATION_STEERING, &value, &count, preparsed_data ); - if (status == HIDP_STATUS_SUCCESS && count) - { - type = DI8DEVTYPE_DRIVING | DIDEVTYPE_HID; + if (status == HIDP_STATUS_SUCCESS && count) type = DI8DEVTYPE_DRIVING;
+ switch (GET_DIDEVICE_TYPE(type)) + { + case DI8DEVTYPE_SUPPLEMENTAL: + type |= (DI8DEVTYPESUPPLEMENTAL_UNKNOWN << 8); + break; + case DI8DEVTYPE_GAMEPAD: + if (button_count < 6) type |= (DI8DEVTYPEGAMEPAD_LIMITED << 8); + else type |= (DI8DEVTYPEGAMEPAD_STANDARD << 8); + break; + case DI8DEVTYPE_JOYSTICK: + count = 1; + status = HidP_GetSpecificValueCaps( HidP_Input, HID_USAGE_PAGE_GENERIC, 0, + HID_USAGE_GENERIC_Z, &value, &count, preparsed_data ); + has_z = (status == HIDP_STATUS_SUCCESS && count); + + count = 1; + status = HidP_GetSpecificValueCaps( HidP_Input, HID_USAGE_PAGE_GENERIC, 0, + HID_USAGE_GENERIC_HATSWITCH, &value, &count, preparsed_data ); + has_pov = (status == HIDP_STATUS_SUCCESS && count); + + if (button_count < 5 || !has_z || !has_pov) + type |= (DI8DEVTYPEJOYSTICK_LIMITED << 8); + else + type |= (DI8DEVTYPEJOYSTICK_STANDARD << 8); + break; + case DI8DEVTYPE_DRIVING: count = 1; status = HidP_GetSpecificValueCaps( HidP_Input, HID_USAGE_PAGE_SIMULATION, 0, HID_USAGE_SIMULATION_ACCELERATOR, &value, &count, preparsed_data ); @@ -1525,15 +1524,19 @@ static BOOL hid_joystick_device_try_open( UINT32 handle, const WCHAR *path, HAND &value, &count, preparsed_data ); has_clutch = (status == HIDP_STATUS_SUCCESS && count);
- if (has_accelerator && has_brake && has_clutch) + if (button_count < 4) + type |= (DI8DEVTYPEDRIVING_LIMITED << 8); + else if (has_accelerator && has_brake && has_clutch) type |= (DI8DEVTYPEDRIVING_THREEPEDALS << 8); else if (has_accelerator && has_brake) type |= (DI8DEVTYPEDRIVING_DUALPEDALS << 8); else type |= (DI8DEVTYPEDRIVING_LIMITED << 8); + break; }
- instance->dwDevType = device_type_for_version( type, version ); + instance->dwDevType = device_type_for_version( type, version ) | DIDEVTYPE_HID; + TRACE("detected device type %#lx\n", instance->dwDevType);
*device = device_file; *preparsed = preparsed_data; diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 8899cbdfecf..2d801aacda2 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -2805,7 +2805,6 @@ static void test_driving_wheel_axes(void) todo_wine check_member_guid( devinst, expect_devinst, guidInstance ); check_member_guid( devinst, expect_devinst, guidProduct ); - todo_wine check_member( devinst, expect_devinst, "%#lx", dwDevType ); todo_wine check_member_wstr( devinst, expect_devinst, tszInstanceName ); @@ -2824,7 +2823,6 @@ static void test_driving_wheel_axes(void) ok( hr == DI_OK, "GetCapabilities returned %#lx\n", hr ); check_member( caps, expect_caps, "%lu", dwSize ); check_member( caps, expect_caps, "%#lx", dwFlags ); - todo_wine check_member( caps, expect_caps, "%#lx", dwDevType ); check_member( caps, expect_caps, "%lu", dwAxes ); check_member( caps, expect_caps, "%lu", dwButtons );
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_sdl.c | 6 +++-- dlls/winebus.sys/bus_udev.c | 39 +++++++++++++++++---------------- dlls/winebus.sys/hid.c | 7 +++--- dlls/winebus.sys/unix_private.h | 2 +- dlls/winebus.sys/unixlib.c | 6 +++-- 5 files changed, 32 insertions(+), 28 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index c80b7ce324a..9efd8e2d00e 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -229,6 +229,7 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl)
static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface) { + const USAGE_AND_PAGE device_usage = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_JOYSTICK}; static const USAGE_AND_PAGE absolute_usages[] = { {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_X}, @@ -275,7 +276,7 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface) hat_count = pSDL_JoystickNumHats(impl->sdl_joystick); button_count = pSDL_JoystickNumButtons(impl->sdl_joystick);
- if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_JOYSTICK)) + if (!hid_device_begin_report_descriptor(iface, &device_usage)) return STATUS_NO_MEMORY;
if (!hid_device_begin_input_report(iface)) @@ -321,6 +322,7 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
static NTSTATUS build_controller_report_descriptor(struct unix_device *iface) { + const USAGE_AND_PAGE device_usage = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_GAMEPAD}; static const USAGE left_axis_usages[] = {HID_USAGE_GENERIC_X, HID_USAGE_GENERIC_Y}; static const USAGE right_axis_usages[] = {HID_USAGE_GENERIC_RX, HID_USAGE_GENERIC_RY}; static const USAGE trigger_axis_usages[] = {HID_USAGE_GENERIC_Z, HID_USAGE_GENERIC_RZ}; @@ -328,7 +330,7 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface) ULONG i, button_count = SDL_CONTROLLER_BUTTON_MAX - 1; C_ASSERT(SDL_CONTROLLER_AXIS_MAX == 6);
- if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_GAMEPAD)) + if (!hid_device_begin_report_descriptor(iface, &device_usage)) return STATUS_NO_MEMORY;
if (!hid_device_begin_input_report(iface)) diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 08034c8a07e..7a0a9587af0 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -555,16 +555,16 @@ static struct base_device *find_device_from_syspath(const char *path)
#define test_bit(arr,bit) (((BYTE*)(arr))[(bit)>>3]&(1<<((bit)&7)))
-static const BYTE* what_am_I(struct udev_device *dev) +static const USAGE_AND_PAGE *what_am_I(struct udev_device *dev, int fd) { - 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, HID_USAGE_DIGITIZER_PEN}; - static const BYTE Touchscreen[2] = {HID_USAGE_PAGE_DIGITIZER, HID_USAGE_DIGITIZER_TOUCH_SCREEN}; - static const BYTE Touchpad[2] = {HID_USAGE_PAGE_DIGITIZER, HID_USAGE_DIGITIZER_TOUCH_PAD}; + static const USAGE_AND_PAGE Unknown = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = 0}; + static const USAGE_AND_PAGE Mouse = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_MOUSE}; + static const USAGE_AND_PAGE Keyboard = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_KEYBOARD}; + static const USAGE_AND_PAGE Gamepad = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_GAMEPAD}; + static const USAGE_AND_PAGE Keypad = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_KEYPAD}; + static const USAGE_AND_PAGE Tablet = {.UsagePage = HID_USAGE_PAGE_DIGITIZER, .Usage = HID_USAGE_DIGITIZER_PEN}; + static const USAGE_AND_PAGE Touchscreen = {.UsagePage = HID_USAGE_PAGE_DIGITIZER, .Usage = HID_USAGE_DIGITIZER_TOUCH_SCREEN}; + static const USAGE_AND_PAGE Touchpad = {.UsagePage = HID_USAGE_PAGE_DIGITIZER, .Usage = HID_USAGE_DIGITIZER_TOUCH_PAD};
struct udev_device *parent = dev;
@@ -572,23 +572,24 @@ static const BYTE* what_am_I(struct udev_device *dev) while (parent) { if (udev_device_get_property_value(parent, "ID_INPUT_MOUSE")) - return Mouse; + return &Mouse; else if (udev_device_get_property_value(parent, "ID_INPUT_KEYBOARD")) - return Keyboard; + return &Keyboard; else if (udev_device_get_property_value(parent, "ID_INPUT_JOYSTICK")) - return Gamepad; + return &Gamepad; else if (udev_device_get_property_value(parent, "ID_INPUT_KEY")) - return Keypad; + return &Keypad; else if (udev_device_get_property_value(parent, "ID_INPUT_TOUCHPAD")) - return Touchpad; + return &Touchpad; else if (udev_device_get_property_value(parent, "ID_INPUT_TOUCHSCREEN")) - return Touchscreen; + return &Touchscreen; else if (udev_device_get_property_value(parent, "ID_INPUT_TABLET")) - return Tablet; + return &Tablet;
parent = udev_device_get_parent_with_subsystem_devtype(parent, "input", NULL); } - return Unknown; + + return &Unknown; }
static INT count_buttons(int device_fd, BYTE *map) @@ -642,8 +643,8 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d USHORT count = 0; USAGE usages[16]; INT i, button_count, abs_count, rel_count, hat_count; - const BYTE *device_usage = what_am_I(dev); struct lnxev_device *impl = lnxev_impl_from_unix_device(iface); + const USAGE_AND_PAGE device_usage = *what_am_I(dev, impl->base.device_fd);
if (ioctl(impl->base.device_fd, EVIOCGBIT(EV_REL, sizeof(relbits)), relbits) == -1) { @@ -661,7 +662,7 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d memset(ffbits, 0, sizeof(ffbits)); }
- if (!hid_device_begin_report_descriptor(iface, device_usage[0], device_usage[1])) + if (!hid_device_begin_report_descriptor(iface, &device_usage)) return STATUS_NO_MEMORY;
if (!hid_device_begin_input_report(iface)) diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index 8d34fc86e63..ba0fa77ee11 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -74,15 +74,14 @@ static BOOL hid_report_descriptor_append_usage(struct hid_report_descriptor *des return hid_report_descriptor_append(desc, template, sizeof(template)); }
-BOOL hid_device_begin_report_descriptor(struct unix_device *iface, USAGE usage_page, USAGE usage) +BOOL hid_device_begin_report_descriptor(struct unix_device *iface, const USAGE_AND_PAGE *device_usage) { struct hid_report_descriptor *desc = &iface->hid_report_descriptor; const BYTE template[] = { - USAGE_PAGE(2, usage_page), - USAGE(2, usage), + USAGE_PAGE(2, device_usage->UsagePage), + USAGE(2, device_usage->Usage), COLLECTION(1, Application), - USAGE(1, 0), };
memset(desc, 0, sizeof(*desc)); diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index 3c37f219a4b..2cf6d382759 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -242,7 +242,7 @@ extern BOOL bus_event_queue_input_report(struct list *queue, struct unix_device BYTE *report, USHORT length) DECLSPEC_HIDDEN; extern BOOL bus_event_queue_pop(struct list *queue, struct bus_event *event) DECLSPEC_HIDDEN;
-extern BOOL hid_device_begin_report_descriptor(struct unix_device *iface, USAGE usage_page, USAGE usage) DECLSPEC_HIDDEN; +extern BOOL hid_device_begin_report_descriptor(struct unix_device *iface, const USAGE_AND_PAGE *device_usage) DECLSPEC_HIDDEN; extern BOOL hid_device_end_report_descriptor(struct unix_device *iface) DECLSPEC_HIDDEN;
extern BOOL hid_device_begin_input_report(struct unix_device *iface) DECLSPEC_HIDDEN; diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c index f251e8e6af7..88cc513125a 100644 --- a/dlls/winebus.sys/unixlib.c +++ b/dlls/winebus.sys/unixlib.c @@ -87,7 +87,8 @@ static void mouse_destroy(struct unix_device *iface)
static NTSTATUS mouse_start(struct unix_device *iface) { - if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_MOUSE)) + const USAGE_AND_PAGE device_usage = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_MOUSE}; + if (!hid_device_begin_report_descriptor(iface, &device_usage)) return STATUS_NO_MEMORY; if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, 3)) return STATUS_NO_MEMORY; @@ -176,7 +177,8 @@ static void keyboard_destroy(struct unix_device *iface)
static NTSTATUS keyboard_start(struct unix_device *iface) { - if (!hid_device_begin_report_descriptor(iface, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_KEYBOARD)) + const USAGE_AND_PAGE device_usage = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_KEYBOARD}; + if (!hid_device_begin_report_descriptor(iface, &device_usage)) return STATUS_NO_MEMORY; if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_KEYBOARD, 0, 101)) return STATUS_NO_MEMORY;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_sdl.c | 4 ++-- dlls/winebus.sys/bus_udev.c | 2 +- dlls/winebus.sys/hid.c | 40 ++++++++++++++++++++------------- dlls/winebus.sys/unix_private.h | 2 +- 4 files changed, 29 insertions(+), 19 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 9efd8e2d00e..3d9935f0714 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -279,7 +279,7 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface) if (!hid_device_begin_report_descriptor(iface, &device_usage)) return STATUS_NO_MEMORY;
- if (!hid_device_begin_input_report(iface)) + if (!hid_device_begin_input_report(iface, &device_usage)) return STATUS_NO_MEMORY;
for (i = 0; i < axis_count; i++) @@ -333,7 +333,7 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface) if (!hid_device_begin_report_descriptor(iface, &device_usage)) return STATUS_NO_MEMORY;
- if (!hid_device_begin_input_report(iface)) + if (!hid_device_begin_input_report(iface, &device_usage)) return STATUS_NO_MEMORY;
if (!hid_device_add_axes(iface, 2, HID_USAGE_PAGE_GENERIC, left_axis_usages, diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 7a0a9587af0..db173b63fb5 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -665,7 +665,7 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d if (!hid_device_begin_report_descriptor(iface, &device_usage)) return STATUS_NO_MEMORY;
- if (!hid_device_begin_input_report(iface)) + if (!hid_device_begin_input_report(iface, &device_usage)) return STATUS_NO_MEMORY;
abs_count = 0; diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index ba0fa77ee11..d5637c0353b 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -74,23 +74,21 @@ static BOOL hid_report_descriptor_append_usage(struct hid_report_descriptor *des return hid_report_descriptor_append(desc, template, sizeof(template)); }
-BOOL hid_device_begin_report_descriptor(struct unix_device *iface, const USAGE_AND_PAGE *device_usage) +static BOOL hid_device_begin_collection(struct hid_report_descriptor *desc, const USAGE_AND_PAGE *usage, BYTE type) { - struct hid_report_descriptor *desc = &iface->hid_report_descriptor; const BYTE template[] = { - USAGE_PAGE(2, device_usage->UsagePage), - USAGE(2, device_usage->Usage), - COLLECTION(1, Application), + USAGE_PAGE(2, usage->UsagePage), + USAGE(2, usage->Usage), + COLLECTION(1, type), };
memset(desc, 0, sizeof(*desc)); return hid_report_descriptor_append(desc, template, sizeof(template)); }
-BOOL hid_device_end_report_descriptor(struct unix_device *iface) +static BOOL hid_device_end_collection(struct hid_report_descriptor *desc) { - struct hid_report_descriptor *desc = &iface->hid_report_descriptor; static const BYTE template[] = { END_COLLECTION, @@ -99,15 +97,27 @@ BOOL hid_device_end_report_descriptor(struct unix_device *iface) return hid_report_descriptor_append(desc, template, sizeof(template)); }
-BOOL hid_device_begin_input_report(struct unix_device *iface) +BOOL hid_device_begin_report_descriptor(struct unix_device *iface, const USAGE_AND_PAGE *device_usage) +{ + struct hid_report_descriptor *desc = &iface->hid_report_descriptor; + memset(desc, 0, sizeof(*desc)); + return hid_device_begin_collection(desc, device_usage, Application); +} + +BOOL hid_device_end_report_descriptor(struct unix_device *iface) +{ + struct hid_report_descriptor *desc = &iface->hid_report_descriptor; + return hid_device_end_collection(desc); +} + +BOOL hid_device_begin_input_report(struct unix_device *iface, const USAGE_AND_PAGE *physical_usage) { struct hid_report_descriptor *desc = &iface->hid_report_descriptor; struct hid_device_state *state = &iface->hid_device_state; const BYTE report_id = ++desc->next_report_id[HidP_Input]; const BYTE template[] = { - COLLECTION(1, Report), - REPORT_ID(1, report_id), + REPORT_ID(1, report_id), };
if (state->report_len) @@ -118,6 +128,10 @@ BOOL hid_device_begin_input_report(struct unix_device *iface)
state->id = report_id; state->bit_size += 8; + + if (!hid_device_begin_collection(desc, physical_usage, Physical)) + return FALSE; + return hid_report_descriptor_append(desc, template, sizeof(template)); }
@@ -125,10 +139,6 @@ BOOL hid_device_end_input_report(struct unix_device *iface) { struct hid_report_descriptor *desc = &iface->hid_report_descriptor; struct hid_device_state *state = &iface->hid_device_state; - static const BYTE template[] = - { - END_COLLECTION, - };
state->report_len = (state->bit_size + 7) / 8; if (!(state->report_buf = calloc(1, state->report_len))) return FALSE; @@ -136,7 +146,7 @@ BOOL hid_device_end_input_report(struct unix_device *iface)
state->report_buf[0] = state->id; state->last_report_buf[0] = state->id; - return hid_report_descriptor_append(desc, template, sizeof(template)); + return hid_device_end_collection(desc); }
static BOOL hid_device_add_button_count(struct unix_device *iface, BYTE count) diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index 2cf6d382759..553631e40fb 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -245,7 +245,7 @@ extern BOOL bus_event_queue_pop(struct list *queue, struct bus_event *event) DEC extern BOOL hid_device_begin_report_descriptor(struct unix_device *iface, const USAGE_AND_PAGE *device_usage) DECLSPEC_HIDDEN; extern BOOL hid_device_end_report_descriptor(struct unix_device *iface) DECLSPEC_HIDDEN;
-extern BOOL hid_device_begin_input_report(struct unix_device *iface) DECLSPEC_HIDDEN; +extern BOOL hid_device_begin_input_report(struct unix_device *iface, const USAGE_AND_PAGE *physical_usage) DECLSPEC_HIDDEN; extern BOOL hid_device_end_input_report(struct unix_device *iface) DECLSPEC_HIDDEN; extern BOOL hid_device_add_buttons(struct unix_device *iface, USAGE usage_page, USAGE usage_min, USAGE usage_max) DECLSPEC_HIDDEN;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- include/hidusage.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/hidusage.h b/include/hidusage.h index 3e2ee77f8c8..2ea3784d626 100644 --- a/include/hidusage.h +++ b/include/hidusage.h @@ -203,6 +203,8 @@ typedef USHORT USAGE, *PUSAGE; #define HID_USAGE_PAGE_VENDOR_DEFINED_BEGIN ((USAGE) 0xff00) #define HID_USAGE_PAGE_VENDOR_DEFINED_END ((USAGE) 0xffff)
+#define HID_USAGE_SIMULATION_FLIGHT_SIMULATION_DEVICE ((USAGE) 0x01) +#define HID_USAGE_SIMULATION_AUTOMOBILE_SIMULATION_DEVICE ((USAGE) 0x02) #define HID_USAGE_SIMULATION_RUDDER ((USAGE) 0xBA) #define HID_USAGE_SIMULATION_THROTTLE ((USAGE) 0xBB) #define HID_USAGE_SIMULATION_ACCELERATOR ((USAGE) 0xC4)
And pass through driving wheel and flight stick information to DInput.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_sdl.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 3d9935f0714..aedef50d3f7 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -117,6 +117,7 @@ static int (*pSDL_JoystickRumble)(SDL_Joystick *joystick, Uint16 low_frequency_r static Uint16 (*pSDL_JoystickGetProduct)(SDL_Joystick * joystick); static Uint16 (*pSDL_JoystickGetProductVersion)(SDL_Joystick * joystick); static Uint16 (*pSDL_JoystickGetVendor)(SDL_Joystick * joystick); +static SDL_JoystickType (*pSDL_JoystickGetType)(SDL_Joystick * joystick);
/* internal bits for extended rumble support, SDL_Haptic types are 16-bits */ #define WINE_SDL_JOYSTICK_RUMBLE 0x40000000 /* using SDL_JoystickRumble API */ @@ -258,6 +259,7 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface) }; struct sdl_device *impl = impl_from_unix_device(iface); int i, button_count, axis_count, ball_count, hat_count; + USAGE_AND_PAGE physical_usage;
axis_count = pSDL_JoystickNumAxes(impl->sdl_joystick); if (axis_count > ARRAY_SIZE(absolute_usages)) @@ -276,10 +278,37 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface) hat_count = pSDL_JoystickNumHats(impl->sdl_joystick); button_count = pSDL_JoystickNumButtons(impl->sdl_joystick);
+ if (!pSDL_JoystickGetType) physical_usage = device_usage; + else switch (pSDL_JoystickGetType(impl->sdl_joystick)) + { + case SDL_JOYSTICK_TYPE_ARCADE_PAD: + case SDL_JOYSTICK_TYPE_ARCADE_STICK: + case SDL_JOYSTICK_TYPE_DANCE_PAD: + case SDL_JOYSTICK_TYPE_DRUM_KIT: + case SDL_JOYSTICK_TYPE_GUITAR: + case SDL_JOYSTICK_TYPE_UNKNOWN: + physical_usage.UsagePage = HID_USAGE_PAGE_GENERIC; + physical_usage.Usage = HID_USAGE_GENERIC_JOYSTICK; + break; + case SDL_JOYSTICK_TYPE_GAMECONTROLLER: + physical_usage.UsagePage = HID_USAGE_PAGE_GENERIC; + physical_usage.Usage = HID_USAGE_GENERIC_GAMEPAD; + break; + case SDL_JOYSTICK_TYPE_WHEEL: + physical_usage.UsagePage = HID_USAGE_PAGE_SIMULATION; + physical_usage.Usage = HID_USAGE_SIMULATION_AUTOMOBILE_SIMULATION_DEVICE; + break; + case SDL_JOYSTICK_TYPE_FLIGHT_STICK: + case SDL_JOYSTICK_TYPE_THROTTLE: + physical_usage.UsagePage = HID_USAGE_PAGE_SIMULATION; + physical_usage.Usage = HID_USAGE_SIMULATION_FLIGHT_SIMULATION_DEVICE; + break; + } + if (!hid_device_begin_report_descriptor(iface, &device_usage)) return STATUS_NO_MEMORY;
- if (!hid_device_begin_input_report(iface, &device_usage)) + if (!hid_device_begin_input_report(iface, &physical_usage)) return STATUS_NO_MEMORY;
for (i = 0; i < axis_count; i++) @@ -1026,6 +1055,7 @@ NTSTATUS sdl_bus_init(void *args) pSDL_JoystickGetProduct = dlsym(sdl_handle, "SDL_JoystickGetProduct"); pSDL_JoystickGetProductVersion = dlsym(sdl_handle, "SDL_JoystickGetProductVersion"); pSDL_JoystickGetVendor = dlsym(sdl_handle, "SDL_JoystickGetVendor"); + pSDL_JoystickGetType = dlsym(sdl_handle, "SDL_JoystickGetType");
if (pSDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) < 0) {
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/joystick_hid.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 1a39dfd6cab..4f1c8444e43 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -1418,10 +1418,12 @@ static BOOL hid_joystick_device_try_open( UINT32 handle, const WCHAR *path, HAND { BOOL has_accelerator, has_brake, has_clutch, has_z, has_pov; PHIDP_PREPARSED_DATA preparsed_data = NULL; + HIDP_LINK_COLLECTION_NODE nodes[256]; DWORD type, button_count = 0; HIDP_BUTTON_CAPS buttons[10]; HIDP_VALUE_CAPS value; HANDLE device_file; + ULONG node_count; NTSTATUS status; USHORT count;
@@ -1453,6 +1455,16 @@ static BOOL hid_joystick_device_try_open( UINT32 handle, const WCHAR *path, HAND instance->wUsagePage = caps->UsagePage; instance->wUsage = caps->Usage;
+ node_count = ARRAY_SIZE(nodes); + status = HidP_GetLinkCollectionNodes( nodes, &node_count, preparsed_data ); + if (status != HIDP_STATUS_SUCCESS) node_count = 0; + while (node_count--) + { + if (nodes[node_count].LinkUsagePage != HID_USAGE_PAGE_SIMULATION) continue; + if (nodes[node_count].LinkUsage == HID_USAGE_SIMULATION_AUTOMOBILE_SIMULATION_DEVICE) type = DI8DEVTYPE_DRIVING; + if (nodes[node_count].LinkUsage == HID_USAGE_SIMULATION_FLIGHT_SIMULATION_DEVICE) type = DI8DEVTYPE_FLIGHT; + } + count = ARRAY_SIZE(buttons); status = HidP_GetSpecificButtonCaps( HidP_Output, HID_USAGE_PAGE_PID, 0, PID_USAGE_DC_DEVICE_RESET, buttons, &count, preparsed_data ); @@ -1533,6 +1545,9 @@ static BOOL hid_joystick_device_try_open( UINT32 handle, const WCHAR *path, HAND else type |= (DI8DEVTYPEDRIVING_LIMITED << 8); break; + case DI8DEVTYPE_FLIGHT: + type |= (DI8DEVTYPEFLIGHT_STICK << 8); + break; }
instance->dwDevType = device_type_for_version( type, version ) | DIDEVTYPE_HID;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=109681
Your paranoid android.
=== w8 (32 bit report) ===
dinput: joystick8.c:1692: Test failed: 0x800: got lX 16853 joystick8.c:1693: Test failed: 0x800: got lY 16853