[PATCH v12 0/11] MR10649: win32u: Initial implementation for GetPointer{,Frame}Info{,History} and GetPointerDeviceRects
-- v12: win32u: Implement NtUserGetPointerInfoList. win32u: Update pointerid 1 from mouse_in_pointer events. win32u: Implement NtUserGetPointerType. win32u: Keep track of pointer types. win32u: Preallocate pointerId 1 for the mouse pointer. win32u: Keep per-thread list of known pointers. win32u: Move process_pointer_message to input.c. win32u: Implement NtUserGetPointerDeviceRects for INVALID_HANDLE_VALUE. win32u: Add NtUserGetPointerDeviceRects test for INVALID_HANDLE_VALUE. win32u: Stub NtUserGetPointerDeviceRects. https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/input.c | 10 ++++++++++ dlls/win32u/main.c | 5 +++++ dlls/win32u/win32syscalls.h | 5 ++--- dlls/win32u/win32u.spec | 2 +- dlls/wow64win/user.c | 8 ++++++++ include/ntuser.h | 1 + 6 files changed, 27 insertions(+), 4 deletions(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index ab09c3b7d42..16f9b33ebe5 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2852,3 +2852,13 @@ INT WINAPI NtUserScheduleDispatchNotification( HWND hwnd ) return 0; } + +/********************************************************************** + * NtUserGetPointerType (win32u.@) + */ +BOOL WINAPI NtUserGetPointerType(UINT32 id, POINTER_INPUT_TYPE *type) +{ + FIXME( "(%u, %p) stub!\n", id, type ); + RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); + return FALSE; +} diff --git a/dlls/win32u/main.c b/dlls/win32u/main.c index 73a6ae32448..80f309474f3 100644 --- a/dlls/win32u/main.c +++ b/dlls/win32u/main.c @@ -1743,6 +1743,11 @@ BOOL SYSCALL_API NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE type, U SYSCALL_FUNC( NtUserGetPointerInfoList ); } +BOOL SYSCALL_API NtUserGetPointerType( UINT32 id, POINTER_INPUT_TYPE *type ) +{ + SYSCALL_FUNC( NtUserGetPointerType ); +} + INT SYSCALL_API NtUserGetPriorityClipboardFormat( UINT *list, INT count ) { SYSCALL_FUNC( NtUserGetPriorityClipboardFormat ); diff --git a/dlls/win32u/win32syscalls.h b/dlls/win32u/win32syscalls.h index aa0ceec4072..36e7d5ff116 100644 --- a/dlls/win32u/win32syscalls.h +++ b/dlls/win32u/win32syscalls.h @@ -1074,7 +1074,7 @@ SYSCALL_ENTRY( 0x142e, NtUserGetPointerInfoList, 32 ) \ SYSCALL_ENTRY( 0x142f, NtUserGetPointerInputTransform, 0 ) \ SYSCALL_ENTRY( 0x1430, NtUserGetPointerProprietaryId, 0 ) \ - SYSCALL_ENTRY( 0x1431, NtUserGetPointerType, 0 ) \ + SYSCALL_ENTRY( 0x1431, NtUserGetPointerType, 8 ) \ SYSCALL_ENTRY( 0x1432, NtUserGetPrecisionTouchPadConfiguration, 0 ) \ SYSCALL_ENTRY( 0x1433, NtUserGetPriorityClipboardFormat, 8 ) \ SYSCALL_ENTRY( 0x1434, NtUserGetProcessDefaultLayout, 4 ) \ @@ -2616,7 +2616,7 @@ SYSCALL_ENTRY( 0x142e, NtUserGetPointerInfoList, 64 ) \ SYSCALL_ENTRY( 0x142f, NtUserGetPointerInputTransform, 0 ) \ SYSCALL_ENTRY( 0x1430, NtUserGetPointerProprietaryId, 0 ) \ - SYSCALL_ENTRY( 0x1431, NtUserGetPointerType, 0 ) \ + SYSCALL_ENTRY( 0x1431, NtUserGetPointerType, 16 ) \ SYSCALL_ENTRY( 0x1432, NtUserGetPrecisionTouchPadConfiguration, 0 ) \ SYSCALL_ENTRY( 0x1433, NtUserGetPriorityClipboardFormat, 16 ) \ SYSCALL_ENTRY( 0x1434, NtUserGetProcessDefaultLayout, 8 ) \ @@ -3837,7 +3837,6 @@ SYSCALL_STUB( NtUserGetPointerFrameTimes ) \ SYSCALL_STUB( NtUserGetPointerInputTransform ) \ SYSCALL_STUB( NtUserGetPointerProprietaryId ) \ - SYSCALL_STUB( NtUserGetPointerType ) \ SYSCALL_STUB( NtUserGetPrecisionTouchPadConfiguration ) \ SYSCALL_STUB( NtUserGetProcessUIContextInformation ) \ SYSCALL_STUB( NtUserGetProp2 ) \ diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 2f657aa854e..965264c8ef6 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1072,7 +1072,7 @@ @ stdcall -syscall NtUserGetPointerInfoList(long long long long long ptr ptr ptr) @ stub -syscall NtUserGetPointerInputTransform @ stub -syscall NtUserGetPointerProprietaryId -@ stub -syscall NtUserGetPointerType +@ stdcall -syscall NtUserGetPointerType(long ptr) @ stub -syscall NtUserGetPrecisionTouchPadConfiguration @ stdcall -syscall NtUserGetPriorityClipboardFormat(ptr long) @ stdcall -syscall NtUserGetProcessDefaultLayout(ptr) diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 0a570d79ff7..ec5f8b6bbd9 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -2853,6 +2853,14 @@ NTSTATUS WINAPI wow64_NtUserGetPointerInfoList( UINT *args ) return NtUserGetPointerInfoList( id, type, unk0, unk1, size, entry_count, pointer_count, pointer_info ); } +NTSTATUS WINAPI wow64_NtUserGetPointerType( UINT *args ) +{ + UINT id = get_ulong( &args ); + POINTER_INPUT_TYPE *type = get_ptr( &args ); + + return NtUserGetPointerType( id, type ); +} + NTSTATUS WINAPI wow64_NtUserGetPriorityClipboardFormat( UINT *args ) { UINT *list = get_ptr( &args ); diff --git a/include/ntuser.h b/include/ntuser.h index 939771c9121..a73066ba29b 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -894,6 +894,7 @@ W32KAPI BOOL WINAPI NtUserGetObjectInformation( HANDLE handle, INT index, voi W32KAPI HWND WINAPI NtUserGetOpenClipboardWindow(void); W32KAPI BOOL WINAPI NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE type, UINT_PTR, UINT_PTR, SIZE_T size, UINT32 *entry_count, UINT32 *pointer_count, void *pointer_info ); +W32KAPI BOOL WINAPI NtUserGetPointerType( UINT32 id, POINTER_INPUT_TYPE *type ); W32KAPI INT WINAPI NtUserGetPriorityClipboardFormat( UINT *list, INT count ); W32KAPI BOOL WINAPI NtUserGetProcessDefaultLayout( ULONG *layout ); W32KAPI ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/input.c | 10 ++++++++++ dlls/win32u/main.c | 5 +++++ dlls/win32u/win32syscalls.h | 5 ++--- dlls/win32u/win32u.spec | 2 +- dlls/wow64win/user.c | 9 +++++++++ include/ntuser.h | 1 + 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 16f9b33ebe5..3ed2ca3a3e1 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2862,3 +2862,13 @@ BOOL WINAPI NtUserGetPointerType(UINT32 id, POINTER_INPUT_TYPE *type) RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); return FALSE; } + +/********************************************************************** + * NtUserGetPointerDeviceRects (win32u.@) + */ +BOOL WINAPI NtUserGetPointerDeviceRects( HANDLE handle, RECT *pointerDeviceRect, RECT *displayRect ) +{ + FIXME( "(%p, %p, %p) stub!\n", handle, pointerDeviceRect, displayRect ); + RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); + return FALSE; +} diff --git a/dlls/win32u/main.c b/dlls/win32u/main.c index 80f309474f3..08e7c87314d 100644 --- a/dlls/win32u/main.c +++ b/dlls/win32u/main.c @@ -1748,6 +1748,11 @@ BOOL SYSCALL_API NtUserGetPointerType( UINT32 id, POINTER_INPUT_TYPE *type ) SYSCALL_FUNC( NtUserGetPointerType ); } +BOOL SYSCALL_API NtUserGetPointerDeviceRects( HANDLE handle, RECT *pointerDeviceRect, RECT *displayRect ) +{ + SYSCALL_FUNC( NtUserGetPointerDeviceRects ); +} + INT SYSCALL_API NtUserGetPriorityClipboardFormat( UINT *list, INT count ) { SYSCALL_FUNC( NtUserGetPriorityClipboardFormat ); diff --git a/dlls/win32u/win32syscalls.h b/dlls/win32u/win32syscalls.h index 36e7d5ff116..b298d8d4bc9 100644 --- a/dlls/win32u/win32syscalls.h +++ b/dlls/win32u/win32syscalls.h @@ -1068,7 +1068,7 @@ SYSCALL_ENTRY( 0x1428, NtUserGetPointerDeviceInputSpace, 0 ) \ SYSCALL_ENTRY( 0x1429, NtUserGetPointerDeviceOrientation, 0 ) \ SYSCALL_ENTRY( 0x142a, NtUserGetPointerDeviceProperties, 0 ) \ - SYSCALL_ENTRY( 0x142b, NtUserGetPointerDeviceRects, 0 ) \ + SYSCALL_ENTRY( 0x142b, NtUserGetPointerDeviceRects, 12 ) \ SYSCALL_ENTRY( 0x142c, NtUserGetPointerDevices, 0 ) \ SYSCALL_ENTRY( 0x142d, NtUserGetPointerFrameTimes, 0 ) \ SYSCALL_ENTRY( 0x142e, NtUserGetPointerInfoList, 32 ) \ @@ -2610,7 +2610,7 @@ SYSCALL_ENTRY( 0x1428, NtUserGetPointerDeviceInputSpace, 0 ) \ SYSCALL_ENTRY( 0x1429, NtUserGetPointerDeviceOrientation, 0 ) \ SYSCALL_ENTRY( 0x142a, NtUserGetPointerDeviceProperties, 0 ) \ - SYSCALL_ENTRY( 0x142b, NtUserGetPointerDeviceRects, 0 ) \ + SYSCALL_ENTRY( 0x142b, NtUserGetPointerDeviceRects, 24 ) \ SYSCALL_ENTRY( 0x142c, NtUserGetPointerDevices, 0 ) \ SYSCALL_ENTRY( 0x142d, NtUserGetPointerFrameTimes, 0 ) \ SYSCALL_ENTRY( 0x142e, NtUserGetPointerInfoList, 64 ) \ @@ -3832,7 +3832,6 @@ SYSCALL_STUB( NtUserGetPointerDeviceInputSpace ) \ SYSCALL_STUB( NtUserGetPointerDeviceOrientation ) \ SYSCALL_STUB( NtUserGetPointerDeviceProperties ) \ - SYSCALL_STUB( NtUserGetPointerDeviceRects ) \ SYSCALL_STUB( NtUserGetPointerDevices ) \ SYSCALL_STUB( NtUserGetPointerFrameTimes ) \ SYSCALL_STUB( NtUserGetPointerInputTransform ) \ diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 965264c8ef6..4979bf8dd53 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1066,7 +1066,7 @@ @ stub -syscall NtUserGetPointerDeviceInputSpace @ stub -syscall NtUserGetPointerDeviceOrientation @ stub -syscall NtUserGetPointerDeviceProperties -@ stub -syscall NtUserGetPointerDeviceRects +@ stdcall -syscall NtUserGetPointerDeviceRects(long ptr ptr) @ stub -syscall NtUserGetPointerDevices @ stub -syscall NtUserGetPointerFrameTimes @ stdcall -syscall NtUserGetPointerInfoList(long long long long long ptr ptr ptr) diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index ec5f8b6bbd9..a25aa76c44b 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -2861,6 +2861,15 @@ NTSTATUS WINAPI wow64_NtUserGetPointerType( UINT *args ) return NtUserGetPointerType( id, type ); } +NTSTATUS WINAPI wow64_NtUserGetPointerDeviceRects( UINT *args ) +{ + HANDLE device = get_handle( &args ); + RECT *device_rect = get_ptr( &args ); + RECT *display_rect = get_ptr( &args ); + + return NtUserGetPointerDeviceRects(device, device_rect, display_rect); +} + NTSTATUS WINAPI wow64_NtUserGetPriorityClipboardFormat( UINT *args ) { UINT *list = get_ptr( &args ); diff --git a/include/ntuser.h b/include/ntuser.h index a73066ba29b..aef22700926 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -895,6 +895,7 @@ W32KAPI HWND WINAPI NtUserGetOpenClipboardWindow(void); W32KAPI BOOL WINAPI NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE type, UINT_PTR, UINT_PTR, SIZE_T size, UINT32 *entry_count, UINT32 *pointer_count, void *pointer_info ); W32KAPI BOOL WINAPI NtUserGetPointerType( UINT32 id, POINTER_INPUT_TYPE *type ); +W32KAPI BOOL WINAPI NtUserGetPointerDeviceRects( HANDLE handle, RECT *pointerDeviceRect, RECT *displayRect ); W32KAPI INT WINAPI NtUserGetPriorityClipboardFormat( UINT *list, INT count ); W32KAPI BOOL WINAPI NtUserGetProcessDefaultLayout( ULONG *layout ); W32KAPI ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/tests/win32u.c | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 19c05a97835..a7087d46e9d 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -2949,6 +2949,44 @@ static void test_NtUserRegisterWindowMessage(void) ok( !wcscmp( buf, L"#0xabc" ), "buf = %s\n", debugstr_w(buf) ); } +static BOOL CALLBACK get_virtual_screen_proc( HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM lp ) +{ + RECT *virtual_rect = (RECT *)lp; + UnionRect( virtual_rect, virtual_rect, rect ); + return TRUE; +} + +static RECT get_virtual_screen_rect(void) +{ + RECT rect = {0}; + EnumDisplayMonitors( 0, NULL, get_virtual_screen_proc, (LPARAM)&rect ); + return rect; +} + +void test_NtUserGetPointerDeviceRects(void) +{ + RECT screen = get_virtual_screen_rect(), device = {0}, display = {0}; + const int himetric_inch = 2540; + UINT dpi = GetDpiForSystem(); + RECT himetric_dev = { + .left = MulDiv( screen.left, himetric_inch, dpi ), + .top = MulDiv( screen.top, himetric_inch, dpi ), + .right = MulDiv( screen.right, himetric_inch, dpi ), + .bottom = MulDiv( screen.bottom, himetric_inch, dpi ), + }; + UINT ret; + + ret = NtUserGetPointerDeviceRects( INVALID_HANDLE_VALUE, &device, &display ); + todo_wine + { + ok( ret, "NtUserGetPointerDeviceRects failed, error %lu.\n", GetLastError() ); + ok( EqualRect( &device, &himetric_dev ), "device %s, expected %s\n", + wine_dbgstr_rect( &device ), wine_dbgstr_rect( &himetric_dev ) ); + ok( EqualRect( &display, &screen ), "display %s, expected %s\n", + wine_dbgstr_rect( &display ), wine_dbgstr_rect( &screen ) ); + } +} + START_TEST(win32u) { char **argv; @@ -3000,6 +3038,7 @@ START_TEST(win32u) test_NtUserQueryWindow(); test_RegisterClipboardFormat(); test_NtUserRegisterWindowMessage(); + test_NtUserGetPointerDeviceRects(); run_in_process( argv, "NtUserEnableMouseInPointer 0" ); run_in_process( argv, "NtUserEnableMouseInPointer 1" ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/user32/input.c | 8 -------- dlls/user32/user32.spec | 2 +- dlls/win32u/input.c | 19 ++++++++++++++++--- dlls/win32u/tests/win32u.c | 13 +++++-------- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 48b38166b75..623fab14d11 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -750,14 +750,6 @@ BOOL WINAPI GetPointerDeviceProperties( HANDLE device, UINT32 *count, return FALSE; } -BOOL WINAPI GetPointerDeviceRects( HANDLE device, RECT *device_rect, RECT *display_rect ) -{ - FIXME( "device %p, device_rect %p, display_rect %p stub!\n", - device, device_rect, display_rect ); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; -} - BOOL WINAPI GetPointerPenInfo( UINT32 id, POINTER_PEN_INFO *info ) { FIXME( "id %u, info %p stub!\n", id, info ); diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index b8939646668..80dfa388dd8 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -630,7 +630,7 @@ # @ stub GetPointerDeviceInputSpace # @ stub GetPointerDeviceOrientation @ stdcall GetPointerDeviceProperties(ptr ptr ptr) -@ stdcall GetPointerDeviceRects(ptr ptr ptr) +@ stdcall GetPointerDeviceRects(ptr ptr ptr) NtUserGetPointerDeviceRects @ stdcall GetPointerDevices(ptr ptr) # @ stub GetPointerFrameInfo # @ stub GetPointerFrameInfoHistory diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 3ed2ca3a3e1..d1384a08ab9 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -40,6 +40,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(win); WINE_DECLARE_DEBUG_CHANNEL(keyboard); +#define HIMETRIC 2540 + static const WCHAR keyboard_layouts_keyW[] = { '\\','R','e','g','i','s','t','r','y', @@ -2868,7 +2870,18 @@ BOOL WINAPI NtUserGetPointerType(UINT32 id, POINTER_INPUT_TYPE *type) */ BOOL WINAPI NtUserGetPointerDeviceRects( HANDLE handle, RECT *pointerDeviceRect, RECT *displayRect ) { - FIXME( "(%p, %p, %p) stub!\n", handle, pointerDeviceRect, displayRect ); - RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; + UINT dpi = get_system_dpi(); + + TRACE( "%p, %p, %p\n", handle, pointerDeviceRect, displayRect ); + + if (handle != INVALID_HANDLE_VALUE) + { + FIXME( "Pointer devices are not implemented!\n" ); + RtlSetLastWin32Error( ERROR_NO_DATA ); + return FALSE; + } + + *displayRect = get_virtual_screen_rect( dpi, MDT_DEFAULT ); + *pointerDeviceRect = map_dpi_rect( *displayRect, dpi, HIMETRIC ); + return TRUE; } diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index a7087d46e9d..1fd6358df39 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -2977,14 +2977,11 @@ void test_NtUserGetPointerDeviceRects(void) UINT ret; ret = NtUserGetPointerDeviceRects( INVALID_HANDLE_VALUE, &device, &display ); - todo_wine - { - ok( ret, "NtUserGetPointerDeviceRects failed, error %lu.\n", GetLastError() ); - ok( EqualRect( &device, &himetric_dev ), "device %s, expected %s\n", - wine_dbgstr_rect( &device ), wine_dbgstr_rect( &himetric_dev ) ); - ok( EqualRect( &display, &screen ), "display %s, expected %s\n", - wine_dbgstr_rect( &display ), wine_dbgstr_rect( &screen ) ); - } + ok( ret, "NtUserGetPointerDeviceRects failed, error %lu.\n", GetLastError() ); + ok( EqualRect( &device, &himetric_dev ), "device %s, expected %s\n", + wine_dbgstr_rect( &device ), wine_dbgstr_rect( &himetric_dev ) ); + ok( EqualRect( &display, &screen ), "display %s, expected %s\n", + wine_dbgstr_rect( &display ), wine_dbgstr_rect( &screen ) ); } START_TEST(win32u) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/input.c | 11 +++++++++++ dlls/win32u/message.c | 11 ----------- dlls/win32u/win32u_private.h | 1 + 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index d1384a08ab9..d8c3cb76c77 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2855,6 +2855,17 @@ INT WINAPI NtUserScheduleDispatchNotification( HWND hwnd ) return 0; } +/*********************************************************************** + * process_pointer_message + g* + * returns TRUE if the contents of 'msg' should be passed to the application + */ +BOOL process_pointer_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ) +{ + msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt ); + return TRUE; +} + /********************************************************************** * NtUserGetPointerType (win32u.@) */ diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index fe0cd2a61fe..62115515fb2 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2456,17 +2456,6 @@ static void send_parent_notify( HWND hwnd, WORD event, WORD idChild, POINT pt ) } } -/*********************************************************************** - * process_pointer_message - * - * returns TRUE if the contents of 'msg' should be passed to the application - */ -static BOOL process_pointer_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ) -{ - msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt ); - return TRUE; -} - /*********************************************************************** * process_keyboard_message * diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index cab58dfd499..d68cba0dc50 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -110,6 +110,7 @@ extern void update_current_mouse_window( HWND hwnd, INT hittest, POINT pos ); extern BOOL process_wine_clipcursor( HWND hwnd, UINT flags, BOOL reset ); extern BOOL clip_fullscreen_window( HWND hwnd, BOOL reset ); extern USHORT map_scan_to_kbd_vkey( USHORT scan, HKL layout ); +extern BOOL process_pointer_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ); /* menu.c */ extern UINT draw_nc_menu_bar( HDC hdc, RECT *rect, HWND hwnd ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/input.c | 106 +++++++++++++++++++++++++++++++++++ dlls/win32u/ntuser_private.h | 1 + 2 files changed, 107 insertions(+) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index d8c3cb76c77..d97474516d4 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -407,6 +407,19 @@ static const KBDTABLES kbdus_tables = static LONG clipping_cursor; /* clipping thread counter */ static LONG enable_mouse_in_pointer = -1; +static LONG last_frame = 0; + +struct pointer +{ + UINT32 id; + struct list entry; + POINTER_INFO info; +}; + +struct pointer_thread_data +{ + struct list known_pointers; +}; BOOL grab_pointer = TRUE; BOOL grab_fullscreen = FALSE; @@ -2855,6 +2868,91 @@ INT WINAPI NtUserScheduleDispatchNotification( HWND hwnd ) return 0; } +static struct pointer_thread_data *get_pointer_thread_data(void) +{ + struct user_thread_info *thread_info = get_user_thread_info(); + if (!thread_info->pointer_data && (thread_info->pointer_data = calloc( 1, sizeof(*thread_info->pointer_data) ))) + list_init( &thread_info->pointer_data->known_pointers ); + return thread_info->pointer_data; +}; + +static struct pointer *find_pointerid(UINT32 id) +{ + struct pointer_thread_data *thread_data = get_pointer_thread_data(); + struct pointer *pointer; + + TRACE( "looking for pointer id %d\n", id ); + + if (!thread_data) + return NULL; + + LIST_FOR_EACH_ENTRY(pointer, &thread_data->known_pointers, struct pointer, entry) + if (pointer->id == id) + return pointer; + + TRACE( "allocating pointer id %d\n", id ); + + if (!(pointer = calloc( 1, sizeof(*pointer) ))) + return NULL; + + pointer->id = id; + list_add_tail( &thread_data->known_pointers, &pointer->entry ); + + return pointer; +} + +static POINTER_INFO pointer_info_from_msg( const MSG *msg ) +{ + POINT location = { LOWORD( msg->lParam ), HIWORD( msg->lParam ) }; + LARGE_INTEGER counter; + POINTER_INFO info = { + .pointerId = GET_POINTERID_WPARAM( msg->wParam ), + .sourceDevice = INVALID_HANDLE_VALUE, + .frameId = InterlockedIncrement( &last_frame ), + .hwndTarget = msg->hwnd, + .historyCount = 1, + .dwTime = msg->time, + }; + + info.pointerFlags = HIWORD( msg->wParam ); + switch (msg->message) + { + case WM_POINTERUPDATE: info.pointerFlags |= POINTER_FLAG_UPDATE; break; + case WM_POINTERDOWN: info.pointerFlags |= POINTER_FLAG_DOWN; break; + case WM_POINTERUP: info.pointerFlags |= POINTER_FLAG_UP; break; + } + info.ptPixelLocation = info.ptPixelLocationRaw = location; + info.ptHimetricLocation = info.ptHimetricLocationRaw = map_dpi_point( location, HIMETRIC, get_system_dpi() ); + + NtQueryPerformanceCounter( &counter, NULL ); + info.PerformanceCount = counter.QuadPart; + + return info; +} + +static POINTER_BUTTON_CHANGE_TYPE compare_button( const POINTER_INFO *old, const POINTER_INFO *new ) +{ + POINTER_BUTTON_CHANGE_TYPE change = POINTER_CHANGE_NONE; + static const struct + { + POINTER_FLAGS flag; + POINTER_BUTTON_CHANGE_TYPE down, up; + } map[] = { + { POINTER_FLAG_FIRSTBUTTON, POINTER_CHANGE_FIRSTBUTTON_DOWN, POINTER_CHANGE_FIRSTBUTTON_UP }, + { POINTER_FLAG_SECONDBUTTON, POINTER_CHANGE_SECONDBUTTON_DOWN, POINTER_CHANGE_SECONDBUTTON_UP }, + { POINTER_FLAG_THIRDBUTTON, POINTER_CHANGE_THIRDBUTTON_DOWN, POINTER_CHANGE_THIRDBUTTON_UP }, + { POINTER_FLAG_FOURTHBUTTON, POINTER_CHANGE_FOURTHBUTTON_DOWN, POINTER_CHANGE_FOURTHBUTTON_UP }, + { POINTER_FLAG_FIFTHBUTTON, POINTER_CHANGE_FIFTHBUTTON_DOWN, POINTER_CHANGE_FIFTHBUTTON_UP }, + }; + + for (size_t i = 0; i < ARRAY_SIZE(map); i++) + if (!(old->pointerFlags & map[i].flag) && new->pointerFlags & map[i].flag) + change |= map[i].down; + else if (old->pointerFlags & map[i].flag && !(new->pointerFlags & map[i].flag)) + change |= map[i].up; + return change; +} + /*********************************************************************** * process_pointer_message g* @@ -2862,7 +2960,15 @@ INT WINAPI NtUserScheduleDispatchNotification( HWND hwnd ) */ BOOL process_pointer_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ) { + struct pointer *pointer; + POINTER_INFO info; + msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt ); + if (!(pointer = find_pointerid( GET_POINTERID_WPARAM( msg->wParam ) ))) + return TRUE; + info = pointer_info_from_msg( msg ); + info.ButtonChangeType = compare_button( &pointer->info, &info ); + pointer->info = info; return TRUE; } diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 2f9bc9c2ccc..2fa6944b820 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -130,6 +130,7 @@ struct user_thread_info DWORD clipping_reset; /* time when clipping was last reset */ struct session_thread_data *session_data; /* shared session thread data */ struct mouse_tracking_info *mouse_tracking_info; /* NtUserTrackMouseEvent handling */ + struct pointer_thread_data *pointer_data; /* list of known pointers */ }; C_ASSERT( sizeof(struct user_thread_info) <= sizeof(((TEB *)0)->Win32ClientInfo) ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> Seems like pointerId 1 is always the mouse, regardless of EnableMouseInPointer. --- dlls/win32u/input.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index d97474516d4..a613265cd61 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2868,19 +2868,38 @@ INT WINAPI NtUserScheduleDispatchNotification( HWND hwnd ) return 0; } +static struct pointer *allocate_pointerid( UINT32 id ); + static struct pointer_thread_data *get_pointer_thread_data(void) { struct user_thread_info *thread_info = get_user_thread_info(); if (!thread_info->pointer_data && (thread_info->pointer_data = calloc( 1, sizeof(*thread_info->pointer_data) ))) + { list_init( &thread_info->pointer_data->known_pointers ); + allocate_pointerid( 1 ); + } return thread_info->pointer_data; }; -static struct pointer *find_pointerid(UINT32 id) +static struct pointer *allocate_pointerid( UINT32 id ) { struct pointer_thread_data *thread_data = get_pointer_thread_data(); struct pointer *pointer; + TRACE( "allocating pointer id %d\n", id ); + + if (!thread_data || !(pointer = calloc( 1, sizeof(*pointer) ))) + return NULL; + pointer->id = id; + list_add_tail( &thread_data->known_pointers, &pointer->entry ); + + return pointer; +} + +static struct pointer *find_pointerid( UINT32 id ) { + struct pointer_thread_data *thread_data = get_pointer_thread_data(); + struct pointer *pointer; + TRACE( "looking for pointer id %d\n", id ); if (!thread_data) @@ -2890,15 +2909,7 @@ static struct pointer *find_pointerid(UINT32 id) if (pointer->id == id) return pointer; - TRACE( "allocating pointer id %d\n", id ); - - if (!(pointer = calloc( 1, sizeof(*pointer) ))) - return NULL; - - pointer->id = id; - list_add_tail( &thread_data->known_pointers, &pointer->entry ); - - return pointer; + return allocate_pointerid( id ); } static POINTER_INFO pointer_info_from_msg( const MSG *msg ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/input.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index a613265cd61..5aa9a7b1b7f 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -413,6 +413,7 @@ struct pointer { UINT32 id; struct list entry; + POINTER_INPUT_TYPE type; POINTER_INFO info; }; @@ -2868,7 +2869,7 @@ INT WINAPI NtUserScheduleDispatchNotification( HWND hwnd ) return 0; } -static struct pointer *allocate_pointerid( UINT32 id ); +static struct pointer *allocate_pointerid( UINT32 id, POINTER_INPUT_TYPE type ); static struct pointer_thread_data *get_pointer_thread_data(void) { @@ -2876,27 +2877,29 @@ static struct pointer_thread_data *get_pointer_thread_data(void) if (!thread_info->pointer_data && (thread_info->pointer_data = calloc( 1, sizeof(*thread_info->pointer_data) ))) { list_init( &thread_info->pointer_data->known_pointers ); - allocate_pointerid( 1 ); + allocate_pointerid( 1, PT_MOUSE ); } return thread_info->pointer_data; }; -static struct pointer *allocate_pointerid( UINT32 id ) +static struct pointer *allocate_pointerid( UINT32 id, POINTER_INPUT_TYPE type ) { struct pointer_thread_data *thread_data = get_pointer_thread_data(); struct pointer *pointer; - TRACE( "allocating pointer id %d\n", id ); + TRACE( "allocating pointer id %d, type %#x\n", id, type ); if (!thread_data || !(pointer = calloc( 1, sizeof(*pointer) ))) return NULL; pointer->id = id; + pointer->type = type; list_add_tail( &thread_data->known_pointers, &pointer->entry ); return pointer; } -static struct pointer *find_pointerid( UINT32 id ) { +static struct pointer *find_pointerid( UINT32 id, POINTER_INPUT_TYPE type ) +{ struct pointer_thread_data *thread_data = get_pointer_thread_data(); struct pointer *pointer; @@ -2909,7 +2912,7 @@ static struct pointer *find_pointerid( UINT32 id ) { if (pointer->id == id) return pointer; - return allocate_pointerid( id ); + return allocate_pointerid( id, type ); } static POINTER_INFO pointer_info_from_msg( const MSG *msg ) @@ -2964,6 +2967,18 @@ static POINTER_BUTTON_CHANGE_TYPE compare_button( const POINTER_INFO *old, const return change; } +static POINTER_INPUT_TYPE pointer_type_from_hw( const struct hw_msg_source *source ) +{ + switch (source->origin) + { + case IMDT_PEN: return PT_PEN; + case IMDT_MOUSE: return PT_MOUSE; + case IMDT_TOUCH: + case IMDT_TOUCHPAD: return PT_TOUCH; + default: return PT_POINTER; + } +} + /*********************************************************************** * process_pointer_message g* @@ -2975,11 +2990,12 @@ BOOL process_pointer_message( MSG *msg, UINT hw_id, const struct hardware_msg_da POINTER_INFO info; msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt ); - if (!(pointer = find_pointerid( GET_POINTERID_WPARAM( msg->wParam ) ))) + if (!(pointer = find_pointerid( GET_POINTERID_WPARAM( msg->wParam ), pointer_type_from_hw( &msg_data->source ) ))) return TRUE; info = pointer_info_from_msg( msg ); info.ButtonChangeType = compare_button( &pointer->info, &info ); pointer->info = info; + pointer->info.pointerType = pointer->type; return TRUE; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/user32/misc.c | 11 ++--------- dlls/user32/tests/input.c | 2 -- dlls/win32u/input.c | 23 +++++++++++++++++------ 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c index 6333fcb48b4..16f02958135 100644 --- a/dlls/user32/misc.c +++ b/dlls/user32/misc.c @@ -512,16 +512,9 @@ LRESULT WINAPI PackTouchHitTestingProximityEvaluation(const TOUCH_HIT_TESTING_IN */ BOOL WINAPI GetPointerType(UINT32 id, POINTER_INPUT_TYPE *type) { - FIXME("(%d %p): stub\n", id, type); + TRACE( "%d %p\n", id, type ); - if(!id || !type) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - *type = PT_MOUSE; - return TRUE; + return NtUserGetPointerType( id, type ); } BOOL WINAPI GetPointerInfo(UINT32 id, POINTER_INFO *info) diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 905ff0dd922..d6fb9830d76 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -5527,9 +5527,7 @@ static void test_GetPointerInfo( BOOL mouse_in_pointer_enabled ) ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); SetLastError( 0xdeadbeef ); ret = pGetPointerType( 0xdead, &type ); - todo_wine ok( !ret, "GetPointerType succeeded\n" ); - todo_wine ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); ret = pGetPointerType( 1, &type ); ok( ret, "GetPointerType failed, error %lu\n", GetLastError() ); diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 5aa9a7b1b7f..d823cf8745b 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2898,7 +2898,7 @@ static struct pointer *allocate_pointerid( UINT32 id, POINTER_INPUT_TYPE type ) return pointer; } -static struct pointer *find_pointerid( UINT32 id, POINTER_INPUT_TYPE type ) +static struct pointer *find_pointerid( UINT32 id ) { struct pointer_thread_data *thread_data = get_pointer_thread_data(); struct pointer *pointer; @@ -2912,7 +2912,7 @@ static struct pointer *find_pointerid( UINT32 id, POINTER_INPUT_TYPE type ) if (pointer->id == id) return pointer; - return allocate_pointerid( id, type ); + return NULL; } static POINTER_INFO pointer_info_from_msg( const MSG *msg ) @@ -2986,11 +2986,13 @@ static POINTER_INPUT_TYPE pointer_type_from_hw( const struct hw_msg_source *sour */ BOOL process_pointer_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ) { + UINT32 pointer_id = GET_POINTERID_WPARAM( msg->wParam ); struct pointer *pointer; POINTER_INFO info; msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt ); - if (!(pointer = find_pointerid( GET_POINTERID_WPARAM( msg->wParam ), pointer_type_from_hw( &msg_data->source ) ))) + if (!(pointer = find_pointerid( pointer_id )) && + !(pointer = allocate_pointerid( pointer_id, pointer_type_from_hw( &msg_data->source ) ))) return TRUE; info = pointer_info_from_msg( msg ); info.ButtonChangeType = compare_button( &pointer->info, &info ); @@ -3004,9 +3006,18 @@ BOOL process_pointer_message( MSG *msg, UINT hw_id, const struct hardware_msg_da */ BOOL WINAPI NtUserGetPointerType(UINT32 id, POINTER_INPUT_TYPE *type) { - FIXME( "(%u, %p) stub!\n", id, type ); - RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; + struct pointer *pointer; + + TRACE( "%u, %p\n", id, type ); + + if (!id || !type || !(pointer = find_pointerid( id )) ) + { + RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + *type = pointer->type; + return TRUE; } /********************************************************************** -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/input.c | 45 +++++++++++++++++++++--------------- dlls/win32u/message.c | 11 ++++++++- dlls/win32u/win32u_private.h | 2 ++ 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index d823cf8745b..982f0165bc5 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2915,21 +2915,21 @@ static struct pointer *find_pointerid( UINT32 id ) return NULL; } -static POINTER_INFO pointer_info_from_msg( const MSG *msg ) +POINTER_INFO pointer_info_from_msg( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, DWORD time ) { - POINT location = { LOWORD( msg->lParam ), HIWORD( msg->lParam ) }; + POINT location = { LOWORD( lParam ), HIWORD( lParam ) }; LARGE_INTEGER counter; POINTER_INFO info = { - .pointerId = GET_POINTERID_WPARAM( msg->wParam ), + .pointerId = GET_POINTERID_WPARAM( wParam ), .sourceDevice = INVALID_HANDLE_VALUE, .frameId = InterlockedIncrement( &last_frame ), - .hwndTarget = msg->hwnd, + .hwndTarget = hwnd, .historyCount = 1, - .dwTime = msg->time, + .dwTime = time, }; - info.pointerFlags = HIWORD( msg->wParam ); - switch (msg->message) + info.pointerFlags = HIWORD( wParam ); + switch (msg) { case WM_POINTERUPDATE: info.pointerFlags |= POINTER_FLAG_UPDATE; break; case WM_POINTERDOWN: info.pointerFlags |= POINTER_FLAG_DOWN; break; @@ -2967,6 +2967,23 @@ static POINTER_BUTTON_CHANGE_TYPE compare_button( const POINTER_INFO *old, const return change; } +void pointer_update( UINT32 id, POINTER_INPUT_TYPE type, POINTER_INFO *info ) +{ + POINTER_BUTTON_CHANGE_TYPE buttons; + struct pointer *pointer; + + TRACE( "updating pointer id %d.\n", id ); + + if (!(pointer = find_pointerid( id )) && !(pointer = allocate_pointerid( id, type ))) + return; + + buttons = compare_button(&pointer->info, info); + + pointer->info = *info; + pointer->info.pointerType = pointer->type; + pointer->info.ButtonChangeType = buttons; +} + static POINTER_INPUT_TYPE pointer_type_from_hw( const struct hw_msg_source *source ) { switch (source->origin) @@ -2986,18 +3003,8 @@ static POINTER_INPUT_TYPE pointer_type_from_hw( const struct hw_msg_source *sour */ BOOL process_pointer_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ) { - UINT32 pointer_id = GET_POINTERID_WPARAM( msg->wParam ); - struct pointer *pointer; - POINTER_INFO info; - - msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt ); - if (!(pointer = find_pointerid( pointer_id )) && - !(pointer = allocate_pointerid( pointer_id, pointer_type_from_hw( &msg_data->source ) ))) - return TRUE; - info = pointer_info_from_msg( msg ); - info.ButtonChangeType = compare_button( &pointer->info, &info ); - pointer->info = info; - pointer->info.pointerType = pointer->type; + POINTER_INFO info = pointer_info_from_msg( msg->hwnd, msg->message, msg->wParam, msg->lParam, msg->time ); + pointer_update( GET_POINTERID_WPARAM( msg->wParam ), pointer_type_from_hw( &msg_data->source ), &info ); return TRUE; } diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 62115515fb2..c694e88f77d 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2666,7 +2666,16 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H break; } - if (message) send_message( msg->hwnd, message, MAKELONG( 1, flags ), MAKELONG( msg->pt.x, msg->pt.y ) ); + if (message) + { + LPARAM lParam = MAKELONG( msg->pt.x, msg->pt.y ); + WPARAM wParam = MAKELONG( 1, flags ); + POINTER_INFO info; + + info = pointer_info_from_msg( msg->hwnd, message, wParam, lParam, msg->time ); + pointer_update( 1, PT_MOUSE, &info ); + send_message( msg->hwnd, message, wParam, lParam ); + } } /* FIXME: is this really the right place for this hook? */ diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index d68cba0dc50..0217f52e5da 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -111,6 +111,8 @@ extern BOOL process_wine_clipcursor( HWND hwnd, UINT flags, BOOL reset ); extern BOOL clip_fullscreen_window( HWND hwnd, BOOL reset ); extern USHORT map_scan_to_kbd_vkey( USHORT scan, HKL layout ); extern BOOL process_pointer_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ); +extern POINTER_INFO pointer_info_from_msg( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, DWORD time ); +extern void pointer_update( UINT32 id, POINTER_INPUT_TYPE type, POINTER_INFO *info ); /* menu.c */ extern UINT draw_nc_menu_bar( HDC hdc, RECT *rect, HWND hwnd ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/user32/input.c | 63 ++++++++++++++++++++++++++++++++------ dlls/user32/misc.c | 32 +++++++++++++++++-- dlls/user32/tests/input.c | 17 ++++------ dlls/user32/user32.spec | 16 +++++----- dlls/win32u/input.c | 62 +++++++++++++++++++++++++++++-------- dlls/win32u/tests/win32u.c | 8 ++--- 6 files changed, 151 insertions(+), 47 deletions(-) diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 623fab14d11..051f4e48ec9 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -752,16 +752,20 @@ BOOL WINAPI GetPointerDeviceProperties( HANDLE device, UINT32 *count, BOOL WINAPI GetPointerPenInfo( UINT32 id, POINTER_PEN_INFO *info ) { - FIXME( "id %u, info %p stub!\n", id, info ); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; + UINT32 count = 1; + + TRACE( "id %u, info %p\n", id, info ); + + return NtUserGetPointerInfoList( id, PT_PEN, 0, 0, sizeof(*info), &count, &count, info ); } BOOL WINAPI GetPointerTouchInfo( UINT32 id, POINTER_TOUCH_INFO *info ) { - FIXME( "id %u, info %p stub!\n", id, info ); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; + UINT32 count = 1; + + TRACE( "id %u, info %p stub!\n", id, info ); + + return NtUserGetPointerInfoList( id, PT_TOUCH, 0, 0, sizeof(*info), &count, &count, info ); } BOOL WINAPI GetRawPointerDeviceData( UINT32 id, UINT32 hist_count, UINT32 prop_count, @@ -775,9 +779,50 @@ BOOL WINAPI GetRawPointerDeviceData( UINT32 id, UINT32 hist_count, UINT32 prop_c BOOL WINAPI GetPointerTouchInfoHistory( UINT32 id, UINT32 *count, POINTER_TOUCH_INFO *info ) { - FIXME( "id %u, count %p, info %p stub!\n", id, count, info ); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; + UINT32 pointers = 1; + + TRACE( "id %u, count %p, info %p\n", id, count, info ); + + return NtUserGetPointerInfoList( id, PT_TOUCH, 0, 0, sizeof(*info), count, &pointers, info ); +} + +BOOL WINAPI GetPointerPenInfoHistory( UINT32 id, UINT32 *count, POINTER_PEN_INFO *info ) +{ + UINT32 pointers = 1; + + TRACE( "id %u, count %p, info %p\n", id, count, info ); + + return NtUserGetPointerInfoList( id, PT_PEN, 0, 0, sizeof(*info), count, &pointers, info ); +} + +BOOL WINAPI GetPointerFrameTouchInfo( UINT32 id, UINT32 *count, POINTER_TOUCH_INFO *info ) +{ + UINT32 entries = 1; + + TRACE( "id %u, count %p, info %p\n", id, count, info ); + + return NtUserGetPointerInfoList( id, PT_TOUCH, 0, 0, sizeof(*info), &entries, count, info ); +} + +BOOL WINAPI GetPointerFramePenInfo( UINT32 id, UINT32 *count, POINTER_PEN_INFO *info ) +{ + UINT32 entries = 1; + + TRACE( "id %u, count %p, info %p\n", id, count, info ); + + return NtUserGetPointerInfoList( id, PT_PEN, 0, 0, sizeof(*info), &entries, count, info ); +} + +BOOL WINAPI GetPointerFrameTouchInfoHistory( UINT32 id, UINT32 *entries, UINT32 *pointers, POINTER_TOUCH_INFO *info ) +{ + TRACE( "id %u, entries %p, pointers %p, info %p\n", id, entries, pointers, info ); + return NtUserGetPointerInfoList( id, PT_TOUCH, 0, 0, sizeof(*info), entries, pointers, info ); +} + +BOOL WINAPI GetPointerFramePenInfoHistory( UINT32 id, UINT32 *entries, UINT32 *pointers, POINTER_PEN_INFO *info ) +{ + TRACE( "id %u, entries %p, pointers %p, info %p\n", id, entries, pointers, info ); + return NtUserGetPointerInfoList( id, PT_PEN, 0, 0, sizeof(*info), entries, pointers, info ); } diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c index 16f02958135..764e559df19 100644 --- a/dlls/user32/misc.c +++ b/dlls/user32/misc.c @@ -519,10 +519,36 @@ BOOL WINAPI GetPointerType(UINT32 id, POINTER_INPUT_TYPE *type) BOOL WINAPI GetPointerInfo(UINT32 id, POINTER_INFO *info) { - FIXME("(%d %p): stub\n", id, info); + UINT32 count = 1; - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; + TRACE( "id %d, info %p\n", id, info ); + + return NtUserGetPointerInfoList( id, PT_POINTER, 0, 0, sizeof(*info), &count, &count, info ); +} + +BOOL WINAPI GetPointerInfoHistory( UINT32 id, UINT32 *count, POINTER_INFO *info ) +{ + UINT32 pointers = 1; + + TRACE( "id %u, count %p, info %p\n", id, count, info ); + + return NtUserGetPointerInfoList( id, PT_POINTER, 0, 0, sizeof(*info), count, &pointers, info ); +} + +BOOL WINAPI GetPointerFrameInfo( UINT32 id, UINT32 *count, POINTER_INFO *info ) +{ + UINT32 entries = 1; + + TRACE( "id %u, count %p, info %p\n", id, count, info ); + + return NtUserGetPointerInfoList( id, PT_POINTER, 0, 0, sizeof(*info), &entries, count, info ); +} + +BOOL WINAPI GetPointerFrameInfoHistory( UINT32 id, UINT32 *entries, UINT32 *pointers, POINTER_INFO *info ) +{ + TRACE( "id %u, entries %p, pointers %p, info %p\n", id, entries, pointers, info ); + + return NtUserGetPointerInfoList( id, PT_POINTER, 0, 0, sizeof(*info), entries, pointers, info ); } LRESULT WINAPI ImeWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index d6fb9830d76..51bad80e252 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -5416,7 +5416,9 @@ static DWORD CALLBACK test_GetPointerInfo_thread( void *arg ) memset( &pointer_info, 0xcd, sizeof(pointer_info) ); ret = pGetPointerInfo( 1, &pointer_info ); + todo_wine ok( !ret, "GetPointerInfo succeeded\n" ); + todo_wine ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); DestroyWindow( hwnd ); @@ -5545,13 +5547,13 @@ static void test_GetPointerInfo( BOOL mouse_in_pointer_enabled ) ret = pGetPointerInfo( 1, invalid_ptr ); ok( !ret, "GetPointerInfo succeeded\n" ); - todo_wine ok( GetLastError() == ERROR_NOACCESS || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* w10 32bit */, "got error %lu\n", GetLastError() ); memset( pointer_info, 0xcd, sizeof(pointer_info) ); ret = pGetPointerInfo( 1, pointer_info ); ok( !ret, "GetPointerInfo succeeded\n" ); + todo_wine ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); SetCursorPos( 500, 500 ); /* avoid generating mouse message on window creation */ @@ -5563,6 +5565,7 @@ static void test_GetPointerInfo( BOOL mouse_in_pointer_enabled ) memset( pointer_info, 0xcd, sizeof(pointer_info) ); ret = pGetPointerInfo( 1, pointer_info ); ok( !ret, "GetPointerInfo succeeded\n" ); + todo_wine ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); SetCursorPos( 200, 200 ); @@ -5648,30 +5651,26 @@ static void test_GetPointerInfo( BOOL mouse_in_pointer_enabled ) memset( pointer_info, 0xcd, sizeof(pointer_info) ); ret = pGetPointerInfo( 0xdead, pointer_info ); ok( !ret, "GetPointerInfo succeeded\n" ); + todo_wine ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); memset( pointer_info, 0xcd, sizeof(pointer_info) ); ret = pGetPointerInfo( 1, pointer_info ); - todo_wine_if(mouse_in_pointer_enabled) ok( ret == mouse_in_pointer_enabled, "GetPointerInfo failed, error %lu\n", GetLastError() ); if (!mouse_in_pointer_enabled) { + todo_wine ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); return; } - todo_wine ok( pointer_info[0].pointerType == PT_MOUSE, "got pointerType %lu\n", pointer_info[0].pointerType ); - todo_wine ok( pointer_info[0].pointerId == 1, "got pointerId %u\n", pointer_info[0].pointerId ); ok( !!pointer_info[0].frameId, "got frameId %u\n", pointer_info[0].frameId ); - todo_wine ok( pointer_info[0].pointerFlags == (0x40000 | POINTER_MESSAGE_FLAG_INRANGE), "got pointerFlags %#x\n", pointer_info[0].pointerFlags ); - todo_wine ok( pointer_info[0].sourceDevice == INVALID_HANDLE_VALUE || broken(!!pointer_info[0].sourceDevice) /* < w10 & 32bit */, "got sourceDevice %p\n", pointer_info[0].sourceDevice ); - todo_wine ok( pointer_info[0].hwndTarget == hwnd, "got hwndTarget %p\n", pointer_info[0].hwndTarget ); ok( !!pointer_info[0].ptPixelLocation.x, "got ptPixelLocation %s\n", wine_dbgstr_point( &pointer_info[0].ptPixelLocation ) ); ok( !!pointer_info[0].ptPixelLocation.y, "got ptPixelLocation %s\n", wine_dbgstr_point( &pointer_info[0].ptPixelLocation ) ); @@ -5682,14 +5681,10 @@ static void test_GetPointerInfo( BOOL mouse_in_pointer_enabled ) ok( !!pointer_info[0].ptHimetricLocationRaw.x, "got ptHimetricLocationRaw %s\n", wine_dbgstr_point( &pointer_info[0].ptHimetricLocationRaw ) ); ok( !!pointer_info[0].ptHimetricLocationRaw.y, "got ptHimetricLocationRaw %s\n", wine_dbgstr_point( &pointer_info[0].ptHimetricLocationRaw ) ); ok( !!pointer_info[0].dwTime, "got dwTime %lu\n", pointer_info[0].dwTime ); - todo_wine ok( pointer_info[0].historyCount == 1, "got historyCount %u\n", pointer_info[0].historyCount ); - todo_wine ok( pointer_info[0].InputData == 0, "got InputData %u\n", pointer_info[0].InputData ); - todo_wine ok( pointer_info[0].dwKeyStates == 0, "got dwKeyStates %lu\n", pointer_info[0].dwKeyStates ); ok( !!pointer_info[0].PerformanceCount, "got PerformanceCount %I64u\n", pointer_info[0].PerformanceCount ); - todo_wine ok( pointer_info[0].ButtonChangeType == POINTER_CHANGE_FIRSTBUTTON_UP, "got ButtonChangeType %u\n", pointer_info[0].ButtonChangeType ); thread = CreateThread( NULL, 0, test_GetPointerInfo_thread, NULL, 0, NULL ); diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index 80dfa388dd8..2ae092d696f 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -632,18 +632,18 @@ @ stdcall GetPointerDeviceProperties(ptr ptr ptr) @ stdcall GetPointerDeviceRects(ptr ptr ptr) NtUserGetPointerDeviceRects @ stdcall GetPointerDevices(ptr ptr) -# @ stub GetPointerFrameInfo -# @ stub GetPointerFrameInfoHistory -# @ stub GetPointerFramePenInfo -# @ stub GetPointerFramePenInfoHistory +@ stdcall GetPointerFrameInfo(long ptr ptr) +@ stdcall GetPointerFrameInfoHistory(long ptr ptr ptr) +@ stdcall GetPointerFramePenInfo(long ptr ptr) +@ stdcall GetPointerFramePenInfoHistory(long ptr ptr ptr) # @ stub GetPointerFrameTimes -# @ stub GetPointerFrameTouchInfo -# @ stub GetPointerFrameTouchInfoHistory +@ stdcall GetPointerFrameTouchInfo(long ptr ptr) +@ stdcall GetPointerFrameTouchInfoHistory(long ptr ptr ptr) @ stdcall GetPointerInfo(long ptr) -# @ stub GetPointerInfoHistory +@ stdcall GetPointerInfoHistory(long ptr ptr) # @ stub GetPointerInputTransform @ stdcall GetPointerPenInfo(long ptr) -# @ stub GetPointerPenInfoHistory +@ stdcall GetPointerPenInfoHistory(long ptr ptr) @ stdcall GetPointerTouchInfo(long ptr) @ stdcall GetPointerTouchInfoHistory(long ptr ptr) @ stdcall GetPointerType(long ptr) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 982f0165bc5..eb8191c02c2 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2735,18 +2735,6 @@ BOOL clip_fullscreen_window( HWND hwnd, BOOL reset ) return ret; } -/********************************************************************** - * NtUserGetPointerInfoList (win32u.@) - */ -BOOL WINAPI NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE type, UINT_PTR unk0, UINT_PTR unk1, SIZE_T size, - UINT32 *entry_count, UINT32 *pointer_count, void *pointer_info ) -{ - FIXME( "id %#x, type %#x, unk0 %#lx, unk1 %#lx, size %#lx, entry_count %p, pointer_count %p, pointer_info %p stub!\n", - id, type, (long)unk0, (long)unk1, size, entry_count, pointer_count, pointer_info ); - RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; -} - static BOOL get_clip_cursor( RECT *rect, UINT dpi, MONITOR_DPI_TYPE type ) { struct object_lock lock = OBJECT_LOCK_INIT; @@ -3027,6 +3015,56 @@ BOOL WINAPI NtUserGetPointerType(UINT32 id, POINTER_INPUT_TYPE *type) return TRUE; } +/********************************************************************** + * NtUserGetPointerInfoList (win32u.@) + */ +BOOL WINAPI NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE type, UINT_PTR unk0, UINT_PTR unk1, SIZE_T size, + UINT32 *entry_count, UINT32 *pointer_count, void *pointer_info ) +{ + struct pointer *pointer; + size_t target_size = 0; + + TRACE( "id %d, type %#x, unk0 %#lx, unk1 %#lx, size %#lx, entry_count %p, pointer_count %p, pointer_info %p\n", + id, type, (long)unk0, (long)unk1, size, entry_count, pointer_count, pointer_info ); + + switch (type) + { + case PT_MOUSE: + case PT_PEN: target_size = sizeof(POINTER_PEN_INFO); break; + case PT_POINTER: target_size = sizeof(POINTER_INFO); break; + case PT_TOUCHPAD: + case PT_TOUCH: target_size = sizeof(POINTER_TOUCH_INFO); break; + } + + if (type == PT_MOUSE || size != target_size) + { + RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + if (!(pointer = find_pointerid( id ))) + { + TRACE( "pointer id %d not found.\n", id ); + RtlSetLastWin32Error( ERROR_NOACCESS ); + return FALSE; + } + + if (!pointer->info.pointerId) + { + TRACE( "no info on pointer id %d.\n", id ); + RtlSetLastWin32Error( ERROR_NOACCESS ); + return FALSE; + } + + if (type != PT_POINTER && type != PT_MOUSE) + FIXME( "Pointer type %#x not implemented!", type ); + + *entry_count = 1; + *pointer_count = 1; + *(POINTER_INFO *)pointer_info = pointer->info; + return TRUE; +} + /********************************************************************** * NtUserGetPointerDeviceRects (win32u.@) */ diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 1fd6358df39..933e9bf5ebe 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -1807,9 +1807,13 @@ static DWORD CALLBACK test_NtUserGetPointerInfoList_thread( void *arg ) memset( &pointer_info, 0xcd, sizeof(pointer_info) ); entry_count = pointer_count = 2; ret = NtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO), &entry_count, &pointer_count, pointer_info ); + todo_wine ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + todo_wine ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + todo_wine ok( pointer_count == 2, "got pointer_count %u\n", pointer_count ); + todo_wine ok( entry_count == 2, "got entry_count %u\n", entry_count ); DestroyWindow( hwnd ); @@ -1869,17 +1873,14 @@ static void test_NtUserGetPointerInfoList( BOOL mouse_in_pointer_enabled ) entry_count = pointer_count = 2; ret = NtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO), invalid_ptr, &pointer_count, pointer_info ); ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); - todo_wine ok( GetLastError() == ERROR_NOACCESS, "got error %lu\n", GetLastError() ); entry_count = pointer_count = 2; ret = NtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO), &entry_count, invalid_ptr, pointer_info ); ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); - todo_wine ok( GetLastError() == ERROR_NOACCESS, "got error %lu\n", GetLastError() ); entry_count = pointer_count = 2; ret = NtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO), &entry_count, &pointer_count, invalid_ptr ); ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); - todo_wine ok( GetLastError() == ERROR_NOACCESS || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* w10 32bit */, "got error %lu\n", GetLastError() ); memset( pointer_info, 0xcd, sizeof(pointer_info) ); @@ -1918,7 +1919,6 @@ static void test_NtUserGetPointerInfoList( BOOL mouse_in_pointer_enabled ) memset( pointer_info, 0xcd, sizeof(pointer_info) ); entry_count = pointer_count = 2; ret = NtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO), &entry_count, &pointer_count, pointer_info ); - todo_wine_if(mouse_in_pointer_enabled) ok( ret == mouse_in_pointer_enabled, "NtUserGetPointerInfoList failed, error %lu\n", GetLastError() ); if (!ret) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
On Fri Apr 17 17:22:25 2026 +0000, Rémi Bernon wrote:
Well portability considerations aside, it's also a matter of whether adding new style patterns to the code really helps making things more readable or convenient, given that style discrepancies have a fixed toll on the reader. In this particular case, I'm not fully convinced that it does. For instance: ``` static POINT pixel_to_himetric( POINT px ) { UINT dpi = HIMETRIC / get_system_dpi(); return (POINT) { .x = px.x * dpi, .y = px.y * dpi, }; } ``` vs: ``` static POINT pixel_to_himetric( POINT px ) { UINT dpi = HIMETRIC / get_system_dpi(); px.x *= dpi; px.y *= dpi; return px; } ``` The latter is even shorter. In addition (and it is not the case here, but we've discussed the case before), the `(<type>) { <init> }` syntax has a very unfortunate "cast-like" looking that can be confusing to any unaware reader. Also, when used to pass parameters, the lifetime of the literal is well defined but potentially full of pitfalls, like this: ``` int *foo( int *a ); /* { return a; } */ /* this is fine: */ int bar(void) { return *foo( (int []) { 1 } ); } /* this is bad, there's a warning only if compiler can figure what foo does: */ int *baz(void) { return foo( (int []) { 1 } ); } int bad(void) { return *baz(); } ``` using map_dpi_{point,rect} indirectly removed both uses of compound literals
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10649#note_136801
participants (2)
-
Anna (navi) Figueiredo Gomes -
navi (@navi)