-- v2: dinput/tests: Add a test with a virtual HID touch screen. include: Add more HID digitizer usage definitions. dinput/tests: Add a test with a virtual HID keyboard. dinput/tests: Add a test with a virtual HID mouse. dinput/tests: Enforce ordering of concurrent read IRPs. dinput/tests: Introduce a new helper to create a foreground window.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/tests/device8.c | 65 ++++++++++++++++++++---------- dlls/dinput/tests/dinput_test.h | 3 ++ dlls/dinput/tests/force_feedback.c | 6 +-- dlls/dinput/tests/joystick8.c | 18 ++------- 4 files changed, 51 insertions(+), 41 deletions(-)
diff --git a/dlls/dinput/tests/device8.c b/dlls/dinput/tests/device8.c index 3a702b8f2fe..7423d6c6ae7 100644 --- a/dlls/dinput/tests/device8.c +++ b/dlls/dinput/tests/device8.c @@ -66,6 +66,41 @@ static void flush_events(void) } }
+HWND create_foreground_window_( const char *file, int line, BOOL fullscreen, UINT retries ) +{ + for (;;) + { + HWND hwnd; + BOOL ret; + + hwnd = CreateWindowW( L"static", NULL, WS_POPUP | (fullscreen ? 0 : WS_VISIBLE), + 100, 100, 200, 200, NULL, NULL, NULL, NULL ); + ok_(file, line)( hwnd != NULL, "CreateWindowW failed, error %lu\n", GetLastError() ); + + if (fullscreen) + { + HMONITOR hmonitor = MonitorFromWindow( hwnd, MONITOR_DEFAULTTOPRIMARY ); + MONITORINFO mi = {.cbSize = sizeof(MONITORINFO)}; + + ok_(file, line)( hmonitor != NULL, "MonitorFromWindow failed, error %lu\n", GetLastError() ); + ret = GetMonitorInfoW( hmonitor, &mi ); + ok_(file, line)( ret, "GetMonitorInfoW failed, error %lu\n", GetLastError() ); + ret = SetWindowPos( hwnd, 0, mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right - mi.rcMonitor.left, + mi.rcMonitor.bottom - mi.rcMonitor.top, SWP_FRAMECHANGED | SWP_SHOWWINDOW ); + ok_(file, line)( ret, "SetWindowPos failed, error %lu\n", GetLastError() ); + } + flush_events(); + + if (GetForegroundWindow() == hwnd) return hwnd; + ok_(file, line)( retries > 0, "failed to create foreground window\n" ); + if (!retries--) return hwnd; + + ret = DestroyWindow( hwnd ); + ok_(file, line)( ret, "DestroyWindow failed, error %lu\n", GetLastError() ); + flush_events(); + } +} + static HRESULT create_dinput_device( DWORD version, const GUID *guid, IDirectInputDevice8W **device ) { IDirectInputW *dinput; @@ -294,8 +329,7 @@ void test_overlapped_format( DWORD version )
event = CreateEventW( NULL, FALSE, FALSE, NULL ); ok( !!event, "CreateEventW failed, error %lu\n", GetLastError() ); - hwnd = CreateWindowW( L"static", L"Title", WS_POPUP | WS_VISIBLE, 10, 10, 200, 200, NULL, NULL, NULL, NULL ); - ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() ); + hwnd = create_foreground_window( FALSE );
hr = IDirectInput_CreateDevice( dinput, &GUID_SysKeyboard, &keyboard, NULL ); ok( hr == DI_OK, "CreateDevice returned %#lx\n", hr ); @@ -556,10 +590,6 @@ static void test_mouse_keyboard(void) UINT raw_devices_count; RAWINPUTDEVICE raw_devices[3];
- hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput", WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL); - ok(hwnd != NULL, "CreateWindowExA failed\n"); - flush_events(); - hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&di); if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION || @@ -578,6 +608,8 @@ static void test_mouse_keyboard(void) } ok(SUCCEEDED(hr), "IDirectInput8_Initialize failed: %#lx\n", hr);
+ hwnd = create_foreground_window( TRUE ); + hr = IDirectInput8_CreateDevice(di, &GUID_SysMouse, &di_mouse, NULL); ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %#lx\n", hr); hr = IDirectInputDevice8_SetDataFormat(di_mouse, &c_dfDIMouse); @@ -771,8 +803,7 @@ static void test_keyboard_events(void) } ok(SUCCEEDED(hr), "IDirectInput8_Initialize failed: %#lx\n", hr);
- hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput", WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL); - ok(hwnd != NULL, "CreateWindowExA failed\n"); + hwnd = create_foreground_window( FALSE );
hr = IDirectInput8_CreateDevice(di, &GUID_SysKeyboard, &di_keyboard, NULL); ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %#lx\n", hr); @@ -872,9 +903,7 @@ static void test_appdata_property(void) ok(SUCCEEDED(hr), "DirectInput8 Initialize failed: hr=%#lx\n", hr); if (FAILED(hr)) return;
- hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput", - WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL); - ok(hwnd != NULL, "failed to create window\n"); + hwnd = create_foreground_window( TRUE );
hr = IDirectInput8_CreateDevice(pDI, &GUID_SysKeyboard, &di_keyboard, NULL); ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %#lx\n", hr); @@ -1412,11 +1441,7 @@ static void test_sys_mouse( DWORD version ) check_member( objinst, expect_objects[3], "%u", wReportId );
- SetCursorPos( 60, 60 ); - - hwnd = CreateWindowW( L"static", L"static", WS_POPUP | WS_VISIBLE, - 50, 50, 200, 200, NULL, NULL, NULL, NULL ); - ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() ); + hwnd = create_foreground_window( TRUE );
hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_FOREGROUND ); ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr ); @@ -1571,9 +1596,7 @@ static void test_sys_mouse( DWORD version ) ok( hr == DI_OK, "Unacquire returned %#lx\n", hr ); }
- tmp_hwnd = CreateWindowW( L"static", L"static", WS_POPUP | WS_VISIBLE, - 50, 250, 200, 200, NULL, NULL, NULL, NULL ); - ok( !!tmp_hwnd, "CreateWindowW failed, error %lu\n", GetLastError() ); + tmp_hwnd = create_foreground_window( FALSE );
hr = IDirectInputDevice8_GetDeviceState( device, sizeof(state), &state ); ok( hr == DIERR_NOTACQUIRED, "GetDeviceState returned %#lx\n", hr ); @@ -2126,9 +2149,7 @@ static void test_sys_keyboard( DWORD version ) check_member( objinst, expect_objects[2], "%u", wReportId );
- hwnd = CreateWindowW( L"static", L"static", WS_POPUP | WS_VISIBLE, - 50, 50, 200, 200, NULL, NULL, NULL, NULL ); - ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() ); + hwnd = create_foreground_window( FALSE );
hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_FOREGROUND ); ok( hr == DIERR_INVALIDPARAM, "SetCooperativeLevel returned %#lx\n", hr ); diff --git a/dlls/dinput/tests/dinput_test.h b/dlls/dinput/tests/dinput_test.h index a4a133e6384..b53978bbe97 100644 --- a/dlls/dinput/tests/dinput_test.h +++ b/dlls/dinput/tests/dinput_test.h @@ -109,4 +109,7 @@ void send_hid_input_( const char *file, int line, HANDLE device, struct hid_devi #define msg_wait_for_events( a, b, c ) msg_wait_for_events_( __FILE__, __LINE__, a, b, c ) DWORD msg_wait_for_events_( const char *file, int line, DWORD count, HANDLE *events, DWORD timeout );
+#define create_foreground_window( a ) create_foreground_window_( __FILE__, __LINE__, a, 5 ) +HWND create_foreground_window_( const char *file, int line, BOOL fullscreen, UINT retries ); + #endif /* __WINE_DINPUT_TEST_H */ diff --git a/dlls/dinput/tests/force_feedback.c b/dlls/dinput/tests/force_feedback.c index c20125655f4..bb3578e4590 100644 --- a/dlls/dinput/tests/force_feedback.c +++ b/dlls/dinput/tests/force_feedback.c @@ -3079,8 +3079,7 @@ static BOOL test_force_feedback_joystick( DWORD version ) FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL ); ok( file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError() );
- hwnd = CreateWindowW( L"static", L"dinput", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 10, 10, 200, 200, - NULL, NULL, NULL, NULL ); + hwnd = create_foreground_window( FALSE );
hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE ); ok( hr == DI_OK, "SetCooperativeLevel returned: %#lx\n", hr ); @@ -4131,8 +4130,7 @@ static void test_device_managed_effect(void) FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL ); ok( file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError() );
- hwnd = CreateWindowW( L"static", L"dinput", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 10, 10, 200, 200, - NULL, NULL, NULL, NULL ); + hwnd = create_foreground_window( FALSE );
event = CreateEventW( NULL, FALSE, FALSE, NULL ); ok( event != NULL, "CreateEventW failed, last error %lu\n", GetLastError() ); diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 88d9e4d9ffe..b4cd4a771de 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -2279,8 +2279,7 @@ static void test_simple_joystick( DWORD version ) hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_FOREGROUND | DISCL_EXCLUSIVE ); ok( hr == E_HANDLE, "SetCooperativeLevel returned: %#lx\n", hr );
- hwnd = CreateWindowW( L"static", L"dinput", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 10, 10, 200, 200, - NULL, NULL, NULL, NULL ); + hwnd = create_foreground_window( FALSE );
hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE ); ok( hr == DI_OK, "SetCooperativeLevel returned: %#lx\n", hr ); @@ -5278,13 +5277,6 @@ static void test_rawinput(void) .report_buf = {1,0x10,0x10,0x10,0xee,0x10,0x10,0x10,0x54}, }, }; - WNDCLASSEXW class = - { - .cbSize = sizeof(WNDCLASSEXW), - .hInstance = GetModuleHandleW( NULL ), - .lpszClassName = L"rawinput", - .lpfnWndProc = rawinput_wndproc, - }; RAWINPUT *rawinput = (RAWINPUT *)wm_input_buf; RAWINPUTDEVICELIST raw_device_list[16]; RAWINPUTDEVICE raw_devices[16]; @@ -5295,8 +5287,6 @@ static void test_rawinput(void) HWND hwnd; BOOL ret;
- RegisterClassExW( &class ); - cleanup_registry_keys();
desc.report_descriptor_len = sizeof(report_desc); @@ -5310,9 +5300,8 @@ static void test_rawinput(void) rawinput_event = CreateSemaphoreW( NULL, 0, LONG_MAX, NULL ); ok( !!rawinput_event, "CreateSemaphoreW failed, error %lu\n", GetLastError() );
- hwnd = CreateWindowW( class.lpszClassName, L"dinput", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 10, 10, 200, 200, - NULL, NULL, NULL, NULL ); - ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() ); + hwnd = create_foreground_window( FALSE ); + SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (ULONG_PTR)rawinput_wndproc );
count = ARRAY_SIZE(raw_devices); res = GetRegisteredRawInputDevices( raw_devices, &count, sizeof(RAWINPUTDEVICE) ); @@ -5464,7 +5453,6 @@ done: cleanup_registry_keys();
DestroyWindow( hwnd ); - UnregisterClassW( class.lpszClassName, class.hInstance ); }
START_TEST( joystick8 )
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/tests/driver_bus.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/dlls/dinput/tests/driver_bus.c b/dlls/dinput/tests/driver_bus.c index c0d181c58a5..e0943c35294 100644 --- a/dlls/dinput/tests/driver_bus.c +++ b/dlls/dinput/tests/driver_bus.c @@ -348,13 +348,13 @@ static void irp_queue_push( struct irp_queue *queue, IRP *irp ) KeReleaseSpinLock( &queue->lock, irql ); }
-static void irp_queue_clear( struct irp_queue *queue ) +static void irp_queue_complete( struct irp_queue *queue, BOOL delete ) { IRP *irp;
while ((irp = irp_queue_pop( queue ))) { - irp->IoStatus.Status = STATUS_DELETE_PENDING; + if (delete) irp->IoStatus.Status = STATUS_DELETE_PENDING; IoCompleteRequest( irp, IO_NO_INCREMENT ); } } @@ -373,6 +373,7 @@ struct input_queue struct hid_expect *end; struct hid_expect *buffer; struct irp_queue pending; + struct irp_queue completed; };
static void input_queue_init( struct input_queue *queue, BOOL is_polled ) @@ -384,6 +385,7 @@ static void input_queue_init( struct input_queue *queue, BOOL is_polled ) queue->pos = queue->buffer; queue->end = queue->buffer; irp_queue_init( &queue->pending ); + irp_queue_init( &queue->completed ); }
static void input_queue_cleanup( struct input_queue *queue ) @@ -416,7 +418,11 @@ static NTSTATUS input_queue_read( struct input_queue *queue, IRP *irp ) KIRQL irql;
KeAcquireSpinLock( &queue->lock, &irql ); - if (input_queue_read_locked( queue, irp )) status = STATUS_SUCCESS; + if (input_queue_read_locked( queue, irp )) + { + irp_queue_push( &queue->completed, irp ); + status = STATUS_SUCCESS; + } else { IoMarkIrpPending( irp ); @@ -430,13 +436,10 @@ static NTSTATUS input_queue_read( struct input_queue *queue, IRP *irp )
static void input_queue_reset( struct input_queue *queue, void *in_buf, ULONG in_size ) { - struct irp_queue completed; ULONG remaining; KIRQL irql; IRP *irp;
- irp_queue_init( &completed ); - KeAcquireSpinLock( &queue->lock, &irql ); remaining = queue->end - queue->pos; queue->pos = queue->buffer; @@ -447,13 +450,13 @@ static void input_queue_reset( struct input_queue *queue, void *in_buf, ULONG in while (!queue->is_polled && queue->pos < queue->end && (irp = irp_queue_pop( &queue->pending ))) { input_queue_read_locked( queue, irp ); - irp_queue_push( &completed, irp ); + irp_queue_push( &queue->completed, irp ); } KeReleaseSpinLock( &queue->lock, irql );
if (!queue->is_polled) ok( !remaining, "unread input\n" );
- while ((irp = irp_queue_pop( &completed ))) IoCompleteRequest( irp, IO_NO_INCREMENT ); + irp_queue_complete( &queue->completed, FALSE ); }
struct device @@ -721,7 +724,8 @@ static NTSTATUS pdo_pnp( DEVICE_OBJECT *device, IRP *irp ) state = (code == IRP_MN_START_DEVICE || code == IRP_MN_CANCEL_REMOVE_DEVICE) ? 0 : PNP_DEVICE_REMOVED; KeAcquireSpinLock( &impl->base.lock, &irql ); impl->base.state = state; - irp_queue_clear( &impl->input_queue.pending ); + irp_queue_complete( &impl->input_queue.pending, TRUE ); + irp_queue_complete( &impl->input_queue.completed, TRUE ); KeReleaseSpinLock( &impl->base.lock, irql ); if (code != IRP_MN_REMOVE_DEVICE) status = STATUS_SUCCESS; else @@ -1087,7 +1091,10 @@ static NTSTATUS pdo_internal_ioctl( DEVICE_OBJECT *device, IRP *irp ) ok( !in_size, "got input size %lu\n", in_size ); ok( out_size == expected_size, "got output size %lu\n", out_size ); status = input_queue_read( &impl->input_queue, irp ); - break; + irp_queue_complete( &impl->input_queue.completed, FALSE ); + + winetest_pop_context(); + return status; }
case IOCTL_HID_WRITE_REPORT: @@ -1277,7 +1284,8 @@ static NTSTATUS pdo_handle_ioctl( struct phys_device *impl, IRP *irp, ULONG code case IOCTL_WINETEST_REMOVE_DEVICE: KeAcquireSpinLock( &impl->base.lock, &irql ); impl->base.state = PNP_DEVICE_REMOVED; - irp_queue_clear( &impl->input_queue.pending ); + irp_queue_complete( &impl->input_queue.pending, TRUE ); + irp_queue_complete( &impl->input_queue.completed, TRUE ); KeReleaseSpinLock( &impl->base.lock, irql ); impl->pending_remove = irp; IoMarkIrpPending( irp );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/tests/device8.c | 149 ++++++++++++++++++++++++++++++++ dlls/dinput/tests/dinput_test.h | 4 +- dlls/dinput/tests/hid.c | 6 +- 3 files changed, 155 insertions(+), 4 deletions(-)
diff --git a/dlls/dinput/tests/device8.c b/dlls/dinput/tests/device8.c index 7423d6c6ae7..e3cd75f7c08 100644 --- a/dlls/dinput/tests/device8.c +++ b/dlls/dinput/tests/device8.c @@ -1618,6 +1618,149 @@ cleanup: localized = old_localized; }
+static UINT mouse_move_count; + +static LRESULT CALLBACK mouse_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + if (msg == WM_MOUSEMOVE) + { + ok( wparam == 0, "got wparam %#Ix\n", wparam ); + ok( LOWORD(lparam) - 107 <= 2, "got LOWORD(lparam) %u\n", LOWORD(lparam) ); + ok( HIWORD(lparam) - 107 <= 2, "got HIWORD(lparam) %u\n", HIWORD(lparam) ); + mouse_move_count++; + } + return DefWindowProcA( hwnd, msg, wparam, lparam ); +} + +static void test_hid_mouse(void) +{ +#include "psh_hid_macros.h" + const unsigned char report_desc[] = + { + USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), + USAGE(1, HID_USAGE_GENERIC_MOUSE), + COLLECTION(1, Application), + USAGE(1, HID_USAGE_GENERIC_POINTER), + COLLECTION(1, Physical), + REPORT_ID(1, 1), + + USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON), + USAGE_MINIMUM(1, 1), + USAGE_MAXIMUM(1, 2), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 1), + REPORT_SIZE(1, 1), + REPORT_COUNT(1, 8), + INPUT(1, Data|Var|Abs), + + USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), + USAGE(1, HID_USAGE_GENERIC_X), + USAGE(1, HID_USAGE_GENERIC_Y), + REPORT_SIZE(1, 16), + REPORT_COUNT(1, 2), + LOGICAL_MINIMUM(2, -10), + LOGICAL_MAXIMUM(2, +10), + INPUT(1, Data|Var|Rel), + END_COLLECTION, + END_COLLECTION, + }; + C_ASSERT(sizeof(report_desc) < MAX_HID_DESCRIPTOR_LEN); +#include "pop_hid_macros.h" + + const HID_DEVICE_ATTRIBUTES attributes = + { + .Size = sizeof(HID_DEVICE_ATTRIBUTES), + .VendorID = LOWORD(EXPECT_VIDPID), + .ProductID = 0x0002, + .VersionNumber = 0x0100, + }; + struct hid_device_desc desc = + { + .caps = { .InputReportByteLength = 6 }, + .attributes = attributes, + .use_report_id = 1, + }; + struct hid_expect single_move[] = + { + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1,0x00,0x08,0x00,0x08,0x00}, + }, + }; + + WCHAR device_path[MAX_PATH]; + HANDLE file; + POINT pos; + DWORD res; + HWND hwnd; + BOOL ret; + + winetest_push_context( "mouse "); + + desc.report_descriptor_len = sizeof(report_desc); + memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) ); + + if (!hid_device_start_( &desc, 1, 5000 /* needs a long timeout on Win7 */ )) goto done; + + swprintf( device_path, MAX_PATH, L"\\?\hid#vid_%04x&pid_%04x", desc.attributes.VendorID, + desc.attributes.ProductID ); + ret = find_hid_device_path( device_path ); + ok( ret, "Failed to find HID device matching %s\n", debugstr_w( device_path ) ); + + + /* windows doesn't let us open HID mouse devices */ + + file = CreateFileW( device_path, FILE_READ_ACCESS | FILE_WRITE_ACCESS, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); + todo_wine + ok( file == INVALID_HANDLE_VALUE, "CreateFileW succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError() ); + CloseHandle( file ); + + file = CreateFileW( L"\\?\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, + NULL, OPEN_EXISTING, 0, NULL ); + ok( file != INVALID_HANDLE_VALUE, "CreateFile failed, error %lu\n", GetLastError() ); + + + /* check basic mouse input injection to window message */ + + SetCursorPos( 100, 100 ); + hwnd = create_foreground_window( TRUE ); + SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)mouse_wndproc ); + + GetCursorPos( &pos ); + ok( pos.x == 100, "got x %lu\n", pos.x ); + ok( pos.y == 100, "got y %lu\n", pos.y ); + + mouse_move_count = 0; + bus_send_hid_input( file, &desc, single_move, sizeof(single_move) ); + + res = MsgWaitForMultipleObjects( 0, NULL, FALSE, 500, QS_MOUSEMOVE ); + todo_wine + ok( !res, "MsgWaitForMultipleObjects returned %#lx\n", res ); + msg_wait_for_events( 0, NULL, 5 ); /* process pending messages */ + todo_wine + ok( mouse_move_count == 1, "got mouse_move_count %u\n", mouse_move_count ); + + GetCursorPos( &pos ); + todo_wine + ok( (ULONG)pos.x - 107 <= 2, "got x %lu\n", pos.x ); + todo_wine + ok( (ULONG)pos.y - 107 <= 2, "got y %lu\n", pos.y ); + + DestroyWindow( hwnd ); + + + CloseHandle( file ); + +done: + hid_device_stop( &desc, 1 ); + + winetest_pop_context(); +} + static void test_dik_codes( IDirectInputDevice8W *device, HANDLE event, HWND hwnd, DWORD version ) { static const struct key2dik @@ -2371,5 +2514,11 @@ START_TEST(device8) test_keyboard_events(); test_appdata_property();
+ if (!bus_device_start()) goto done; + + test_hid_mouse(); + +done: + bus_device_stop(); dinput_test_exit(); } diff --git a/dlls/dinput/tests/dinput_test.h b/dlls/dinput/tests/dinput_test.h index b53978bbe97..e13ba2421d2 100644 --- a/dlls/dinput/tests/dinput_test.h +++ b/dlls/dinput/tests/dinput_test.h @@ -51,11 +51,13 @@ extern const WCHAR expect_path_end[]; extern HINSTANCE instance; extern BOOL localized; /* object names get translated */
-BOOL hid_device_start( struct hid_device_desc *desc, UINT count ); +#define hid_device_start( a, b ) hid_device_start_( a, b, 1000 ) +BOOL hid_device_start_( struct hid_device_desc *desc, UINT count, DWORD timeout ); void hid_device_stop( struct hid_device_desc *desc, UINT count ); BOOL bus_device_start(void); void bus_device_stop(void);
+BOOL find_hid_device_path( WCHAR *device_path ); void cleanup_registry_keys(void);
#define dinput_test_init() dinput_test_init_( __FILE__, __LINE__ ) diff --git a/dlls/dinput/tests/hid.c b/dlls/dinput/tests/hid.c index 0a28fda6f99..e5f6ea4640d 100644 --- a/dlls/dinput/tests/hid.c +++ b/dlls/dinput/tests/hid.c @@ -553,7 +553,7 @@ void bus_device_stop(void) ok( ret || GetLastError() == ERROR_FILE_NOT_FOUND, "Failed to delete file, error %lu\n", GetLastError() ); }
-static BOOL find_hid_device_path( WCHAR *device_path ) +BOOL find_hid_device_path( WCHAR *device_path ) { char buffer[FIELD_OFFSET( SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath[MAX_PATH] )] = {0}; SP_DEVICE_INTERFACE_DATA iface = {sizeof(SP_DEVICE_INTERFACE_DATA)}; @@ -735,7 +735,7 @@ void hid_device_stop( struct hid_device_desc *desc, UINT count ) } }
-BOOL hid_device_start( struct hid_device_desc *desc, UINT count ) +BOOL hid_device_start_( struct hid_device_desc *desc, UINT count, DWORD timeout ) { HANDLE control; DWORD ret, i; @@ -754,7 +754,7 @@ BOOL hid_device_start( struct hid_device_desc *desc, UINT count )
for (i = 0; i < count; ++i) { - ret = WaitForSingleObject( device_added, 1000 ); + ret = WaitForSingleObject( device_added, timeout ); todo_wine_if(i > 0) ok( !ret, "WaitForSingleObject returned %#lx\n", ret ); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/tests/device8.c | 148 ++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+)
diff --git a/dlls/dinput/tests/device8.c b/dlls/dinput/tests/device8.c index e3cd75f7c08..594a34222ce 100644 --- a/dlls/dinput/tests/device8.c +++ b/dlls/dinput/tests/device8.c @@ -2488,6 +2488,153 @@ static void test_sys_keyboard_action_format(void) ok( ref == 0, "Release returned %ld\n", ref ); }
+static UINT key_down_count; +static UINT key_up_count; + +static LRESULT CALLBACK keyboard_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + BOOL us_kbd = (GetKeyboardLayout(0) == (HKL)(ULONG_PTR)0x04090409); + + if (msg == WM_KEYDOWN) + { + key_down_count++; + if (us_kbd) ok( wparam == 'A', "got wparam %#Ix\n", wparam ); + ok( lparam == 0x1e0001, "got lparam %#Ix\n", lparam ); + } + if (msg == WM_KEYUP) + { + key_up_count++; + if (us_kbd) ok( wparam == 'A', "got wparam %#Ix\n", wparam ); + ok( lparam == 0xc01e0001, "got lparam %#Ix\n", lparam ); + } + return DefWindowProcA( hwnd, msg, wparam, lparam ); +} + +static void test_hid_keyboard(void) +{ +#include "psh_hid_macros.h" + const unsigned char report_desc[] = + { + USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), + USAGE(1, HID_USAGE_GENERIC_KEYBOARD), + COLLECTION(1, Application), + USAGE(1, HID_USAGE_GENERIC_KEYBOARD), + COLLECTION(1, Physical), + REPORT_ID(1, 1), + + USAGE_PAGE(1, HID_USAGE_PAGE_KEYBOARD), + USAGE_MINIMUM(1, HID_USAGE_KEYBOARD_aA), + USAGE_MAXIMUM(1, HID_USAGE_KEYBOARD_zZ), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 1), + REPORT_SIZE(1, 1), + REPORT_COUNT(1, 32), + INPUT(1, Data|Var|Abs), + END_COLLECTION, + END_COLLECTION, + }; + C_ASSERT(sizeof(report_desc) < MAX_HID_DESCRIPTOR_LEN); +#include "pop_hid_macros.h" + + const HID_DEVICE_ATTRIBUTES attributes = + { + .Size = sizeof(HID_DEVICE_ATTRIBUTES), + .VendorID = LOWORD(EXPECT_VIDPID), + .ProductID = 0x0003, + .VersionNumber = 0x0100, + }; + struct hid_device_desc desc = + { + .caps = { .InputReportByteLength = 5 }, + .attributes = attributes, + .use_report_id = 1, + }; + struct hid_expect key_press_release[] = + { + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1,0x01,0x00,0x00,0x00}, + }, + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1,0x00,0x00,0x00,0x00}, + }, + }; + + WCHAR device_path[MAX_PATH]; + HANDLE file; + DWORD res; + HWND hwnd; + BOOL ret; + + winetest_push_context( "keyboard" ); + + desc.report_descriptor_len = sizeof(report_desc); + memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) ); + + if (!hid_device_start_( &desc, 1, 5000 /* needs a long timeout on Win7 */ )) goto done; + + swprintf( device_path, MAX_PATH, L"\\?\hid#vid_%04x&pid_%04x", desc.attributes.VendorID, + desc.attributes.ProductID ); + ret = find_hid_device_path( device_path ); + ok( ret, "Failed to find HID device matching %s\n", debugstr_w( device_path ) ); + + + /* windows doesn't let us open HID keyboard devices */ + + file = CreateFileW( device_path, FILE_READ_ACCESS | FILE_WRITE_ACCESS, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); + todo_wine + ok( file == INVALID_HANDLE_VALUE, "CreateFileW succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError() ); + CloseHandle( file ); + + file = CreateFileW( L"\\?\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, + NULL, OPEN_EXISTING, 0, NULL ); + ok( file != INVALID_HANDLE_VALUE, "CreateFile failed, error %lu\n", GetLastError() ); + + + /* check basic keyboard input injection to window message */ + + hwnd = create_foreground_window( FALSE ); + SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)keyboard_wndproc ); + + key_down_count = 0; + key_up_count = 0; + bus_send_hid_input( file, &desc, &key_press_release[0], sizeof(key_press_release[0]) ); + + res = MsgWaitForMultipleObjects( 0, NULL, FALSE, 500, QS_KEY ); + todo_wine + ok( !res, "MsgWaitForMultipleObjects returned %#lx\n", res ); + msg_wait_for_events( 0, NULL, 5 ); /* process pending messages */ + todo_wine + ok( key_down_count == 1, "got key_down_count %u\n", key_down_count ); + ok( key_up_count == 0, "got key_up_count %u\n", key_up_count ); + + bus_send_hid_input( file, &desc, &key_press_release[1], sizeof(key_press_release[1]) ); + + res = MsgWaitForMultipleObjects( 0, NULL, FALSE, 500, QS_KEY ); + todo_wine + ok( !res, "MsgWaitForMultipleObjects returned %#lx\n", res ); + msg_wait_for_events( 0, NULL, 5 ); /* process pending messages */ + todo_wine + ok( key_down_count == 1, "got key_down_count %u\n", key_down_count ); + todo_wine + ok( key_up_count == 1, "got key_up_count %u\n", key_up_count ); + + DestroyWindow( hwnd ); + + + CloseHandle( file ); + +done: + hid_device_stop( &desc, 1 ); + + winetest_pop_context(); +} + START_TEST(device8) { dinput_test_init(); @@ -2517,6 +2664,7 @@ START_TEST(device8) if (!bus_device_start()) goto done;
test_hid_mouse(); + test_hid_keyboard();
done: bus_device_stop();
From: Rémi Bernon rbernon@codeweavers.com
--- include/hidusage.h | 2 ++ include/wine/hid.h | 12 ++++++++++++ 2 files changed, 14 insertions(+)
diff --git a/include/hidusage.h b/include/hidusage.h index 2ea3784d626..58ae5aab3e6 100644 --- a/include/hidusage.h +++ b/include/hidusage.h @@ -31,6 +31,7 @@ typedef USHORT USAGE, *PUSAGE; #define HID_USAGE_DIGITIZER_PEN ((USAGE) 0x02) #define HID_USAGE_DIGITIZER_TOUCH_SCREEN ((USAGE) 0x04) #define HID_USAGE_DIGITIZER_TOUCH_PAD ((USAGE) 0x05) +#define HID_USAGE_DIGITIZER_FINGER ((USAGE) 0x22) #define HID_USAGE_DIGITIZER_TIP_PRESSURE ((USAGE) 0x30) #define HID_USAGE_DIGITIZER_IN_RANGE ((USAGE) 0x32) #define HID_USAGE_DIGITIZER_X_TILT ((USAGE) 0x3D) @@ -38,6 +39,7 @@ typedef USHORT USAGE, *PUSAGE; #define HID_USAGE_DIGITIZER_AZIMUTH ((USAGE) 0x3F) #define HID_USAGE_DIGITIZER_TIP_SWITCH ((USAGE) 0x42) #define HID_USAGE_DIGITIZER_BARREL_SWITCH ((USAGE) 0x44) +#define HID_USAGE_DIGITIZER_CONFIDENCE ((USAGE) 0x47)
#define HID_USAGE_GENERIC_POINTER ((USAGE) 0x01) #define HID_USAGE_GENERIC_MOUSE ((USAGE) 0x02) diff --git a/include/wine/hid.h b/include/wine/hid.h index 6a92317551f..8200ca9beec 100644 --- a/include/wine/hid.h +++ b/include/wine/hid.h @@ -117,6 +117,18 @@ struct hid_preparsed_data #define HID_FEATURE_VALUE_CAPS(d) ((d)->value_caps + (d)->feature_caps_start) #define HID_COLLECTION_NODES(d) (struct hid_collection_node *)((char *)(d)->value_caps + (d)->caps_size)
+ +/* Wine-specific Digitizer page usages, not declared in hidusage.h */ +/* From HID Usage Tables */ +/* https://usb.org/sites/default/files/hut1_22.pdf */ +#define HID_USAGE_DIGITIZER_WIDTH ((USAGE) 0x48) +#define HID_USAGE_DIGITIZER_HEIGHT ((USAGE) 0x49) +#define HID_USAGE_DIGITIZER_CONTACT_ID ((USAGE) 0x51) +#define HID_USAGE_DIGITIZER_CONTACT_COUNT ((USAGE) 0x54) +#define HID_USAGE_DIGITIZER_CONTACT_COUNT_MAX ((USAGE) 0x55) +#define HID_USAGE_DIGITIZER_SCAN_TIME ((USAGE) 0x56) + + /* Wine-specific Physical Interface Device usages */ /* From USB Device Class Definition for Physical Interface Devices */ /* https://www.usb.org/sites/default/files/documents/pid1_01.pdf */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/tests/device8.c | 270 ++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+)
diff --git a/dlls/dinput/tests/device8.c b/dlls/dinput/tests/device8.c index 594a34222ce..0f586c69f6a 100644 --- a/dlls/dinput/tests/device8.c +++ b/dlls/dinput/tests/device8.c @@ -34,6 +34,8 @@
#include "dinput_test.h"
+#include "wine/hid.h" + #include "initguid.h"
DEFINE_GUID(GUID_keyboard_action_mapping,0x00000001,0x0002,0x0003,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b); @@ -1761,6 +1763,273 @@ done: winetest_pop_context(); }
+static UINT pointer_enter_count; +static UINT pointer_down_count; +static UINT pointer_up_count; +static UINT pointer_leave_count; + +static LRESULT CALLBACK touch_screen_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + if (msg == WM_POINTERENTER) pointer_enter_count++; + if (msg == WM_POINTERDOWN) pointer_down_count++; + if (msg == WM_POINTERUP) pointer_up_count++; + if (msg == WM_POINTERLEAVE) pointer_leave_count++; + return DefWindowProcA( hwnd, msg, wparam, lparam ); +} + +static void test_hid_touch_screen(void) +{ +#include "psh_hid_macros.h" + const unsigned char report_desc[] = + { + USAGE_PAGE(1, HID_USAGE_PAGE_DIGITIZER), + USAGE(1, HID_USAGE_DIGITIZER_TOUCH_SCREEN), + COLLECTION(1, Application), + REPORT_ID(1, 1), + + USAGE(1, HID_USAGE_DIGITIZER_CONTACT_COUNT), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 0x7f), + REPORT_COUNT(1, 1), + REPORT_SIZE(1, 8), + INPUT(1, Data|Var|Abs), + + USAGE_PAGE(1, HID_USAGE_PAGE_DIGITIZER), + USAGE(1, HID_USAGE_DIGITIZER_FINGER), + COLLECTION(1, Logical), + USAGE(1, HID_USAGE_DIGITIZER_TIP_SWITCH), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 1), + REPORT_SIZE(1, 1), + REPORT_COUNT(1, 8), + INPUT(1, Data|Var|Abs), + + USAGE(1, HID_USAGE_DIGITIZER_CONTACT_ID), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 0x7f), + REPORT_SIZE(1, 8), + REPORT_COUNT(1, 1), + INPUT(1, Data|Var|Abs), + + USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), + USAGE(1, HID_USAGE_GENERIC_X), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 0x7f), + REPORT_SIZE(1, 8), + REPORT_COUNT(1, 1), + INPUT(1, Data|Var|Abs), + + USAGE(1, HID_USAGE_GENERIC_Y), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 0x7f), + REPORT_SIZE(1, 8), + REPORT_COUNT(1, 1), + INPUT(1, Data|Var|Abs), + END_COLLECTION, + + USAGE_PAGE(1, HID_USAGE_PAGE_DIGITIZER), + USAGE(1, HID_USAGE_DIGITIZER_FINGER), + COLLECTION(1, Logical), + USAGE(1, HID_USAGE_DIGITIZER_TIP_SWITCH), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 1), + REPORT_SIZE(1, 1), + REPORT_COUNT(1, 8), + INPUT(1, Data|Var|Abs), + + USAGE(1, HID_USAGE_DIGITIZER_CONTACT_ID), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 0x7f), + REPORT_SIZE(1, 8), + REPORT_COUNT(1, 1), + INPUT(1, Data|Var|Abs), + + USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), + USAGE(1, HID_USAGE_GENERIC_X), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 0x7f), + REPORT_SIZE(1, 8), + REPORT_COUNT(1, 1), + INPUT(1, Data|Var|Abs), + + USAGE(1, HID_USAGE_GENERIC_Y), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 0x7f), + REPORT_SIZE(1, 8), + REPORT_COUNT(1, 1), + INPUT(1, Data|Var|Abs), + END_COLLECTION, + + USAGE_PAGE(1, HID_USAGE_PAGE_DIGITIZER), + USAGE(1, HID_USAGE_DIGITIZER_CONTACT_COUNT_MAX), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 2), + REPORT_COUNT(1, 1), + REPORT_SIZE(1, 8), + FEATURE(1, Data|Var|Abs), + END_COLLECTION + }; + C_ASSERT(sizeof(report_desc) < MAX_HID_DESCRIPTOR_LEN); +#include "pop_hid_macros.h" + + const HID_DEVICE_ATTRIBUTES attributes = + { + .Size = sizeof(HID_DEVICE_ATTRIBUTES), + .VendorID = LOWORD(EXPECT_VIDPID), + .ProductID = 0x0004, + .VersionNumber = 0x0100, + }; + struct hid_device_desc desc = + { + .caps = { .InputReportByteLength = 10, .FeatureReportByteLength = 2 }, + .attributes = attributes, + .use_report_id = 1, + }; + struct hid_expect touch_single = + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1, 1, 0x01,0x02,0x08,0x10}, + }; + struct hid_expect touch_multiple = + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1, 2, 0x01,0x02,0x08,0x10, 0x01,0x03,0x18,0x20}, + }; + struct hid_expect touch_release = + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1, 0}, + }; + struct hid_expect expect_max_count = + { + .code = IOCTL_HID_GET_FEATURE, + .report_id = 1, + .report_len = 2, + .report_buf = {1,0x02}, + .todo = TRUE, + }; + + WCHAR device_path[MAX_PATH]; + HANDLE file; + DWORD res; + HWND hwnd; + BOOL ret; + + desc.report_descriptor_len = sizeof(report_desc); + memcpy( desc.report_descriptor_buf, report_desc, sizeof(report_desc) ); + desc.expect_size = sizeof(expect_max_count); + memcpy( desc.expect, &expect_max_count, sizeof(expect_max_count) ); + fill_context( desc.context, ARRAY_SIZE(desc.context) ); + + if (!hid_device_start( &desc, 1 )) goto done; + + swprintf( device_path, MAX_PATH, L"\\?\hid#vid_%04x&pid_%04x", desc.attributes.VendorID, + desc.attributes.ProductID ); + ret = find_hid_device_path( device_path ); + ok( ret, "Failed to find HID device matching %s\n", debugstr_w( device_path ) ); + + + /* windows doesn't let us open HID touch_screen devices */ + + file = CreateFileW( device_path, FILE_READ_ACCESS | FILE_WRITE_ACCESS, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); + /* except on Win7 which doesn't seem to support HID touch screen */ + if (broken(sizeof(void *) == 4 && file != INVALID_HANDLE_VALUE)) + { + win_skip( "HID touchscreen unsupported, skipping tests\n" ); + CloseHandle( file ); + goto done; + } + + todo_wine + ok( file == INVALID_HANDLE_VALUE, "CreateFileW succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_SHARING_VIOLATION, "got error %lu\n", GetLastError() ); + CloseHandle( file ); + + + file = CreateFileW( L"\\?\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, + NULL, OPEN_EXISTING, 0, NULL ); + ok( file != INVALID_HANDLE_VALUE, "CreateFile failed, error %lu\n", GetLastError() ); + + + /* check basic touch_screen input injection to window message */ + + SetCursorPos( 0, 0 ); + + hwnd = create_foreground_window( TRUE ); + SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)touch_screen_wndproc ); + + + pointer_enter_count = pointer_down_count = pointer_up_count = pointer_leave_count = 0; + bus_send_hid_input( file, &desc, &touch_single, sizeof(touch_single) ); + + res = MsgWaitForMultipleObjects( 0, NULL, FALSE, 500, QS_POINTER ); + todo_wine + ok( !res, "MsgWaitForMultipleObjects returned %#lx\n", res ); + msg_wait_for_events( 0, NULL, 5 ); /* process pending messages */ + todo_wine + ok( pointer_enter_count == 1, "got pointer_enter_count %u\n", pointer_enter_count ); + todo_wine + ok( pointer_down_count == 1, "got pointer_down_count %u\n", pointer_down_count ); + ok( pointer_up_count == 0, "got pointer_up_count %u\n", pointer_up_count ); + ok( pointer_leave_count == 0, "got pointer_leave_count %u\n", pointer_leave_count ); + + + pointer_enter_count = pointer_down_count = pointer_up_count = pointer_leave_count = 0; + bus_send_hid_input( file, &desc, &touch_release, sizeof(touch_release) ); + + res = MsgWaitForMultipleObjects( 0, NULL, FALSE, 500, QS_POINTER ); + todo_wine + ok( !res, "MsgWaitForMultipleObjects returned %#lx\n", res ); + msg_wait_for_events( 0, NULL, 5 ); /* process pending messages */ + ok( pointer_enter_count == 0, "got pointer_enter_count %u\n", pointer_enter_count ); + ok( pointer_down_count == 0, "got pointer_down_count %u\n", pointer_down_count ); + todo_wine + ok( pointer_up_count == 1, "got pointer_up_count %u\n", pointer_up_count ); + todo_wine + ok( pointer_leave_count == 1, "got pointer_leave_count %u\n", pointer_leave_count ); + + + + pointer_enter_count = pointer_down_count = pointer_up_count = pointer_leave_count = 0; + bus_send_hid_input( file, &desc, &touch_multiple, sizeof(touch_multiple) ); + + res = MsgWaitForMultipleObjects( 0, NULL, FALSE, 500, QS_POINTER ); + todo_wine + ok( !res, "MsgWaitForMultipleObjects returned %#lx\n", res ); + msg_wait_for_events( 0, NULL, 5 ); /* process pending messages */ + todo_wine + ok( pointer_enter_count == 2, "got pointer_enter_count %u\n", pointer_enter_count ); + todo_wine + ok( pointer_down_count == 2, "got pointer_down_count %u\n", pointer_down_count ); + ok( pointer_up_count == 0, "got pointer_up_count %u\n", pointer_up_count ); + ok( pointer_leave_count == 0, "got pointer_leave_count %u\n", pointer_leave_count ); + + + pointer_enter_count = pointer_down_count = pointer_up_count = pointer_leave_count = 0; + bus_send_hid_input( file, &desc, &touch_release, sizeof(touch_release) ); + + res = MsgWaitForMultipleObjects( 0, NULL, FALSE, 500, QS_POINTER ); + todo_wine + ok( !res, "MsgWaitForMultipleObjects returned %#lx\n", res ); + msg_wait_for_events( 0, NULL, 5 ); /* process pending messages */ + ok( pointer_enter_count == 0, "got pointer_enter_count %u\n", pointer_enter_count ); + ok( pointer_down_count == 0, "got pointer_down_count %u\n", pointer_down_count ); + todo_wine + ok( pointer_up_count == 2, "got pointer_up_count %u\n", pointer_up_count ); + todo_wine + ok( pointer_leave_count == 2, "got pointer_leave_count %u\n", pointer_leave_count ); + + + DestroyWindow( hwnd ); + + CloseHandle( file ); + +done: + hid_device_stop( &desc, 1 ); +} + static void test_dik_codes( IDirectInputDevice8W *device, HANDLE event, HWND hwnd, DWORD version ) { static const struct key2dik @@ -2665,6 +2934,7 @@ START_TEST(device8)
test_hid_mouse(); test_hid_keyboard(); + test_hid_touch_screen();
done: bus_device_stop();
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=142279
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w7u_adm (32 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w7u_el (32 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w8 (32 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w8adm (32 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w864 (32 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w1064v1507 (32 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w1064v1809 (32 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w1064_tsign (32 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w10pro64 (32 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w10pro64_en_AE_u8 (32 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w11pro64 (32 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w7pro64 (64 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w864 (64 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w1064v1507 (64 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w1064v1809 (64 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w1064_2qxl (64 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w1064_adm (64 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w1064_tsign (64 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w10pro64 (64 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w10pro64_ar (64 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w10pro64_ja (64 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w10pro64_zh_CN (64 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w11pro64_amd (64 bit report) ===
dinput: Fatal: test 'driver_bus' does not exist.
=== w7u_2qxl (32 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w7u_adm (32 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w7u_el (32 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w8 (32 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w8adm (32 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w864 (32 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w1064v1507 (32 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w1064v1809 (32 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w1064_tsign (32 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w10pro64 (32 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w10pro64_en_AE_u8 (32 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w11pro64 (32 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w7pro64 (64 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w864 (64 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w1064v1507 (64 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w1064v1809 (64 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w1064_2qxl (64 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w1064_adm (64 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w1064_tsign (64 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w10pro64 (64 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w10pro64_ar (64 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w10pro64_ja (64 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w10pro64_zh_CN (64 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w11pro64_amd (64 bit report) ===
dinput: Fatal: test 'driver_hid' does not exist.
=== w7u_2qxl (32 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w7u_adm (32 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w7u_el (32 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w8 (32 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w8adm (32 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w864 (32 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w1064v1507 (32 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w1064v1809 (32 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w1064_tsign (32 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w10pro64 (32 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w10pro64_en_AE_u8 (32 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w11pro64 (32 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w7pro64 (64 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w864 (64 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w1064v1507 (64 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w1064v1809 (64 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w1064_2qxl (64 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w1064_adm (64 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w1064_tsign (64 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w10pro64 (64 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w10pro64_ar (64 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w10pro64_ja (64 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w10pro64_zh_CN (64 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
=== w11pro64_amd (64 bit report) ===
dinput: Fatal: test 'driver_hid_poll' does not exist.
v2: Rebased on top of 35ac0e7ac0511ef766f3f35220869565ce07906e which should make the tests pass.