user32: Add rawinput mouse support.
This commit is contained in:
parent
d601a0dede
commit
faaf3d388e
|
@ -532,12 +532,41 @@ BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(RAWINPUTDEVICE *devices, U
|
|||
/******************************************************************
|
||||
* GetRawInputData (USER32.@)
|
||||
*/
|
||||
UINT WINAPI GetRawInputData(HRAWINPUT hRawInput, UINT uiCommand, LPVOID pData, PUINT pcbSize, UINT cbSizeHeader)
|
||||
UINT WINAPI GetRawInputData(HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size)
|
||||
{
|
||||
FIXME("(hRawInput=%p, uiCommand=%d, pData=%p, pcbSize=%p, cbSizeHeader=%d) stub!\n",
|
||||
hRawInput, uiCommand, pData, pcbSize, cbSizeHeader);
|
||||
RAWINPUT *ri = (RAWINPUT *)rawinput;
|
||||
UINT s;
|
||||
|
||||
return 0;
|
||||
TRACE("rawinput %p, command %#x, data %p, data_size %p, header_size %u.\n",
|
||||
rawinput, command, data, data_size, header_size);
|
||||
|
||||
if (header_size != sizeof(RAWINPUTHEADER))
|
||||
{
|
||||
WARN("Invalid structure size %u.\n", header_size);
|
||||
return ~0U;
|
||||
}
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case RID_INPUT:
|
||||
s = ri->header.dwSize;
|
||||
break;
|
||||
case RID_HEADER:
|
||||
s = sizeof(RAWINPUTHEADER);
|
||||
break;
|
||||
default:
|
||||
return ~0U;
|
||||
}
|
||||
|
||||
if (!data)
|
||||
{
|
||||
*data_size = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*data_size < s) return ~0U;
|
||||
memcpy(data, ri, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msg);
|
|||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(key);
|
||||
|
||||
#define WINE_MOUSE_HANDLE ((HANDLE)1)
|
||||
|
||||
#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
|
||||
#define WM_NCMOUSELAST (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST))
|
||||
|
||||
|
@ -2268,6 +2270,84 @@ static void accept_hardware_message( UINT hw_id, BOOL remove, HWND new_hwnd )
|
|||
}
|
||||
|
||||
|
||||
static BOOL process_rawinput_message( MSG *msg, const struct hardware_msg_data *msg_data )
|
||||
{
|
||||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
RAWINPUT *rawinput = thread_info->rawinput;
|
||||
|
||||
if (!rawinput)
|
||||
{
|
||||
thread_info->rawinput = HeapAlloc( GetProcessHeap(), 0, sizeof(*rawinput) );
|
||||
if (!(rawinput = thread_info->rawinput)) return FALSE;
|
||||
}
|
||||
|
||||
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.u.s.usButtonFlags = 0;
|
||||
rawinput->data.mouse.u.s.usButtonData = 0;
|
||||
for (i = 1; i < sizeof(button_flags) / sizeof(*button_flags); ++i)
|
||||
{
|
||||
if (msg_data->flags & (1 << i))
|
||||
rawinput->data.mouse.u.s.usButtonFlags |= button_flags[i];
|
||||
}
|
||||
if (msg_data->flags & MOUSEEVENTF_WHEEL)
|
||||
{
|
||||
rawinput->data.mouse.u.s.usButtonFlags |= RI_MOUSE_WHEEL;
|
||||
rawinput->data.mouse.u.s.usButtonData = msg_data->rawinput.mouse.data;
|
||||
}
|
||||
if (msg_data->flags & MOUSEEVENTF_HWHEEL)
|
||||
{
|
||||
rawinput->data.mouse.u.s.usButtonFlags |= RI_MOUSE_HORIZONTAL_WHEEL;
|
||||
rawinput->data.mouse.u.s.usButtonData = msg_data->rawinput.mouse.data;
|
||||
}
|
||||
if (msg_data->flags & MOUSEEVENTF_XDOWN)
|
||||
{
|
||||
if (msg_data->rawinput.mouse.data == XBUTTON1)
|
||||
rawinput->data.mouse.u.s.usButtonFlags |= RI_MOUSE_BUTTON_4_DOWN;
|
||||
else if (msg_data->rawinput.mouse.data == XBUTTON2)
|
||||
rawinput->data.mouse.u.s.usButtonFlags |= RI_MOUSE_BUTTON_5_DOWN;
|
||||
}
|
||||
if (msg_data->flags & MOUSEEVENTF_XUP)
|
||||
{
|
||||
if (msg_data->rawinput.mouse.data == XBUTTON1)
|
||||
rawinput->data.mouse.u.s.usButtonFlags |= RI_MOUSE_BUTTON_4_UP;
|
||||
else if (msg_data->rawinput.mouse.data == XBUTTON2)
|
||||
rawinput->data.mouse.u.s.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
|
||||
{
|
||||
FIXME("Unhandled rawinput type %#x.\n", msg_data->rawinput.type);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
msg->lParam = (LPARAM)rawinput;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* process_keyboard_message
|
||||
*
|
||||
|
@ -2558,14 +2638,17 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H
|
|||
*
|
||||
* Process a hardware message; return TRUE if message should be passed on to the app
|
||||
*/
|
||||
static BOOL process_hardware_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, HWND hwnd_filter,
|
||||
UINT first, UINT last, BOOL remove )
|
||||
static BOOL process_hardware_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data,
|
||||
HWND hwnd_filter, UINT first, UINT last, BOOL remove )
|
||||
{
|
||||
if (msg->message == WM_INPUT)
|
||||
return process_rawinput_message( msg, msg_data );
|
||||
|
||||
if (is_keyboard_message( msg->message ))
|
||||
return process_keyboard_message( msg, hw_id, hwnd_filter, first, last, remove );
|
||||
|
||||
if (is_mouse_message( msg->message ))
|
||||
return process_mouse_message( msg, hw_id, extra_info, hwnd_filter, first, last, remove );
|
||||
return process_mouse_message( msg, hw_id, msg_data->info, hwnd_filter, first, last, remove );
|
||||
|
||||
ERR( "unknown message type %x\n", msg->message );
|
||||
return FALSE;
|
||||
|
@ -2765,7 +2848,7 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
|
|||
info.msg.pt.x = msg_data->hardware.x;
|
||||
info.msg.pt.y = msg_data->hardware.y;
|
||||
hw_id = msg_data->hardware.hw_id;
|
||||
if (!process_hardware_message( &info.msg, hw_id, msg_data->hardware.info,
|
||||
if (!process_hardware_message( &info.msg, hw_id, &msg_data->hardware,
|
||||
hwnd, first, last, flags & PM_REMOVE ))
|
||||
{
|
||||
TRACE("dropping msg %x\n", info.msg.message );
|
||||
|
|
|
@ -313,6 +313,7 @@ static void thread_detach(void)
|
|||
CloseHandle( thread_info->server_queue );
|
||||
HeapFree( GetProcessHeap(), 0, thread_info->wmchar_data );
|
||||
HeapFree( GetProcessHeap(), 0, thread_info->key_state );
|
||||
HeapFree( GetProcessHeap(), 0, thread_info->rawinput );
|
||||
|
||||
exiting_thread_id = 0;
|
||||
}
|
||||
|
|
|
@ -182,8 +182,9 @@ struct user_thread_info
|
|||
BYTE *key_state; /* Cache of global key state */
|
||||
HWND top_window; /* Desktop window */
|
||||
HWND msg_window; /* HWND_MESSAGE parent window */
|
||||
RAWINPUT *rawinput;
|
||||
|
||||
ULONG pad[9]; /* Available for more data */
|
||||
ULONG pad[8]; /* Available for more data */
|
||||
};
|
||||
|
||||
struct hook_extra_info
|
||||
|
|
|
@ -279,6 +279,17 @@ struct hardware_msg_data
|
|||
int y;
|
||||
unsigned int hw_id;
|
||||
unsigned int flags;
|
||||
union
|
||||
{
|
||||
int type;
|
||||
struct
|
||||
{
|
||||
int type;
|
||||
int x;
|
||||
int y;
|
||||
unsigned int data;
|
||||
} mouse;
|
||||
} rawinput;
|
||||
};
|
||||
|
||||
struct callback_msg_data
|
||||
|
@ -5672,6 +5683,6 @@ union generic_reply
|
|||
struct set_suspend_context_reply set_suspend_context_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 433
|
||||
#define SERVER_PROTOCOL_VERSION 434
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -333,6 +333,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
|
|||
process->desktop = 0;
|
||||
process->token = NULL;
|
||||
process->trace_data = 0;
|
||||
process->rawinput_mouse = NULL;
|
||||
list_init( &process->thread_list );
|
||||
list_init( &process->locks );
|
||||
list_init( &process->classes );
|
||||
|
|
|
@ -88,6 +88,7 @@ struct process
|
|||
client_ptr_t ldt_copy; /* pointer to LDT copy in client addr space */
|
||||
unsigned int trace_data; /* opaque data used by the process tracing mechanism */
|
||||
struct list rawinput_devices;/* list of registered rawinput devices */
|
||||
const struct rawinput_device *rawinput_mouse; /* rawinput mouse device, if any */
|
||||
};
|
||||
|
||||
struct process_snapshot
|
||||
|
|
|
@ -295,6 +295,17 @@ struct hardware_msg_data
|
|||
int y; /* y position */
|
||||
unsigned int hw_id; /* unique id */
|
||||
unsigned int flags; /* hook flags */
|
||||
union
|
||||
{
|
||||
int type;
|
||||
struct
|
||||
{
|
||||
int type; /* RIM_TYPEMOUSE */
|
||||
int x; /* x coordinate */
|
||||
int y; /* y coordinate */
|
||||
unsigned int data; /* mouse data */
|
||||
} mouse;
|
||||
} rawinput;
|
||||
};
|
||||
|
||||
struct callback_msg_data
|
||||
|
|
|
@ -448,11 +448,11 @@ static inline int filter_contains_hw_range( unsigned int first, unsigned int las
|
|||
{
|
||||
/* hardware message ranges are (in numerical order):
|
||||
* WM_NCMOUSEFIRST .. WM_NCMOUSELAST
|
||||
* WM_KEYFIRST .. WM_KEYLAST
|
||||
* WM_INPUT_DEVICE_CHANGE .. WM_KEYLAST
|
||||
* WM_MOUSEFIRST .. WM_MOUSELAST
|
||||
*/
|
||||
if (last < WM_NCMOUSEFIRST) return 0;
|
||||
if (first > WM_NCMOUSELAST && last < WM_KEYFIRST) return 0;
|
||||
if (first > WM_NCMOUSELAST && last < WM_INPUT_DEVICE_CHANGE) return 0;
|
||||
if (first > WM_KEYLAST && last < WM_MOUSEFIRST) return 0;
|
||||
if (first > WM_MOUSELAST) return 0;
|
||||
return 1;
|
||||
|
@ -461,6 +461,7 @@ static inline int filter_contains_hw_range( unsigned int first, unsigned int las
|
|||
/* get the QS_* bit corresponding to a given hardware message */
|
||||
static inline int get_hardware_msg_bit( struct message *msg )
|
||||
{
|
||||
if (msg->msg == WM_INPUT_DEVICE_CHANGE || msg->msg == WM_INPUT) return QS_RAWINPUT;
|
||||
if (msg->msg == WM_MOUSEMOVE || msg->msg == WM_NCMOUSEMOVE) return QS_MOUSEMOVE;
|
||||
if (is_keyboard_msg( msg )) return QS_KEY;
|
||||
return QS_MOUSEBUTTON;
|
||||
|
@ -489,8 +490,12 @@ static int merge_message( struct thread_input *input, const struct message *msg
|
|||
struct list *ptr;
|
||||
|
||||
if (msg->msg != WM_MOUSEMOVE) return 0;
|
||||
if (!(ptr = list_tail( &input->msg_list ))) return 0;
|
||||
prev = LIST_ENTRY( ptr, struct message, entry );
|
||||
for (ptr = list_tail( &input->msg_list ); ptr; ptr = list_prev( &input->msg_list, ptr ))
|
||||
{
|
||||
prev = LIST_ENTRY( ptr, struct message, entry );
|
||||
if (prev->msg != WM_INPUT) break;
|
||||
}
|
||||
if (!ptr) return 0;
|
||||
if (prev->result) return 0;
|
||||
if (prev->win && msg->win && prev->win != msg->win) return 0;
|
||||
if (prev->msg != msg->msg) return 0;
|
||||
|
@ -507,6 +512,8 @@ static int merge_message( struct thread_input *input, const struct message *msg
|
|||
prev_data->y = msg_data->y;
|
||||
prev_data->info = msg_data->info;
|
||||
}
|
||||
list_remove( ptr );
|
||||
list_add_tail( &input->msg_list, ptr );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1372,7 +1379,11 @@ static user_handle_t find_hardware_message_window( struct desktop *desktop, stru
|
|||
user_handle_t win = 0;
|
||||
|
||||
*msg_code = msg->msg;
|
||||
if (is_keyboard_msg( msg ))
|
||||
if (msg->msg == WM_INPUT)
|
||||
{
|
||||
if (!(win = msg->win) && input) win = input->focus;
|
||||
}
|
||||
else if (is_keyboard_msg( msg ))
|
||||
{
|
||||
if (input && !(win = input->focus))
|
||||
{
|
||||
|
@ -1445,7 +1456,7 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
|
|||
if (msg->wparam == VK_SHIFT || msg->wparam == VK_LSHIFT || msg->wparam == VK_RSHIFT)
|
||||
msg->lparam &= ~(KF_EXTENDED << 16);
|
||||
}
|
||||
else
|
||||
else if (msg->msg != WM_INPUT)
|
||||
{
|
||||
if (msg->msg == WM_MOUSEMOVE)
|
||||
{
|
||||
|
@ -1545,6 +1556,7 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
|
|||
static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
|
||||
unsigned int hook_flags, struct msg_queue *sender )
|
||||
{
|
||||
const struct rawinput_device *device;
|
||||
struct hardware_msg_data *msg_data;
|
||||
struct message *msg;
|
||||
unsigned int i, time, flags;
|
||||
|
@ -1594,6 +1606,35 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
|||
y = desktop->cursor.y;
|
||||
}
|
||||
|
||||
if ((device = current->process->rawinput_mouse))
|
||||
{
|
||||
if (!(msg = mem_alloc( sizeof(*msg) ))) return 0;
|
||||
if (!(msg_data = mem_alloc( sizeof(*msg_data) )))
|
||||
{
|
||||
free( msg );
|
||||
return 0;
|
||||
}
|
||||
|
||||
msg->type = MSG_HARDWARE;
|
||||
msg->win = device->target;
|
||||
msg->msg = WM_INPUT;
|
||||
msg->wparam = RIM_INPUT;
|
||||
msg->lparam = 0;
|
||||
msg->time = time;
|
||||
msg->data = msg_data;
|
||||
msg->data_size = sizeof(*msg_data);
|
||||
msg->result = NULL;
|
||||
|
||||
msg_data->info = input->mouse.info;
|
||||
msg_data->flags = flags;
|
||||
msg_data->rawinput.type = RIM_TYPEMOUSE;
|
||||
msg_data->rawinput.mouse.x = x - desktop->cursor.x;
|
||||
msg_data->rawinput.mouse.y = y - desktop->cursor.y;
|
||||
msg_data->rawinput.mouse.data = input->mouse.data;
|
||||
|
||||
queue_hardware_message( desktop, msg, 0 );
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(messages)/sizeof(messages[0]); i++)
|
||||
{
|
||||
if (!messages[i]) continue;
|
||||
|
@ -1833,7 +1874,7 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
|
|||
}
|
||||
|
||||
if (ptr == list_head( &input->msg_list ))
|
||||
clear_bits = QS_KEY | QS_MOUSEMOVE | QS_MOUSEBUTTON;
|
||||
clear_bits = QS_INPUT;
|
||||
else
|
||||
clear_bits = 0; /* don't clear bits if we don't go through the whole list */
|
||||
|
||||
|
@ -1890,6 +1931,7 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
|
|||
|
||||
data->hw_id = msg->unique_id;
|
||||
set_reply_data( msg->data, msg->data_size );
|
||||
if (msg->msg == WM_INPUT) release_hardware_message( current->queue, data->hw_id, 1, 0 );
|
||||
return 1;
|
||||
}
|
||||
/* nothing found, clear the hardware queue bits */
|
||||
|
@ -2970,10 +3012,14 @@ DECL_HANDLER(update_rawinput_devices)
|
|||
{
|
||||
const struct rawinput_device *devices = get_req_data();
|
||||
unsigned int device_count = get_req_data_size() / sizeof (*devices);
|
||||
const struct rawinput_device_entry *e;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < device_count; ++i)
|
||||
{
|
||||
update_rawinput_device(&devices[i]);
|
||||
}
|
||||
|
||||
e = find_rawinput_device( 1, 2 );
|
||||
current->process->rawinput_mouse = e ? &e->device : NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue