From: navi <navi@vlhl.dev> --- dlls/mouhid.sys/main.c | 10 +-- dlls/user32/input.c | 8 ++- dlls/user32/user32.spec | 10 +-- dlls/win32u/input.c | 118 ++++++++++++++++++++++++++++++++++- dlls/win32u/main.c | 26 ++++++++ dlls/win32u/message.c | 2 +- dlls/win32u/win32syscalls.h | 15 ++--- dlls/win32u/win32u.spec | 6 +- dlls/win32u/win32u_private.h | 2 +- dlls/wow64win/user.c | 27 ++++++++ include/ntuser.h | 11 ++++ server/protocol.def | 1 + server/queue.c | 22 +++++-- 13 files changed, 225 insertions(+), 33 deletions(-) diff --git a/dlls/mouhid.sys/main.c b/dlls/mouhid.sys/main.c index 23e731ae674..0d0413deea2 100644 --- a/dlls/mouhid.sys/main.c +++ b/dlls/mouhid.sys/main.c @@ -114,6 +114,7 @@ static NTSTATUS start_device_read( DEVICE_OBJECT *device ) static void add_contact( struct device *impl, struct list *old_contacts, ULONG id, LONG x, LONG y ) { UINT msg, flags = POINTER_MESSAGE_FLAG_INRANGE | POINTER_MESSAGE_FLAG_INCONTACT | POINTER_MESSAGE_FLAG_CONFIDENCE; + enum wine_pointer_flags inject_flags = WINE_POINTER_MAP_COORDS | WINE_POINTER_TIMEOUT; POINTER_TYPE_INFO pointer = { .type = PT_TOUCH }; POINTER_INFO *info = &pointer.pointerInfo; struct contact *contact; @@ -151,14 +152,15 @@ static void add_contact( struct device *impl, struct list *old_contacts, ULONG i info->pointerFlags = flags; info->ptPixelLocation = contact->pos; if (msg == WM_POINTERDOWN) - NtUserMessageCall(0, WM_POINTERENTER, 0, 0, &pointer, NtUserInjectPointer, FALSE); - NtUserMessageCall(0, msg, 0, 0, &pointer, NtUserInjectPointer, FALSE); + NtUserMessageCall(0, WM_POINTERENTER, 0, inject_flags, &pointer, NtUserInjectPointer, FALSE); + NtUserMessageCall(0, msg, 0, inject_flags, &pointer, NtUserInjectPointer, FALSE); list_add_tail( &impl->contacts, &contact->entry ); } static void release_contacts( struct list *contacts ) { + enum wine_pointer_flags inject_flags = WINE_POINTER_MAP_COORDS | WINE_POINTER_TIMEOUT; struct contact *contact, *next; LIST_FOR_EACH_ENTRY_SAFE( contact, next, contacts, struct contact, entry ) @@ -173,8 +175,8 @@ static void release_contacts( struct list *contacts ) info->pointerFlags = flags; info->ptPixelLocation = contact->pos; - NtUserMessageCall(0, WM_POINTERUP, 0, 0, &pointer, NtUserInjectPointer, FALSE); - NtUserMessageCall(0, WM_POINTERLEAVE, 0, 0, &pointer, NtUserInjectPointer, FALSE); + NtUserMessageCall(0, WM_POINTERUP, 0, inject_flags, &pointer, NtUserInjectPointer, FALSE); + NtUserMessageCall(0, WM_POINTERLEAVE, 0, inject_flags, &pointer, NtUserInjectPointer, FALSE); list_remove( &contact->entry ); free( contact ); diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 051f4e48ec9..6b64a0d32ad 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -881,9 +881,11 @@ HWND WINAPI GetTaskmanWindow(void) HSYNTHETICPOINTERDEVICE WINAPI CreateSyntheticPointerDevice(POINTER_INPUT_TYPE type, ULONG max_count, POINTER_FEEDBACK_MODE mode) { - FIXME( "type %ld, max_count %ld, mode %d stub!\n", type, max_count, mode); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return NULL; + HANDLE handle; + + if (!NtUserInitializePointerDeviceInjection( type, max_count, NULL, mode, &handle )) + return NULL; + return (HSYNTHETICPOINTERDEVICE) handle; } /*********************************************************************** diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index 241b40054b8..f6f350333e7 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -399,7 +399,7 @@ @ stdcall DestroyIcon(long) @ stdcall DestroyMenu(long) NtUserDestroyMenu # @ stub DestroyReasons -# @ stub DestroySyntheticPointerDevice +@ stdcall DestroySyntheticPointerDevice(long) NtUserRemoveInjectionDevice @ stdcall DestroyWindow(long) NtUserDestroyWindow @ stdcall DialogBoxIndirectParamA(long ptr long ptr long) @ stdcall DialogBoxIndirectParamAorW(long ptr long ptr long long) @@ -747,15 +747,15 @@ # @ stub InitializeGenericHidInjection # @ stub InitializeInputDeviceInjection # @ stub InitializeLpkHooks -# @ stub InitializePointerDeviceInjection +@ stdcall InitializePointerDeviceInjection(long long long long ptr) NtUserInitializePointerDeviceInjection # @ stub InitializePointerDeviceInjectionEx @ stdcall InitializeTouchInjection(long long) NtUserInitializeTouchInjection # @ stub InjectDeviceInput # @ stub InjectGenericHidInput # @ stub InjectKeyboardInput # @ stub InjectMouseInput -# @ stub InjectPointerInput -# @ stub InjectSyntheticPointerInput +@ stdcall InjectPointerInput(long ptr long) NtUserInjectPointerInput +@ stdcall InjectSyntheticPointerInput(long ptr long) NtUserInjectPointerInput # @ stub InjectTouchInput # @ stub InputSpaceRegionFromPoint @ stdcall InsertMenuA(long long long long ptr) @@ -986,7 +986,7 @@ @ stdcall ReleaseDC(long long) NtUserReleaseDC # @ stub ReleaseDwmHitTestWaiters @ stdcall RemoveClipboardFormatListener(long) NtUserRemoveClipboardFormatListener -# @ stub RemoveInjectionDevice +@ stdcall RemoveInjectionDevice(long) NtUserRemoveInjectionDevice @ stdcall RemoveMenu(long long long) NtUserRemoveMenu @ stdcall RemovePropA(long str) @ stdcall RemovePropW(long wstr) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index a4bd8327894..729420165cb 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -3077,7 +3077,7 @@ void update_pointer_from_msg( POINTER_INPUT_TYPE type, const MSG *msg ) update_pointer( &info ); } -NTSTATUS send_pointer_message( UINT msg, const POINTER_TYPE_INFO *info ) +NTSTATUS send_pointer_message( UINT msg, enum wine_pointer_flags flags, const POINTER_TYPE_INFO *info ) { POINTER_TYPE_INFO pointer = *info; LARGE_INTEGER counter; @@ -3092,6 +3092,7 @@ NTSTATUS send_pointer_message( UINT msg, const POINTER_TYPE_INFO *info ) { req->win = wine_server_user_handle( pointer.pointerInfo.hwndTarget ); req->msg = msg; + req->flags = flags; wine_server_add_data( req, &pointer, sizeof(pointer) ); ret = wine_server_call( req ); } @@ -3244,3 +3245,118 @@ BOOL WINAPI NtUserGetPointerDeviceRects( HANDLE handle, RECT *device_rect, RECT TRACE( "returning device %s, display %s\n", wine_dbgstr_rect(device_rect), wine_dbgstr_rect(display_rect) ); return TRUE; } + +struct syn_pointer +{ + HWND focus; + UINT32 id; + POINTER_TYPE_INFO last; +}; + +BOOL WINAPI NtUserInjectPointerInput( HSYNTHETICPOINTERDEVICE device, const POINTER_TYPE_INFO *pointerInfo, UINT32 count ) +{ + UINT msg = WM_POINTERUPDATE; + struct syn_pointer *pointer; + POINTER_TYPE_INFO type_info; + POINTER_INFO *info; + INT hittest; + HWND hwnd; + + type_info = *pointerInfo; + info = &type_info.pointerInfo; + info->pointerType = type_info.type; + info->pointerFlags &= (POINTER_FLAG_INRANGE | POINTER_FLAG_INCONTACT); + info->pointerFlags |= POINTER_FLAG_UPDATE | POINTER_FLAG_CONFIDENCE; + + switch (type_info.type) + { + case PT_PEN: + type_info.penInfo.penMask = PEN_MASK_PRESSURE | PEN_MASK_ROTATION | PEN_MASK_TILT_X | PEN_MASK_TILT_Y; + break; + default: break; + } + + hwnd = window_from_point( NULL, info->ptPixelLocation, &hittest, TRUE ); + + pointer = get_user_handle_ptr( device, NTUSER_OBJ_POINTER_DEVICE ); + + TRACE( "Injecting pointer input for pointer %d.\n", pointer->id ); + + if (info->pointerFlags & POINTER_FLAG_INCONTACT) + info->pointerFlags |= POINTER_FLAG_FIRSTBUTTON; + + info->pointerId = pointer->id; + info->pointerType = PT_PEN; + info->ptHimetricLocation.x = info->ptPixelLocation.x * HIMETRIC_PER_INCH / system_dpi; + info->ptHimetricLocation.y = info->ptPixelLocation.y * HIMETRIC_PER_INCH / system_dpi; + + info->ptPixelLocationRaw = info->ptPixelLocation; + info->ptHimetricLocationRaw = info->ptHimetricLocation; + info->sourceDevice = device; + info->hwndTarget = hwnd; + + if (!(info->pointerFlags & POINTER_FLAG_INRANGE)) + { + if (pointer->focus) + { + info->hwndTarget = pointer->focus; + send_pointer_message( WM_POINTERUPDATE, 0, &type_info ); + send_pointer_message( WM_POINTERLEAVE, 0, &type_info ); + } + pointer->focus = NULL; + goto out; + } + + if (!pointer->focus) + { + info->pointerId = pointer->id = allocate_pointer_id(); + info->pointerFlags |= POINTER_FLAG_NEW; + } + + if (hwnd != pointer->focus) + { + if (pointer->focus) + send_pointer_message( WM_POINTERLEAVE, 0, &pointer->last ); + send_pointer_message( WM_POINTERENTER, 0, &type_info ); + pointer->focus = hwnd; + } + + if ((info->pointerFlags & POINTER_FLAG_INCONTACT) != (pointer->last.pointerInfo.pointerFlags & POINTER_FLAG_INCONTACT)) + { + info->pointerFlags &= ~POINTER_FLAG_UPDATE; + if (info->pointerFlags & POINTER_FLAG_INCONTACT) + { + info->pointerFlags |= POINTER_FLAG_DOWN; + msg = WM_POINTERDOWN; + } + else + { + info->pointerFlags |= POINTER_FLAG_UP; + msg = WM_POINTERUP; + } + } + + send_pointer_message( msg, 0, &type_info ); + pointer->last = type_info; + +out: + release_user_handle_ptr( pointer ); + return TRUE; +} + +W32KAPI BOOL WINAPI NtUserInitializePointerDeviceInjection( POINTER_INPUT_TYPE type, ULONG contactCount, + HMONITOR monitor, DWORD visualMode, HANDLE* device ) +{ + struct syn_pointer *pointer = calloc( 1, sizeof(*pointer) ); + + TRACE( "%#x, %u, %p, %d, %p\n", type, contactCount, monitor, visualMode, device ); + + *device = alloc_user_handle( pointer, NTUSER_OBJ_POINTER_DEVICE ); + return TRUE; +} + +W32KAPI BOOL WINAPI NtUserRemoveInjectionDevice( HANDLE device ) +{ + free( free_user_handle( device, NTUSER_OBJ_POINTER_DEVICE ) ); + return true; +} diff --git a/dlls/win32u/main.c b/dlls/win32u/main.c index 22e5368b132..d6c60edd900 100644 --- a/dlls/win32u/main.c +++ b/dlls/win32u/main.c @@ -1753,11 +1753,37 @@ BOOL SYSCALL_API NtUserGetPointerType( UINT32 id, POINTER_INPUT_TYPE *type ) SYSCALL_FUNC( NtUserGetPointerType ); } +BOOL SYSCALL_API NtUserGetPointerCursorId( UINT32 id, UINT32 *type ) +{ + SYSCALL_FUNC( NtUserGetPointerCursorId ); +} + +BOOL SYSCALL_API NtUserGetPointerDevices( UINT32 *deviceCount, POINTER_DEVICE_INFO *pointerDevices ) +{ + SYSCALL_FUNC( NtUserGetPointerDevices ); +} + BOOL SYSCALL_API NtUserGetPointerDeviceRects( HANDLE handle, RECT *device_rect, RECT *display_rect ) { SYSCALL_FUNC( NtUserGetPointerDeviceRects ); } +BOOL SYSCALL_API NtUserInitializePointerDeviceInjection( POINTER_INPUT_TYPE type, ULONG contactCount, + HMONITOR monitor, DWORD visualMode, HANDLE* device ) +{ + SYSCALL_FUNC( NtUserInitializePointerDeviceInjection ); +} + +BOOL SYSCALL_API NtUserRemoveInjectionDevice( HANDLE device ) +{ + SYSCALL_FUNC( NtUserRemoveInjectionDevice ); +} + +BOOL SYSCALL_API NtUserInjectPointerInput( HSYNTHETICPOINTERDEVICE device, const POINTER_TYPE_INFO *pointerInfo, UINT32 count ) +{ + SYSCALL_FUNC( NtUserInjectPointerInput ); +} + INT SYSCALL_API NtUserGetPriorityClipboardFormat( UINT *list, INT count ) { SYSCALL_FUNC( NtUserGetPriorityClipboardFormat ); diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 21e15637ede..2b875171956 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -4819,7 +4819,7 @@ LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa return user_driver->pWintabProc( hwnd, msg, wparam, lparam, result_info ); case NtUserInjectPointer: - return send_pointer_message( msg, result_info ); + return send_pointer_message( msg, lparam, result_info ); case NtUserAllocatePointer: *(UINT *)result_info = allocate_pointer_id(); diff --git a/dlls/win32u/win32syscalls.h b/dlls/win32u/win32syscalls.h index 132ac47836b..86f39844c0b 100644 --- a/dlls/win32u/win32syscalls.h +++ b/dlls/win32u/win32syscalls.h @@ -1150,7 +1150,7 @@ SYSCALL_ENTRY( 0x147a, NtUserInitializeClientPfnArrays, 16 ) \ SYSCALL_ENTRY( 0x147b, NtUserInitializeGenericHidInjection, 0 ) \ SYSCALL_ENTRY( 0x147c, NtUserInitializeInputDeviceInjection, 0 ) \ - SYSCALL_ENTRY( 0x147d, NtUserInitializePointerDeviceInjection, 0 ) \ + SYSCALL_ENTRY( 0x147d, NtUserInitializePointerDeviceInjection, 20 ) \ SYSCALL_ENTRY( 0x147e, NtUserInitializePointerDeviceInjectionEx, 0 ) \ SYSCALL_ENTRY( 0x147f, NtUserInitializeTouchInjection, 8 ) \ SYSCALL_ENTRY( 0x1480, NtUserInjectDeviceInput, 0 ) \ @@ -1158,7 +1158,7 @@ SYSCALL_ENTRY( 0x1482, NtUserInjectGesture, 0 ) \ SYSCALL_ENTRY( 0x1483, NtUserInjectKeyboardInput, 0 ) \ SYSCALL_ENTRY( 0x1484, NtUserInjectMouseInput, 0 ) \ - SYSCALL_ENTRY( 0x1485, NtUserInjectPointerInput, 0 ) \ + SYSCALL_ENTRY( 0x1485, NtUserInjectPointerInput, 12 ) \ SYSCALL_ENTRY( 0x1486, NtUserInjectTouchInput, 0 ) \ SYSCALL_ENTRY( 0x1487, NtUserInteractiveControlQueryUsage, 0 ) \ SYSCALL_ENTRY( 0x1488, NtUserInternalGetWindowIcon, 8 ) \ @@ -1309,7 +1309,7 @@ SYSCALL_ENTRY( 0x1519, NtUserRemoteStopScreenUpdates, 0 ) \ SYSCALL_ENTRY( 0x151a, NtUserRemoteThinwireStats, 0 ) \ SYSCALL_ENTRY( 0x151b, NtUserRemoveClipboardFormatListener, 4 ) \ - SYSCALL_ENTRY( 0x151c, NtUserRemoveInjectionDevice, 0 ) \ + SYSCALL_ENTRY( 0x151c, NtUserRemoveInjectionDevice, 4 ) \ SYSCALL_ENTRY( 0x151d, NtUserRemoveMenu, 12 ) \ SYSCALL_ENTRY( 0x151e, NtUserRemoveProp, 8 ) \ SYSCALL_ENTRY( 0x151f, NtUserRemoveQueueCompletion, 0 ) \ @@ -2692,7 +2692,7 @@ SYSCALL_ENTRY( 0x147a, NtUserInitializeClientPfnArrays, 32 ) \ SYSCALL_ENTRY( 0x147b, NtUserInitializeGenericHidInjection, 0 ) \ SYSCALL_ENTRY( 0x147c, NtUserInitializeInputDeviceInjection, 0 ) \ - SYSCALL_ENTRY( 0x147d, NtUserInitializePointerDeviceInjection, 0 ) \ + SYSCALL_ENTRY( 0x147d, NtUserInitializePointerDeviceInjection, 40 ) \ SYSCALL_ENTRY( 0x147e, NtUserInitializePointerDeviceInjectionEx, 0 ) \ SYSCALL_ENTRY( 0x147f, NtUserInitializeTouchInjection, 16 ) \ SYSCALL_ENTRY( 0x1480, NtUserInjectDeviceInput, 0 ) \ @@ -2700,7 +2700,7 @@ SYSCALL_ENTRY( 0x1482, NtUserInjectGesture, 0 ) \ SYSCALL_ENTRY( 0x1483, NtUserInjectKeyboardInput, 0 ) \ SYSCALL_ENTRY( 0x1484, NtUserInjectMouseInput, 0 ) \ - SYSCALL_ENTRY( 0x1485, NtUserInjectPointerInput, 0 ) \ + SYSCALL_ENTRY( 0x1485, NtUserInjectPointerInput, 24 ) \ SYSCALL_ENTRY( 0x1486, NtUserInjectTouchInput, 0 ) \ SYSCALL_ENTRY( 0x1487, NtUserInteractiveControlQueryUsage, 0 ) \ SYSCALL_ENTRY( 0x1488, NtUserInternalGetWindowIcon, 16 ) \ @@ -2851,7 +2851,7 @@ SYSCALL_ENTRY( 0x1519, NtUserRemoteStopScreenUpdates, 0 ) \ SYSCALL_ENTRY( 0x151a, NtUserRemoteThinwireStats, 0 ) \ SYSCALL_ENTRY( 0x151b, NtUserRemoveClipboardFormatListener, 8 ) \ - SYSCALL_ENTRY( 0x151c, NtUserRemoveInjectionDevice, 0 ) \ + SYSCALL_ENTRY( 0x151c, NtUserRemoveInjectionDevice, 8 ) \ SYSCALL_ENTRY( 0x151d, NtUserRemoveMenu, 24 ) \ SYSCALL_ENTRY( 0x151e, NtUserRemoveProp, 16 ) \ SYSCALL_ENTRY( 0x151f, NtUserRemoveQueueCompletion, 0 ) \ @@ -3882,14 +3882,12 @@ SYSCALL_STUB( NtUserInitialize ) \ SYSCALL_STUB( NtUserInitializeGenericHidInjection ) \ SYSCALL_STUB( NtUserInitializeInputDeviceInjection ) \ - SYSCALL_STUB( NtUserInitializePointerDeviceInjection ) \ SYSCALL_STUB( NtUserInitializePointerDeviceInjectionEx ) \ SYSCALL_STUB( NtUserInjectDeviceInput ) \ SYSCALL_STUB( NtUserInjectGenericHidInput ) \ SYSCALL_STUB( NtUserInjectGesture ) \ SYSCALL_STUB( NtUserInjectKeyboardInput ) \ SYSCALL_STUB( NtUserInjectMouseInput ) \ - SYSCALL_STUB( NtUserInjectPointerInput ) \ SYSCALL_STUB( NtUserInjectTouchInput ) \ SYSCALL_STUB( NtUserInteractiveControlQueryUsage ) \ SYSCALL_STUB( NtUserInternalStartMoveSize ) \ @@ -3996,7 +3994,6 @@ SYSCALL_STUB( NtUserRemoteShadowStop ) \ SYSCALL_STUB( NtUserRemoteStopScreenUpdates ) \ SYSCALL_STUB( NtUserRemoteThinwireStats ) \ - SYSCALL_STUB( NtUserRemoveInjectionDevice ) \ SYSCALL_STUB( NtUserRemoveQueueCompletion ) \ SYSCALL_STUB( NtUserRemoveVisualIdentifier ) \ SYSCALL_STUB( NtUserReportInertia ) \ diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 2c409010cd2..e89f55d2d80 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1148,7 +1148,7 @@ @ stdcall -syscall NtUserInitializeClientPfnArrays(ptr ptr ptr ptr) @ stub -syscall NtUserInitializeGenericHidInjection @ stub -syscall NtUserInitializeInputDeviceInjection -@ stub -syscall NtUserInitializePointerDeviceInjection +@ stdcall -syscall NtUserInitializePointerDeviceInjection(long long long long ptr) @ stub -syscall NtUserInitializePointerDeviceInjectionEx @ stdcall -syscall NtUserInitializeTouchInjection(long long) @ stub -syscall NtUserInjectDeviceInput @@ -1156,7 +1156,7 @@ @ stub -syscall NtUserInjectGesture @ stub -syscall NtUserInjectKeyboardInput @ stub -syscall NtUserInjectMouseInput -@ stub -syscall NtUserInjectPointerInput +@ stdcall -syscall NtUserInjectPointerInput(long ptr long) @ stub -syscall NtUserInjectTouchInput @ stub -syscall NtUserInteractiveControlQueryUsage @ stdcall -syscall NtUserInternalGetWindowIcon(ptr long) @@ -1307,7 +1307,7 @@ @ stub -syscall NtUserRemoteStopScreenUpdates @ stub -syscall NtUserRemoteThinwireStats @ stdcall -syscall NtUserRemoveClipboardFormatListener(long) -@ stub -syscall NtUserRemoveInjectionDevice +@ stdcall -syscall NtUserRemoveInjectionDevice(long) @ stdcall -syscall NtUserRemoveMenu(long long long) @ stdcall -syscall NtUserRemoveProp(long wstr) @ stub -syscall NtUserRemoveQueueCompletion diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index c6288a3c2f9..4c129fd44d9 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -113,7 +113,7 @@ 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 ); -extern NTSTATUS send_pointer_message( UINT msg, const POINTER_TYPE_INFO *info ); +NTSTATUS send_pointer_message( UINT msg, enum wine_pointer_flags flags, const POINTER_TYPE_INFO *info ); extern UINT allocate_pointer_id( void ); extern void update_pointer_from_msg( POINTER_INPUT_TYPE type, const MSG *msg ); extern NTSTATUS send_hardware_input( HWND hwnd, UINT flags, const INPUT *input, LPARAM lparam ); diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 4cf6b3d6dc8..719fa0783a2 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -2981,6 +2981,33 @@ NTSTATUS WINAPI wow64_NtUserGetPointerDeviceRects( UINT *args ) return NtUserGetPointerDeviceRects( device, device_rect, display_rect ); } +NTSTATUS WINAPI wow64_NtUserInitializePointerDeviceInjection( UINT *args ) +{ + POINTER_INPUT_TYPE type = get_ulong( &args ); + ULONG contactCount = get_ulong( &args ); + HMONITOR monitor = get_handle( &args ); + DWORD visualMode = get_ulong( &args ); + HANDLE* device = get_ptr( &args ); + + return NtUserInitializePointerDeviceInjection( type, contactCount, monitor, visualMode, device ); +} + +NTSTATUS WINAPI wow64_NtUserRemoveInjectionDevice( UINT *args ) +{ + HANDLE device = get_handle( &args ); + + return NtUserRemoveInjectionDevice( device ); +} + +NTSTATUS WINAPI wow64_NtUserInjectPointerInput( UINT *args ) +{ + HSYNTHETICPOINTERDEVICE handle = get_handle( &args ); + const POINTER_TYPE_INFO *pointerInfo = get_ptr( &args ); + UINT32 count = get_ulong( &args ); + + return NtUserInjectPointerInput( handle, pointerInfo, count ); +} + NTSTATUS WINAPI wow64_NtUserGetPriorityClipboardFormat( UINT *args ) { UINT *list = get_ptr( &args ); diff --git a/include/ntuser.h b/include/ntuser.h index f3c16befbbb..e7fb3a6bccf 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -476,6 +476,7 @@ struct post_dde_message_call_params #define NTUSER_OBJ_ACCEL 0x08 #define NTUSER_OBJ_HOOK 0x0f #define NTUSER_OBJ_IMC 0x11 +#define NTUSER_OBJ_POINTER_DEVICE 0x12 /* NtUserScrollWindowEx flag */ #define SW_NODCCACHE 0x8000 @@ -699,6 +700,12 @@ enum wine_drag_drop_call WINE_DRAG_DROP_POST, }; +enum wine_pointer_flags +{ + WINE_POINTER_MAP_COORDS = 0x1, + WINE_POINTER_TIMEOUT = 0x2, +}; + struct ntuser_property_list { UINT64 data; @@ -885,6 +892,10 @@ W32KAPI BOOL WINAPI NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE t 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 *device_rect, RECT *display_rect ); +W32KAPI BOOL WINAPI NtUserInitializePointerDeviceInjection( POINTER_INPUT_TYPE type, ULONG contactCount, + HMONITOR monitor, DWORD visualMode, HANDLE* device ); +W32KAPI BOOL WINAPI NtUserRemoveInjectionDevice( HANDLE device ); +W32KAPI BOOL WINAPI NtUserInjectPointerInput( HSYNTHETICPOINTERDEVICE handle, const POINTER_TYPE_INFO *pointerInfo, UINT32 count ); W32KAPI INT WINAPI NtUserGetPriorityClipboardFormat( UINT *list, INT count ); W32KAPI BOOL WINAPI NtUserGetProcessDefaultLayout( ULONG *layout ); W32KAPI ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process ); diff --git a/server/protocol.def b/server/protocol.def index a20b7058e67..d647183b62e 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2438,6 +2438,7 @@ enum message_type @REQ(send_pointer_message) user_handle_t win; unsigned int msg; + unsigned int flags; VARARG(data,bytes); @END diff --git a/server/queue.c b/server/queue.c index d150a9cdb04..04157b6e605 100644 --- a/server/queue.c +++ b/server/queue.c @@ -2462,7 +2462,7 @@ struct pointer struct timeout_user *timeout; struct desktop *desktop; user_handle_t win; - int primary; + int primary, do_timeout; POINTER_TYPE_INFO info; }; @@ -2487,14 +2487,12 @@ static void queue_pointer_message( UINT message, struct pointer *pointer, int re struct hardware_msg_data *msg_data; timeout_t time = get_tick_count(); user_handle_t win = pointer->win; - struct rectangle top_rect; unsigned int wparam; struct message *msg; int x, y; - get_virtual_screen_rect( desktop, &top_rect, 0 ); - x = info->ptPixelLocation.x * (top_rect.right - top_rect.left) / 65535; - y = info->ptPixelLocation.y * (top_rect.bottom - top_rect.top) / 65535; + x = info->ptPixelLocation.x; + y = info->ptPixelLocation.y; if (pointer->primary) info->pointerFlags |= POINTER_FLAG_PRIMARY; info->pointerType = pointer->info.type; @@ -2533,7 +2531,8 @@ static void queue_pointer_message( UINT message, struct pointer *pointer, int re if (message != WM_POINTERLEAVE) { - pointer->timeout = add_timeout_user( -160000, pointer_message_timeout, pointer ); + if (pointer->do_timeout) + pointer->timeout = add_timeout_user( -160000, pointer_message_timeout, pointer ); info->pointerFlags &= ~POINTER_FLAG_NEW; } else @@ -3246,6 +3245,17 @@ DECL_HANDLER(send_pointer_message) if (pointer->timeout) remove_timeout_user( pointer->timeout ); pointer->info = *info; pointer->win = req->win; + pointer->do_timeout = !!(req->flags & WINE_POINTER_TIMEOUT); + + if (req->flags & WINE_POINTER_MAP_COORDS) + { + POINT *pt = &pointer->info.pointerInfo.ptPixelLocation; + struct rectangle top_rect; + + get_virtual_screen_rect( desktop, &top_rect, 0 ); + pt->x = pt->x * (top_rect.right - top_rect.left) / 65535; + pt->y = pt->y * (top_rect.bottom - top_rect.top) / 65535; + } queue_pointer_message( req->msg, pointer, 0 ); return; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11693