mirror of
git://source.winehq.org/git/wine.git
synced 2024-08-31 21:54:21 +00:00
win32u: Move NtUserGetRawInputBuffer from user32.
This commit is contained in:
parent
db43005cd8
commit
591fd06b6c
|
@ -593,117 +593,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(const RAWINPUTDEVICE *devi
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
typedef RAWINPUTHEADER RAWINPUTHEADER64;
|
||||
typedef RAWINPUT RAWINPUT64;
|
||||
#else
|
||||
typedef struct
|
||||
{
|
||||
DWORD dwType;
|
||||
DWORD dwSize;
|
||||
ULONGLONG hDevice;
|
||||
ULONGLONG wParam;
|
||||
} RAWINPUTHEADER64;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RAWINPUTHEADER64 header;
|
||||
union {
|
||||
RAWMOUSE mouse;
|
||||
RAWKEYBOARD keyboard;
|
||||
RAWHID hid;
|
||||
} data;
|
||||
} RAWINPUT64;
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* GetRawInputBuffer (USER32.@)
|
||||
*/
|
||||
UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size, UINT header_size)
|
||||
{
|
||||
struct hardware_msg_data *msg_data;
|
||||
struct rawinput_thread_data *thread_data;
|
||||
RAWINPUT *rawinput;
|
||||
UINT count = 0, remaining, rawinput_size, next_size, overhead;
|
||||
BOOL is_wow64;
|
||||
int i;
|
||||
|
||||
if (IsWow64Process( GetCurrentProcess(), &is_wow64 ) && is_wow64)
|
||||
rawinput_size = sizeof(RAWINPUT64);
|
||||
else
|
||||
rawinput_size = sizeof(RAWINPUT);
|
||||
overhead = rawinput_size - sizeof(RAWINPUT);
|
||||
|
||||
if (header_size != sizeof(RAWINPUTHEADER))
|
||||
{
|
||||
WARN("Invalid structure size %u.\n", header_size);
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return ~0U;
|
||||
}
|
||||
|
||||
if (!data_size)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return ~0U;
|
||||
}
|
||||
|
||||
if (!data)
|
||||
{
|
||||
TRACE("data %p, data_size %p (%u), header_size %u\n", data, data_size, *data_size, header_size);
|
||||
SERVER_START_REQ( get_rawinput_buffer )
|
||||
{
|
||||
req->rawinput_size = rawinput_size;
|
||||
req->buffer_size = 0;
|
||||
if (wine_server_call( req )) return ~0U;
|
||||
*data_size = reply->next_size;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(thread_data = rawinput_thread_data())) return ~0U;
|
||||
rawinput = thread_data->buffer;
|
||||
|
||||
/* first RAWINPUT block in the buffer is used for WM_INPUT message data */
|
||||
msg_data = (struct hardware_msg_data *)NEXTRAWINPUTBLOCK(rawinput);
|
||||
SERVER_START_REQ( get_rawinput_buffer )
|
||||
{
|
||||
req->rawinput_size = rawinput_size;
|
||||
req->buffer_size = *data_size;
|
||||
wine_server_set_reply( req, msg_data, RAWINPUT_BUFFER_SIZE - rawinput->header.dwSize );
|
||||
if (wine_server_call( req )) return ~0U;
|
||||
next_size = reply->next_size;
|
||||
count = reply->count;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
remaining = *data_size;
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
data->header.dwSize = remaining;
|
||||
if (!rawinput_from_hardware_message(data, msg_data)) break;
|
||||
if (overhead) memmove((char *)&data->data + overhead, &data->data,
|
||||
data->header.dwSize - sizeof(RAWINPUTHEADER));
|
||||
data->header.dwSize += overhead;
|
||||
remaining -= data->header.dwSize;
|
||||
data = NEXTRAWINPUTBLOCK(data);
|
||||
msg_data = (struct hardware_msg_data *)((char *)msg_data + msg_data->size);
|
||||
}
|
||||
|
||||
if (count == 0 && next_size == 0) *data_size = 0;
|
||||
else if (next_size == 0) next_size = rawinput_size;
|
||||
|
||||
if (next_size && *data_size <= next_size)
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
*data_size = next_size;
|
||||
count = ~0U;
|
||||
}
|
||||
|
||||
if (count) TRACE("data %p, data_size %p (%u), header_size %u, count %u\n", data, data_size, *data_size, header_size, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetRawInputDeviceInfoA (USER32.@)
|
||||
*/
|
||||
|
|
|
@ -366,7 +366,7 @@
|
|||
@ stdcall GetPropA(long str)
|
||||
@ stdcall GetPropW(long wstr)
|
||||
@ stdcall GetQueueStatus(long) NtUserGetQueueStatus
|
||||
@ stdcall GetRawInputBuffer(ptr ptr long)
|
||||
@ stdcall GetRawInputBuffer(ptr ptr long) NtUserGetRawInputBuffer
|
||||
@ stdcall GetRawInputData(ptr long ptr ptr long) NtUserGetRawInputData
|
||||
@ stdcall GetRawInputDeviceInfoA(ptr long ptr ptr)
|
||||
@ stdcall GetRawInputDeviceInfoW(ptr long ptr ptr)
|
||||
|
|
|
@ -47,10 +47,6 @@ struct wm_char_mapping_data
|
|||
MSG get_msg;
|
||||
};
|
||||
|
||||
/* on windows the buffer capacity is quite large as well, enough to */
|
||||
/* hold up to 10s of 1kHz mouse rawinput events */
|
||||
#define RAWINPUT_BUFFER_SIZE (512*1024)
|
||||
|
||||
extern BOOL (WINAPI *imm_register_window)(HWND) DECLSPEC_HIDDEN;
|
||||
extern void (WINAPI *imm_unregister_window)(HWND) DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
|
@ -1184,6 +1184,7 @@ static struct unix_funcs unix_funcs =
|
|||
NtUserGetMessage,
|
||||
NtUserGetPriorityClipboardFormat,
|
||||
NtUserGetQueueStatus,
|
||||
NtUserGetRawInputBuffer,
|
||||
NtUserGetRawInputData,
|
||||
NtUserGetSystemMenu,
|
||||
NtUserGetUpdateRect,
|
||||
|
|
|
@ -68,6 +68,10 @@ struct rawinput_thread_data
|
|||
RAWINPUT buffer[1]; /* rawinput message data buffer */
|
||||
};
|
||||
|
||||
/* on windows the buffer capacity is quite large as well, enough to */
|
||||
/* hold up to 10s of 1kHz mouse rawinput events */
|
||||
#define RAWINPUT_BUFFER_SIZE (512 * 1024)
|
||||
|
||||
struct user_object
|
||||
{
|
||||
HANDLE handle;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#pragma makedep unix
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "win32u_private.h"
|
||||
#include "ntuser_private.h"
|
||||
#include "wine/server.h"
|
||||
|
@ -30,6 +31,250 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
|
||||
|
||||
#define WINE_MOUSE_HANDLE ((HANDLE)1)
|
||||
#define WINE_KEYBOARD_HANDLE ((HANDLE)2)
|
||||
|
||||
#ifdef _WIN64
|
||||
typedef RAWINPUTHEADER RAWINPUTHEADER64;
|
||||
typedef RAWINPUT RAWINPUT64;
|
||||
#else
|
||||
typedef struct
|
||||
{
|
||||
DWORD dwType;
|
||||
DWORD dwSize;
|
||||
ULONGLONG hDevice;
|
||||
ULONGLONG wParam;
|
||||
} RAWINPUTHEADER64;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RAWINPUTHEADER64 header;
|
||||
union
|
||||
{
|
||||
RAWMOUSE mouse;
|
||||
RAWKEYBOARD keyboard;
|
||||
RAWHID hid;
|
||||
} data;
|
||||
} RAWINPUT64;
|
||||
#endif
|
||||
|
||||
static bool rawinput_from_hardware_message( RAWINPUT *rawinput, const struct hardware_msg_data *msg_data )
|
||||
{
|
||||
SIZE_T size;
|
||||
|
||||
rawinput->header.dwType = msg_data->rawinput.type;
|
||||
if (msg_data->rawinput.type == RIM_TYPEMOUSE)
|
||||
{
|
||||
static const unsigned int button_flags[] =
|
||||
{
|
||||
0, /* MOUSEEVENTF_MOVE */
|
||||
RI_MOUSE_LEFT_BUTTON_DOWN, /* MOUSEEVENTF_LEFTDOWN */
|
||||
RI_MOUSE_LEFT_BUTTON_UP, /* MOUSEEVENTF_LEFTUP */
|
||||
RI_MOUSE_RIGHT_BUTTON_DOWN, /* MOUSEEVENTF_RIGHTDOWN */
|
||||
RI_MOUSE_RIGHT_BUTTON_UP, /* MOUSEEVENTF_RIGHTUP */
|
||||
RI_MOUSE_MIDDLE_BUTTON_DOWN, /* MOUSEEVENTF_MIDDLEDOWN */
|
||||
RI_MOUSE_MIDDLE_BUTTON_UP, /* MOUSEEVENTF_MIDDLEUP */
|
||||
};
|
||||
unsigned int i;
|
||||
|
||||
rawinput->header.dwSize = FIELD_OFFSET(RAWINPUT, data) + sizeof(RAWMOUSE);
|
||||
rawinput->header.hDevice = WINE_MOUSE_HANDLE;
|
||||
rawinput->header.wParam = 0;
|
||||
|
||||
rawinput->data.mouse.usFlags = MOUSE_MOVE_RELATIVE;
|
||||
rawinput->data.mouse.usButtonFlags = 0;
|
||||
rawinput->data.mouse.usButtonData = 0;
|
||||
for (i = 1; i < ARRAY_SIZE(button_flags); ++i)
|
||||
{
|
||||
if (msg_data->flags & (1 << i))
|
||||
rawinput->data.mouse.usButtonFlags |= button_flags[i];
|
||||
}
|
||||
if (msg_data->flags & MOUSEEVENTF_WHEEL)
|
||||
{
|
||||
rawinput->data.mouse.usButtonFlags |= RI_MOUSE_WHEEL;
|
||||
rawinput->data.mouse.usButtonData = msg_data->rawinput.mouse.data;
|
||||
}
|
||||
if (msg_data->flags & MOUSEEVENTF_HWHEEL)
|
||||
{
|
||||
rawinput->data.mouse.usButtonFlags |= RI_MOUSE_HORIZONTAL_WHEEL;
|
||||
rawinput->data.mouse.usButtonData = msg_data->rawinput.mouse.data;
|
||||
}
|
||||
if (msg_data->flags & MOUSEEVENTF_XDOWN)
|
||||
{
|
||||
if (msg_data->rawinput.mouse.data == XBUTTON1)
|
||||
rawinput->data.mouse.usButtonFlags |= RI_MOUSE_BUTTON_4_DOWN;
|
||||
else if (msg_data->rawinput.mouse.data == XBUTTON2)
|
||||
rawinput->data.mouse.usButtonFlags |= RI_MOUSE_BUTTON_5_DOWN;
|
||||
}
|
||||
if (msg_data->flags & MOUSEEVENTF_XUP)
|
||||
{
|
||||
if (msg_data->rawinput.mouse.data == XBUTTON1)
|
||||
rawinput->data.mouse.usButtonFlags |= RI_MOUSE_BUTTON_4_UP;
|
||||
else if (msg_data->rawinput.mouse.data == XBUTTON2)
|
||||
rawinput->data.mouse.usButtonFlags |= RI_MOUSE_BUTTON_5_UP;
|
||||
}
|
||||
|
||||
rawinput->data.mouse.ulRawButtons = 0;
|
||||
rawinput->data.mouse.lLastX = msg_data->rawinput.mouse.x;
|
||||
rawinput->data.mouse.lLastY = msg_data->rawinput.mouse.y;
|
||||
rawinput->data.mouse.ulExtraInformation = msg_data->info;
|
||||
}
|
||||
else if (msg_data->rawinput.type == RIM_TYPEKEYBOARD)
|
||||
{
|
||||
rawinput->header.dwSize = FIELD_OFFSET(RAWINPUT, data) + sizeof(RAWKEYBOARD);
|
||||
rawinput->header.hDevice = WINE_KEYBOARD_HANDLE;
|
||||
rawinput->header.wParam = 0;
|
||||
|
||||
rawinput->data.keyboard.MakeCode = msg_data->rawinput.kbd.scan;
|
||||
rawinput->data.keyboard.Flags = (msg_data->flags & KEYEVENTF_KEYUP) ? RI_KEY_BREAK : RI_KEY_MAKE;
|
||||
if (msg_data->flags & KEYEVENTF_EXTENDEDKEY)
|
||||
rawinput->data.keyboard.Flags |= RI_KEY_E0;
|
||||
rawinput->data.keyboard.Reserved = 0;
|
||||
|
||||
switch (msg_data->rawinput.kbd.vkey)
|
||||
{
|
||||
case VK_LSHIFT:
|
||||
case VK_RSHIFT:
|
||||
rawinput->data.keyboard.VKey = VK_SHIFT;
|
||||
rawinput->data.keyboard.Flags &= ~RI_KEY_E0;
|
||||
break;
|
||||
|
||||
case VK_LCONTROL:
|
||||
case VK_RCONTROL:
|
||||
rawinput->data.keyboard.VKey = VK_CONTROL;
|
||||
break;
|
||||
|
||||
case VK_LMENU:
|
||||
case VK_RMENU:
|
||||
rawinput->data.keyboard.VKey = VK_MENU;
|
||||
break;
|
||||
|
||||
default:
|
||||
rawinput->data.keyboard.VKey = msg_data->rawinput.kbd.vkey;
|
||||
break;
|
||||
}
|
||||
|
||||
rawinput->data.keyboard.Message = msg_data->rawinput.kbd.message;
|
||||
rawinput->data.keyboard.ExtraInformation = msg_data->info;
|
||||
}
|
||||
else if (msg_data->rawinput.type == RIM_TYPEHID)
|
||||
{
|
||||
size = msg_data->size - sizeof(*msg_data);
|
||||
if (size > rawinput->header.dwSize - sizeof(*rawinput)) return false;
|
||||
|
||||
rawinput->header.dwSize = FIELD_OFFSET( RAWINPUT, data.hid.bRawData ) + size;
|
||||
rawinput->header.hDevice = ULongToHandle( msg_data->rawinput.hid.device );
|
||||
rawinput->header.wParam = 0;
|
||||
|
||||
rawinput->data.hid.dwCount = msg_data->rawinput.hid.count;
|
||||
rawinput->data.hid.dwSizeHid = msg_data->rawinput.hid.length;
|
||||
memcpy( rawinput->data.hid.bRawData, msg_data + 1, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME( "Unhandled rawinput type %#x.\n", msg_data->rawinput.type );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NtUserGetRawInputBuffer (win32u.@)
|
||||
*/
|
||||
UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT header_size )
|
||||
{
|
||||
unsigned int count = 0, remaining, rawinput_size, next_size, overhead;
|
||||
struct rawinput_thread_data *thread_data;
|
||||
struct hardware_msg_data *msg_data;
|
||||
RAWINPUT *rawinput;
|
||||
int i;
|
||||
|
||||
if (NtCurrentTeb()->WowTebOffset)
|
||||
rawinput_size = sizeof(RAWINPUT64);
|
||||
else
|
||||
rawinput_size = sizeof(RAWINPUT);
|
||||
overhead = rawinput_size - sizeof(RAWINPUT);
|
||||
|
||||
if (header_size != sizeof(RAWINPUTHEADER))
|
||||
{
|
||||
WARN( "Invalid structure size %u.\n", header_size );
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return ~0u;
|
||||
}
|
||||
|
||||
if (!data_size)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return ~0u;
|
||||
}
|
||||
|
||||
if (!data)
|
||||
{
|
||||
TRACE( "data %p, data_size %p (%u), header_size %u\n", data, data_size, *data_size, header_size );
|
||||
SERVER_START_REQ( get_rawinput_buffer )
|
||||
{
|
||||
req->rawinput_size = rawinput_size;
|
||||
req->buffer_size = 0;
|
||||
if (wine_server_call( req )) return ~0u;
|
||||
*data_size = reply->next_size;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!user_callbacks || !(thread_data = user_callbacks->get_rawinput_thread_data())) return ~0u;
|
||||
rawinput = thread_data->buffer;
|
||||
|
||||
/* first RAWINPUT block in the buffer is used for WM_INPUT message data */
|
||||
msg_data = (struct hardware_msg_data *)NEXTRAWINPUTBLOCK(rawinput);
|
||||
SERVER_START_REQ( get_rawinput_buffer )
|
||||
{
|
||||
req->rawinput_size = rawinput_size;
|
||||
req->buffer_size = *data_size;
|
||||
wine_server_set_reply( req, msg_data, RAWINPUT_BUFFER_SIZE - rawinput->header.dwSize );
|
||||
if (wine_server_call( req )) return ~0u;
|
||||
next_size = reply->next_size;
|
||||
count = reply->count;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
remaining = *data_size;
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
data->header.dwSize = remaining;
|
||||
if (!rawinput_from_hardware_message( data, msg_data )) break;
|
||||
if (overhead)
|
||||
{
|
||||
memmove( (char *)&data->data + overhead, &data->data,
|
||||
data->header.dwSize - sizeof(RAWINPUTHEADER) );
|
||||
}
|
||||
data->header.dwSize += overhead;
|
||||
remaining -= data->header.dwSize;
|
||||
data = NEXTRAWINPUTBLOCK(data);
|
||||
msg_data = (struct hardware_msg_data *)((char *)msg_data + msg_data->size);
|
||||
}
|
||||
|
||||
if (!next_size)
|
||||
{
|
||||
if (!count)
|
||||
*data_size = 0;
|
||||
else
|
||||
next_size = rawinput_size;
|
||||
}
|
||||
|
||||
if (next_size && *data_size <= next_size)
|
||||
{
|
||||
SetLastError( ERROR_INSUFFICIENT_BUFFER );
|
||||
*data_size = next_size;
|
||||
count = ~0u;
|
||||
}
|
||||
|
||||
TRACE( "data %p, data_size %p (%u), header_size %u, count %u\n",
|
||||
data, data_size, *data_size, header_size, count );
|
||||
return count;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NtUserGetRawInputData (win32u.@)
|
||||
*/
|
||||
|
|
|
@ -983,7 +983,7 @@
|
|||
@ stdcall -syscall NtUserGetProp(long wstr)
|
||||
@ stdcall NtUserGetQueueStatus(long)
|
||||
@ stub NtUserGetQueueStatusReadonly
|
||||
@ stub NtUserGetRawInputBuffer
|
||||
@ stdcall NtUserGetRawInputBuffer(ptr ptr long)
|
||||
@ stdcall NtUserGetRawInputData(ptr long ptr ptr long)
|
||||
@ stub NtUserGetRawInputDeviceInfo
|
||||
@ stub NtUserGetRawInputDeviceList
|
||||
|
|
|
@ -247,6 +247,7 @@ struct unix_funcs
|
|||
BOOL (WINAPI *pNtUserGetMessage)( MSG *msg, HWND hwnd, UINT first, UINT last );
|
||||
INT (WINAPI *pNtUserGetPriorityClipboardFormat)( UINT *list, INT count );
|
||||
DWORD (WINAPI *pNtUserGetQueueStatus)( UINT flags );
|
||||
UINT (WINAPI *pNtUserGetRawInputBuffer)( RAWINPUT *data, UINT *data_size, UINT header_size );
|
||||
UINT (WINAPI *pNtUserGetRawInputData)( HRAWINPUT rawinput, UINT command,
|
||||
void *data, UINT *data_size, UINT header_size );
|
||||
HMENU (WINAPI *pNtUserGetSystemMenu)( HWND hwnd, BOOL revert );
|
||||
|
|
|
@ -1048,6 +1048,12 @@ DWORD WINAPI NtUserGetQueueStatus( UINT flags )
|
|||
return unix_funcs->pNtUserGetQueueStatus( flags );
|
||||
}
|
||||
|
||||
UINT WINAPI DECLSPEC_HOTPATCH NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT header_size )
|
||||
{
|
||||
if (!unix_funcs) return ~0u;
|
||||
return unix_funcs->pNtUserGetRawInputBuffer( data, data_size, header_size );
|
||||
}
|
||||
|
||||
UINT WINAPI NtUserGetRawInputData( HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size )
|
||||
{
|
||||
if (!unix_funcs) return ~0u;
|
||||
|
|
|
@ -606,6 +606,7 @@ HWINSTA WINAPI NtUserGetProcessWindowStation(void);
|
|||
HANDLE WINAPI NtUserGetProp( HWND hwnd, const WCHAR *str );
|
||||
ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process );
|
||||
DWORD WINAPI NtUserGetQueueStatus( UINT flags );
|
||||
UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT header_size );
|
||||
UINT WINAPI NtUserGetRawInputData( HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size );
|
||||
ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process );
|
||||
HMENU WINAPI NtUserGetSystemMenu( HWND hwnd, BOOL revert );
|
||||
|
|
Loading…
Reference in a new issue