[PATCH v2 3/3] user32: Introduce WINEINPUT type for internal SendInput.

Rémi Bernon rbernon at codeweavers.com
Tue Mar 9 12:39:32 CST 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/user32/input.c        | 21 +++++++++++++++------
 dlls/user32/message.c      | 15 ++++++++++++---
 dlls/user32/user_private.h |  2 +-
 include/winuser.h          | 10 ++++++++++
 4 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 03d853d2f48..ac276ec1462 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -121,7 +121,10 @@ BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret )
  */
 BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input )
 {
-    NTSTATUS status = send_hardware_message( hwnd, input, 0 );
+    NTSTATUS status;
+    INPUT tmp = *input;
+    tmp.type |= INPUT_WINE;
+    status = send_hardware_message( hwnd, &tmp );
     if (status) SetLastError( RtlNtStatusToDosError(status) );
     return !status;
 }
@@ -179,11 +182,13 @@ static void update_mouse_coords( INPUT *input )
  */
 UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
 {
+    WINEINPUT tmp;
     NTSTATUS status = STATUS_SUCCESS;
-    INPUT tmp;
+    BOOL internal;
     UINT i;
 
-    if (size != sizeof(INPUT))
+    internal = count && inputs && inputs[0].type & INPUT_WINE;
+    if (size != (internal ? sizeof(WINEINPUT) : sizeof(INPUT)))
     {
         SetLastError( ERROR_INVALID_PARAMETER );
         return 0;
@@ -204,15 +209,19 @@ UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
     for (i = 0; i < count; i++)
     {
         memcpy( &tmp, (char *)inputs + i * size, size );
+        if (!(tmp.input.type & INPUT_WINE)) tmp.hwnd = 0;
 
-        switch (tmp.type)
+        switch (tmp.input.type)
         {
         case INPUT_MOUSE:
+        case INPUT_MOUSE|INPUT_WINE:
             /* we need to update the coordinates to what the server expects */
-            update_mouse_coords( &tmp );
+            update_mouse_coords( &tmp.input );
             /* fallthrough */
         case INPUT_KEYBOARD:
-            status = send_hardware_message( 0, &tmp, SEND_HWMSG_INJECTED );
+        case INPUT_KEYBOARD|INPUT_WINE:
+        case INPUT_HARDWARE|INPUT_WINE:
+            status = send_hardware_message( tmp.hwnd, &tmp.input );
             break;
 #ifdef _WIN64
         case INPUT_HARDWARE:
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index def59998a52..ec8513a1903 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -3227,7 +3227,7 @@ static BOOL send_message( struct send_message_info *info, DWORD_PTR *res_ptr, BO
 /***********************************************************************
  *		send_hardware_message
  */
-NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
+NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input )
 {
     struct user_key_state_info *key_state_info = get_user_thread_info()->key_state;
     struct send_message_info info;
@@ -3245,11 +3245,14 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
     SERVER_START_REQ( send_hardware_message )
     {
         req->win        = wine_server_user_handle( hwnd );
-        req->flags      = flags;
+        req->flags      = 0;
         req->input.type = input->type;
         switch (input->type)
         {
         case INPUT_MOUSE:
+            req->flags = SEND_HWMSG_INJECTED;
+            /* fallthrough */
+        case INPUT_MOUSE|INPUT_WINE:
             req->input.mouse.x     = input->u.mi.dx;
             req->input.mouse.y     = input->u.mi.dy;
             req->input.mouse.data  = input->u.mi.mouseData;
@@ -3258,6 +3261,9 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
             req->input.mouse.info  = input->u.mi.dwExtraInfo;
             break;
         case INPUT_KEYBOARD:
+            req->flags = SEND_HWMSG_INJECTED;
+            /* fallthrough */
+        case INPUT_KEYBOARD|INPUT_WINE:
             req->input.kbd.vkey  = input->u.ki.wVk;
             req->input.kbd.scan  = input->u.ki.wScan;
             req->input.kbd.flags = input->u.ki.dwFlags;
@@ -3265,6 +3271,9 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
             req->input.kbd.info  = input->u.ki.dwExtraInfo;
             break;
         case INPUT_HARDWARE:
+            req->flags = SEND_HWMSG_INJECTED;
+            /* fallthrough */
+        case INPUT_HARDWARE|INPUT_WINE:
             req->input.hw.msg    = input->u.hi.uMsg;
             req->input.hw.lparam = MAKELONG( input->u.hi.wParamL, input->u.hi.wParamH );
             break;
@@ -3287,7 +3296,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
             key_state_info->time    = GetTickCount();
             key_state_info->counter = counter;
         }
-        if ((flags & SEND_HWMSG_INJECTED) && (prev_x != new_x || prev_y != new_y))
+        if (!(input->type & INPUT_WINE) && (prev_x != new_x || prev_y != new_y))
             USER_Driver->pSetCursorPos( new_x, new_y );
     }
 
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 7761a1ceb4f..2425d14e43b 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -263,7 +263,7 @@ extern RECT get_virtual_screen_rect(void) DECLSPEC_HIDDEN;
 extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN;
 extern DWORD get_input_codepage( void ) DECLSPEC_HIDDEN;
 extern BOOL map_wparam_AtoW( UINT message, WPARAM *wparam, enum wm_char_mapping mapping ) DECLSPEC_HIDDEN;
-extern NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags ) DECLSPEC_HIDDEN;
+extern NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input ) DECLSPEC_HIDDEN;
 extern LRESULT MSG_SendInternalMessageTimeout( DWORD dest_pid, DWORD dest_tid,
                                                UINT msg, WPARAM wparam, LPARAM lparam,
                                                UINT flags, UINT timeout, PDWORD_PTR res_ptr ) DECLSPEC_HIDDEN;
diff --git a/include/winuser.h b/include/winuser.h
index 53661f6c788..2072f047165 100644
--- a/include/winuser.h
+++ b/include/winuser.h
@@ -477,6 +477,16 @@ typedef struct tagINPUT
     } DUMMYUNIONNAME;
 } INPUT, *PINPUT, *LPINPUT;
 
+#ifdef __WINESRC__
+/* extension to send hardware input from drivers */
+#define INPUT_WINE      0x80000000
+typedef struct
+{
+    INPUT input;
+    HWND hwnd;
+} WINEINPUT;
+#endif /* __WINESRC__ */
+
 DECLARE_HANDLE(HRAWINPUT);
 
 typedef struct tagRAWINPUTDEVICELIST
-- 
2.30.0




More information about the wine-devel mailing list