[PATCH v2 0/5] MR11286: win32u: Implement GetPointerType
Supersedes https://gitlab.winehq.org/wine/wine/-/merge_requests/11171 with misc stylistic fixups. More importantly I've changed some `get_system_dpi()` calls into directly accessing the system_dpi global, to avoid having to change the thread DPI awareness context. I've also included a change to `NtUserGetPointerDeviceRects` to do the same thing, as I broke it when I removed the thread awareness context swap in https://gitlab.winehq.org/wine/wine/-/merge_requests/11166. -- v2: 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. https://gitlab.winehq.org/wine/wine/-/merge_requests/11286
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 77bf7f2efa3..bf6f7f41466 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2879,6 +2879,17 @@ INT WINAPI NtUserScheduleDispatchNotification( HWND hwnd ) return 0; } +/*********************************************************************** + * process_pointer_message + * + * 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; +} + /********************************************************************** * NtUserInitializeTouchInjection (win32u.@) */ diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 78a4821f573..bceb450eb6b 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2474,17 +2474,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 bc70d8b4bd1..9011f5e352a 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -111,6 +111,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, UINT *mapped ); +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/11286
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/input.c | 118 ++++++++++++++++++++++++++++++++++- dlls/win32u/ntuser_private.h | 1 + dlls/win32u/syscall.c | 1 + dlls/win32u/sysparams.c | 3 +- dlls/win32u/win32u_private.h | 2 + 5 files changed, 122 insertions(+), 3 deletions(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index bf6f7f41466..e91203b4ef9 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -407,6 +407,14 @@ 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; +}; BOOL grab_pointer = TRUE; BOOL grab_fullscreen = FALSE; @@ -2879,6 +2887,104 @@ INT WINAPI NtUserScheduleDispatchNotification( HWND hwnd ) return 0; } +void destroy_thread_pointers(void) +{ + struct user_thread_info *thread_info = get_user_thread_info(); + struct pointer *pointer, *next; + + LIST_FOR_EACH_ENTRY_SAFE( pointer, next, &thread_info->known_pointers, struct pointer, entry ) + { + list_remove( &pointer->entry ); + free( pointer ); + } +} + +static struct pointer *pointer_create( UINT32 id ) +{ + struct user_thread_info *thread_info = get_user_thread_info(); + struct pointer *pointer; + + TRACE( "allocating pointer id %d\n", id ); + + if (!(pointer = calloc( 1, sizeof(*pointer) ))) return NULL; + pointer->id = id; + list_add_tail( &thread_info->known_pointers, &pointer->entry ); + + return pointer; +} + +static struct pointer *find_pointer( UINT32 id ) +{ + struct user_thread_info *thread_info = get_user_thread_info(); + struct pointer *pointer; + + TRACE( "looking for pointer id %d\n", id ); + + LIST_FOR_EACH_ENTRY( pointer, &thread_info->known_pointers, struct pointer, entry ) + if (pointer->id == id) return pointer; + + WARN( "failed to find pointer with id %d\n", id ); + return NULL; +} + +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.x = location.x * HIMETRIC_PER_INCH / system_dpi; + info.ptHimetricLocation.y = location.y * HIMETRIC_PER_INCH / system_dpi; + info.ptHimetricLocationRaw = info.ptHimetricLocation; + + 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 }, + }; + POINTER_FLAGS down = ~old->pointerFlags & new->pointerFlags, up = old->pointerFlags & ~new->pointerFlags; + + for (size_t i = 0; i < ARRAY_SIZE(map); i++) + { + if (down & map[i].flag) change |= map[i].down; + if (up & map[i].flag) change |= map[i].up; + } + return change; +} + /*********************************************************************** * process_pointer_message * @@ -2886,7 +2992,15 @@ INT WINAPI NtUserScheduleDispatchNotification( HWND hwnd ) */ BOOL process_pointer_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ) { + UINT 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_pointer( id )) && !(pointer = pointer_create( id ))) return TRUE; + info = pointer_info_from_msg( msg ); + info.ButtonChangeType = compare_button( &pointer->info, &info ); + pointer->info = info; return TRUE; } @@ -2924,8 +3038,8 @@ BOOL WINAPI NtUserGetPointerDeviceRects( HANDLE handle, RECT *device_rect, RECT } rect = get_virtual_screen_rect( 0, MDT_DEFAULT ); - SetRect( device_rect, 0, 0, (rect.right - rect.left) * HIMETRIC_PER_INCH / get_system_dpi(), - (rect.bottom - rect.top) * HIMETRIC_PER_INCH / get_system_dpi() ); + SetRect( device_rect, 0, 0, (rect.right - rect.left) * HIMETRIC_PER_INCH / system_dpi, + (rect.bottom - rect.top) * HIMETRIC_PER_INCH / system_dpi ); *display_rect = get_virtual_screen_rect( get_thread_dpi(), MDT_DEFAULT ); TRACE( "returning device %s, display %s\n", wine_dbgstr_rect(device_rect), wine_dbgstr_rect(display_rect) ); diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index dc14811ce86..8b5a17bef98 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -128,6 +128,7 @@ struct user_thread_info struct session_thread_data *session_data; /* shared session thread data */ struct mouse_tracking_info *mouse_tracking_info; /* NtUserTrackMouseEvent handling */ struct opengl_thread_data *opengl_data; /* OpenGL private thread data */ + struct list known_pointers; /* list of known pointers */ }; extern struct user_thread_info *get_user_thread_info(void); diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index e9f36bdd32b..ca1be7227ca 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -197,6 +197,7 @@ struct user_thread_info *get_user_thread_info(void) info = calloc( 1, sizeof(*info) ); pthread_setspecific( user_thread_info_key, info ); + list_init( &info->known_pointers ); if (teb) { diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 239d13df6cc..0c649c1a286 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -292,7 +292,7 @@ union sysparam_all_entry struct sysparam_pref_entry pref; }; -static UINT system_dpi; +UINT system_dpi; static RECT work_area; static DWORD process_layout = ~0u; @@ -7462,6 +7462,7 @@ static void thread_detach(void) struct user_thread_info *thread_info = get_user_thread_info(); destroy_thread_windows(); + destroy_thread_pointers(); user_driver->pThreadDetach(); free( thread_info->rawinput ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 9011f5e352a..c76bee2dcab 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -111,6 +111,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, UINT *mapped ); +extern void destroy_thread_pointers(void); extern BOOL process_pointer_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ); /* menu.c */ @@ -156,6 +157,7 @@ extern void set_standard_scroll_painted( HWND hwnd, int bar, BOOL painted ); extern void track_scroll_bar( HWND hwnd, int scrollbar, POINT pt ); /* sysparams.c */ +extern UINT system_dpi; extern BOOL decorated_mode; extern UINT64 thunk_lock_callback; extern HBRUSH get_55aa_brush(void); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11286
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> Seems like pointerId 1 is always the mouse, regardless of EnableMouseInPointer. --- dlls/win32u/input.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index e91203b4ef9..2248373c307 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2923,6 +2923,9 @@ static struct pointer *find_pointer( UINT32 id ) LIST_FOR_EACH_ENTRY( pointer, &thread_info->known_pointers, struct pointer, entry ) if (pointer->id == id) return pointer; + /* allocate a pointer for the mouse if we don't have one yet */ + if (id == 1) return pointer_create( id ); + WARN( "failed to find pointer with id %d\n", id ); return NULL; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11286
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/input.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 2248373c307..7414fbf0659 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; }; @@ -2899,15 +2900,16 @@ void destroy_thread_pointers(void) } } -static struct pointer *pointer_create( UINT32 id ) +static struct pointer *pointer_create( UINT32 id, POINTER_INPUT_TYPE type ) { struct user_thread_info *thread_info = get_user_thread_info(); struct pointer *pointer; - TRACE( "allocating pointer id %d\n", id ); + TRACE( "allocating pointer id %d, type %#x\n", id, type ); if (!(pointer = calloc( 1, sizeof(*pointer) ))) return NULL; pointer->id = id; + pointer->type = type; list_add_tail( &thread_info->known_pointers, &pointer->entry ); return pointer; @@ -2924,7 +2926,7 @@ static struct pointer *find_pointer( UINT32 id ) if (pointer->id == id) return pointer; /* allocate a pointer for the mouse if we don't have one yet */ - if (id == 1) return pointer_create( id ); + if (id == 1) return pointer_create( id, PT_MOUSE ); WARN( "failed to find pointer with id %d\n", id ); return NULL; @@ -2988,6 +2990,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: return PT_TOUCH; + case IMDT_TOUCHPAD: return PT_TOUCHPAD; + default: return PT_POINTER; + } +} + /*********************************************************************** * process_pointer_message * @@ -2995,15 +3009,17 @@ 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 ) { + POINTER_INPUT_TYPE type = pointer_type_from_hw( &msg_data->source ); UINT 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_pointer( id )) && !(pointer = pointer_create( id ))) return TRUE; + if (!(pointer = find_pointer( id )) && !(pointer = pointer_create( id, type ))) 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/11286
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/dinput/tests/device8.c | 22 ++++++++++++++++++++++ dlls/user32/misc.c | 17 ----------------- dlls/user32/tests/input.c | 2 -- dlls/user32/user32.spec | 2 +- dlls/win32u/input.c | 15 ++++++++++++--- 5 files changed, 35 insertions(+), 23 deletions(-) diff --git a/dlls/dinput/tests/device8.c b/dlls/dinput/tests/device8.c index e1a96558ad5..ab26b18fb5d 100644 --- a/dlls/dinput/tests/device8.c +++ b/dlls/dinput/tests/device8.c @@ -1937,6 +1937,7 @@ static void test_hid_touch_screen(void) RAWINPUTDEVICE rawdevice = {.usUsagePage = HID_USAGE_PAGE_DIGITIZER, .usUsage = HID_USAGE_DIGITIZER_TOUCH_SCREEN}; UINT rawbuffer_count, rawbuffer_size, expect_flags, id, width, height; WCHAR device_path[MAX_PATH]; + POINTER_INPUT_TYPE type; char rawbuffer[1024]; RAWINPUT *rawinput; HANDLE file; @@ -2022,6 +2023,9 @@ static void test_hid_touch_screen(void) todo_wine /* missing POINTER_MESSAGE_FLAG_FIRSTBUTTON */ ok( HIWORD( pointer_wparam[0] ) == expect_flags, "got wparam %#Ix\n", pointer_wparam[0] ); ok( LOWORD( pointer_wparam[0] ) > 0, "got wparam %#Ix\n", pointer_wparam[0] ); + ret = GetPointerType( LOWORD( pointer_wparam[0] ), &type ); + ok( ret, "GetPointerType failed, error %lu\n", GetLastError() ); + ok( type == PT_TOUCH, "got pointer type %#lx\n", type ); ok( LOWORD( pointer_lparam[0] ) * 128 / width == 0x08, "got lparam %#Ix\n", pointer_lparam[0] ); ok( HIWORD( pointer_lparam[0] ) * 128 / height == 0x10, "got lparam %#Ix\n", pointer_lparam[0] ); id = LOWORD( pointer_wparam[0] ); @@ -2165,6 +2169,9 @@ static void test_hid_touch_screen(void) todo_wine /* missing POINTER_MESSAGE_FLAG_FIRSTBUTTON */ ok( HIWORD( pointer_wparam[0] ) == expect_flags, "got wparam %#Ix\n", pointer_wparam[0] ); ok( LOWORD( pointer_wparam[0] ) > 0, "got wparam %#Ix\n", pointer_wparam[0] ); + ret = GetPointerType( LOWORD( pointer_wparam[0] ), &type ); + ok( ret, "GetPointerType failed, error %lu\n", GetLastError() ); + ok( type == PT_TOUCH, "got pointer type %#lx\n", type ); ok( LOWORD( pointer_lparam[0] ) * 128 / width == 0x08, "got lparam %#Ix\n", pointer_lparam[0] ); ok( HIWORD( pointer_lparam[0] ) * 128 / height == 0x10, "got lparam %#Ix\n", pointer_lparam[0] ); ok( pointer_wparam[1] == 0, "got wparam %#Ix\n", pointer_wparam[1] ); @@ -2189,6 +2196,9 @@ static void test_hid_touch_screen(void) broken(HIWORD( pointer_wparam[0] ) == (expect_flags & ~POINTER_MESSAGE_FLAG_CONFIDENCE)), /* Win8 32bit */ "got wparam %#Ix\n", pointer_wparam[0] ); ok( LOWORD( pointer_wparam[0] ) == id, "got wparam %#Ix\n", pointer_wparam[0] ); + ret = GetPointerType( LOWORD( pointer_wparam[0] ), &type ); + ok( ret, "GetPointerType failed, error %lu\n", GetLastError() ); + ok( type == PT_TOUCH, "got pointer type %#lx\n", type ); ok( LOWORD( pointer_lparam[0] ) * 128 / width == 0x08, "got lparam %#Ix\n", pointer_lparam[0] ); ok( HIWORD( pointer_lparam[0] ) * 128 / height == 0x10, "got lparam %#Ix\n", pointer_lparam[0] ); ok( pointer_wparam[1] == 0, "got wparam %#Ix\n", pointer_wparam[1] ); @@ -2215,6 +2225,9 @@ static void test_hid_touch_screen(void) todo_wine /* missing POINTER_MESSAGE_FLAG_FIRSTBUTTON */ ok( HIWORD( pointer_wparam[0] ) == expect_flags, "got wparam %#Ix\n", pointer_wparam[0] ); ok( LOWORD( pointer_wparam[0] ) > 0, "got wparam %#Ix\n", pointer_wparam[0] ); + ret = GetPointerType( LOWORD( pointer_wparam[0] ), &type ); + ok( ret, "GetPointerType failed, error %lu\n", GetLastError() ); + ok( type == PT_TOUCH, "got pointer type %#lx\n", type ); ok( LOWORD( pointer_lparam[0] ) * 128 / width == 0x08, "got lparam %#Ix\n", pointer_lparam[0] ); ok( HIWORD( pointer_lparam[0] ) * 128 / height == 0x10, "got lparam %#Ix\n", pointer_lparam[0] ); id = LOWORD( pointer_wparam[0] ); @@ -2226,6 +2239,9 @@ static void test_hid_touch_screen(void) broken(HIWORD( pointer_wparam[1] ) == (expect_flags & ~POINTER_MESSAGE_FLAG_CONFIDENCE)), /* Win8 32bit */ "got wparam %#Ix\n", pointer_wparam[1] ); ok( LOWORD( pointer_wparam[1] ) == id + 1, "got wparam %#Ix\n", pointer_wparam[1] ); + ret = GetPointerType( LOWORD( pointer_wparam[1] ), &type ); + ok( ret, "GetPointerType failed, error %lu\n", GetLastError() ); + ok( type == PT_TOUCH, "got pointer type %#lx\n", type ); ok( LOWORD( pointer_lparam[1] ) * 128 / width == 0x18, "got lparam %#Ix\n", pointer_lparam[1] ); ok( HIWORD( pointer_lparam[1] ) * 128 / height == 0x20, "got lparam %#Ix\n", pointer_lparam[1] ); @@ -2249,6 +2265,9 @@ static void test_hid_touch_screen(void) broken(HIWORD( pointer_wparam[0] ) == (expect_flags & ~POINTER_MESSAGE_FLAG_CONFIDENCE)), /* Win8 32bit */ "got wparam %#Ix\n", pointer_wparam[0] ); ok( LOWORD( pointer_wparam[0] ) == id, "got wparam %#Ix\n", pointer_wparam[0] ); + ret = GetPointerType( LOWORD( pointer_wparam[0] ), &type ); + ok( ret, "GetPointerType failed, error %lu\n", GetLastError() ); + ok( type == PT_TOUCH, "got pointer type %#lx\n", type ); ok( LOWORD( pointer_lparam[0] ) * 128 / width == 0x08, "got lparam %#Ix\n", pointer_lparam[0] ); ok( HIWORD( pointer_lparam[0] ) * 128 / height == 0x10, "got lparam %#Ix\n", pointer_lparam[0] ); @@ -2257,6 +2276,9 @@ static void test_hid_touch_screen(void) broken(HIWORD( pointer_wparam[1] ) == (expect_flags & ~POINTER_MESSAGE_FLAG_CONFIDENCE)), /* Win8 32bit */ "got wparam %#Ix\n", pointer_wparam[1] ); ok( LOWORD( pointer_wparam[1] ) == id + 1, "got wparam %#Ix\n", pointer_wparam[1] ); + ret = GetPointerType( LOWORD( pointer_wparam[1] ), &type ); + ok( ret, "GetPointerType failed, error %lu\n", GetLastError() ); + ok( type == PT_TOUCH, "got pointer type %#lx\n", type ); ok( LOWORD( pointer_lparam[1] ) * 128 / width == 0x18, "got lparam %#Ix\n", pointer_lparam[1] ); ok( HIWORD( pointer_lparam[1] ) * 128 / height == 0x20, "got lparam %#Ix\n", pointer_lparam[1] ); diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c index 5e26601d234..cc348eb1dd5 100644 --- a/dlls/user32/misc.c +++ b/dlls/user32/misc.c @@ -516,23 +516,6 @@ LRESULT WINAPI PackTouchHitTestingProximityEvaluation(const TOUCH_HIT_TESTING_IN return 0; } -/********************************************************************** - * GetPointerType [USER32.@] - */ -BOOL WINAPI GetPointerType(UINT32 id, POINTER_INPUT_TYPE *type) -{ - FIXME("(%d %p): stub\n", id, type); - - if(!id || !type) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - *type = PT_MOUSE; - return TRUE; -} - BOOL WINAPI GetPointerInfo(UINT32 id, POINTER_INFO *info) { FIXME("(%d %p): stub\n", id, info); diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 922e300c1fd..e5810400ac8 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -5754,9 +5754,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/user32/user32.spec b/dlls/user32/user32.spec index e6033186490..e0bb89a0a2e 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -646,7 +646,7 @@ # @ stub GetPointerPenInfoHistory @ stdcall GetPointerTouchInfo(long ptr) @ stdcall GetPointerTouchInfoHistory(long ptr ptr) -@ stdcall GetPointerType(long ptr) +@ stdcall GetPointerType(long ptr) NtUserGetPointerType @ stdcall GetPriorityClipboardFormat(ptr long) NtUserGetPriorityClipboardFormat @ stdcall GetProcessDefaultLayout(ptr) @ stdcall GetProcessDpiAwarenessInternal(long ptr) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 7414fbf0659..2db0efb06dc 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -3037,9 +3037,18 @@ BOOL WINAPI NtUserInitializeTouchInjection( UINT max_count, UINT mode ) */ BOOL WINAPI NtUserGetPointerType( UINT32 id, POINTER_INPUT_TYPE *type ) { - FIXME( "id %u, type %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_pointer( id ))) + { + RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + *type = pointer->type; + return TRUE; } /********************************************************************** -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11286
Right sorry, done. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11286#note_144798
participants (2)
-
Anna (navi) Figueiredo Gomes -
Rémi Bernon (@rbernon)