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 )
/***********************************************************************
* __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 )
......
......@@ -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
......
......@@ -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)
......@@ -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;
......
......@@ -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 );
}
......
......@@ -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
......
......@@ -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
......
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