Commit 6ff2d287 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Move NtUserSendInput implementation from user32.

parent 21d60952
......@@ -65,11 +65,6 @@ void USER_unload_driver(void)
* These are fallbacks for entry points that are not implemented in the real driver.
*/
static BOOL CDECL nulldrv_SetCursorPos( INT x, INT y )
{
return TRUE;
}
static void CDECL nulldrv_UpdateClipboard(void)
{
}
......@@ -103,11 +98,6 @@ static LRESULT CDECL nulldrv_SysCommand( HWND hwnd, WPARAM wparam, LPARAM lparam
* Each entry point simply loads the real driver and chains to it.
*/
static BOOL CDECL loaderdrv_SetCursorPos( INT x, INT y )
{
return load_driver()->pSetCursorPos( x, y );
}
static void CDECL loaderdrv_UpdateClipboard(void)
{
load_driver()->pUpdateClipboard();
......@@ -130,7 +120,7 @@ static struct user_driver_funcs lazy_load_driver =
NULL,
NULL,
NULL,
loaderdrv_SetCursorPos,
NULL,
NULL,
/* clipboard functions */
loaderdrv_UpdateClipboard,
......@@ -187,7 +177,6 @@ void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT v
#define SET_USER_FUNC(name) \
do { if (!driver->p##name) driver->p##name = nulldrv_##name; } while(0)
SET_USER_FUNC(SetCursorPos);
SET_USER_FUNC(UpdateClipboard);
SET_USER_FUNC(MsgWaitForMultipleObjectsEx);
SET_USER_FUNC(SetWindowIcon);
......
......@@ -123,105 +123,6 @@ BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret )
/***********************************************************************
* 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)
{
DPI_AWARENESS_CONTEXT context = SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
RECT rc;
if (input->u.mi.dwFlags & MOUSEEVENTF_VIRTUALDESK)
rc = get_virtual_screen_rect();
else
rc = get_primary_monitor_rect();
input->u.mi.dx = rc.left + ((input->u.mi.dx * (rc.right - rc.left)) >> 16);
input->u.mi.dy = rc.top + ((input->u.mi.dy * (rc.bottom - rc.top)) >> 16);
SetThreadDpiAwarenessContext( context );
}
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.@)
*/
UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
{
UINT i;
NTSTATUS status = STATUS_SUCCESS;
if (size != sizeof(INPUT))
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (!count)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (!inputs)
{
SetLastError( ERROR_NOACCESS );
return 0;
}
for (i = 0; i < count; i++)
{
INPUT input = inputs[i];
switch (input.type)
{
case INPUT_MOUSE:
/* we need to update the coordinates to what the server expects */
update_mouse_coords( &input );
/* fallthrough */
case INPUT_KEYBOARD:
status = send_hardware_message( 0, &input, NULL, SEND_HWMSG_INJECTED );
break;
case INPUT_HARDWARE:
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return 0;
}
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
break;
}
}
return i;
}
/***********************************************************************
* keybd_event (USER32.@)
*/
void WINAPI keybd_event( BYTE bVk, BYTE bScan,
......@@ -235,7 +136,7 @@ void WINAPI keybd_event( BYTE bVk, BYTE bScan,
input.u.ki.dwFlags = dwFlags;
input.u.ki.time = 0;
input.u.ki.dwExtraInfo = dwExtraInfo;
SendInput( 1, &input, sizeof(input) );
NtUserSendInput( 1, &input, sizeof(input) );
}
......@@ -254,7 +155,7 @@ void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
input.u.mi.dwFlags = dwFlags;
input.u.mi.time = 0;
input.u.mi.dwExtraInfo = dwExtraInfo;
SendInput( 1, &input, sizeof(input) );
NtUserSendInput( 1, &input, sizeof(input) );
}
......
......@@ -2178,123 +2178,6 @@ 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, const RAWINPUT *rawinput, UINT flags )
{
struct user_key_state_info *key_state_info = get_user_thread_info()->key_state;
struct send_message_info info;
int prev_x, prev_y, new_x, new_y;
INT counter = NtUserCallOneParam( 0, NtUserIncrementKeyStateCounter );
USAGE hid_usage_page, hid_usage;
NTSTATUS ret;
BOOL wait;
info.type = MSG_HARDWARE;
info.dest_tid = 0;
info.hwnd = hwnd;
info.flags = 0;
info.timeout = 0;
if (input->type == INPUT_HARDWARE && rawinput->header.dwType == RIM_TYPEHID)
{
if (input->u.hi.uMsg == WM_INPUT_DEVICE_CHANGE)
{
hid_usage_page = ((USAGE *)rawinput->data.hid.bRawData)[0];
hid_usage = ((USAGE *)rawinput->data.hid.bRawData)[1];
}
if (input->u.hi.uMsg == WM_INPUT)
{
if (!rawinput_device_get_usages( rawinput->header.hDevice, &hid_usage_page, &hid_usage ))
{
WARN( "unable to get HID usages for device %p\n", rawinput->header.hDevice );
return STATUS_INVALID_HANDLE;
}
}
}
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 );
switch (input->u.hi.uMsg)
{
case WM_INPUT:
case WM_INPUT_DEVICE_CHANGE:
req->input.hw.rawinput.type = rawinput->header.dwType;
switch (rawinput->header.dwType)
{
case RIM_TYPEHID:
req->input.hw.rawinput.hid.device = HandleToUlong( rawinput->header.hDevice );
req->input.hw.rawinput.hid.param = rawinput->header.wParam;
req->input.hw.rawinput.hid.usage_page = hid_usage_page;
req->input.hw.rawinput.hid.usage = hid_usage;
req->input.hw.rawinput.hid.count = rawinput->data.hid.dwCount;
req->input.hw.rawinput.hid.length = rawinput->data.hid.dwSizeHid;
wine_server_add_data( req, rawinput->data.hid.bRawData,
rawinput->data.hid.dwCount * rawinput->data.hid.dwSizeHid );
break;
default:
assert( 0 );
break;
}
}
break;
}
if (key_state_info) wine_server_set_reply( req, key_state_info->state,
sizeof(key_state_info->state) );
ret = wine_server_call( req );
wait = reply->wait;
prev_x = reply->prev_x;
prev_y = reply->prev_y;
new_x = reply->new_x;
new_y = reply->new_y;
}
SERVER_END_REQ;
if (!ret)
{
if (key_state_info)
{
key_state_info->time = GetTickCount();
key_state_info->counter = counter;
}
if ((flags & SEND_HWMSG_INJECTED) && (prev_x != new_x || prev_y != new_y))
USER_Driver->pSetCursorPos( new_x, new_y );
}
if (wait)
{
LRESULT ignored;
wait_message_reply( 0 );
retrieve_reply( &info, 0, &ignored );
}
return ret;
}
/***********************************************************************
* SendMessageTimeoutW (USER32.@)
*/
LRESULT WINAPI SendMessageTimeoutW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
......
......@@ -635,7 +635,7 @@
@ stdcall SendDlgItemMessageW(long long long long long)
@ stdcall SendIMEMessageExA(long long)
@ stdcall SendIMEMessageExW(long long)
@ stdcall SendInput(long ptr long)
@ stdcall SendInput(long ptr long) NtUserSendInput
@ stdcall SendMessageA(long long long long)
@ stdcall SendMessageCallbackA(long long long long ptr long)
@ stdcall SendMessageCallbackW(long long long long ptr long)
......
......@@ -165,7 +165,6 @@ static const struct user_callbacks user_funcs =
EndMenu,
HideCaret,
PostMessageW,
SendInput,
SendMessageTimeoutW,
SendMessageA,
SendMessageW,
......
......@@ -101,7 +101,6 @@ extern RECT get_virtual_screen_rect(void) DECLSPEC_HIDDEN;
extern RECT get_primary_monitor_rect(void) DECLSPEC_HIDDEN;
extern DWORD get_input_codepage( void ) 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, const RAWINPUT *rawinput, UINT flags ) DECLSPEC_HIDDEN;
extern HPEN SYSCOLOR_GetPen( INT index ) DECLSPEC_HIDDEN;
extern HBRUSH SYSCOLOR_Get55AABrush(void) DECLSPEC_HIDDEN;
extern void SYSPARAMS_Init(void) DECLSPEC_HIDDEN;
......
......@@ -1199,6 +1199,7 @@ static struct unix_funcs unix_funcs =
NtUserReleaseDC,
NtUserScrollDC,
NtUserSelectPalette,
NtUserSendInput,
NtUserSetActiveWindow,
NtUserSetCapture,
NtUserSetClassLong,
......
......@@ -26,6 +26,8 @@
#pragma makedep unix
#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "win32u_private.h"
#include "ntuser_private.h"
#include "wine/server.h"
......@@ -76,12 +78,99 @@ BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, const RAWINPUT *raw
}
/***********************************************************************
* update_mouse_coords
*
* Helper for NtUserSendInput.
*/
static void update_mouse_coords( INPUT *input )
{
if (!(input->mi.dwFlags & MOUSEEVENTF_MOVE)) return;
if (input->mi.dwFlags & MOUSEEVENTF_ABSOLUTE)
{
RECT rc;
if (input->mi.dwFlags & MOUSEEVENTF_VIRTUALDESK)
rc = get_virtual_screen_rect( 0 );
else
rc = get_primary_monitor_rect( 0 );
input->mi.dx = rc.left + ((input->mi.dx * (rc.right - rc.left)) >> 16);
input->mi.dy = rc.top + ((input->mi.dy * (rc.bottom - rc.top)) >> 16);
}
else
{
int accel[3];
/* dx and dy can be negative numbers for relative movements */
NtUserSystemParametersInfo( SPI_GETMOUSE, 0, accel, 0 );
if (!accel[2]) return;
if (abs( input->mi.dx ) > accel[0])
{
input->mi.dx *= 2;
if (abs( input->mi.dx ) > accel[1] && accel[2] == 2) input->mi.dx *= 2;
}
if (abs(input->mi.dy) > accel[0])
{
input->mi.dy *= 2;
if (abs( input->mi.dy ) > accel[1] && accel[2] == 2) input->mi.dy *= 2;
}
}
}
/***********************************************************************
* NtUserSendInput (win32u.@)
*/
UINT WINAPI NtUserSendInput( UINT count, INPUT *inputs, int size )
{
if (!user_callbacks) return 0;
return user_callbacks->pSendInput( count, inputs, size );
UINT i;
NTSTATUS status = STATUS_SUCCESS;
if (size != sizeof(INPUT))
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (!count)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (!inputs)
{
SetLastError( ERROR_NOACCESS );
return 0;
}
for (i = 0; i < count; i++)
{
INPUT input = inputs[i];
switch (input.type)
{
case INPUT_MOUSE:
/* we need to update the coordinates to what the server expects */
update_mouse_coords( &input );
/* fallthrough */
case INPUT_KEYBOARD:
status = send_hardware_message( 0, &input, NULL, SEND_HWMSG_INJECTED );
break;
case INPUT_HARDWARE:
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return 0;
}
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
break;
}
}
return i;
}
/***********************************************************************
......
......@@ -38,7 +38,6 @@ struct user_callbacks
BOOL (WINAPI *pEndMenu)(void);
BOOL (WINAPI *pHideCaret)( HWND hwnd );
BOOL (WINAPI *pPostMessageW)( HWND, UINT, WPARAM, LPARAM );
UINT (WINAPI *pSendInput)( UINT count, INPUT *inputs, int size );
LRESULT (WINAPI *pSendMessageTimeoutW)( HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR );
LRESULT (WINAPI *pSendMessageA)( HWND, UINT, WPARAM, LPARAM );
LRESULT (WINAPI *pSendMessageW)( HWND, UINT, WPARAM, LPARAM );
......
......@@ -4717,8 +4717,6 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code )
MSG *msg = (MSG *)arg;
return handle_internal_message( msg->hwnd, msg->message, msg->wParam, msg->lParam );
}
case NtUserIncrementKeyStateCounter:
return InterlockedAdd( &global_key_state_counter, arg );
case NtUserLock:
switch( arg )
{
......
......@@ -1159,7 +1159,7 @@
@ stub NtUserScrollWindowEx
@ stdcall NtUserSelectPalette(long long long)
@ stub NtUserSendEventMessage
@ stub NtUserSendInput
@ stdcall NtUserSendInput(long ptr long)
@ stub NtUserSendInteractiveControlHapticsReport
@ stub NtUserSetActivationFilter
@ stub NtUserSetActiveProcessForMonitor
......
......@@ -252,6 +252,7 @@ struct unix_funcs
BOOL (WINAPI *pNtUserScrollDC)( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
HRGN ret_update_rgn, RECT *update_rect );
HPALETTE (WINAPI *pNtUserSelectPalette)( HDC hdc, HPALETTE hpal, WORD bkg );
UINT (WINAPI *pNtUserSendInput)( UINT count, INPUT *inputs, int size );
HWND (WINAPI *pNtUserSetActiveWindow)( HWND hwnd );
HWND (WINAPI *pNtUserSetCapture)( HWND hwnd );
DWORD (WINAPI *pNtUserSetClassLong)( HWND hwnd, INT offset, LONG newval, BOOL ansi );
......
......@@ -1016,6 +1016,12 @@ HPALETTE WINAPI NtUserSelectPalette( HDC hdc, HPALETTE hpal, WORD bkg )
return unix_funcs->pNtUserSelectPalette( hdc, hpal, bkg );
}
UINT WINAPI NtUserSendInput( UINT count, INPUT *inputs, int size )
{
if (!unix_funcs) return 0;
return unix_funcs->pNtUserSendInput( count, inputs, size );
}
HWND WINAPI NtUserSetActiveWindow( HWND hwnd )
{
if (!unix_funcs) return 0;
......
......@@ -169,7 +169,6 @@ enum
NtUserGetDeskPattern,
NtUserGetWinProcPtr,
NtUserHandleInternalMessage,
NtUserIncrementKeyStateCounter,
NtUserLock,
NtUserSetCallbacks,
NtUserSpyGetVKeyName,
......@@ -605,6 +604,7 @@ HANDLE WINAPI NtUserRemoveProp( HWND hwnd, const WCHAR *str );
BOOL WINAPI NtUserScrollDC( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
HRGN ret_update_rgn, RECT *update_rect );
HPALETTE WINAPI NtUserSelectPalette( HDC hdc, HPALETTE palette, WORD force_background );
UINT WINAPI NtUserSendInput( UINT count, INPUT *inputs, int size );
HWND WINAPI NtUserSetActiveWindow( HWND hwnd );
HWND WINAPI NtUserSetCapture( HWND hwnd );
DWORD WINAPI NtUserSetClassLong( HWND hwnd, INT offset, LONG newval, BOOL ansi );
......
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