[PATCH 3/3] user32: Add rawinput keyboard support.
Henri Verbeet
hverbeet at codeweavers.com
Thu Sep 6 14:33:27 CDT 2012
---
dlls/user32/message.c | 35 +++++++++++++++
server/process.c | 1 +
server/process.h | 1 +
server/protocol.def | 7 +++
server/queue.c | 115 +++++++++++++++++++++++++++++++++----------------
5 files changed, 121 insertions(+), 38 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 264eeec..2e81e3a 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -52,6 +52,7 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
WINE_DECLARE_DEBUG_CHANNEL(key);
#define WINE_MOUSE_HANDLE ((HANDLE)1)
+#define WINE_KEYBOARD_HANDLE ((HANDLE)2)
#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
#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 *
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
{
FIXME("Unhandled rawinput type %#x.\n", msg_data->rawinput.type);
diff --git a/server/process.c b/server/process.c
index f6fb772..058538f 100644
--- a/server/process.c
+++ b/server/process.c
@@ -334,6 +334,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
process->token = NULL;
process->trace_data = 0;
process->rawinput_mouse = NULL;
+ process->rawinput_kbd = NULL;
list_init( &process->thread_list );
list_init( &process->locks );
list_init( &process->classes );
diff --git a/server/process.h b/server/process.h
index 4a20c76..284429e 100644
--- a/server/process.h
+++ b/server/process.h
@@ -89,6 +89,7 @@ struct process
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 */
+ const struct rawinput_device *rawinput_kbd; /* rawinput keyboard device, if any */
};
struct process_snapshot
diff --git a/server/protocol.def b/server/protocol.def
index 14e8239..6f101b7 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -300,6 +300,13 @@ struct hardware_msg_data
int type;
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 x; /* x coordinate */
int y; /* y coordinate */
diff --git a/server/queue.c b/server/queue.c
index 840dfbe..df11339 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -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,
unsigned int hook_flags, struct msg_queue *sender )
{
+ const struct rawinput_device *device;
struct hardware_msg_data *msg_data;
struct message *msg;
unsigned char vkey = input->kbd.vkey;
+ unsigned int message_code, time;
int wait;
- 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) );
+ if (!(time = input->kbd.time)) time = get_tick_count();
- msg->type = MSG_HARDWARE;
- 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)
+ if (!(input->kbd.flags & KEYEVENTF_UNICODE))
{
- msg->wparam = VK_PACKET;
- }
- else
- {
- unsigned int flags = 0;
switch (vkey)
{
case VK_MENU:
@@ -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;
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)
{
case VK_LMENU:
@@ -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 */
/* we use 0x02 as a flag to track if some other SYSKEYUP was sent already */
if ((desktop->keystate[VK_MENU] & 0x82) != 0x82) break;
- msg->msg = WM_SYSKEYUP;
+ message_code = WM_SYSKEYUP;
desktop->keystate[VK_MENU] &= ~0x02;
}
else
{
/* send WM_SYSKEYDOWN for Alt except with Ctrl */
if (desktop->keystate[VK_CONTROL] & 0x80) break;
- msg->msg = WM_SYSKEYDOWN;
+ message_code = WM_SYSKEYDOWN;
desktop->keystate[VK_MENU] |= 0x02;
}
break;
@@ -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 */
if (!(input->kbd.flags & KEYEVENTF_KEYUP)) break;
if (!(desktop->keystate[VK_MENU] & 0x80)) break;
- msg->msg = WM_SYSKEYUP;
+ message_code = WM_SYSKEYUP;
desktop->keystate[VK_MENU] &= ~0x02;
break;
@@ -1776,10 +1747,76 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
if (!(desktop->keystate[VK_MENU] & 0x80)) break;
/* fall through */
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;
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 )))
queue_hardware_message( desktop, msg, 1 );
@@ -3021,4 +3058,6 @@ DECL_HANDLER(update_rawinput_devices)
e = find_rawinput_device( 1, 2 );
current->process->rawinput_mouse = e ? &e->device : NULL;
+ e = find_rawinput_device( 1, 6 );
+ current->process->rawinput_kbd = e ? &e->device : NULL;
}
--
1.7.8.6
More information about the wine-patches
mailing list