Alexandre Julliard : user32: Export a Wine-specific function to send hardware input from the graphics driver .
Alexandre Julliard
julliard at winehq.org
Thu Mar 3 11:46:21 CST 2011
Module: wine
Branch: master
Commit: ae895a1f100682fdee679bad1b5cadda8e00ddef
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ae895a1f100682fdee679bad1b5cadda8e00ddef
Author: Alexandre Julliard <julliard at 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
More information about the wine-cvs
mailing list