Commit ae895a1f authored by Alexandre Julliard's avatar Alexandre Julliard

user32: Export a Wine-specific function to send hardware input from the graphics driver.

parent 9f91254c
...@@ -115,6 +115,19 @@ BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) ...@@ -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.@) * SendInput (USER32.@)
*/ */
UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size ) UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <assert.h> #include <assert.h>
#include <stdarg.h> #include <stdarg.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "ntstatus.h" #include "ntstatus.h"
#define WIN32_NO_STATUS #define WIN32_NO_STATUS
#include "windef.h" #include "windef.h"
...@@ -3066,6 +3068,47 @@ static BOOL send_message( struct send_message_info *info, DWORD_PTR *res_ptr, BO ...@@ -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 * MSG_SendInternalMessageTimeout
* *
* Same as SendMessageTimeoutW but sends the message to a specific thread * Same as SendMessageTimeoutW but sends the message to a specific thread
......
...@@ -774,6 +774,14 @@ ...@@ -774,6 +774,14 @@
@ stdcall wvsprintfW(ptr wstr ptr) @ 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 # Wine dll separation hacks, these will go away, don't use them
# #
@ cdecl HOOK_CallHooks(long long long long long) @ cdecl HOOK_CallHooks(long long long long long)
...@@ -213,6 +213,7 @@ extern void erase_now( HWND hwnd, UINT rdw_flags ) DECLSPEC_HIDDEN; ...@@ -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 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 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 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, extern LRESULT MSG_SendInternalMessageTimeout( DWORD dest_pid, DWORD dest_tid,
UINT msg, WPARAM wparam, LPARAM lparam, UINT msg, WPARAM wparam, LPARAM lparam,
UINT flags, UINT timeout, PDWORD_PTR res_ptr ) DECLSPEC_HIDDEN; UINT flags, UINT timeout, PDWORD_PTR res_ptr ) DECLSPEC_HIDDEN;
......
...@@ -1154,6 +1154,7 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl ...@@ -1154,6 +1154,7 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl
DWORD dwExtraInfo, UINT injected_flags ) DWORD dwExtraInfo, UINT injected_flags )
{ {
UINT message; UINT message;
INPUT input;
KBDLLHOOKSTRUCT hook; KBDLLHOOKSTRUCT hook;
WORD flags, wVkStripped, wVkL, wVkR, vk_hook = wVk; 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 ...@@ -1234,6 +1235,13 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl
hook.dwExtraInfo = dwExtraInfo; hook.dwExtraInfo = dwExtraInfo;
if (HOOK_CallHooks( WH_KEYBOARD_LL, HC_ACTION, message, (LPARAM)&hook, TRUE )) return; 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_UNICODE))
{ {
if (event_flags & KEYEVENTF_KEYUP) if (event_flags & KEYEVENTF_KEYUP)
...@@ -1252,20 +1260,7 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl ...@@ -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", TRACE_(key)("message=0x%04x wParam=0x%04x InputKeyState=0x%x\n",
message, wVk, key_state_table[wVk]); message, wVk, key_state_table[wVk]);
SERVER_START_REQ( send_hardware_message ) __wine_send_input( hwnd, &input, (injected_flags & LLKHF_INJECTED) != 0 );
{
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;
} }
......
...@@ -292,6 +292,7 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y, ...@@ -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 ) DWORD data, DWORD time, DWORD extra_info, UINT injected_flags )
{ {
POINT pt; POINT pt;
INPUT input;
MSLLHOOKSTRUCT hook; MSLLHOOKSTRUCT hook;
if (!time) time = GetTickCount(); if (!time) time = GetTickCount();
...@@ -414,20 +415,15 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y, ...@@ -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; if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_XBUTTONUP, (LPARAM)&hook, TRUE )) return;
} }
SERVER_START_REQ( send_hardware_message ) input.type = INPUT_MOUSE;
{ input.u.mi.dx = pt.x;
req->win = wine_server_user_handle( hwnd ); input.u.mi.dy = pt.y;
req->input.type = INPUT_MOUSE; input.u.mi.mouseData = data;
req->input.mouse.x = pt.x; input.u.mi.dwFlags = flags | MOUSEEVENTF_ABSOLUTE;
req->input.mouse.y = pt.y; input.u.mi.time = time;
req->input.mouse.data = data; input.u.mi.dwExtraInfo = extra_info;
req->input.mouse.flags = flags | MOUSEEVENTF_ABSOLUTE;
req->input.mouse.time = time; __wine_send_input( hwnd, &input, (injected_flags & LLMHF_INJECTED) != 0 );
req->input.mouse.info = extra_info;
if (injected_flags & LLMHF_INJECTED) req->flags = SEND_HWMSG_INJECTED;
wine_server_call( req );
}
SERVER_END_REQ;
} }
#ifdef SONAME_LIBXCURSOR #ifdef SONAME_LIBXCURSOR
......
...@@ -5136,6 +5136,10 @@ WINUSERAPI INT WINAPI wvsprintfW(LPWSTR,LPCWSTR,__ms_va_list); ...@@ -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 */ /* NOTE: This is SYSTEM.3, not USER.182, which is also named KillSystemTimer */
WORD WINAPI SYSTEM_KillSystemTimer( WORD ); WORD WINAPI SYSTEM_KillSystemTimer( WORD );
#ifdef __WINESRC__
WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, BOOL injected );
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment