This should prevent spurious failures on Windows.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/hid.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 007f81688cc..9ec9d147dd1 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -4267,6 +4267,7 @@ static void test_simple_joystick(void)
hwnd = CreateWindowW( L"static", L"dinput", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 10, 10, 200, 200, NULL, NULL, NULL, NULL ); + SetForegroundWindow( hwnd );
hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE ); ok( hr == DI_OK, "SetCooperativeLevel returned: %#x\n", hr );
Fixes some issues with apps like WheelCheck from iRacing, which show detailed info about available objects on the device (such as axes, buttons, other non-data caps, collections, etc.).
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/joystick_hid.c | 92 +++++++++++++++++++++++++++++++++++++- dlls/dinput8/tests/hid.c | 13 +++--- 2 files changed, 98 insertions(+), 7 deletions(-)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 67a43924e19..17b79a0f716 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -294,6 +294,85 @@ static const WCHAR *effect_guid_to_string( const GUID *guid ) return L"GUID_Unknown"; }
+static const WCHAR *object_usage_to_string( DIDEVICEOBJECTINSTANCEW *instance ) +{ + switch (MAKELONG(instance->wUsage, instance->wUsagePage)) + { + case MAKELONG(HID_USAGE_DIGITIZER_TIP_PRESSURE, HID_USAGE_PAGE_DIGITIZER): return L"Tip Pressure"; + case MAKELONG(HID_USAGE_CONSUMER_VOLUME, HID_USAGE_PAGE_CONSUMER): return L"Volume"; + + case MAKELONG(HID_USAGE_GENERIC_HATSWITCH, HID_USAGE_PAGE_GENERIC): return L"Hat Switch"; + case MAKELONG(HID_USAGE_GENERIC_JOYSTICK, HID_USAGE_PAGE_GENERIC): return L"Joystick"; + case MAKELONG(HID_USAGE_GENERIC_RX, HID_USAGE_PAGE_GENERIC): return L"X Rotation"; + case MAKELONG(HID_USAGE_GENERIC_RY, HID_USAGE_PAGE_GENERIC): return L"Y Rotation"; + case MAKELONG(HID_USAGE_GENERIC_RZ, HID_USAGE_PAGE_GENERIC): return L"Z Rotation"; + case MAKELONG(HID_USAGE_GENERIC_WHEEL, HID_USAGE_PAGE_GENERIC): return L"Wheel"; + 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(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"; + case MAKELONG(PID_USAGE_AXES_ENABLE, HID_USAGE_PAGE_PID): return L"Axes Enable"; + + case MAKELONG(PID_USAGE_DC_DEVICE_CONTINUE, HID_USAGE_PAGE_PID): return L"DC Device Continue"; + case MAKELONG(PID_USAGE_DC_DEVICE_PAUSE, HID_USAGE_PAGE_PID): return L"DC Device Pause"; + case MAKELONG(PID_USAGE_DC_DEVICE_RESET, HID_USAGE_PAGE_PID): return L"DC Device Reset"; + case MAKELONG(PID_USAGE_DC_DISABLE_ACTUATORS, HID_USAGE_PAGE_PID): return L"DC Disable Actuators"; + case MAKELONG(PID_USAGE_DC_ENABLE_ACTUATORS, HID_USAGE_PAGE_PID): return L"DC Enable Actuators"; + case MAKELONG(PID_USAGE_DC_STOP_ALL_EFFECTS, HID_USAGE_PAGE_PID): return L"DC Stop All Effects"; + + case MAKELONG(PID_USAGE_CP_OFFSET, HID_USAGE_PAGE_PID): return L"CP Offset"; + case MAKELONG(PID_USAGE_DEAD_BAND, HID_USAGE_PAGE_PID): return L"Dead Band"; + case MAKELONG(PID_USAGE_DEVICE_CONTROL, HID_USAGE_PAGE_PID): return L"PID Device Control"; + case MAKELONG(PID_USAGE_DEVICE_CONTROL_REPORT, HID_USAGE_PAGE_PID): return L"PID Device Control Report"; + case MAKELONG(PID_USAGE_DIRECTION, HID_USAGE_PAGE_PID): return L"Direction"; + case MAKELONG(PID_USAGE_DIRECTION_ENABLE, HID_USAGE_PAGE_PID): return L"Direction Enable"; + case MAKELONG(PID_USAGE_DURATION, HID_USAGE_PAGE_PID): return L"Duration"; + case MAKELONG(PID_USAGE_EFFECT_BLOCK_INDEX, HID_USAGE_PAGE_PID): return L"Effect Block Index"; + case MAKELONG(PID_USAGE_EFFECT_OPERATION, HID_USAGE_PAGE_PID): return L"Effect Operation"; + case MAKELONG(PID_USAGE_EFFECT_OPERATION_REPORT, HID_USAGE_PAGE_PID): return L"Effect Operation Report"; + case MAKELONG(PID_USAGE_EFFECT_TYPE, HID_USAGE_PAGE_PID): return L"Effect Type"; + + case MAKELONG(PID_USAGE_ET_CONSTANT_FORCE, HID_USAGE_PAGE_PID): return L"ET Constant Force"; + case MAKELONG(PID_USAGE_ET_CUSTOM_FORCE_DATA, HID_USAGE_PAGE_PID): return L"ET Custom Force Data"; + case MAKELONG(PID_USAGE_ET_DAMPER, HID_USAGE_PAGE_PID): return L"ET Damper"; + case MAKELONG(PID_USAGE_ET_FRICTION, HID_USAGE_PAGE_PID): return L"ET Friction"; + case MAKELONG(PID_USAGE_ET_INERTIA, HID_USAGE_PAGE_PID): return L"ET Inertia"; + case MAKELONG(PID_USAGE_ET_RAMP, HID_USAGE_PAGE_PID): return L"ET Ramp"; + case MAKELONG(PID_USAGE_ET_SAWTOOTH_DOWN, HID_USAGE_PAGE_PID): return L"ET Sawtooth Down"; + case MAKELONG(PID_USAGE_ET_SAWTOOTH_UP, HID_USAGE_PAGE_PID): return L"ET Sawtooth Up"; + case MAKELONG(PID_USAGE_ET_SINE, HID_USAGE_PAGE_PID): return L"ET Sine"; + case MAKELONG(PID_USAGE_ET_SPRING, HID_USAGE_PAGE_PID): return L"ET Spring"; + case MAKELONG(PID_USAGE_ET_SQUARE, HID_USAGE_PAGE_PID): return L"ET Square"; + case MAKELONG(PID_USAGE_ET_TRIANGLE, HID_USAGE_PAGE_PID): return L"ET Triangle"; + + case MAKELONG(PID_USAGE_NEGATIVE_COEFFICIENT, HID_USAGE_PAGE_PID): return L"Negative Coefficient"; + case MAKELONG(PID_USAGE_NEGATIVE_SATURATION, HID_USAGE_PAGE_PID): return L"Negative Saturation"; + case MAKELONG(PID_USAGE_POSITIVE_COEFFICIENT, HID_USAGE_PAGE_PID): return L"Positive Coefficient"; + case MAKELONG(PID_USAGE_POSITIVE_SATURATION, HID_USAGE_PAGE_PID): return L"Positive Saturation"; + case MAKELONG(PID_USAGE_SET_CONDITION_REPORT, HID_USAGE_PAGE_PID): return L"Set Condition Report"; + case MAKELONG(PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET, HID_USAGE_PAGE_PID): return L"Type Specific Block Offset"; + + case MAKELONG(PID_USAGE_FADE_LEVEL, HID_USAGE_PAGE_PID): return L"Fade Level"; + case MAKELONG(PID_USAGE_FADE_TIME, HID_USAGE_PAGE_PID): return L"Fade Time"; + case MAKELONG(PID_USAGE_LOOP_COUNT, HID_USAGE_PAGE_PID): return L"Loop Count"; + case MAKELONG(PID_USAGE_MAGNITUDE, HID_USAGE_PAGE_PID): return L"Magnitude"; + case MAKELONG(PID_USAGE_OP_EFFECT_START, HID_USAGE_PAGE_PID): return L"Op Effect Start"; + case MAKELONG(PID_USAGE_OP_EFFECT_START_SOLO, HID_USAGE_PAGE_PID): return L"Op Effect Start Solo"; + case MAKELONG(PID_USAGE_OP_EFFECT_STOP, HID_USAGE_PAGE_PID): return L"Op Effect Stop"; + case MAKELONG(PID_USAGE_SET_EFFECT_REPORT, HID_USAGE_PAGE_PID): return L"Set Effect Report"; + case MAKELONG(PID_USAGE_SET_ENVELOPE_REPORT, HID_USAGE_PAGE_PID): return L"Set Envelope Report"; + case MAKELONG(PID_USAGE_SET_PERIODIC_REPORT, HID_USAGE_PAGE_PID): return L"Set Periodic Report"; + case MAKELONG(PID_USAGE_START_DELAY, HID_USAGE_PAGE_PID): return L"Start Delay"; + case MAKELONG(PID_USAGE_STATE_REPORT, HID_USAGE_PAGE_PID): return L"PID State Report"; + 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"; + default: return NULL; + } +} + static HRESULT find_next_effect_id( struct hid_joystick *impl, ULONG *index ) { ULONG i; @@ -365,13 +444,14 @@ static void set_axis_type( DIDEVICEOBJECTINSTANCEW *instance, BOOL *seen, DWORD static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *filter, DWORD flags, enum_object_callback callback, void *data ) { - DWORD collection = 0, object = 0, axis = 0, button = 0, pov = 0, value_ofs = 0, button_ofs = 0, j; + DWORD collection = 0, object = 0, axis = 0, button = 0, pov = 0, value_ofs = 0, button_ofs = 0, j, len; struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)impl->preparsed; DIDEVICEOBJECTINSTANCEW instance = {.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW)}; struct hid_value_caps *caps, *caps_end, *nary, *nary_end, *effect_caps; struct hid_collection_node *node, *node_end; WORD version = impl->base.dinput->dwVersion; BOOL ret, seen_axis[6] = {0}; + const WCHAR *tmp;
button_ofs += impl->caps.NumberInputValueCaps * sizeof(LONG); if (version >= 0x800) @@ -446,6 +526,8 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *filter, instance.wCollectionNumber = caps->link_collection; instance.dwDimension = caps->units; instance.wExponent = caps->units_exp; + if ((tmp = object_usage_to_string( &instance ))) lstrcpynW( instance.tszName, tmp, MAX_PATH ); + else swprintf( instance.tszName, MAX_PATH, L"Unknown %u", DIDFT_GETINSTANCE( instance.dwType ) ); check_pid_effect_axis_caps( impl, &instance ); ret = enum_object( impl, filter, flags, callback, caps, &instance, data ); if (ret != DIENUM_CONTINUE) return ret; @@ -486,6 +568,7 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *filter, instance.wCollectionNumber = caps->link_collection; instance.dwDimension = caps->units; instance.wExponent = caps->units_exp; + swprintf( instance.tszName, MAX_PATH, L"Button %u", DIDFT_GETINSTANCE( instance.dwType ) ); ret = enum_object( impl, filter, flags, callback, caps, &instance, data ); if (ret != DIENUM_CONTINUE) return ret; button_ofs++; @@ -522,6 +605,8 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *filter, instance.wCollectionNumber = nary->link_collection; instance.dwDimension = caps->units; instance.wExponent = caps->units_exp; + if ((tmp = object_usage_to_string( &instance ))) lstrcpynW( instance.tszName, tmp, MAX_PATH ); + else swprintf( instance.tszName, MAX_PATH, L"Unknown %u", DIDFT_GETINSTANCE( instance.dwType ) ); ret = enum_object( impl, filter, flags, callback, nary, &instance, data ); if (ret != DIENUM_CONTINUE) return ret; button_ofs++; @@ -542,6 +627,8 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *filter, instance.wCollectionNumber = caps->link_collection; instance.dwDimension = caps->units; instance.wExponent = caps->units_exp; + if ((tmp = object_usage_to_string( &instance ))) lstrcpynW( instance.tszName, tmp, MAX_PATH ); + else swprintf( instance.tszName, MAX_PATH, L"Unknown %u", DIDFT_GETINSTANCE( instance.dwType ) ); ret = enum_object( impl, filter, flags, callback, caps, &instance, data ); if (ret != DIENUM_CONTINUE) return ret;
@@ -566,6 +653,9 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *filter, instance.wCollectionNumber = node->parent; instance.dwDimension = 0; instance.wExponent = 0; + len = swprintf( instance.tszName, MAX_PATH, L"Collection %u - ", DIDFT_GETINSTANCE( instance.dwType ) ); + if ((tmp = object_usage_to_string( &instance ))) lstrcpynW( instance.tszName + len, tmp, MAX_PATH - len ); + else swprintf( instance.tszName + len, MAX_PATH - len, L"Unknown %u", DIDFT_GETINSTANCE( instance.dwType ) ); ret = enum_object( impl, filter, flags, callback, NULL, &instance, data ); if (ret != DIENUM_CONTINUE) return ret; } diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 9ec9d147dd1..a460357af0c 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -3323,6 +3323,7 @@ struct check_objects_todos BOOL type; BOOL guid; BOOL usage; + BOOL name; };
struct check_objects_params @@ -3363,7 +3364,7 @@ static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *ar todo_wine_if( todo->type ) check_member( *obj, *exp, "%#x", dwType ); check_member( *obj, *exp, "%#x", dwFlags ); - if (!localized) todo_wine check_member_wstr( *obj, *exp, tszName ); + if (!localized) todo_wine_if( todo->name )check_member_wstr( *obj, *exp, tszName ); check_member( *obj, *exp, "%u", dwFFMaxForce ); check_member( *obj, *exp, "%u", dwFFForceResolution ); check_member( *obj, *exp, "%u", wCollectionNumber ); @@ -4146,7 +4147,7 @@ static void test_simple_joystick(void) check_member( objinst, expect_objects[4], "%#x", dwOfs ); check_member( objinst, expect_objects[4], "%#x", dwType ); check_member( objinst, expect_objects[4], "%#x", dwFlags ); - if (!localized) todo_wine check_member_wstr( objinst, expect_objects[4], tszName ); + if (!localized) check_member_wstr( objinst, expect_objects[4], tszName ); check_member( objinst, expect_objects[4], "%u", dwFFMaxForce ); check_member( objinst, expect_objects[4], "%u", dwFFForceResolution ); check_member( objinst, expect_objects[4], "%u", wCollectionNumber ); @@ -4173,7 +4174,7 @@ static void test_simple_joystick(void) check_member( objinst, expect_objects[8], "%#x", dwOfs ); check_member( objinst, expect_objects[8], "%#x", dwType ); check_member( objinst, expect_objects[8], "%#x", 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], "%u", dwFFMaxForce ); check_member( objinst, expect_objects[8], "%u", dwFFForceResolution ); check_member( objinst, expect_objects[8], "%u", wCollectionNumber ); @@ -4231,7 +4232,7 @@ static void test_simple_joystick(void) check_member( objinst, expect_objects[3], "%#x", dwOfs ); check_member( objinst, expect_objects[3], "%#x", dwType ); check_member( objinst, expect_objects[3], "%#x", dwFlags ); - if (!localized) todo_wine check_member_wstr( objinst, expect_objects[3], tszName ); + if (!localized) check_member_wstr( objinst, expect_objects[3], tszName ); check_member( objinst, expect_objects[3], "%u", dwFFMaxForce ); check_member( objinst, expect_objects[3], "%u", dwFFForceResolution ); check_member( objinst, expect_objects[3], "%u", wCollectionNumber ); @@ -7475,9 +7476,9 @@ static void test_force_feedback_joystick( DWORD version )
struct check_objects_todos todo_objects_5[ARRAY_SIZE(expect_objects_5)] = { - {.guid = TRUE, .type = TRUE, .usage = TRUE}, + {.guid = TRUE, .type = TRUE, .usage = TRUE, .name = TRUE}, {0}, - {.guid = TRUE, .type = TRUE, .usage = TRUE}, + {.guid = TRUE, .type = TRUE, .usage = TRUE, .name = TRUE}, }; struct check_objects_params check_objects_params = {
Signed-off-by: Ivo Ivanov logos128@gmail.com Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 16 +++++++++++++--- dlls/dinput/device_private.h | 2 ++ dlls/dinput8/tests/hid.c | 6 +++++- 3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index c58ffc7ac73..8d65d051a3b 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -974,9 +974,13 @@ static HRESULT WINAPI dinput_device_GetProperty( IDirectInputDevice8W *iface, co return impl->vtbl->get_property( iface, LOWORD( guid ), header, &instance );
case (DWORD_PTR)DIPROP_AUTOCENTER: + { + DIPROPDWORD *value = (DIPROPDWORD *)header; if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; - return DIERR_UNSUPPORTED; - + if (!(impl->caps.dwFlags & DIDC_FORCEFEEDBACK)) return DIERR_UNSUPPORTED; + value->dwData = impl->autocenter; + return DI_OK; + } case (DWORD_PTR)DIPROP_BUFFERSIZE: { DIPROPDWORD *value = (DIPROPDWORD *)header; @@ -1076,11 +1080,17 @@ static HRESULT WINAPI dinput_device_SetProperty( IDirectInputDevice8W *iface, co { const DIPROPDWORD *value = (const DIPROPDWORD *)header; if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; + if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED; EnterCriticalSection( &impl->crit ); if (impl->acquired) hr = DIERR_ACQUIRED; else if (value->dwData > DIPROPAUTOCENTER_ON) hr = DIERR_INVALIDPARAM; else if (!(impl->caps.dwFlags & DIDC_FORCEFEEDBACK)) hr = DIERR_UNSUPPORTED; - else hr = DI_OK; + else + { + FIXME( "DIPROP_AUTOCENTER stub!\n" ); + impl->autocenter = value->dwData; + hr = DI_OK; + } LeaveCriticalSection( &impl->crit ); return hr; } diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index e77d0190a48..02befc6e869 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -96,6 +96,8 @@ struct dinput_device
BYTE device_state_report_id; BYTE device_state[DEVICE_STATE_MAX_SIZE]; + + BOOL autocenter; };
extern HRESULT dinput_device_alloc( SIZE_T size, const struct dinput_device_vtbl *vtbl, const GUID *guid, diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index a460357af0c..d553fa92ef7 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -7616,9 +7616,13 @@ static void test_force_feedback_joystick( DWORD version ) hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE ); ok( hr == DI_OK, "SetCooperativeLevel returned: %#x\n", hr );
+ prop_dword.diph.dwHow = DIPH_BYUSAGE; + prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + prop_dword.dwData = DIPROPAUTOCENTER_ON; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_AUTOCENTER, &prop_dword.diph ); + ok( hr == DIERR_UNSUPPORTED, "SetProperty DIPROP_AUTOCENTER returned %#x\n", hr ); prop_dword.diph.dwHow = DIPH_DEVICE; prop_dword.diph.dwObj = 0; - prop_dword.dwData = DIPROPAUTOCENTER_ON; hr = IDirectInputDevice8_SetProperty( device, DIPROP_AUTOCENTER, &prop_dword.diph ); ok( hr == DI_OK, "SetProperty DIPROP_AUTOCENTER returned %#x\n", hr );
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/hid.c | 111 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index d553fa92ef7..3c8492842e4 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -3453,6 +3453,13 @@ static BOOL CALLBACK check_created_effect_objects( IDirectInputEffect *effect, v return DIENUM_CONTINUE; }
+static BOOL CALLBACK enum_device_count( const DIDEVICEINSTANCEW *devinst, void *context ) +{ + DWORD *count = context; + *count = *count + 1; + return DIENUM_CONTINUE; +} + static HRESULT create_dinput_device( DWORD version, DIDEVICEINSTANCEW *devinst, IDirectInputDevice8W **device ) { DIPROPDWORD prop_dword = @@ -3466,8 +3473,8 @@ static HRESULT create_dinput_device( DWORD version, DIDEVICEINSTANCEW *devinst, }; IDirectInput8W *di8; IDirectInputW *di; + ULONG ref, count; HRESULT hr; - ULONG ref;
if (version >= 0x800) { @@ -3488,6 +3495,57 @@ static HRESULT create_dinput_device( DWORD version, DIDEVICEINSTANCEW *devinst, return DIERR_DEVICENOTREG; }
+ hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_ALL, NULL, NULL, DIEDFL_ALLDEVICES ); + ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#x\n", hr ); + hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_ALL, enum_device_count, &count, 0xdeadbeef ); + ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#x\n", hr ); + hr = IDirectInput8_EnumDevices( di8, 0xdeadbeef, enum_device_count, &count, DIEDFL_ALLDEVICES ); + ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#x\n", hr ); + + count = 0; + hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_ALL, enum_device_count, &count, DIEDFL_ALLDEVICES ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + ok( count == 3, "got count %u, expected 0\n", count ); + count = 0; + hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_DEVICE, enum_device_count, &count, DIEDFL_ALLDEVICES ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + ok( count == 0, "got count %u, expected 0\n", count ); + count = 0; + hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_POINTER, enum_device_count, &count, + DIEDFL_INCLUDEALIASES | DIEDFL_INCLUDEPHANTOMS | DIEDFL_INCLUDEHIDDEN ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + todo_wine + ok( count == 3, "got count %u, expected 3\n", count ); + count = 0; + hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_KEYBOARD, enum_device_count, &count, + DIEDFL_INCLUDEALIASES | DIEDFL_INCLUDEPHANTOMS | DIEDFL_INCLUDEHIDDEN ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + todo_wine + ok( count == 3, "got count %u, expected 3\n", count ); + count = 0; + hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_GAMECTRL, enum_device_count, &count, + DIEDFL_INCLUDEALIASES | DIEDFL_INCLUDEPHANTOMS | DIEDFL_INCLUDEHIDDEN ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + ok( count == 1, "got count %u, expected 1\n", count ); + + count = 0; + hr = IDirectInput8_EnumDevices( di8, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_ALLDEVICES ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + todo_wine + ok( count == 1, "got count %u, expected 1\n", count ); + + count = 0; + hr = IDirectInput8_EnumDevices( di8, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_FORCEFEEDBACK ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + if (IsEqualGUID( &devinst->guidFFDriver, &GUID_NULL )) ok( count == 0, "got count %u, expected 0\n", count ); + else todo_wine ok( count == 1, "got count %u, expected 1\n", count ); + + count = 0; + hr = IDirectInput8_EnumDevices( di8, (devinst->dwDevType & 0xff) + 1, enum_device_count, &count, DIEDFL_ALLDEVICES ); + if ((devinst->dwDevType & 0xff) != DI8DEVTYPE_SUPPLEMENTAL) ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + else ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#x\n", hr ); + ok( count == 0, "got count %u, expected 0\n", count ); + hr = IDirectInput8_CreateDevice( di8, &devinst->guidInstance, NULL, NULL ); ok( hr == E_POINTER, "CreateDevice returned %#x\n", hr ); hr = IDirectInput8_CreateDevice( di8, NULL, device, NULL ); @@ -3535,6 +3593,57 @@ static HRESULT create_dinput_device( DWORD version, DIDEVICEINSTANCEW *devinst, return DIERR_DEVICENOTREG; }
+ hr = IDirectInput_EnumDevices( di, 0, NULL, NULL, DIEDFL_ALLDEVICES ); + ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#x\n", hr ); + hr = IDirectInput_EnumDevices( di, 0, enum_device_count, &count, 0xdeadbeef ); + ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#x\n", hr ); + hr = IDirectInput_EnumDevices( di, 0xdeadbeef, enum_device_count, &count, DIEDFL_ALLDEVICES ); + ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#x\n", hr ); + hr = IDirectInput_EnumDevices( di, 0, enum_device_count, &count, DIEDFL_INCLUDEHIDDEN ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#x\n", hr ); + + count = 0; + hr = IDirectInput_EnumDevices( di, 0, enum_device_count, &count, DIEDFL_ALLDEVICES ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + ok( count == 3, "got count %u, expected 0\n", count ); + count = 0; + hr = IDirectInput_EnumDevices( di, DIDEVTYPE_DEVICE, enum_device_count, &count, DIEDFL_ALLDEVICES ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + ok( count == 0, "got count %u, expected 0\n", count ); + count = 0; + hr = IDirectInput_EnumDevices( di, DIDEVTYPE_MOUSE, enum_device_count, &count, + DIEDFL_INCLUDEALIASES | DIEDFL_INCLUDEPHANTOMS ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + todo_wine + ok( count == 3, "got count %u, expected 3\n", count ); + count = 0; + hr = IDirectInput_EnumDevices( di, DIDEVTYPE_KEYBOARD, enum_device_count, &count, + DIEDFL_INCLUDEALIASES | DIEDFL_INCLUDEPHANTOMS ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + todo_wine + ok( count == 3, "got count %u, expected 3\n", count ); + count = 0; + hr = IDirectInput_EnumDevices( di, DIDEVTYPE_JOYSTICK, enum_device_count, &count, + DIEDFL_INCLUDEALIASES | DIEDFL_INCLUDEPHANTOMS ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + ok( count == 1, "got count %u, expected 1\n", count ); + + count = 0; + hr = IDirectInput_EnumDevices( di, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_ALLDEVICES ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + ok( count == 1, "got count %u, expected 1\n", count ); + + count = 0; + hr = IDirectInput_EnumDevices( di, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_FORCEFEEDBACK ); + ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); + if (IsEqualGUID( &devinst->guidFFDriver, &GUID_NULL )) todo_wine ok( count == 0, "got count %u, expected 0\n", count ); + else ok( count == 1, "got count %u, expected 1\n", count ); + + hr = IDirectInput_EnumDevices( di, 0x14, enum_device_count, &count, DIEDFL_ALLDEVICES ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#x\n", hr ); + hr = IDirectInput_CreateDevice( di, &expect_guid_product, (IDirectInputDeviceW **)device, NULL ); ok( hr == DI_OK, "CreateDevice returned %#x\n", hr );
Instead of the other way around.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/dinput_main.c | 66 ++++++++++++++++++++++----------------- dlls/dinput8/tests/hid.c | 2 -- 2 files changed, 37 insertions(+), 31 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 835a8656bd1..f53a1b502e9 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -315,39 +315,17 @@ __ASM_GLOBAL_FUNC( enum_callback_wrapper, static HRESULT WINAPI IDirectInputWImpl_EnumDevices( IDirectInput7W *iface, DWORD type, LPDIENUMDEVICESCALLBACKW callback, void *context, DWORD flags ) { - DIDEVICEINSTANCEW instance = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; IDirectInputImpl *impl = impl_from_IDirectInput7W( iface ); - unsigned int i = 0; - HRESULT hr;
TRACE( "iface %p, type %#x, callback %p, context %p, flags %#x\n", iface, type, callback, context, flags );
if (!callback) return DIERR_INVALIDPARAM;
- if ((type > DI8DEVCLASS_GAMECTRL && type < DI8DEVTYPE_DEVICE) || type > DI8DEVTYPE_SUPPLEMENTAL) - return DIERR_INVALIDPARAM; - if (flags & ~(DIEDFL_ATTACHEDONLY|DIEDFL_FORCEFEEDBACK|DIEDFL_INCLUDEALIASES|DIEDFL_INCLUDEPHANTOMS|DIEDFL_INCLUDEHIDDEN)) + if (type > DIDEVTYPE_JOYSTICK) return DIERR_INVALIDPARAM; + if (flags & ~(DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK | DIEDFL_INCLUDEALIASES | DIEDFL_INCLUDEPHANTOMS)) return DIERR_INVALIDPARAM;
- if (!impl->initialized) - return DIERR_NOTINITIALIZED; - - hr = mouse_enum_device( type, flags, &instance, impl->dwVersion, 0 ); - if (hr == DI_OK && enum_callback_wrapper( callback, &instance, context ) == DIENUM_STOP) - return DI_OK; - hr = keyboard_enum_device( type, flags, &instance, impl->dwVersion, 0 ); - if (hr == DI_OK && enum_callback_wrapper( callback, &instance, context ) == DIENUM_STOP) - return DI_OK; - - do - { - hr = hid_joystick_enum_device( type, flags, &instance, impl->dwVersion, i++ ); - if (hr == DI_OK && enum_callback_wrapper( callback, &instance, context ) == DIENUM_STOP) - return DI_OK; - } - while (SUCCEEDED(hr)); - - return DI_OK; + return IDirectInput8_EnumDevices( &impl->IDirectInput8W_iface, type, callback, context, flags ); }
static ULONG WINAPI IDirectInputWImpl_AddRef( IDirectInput7W *iface ) @@ -659,11 +637,41 @@ static HRESULT WINAPI IDirectInput8WImpl_CreateDevice(LPDIRECTINPUT8W iface, REF return IDirectInput7_CreateDeviceEx( &This->IDirectInput7W_iface, rguid, &IID_IDirectInputDevice8W, (LPVOID *)pdev, punk ); }
-static HRESULT WINAPI IDirectInput8WImpl_EnumDevices(LPDIRECTINPUT8W iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback, - LPVOID pvRef, DWORD dwFlags) +static HRESULT WINAPI IDirectInput8WImpl_EnumDevices( IDirectInput8W *iface, DWORD type, LPDIENUMDEVICESCALLBACKW callback, + void *context, DWORD flags ) { - IDirectInputImpl *This = impl_from_IDirectInput8W( iface ); - return IDirectInput_EnumDevices( &This->IDirectInput7W_iface, dwDevType, lpCallback, pvRef, dwFlags ); + DIDEVICEINSTANCEW instance = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; + IDirectInputImpl *impl = impl_from_IDirectInput8W( iface ); + unsigned int i = 0; + HRESULT hr; + + TRACE( "iface %p, type %#x, callback %p, context %p, flags %#x\n", iface, type, callback, context, flags ); + + if (!callback) return DIERR_INVALIDPARAM; + + if ((type > DI8DEVCLASS_GAMECTRL && type < DI8DEVTYPE_DEVICE) || type > DI8DEVTYPE_SUPPLEMENTAL) + return DIERR_INVALIDPARAM; + if (flags & ~(DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK | DIEDFL_INCLUDEALIASES | + DIEDFL_INCLUDEPHANTOMS | DIEDFL_INCLUDEHIDDEN)) + return DIERR_INVALIDPARAM; + + if (!impl->initialized) return DIERR_NOTINITIALIZED; + + hr = mouse_enum_device( type, flags, &instance, impl->dwVersion, 0 ); + if (hr == DI_OK && enum_callback_wrapper( callback, &instance, context ) == DIENUM_STOP) + return DI_OK; + hr = keyboard_enum_device( type, flags, &instance, impl->dwVersion, 0 ); + if (hr == DI_OK && enum_callback_wrapper( callback, &instance, context ) == DIENUM_STOP) + return DI_OK; + + do + { + hr = hid_joystick_enum_device( type, flags, &instance, impl->dwVersion, i++ ); + if (hr == DI_OK && enum_callback_wrapper( callback, &instance, context ) == DIENUM_STOP) + return DI_OK; + } while (SUCCEEDED(hr)); + + return DI_OK; }
static HRESULT WINAPI IDirectInput8WImpl_GetDeviceStatus(LPDIRECTINPUT8W iface, REFGUID rguid) diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 3c8492842e4..73f8ea33650 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -3600,7 +3600,6 @@ static HRESULT create_dinput_device( DWORD version, DIDEVICEINSTANCEW *devinst, hr = IDirectInput_EnumDevices( di, 0xdeadbeef, enum_device_count, &count, DIEDFL_ALLDEVICES ); ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#x\n", hr ); hr = IDirectInput_EnumDevices( di, 0, enum_device_count, &count, DIEDFL_INCLUDEHIDDEN ); - todo_wine ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#x\n", hr );
count = 0; @@ -3641,7 +3640,6 @@ static HRESULT create_dinput_device( DWORD version, DIDEVICEINSTANCEW *devinst, else ok( count == 1, "got count %u, expected 1\n", count );
hr = IDirectInput_EnumDevices( di, 0x14, enum_device_count, &count, DIEDFL_ALLDEVICES ); - todo_wine ok( hr == DIERR_INVALIDPARAM, "EnumDevices returned: %#x\n", hr );
hr = IDirectInput_CreateDevice( di, &expect_guid_product, (IDirectInputDeviceW **)device, NULL );
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/dinput_main.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index f53a1b502e9..f2526f25972 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -926,12 +926,24 @@ static HRESULT WINAPI JoyConfig8Impl_DeleteType(IDirectInputJoyConfig8 *iface, L return E_NOTIMPL; }
+struct find_device_from_index_params +{ + UINT index; + DIDEVICEINSTANCEW instance; +}; + +static BOOL CALLBACK find_device_from_index( const DIDEVICEINSTANCEW *instance, void *context ) +{ + struct find_device_from_index_params *params = context; + params->instance = *instance; + if (!params->index--) return DIENUM_STOP; + return DIENUM_CONTINUE; +} + static HRESULT WINAPI JoyConfig8Impl_GetConfig(IDirectInputJoyConfig8 *iface, UINT id, LPDIJOYCONFIG info, DWORD flags) { - DIDEVICEINSTANCEW instance = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; IDirectInputImpl *di = impl_from_IDirectInputJoyConfig8(iface); - unsigned int i = 0; - UINT found = 0; + struct find_device_from_index_params params = {.index = id}; HRESULT hr;
FIXME("(%p)->(%d, %p, 0x%08x): semi-stub!\n", iface, id, info, flags); @@ -943,16 +955,11 @@ static HRESULT WINAPI JoyConfig8Impl_GetConfig(IDirectInputJoyConfig8 *iface, UI X(DIJC_CALLOUT) #undef X
- do - { - hr = hid_joystick_enum_device( DI8DEVCLASS_GAMECTRL, 0, &instance, di->dwVersion, i++ ); - if (hr != DI_OK) continue; - if (flags & DIJC_GUIDINSTANCE) info->guidInstance = instance.guidInstance; - /* Only take into account the chosen id */ - if (found++ == id) return DI_OK; - } while (SUCCEEDED(hr)); - - return DIERR_NOMOREITEMS; + hr = IDirectInput8_EnumDevices( &di->IDirectInput8W_iface, DI8DEVCLASS_GAMECTRL, find_device_from_index, ¶ms, 0 ); + if (FAILED(hr)) return hr; + if (params.index != ~0) return DIERR_NOMOREITEMS; + if (flags & DIJC_GUIDINSTANCE) info->guidInstance = params.instance.guidInstance; + return DI_OK; }
static HRESULT WINAPI JoyConfig8Impl_SetConfig(IDirectInputJoyConfig8 *iface, UINT id, LPCDIJOYCONFIG info, DWORD flags)
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/dinput_main.c | 58 ++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 19 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index f2526f25972..4a6bca7d77f 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -751,42 +751,62 @@ static BOOL should_enumerate_device(const WCHAR *username, DWORD dwFlags, return should_enumerate; }
+struct enum_device_by_semantics_params +{ + IDirectInput8W *iface; + const WCHAR *username; + DWORD flags; + + DIDEVICEINSTANCEW *instances; + DWORD instance_count; +}; + +static BOOL CALLBACK enum_device_by_semantics( const DIDEVICEINSTANCEW *instance, void *context ) +{ + struct enum_device_by_semantics_params *params = context; + IDirectInputImpl *This = impl_from_IDirectInput8W( params->iface ); + + if (should_enumerate_device( params->username, params->flags, &This->device_players, &instance->guidInstance )) + { + params->instance_count++; + params->instances = realloc( params->instances, sizeof(DIDEVICEINSTANCEW) * params->instance_count ); + params->instances[params->instance_count - 1] = *instance; + } + + return DIENUM_CONTINUE; +} + static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics( LPDIRECTINPUT8W iface, LPCWSTR ptszUserName, LPDIACTIONFORMATW lpdiActionFormat, LPDIENUMDEVICESBYSEMANTICSCBW lpCallback, LPVOID pvRef, DWORD dwFlags ) { + struct enum_device_by_semantics_params params = {.iface = iface, .username = ptszUserName, .flags = dwFlags}; + DWORD callbackFlags, enum_flags = DIEDFL_ATTACHEDONLY | (dwFlags & DIEDFL_FORCEFEEDBACK); static REFGUID guids[2] = { &GUID_SysKeyboard, &GUID_SysMouse }; static const DWORD actionMasks[] = { DIKEYBOARD_MASK, DIMOUSE_MASK }; IDirectInputImpl *This = impl_from_IDirectInput8W(iface); DIDEVICEINSTANCEW didevi; LPDIRECTINPUTDEVICE8W lpdid; - DWORD callbackFlags; unsigned int i = 0; HRESULT hr; - int device_count = 0; int remain; - DIDEVICEINSTANCEW *didevis = 0;
FIXME("(this=%p,%s,%p,%p,%p,%04x): semi-stub\n", This, debugstr_w(ptszUserName), lpdiActionFormat, lpCallback, pvRef, dwFlags);
didevi.dwSize = sizeof(didevi);
- do + hr = IDirectInput8_EnumDevices( &This->IDirectInput8W_iface, DI8DEVCLASS_GAMECTRL, + enum_device_by_semantics, ¶ms, enum_flags ); + if (FAILED(hr)) { - hr = hid_joystick_enum_device( DI8DEVCLASS_GAMECTRL, DIEDFL_ATTACHEDONLY | dwFlags, &didevi, This->dwVersion, i++ ); - if (hr != DI_OK) continue; - if (should_enumerate_device( ptszUserName, dwFlags, &This->device_players, &didevi.guidInstance )) - { - device_count++; - didevis = realloc( didevis, sizeof(DIDEVICEINSTANCEW) * device_count ); - didevis[device_count - 1] = didevi; - } - } while (SUCCEEDED(hr)); + free( params.instances ); + return hr; + }
- remain = device_count; + remain = params.instance_count; /* Add keyboard and mouse to remaining device count */ if (!(dwFlags & DIEDBSFL_FORCEFEEDBACK)) { @@ -797,21 +817,21 @@ static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics( } }
- for (i = 0; i < device_count; i++) + for (i = 0; i < params.instance_count; i++) { callbackFlags = diactionformat_priorityW(lpdiActionFormat, lpdiActionFormat->dwGenre); - IDirectInput_CreateDevice(iface, &didevis[i].guidInstance, &lpdid, NULL); + IDirectInput_CreateDevice( iface, ¶ms.instances[i].guidInstance, &lpdid, NULL );
- if (lpCallback(&didevis[i], lpdid, callbackFlags, --remain, pvRef) == DIENUM_STOP) + if (lpCallback( ¶ms.instances[i], lpdid, callbackFlags, --remain, pvRef ) == DIENUM_STOP) { - free( didevis ); + free( params.instances ); IDirectInputDevice_Release(lpdid); return DI_OK; } IDirectInputDevice_Release(lpdid); }
- free( didevis ); + free( params.instances );
if (dwFlags & DIEDBSFL_FORCEFEEDBACK) return DI_OK;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/dinput_main.c | 43 +++++++++++++++++++++++++++--------- dlls/dinput/dinput_private.h | 4 ++-- dlls/dinput/joystick_hid.c | 7 ------ dlls/dinput/keyboard.c | 16 +++----------- dlls/dinput/mouse.c | 16 +++----------- dlls/dinput8/tests/hid.c | 5 ++--- 6 files changed, 43 insertions(+), 48 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 4a6bca7d77f..55d566afa4a 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -637,11 +637,21 @@ static HRESULT WINAPI IDirectInput8WImpl_CreateDevice(LPDIRECTINPUT8W iface, REF return IDirectInput7_CreateDeviceEx( &This->IDirectInput7W_iface, rguid, &IID_IDirectInputDevice8W, (LPVOID *)pdev, punk ); }
+static BOOL try_enum_device( DWORD type, LPDIENUMDEVICESCALLBACKW callback, + DIDEVICEINSTANCEW *instance, void *context, DWORD flags ) +{ + if (type && (instance->dwDevType & 0xff) != type) return DIENUM_CONTINUE; + if ((flags & DIEDFL_FORCEFEEDBACK) && IsEqualGUID( &instance->guidFFDriver, &GUID_NULL )) + return DIENUM_CONTINUE; + return enum_callback_wrapper( callback, instance, context ); +} + static HRESULT WINAPI IDirectInput8WImpl_EnumDevices( IDirectInput8W *iface, DWORD type, LPDIENUMDEVICESCALLBACKW callback, void *context, DWORD flags ) { DIDEVICEINSTANCEW instance = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; IDirectInputImpl *impl = impl_from_IDirectInput8W( iface ); + DWORD device_class = 0, device_type = 0; unsigned int i = 0; HRESULT hr;
@@ -657,19 +667,32 @@ static HRESULT WINAPI IDirectInput8WImpl_EnumDevices( IDirectInput8W *iface, DWO
if (!impl->initialized) return DIERR_NOTINITIALIZED;
- hr = mouse_enum_device( type, flags, &instance, impl->dwVersion, 0 ); - if (hr == DI_OK && enum_callback_wrapper( callback, &instance, context ) == DIENUM_STOP) - return DI_OK; - hr = keyboard_enum_device( type, flags, &instance, impl->dwVersion, 0 ); - if (hr == DI_OK && enum_callback_wrapper( callback, &instance, context ) == DIENUM_STOP) - return DI_OK; + if (type <= DI8DEVCLASS_GAMECTRL) device_class = type; + else device_type = type;
- do + if (device_class == DI8DEVCLASS_ALL || device_class == DI8DEVCLASS_POINTER) { - hr = hid_joystick_enum_device( type, flags, &instance, impl->dwVersion, i++ ); - if (hr == DI_OK && enum_callback_wrapper( callback, &instance, context ) == DIENUM_STOP) + hr = mouse_enum_device( type, flags, &instance, impl->dwVersion ); + if (hr == DI_OK && try_enum_device( device_type, callback, &instance, context, flags ) == DIENUM_STOP) return DI_OK; - } while (SUCCEEDED(hr)); + } + + if (device_class == DI8DEVCLASS_ALL || device_class == DI8DEVCLASS_KEYBOARD) + { + hr = keyboard_enum_device( type, flags, &instance, impl->dwVersion ); + if (hr == DI_OK && try_enum_device( device_type, callback, &instance, context, flags ) == DIENUM_STOP) + return DI_OK; + } + + if (device_class == DI8DEVCLASS_ALL || device_class == DI8DEVCLASS_GAMECTRL) + { + do + { + hr = hid_joystick_enum_device( type, flags, &instance, impl->dwVersion, i++ ); + if (hr == DI_OK && try_enum_device( device_type, callback, &instance, context, flags ) == DIENUM_STOP) + return DI_OK; + } while (SUCCEEDED(hr)); + }
return DI_OK; } diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h index a9777dc8dbb..c25fe6320ca 100644 --- a/dlls/dinput/dinput_private.h +++ b/dlls/dinput/dinput_private.h @@ -52,9 +52,9 @@ struct IDirectInputImpl extern const IDirectInput7AVtbl dinput7_a_vtbl DECLSPEC_HIDDEN; extern const IDirectInput8AVtbl dinput8_a_vtbl DECLSPEC_HIDDEN;
-extern HRESULT mouse_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version, int index ); +extern HRESULT mouse_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version ); extern HRESULT mouse_create_device( IDirectInputImpl *dinput, const GUID *guid, IDirectInputDevice8W **out ); -extern HRESULT keyboard_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version, int index ); +extern HRESULT keyboard_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version ); extern HRESULT keyboard_create_device( IDirectInputImpl *dinput, const GUID *guid, IDirectInputDevice8W **out ); extern HRESULT hid_joystick_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version, int index ); extern HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID *guid, IDirectInputDevice8W **out ); diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 17b79a0f716..4af7da6654d 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -1510,13 +1510,6 @@ HRESULT hid_joystick_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *in HidD_FreePreparsedData( preparsed ); CloseHandle( device );
- if (instance->dwSize != sizeof(DIDEVICEINSTANCEW)) - return S_FALSE; - if (version < 0x0800 && type != 0 && type != DIDEVTYPE_JOYSTICK) - return S_FALSE; - if (version >= 0x0800 && type != DI8DEVCLASS_ALL && type != DI8DEVCLASS_GAMECTRL) - return S_FALSE; - TRACE( "found device %s, usage %04x:%04x, product %s, instance %s, name %s\n", debugstr_w(device_path), instance->wUsagePage, instance->wUsage, debugstr_guid( &instance->guidProduct ), debugstr_guid( &instance->guidInstance ), debugstr_w(instance->tszInstanceName) ); diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index ef125176ecb..f906e32a59d 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -144,22 +144,12 @@ static DWORD get_keyboard_subtype(void) return dev_subtype; }
-HRESULT keyboard_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version, int index ) +HRESULT keyboard_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version ) { BYTE subtype = get_keyboard_subtype(); DWORD size;
- TRACE( "type %#x, flags %#x, instance %p, version %#04x, index %d\n", type, flags, instance, version, index ); - - if (index != 0) return DIERR_GENERIC; - if (flags & DIEDFL_FORCEFEEDBACK) return DI_NOEFFECT; - if (version < 0x0800 && type != 0 && type != DIDEVTYPE_KEYBOARD) return DI_NOEFFECT; - if (version >= 0x0800 && type != DI8DEVCLASS_ALL && type != DI8DEVCLASS_KEYBOARD && type != DI8DEVTYPE_KEYBOARD) - return DI_NOEFFECT; - - if (instance->dwSize != sizeof(DIDEVICEINSTANCEW) && - instance->dwSize != sizeof(DIDEVICEINSTANCE_DX3W)) - return DIERR_INVALIDPARAM; + TRACE( "type %#x, flags %#x, instance %p, version %#04x\n", type, flags, instance, version );
size = instance->dwSize; memset( instance, 0, size ); @@ -188,7 +178,7 @@ HRESULT keyboard_create_device( IDirectInputImpl *dinput, const GUID *guid, IDir return hr; impl->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": struct keyboard*->base.crit");
- keyboard_enum_device( 0, 0, &impl->base.instance, dinput->dwVersion, 0 ); + keyboard_enum_device( 0, 0, &impl->base.instance, dinput->dwVersion ); impl->base.caps.dwDevType = impl->base.instance.dwDevType; impl->base.caps.dwFirmwareRevision = 100; impl->base.caps.dwHardwareRevision = 100; diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index 628011c13e1..1b45c8d5fd4 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -72,21 +72,11 @@ static inline struct mouse *impl_from_IDirectInputDevice8W( IDirectInputDevice8W return CONTAINING_RECORD( CONTAINING_RECORD( iface, struct dinput_device, IDirectInputDevice8W_iface ), struct mouse, base ); }
-HRESULT mouse_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version, int index ) +HRESULT mouse_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version ) { DWORD size;
- TRACE( "type %#x, flags %#x, instance %p, version %#04x, index %d\n", type, flags, instance, version, index ); - - if (index != 0) return DIERR_GENERIC; - if (flags & DIEDFL_FORCEFEEDBACK) return DI_NOEFFECT; - if (version < 0x0800 && type != 0 && type != DIDEVTYPE_MOUSE) return DI_NOEFFECT; - if (version >= 0x0800 && type != DI8DEVCLASS_ALL && type != DI8DEVCLASS_POINTER && type != DI8DEVTYPE_MOUSE) - return DI_NOEFFECT; - - if (instance->dwSize != sizeof(DIDEVICEINSTANCEW) && - instance->dwSize != sizeof(DIDEVICEINSTANCE_DX3W)) - return DIERR_INVALIDPARAM; + TRACE( "type %#x, flags %#x, instance %p, version %#04x\n", type, flags, instance, version );
size = instance->dwSize; memset( instance, 0, size ); @@ -117,7 +107,7 @@ HRESULT mouse_create_device( IDirectInputImpl *dinput, const GUID *guid, IDirect return hr; impl->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": struct mouse*->base.crit");
- mouse_enum_device( 0, 0, &impl->base.instance, dinput->dwVersion, 0 ); + mouse_enum_device( 0, 0, &impl->base.instance, dinput->dwVersion ); impl->base.caps.dwDevType = impl->base.instance.dwDevType; impl->base.caps.dwFirmwareRevision = 100; impl->base.caps.dwHardwareRevision = 100; diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 73f8ea33650..38bdfb7455e 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -3531,14 +3531,13 @@ static HRESULT create_dinput_device( DWORD version, DIDEVICEINSTANCEW *devinst, count = 0; hr = IDirectInput8_EnumDevices( di8, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_ALLDEVICES ); ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); - todo_wine ok( count == 1, "got count %u, expected 1\n", count );
count = 0; hr = IDirectInput8_EnumDevices( di8, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_FORCEFEEDBACK ); ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); if (IsEqualGUID( &devinst->guidFFDriver, &GUID_NULL )) ok( count == 0, "got count %u, expected 0\n", count ); - else todo_wine ok( count == 1, "got count %u, expected 1\n", count ); + else ok( count == 1, "got count %u, expected 1\n", count );
count = 0; hr = IDirectInput8_EnumDevices( di8, (devinst->dwDevType & 0xff) + 1, enum_device_count, &count, DIEDFL_ALLDEVICES ); @@ -3636,7 +3635,7 @@ static HRESULT create_dinput_device( DWORD version, DIDEVICEINSTANCEW *devinst, count = 0; hr = IDirectInput_EnumDevices( di, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_FORCEFEEDBACK ); ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr ); - if (IsEqualGUID( &devinst->guidFFDriver, &GUID_NULL )) todo_wine ok( count == 0, "got count %u, expected 0\n", count ); + if (IsEqualGUID( &devinst->guidFFDriver, &GUID_NULL )) ok( count == 0, "got count %u, expected 0\n", count ); else ok( count == 1, "got count %u, expected 1\n", count );
hr = IDirectInput_EnumDevices( di, 0x14, enum_device_count, &count, DIEDFL_ALLDEVICES );
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=101970
Your paranoid android.
=== w8 (32 bit report) ===
dinput8: hid.c:4813: Test failed: state[0]: WaitForSingleObject succeeded