Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/tests/Makefile.in | 2 +- dlls/dinput/tests/hotplug.c | 244 ++++++++++++++++++++++++++++++++++ 2 files changed, 245 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput/tests/Makefile.in b/dlls/dinput/tests/Makefile.in index 5ba0e5be4d7..d32092ca03b 100644 --- a/dlls/dinput/tests/Makefile.in +++ b/dlls/dinput/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = dinput.dll -IMPORTS = dinput dinput8 ole32 version user32 advapi32 hid uuid crypt32 newdev setupapi wintrust winmm +IMPORTS = dinput dinput8 ole32 version user32 advapi32 hid uuid crypt32 newdev setupapi wintrust winmm combase
driver_hid_IMPORTS = winecrt0 ntoskrnl hal hidclass driver_hid_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native diff --git a/dlls/dinput/tests/hotplug.c b/dlls/dinput/tests/hotplug.c index 39f80774012..49cc5423807 100644 --- a/dlls/dinput/tests/hotplug.c +++ b/dlls/dinput/tests/hotplug.c @@ -32,11 +32,21 @@ #include "dinputd.h" #include "devguid.h" #include "dbt.h" +#include "unknwn.h" +#include "winstring.h"
#include "wine/hid.h"
#include "dinput_test.h"
+#include "initguid.h" +#include "roapi.h" +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Gaming_Input +#include "windows.gaming.input.h" + static BOOL test_input_lost( DWORD version ) { #include "psh_hid_macros.h" @@ -322,6 +332,7 @@ static void test_RegisterDeviceNotification(void)
while (device_change_count < device_change_expect) { + MsgWaitForMultipleObjects( 0, NULL, FALSE, INFINITE, QS_ALLINPUT ); while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE )) { TranslateMessage( &msg ); @@ -355,6 +366,7 @@ static void test_RegisterDeviceNotification(void)
while (device_change_count < device_change_expect) { + MsgWaitForMultipleObjects( 0, NULL, FALSE, INFINITE, QS_ALLINPUT ); while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE )) { TranslateMessage( &msg ); @@ -385,6 +397,7 @@ static void test_RegisterDeviceNotification(void)
while (device_change_count < device_change_expect) { + MsgWaitForMultipleObjects( 0, NULL, FALSE, INFINITE, QS_ALLINPUT ); while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE )) { TranslateMessage( &msg ); @@ -404,6 +417,236 @@ static void test_RegisterDeviceNotification(void) UnregisterClassW( class.lpszClassName, class.hInstance ); }
+struct controller_handler +{ + IEventHandler_RawGameController IEventHandler_RawGameController_iface; + BOOL invoked; +}; + +static inline struct controller_handler *impl_from_IEventHandler_RawGameController( IEventHandler_RawGameController *iface ) +{ + return CONTAINING_RECORD( iface, struct controller_handler, IEventHandler_RawGameController_iface ); +} + +static HRESULT WINAPI controller_handler_QueryInterface( IEventHandler_RawGameController *iface, REFIID iid, void **out ) +{ + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IAgileObject ) || + IsEqualGUID( iid, &IID_IEventHandler_RawGameController )) + { + IUnknown_AddRef( iface ); + *out = iface; + return S_OK; + } + + trace( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI controller_handler_AddRef( IEventHandler_RawGameController *iface ) +{ + return 2; +} + +static ULONG WINAPI controller_handler_Release( IEventHandler_RawGameController *iface ) +{ + return 1; +} + +static HRESULT WINAPI controller_handler_Invoke( IEventHandler_RawGameController *iface, + IInspectable *sender, IRawGameController *controller ) +{ + struct controller_handler *impl = impl_from_IEventHandler_RawGameController( iface ); + + trace( "iface %p, sender %p, controller %p\n", iface, sender, controller ); + + ok( sender == NULL, "got sender %p\n", sender ); + impl->invoked = TRUE; + + return S_OK; +} + +static const IEventHandler_RawGameControllerVtbl controller_handler_vtbl = +{ + controller_handler_QueryInterface, + controller_handler_AddRef, + controller_handler_Release, + controller_handler_Invoke, +}; + +static struct controller_handler controller_removed = {{&controller_handler_vtbl}}; +static struct controller_handler controller_added = {{&controller_handler_vtbl}}; + +static LRESULT CALLBACK windows_gaming_input_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + if (msg == WM_DEVICECHANGE) + { + winetest_push_context( "%u", device_change_count ); + if (device_change_count++ >= device_change_expect / 2) + { + ok( wparam == DBT_DEVICEREMOVECOMPLETE, "got wparam %#Ix\n", wparam ); + ok( controller_added.invoked, "controller added handler not invoked\n" ); + ok( controller_removed.invoked, "controller removed handler not invoked\n" ); + } + else + { + ok( wparam == DBT_DEVICEARRIVAL, "got wparam %#Ix\n", wparam ); + ok( !controller_added.invoked, "controller added handler not invoked\n" ); + ok( !controller_removed.invoked, "controller removed handler invoked\n" ); + } + winetest_pop_context(); + } + + return DefWindowProcW( hwnd, msg, wparam, lparam ); +} + +static void test_windows_gaming_input(void) +{ + static const WCHAR *class_name = RuntimeClass_Windows_Gaming_Input_RawGameController; + DEV_BROADCAST_DEVICEINTERFACE_A iface_filter_a = + { + .dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE_A), + .dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE, + .dbcc_classguid = GUID_DEVINTERFACE_HID, + }; + WNDCLASSEXW class = + { + .cbSize = sizeof(WNDCLASSEXW), + .hInstance = GetModuleHandleW( NULL ), + .lpszClassName = L"devnotify", + .lpfnWndProc = windows_gaming_input_wndproc, + }; + EventRegistrationToken controller_removed_token; + IVectorView_RawGameController *controller_view; + EventRegistrationToken controller_added_token; + IRawGameControllerStatics *statics; + HANDLE hwnd, thread, stop_event; + HDEVNOTIFY devnotify; + BOOL removed; + HSTRING str; + UINT32 size; + HRESULT hr; + MSG msg; + + hr = RoInitialize( RO_INIT_MULTITHREADED ); + ok( hr == RPC_E_CHANGED_MODE, "RoInitialize failed, hr %#lx\n", hr ); + + hr = WindowsCreateString( class_name, wcslen( class_name ), &str ); + ok( hr == S_OK, "WindowsCreateString failed, hr %#lx\n", hr ); + + hr = RoGetActivationFactory( str, &IID_IRawGameControllerStatics, (void **)&statics ); + ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "RoGetActivationFactory failed, hr %#lx\n", hr ); + WindowsDeleteString( str ); + + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( class_name ) ); + RoUninitialize(); + return; + } + + hr = IRawGameControllerStatics_add_RawGameControllerAdded( statics, &controller_added.IEventHandler_RawGameController_iface, + &controller_added_token ); + ok( hr == S_OK, "add_RawGameControllerAdded returned %#lx\n", hr ); + todo_wine + ok( controller_added_token.value, "got token %I64u\n", controller_added_token.value ); + if (!controller_added_token.value) goto done; + + hr = IRawGameControllerStatics_add_RawGameControllerRemoved( statics, &controller_removed.IEventHandler_RawGameController_iface, + &controller_removed_token ); + ok( hr == S_OK, "add_RawGameControllerAdded returned %#lx\n", hr ); + + hr = IRawGameControllerStatics_get_RawGameControllers( statics, &controller_view ); + ok( hr == S_OK, "get_RawGameControllers returned %#lx\n", hr ); + + RegisterClassExW( &class ); + + hwnd = CreateWindowW( class.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL ); + ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() ); + + devnotify = RegisterDeviceNotificationA( hwnd, &iface_filter_a, DEVICE_NOTIFY_WINDOW_HANDLE ); + ok( !!devnotify, "RegisterDeviceNotificationA failed, error %lu\n", GetLastError() ); + while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); + + device_change_count = 0; + device_change_expect = 2; + device_change_hwnd = hwnd; + device_change_all = FALSE; + stop_event = CreateEventW( NULL, FALSE, FALSE, NULL ); + ok( !!stop_event, "CreateEventW failed, error %lu\n", GetLastError() ); + thread = CreateThread( NULL, 0, dinput_test_device_thread, stop_event, 0, NULL ); + ok( !!thread, "CreateThread failed, error %lu\n", GetLastError() ); + + removed = FALSE; + while (device_change_count < device_change_expect) + { + MsgWaitForMultipleObjects( 0, NULL, FALSE, 50, QS_ALLINPUT ); + while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE )) + { + TranslateMessage( &msg ); + ok( msg.message != WM_DEVICECHANGE, "got WM_DEVICECHANGE\n" ); + DispatchMessageW( &msg ); + } + if (controller_added.invoked && !removed) + { + ok( !controller_removed.invoked, "controller removed handler invoked\n" ); + removed = TRUE; + + hr = IVectorView_RawGameController_get_Size( controller_view, &size ); + ok( hr == S_OK, "get_Size returned %#lx\n", hr ); + ok( size == 0, "got size %u\n", size ); + + IVectorView_RawGameController_Release( controller_view ); + hr = IRawGameControllerStatics_get_RawGameControllers( statics, &controller_view ); + ok( hr == S_OK, "get_RawGameControllers returned %#lx\n", hr ); + + hr = IVectorView_RawGameController_get_Size( controller_view, &size ); + ok( hr == S_OK, "get_Size returned %#lx\n", hr ); + ok( size == 1, "got size %u\n", size ); + + SetEvent( stop_event ); + } + } + + ok( controller_added.invoked, "controller added handler not invoked\n" ); + ok( controller_removed.invoked, "controller removed handler not invoked\n" ); + + hr = IVectorView_RawGameController_get_Size( controller_view, &size ); + ok( hr == S_OK, "get_Size returned %#lx\n", hr ); + ok( size == 1, "got size %u\n", size ); + + IVectorView_RawGameController_Release( controller_view ); + hr = IRawGameControllerStatics_get_RawGameControllers( statics, &controller_view ); + ok( hr == S_OK, "get_RawGameControllers returned %#lx\n", hr ); + + hr = IVectorView_RawGameController_get_Size( controller_view, &size ); + ok( hr == S_OK, "get_Size returned %#lx\n", hr ); + ok( size == 0, "got size %u\n", size ); + + hr = IRawGameControllerStatics_remove_RawGameControllerAdded( statics, controller_added_token ); + ok( hr == S_OK, "remove_RawGameControllerAdded returned %#lx\n", hr ); + hr = IRawGameControllerStatics_remove_RawGameControllerRemoved( statics, controller_removed_token ); + ok( hr == S_OK, "remove_RawGameControllerRemoved returned %#lx\n", hr ); + hr = IRawGameControllerStatics_remove_RawGameControllerRemoved( statics, controller_removed_token ); + ok( hr == S_OK, "remove_RawGameControllerRemoved returned %#lx\n", hr ); + + IVectorView_RawGameController_Release( controller_view ); + IRawGameControllerStatics_Release( statics ); + + WaitForSingleObject( thread, INFINITE ); + CloseHandle( thread ); + CloseHandle( stop_event ); + + UnregisterDeviceNotification( devnotify ); + + DestroyWindow( hwnd ); + UnregisterClassW( class.lpszClassName, class.hInstance ); + +done: + RoUninitialize(); +} + START_TEST( hotplug ) { if (!dinput_test_init()) return; @@ -415,6 +658,7 @@ START_TEST( hotplug ) test_input_lost( 0x800 );
test_RegisterDeviceNotification(); + test_windows_gaming_input(); } CoUninitialize();
Only works with an XBox gamepad, looks like DInput gamepads aren't exposed as WGI gamepads.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/tests/joystick8.c | 170 ++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+)
diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 9c700c00971..959f91aae78 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -31,11 +31,21 @@ #include "dinputd.h" #include "devguid.h" #include "mmsystem.h" +#include "roapi.h" +#include "unknwn.h" +#include "winstring.h"
#include "wine/hid.h"
#include "dinput_test.h"
+#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Devices_Haptics +#define WIDL_using_Windows_Gaming_Input +#include "windows.gaming.input.h" + struct check_objects_todos { BOOL type; @@ -3181,6 +3191,165 @@ done: return device != NULL; }
+#define check_interface( a, b, c ) check_interface_( __LINE__, a, b, c ) +static void check_interface_( unsigned int line, void *iface_ptr, REFIID iid, BOOL supported ) +{ + IUnknown *iface = iface_ptr; + HRESULT hr, expected; + IUnknown *unk; + + expected = supported ? S_OK : E_NOINTERFACE; + hr = IUnknown_QueryInterface( iface, iid, (void **)&unk ); + ok_ (__FILE__, line)( hr == expected, "got hr %#lx, expected %#lx.\n", hr, expected ); + if (SUCCEEDED(hr)) IUnknown_Release( unk ); +} + +#define check_runtimeclass( a, b ) check_runtimeclass_( __LINE__, (IInspectable *)a, b ) +static void check_runtimeclass_( int line, IInspectable *inspectable, const WCHAR *class_name ) +{ + const WCHAR *buffer; + UINT32 length; + HSTRING str; + HRESULT hr; + + hr = IInspectable_GetRuntimeClassName( inspectable, &str ); + ok_ (__FILE__, line)( hr == S_OK, "GetRuntimeClassName returned %#lx\n", hr ); + buffer = WindowsGetStringRawBuffer( str, &length ); + ok_ (__FILE__, line)( !wcscmp( buffer, class_name ), "got class name %s\n", debugstr_w(buffer) ); + WindowsDeleteString( str ); +} + +static void test_windows_gaming_input(void) +{ +#include "psh_hid_macros.h" + const unsigned char report_desc[] = { + USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), + USAGE(1, HID_USAGE_GENERIC_GAMEPAD), + COLLECTION(1, Application), + USAGE(1, HID_USAGE_GENERIC_GAMEPAD), + COLLECTION(1, Physical), + USAGE(1, HID_USAGE_GENERIC_X), + USAGE(1, HID_USAGE_GENERIC_Y), + USAGE(1, HID_USAGE_GENERIC_RX), + USAGE(1, HID_USAGE_GENERIC_RY), + USAGE(1, HID_USAGE_GENERIC_Z), + USAGE(1, HID_USAGE_GENERIC_RZ), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 127), + PHYSICAL_MINIMUM(1, 0), + PHYSICAL_MAXIMUM(1, 127), + REPORT_SIZE(1, 8), + REPORT_COUNT(1, 6), + INPUT(1, Data|Var|Abs), + + USAGE(1, HID_USAGE_GENERIC_HATSWITCH), + LOGICAL_MINIMUM(1, 1), + LOGICAL_MAXIMUM(1, 8), + PHYSICAL_MINIMUM(1, 0), + PHYSICAL_MAXIMUM(1, 8), + REPORT_SIZE(1, 4), + REPORT_COUNT(1, 1), + INPUT(1, Data|Var|Abs|Null), + + USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON), + USAGE_MINIMUM(1, 1), + USAGE_MAXIMUM(1, 12), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 1), + PHYSICAL_MINIMUM(1, 0), + PHYSICAL_MAXIMUM(1, 1), + REPORT_SIZE(1, 1), + REPORT_COUNT(1, 12), + INPUT(1, Data|Var|Abs), + END_COLLECTION, + END_COLLECTION, + }; +#include "pop_hid_macros.h" + + static const HIDP_CAPS hid_caps = + { + .InputReportByteLength = 8, + }; + static const WCHAR *controller_class_name = RuntimeClass_Windows_Gaming_Input_RawGameController; + + IVectorView_RawGameController *controllers_view; + IRawGameControllerStatics *controller_statics; + WCHAR cwd[MAX_PATH], tempdir[MAX_PATH]; + IRawGameController *raw_controller; + UINT32 size; + HSTRING str; + HRESULT hr; + + GetCurrentDirectoryW( ARRAY_SIZE(cwd), cwd ); + GetTempPathW( ARRAY_SIZE(tempdir), tempdir ); + SetCurrentDirectoryW( tempdir ); + + cleanup_registry_keys(); + + hr = RoInitialize( RO_INIT_MULTITHREADED ); + ok( hr == RPC_E_CHANGED_MODE, "RoInitialize returned %#lx\n", hr ); + + hr = WindowsCreateString( controller_class_name, wcslen( controller_class_name ), &str ); + ok( hr == S_OK, "WindowsCreateString returned %#lx\n", hr ); + hr = RoGetActivationFactory( str, &IID_IRawGameControllerStatics, (void **)&controller_statics ); + ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "RoGetActivationFactory returned %#lx\n", hr ); + WindowsDeleteString( str ); + + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( controller_class_name ) ); + goto done; + } + + hr = IRawGameControllerStatics_get_RawGameControllers( controller_statics, &controllers_view ); + ok( hr == S_OK, "get_RawGameControllers returned %#lx\n", hr ); + hr = IVectorView_RawGameController_get_Size( controllers_view, &size ); + ok( hr == S_OK, "get_Size returned %#lx\n", hr ); + ok( size == 0, "got size %u\n", size ); + + if (!dinput_driver_start( report_desc, sizeof(report_desc), &hid_caps, NULL, 0 )) goto done; + + hr = IVectorView_RawGameController_get_Size( controllers_view, &size ); + ok( hr == S_OK, "get_Size returned %#lx\n", hr ); + ok( size == 0, "got size %u\n", size ); + IVectorView_RawGameController_Release( controllers_view ); + + hr = IRawGameControllerStatics_get_RawGameControllers( controller_statics, &controllers_view ); + ok( hr == S_OK, "get_RawGameControllers returned %#lx\n", hr ); + hr = IVectorView_RawGameController_get_Size( controllers_view, &size ); + ok( hr == S_OK, "get_Size returned %#lx\n", hr ); + todo_wine + ok( size == 1, "got size %u\n", size ); + hr = IVectorView_RawGameController_GetAt( controllers_view, 0, &raw_controller ); + todo_wine + ok( hr == S_OK, "GetAt returned %#lx\n", hr ); + IVectorView_RawGameController_Release( controllers_view ); + if (hr != S_OK) + { + IRawGameControllerStatics_Release( controller_statics ); + goto done; + } + + check_runtimeclass( raw_controller, RuntimeClass_Windows_Gaming_Input_RawGameController ); + check_interface( raw_controller, &IID_IUnknown, TRUE ); + check_interface( raw_controller, &IID_IInspectable, TRUE ); + check_interface( raw_controller, &IID_IAgileObject, TRUE ); + check_interface( raw_controller, &IID_IRawGameController, TRUE ); + check_interface( raw_controller, &IID_IRawGameController2, TRUE ); + check_interface( raw_controller, &IID_IGameController, TRUE ); + check_interface( raw_controller, &IID_IGamepad, FALSE ); + + IRawGameController_Release( raw_controller ); + IRawGameControllerStatics_Release( controller_statics ); + +done: + pnp_driver_stop(); + cleanup_registry_keys(); + SetCurrentDirectoryW( cwd ); + + RoUninitialize(); +} + START_TEST( joystick8 ) { if (!dinput_test_init()) return; @@ -3200,6 +3369,7 @@ START_TEST( joystick8 ) test_simple_joystick( 0x800 );
test_driving_wheel_axes(); + test_windows_gaming_input(); } CoUninitialize();
And check the RawGameController IGameController interface.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/tests/joystick8.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 959f91aae78..d98faf7d3ee 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -3272,10 +3272,11 @@ static void test_windows_gaming_input(void) }; static const WCHAR *controller_class_name = RuntimeClass_Windows_Gaming_Input_RawGameController;
+ IRawGameController *raw_controller, *tmp_raw_controller; IVectorView_RawGameController *controllers_view; IRawGameControllerStatics *controller_statics; WCHAR cwd[MAX_PATH], tempdir[MAX_PATH]; - IRawGameController *raw_controller; + IGameController *game_controller; UINT32 size; HSTRING str; HRESULT hr; @@ -3339,7 +3340,26 @@ static void test_windows_gaming_input(void) check_interface( raw_controller, &IID_IGameController, TRUE ); check_interface( raw_controller, &IID_IGamepad, FALSE );
+ hr = IRawGameController_QueryInterface( raw_controller, &IID_IGameController, (void **)&game_controller ); + ok( hr == S_OK, "QueryInterface returned %#lx\n", hr ); + + check_runtimeclass( game_controller, RuntimeClass_Windows_Gaming_Input_RawGameController ); + check_interface( game_controller, &IID_IUnknown, TRUE ); + check_interface( game_controller, &IID_IInspectable, TRUE ); + check_interface( game_controller, &IID_IAgileObject, TRUE ); + check_interface( game_controller, &IID_IRawGameController, TRUE ); + check_interface( game_controller, &IID_IRawGameController2, TRUE ); + check_interface( game_controller, &IID_IGameController, TRUE ); + check_interface( game_controller, &IID_IGamepad, FALSE ); + + hr = IRawGameControllerStatics_FromGameController( controller_statics, game_controller, &tmp_raw_controller ); + ok( hr == S_OK, "FromGameController returned %#lx\n", hr ); + ok( tmp_raw_controller == raw_controller, "got unexpected IGameController interface\n" ); + IRawGameController_Release( tmp_raw_controller ); + + IGameController_Release( game_controller ); IRawGameController_Release( raw_controller ); + IRawGameControllerStatics_Release( controller_statics );
done:
Showing that HID gamepads aren't listed as WGI gamepads.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/tests/joystick8.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index d98faf7d3ee..f01bed08030 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -3271,11 +3271,14 @@ static void test_windows_gaming_input(void) .InputReportByteLength = 8, }; static const WCHAR *controller_class_name = RuntimeClass_Windows_Gaming_Input_RawGameController; + static const WCHAR *gamepad_class_name = RuntimeClass_Windows_Gaming_Input_Gamepad;
IRawGameController *raw_controller, *tmp_raw_controller; IVectorView_RawGameController *controllers_view; IRawGameControllerStatics *controller_statics; WCHAR cwd[MAX_PATH], tempdir[MAX_PATH]; + IVectorView_Gamepad *gamepads_view; + IGamepadStatics *gamepad_statics; IGameController *game_controller; UINT32 size; HSTRING str; @@ -3331,6 +3334,21 @@ static void test_windows_gaming_input(void) goto done; }
+ /* HID gamepads aren't exposed as WGI gamepads on Windows */ + + hr = WindowsCreateString( gamepad_class_name, wcslen( gamepad_class_name ), &str ); + ok( hr == S_OK, "WindowsCreateString returned %#lx\n", hr ); + hr = RoGetActivationFactory( str, &IID_IGamepadStatics, (void **)&gamepad_statics ); + ok( hr == S_OK, "RoGetActivationFactory returned %#lx\n", hr ); + WindowsDeleteString( str ); + hr = IGamepadStatics_get_Gamepads( gamepad_statics, &gamepads_view ); + ok( hr == S_OK, "get_Gamepads returned %#lx\n", hr ); + hr = IVectorView_Gamepad_get_Size( gamepads_view, &size ); + ok( hr == S_OK, "get_Size returned %#lx\n", hr ); + ok( size == 0, "got size %u\n", size ); + IVectorView_Gamepad_Release( gamepads_view ); + IGamepadStatics_Release( gamepad_statics ); + check_runtimeclass( raw_controller, RuntimeClass_Windows_Gaming_Input_RawGameController ); check_interface( raw_controller, &IID_IUnknown, TRUE ); check_interface( raw_controller, &IID_IInspectable, TRUE );
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/tests/joystick8.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index f01bed08030..ddc88ff56fe 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -3273,14 +3273,17 @@ static void test_windows_gaming_input(void) static const WCHAR *controller_class_name = RuntimeClass_Windows_Gaming_Input_RawGameController; static const WCHAR *gamepad_class_name = RuntimeClass_Windows_Gaming_Input_Gamepad;
+ IVectorView_SimpleHapticsController *haptics_controllers; IRawGameController *raw_controller, *tmp_raw_controller; IVectorView_RawGameController *controllers_view; IRawGameControllerStatics *controller_statics; WCHAR cwd[MAX_PATH], tempdir[MAX_PATH]; + IRawGameController2 *raw_controller2; IVectorView_Gamepad *gamepads_view; IGamepadStatics *gamepad_statics; IGameController *game_controller; - UINT32 size; + UINT32 size, length; + const WCHAR *buffer; HSTRING str; HRESULT hr;
@@ -3376,6 +3379,33 @@ static void test_windows_gaming_input(void) IRawGameController_Release( tmp_raw_controller );
IGameController_Release( game_controller ); + + hr = IRawGameController_QueryInterface( raw_controller, &IID_IRawGameController2, (void **)&raw_controller2 ); + ok( hr == S_OK, "QueryInterface returned %#lx\n", hr ); + + hr = IRawGameController2_get_DisplayName( raw_controller2, &str ); + ok( hr == S_OK, "get_DisplayName returned %#lx\n", hr ); + buffer = WindowsGetStringRawBuffer( str, &length ); + ok( !wcscmp( buffer, L"Xbox 360 Controller for Windows" ), + "get_DisplayName returned %s\n", debugstr_wn(buffer, length) ); + WindowsDeleteString( str ); + + hr = IRawGameController2_get_NonRoamableId( raw_controller2, &str ); + ok( hr == S_OK, "get_NonRoamableId returned %#lx\n", hr ); + buffer = WindowsGetStringRawBuffer( str, &length ); + ok( !wcscmp( buffer, L"{wgi/nrid/GmVbh^-FUL-nQOi-FgZbDiP-0Q8R1k-9ocj5N-}" ), + "get_NonRoamableId returned %s\n", debugstr_wn(buffer, length) ); + WindowsDeleteString( str ); + + hr = IRawGameController2_get_SimpleHapticsControllers( raw_controller2, &haptics_controllers ); + ok( hr == S_OK, "get_SimpleHapticsControllers returned %#lx\n", hr ); + hr = IVectorView_SimpleHapticsController_get_Size( haptics_controllers, &length ); + ok( hr == S_OK, "get_Size returned %#lx\n", hr ); + ok( length == 0, "got length %u\n", length ); + IVectorView_SimpleHapticsController_Release( haptics_controllers ); + + IRawGameController2_Release( raw_controller2 ); + IRawGameController_Release( raw_controller );
IRawGameControllerStatics_Release( controller_statics );
Please ignore this last patch, it's obviously wrong.
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=109115
Your paranoid android.
=== w1064_tsign (64 bit report) ===
dinput: joystick8.c:3389: Test failed: get_DisplayName returned L"HID-compliant game controller" joystick8.c:3396: Test failed: get_NonRoamableId returned L"{wgi/nrid/j_BR;U6o-laJ7^G_-KOl_-Zd`-MagL-F3F^-GE}\0000"
On Wed, 23 Feb 2022, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/dinput/tests/Makefile.in | 2 +- dlls/dinput/tests/hotplug.c | 244 ++++++++++++++++++++++++++++++++++ 2 files changed, 245 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput/tests/Makefile.in b/dlls/dinput/tests/Makefile.in index 5ba0e5be4d7..d32092ca03b 100644 --- a/dlls/dinput/tests/Makefile.in +++ b/dlls/dinput/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = dinput.dll -IMPORTS = dinput dinput8 ole32 version user32 advapi32 hid uuid crypt32 newdev setupapi wintrust winmm +IMPORTS = dinput dinput8 ole32 version user32 advapi32 hid uuid crypt32 newdev setupapi wintrust winmm combase
Linking with combase.dll prevents the dinput tests from running on Windows 7:
https://testbot.winehq.org/JobDetails.pl?Key=109252&f202=exe32.report#k2... https://test.winehq.org/data/patterns.html#dinput:dinput
Before that they may have been skipping some tests on Windows 7 but it appears they were still running quite a few:
0798:device: 7517168 tests executed (0 marked as todo, 0 failures), 1 skipped. 0b34:device8: 1915 tests executed (0 marked as todo, 0 failures), 1 skipped. 0070:dinput: 2375 tests executed (0 marked as todo, 0 failures), 1 skipped. ...
On 2/25/22 15:32, Francois Gouget wrote:
On Wed, 23 Feb 2022, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/dinput/tests/Makefile.in | 2 +- dlls/dinput/tests/hotplug.c | 244 ++++++++++++++++++++++++++++++++++ 2 files changed, 245 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput/tests/Makefile.in b/dlls/dinput/tests/Makefile.in index 5ba0e5be4d7..d32092ca03b 100644 --- a/dlls/dinput/tests/Makefile.in +++ b/dlls/dinput/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = dinput.dll -IMPORTS = dinput dinput8 ole32 version user32 advapi32 hid uuid crypt32 newdev setupapi wintrust winmm +IMPORTS = dinput dinput8 ole32 version user32 advapi32 hid uuid crypt32 newdev setupapi wintrust winmm combase
Linking with combase.dll prevents the dinput tests from running on Windows 7:
https://testbot.winehq.org/JobDetails.pl?Key=109252&f202=exe32.report#k2... https://test.winehq.org/data/patterns.html#dinput:dinput
Before that they may have been skipping some tests on Windows 7 but it appears they were still running quite a few:
0798:device: 7517168 tests executed (0 marked as todo, 0 failures), 1 skipped. 0b34:device8: 1915 tests executed (0 marked as todo, 0 failures), 1 skipped. 0070:dinput: 2375 tests executed (0 marked as todo, 0 failures), 1 skipped. ...
Ah, thanks for spotting this, I'll make the dependency optional.