user32: Add rawinput keyboard support.
This commit is contained in:
parent
706ece827b
commit
c6fcc0255c
|
@ -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);
|
||||
|
|
|
@ -283,6 +283,13 @@ struct hardware_msg_data
|
|||
{
|
||||
int type;
|
||||
struct
|
||||
{
|
||||
int type;
|
||||
unsigned int message;
|
||||
unsigned short vkey;
|
||||
unsigned short scan;
|
||||
} kbd;
|
||||
struct
|
||||
{
|
||||
int type;
|
||||
int x;
|
||||
|
@ -5683,6 +5690,6 @@ union generic_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 */
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -299,6 +299,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 */
|
||||
|
|
171
server/queue.c
171
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,6 +1708,105 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
|||
vkey = (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) ? VK_RSHIFT : VK_LSHIFT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
message_code = (input->kbd.flags & KEYEVENTF_KEYUP) ? WM_KEYUP : WM_KEYDOWN;
|
||||
switch (vkey)
|
||||
{
|
||||
case VK_LMENU:
|
||||
case VK_RMENU:
|
||||
if (input->kbd.flags & KEYEVENTF_KEYUP)
|
||||
{
|
||||
/* 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;
|
||||
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;
|
||||
message_code = WM_SYSKEYDOWN;
|
||||
desktop->keystate[VK_MENU] |= 0x02;
|
||||
}
|
||||
break;
|
||||
|
||||
case VK_LCONTROL:
|
||||
case VK_RCONTROL:
|
||||
/* send WM_SYSKEYUP on release if Alt still pressed */
|
||||
if (!(input->kbd.flags & KEYEVENTF_KEYUP)) break;
|
||||
if (!(desktop->keystate[VK_MENU] & 0x80)) break;
|
||||
message_code = WM_SYSKEYUP;
|
||||
desktop->keystate[VK_MENU] &= ~0x02;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* send WM_SYSKEY for Alt-anykey and for F10 */
|
||||
if (desktop->keystate[VK_CONTROL] & 0x80) break;
|
||||
if (!(desktop->keystate[VK_MENU] & 0x80)) break;
|
||||
/* fall through */
|
||||
case VK_F10:
|
||||
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;
|
||||
|
@ -1738,48 +1817,6 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
|||
msg_data->flags |= (flags & (KF_EXTENDED | KF_ALTDOWN | KF_UP)) >> 8;
|
||||
}
|
||||
|
||||
msg->msg = (input->kbd.flags & KEYEVENTF_KEYUP) ? WM_KEYUP : WM_KEYDOWN;
|
||||
|
||||
switch (vkey)
|
||||
{
|
||||
case VK_LMENU:
|
||||
case VK_RMENU:
|
||||
if (input->kbd.flags & KEYEVENTF_KEYUP)
|
||||
{
|
||||
/* 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;
|
||||
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;
|
||||
desktop->keystate[VK_MENU] |= 0x02;
|
||||
}
|
||||
break;
|
||||
|
||||
case VK_LCONTROL:
|
||||
case VK_RCONTROL:
|
||||
/* 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;
|
||||
desktop->keystate[VK_MENU] &= ~0x02;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* send WM_SYSKEY for Alt-anykey and for F10 */
|
||||
if (desktop->keystate[VK_CONTROL] & 0x80) break;
|
||||
if (!(desktop->keystate[VK_MENU] & 0x80)) break;
|
||||
/* fall through */
|
||||
case VK_F10:
|
||||
msg->msg = (input->kbd.flags & KEYEVENTF_KEYUP) ? WM_SYSKEYUP : WM_SYSKEYDOWN;
|
||||
desktop->keystate[VK_MENU] &= ~0x02;
|
||||
break;
|
||||
}
|
||||
if (!(wait = send_hook_ll_message( desktop, msg, input, sender )))
|
||||
queue_hardware_message( desktop, msg, 1 );
|
||||
|
||||
|
@ -3022,4 +3059,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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue