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