Commit c6fcc025 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

user32: Add rawinput keyboard support.

parent 706ece82
...@@ -52,6 +52,7 @@ WINE_DECLARE_DEBUG_CHANNEL(relay); ...@@ -52,6 +52,7 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
WINE_DECLARE_DEBUG_CHANNEL(key); WINE_DECLARE_DEBUG_CHANNEL(key);
#define WINE_MOUSE_HANDLE ((HANDLE)1) #define WINE_MOUSE_HANDLE ((HANDLE)1)
#define WINE_KEYBOARD_HANDLE ((HANDLE)2)
#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE #define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
#define WM_NCMOUSELAST (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST)) #define WM_NCMOUSELAST (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST))
...@@ -2338,6 +2339,40 @@ static BOOL process_rawinput_message( MSG *msg, const struct hardware_msg_data * ...@@ -2338,6 +2339,40 @@ static BOOL process_rawinput_message( MSG *msg, const struct hardware_msg_data *
rawinput->data.mouse.lLastY = msg_data->rawinput.mouse.y; rawinput->data.mouse.lLastY = msg_data->rawinput.mouse.y;
rawinput->data.mouse.ulExtraInformation = msg_data->info; 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 else
{ {
FIXME("Unhandled rawinput type %#x.\n", msg_data->rawinput.type); FIXME("Unhandled rawinput type %#x.\n", msg_data->rawinput.type);
......
...@@ -285,6 +285,13 @@ struct hardware_msg_data ...@@ -285,6 +285,13 @@ struct hardware_msg_data
struct struct
{ {
int type; int type;
unsigned int message;
unsigned short vkey;
unsigned short scan;
} kbd;
struct
{
int type;
int x; int x;
int y; int y;
unsigned int data; unsigned int data;
...@@ -5683,6 +5690,6 @@ union generic_reply ...@@ -5683,6 +5690,6 @@ union generic_reply
struct set_suspend_context_reply set_suspend_context_reply; struct set_suspend_context_reply set_suspend_context_reply;
}; };
#define SERVER_PROTOCOL_VERSION 434 #define SERVER_PROTOCOL_VERSION 435
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -334,6 +334,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit ...@@ -334,6 +334,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
process->token = NULL; process->token = NULL;
process->trace_data = 0; process->trace_data = 0;
process->rawinput_mouse = NULL; process->rawinput_mouse = NULL;
process->rawinput_kbd = NULL;
list_init( &process->thread_list ); list_init( &process->thread_list );
list_init( &process->locks ); list_init( &process->locks );
list_init( &process->classes ); list_init( &process->classes );
......
...@@ -89,6 +89,7 @@ struct process ...@@ -89,6 +89,7 @@ struct process
unsigned int trace_data; /* opaque data used by the process tracing mechanism */ unsigned int trace_data; /* opaque data used by the process tracing mechanism */
struct list rawinput_devices;/* list of registered rawinput devices */ struct list rawinput_devices;/* list of registered rawinput devices */
const struct rawinput_device *rawinput_mouse; /* rawinput mouse device, if any */ const struct rawinput_device *rawinput_mouse; /* rawinput mouse device, if any */
const struct rawinput_device *rawinput_kbd; /* rawinput keyboard device, if any */
}; };
struct process_snapshot struct process_snapshot
......
...@@ -300,6 +300,13 @@ struct hardware_msg_data ...@@ -300,6 +300,13 @@ struct hardware_msg_data
int type; int type;
struct struct
{ {
int type; /* RIM_TYPEKEYBOARD */
unsigned int message; /* message generated by this rawinput event */
unsigned short vkey; /* virtual key code */
unsigned short scan; /* scan code */
} kbd;
struct
{
int type; /* RIM_TYPEMOUSE */ int type; /* RIM_TYPEMOUSE */
int x; /* x coordinate */ int x; /* x coordinate */
int y; /* y coordinate */ int y; /* y coordinate */
......
...@@ -1679,37 +1679,17 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons ...@@ -1679,37 +1679,17 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input, static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
unsigned int hook_flags, struct msg_queue *sender ) unsigned int hook_flags, struct msg_queue *sender )
{ {
const struct rawinput_device *device;
struct hardware_msg_data *msg_data; struct hardware_msg_data *msg_data;
struct message *msg; struct message *msg;
unsigned char vkey = input->kbd.vkey; unsigned char vkey = input->kbd.vkey;
unsigned int message_code, time;
int wait; int wait;
if (!(msg = mem_alloc( sizeof(*msg) ))) return 0; if (!(time = input->kbd.time)) time = get_tick_count();
if (!(msg_data = mem_alloc( sizeof(*msg_data) )))
{
free( msg );
return 0;
}
memset( msg_data, 0, sizeof(*msg_data) );
msg->type = MSG_HARDWARE; if (!(input->kbd.flags & KEYEVENTF_UNICODE))
msg->win = get_user_full_handle( win );
msg->lparam = (input->kbd.scan << 16) | 1u; /* repeat count */
msg->time = input->kbd.time;
msg->result = NULL;
msg->data = msg_data;
msg->data_size = sizeof(*msg_data);
msg_data->info = input->kbd.info;
if (!msg->time) msg->time = get_tick_count();
if (hook_flags & SEND_HWMSG_INJECTED) msg_data->flags = LLKHF_INJECTED;
if (input->kbd.flags & KEYEVENTF_UNICODE)
{ {
msg->wparam = VK_PACKET;
}
else
{
unsigned int flags = 0;
switch (vkey) switch (vkey)
{ {
case VK_MENU: case VK_MENU:
...@@ -1728,18 +1708,9 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c ...@@ -1728,18 +1708,9 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
vkey = (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) ? VK_RSHIFT : VK_LSHIFT; vkey = (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) ? VK_RSHIFT : VK_LSHIFT;
break; break;
} }
if (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) flags |= KF_EXTENDED;
/* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */
if (input->kbd.flags & KEYEVENTF_KEYUP) flags |= KF_REPEAT | KF_UP;
else if (desktop->keystate[vkey] & 0x80) flags |= KF_REPEAT;
msg->wparam = vkey;
msg->lparam |= flags << 16;
msg_data->flags |= (flags & (KF_EXTENDED | KF_ALTDOWN | KF_UP)) >> 8;
} }
msg->msg = (input->kbd.flags & KEYEVENTF_KEYUP) ? WM_KEYUP : WM_KEYDOWN; message_code = (input->kbd.flags & KEYEVENTF_KEYUP) ? WM_KEYUP : WM_KEYDOWN;
switch (vkey) switch (vkey)
{ {
case VK_LMENU: case VK_LMENU:
...@@ -1749,14 +1720,14 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c ...@@ -1749,14 +1720,14 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
/* send WM_SYSKEYUP if Alt still pressed and no other key in between */ /* send WM_SYSKEYUP if Alt still pressed and no other key in between */
/* we use 0x02 as a flag to track if some other SYSKEYUP was sent already */ /* we use 0x02 as a flag to track if some other SYSKEYUP was sent already */
if ((desktop->keystate[VK_MENU] & 0x82) != 0x82) break; if ((desktop->keystate[VK_MENU] & 0x82) != 0x82) break;
msg->msg = WM_SYSKEYUP; message_code = WM_SYSKEYUP;
desktop->keystate[VK_MENU] &= ~0x02; desktop->keystate[VK_MENU] &= ~0x02;
} }
else else
{ {
/* send WM_SYSKEYDOWN for Alt except with Ctrl */ /* send WM_SYSKEYDOWN for Alt except with Ctrl */
if (desktop->keystate[VK_CONTROL] & 0x80) break; if (desktop->keystate[VK_CONTROL] & 0x80) break;
msg->msg = WM_SYSKEYDOWN; message_code = WM_SYSKEYDOWN;
desktop->keystate[VK_MENU] |= 0x02; desktop->keystate[VK_MENU] |= 0x02;
} }
break; break;
...@@ -1766,7 +1737,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c ...@@ -1766,7 +1737,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
/* send WM_SYSKEYUP on release if Alt still pressed */ /* send WM_SYSKEYUP on release if Alt still pressed */
if (!(input->kbd.flags & KEYEVENTF_KEYUP)) break; if (!(input->kbd.flags & KEYEVENTF_KEYUP)) break;
if (!(desktop->keystate[VK_MENU] & 0x80)) break; if (!(desktop->keystate[VK_MENU] & 0x80)) break;
msg->msg = WM_SYSKEYUP; message_code = WM_SYSKEYUP;
desktop->keystate[VK_MENU] &= ~0x02; desktop->keystate[VK_MENU] &= ~0x02;
break; break;
...@@ -1776,10 +1747,76 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c ...@@ -1776,10 +1747,76 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
if (!(desktop->keystate[VK_MENU] & 0x80)) break; if (!(desktop->keystate[VK_MENU] & 0x80)) break;
/* fall through */ /* fall through */
case VK_F10: case VK_F10:
msg->msg = (input->kbd.flags & KEYEVENTF_KEYUP) ? WM_SYSKEYUP : WM_SYSKEYDOWN; message_code = (input->kbd.flags & KEYEVENTF_KEYUP) ? WM_SYSKEYUP : WM_SYSKEYDOWN;
desktop->keystate[VK_MENU] &= ~0x02; desktop->keystate[VK_MENU] &= ~0x02;
break; break;
} }
if ((device = current->process->rawinput_kbd))
{
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->kbd.info;
msg_data->flags = input->kbd.flags;
msg_data->rawinput.type = RIM_TYPEKEYBOARD;
msg_data->rawinput.kbd.message = message_code;
msg_data->rawinput.kbd.vkey = vkey;
msg_data->rawinput.kbd.scan = input->kbd.scan;
queue_hardware_message( desktop, msg, 0 );
}
if (!(msg = mem_alloc( sizeof(*msg) ))) return 0;
if (!(msg_data = mem_alloc( sizeof(*msg_data) )))
{
free( msg );
return 0;
}
memset( msg_data, 0, sizeof(*msg_data) );
msg->type = MSG_HARDWARE;
msg->win = get_user_full_handle( win );
msg->msg = message_code;
msg->lparam = (input->kbd.scan << 16) | 1u; /* repeat count */
msg->time = time;
msg->result = NULL;
msg->data = msg_data;
msg->data_size = sizeof(*msg_data);
msg_data->info = input->kbd.info;
if (hook_flags & SEND_HWMSG_INJECTED) msg_data->flags = LLKHF_INJECTED;
if (input->kbd.flags & KEYEVENTF_UNICODE)
{
msg->wparam = VK_PACKET;
}
else
{
unsigned int flags = 0;
if (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) flags |= KF_EXTENDED;
/* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */
if (input->kbd.flags & KEYEVENTF_KEYUP) flags |= KF_REPEAT | KF_UP;
else if (desktop->keystate[vkey] & 0x80) flags |= KF_REPEAT;
msg->wparam = vkey;
msg->lparam |= flags << 16;
msg_data->flags |= (flags & (KF_EXTENDED | KF_ALTDOWN | KF_UP)) >> 8;
}
if (!(wait = send_hook_ll_message( desktop, msg, input, sender ))) if (!(wait = send_hook_ll_message( desktop, msg, input, sender )))
queue_hardware_message( desktop, msg, 1 ); queue_hardware_message( desktop, msg, 1 );
...@@ -3022,4 +3059,6 @@ DECL_HANDLER(update_rawinput_devices) ...@@ -3022,4 +3059,6 @@ DECL_HANDLER(update_rawinput_devices)
e = find_rawinput_device( 1, 2 ); e = find_rawinput_device( 1, 2 );
current->process->rawinput_mouse = e ? &e->device : NULL; current->process->rawinput_mouse = e ? &e->device : NULL;
e = find_rawinput_device( 1, 6 );
current->process->rawinput_kbd = e ? &e->device : NULL;
} }
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