user32: Handle input injected through SendInput entirely in user32.
This commit is contained in:
parent
c7efa293f0
commit
f1a3480068
|
@ -80,7 +80,6 @@ static const USER_DRIVER *load_driver(void)
|
||||||
GET_USER_FUNC(GetKeyboardLayoutName);
|
GET_USER_FUNC(GetKeyboardLayoutName);
|
||||||
GET_USER_FUNC(LoadKeyboardLayout);
|
GET_USER_FUNC(LoadKeyboardLayout);
|
||||||
GET_USER_FUNC(MapVirtualKeyEx);
|
GET_USER_FUNC(MapVirtualKeyEx);
|
||||||
GET_USER_FUNC(SendInput);
|
|
||||||
GET_USER_FUNC(ToUnicodeEx);
|
GET_USER_FUNC(ToUnicodeEx);
|
||||||
GET_USER_FUNC(UnloadKeyboardLayout);
|
GET_USER_FUNC(UnloadKeyboardLayout);
|
||||||
GET_USER_FUNC(VkKeyScanEx);
|
GET_USER_FUNC(VkKeyScanEx);
|
||||||
|
@ -196,11 +195,6 @@ static UINT CDECL nulldrv_MapVirtualKeyEx( UINT code, UINT type, HKL layout )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT CDECL nulldrv_SendInput( UINT count, LPINPUT inputs, int size )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INT CDECL nulldrv_ToUnicodeEx( UINT virt, UINT scan, const BYTE *state, LPWSTR str,
|
static INT CDECL nulldrv_ToUnicodeEx( UINT virt, UINT scan, const BYTE *state, LPWSTR str,
|
||||||
int size, UINT flags, HKL layout )
|
int size, UINT flags, HKL layout )
|
||||||
{
|
{
|
||||||
|
@ -448,7 +442,6 @@ static USER_DRIVER null_driver =
|
||||||
nulldrv_GetKeyboardLayoutName,
|
nulldrv_GetKeyboardLayoutName,
|
||||||
nulldrv_LoadKeyboardLayout,
|
nulldrv_LoadKeyboardLayout,
|
||||||
nulldrv_MapVirtualKeyEx,
|
nulldrv_MapVirtualKeyEx,
|
||||||
nulldrv_SendInput,
|
|
||||||
nulldrv_ToUnicodeEx,
|
nulldrv_ToUnicodeEx,
|
||||||
nulldrv_UnloadKeyboardLayout,
|
nulldrv_UnloadKeyboardLayout,
|
||||||
nulldrv_VkKeyScanEx,
|
nulldrv_VkKeyScanEx,
|
||||||
|
@ -549,11 +542,6 @@ static UINT CDECL loaderdrv_MapVirtualKeyEx( UINT code, UINT type, HKL layout )
|
||||||
return load_driver()->pMapVirtualKeyEx( code, type, layout );
|
return load_driver()->pMapVirtualKeyEx( code, type, layout );
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT CDECL loaderdrv_SendInput( UINT count, LPINPUT inputs, int size )
|
|
||||||
{
|
|
||||||
return load_driver()->pSendInput( count, inputs, size );
|
|
||||||
}
|
|
||||||
|
|
||||||
static INT CDECL loaderdrv_ToUnicodeEx( UINT virt, UINT scan, const BYTE *state, LPWSTR str,
|
static INT CDECL loaderdrv_ToUnicodeEx( UINT virt, UINT scan, const BYTE *state, LPWSTR str,
|
||||||
int size, UINT flags, HKL layout )
|
int size, UINT flags, HKL layout )
|
||||||
{
|
{
|
||||||
|
@ -801,7 +789,6 @@ static USER_DRIVER lazy_load_driver =
|
||||||
loaderdrv_GetKeyboardLayoutName,
|
loaderdrv_GetKeyboardLayoutName,
|
||||||
loaderdrv_LoadKeyboardLayout,
|
loaderdrv_LoadKeyboardLayout,
|
||||||
loaderdrv_MapVirtualKeyEx,
|
loaderdrv_MapVirtualKeyEx,
|
||||||
loaderdrv_SendInput,
|
|
||||||
loaderdrv_ToUnicodeEx,
|
loaderdrv_ToUnicodeEx,
|
||||||
loaderdrv_UnloadKeyboardLayout,
|
loaderdrv_UnloadKeyboardLayout,
|
||||||
loaderdrv_VkKeyScanEx,
|
loaderdrv_VkKeyScanEx,
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
|
|
||||||
#define NONAMELESSUNION
|
#define NONAMELESSUNION
|
||||||
#define NONAMELESSSTRUCT
|
#define NONAMELESSSTRUCT
|
||||||
|
#include "ntstatus.h"
|
||||||
|
#define WIN32_NO_STATUS
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
|
@ -50,6 +52,7 @@
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(win);
|
WINE_DEFAULT_DEBUG_CHANNEL(win);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(keyboard);
|
WINE_DECLARE_DEBUG_CHANNEL(keyboard);
|
||||||
|
|
||||||
|
static DWORD last_mouse_event;
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* get_key_state
|
* get_key_state
|
||||||
|
@ -119,52 +122,92 @@ BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret )
|
||||||
*
|
*
|
||||||
* Internal SendInput function to allow the graphics driver to inject real events.
|
* Internal SendInput function to allow the graphics driver to inject real events.
|
||||||
*/
|
*/
|
||||||
BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, BOOL injected )
|
BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input )
|
||||||
{
|
{
|
||||||
NTSTATUS status = send_hardware_message( hwnd, input, injected ? SEND_HWMSG_INJECTED : 0 );
|
NTSTATUS status = send_hardware_message( hwnd, input, 0 );
|
||||||
if (status) SetLastError( RtlNtStatusToDosError(status) );
|
if (status) SetLastError( RtlNtStatusToDosError(status) );
|
||||||
|
else if (input->type == INPUT_MOUSE) last_mouse_event = GetTickCount();
|
||||||
return !status;
|
return !status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* update_mouse_coords
|
||||||
|
*
|
||||||
|
* Helper for SendInput.
|
||||||
|
*/
|
||||||
|
static void update_mouse_coords( INPUT *input )
|
||||||
|
{
|
||||||
|
if (!(input->u.mi.dwFlags & MOUSEEVENTF_MOVE)) return;
|
||||||
|
|
||||||
|
if (input->u.mi.dwFlags & MOUSEEVENTF_ABSOLUTE)
|
||||||
|
{
|
||||||
|
input->u.mi.dx = (input->u.mi.dx * GetSystemMetrics( SM_CXSCREEN )) >> 16;
|
||||||
|
input->u.mi.dy = (input->u.mi.dy * GetSystemMetrics( SM_CYSCREEN )) >> 16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int accel[3];
|
||||||
|
|
||||||
|
/* dx and dy can be negative numbers for relative movements */
|
||||||
|
SystemParametersInfoW(SPI_GETMOUSE, 0, accel, 0);
|
||||||
|
|
||||||
|
if (!accel[2]) return;
|
||||||
|
|
||||||
|
if (abs(input->u.mi.dx) > accel[0])
|
||||||
|
{
|
||||||
|
input->u.mi.dx *= 2;
|
||||||
|
if ((abs(input->u.mi.dx) > accel[1]) && (accel[2] == 2)) input->u.mi.dx *= 2;
|
||||||
|
}
|
||||||
|
if (abs(input->u.mi.dy) > accel[0])
|
||||||
|
{
|
||||||
|
input->u.mi.dy *= 2;
|
||||||
|
if ((abs(input->u.mi.dy) > accel[1]) && (accel[2] == 2)) input->u.mi.dy *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* SendInput (USER32.@)
|
* SendInput (USER32.@)
|
||||||
*/
|
*/
|
||||||
UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
|
UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
|
||||||
{
|
|
||||||
if (TRACE_ON(win))
|
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
switch(inputs[i].type)
|
if (inputs[i].type == INPUT_MOUSE)
|
||||||
{
|
{
|
||||||
case INPUT_MOUSE:
|
/* we need to update the coordinates to what the server expects */
|
||||||
TRACE("mouse: dx %d, dy %d, data %x, flags %x, time %u, info %lx\n",
|
INPUT input = inputs[i];
|
||||||
inputs[i].u.mi.dx, inputs[i].u.mi.dy, inputs[i].u.mi.mouseData,
|
update_mouse_coords( &input );
|
||||||
inputs[i].u.mi.dwFlags, inputs[i].u.mi.time, inputs[i].u.mi.dwExtraInfo);
|
if (!(status = send_hardware_message( 0, &input, SEND_HWMSG_INJECTED )))
|
||||||
break;
|
{
|
||||||
|
last_mouse_event = GetTickCount();
|
||||||
|
|
||||||
case INPUT_KEYBOARD:
|
if ((input.u.mi.dwFlags & MOUSEEVENTF_MOVE) &&
|
||||||
TRACE("keyboard: vk %X, scan %x, flags %x, time %u, info %lx\n",
|
((input.u.mi.dwFlags & MOUSEEVENTF_ABSOLUTE) || input.u.mi.dx || input.u.mi.dy))
|
||||||
inputs[i].u.ki.wVk, inputs[i].u.ki.wScan, inputs[i].u.ki.dwFlags,
|
{
|
||||||
inputs[i].u.ki.time, inputs[i].u.ki.dwExtraInfo);
|
/* we have to actually move the cursor */
|
||||||
break;
|
POINT pt;
|
||||||
|
GetCursorPos( &pt );
|
||||||
case INPUT_HARDWARE:
|
if (!(input.u.mi.dwFlags & MOUSEEVENTF_ABSOLUTE) ||
|
||||||
TRACE("hardware: msg %d, wParamL %x, wParamH %x\n",
|
pt.x != input.u.mi.dx || pt.y != input.u.mi.dy)
|
||||||
inputs[i].u.hi.uMsg, inputs[i].u.hi.wParamL, inputs[i].u.hi.wParamH);
|
USER_Driver->pSetCursorPos( pt.x, pt.y );
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
FIXME("unknown input type %u\n", inputs[i].type);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else status = send_hardware_message( 0, &inputs[i], SEND_HWMSG_INJECTED );
|
||||||
|
|
||||||
return USER_Driver->pSendInput( count, inputs, size );
|
if (status)
|
||||||
|
{
|
||||||
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -210,11 +253,12 @@ void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI DECLSPEC_HOTPATCH GetCursorPos( POINT *pt )
|
BOOL WINAPI DECLSPEC_HOTPATCH GetCursorPos( POINT *pt )
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
if (!pt) return FALSE;
|
if (!pt) return FALSE;
|
||||||
|
|
||||||
ret = USER_Driver->pGetCursorPos( pt );
|
/* query new position from graphics driver if we haven't updated recently */
|
||||||
|
if (GetTickCount() - last_mouse_event > 100) ret = USER_Driver->pGetCursorPos( pt );
|
||||||
|
|
||||||
SERVER_START_REQ( set_cursor )
|
SERVER_START_REQ( set_cursor )
|
||||||
{
|
{
|
||||||
|
@ -232,7 +276,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetCursorPos( POINT *pt )
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -779,7 +779,7 @@
|
||||||
# All functions must be prefixed with '__wine_' (for internal functions)
|
# All functions must be prefixed with '__wine_' (for internal functions)
|
||||||
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
|
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
|
||||||
#
|
#
|
||||||
@ cdecl __wine_send_input(long ptr long)
|
@ cdecl __wine_send_input(long ptr)
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# Wine dll separation hacks, these will go away, don't use them
|
# Wine dll separation hacks, these will go away, don't use them
|
||||||
|
|
|
@ -61,7 +61,6 @@ typedef struct tagUSER_DRIVER {
|
||||||
BOOL (CDECL *pGetKeyboardLayoutName)(LPWSTR);
|
BOOL (CDECL *pGetKeyboardLayoutName)(LPWSTR);
|
||||||
HKL (CDECL *pLoadKeyboardLayout)(LPCWSTR, UINT);
|
HKL (CDECL *pLoadKeyboardLayout)(LPCWSTR, UINT);
|
||||||
UINT (CDECL *pMapVirtualKeyEx)(UINT, UINT, HKL);
|
UINT (CDECL *pMapVirtualKeyEx)(UINT, UINT, HKL);
|
||||||
UINT (CDECL *pSendInput)(UINT, LPINPUT, int);
|
|
||||||
INT (CDECL *pToUnicodeEx)(UINT, UINT, const BYTE *, LPWSTR, int, UINT, HKL);
|
INT (CDECL *pToUnicodeEx)(UINT, UINT, const BYTE *, LPWSTR, int, UINT, HKL);
|
||||||
BOOL (CDECL *pUnloadKeyboardLayout)(HKL);
|
BOOL (CDECL *pUnloadKeyboardLayout)(HKL);
|
||||||
SHORT (CDECL *pVkKeyScanEx)(WCHAR, HKL);
|
SHORT (CDECL *pVkKeyScanEx)(WCHAR, HKL);
|
||||||
|
|
|
@ -1251,7 +1251,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]);
|
||||||
|
|
||||||
__wine_send_input( hwnd, &input, (injected_flags & LLKHF_INJECTED) != 0 );
|
__wine_send_input( hwnd, &input );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -349,7 +349,7 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y,
|
||||||
input.u.mi.time = time;
|
input.u.mi.time = time;
|
||||||
input.u.mi.dwExtraInfo = extra_info;
|
input.u.mi.dwExtraInfo = extra_info;
|
||||||
|
|
||||||
__wine_send_input( hwnd, &input, (injected_flags & LLMHF_INJECTED) != 0 );
|
__wine_send_input( hwnd, &input );
|
||||||
|
|
||||||
if (injected_flags & LLMHF_INJECTED)
|
if (injected_flags & LLMHF_INJECTED)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5137,7 +5137,7 @@ WINUSERAPI INT WINAPI wvsprintfW(LPWSTR,LPCWSTR,__ms_va_list);
|
||||||
WORD WINAPI SYSTEM_KillSystemTimer( WORD );
|
WORD WINAPI SYSTEM_KillSystemTimer( WORD );
|
||||||
|
|
||||||
#ifdef __WINESRC__
|
#ifdef __WINESRC__
|
||||||
WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, BOOL injected );
|
WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
Loading…
Reference in New Issue