[PATCH 0/10] MR10649: win32u: Initial implementation for GetPointer{,Frame}Info{,History} and GetPointerDeviceRects
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/Makefile.in | 1 + dlls/win32u/main.c | 5 +++++ dlls/win32u/pointer.c | 40 +++++++++++++++++++++++++++++++++++++ dlls/win32u/win32syscalls.h | 5 ++--- dlls/win32u/win32u.spec | 2 +- dlls/wow64win/user.c | 8 ++++++++ include/ntuser.h | 1 + 7 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 dlls/win32u/pointer.c diff --git a/dlls/win32u/Makefile.in b/dlls/win32u/Makefile.in index 454fb2555bc..f298064e3ed 100644 --- a/dlls/win32u/Makefile.in +++ b/dlls/win32u/Makefile.in @@ -44,6 +44,7 @@ SOURCES = \ palette.c \ path.c \ pen.c \ + pointer.c \ printdrv.c \ rawinput.c \ region.c \ 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/pointer.c b/dlls/win32u/pointer.c new file mode 100644 index 00000000000..4a8601f3ccd --- /dev/null +++ b/dlls/win32u/pointer.c @@ -0,0 +1,40 @@ +/* + * Pointer Input + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include <stdbool.h> +#include <pthread.h> + +#include "win32u_private.h" +#include "ntuser_private.h" +#include "winbase.h" + +WINE_DEFAULT_DEBUG_CHANNEL(pointer); + +/********************************************************************** + * 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/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 | 12 ------------ dlls/win32u/pointer.c | 13 +++++++++++++ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index ab09c3b7d42..c54615e4f29 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2719,18 +2719,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; diff --git a/dlls/win32u/pointer.c b/dlls/win32u/pointer.c index 4a8601f3ccd..7651843aade 100644 --- a/dlls/win32u/pointer.c +++ b/dlls/win32u/pointer.c @@ -38,3 +38,16 @@ BOOL WINAPI NtUserGetPointerType(UINT32 id, POINTER_INPUT_TYPE *type) RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); return FALSE; } + +/********************************************************************** + * 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; +} + -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/pointer.c | 31 +++++++++++++++++++++++++++++++ dlls/win32u/win32syscalls.h | 5 ++--- dlls/win32u/win32u.spec | 2 +- dlls/wow64win/user.c | 9 +++++++++ include/ntuser.h | 1 + 5 files changed, 44 insertions(+), 4 deletions(-) diff --git a/dlls/win32u/pointer.c b/dlls/win32u/pointer.c index 7651843aade..0725c599473 100644 --- a/dlls/win32u/pointer.c +++ b/dlls/win32u/pointer.c @@ -29,6 +29,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(pointer); +#define HIMETRIC 2540 + /********************************************************************** * NtUserGetPointerType (win32u.@) */ @@ -51,3 +53,32 @@ BOOL WINAPI NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE type, UINT_P return FALSE; } +/********************************************************************** + * NtUserGetPointerDeviceRects (win32u.@) + */ +BOOL WINAPI NtUserGetPointerDeviceRects( HANDLE handle, RECT *pointerDeviceRect, RECT *displayRect ) +{ + UINT dpi = get_system_dpi(); + RECT monitor; + + 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; + } + + monitor = get_virtual_screen_rect( dpi, MDT_DEFAULT ); + + dpi = HIMETRIC / dpi; + *pointerDeviceRect = (RECT) { + .left = monitor.left * dpi, + .top = monitor.top * dpi, + .right = monitor.right * dpi, + .bottom = monitor.bottom * dpi, + }; + *displayRect = monitor; + + return TRUE; +} 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/message.c | 11 ----------- dlls/win32u/pointer.c | 11 +++++++++++ dlls/win32u/win32u_private.h | 3 +++ 3 files changed, 14 insertions(+), 11 deletions(-) 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/pointer.c b/dlls/win32u/pointer.c index 0725c599473..8deb2daf1f8 100644 --- a/dlls/win32u/pointer.c +++ b/dlls/win32u/pointer.c @@ -31,6 +31,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(pointer); #define HIMETRIC 2540 +/*********************************************************************** + * 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/win32u_private.h b/dlls/win32u/win32u_private.h index cab58dfd499..f4bd250f6de 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -144,6 +144,9 @@ extern void pack_user_message( void *buffer, size_t size, UINT message, /* rawinput.c */ extern BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ); +/* pointer.c */ +extern BOOL process_pointer_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ); + /* scroll.c */ extern void draw_nc_scrollbar( HWND hwnd, HDC hdc, BOOL draw_horizontal, BOOL draw_vertical ); extern BOOL get_scroll_info( HWND hwnd, INT bar, SCROLLINFO *info ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/ntuser_private.h | 1 + dlls/win32u/pointer.c | 110 +++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) 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) ); diff --git a/dlls/win32u/pointer.c b/dlls/win32u/pointer.c index 8deb2daf1f8..02a2a992df1 100644 --- a/dlls/win32u/pointer.c +++ b/dlls/win32u/pointer.c @@ -31,6 +31,108 @@ WINE_DEFAULT_DEBUG_CHANNEL(pointer); #define HIMETRIC 2540 +static LONG last_frame = 0; + +struct pointer { + UINT32 id; + struct list entry; + POINTER_INFO info; +}; + +struct pointer_thread_data { + struct list known_pointers; +}; + +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 ); + + 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 (!thread_data || !(pointer = calloc( 1, sizeof(*pointer) ))) + return NULL; + + pointer->id = id; + list_add_tail(&thread_data->known_pointers, &pointer->entry); + + return pointer; +} + +static POINT pixel_to_himetric(POINT px) { + UINT dpi = HIMETRIC / get_system_dpi(); + + return (POINT) { + .x = px.x * dpi, + .y = px.y * dpi, + }; +} + +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 = pixel_to_himetric(location); + + 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* @@ -38,7 +140,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(pointer); */ 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; } -- 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/pointer.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/dlls/win32u/pointer.c b/dlls/win32u/pointer.c index 02a2a992df1..6b90f921d6e 100644 --- a/dlls/win32u/pointer.c +++ b/dlls/win32u/pointer.c @@ -43,35 +43,47 @@ struct pointer_thread_data { struct list known_pointers; }; +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( "looking for pointer id %d\n", id ); - - 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 (!thread_data || !(pointer = calloc( 1, sizeof(*pointer) ))) - return NULL; - + 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 ); + + LIST_FOR_EACH_ENTRY(pointer, &thread_data->known_pointers, struct pointer, entry) + if (pointer->id == id) + return pointer; + + return allocate_pointerid(id); +} + static POINT pixel_to_himetric(POINT px) { UINT dpi = HIMETRIC / get_system_dpi(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10649
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/pointer.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/dlls/win32u/pointer.c b/dlls/win32u/pointer.c index 6b90f921d6e..34895de7e19 100644 --- a/dlls/win32u/pointer.c +++ b/dlls/win32u/pointer.c @@ -36,6 +36,7 @@ static LONG last_frame = 0; struct pointer { UINT32 id; struct list entry; + POINTER_INPUT_TYPE type; POINTER_INFO info; }; @@ -43,7 +44,7 @@ struct pointer_thread_data { struct list known_pointers; }; -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) { @@ -51,12 +52,12 @@ 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; @@ -66,12 +67,13 @@ static struct pointer *allocate_pointerid(UINT32 id) 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; @@ -81,7 +83,7 @@ static struct pointer *find_pointerid(UINT32 id) { if (pointer->id == id) return pointer; - return allocate_pointerid(id); + return allocate_pointerid(id, type); } static POINT pixel_to_himetric(POINT px) { @@ -122,6 +124,16 @@ static POINTER_INFO pointer_info_from_msg( const MSG *msg ) return info; } +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; + } +} static POINTER_BUTTON_CHANGE_TYPE compare_button(const POINTER_INFO *old, const POINTER_INFO *new) { @@ -156,7 +168,7 @@ 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); -- 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/pointer.c | 29 +++++++++++++++++++++-------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c index 6333fcb48b4..880102e263c 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/pointer.c b/dlls/win32u/pointer.c index 34895de7e19..8fa0b1aeba0 100644 --- a/dlls/win32u/pointer.c +++ b/dlls/win32u/pointer.c @@ -62,7 +62,7 @@ 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 @@ -73,7 +73,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; @@ -83,7 +83,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 POINT pixel_to_himetric(POINT px) { @@ -164,14 +164,18 @@ static POINTER_BUTTON_CHANGE_TYPE compare_button(const POINTER_INFO *old, const */ 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 ) ))) - return TRUE; + if (!(pointer = find_pointerid( pointer_id )) && + (!pointer = allocate_pointerid( pointer_id, pointer_type_from_hw( &msg_data->source ) ))) + return NULL; info = pointer_info_from_msg( msg ); info.ButtonChangeType = compare_button(&pointer->info, &info); + info.pointerType = pointer->type; + pointer->info = info; return TRUE; } @@ -181,9 +185,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/message.c | 11 ++++++++- dlls/win32u/pointer.c | 46 ++++++++++++++++++++---------------- dlls/win32u/win32u_private.h | 2 ++ 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 62115515fb2..037f1e6e7b6 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 ); + update_pointer_id( 1, 0, &info ); + send_message( msg->hwnd, message, wParam, lParam ); + } } /* FIXME: is this really the right place for this hook? */ diff --git a/dlls/win32u/pointer.c b/dlls/win32u/pointer.c index 8fa0b1aeba0..1fa42580ece 100644 --- a/dlls/win32u/pointer.c +++ b/dlls/win32u/pointer.c @@ -95,21 +95,21 @@ static POINT pixel_to_himetric(POINT px) { }; } -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; @@ -157,6 +157,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; +} + /*********************************************************************** * process_pointer_message g* @@ -164,19 +181,8 @@ static POINTER_BUTTON_CHANGE_TYPE compare_button(const POINTER_INFO *old, const */ 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 NULL; - info = pointer_info_from_msg( msg ); - info.ButtonChangeType = compare_button(&pointer->info, &info); - info.pointerType = pointer->type; - - pointer->info = info; + POINTER_INFO info = pointer_info_from_msg( msg->hwnd, msg->message, msg->wParam, msg->lParam, msg->time ); + update_pointer_id( GET_POINTERID_WPARAM( msg->wParam ), pointer_type_from_hw( &msg_data->source ), &info ); return TRUE; } diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index f4bd250f6de..5e11d069f5d 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -146,6 +146,8 @@ extern BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardwar /* pointer.c */ 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 ); /* scroll.c */ extern void draw_nc_scrollbar( HWND hwnd, HDC hdc, BOOL draw_horizontal, BOOL draw_vertical ); -- 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/pointer.c | 42 +++++++++++++++++++++++-- dlls/win32u/tests/win32u.c | 8 ++--- 6 files changed, 140 insertions(+), 38 deletions(-) diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 48b38166b75..81553a3a5b4 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -760,16 +760,20 @@ BOOL WINAPI GetPointerDeviceRects( HANDLE device, RECT *device_rect, RECT *displ 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, @@ -783,9 +787,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 880102e263c..7b9a72a7e81 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 b8939646668..698292c2fbf 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) @ 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/pointer.c b/dlls/win32u/pointer.c index 1fa42580ece..e9c45bdf2cf 100644 --- a/dlls/win32u/pointer.c +++ b/dlls/win32u/pointer.c @@ -211,10 +211,46 @@ BOOL WINAPI NtUserGetPointerType(UINT32 id, POINTER_INPUT_TYPE *type) 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", + 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 ); - RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; + + 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; } /********************************************************************** diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 19c05a97835..3c099454a7f 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
participants (2)
-
Anna (navi) Figueiredo Gomes -
navi (@navi)