Throttle that comes with Thrustmaster T16000M FCS has a dial that doesn't work / is usassignable in many games (e.g. Elite Dangerous).
Returning correct GUID and name would be enough but it breaks the tests due to some quirks of the default format so that is also fixed.
-- v2: dinput/tests: Test GetObjectInfo() with three sliders and a proper format. dinput/tests: Assert that we can't get info about the third slider with c_dfDIJoystick2. dinput: Use GUID_Slider type for dials. dinput: Enumerate user format object forwards. dinput/tests: Use helper for checking device object instances. dinput: Get rid of unused parameter in match_device_object. dinput: Set correct object names for dials and sliders.
From: Arkadiusz Hiler ahiler@codeweavers.com
--- dlls/dinput/joystick_hid.c | 2 ++ dlls/dinput/tests/joystick8.c | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 3dc7b70aac4..7370982d4c9 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -354,6 +354,8 @@ static const WCHAR *object_usage_to_string( DIDEVICEOBJECTINSTANCEW *instance ) case MAKELONG(HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC): return L"X Axis"; case MAKELONG(HID_USAGE_GENERIC_Y, HID_USAGE_PAGE_GENERIC): return L"Y Axis"; case MAKELONG(HID_USAGE_GENERIC_Z, HID_USAGE_PAGE_GENERIC): return L"Z Axis"; + case MAKELONG(HID_USAGE_GENERIC_SLIDER, HID_USAGE_PAGE_GENERIC): return L"Slider"; + case MAKELONG(HID_USAGE_GENERIC_DIAL, HID_USAGE_PAGE_GENERIC): return L"Dial";
case MAKELONG(PID_USAGE_ATTACK_LEVEL, HID_USAGE_PAGE_PID): return L"Attack Level"; case MAKELONG(PID_USAGE_ATTACK_TIME, HID_USAGE_PAGE_PID): return L"Attack Time"; diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index e73330815a0..95c78aa5563 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -2992,8 +2992,8 @@ static void test_many_axes_joystick(void) {0}, {0}, {0}, - {.name = TRUE}, - {.name = TRUE, .guid = TRUE}, + {0}, + {.guid = TRUE}, {.flags = TRUE}, {.flags = TRUE}, {.flags = TRUE}, @@ -3120,7 +3120,7 @@ static void test_many_axes_joystick(void) check_member( objinst, expect_objects[8], "%#lx", dwOfs ); check_member( objinst, expect_objects[8], "%#lx", dwType ); check_member( objinst, expect_objects[8], "%#lx", dwFlags ); - if (!localized) todo_wine check_member_wstr( objinst, expect_objects[8], tszName ); + if (!localized) check_member_wstr( objinst, expect_objects[8], tszName ); check_member( objinst, expect_objects[8], "%lu", dwFFMaxForce ); check_member( objinst, expect_objects[8], "%lu", dwFFForceResolution ); check_member( objinst, expect_objects[8], "%u", wCollectionNumber );
From: Arkadiusz Hiler ahiler@codeweavers.com
--- dlls/dinput/device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index f4bdce51633..e15a22bb413 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -244,7 +244,7 @@ LPDIOBJECTDATAFORMAT dataformat_to_odf_by_type(LPCDIDATAFORMAT df, int n, DWORD }
static BOOL match_device_object( const DIDATAFORMAT *device_format, DIDATAFORMAT *user_format, - const DIDATAFORMAT *format, const DIOBJECTDATAFORMAT *match_obj, DWORD version ) + const DIOBJECTDATAFORMAT *match_obj, DWORD version ) { DWORD i, device_instance, instance = DIDFT_GETINSTANCE( match_obj->dwType ); DIOBJECTDATAFORMAT *device_obj, *user_obj; @@ -292,7 +292,7 @@ static HRESULT dinput_device_init_user_format( struct dinput_device *impl, const { match_obj = format->rgodf + i;
- if (!match_device_object( device_format, user_format, format, match_obj, impl->dinput->dwVersion )) + if (!match_device_object( device_format, user_format, match_obj, impl->dinput->dwVersion )) { WARN( "object %s not found\n", debugstr_diobjectdataformat( match_obj ) ); if (!(match_obj->dwType & DIDFT_OPTIONAL)) goto failed;
From: Arkadiusz Hiler ahiler@codeweavers.com
--- dlls/dinput/tests/joystick8.c | 223 ++++++++-------------------------- 1 file changed, 49 insertions(+), 174 deletions(-)
diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 95c78aa5563..a8f444e09a9 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -74,7 +74,7 @@ failed: return FALSE; }
-struct check_objects_todos +struct check_object_todo { BOOL type; BOOL ofs; @@ -91,17 +91,48 @@ struct check_objects_params UINT index; UINT expect_count; const DIDEVICEOBJECTINSTANCEW *expect_objs; - const struct check_objects_todos *todo_objs; + const struct check_object_todo *todo_objs; BOOL todo_extra; };
+#define check_object( a, b, c ) check_object_( __LINE__, a, b, c ) +static void check_object_( int line, const DIDEVICEOBJECTINSTANCEW *actual, + const DIDEVICEOBJECTINSTANCEW *expected, + const struct check_object_todo *todo ) +{ + static const struct check_object_todo todo_none = {0}; + if (!todo) todo = &todo_none; + + check_member_( __FILE__, line, *actual, *expected, "%lu", dwSize ); + todo_wine_if( todo->guid ) + check_member_guid_( __FILE__, line, *actual, *expected, guidType ); + todo_wine_if( todo->ofs ) + check_member_( __FILE__, line, *actual, *expected, "%#lx", dwOfs ); + todo_wine_if( todo->type ) + check_member_( __FILE__, line, *actual, *expected, "%#lx", dwType ); + todo_wine_if( todo->flags ) + check_member_( __FILE__, line, *actual, *expected, "%#lx", dwFlags ); + if (!localized) todo_wine_if( todo->name ) check_member_wstr_( __FILE__, line, *actual, *expected, tszName ); + check_member_( __FILE__, line, *actual, *expected, "%lu", dwFFMaxForce ); + check_member_( __FILE__, line, *actual, *expected, "%lu", dwFFForceResolution ); + check_member_( __FILE__, line, *actual, *expected, "%u", wCollectionNumber ); + check_member_( __FILE__, line, *actual, *expected, "%u", wDesignatorIndex ); + todo_wine_if( todo->usage_page ) + check_member_( __FILE__, line, *actual, *expected, "%#04x", wUsagePage ); + todo_wine_if( todo->usage ) + check_member_( __FILE__, line, *actual, *expected, "%#04x", wUsage ); + check_member_( __FILE__, line, *actual, *expected, "%#lx", dwDimension ); + check_member_( __FILE__, line, *actual, *expected, "%#04x", wExponent ); + check_member_( __FILE__, line, *actual, *expected, "%u", wReportId ); +} + static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *args ) { static const DIDEVICEOBJECTINSTANCEW unexpected_obj = {0}; - static const struct check_objects_todos todo_none = {0}; + static const struct check_object_todo todo_none = {0}; struct check_objects_params *params = args; const DIDEVICEOBJECTINSTANCEW *exp = params->expect_objs + params->index; - const struct check_objects_todos *todo; + const struct check_object_todo *todo;
if (!params->todo_objs) todo = &todo_none; else todo = params->todo_objs + params->index; @@ -115,27 +146,7 @@ static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *ar ok( params->index < params->expect_count, "unexpected extra object\n" ); if (params->index >= params->expect_count) exp = &unexpected_obj;
- check_member( *obj, *exp, "%lu", dwSize ); - todo_wine_if( todo->guid ) - check_member_guid( *obj, *exp, guidType ); - todo_wine_if( todo->ofs ) - check_member( *obj, *exp, "%#lx", dwOfs ); - todo_wine_if( todo->type ) - check_member( *obj, *exp, "%#lx", dwType ); - todo_wine_if( todo->flags ) - check_member( *obj, *exp, "%#lx", dwFlags ); - if (!localized) todo_wine_if( todo->name )check_member_wstr( *obj, *exp, tszName ); - check_member( *obj, *exp, "%lu", dwFFMaxForce ); - check_member( *obj, *exp, "%lu", dwFFForceResolution ); - check_member( *obj, *exp, "%u", wCollectionNumber ); - check_member( *obj, *exp, "%u", wDesignatorIndex ); - todo_wine_if( todo->usage_page ) - check_member( *obj, *exp, "%#04x", wUsagePage ); - todo_wine_if( todo->usage ) - check_member( *obj, *exp, "%#04x", wUsage ); - check_member( *obj, *exp, "%#lx", dwDimension ); - check_member( *obj, *exp, "%#04x", wExponent ); - check_member( *obj, *exp, "%u", wReportId ); + check_object( obj, exp, todo );
winetest_pop_context();
@@ -708,7 +719,7 @@ static void test_simple_joystick( DWORD version ) .wReportId = 1, }, }; - struct check_objects_todos todo_objects_5[ARRAY_SIZE(expect_objects_5)] = + struct check_object_todo todo_objects_5[ARRAY_SIZE(expect_objects_5)] = { {.guid = TRUE, .type = TRUE, .flags = TRUE, .usage = TRUE, .usage_page = TRUE, .name = TRUE}, {.guid = TRUE, .type = TRUE, .flags = TRUE, .usage = TRUE, .usage_page = TRUE, .name = TRUE}, @@ -718,6 +729,7 @@ static void test_simple_joystick( DWORD version ) {.guid = TRUE, .ofs = TRUE, .type = TRUE, .flags = TRUE, .usage = TRUE, .usage_page = TRUE, .name = TRUE}, {.guid = TRUE, .ofs = TRUE, .type = TRUE, .usage = TRUE, .usage_page = TRUE, .name = TRUE}, }; + struct check_object_todo todo_ofs = {.ofs = TRUE}; struct check_objects_params check_objects_params = { .version = version, @@ -1117,22 +1129,7 @@ static void test_simple_joystick( DWORD version )
if (version < 0x0700) expect_obj = expect_objects_5[0]; else expect_obj = expect_objects[4]; - check_member( objinst, expect_obj, "%lu", dwSize ); - check_member_guid( objinst, expect_obj, guidType ); - todo_wine_if( version < 0x0700 ) - check_member( objinst, expect_obj, "%#lx", dwOfs ); - check_member( objinst, expect_obj, "%#lx", dwType ); - check_member( objinst, expect_obj, "%#lx", dwFlags ); - if (!localized) check_member_wstr( objinst, expect_obj, tszName ); - check_member( objinst, expect_obj, "%lu", dwFFMaxForce ); - check_member( objinst, expect_obj, "%lu", dwFFForceResolution ); - check_member( objinst, expect_obj, "%u", wCollectionNumber ); - check_member( objinst, expect_obj, "%u", wDesignatorIndex ); - check_member( objinst, expect_obj, "%#04x", wUsagePage ); - check_member( objinst, expect_obj, "%#04x", wUsage ); - check_member( objinst, expect_obj, "%#lx", dwDimension ); - check_member( objinst, expect_obj, "%#04x", wExponent ); - check_member( objinst, expect_obj, "%u", wReportId ); + check_object( &objinst, &expect_obj, version < 0x0700 ? &todo_ofs : NULL );
hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, 0x14, DIPH_BYOFFSET ); ok( hr == DIERR_NOTFOUND, "GetObjectInfo returned: %#lx\n", hr ); @@ -1147,22 +1144,7 @@ static void test_simple_joystick( DWORD version )
if (version < 0x0700) expect_obj = expect_objects_5[6]; else expect_obj = expect_objects[8]; - check_member( objinst, expect_obj, "%lu", dwSize ); - check_member_guid( objinst, expect_obj, guidType ); - todo_wine_if( version < 0x0700 ) - check_member( objinst, expect_obj, "%#lx", dwOfs ); - check_member( objinst, expect_obj, "%#lx", dwType ); - check_member( objinst, expect_obj, "%#lx", dwFlags ); - if (!localized) check_member_wstr( objinst, expect_obj, tszName ); - check_member( objinst, expect_obj, "%lu", dwFFMaxForce ); - check_member( objinst, expect_obj, "%lu", dwFFForceResolution ); - check_member( objinst, expect_obj, "%u", wCollectionNumber ); - check_member( objinst, expect_obj, "%u", wDesignatorIndex ); - check_member( objinst, expect_obj, "%#04x", wUsagePage ); - check_member( objinst, expect_obj, "%#04x", wUsage ); - check_member( objinst, expect_obj, "%#lx", dwDimension ); - check_member( objinst, expect_obj, "%#04x", wExponent ); - check_member( objinst, expect_obj, "%u", wReportId ); + check_object( &objinst, &expect_obj, version < 0x0700 ? &todo_ofs : NULL );
hr = IDirectInputDevice8_EnumEffects( device, NULL, NULL, DIEFT_ALL ); ok( hr == DIERR_INVALIDPARAM, "EnumEffects returned %#lx\n", hr ); @@ -1209,22 +1191,7 @@ static void test_simple_joystick( DWORD version ) if (version < 0x0700) expect_obj = expect_objects_5[1]; else expect_obj = expect_objects[3]; if (version < 0x0800) expect_obj.dwOfs = DIJOFS_Y; - check_member( objinst, expect_obj, "%lu", dwSize ); - check_member_guid( objinst, expect_obj, guidType ); - todo_wine_if( version < 0x0800 ) - check_member( objinst, expect_obj, "%#lx", dwOfs ); - check_member( objinst, expect_obj, "%#lx", dwType ); - check_member( objinst, expect_obj, "%#lx", dwFlags ); - if (!localized) check_member_wstr( objinst, expect_obj, tszName ); - check_member( objinst, expect_obj, "%lu", dwFFMaxForce ); - check_member( objinst, expect_obj, "%lu", dwFFForceResolution ); - check_member( objinst, expect_obj, "%u", wCollectionNumber ); - check_member( objinst, expect_obj, "%u", wDesignatorIndex ); - check_member( objinst, expect_obj, "%#04x", wUsagePage ); - check_member( objinst, expect_obj, "%#04x", wUsage ); - check_member( objinst, expect_obj, "%#lx", dwDimension ); - check_member( objinst, expect_obj, "%#04x", wExponent ); - check_member( objinst, expect_obj, "%u", wReportId ); + check_object( &objinst, &expect_obj, version < 0x0800 ? &todo_ofs : NULL );
hr = IDirectInputDevice8_SetEventNotification( device, (HANDLE)0xdeadbeef ); todo_wine @@ -2982,7 +2949,7 @@ static void test_many_axes_joystick(void) .wUsage = HID_USAGE_GENERIC_JOYSTICK, }, }; - struct check_objects_todos todo_objects[ARRAY_SIZE(expect_objects)] = + struct check_object_todo todo_objects[ARRAY_SIZE(expect_objects)] = { {0}, {0}, @@ -3013,6 +2980,7 @@ static void test_many_axes_joystick(void) };
DIDEVICEOBJECTINSTANCEW objinst = {.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW)}; + struct check_object_todo todo_flags = {.flags = TRUE}; DIDEVICEINSTANCEW devinst = {0}; IDirectInputDevice8W *device; DIDEVCAPS caps = {0}; @@ -3076,120 +3044,27 @@ static void test_many_axes_joystick(void)
hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, DIJOFS_RZ, DIPH_BYOFFSET ); ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr ); - - check_member( objinst, expect_objects[5], "%lu", dwSize ); - check_member_guid( objinst, expect_objects[5], guidType ); - check_member( objinst, expect_objects[5], "%#lx", dwOfs ); - check_member( objinst, expect_objects[5], "%#lx", dwType ); - check_member( objinst, expect_objects[5], "%#lx", dwFlags ); - if (!localized) check_member_wstr( objinst, expect_objects[5], tszName ); - check_member( objinst, expect_objects[5], "%lu", dwFFMaxForce ); - check_member( objinst, expect_objects[5], "%lu", dwFFForceResolution ); - check_member( objinst, expect_objects[5], "%u", wCollectionNumber ); - check_member( objinst, expect_objects[5], "%u", wDesignatorIndex ); - check_member( objinst, expect_objects[5], "%#04x", wUsagePage ); - check_member( objinst, expect_objects[5], "%#04x", wUsage ); - check_member( objinst, expect_objects[5], "%#lx", dwDimension ); - check_member( objinst, expect_objects[5], "%#04x", wExponent ); - check_member( objinst, expect_objects[5], "%u", wReportId ); + check_object( &objinst, &expect_objects[5], NULL );
hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, offsetof(DIJOYSTATE2, rglSlider[0]), DIPH_BYOFFSET ); ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr ); - - check_member( objinst, expect_objects[6], "%lu", dwSize ); - check_member_guid( objinst, expect_objects[6], guidType ); - check_member( objinst, expect_objects[6], "%#lx", dwOfs ); - check_member( objinst, expect_objects[6], "%#lx", dwType ); - check_member( objinst, expect_objects[6], "%#lx", dwFlags ); - if (!localized) check_member_wstr( objinst, expect_objects[6], tszName ); - check_member( objinst, expect_objects[6], "%lu", dwFFMaxForce ); - check_member( objinst, expect_objects[6], "%lu", dwFFForceResolution ); - check_member( objinst, expect_objects[6], "%u", wCollectionNumber ); - check_member( objinst, expect_objects[6], "%u", wDesignatorIndex ); - check_member( objinst, expect_objects[6], "%#04x", wUsagePage ); - check_member( objinst, expect_objects[6], "%#04x", wUsage ); - check_member( objinst, expect_objects[6], "%#lx", dwDimension ); - check_member( objinst, expect_objects[6], "%#04x", wExponent ); - check_member( objinst, expect_objects[6], "%u", wReportId ); + check_object( &objinst, &expect_objects[6], NULL );
hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, offsetof(DIJOYSTATE2, rglSlider[1]), DIPH_BYOFFSET ); ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr ); - - check_member( objinst, expect_objects[8], "%lu", dwSize ); - check_member_guid( objinst, expect_objects[8], guidType ); - check_member( objinst, expect_objects[8], "%#lx", dwOfs ); - check_member( objinst, expect_objects[8], "%#lx", dwType ); - check_member( objinst, expect_objects[8], "%#lx", dwFlags ); - if (!localized) check_member_wstr( objinst, expect_objects[8], tszName ); - check_member( objinst, expect_objects[8], "%lu", dwFFMaxForce ); - check_member( objinst, expect_objects[8], "%lu", dwFFForceResolution ); - check_member( objinst, expect_objects[8], "%u", wCollectionNumber ); - check_member( objinst, expect_objects[8], "%u", wDesignatorIndex ); - check_member( objinst, expect_objects[8], "%#04x", wUsagePage ); - check_member( objinst, expect_objects[8], "%#04x", wUsage ); - check_member( objinst, expect_objects[8], "%#lx", dwDimension ); - check_member( objinst, expect_objects[8], "%#04x", wExponent ); - check_member( objinst, expect_objects[8], "%u", wReportId ); + check_object( &objinst, &expect_objects[8], NULL );
hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, offsetof(DIJOYSTATE2, lVX), DIPH_BYOFFSET ); ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr ); - - check_member( objinst, expect_objects[10], "%lu", dwSize ); - check_member_guid( objinst, expect_objects[10], guidType ); - check_member( objinst, expect_objects[10], "%#lx", dwOfs ); - check_member( objinst, expect_objects[10], "%#lx", dwType ); - todo_wine - check_member( objinst, expect_objects[10], "%#lx", dwFlags ); - if (!localized) check_member_wstr( objinst, expect_objects[10], tszName ); - check_member( objinst, expect_objects[10], "%lu", dwFFMaxForce ); - check_member( objinst, expect_objects[10], "%lu", dwFFForceResolution ); - check_member( objinst, expect_objects[10], "%u", wCollectionNumber ); - check_member( objinst, expect_objects[10], "%u", wDesignatorIndex ); - check_member( objinst, expect_objects[10], "%#04x", wUsagePage ); - check_member( objinst, expect_objects[10], "%#04x", wUsage ); - check_member( objinst, expect_objects[10], "%#lx", dwDimension ); - check_member( objinst, expect_objects[10], "%#04x", wExponent ); - check_member( objinst, expect_objects[10], "%u", wReportId ); + check_object( &objinst, &expect_objects[10], &todo_flags );
hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, offsetof(DIJOYSTATE2, lAX), DIPH_BYOFFSET ); ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr ); - - check_member( objinst, expect_objects[13], "%lu", dwSize ); - check_member_guid( objinst, expect_objects[13], guidType ); - check_member( objinst, expect_objects[13], "%#lx", dwOfs ); - check_member( objinst, expect_objects[13], "%#lx", dwType ); - todo_wine - check_member( objinst, expect_objects[13], "%#lx", dwFlags ); - if (!localized) check_member_wstr( objinst, expect_objects[13], tszName ); - check_member( objinst, expect_objects[13], "%lu", dwFFMaxForce ); - check_member( objinst, expect_objects[13], "%lu", dwFFForceResolution ); - check_member( objinst, expect_objects[13], "%u", wCollectionNumber ); - check_member( objinst, expect_objects[13], "%u", wDesignatorIndex ); - check_member( objinst, expect_objects[13], "%#04x", wUsagePage ); - check_member( objinst, expect_objects[13], "%#04x", wUsage ); - check_member( objinst, expect_objects[13], "%#lx", dwDimension ); - check_member( objinst, expect_objects[13], "%#04x", wExponent ); - check_member( objinst, expect_objects[13], "%u", wReportId ); + check_object( &objinst, &expect_objects[13], &todo_flags );
hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, offsetof(DIJOYSTATE2, lFX), DIPH_BYOFFSET ); ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr ); - - check_member( objinst, expect_objects[16], "%lu", dwSize ); - check_member_guid( objinst, expect_objects[16], guidType ); - check_member( objinst, expect_objects[16], "%#lx", dwOfs ); - check_member( objinst, expect_objects[16], "%#lx", dwType ); - todo_wine - check_member( objinst, expect_objects[16], "%#lx", dwFlags ); - if (!localized) check_member_wstr( objinst, expect_objects[16], tszName ); - check_member( objinst, expect_objects[16], "%lu", dwFFMaxForce ); - check_member( objinst, expect_objects[16], "%lu", dwFFForceResolution ); - check_member( objinst, expect_objects[16], "%u", wCollectionNumber ); - check_member( objinst, expect_objects[16], "%u", wDesignatorIndex ); - check_member( objinst, expect_objects[16], "%#04x", wUsagePage ); - check_member( objinst, expect_objects[16], "%#04x", wUsage ); - check_member( objinst, expect_objects[16], "%#lx", dwDimension ); - check_member( objinst, expect_objects[16], "%#04x", wExponent ); - check_member( objinst, expect_objects[16], "%u", wReportId ); + check_object( &objinst, &expect_objects[16], &todo_flags );
ref = IDirectInputDevice8_Release( device ); ok( ref == 0, "Release returned %ld\n", ref );
From: Arkadiusz Hiler ahiler@codeweavers.com
It's important for the default broken formats like c_dfDIJoystick2 which have multiple sets of sliders defined with the same offsets. --- dlls/dinput/device.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index e15a22bb413..f0220252279 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -880,25 +880,23 @@ static HRESULT WINAPI dinput_device_EnumObjects( IDirectInputDevice8W *iface,
static HRESULT enum_object_filter_init( struct dinput_device *impl, DIPROPHEADER *filter ) { - DIDATAFORMAT *device_format = &impl->device_format, *user_format = &impl->user_format; - DIOBJECTDATAFORMAT *device_obj, *user_obj; + DIOBJECTDATAFORMAT *user_objs = impl->user_format.rgodf; + DWORD i, count = impl->device_format.dwNumObjs;
if (filter->dwHow > DIPH_BYUSAGE) return DIERR_INVALIDPARAM; if (filter->dwHow == DIPH_BYUSAGE && !(impl->instance.dwDevType & DIDEVTYPE_HID)) return DIERR_UNSUPPORTED; if (filter->dwHow != DIPH_BYOFFSET) return DI_OK;
- if (!user_format->rgodf) return DIERR_NOTFOUND; + if (!user_objs) return DIERR_NOTFOUND;
- user_obj = user_format->rgodf + device_format->dwNumObjs; - device_obj = device_format->rgodf + device_format->dwNumObjs; - while (user_obj-- > user_format->rgodf && device_obj-- > device_format->rgodf) + for (i = 0; i < count; i++) { - if (!user_obj->dwType) continue; - if (user_obj->dwOfs == filter->dwObj) break; + if (!user_objs[i].dwType) continue; + if (user_objs[i].dwOfs == filter->dwObj) break; } - if (user_obj < user_format->rgodf) return DIERR_NOTFOUND; + if (i == count) return DIERR_NOTFOUND;
- filter->dwObj = device_obj->dwOfs; + filter->dwObj = impl->device_format.rgodf[i].dwOfs; return DI_OK; }
From: Arkadiusz Hiler ahiler@codeweavers.com
--- dlls/dinput/joystick_hid.c | 1 + dlls/dinput/tests/joystick8.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 7370982d4c9..ebebbee6eb2 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -276,6 +276,7 @@ static const GUID *object_usage_to_guid( USAGE usage_page, USAGE usage ) case HID_USAGE_GENERIC_RY: return &GUID_RyAxis; case HID_USAGE_GENERIC_RZ: return &GUID_RzAxis; case HID_USAGE_GENERIC_SLIDER: return &GUID_Slider; + case HID_USAGE_GENERIC_DIAL: return &GUID_Slider; case HID_USAGE_GENERIC_HATSWITCH: return &GUID_POV; } break; diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index a8f444e09a9..4ef9f8db78a 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -2960,7 +2960,7 @@ static void test_many_axes_joystick(void) {0}, {0}, {0}, - {.guid = TRUE}, + {0}, {.flags = TRUE}, {.flags = TRUE}, {.flags = TRUE},
From: Arkadiusz Hiler ahiler@codeweavers.com
--- dlls/dinput/tests/joystick8.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 4ef9f8db78a..70b70fb9fca 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -3054,6 +3054,10 @@ static void test_many_axes_joystick(void) ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr ); check_object( &objinst, &expect_objects[8], NULL );
+ /* c_dfDIJoystick2 is broken when it comes to more than two sliders */ + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, offsetof(DIJOYSTATE2, rglVSlider[0]), DIPH_BYOFFSET ); + ok( hr == DIERR_NOTFOUND, "GetObjectInfo returned: %#lx\n", hr ); + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, offsetof(DIJOYSTATE2, lVX), DIPH_BYOFFSET ); ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr ); check_object( &objinst, &expect_objects[10], &todo_flags );
From: Arkadiusz Hiler ahiler@codeweavers.com
--- dlls/dinput/tests/joystick8.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 70b70fb9fca..163e3851519 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -2596,6 +2596,25 @@ static BOOL test_device_types( DWORD version ) return success; }
+struct three_sliders_state { + LONG slider[3]; +}; + +static const DIOBJECTDATAFORMAT df_three_sliders[] = { + { &GUID_Slider,FIELD_OFFSET(struct three_sliders_state, slider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION}, + { &GUID_Slider,FIELD_OFFSET(struct three_sliders_state, slider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION}, + { &GUID_Slider,FIELD_OFFSET(struct three_sliders_state, slider[2]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION}, +}; + +static const DIDATAFORMAT c_df_three_sliders = { + sizeof(DIDATAFORMAT), + sizeof(DIOBJECTDATAFORMAT), + DIDF_ABSAXIS, + sizeof(struct three_sliders_state), + ARRAY_SIZE(df_three_sliders), + (LPDIOBJECTDATAFORMAT)df_three_sliders +}; + static void test_many_axes_joystick(void) { #include "psh_hid_macros.h" @@ -3070,6 +3089,22 @@ static void test_many_axes_joystick(void) ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr ); check_object( &objinst, &expect_objects[16], &todo_flags );
+ /* make sure that we handle three sliders correctly when the format allows */ + hr = IDirectInputDevice8_SetDataFormat( device, &c_df_three_sliders ); + ok( hr == DI_OK, "SetDataFormat returned: %#lx\n", hr ); + + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, offsetof(struct three_sliders_state, slider[0]), DIPH_BYOFFSET ); + ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr ); + check_object( &objinst, &expect_objects[6], NULL ); + + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, offsetof(struct three_sliders_state, slider[1]), DIPH_BYOFFSET ); + ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr ); + check_object( &objinst, &expect_objects[8], NULL ); + + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, offsetof(struct three_sliders_state, slider[2]), DIPH_BYOFFSET ); + ok( hr == DI_OK, "GetObjectInfo returned: %#lx\n", hr ); + check_object( &objinst, &expect_objects[9], NULL ); + ref = IDirectInputDevice8_Release( device ); ok( ref == 0, "Release returned %ld\n", ref );
On Mon Jul 25 10:40:59 2022 +0000, Arek Hiler wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/507/diffs?diff_id=5880&start_sha=59205cd27b61e97c81fa0852794f0d457597f86b#76ba266f5fce82fd34d1cb1e00e1d0b904431229_77_76)
Yes, I agree that it's not very easy to track the individual objects and such a change is generally useful, but the testbot has a small output size limit compared to the number of tests and I'd prefer to keep it local for now at least.
Would you mind updating to https://gitlab.winehq.org/rbernon/wine/-/commit/96877441f24 with some bracing and indent fixes for the last change?