Module: wine Branch: master Commit: ae895a1f100682fdee679bad1b5cadda8e00ddef URL: http://source.winehq.org/git/wine.git/?a=commit;h=ae895a1f100682fdee679bad1b...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Mar 2 19:43:53 2011 +0100
user32: Export a Wine-specific function to send hardware input from the graphics driver.
---
dlls/user32/input.c | 13 +++++++++++++ dlls/user32/message.c | 43 +++++++++++++++++++++++++++++++++++++++++++ dlls/user32/user32.spec | 8 ++++++++ dlls/user32/user_private.h | 1 + dlls/winex11.drv/keyboard.c | 23 +++++++++-------------- dlls/winex11.drv/mouse.c | 24 ++++++++++-------------- include/winuser.h | 4 ++++ 7 files changed, 88 insertions(+), 28 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 455e55a..c30a195 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -115,6 +115,19 @@ BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret )
/*********************************************************************** + * __wine_send_input (USER32.@) + * + * Internal SendInput function to allow the graphics driver to inject real events. + */ +BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, BOOL injected ) +{ + NTSTATUS status = send_hardware_message( hwnd, input, injected ? SEND_HWMSG_INJECTED : 0 ); + if (status) SetLastError( RtlNtStatusToDosError(status) ); + return !status; +} + + +/*********************************************************************** * SendInput (USER32.@) */ UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size ) diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 93a90ea..0095af3 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -25,6 +25,8 @@ #include <assert.h> #include <stdarg.h>
+#define NONAMELESSUNION +#define NONAMELESSSTRUCT #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" @@ -3066,6 +3068,47 @@ 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 ret; + + SERVER_START_REQ( send_hardware_message ) + { + req->win = wine_server_user_handle( hwnd ); + req->flags = flags; + req->input.type = input->type; + switch (input->type) + { + case INPUT_MOUSE: + req->input.mouse.x = input->u.mi.dx; + req->input.mouse.y = input->u.mi.dy; + req->input.mouse.data = input->u.mi.mouseData; + req->input.mouse.flags = input->u.mi.dwFlags; + req->input.mouse.time = input->u.mi.time; + req->input.mouse.info = input->u.mi.dwExtraInfo; + break; + case INPUT_KEYBOARD: + req->input.kbd.vkey = input->u.ki.wVk; + req->input.kbd.scan = input->u.ki.wScan; + req->input.kbd.flags = input->u.ki.dwFlags; + req->input.kbd.time = input->u.ki.time; + req->input.kbd.info = input->u.ki.dwExtraInfo; + break; + case INPUT_HARDWARE: + req->input.hw.msg = input->u.hi.uMsg; + req->input.hw.lparam = MAKELONG( input->u.hi.wParamL, input->u.hi.wParamH ); + break; + } + ret = wine_server_call( req ); + } + SERVER_END_REQ; + return ret; +} + + +/*********************************************************************** * MSG_SendInternalMessageTimeout * * Same as SendMessageTimeoutW but sends the message to a specific thread diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index 5eb7154..63aff08 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -774,6 +774,14 @@ @ stdcall wvsprintfW(ptr wstr ptr)
################################################################ +# Wine internal extensions +# +# All functions must be prefixed with '__wine_' (for internal functions) +# or 'wine_' (for user-visible functions) to avoid namespace conflicts. +# +@ cdecl __wine_send_input(long ptr long) + +################################################################ # Wine dll separation hacks, these will go away, don't use them # @ cdecl HOOK_CallHooks(long long long long long) diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 23b4269..afd948b 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -213,6 +213,7 @@ extern void erase_now( HWND hwnd, UINT rdw_flags ) DECLSPEC_HIDDEN; extern void *get_hook_proc( void *proc, const WCHAR *module ); extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) 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 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/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 04d7371..6fc7bb0 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1154,6 +1154,7 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl DWORD dwExtraInfo, UINT injected_flags ) { UINT message; + INPUT input; KBDLLHOOKSTRUCT hook; WORD flags, wVkStripped, wVkL, wVkR, vk_hook = wVk;
@@ -1234,6 +1235,13 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl hook.dwExtraInfo = dwExtraInfo; if (HOOK_CallHooks( WH_KEYBOARD_LL, HC_ACTION, message, (LPARAM)&hook, TRUE )) return;
+ input.type = INPUT_KEYBOARD; + input.u.ki.wVk = vk_hook; + input.u.ki.wScan = wScan; + input.u.ki.dwFlags = event_flags; + input.u.ki.time = time; + input.u.ki.dwExtraInfo = dwExtraInfo; + if (!(event_flags & KEYEVENTF_UNICODE)) { if (event_flags & KEYEVENTF_KEYUP) @@ -1252,20 +1260,7 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl TRACE_(key)("message=0x%04x wParam=0x%04x InputKeyState=0x%x\n", message, wVk, key_state_table[wVk]);
- SERVER_START_REQ( send_hardware_message ) - { - req->win = wine_server_user_handle( hwnd ); - req->msg = message; - req->input.type = INPUT_KEYBOARD; - req->input.kbd.vkey = vk_hook; - req->input.kbd.scan = wScan; - req->input.kbd.flags = event_flags; - req->input.kbd.time = time; - req->input.kbd.info = dwExtraInfo; - if (injected_flags & LLKHF_INJECTED) req->flags = SEND_HWMSG_INJECTED; - wine_server_call( req ); - } - SERVER_END_REQ; + __wine_send_input( hwnd, &input, (injected_flags & LLKHF_INJECTED) != 0 ); }
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 236ba75..2d71be5 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -292,6 +292,7 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y, DWORD data, DWORD time, DWORD extra_info, UINT injected_flags ) { POINT pt; + INPUT input; MSLLHOOKSTRUCT hook;
if (!time) time = GetTickCount(); @@ -414,20 +415,15 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y, if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_XBUTTONUP, (LPARAM)&hook, TRUE )) return; }
- SERVER_START_REQ( send_hardware_message ) - { - req->win = wine_server_user_handle( hwnd ); - req->input.type = INPUT_MOUSE; - req->input.mouse.x = pt.x; - req->input.mouse.y = pt.y; - req->input.mouse.data = data; - req->input.mouse.flags = flags | MOUSEEVENTF_ABSOLUTE; - req->input.mouse.time = time; - req->input.mouse.info = extra_info; - if (injected_flags & LLMHF_INJECTED) req->flags = SEND_HWMSG_INJECTED; - wine_server_call( req ); - } - SERVER_END_REQ; + input.type = INPUT_MOUSE; + input.u.mi.dx = pt.x; + input.u.mi.dy = pt.y; + input.u.mi.mouseData = data; + input.u.mi.dwFlags = flags | MOUSEEVENTF_ABSOLUTE; + input.u.mi.time = time; + input.u.mi.dwExtraInfo = extra_info; + + __wine_send_input( hwnd, &input, (injected_flags & LLMHF_INJECTED) != 0 ); }
#ifdef SONAME_LIBXCURSOR diff --git a/include/winuser.h b/include/winuser.h index d95bfea..bd35803 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -5136,6 +5136,10 @@ WINUSERAPI INT WINAPI wvsprintfW(LPWSTR,LPCWSTR,__ms_va_list); /* NOTE: This is SYSTEM.3, not USER.182, which is also named KillSystemTimer */ WORD WINAPI SYSTEM_KillSystemTimer( WORD );
+#ifdef __WINESRC__ +WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, BOOL injected ); +#endif + #ifdef __cplusplus } #endif