Signed-off-by: Rémi Bernon rbernon@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