mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 06:21:47 +00:00
server: Send numpad virtual keys if NumLock is active.
If the hardware keyboard event has KBD virtual key information, use it to detect numpad key events and translate them to the appropriate virtual keys depending on NumLock (and Shift) state.
This commit is contained in:
parent
f5f62c945c
commit
11ef7af768
|
@ -1112,6 +1112,31 @@ UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout )
|
|||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* map_scan_to_kbd_vkey
|
||||
*
|
||||
* Map a scancode to a virtual key with KBD information.
|
||||
*/
|
||||
USHORT map_scan_to_kbd_vkey( USHORT scan, HKL layout )
|
||||
{
|
||||
const KBDTABLES *kbd_tables;
|
||||
USHORT vsc2vk[0x300];
|
||||
UINT vkey;
|
||||
|
||||
if ((vkey = user_driver->pMapVirtualKeyEx( scan, MAPVK_VSC_TO_VK_EX, layout )) != -1) return vkey;
|
||||
|
||||
if (!(kbd_tables = user_driver->pKbdLayerDescriptor( layout ))) kbd_tables = &kbdus_tables;
|
||||
|
||||
kbd_tables_init_vsc2vk( kbd_tables, vsc2vk );
|
||||
if (scan & 0xe000) scan -= 0xdf00;
|
||||
if (scan >= ARRAY_SIZE(vsc2vk)) vkey = 0;
|
||||
else vkey = vsc2vk[scan];
|
||||
|
||||
if (kbd_tables != &kbdus_tables) user_driver->pReleaseKbdTables( kbd_tables );
|
||||
|
||||
return vkey;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* NtUserGetKeyNameText (win32u.@)
|
||||
*/
|
||||
|
|
|
@ -3569,7 +3569,7 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA
|
|||
scan = scan & 0xff;
|
||||
if (input->ki.dwFlags & KEYEVENTF_EXTENDEDKEY) scan |= 0xe000;
|
||||
}
|
||||
req->input.kbd.vkey = NtUserMapVirtualKeyEx( scan, MAPVK_VSC_TO_VK_EX, layout );
|
||||
req->input.kbd.vkey = map_scan_to_kbd_vkey( scan, layout );
|
||||
req->input.kbd.scan = input->ki.wScan & 0xff;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -108,6 +108,7 @@ extern void update_mouse_tracking_info( HWND hwnd );
|
|||
extern BOOL get_clip_cursor( RECT *rect );
|
||||
extern BOOL process_wine_clipcursor( HWND hwnd, UINT flags, BOOL reset );
|
||||
extern BOOL clip_fullscreen_window( HWND hwnd, BOOL reset );
|
||||
extern USHORT map_scan_to_kbd_vkey( USHORT scan, HKL layout );
|
||||
|
||||
/* menu.c */
|
||||
extern HMENU create_menu( BOOL is_popup );
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "winternl.h"
|
||||
#include "ntuser.h"
|
||||
#include "hidusage.h"
|
||||
#include "kbd.h"
|
||||
|
||||
#include "handle.h"
|
||||
#include "file.h"
|
||||
|
@ -1763,7 +1764,7 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
|
|||
|
||||
if (input->type == INPUT_KEYBOARD)
|
||||
{
|
||||
unsigned short vkey = input->kbd.vkey;
|
||||
unsigned short vkey = input->kbd.vkey & 0xff;
|
||||
if (input->kbd.flags & KEYEVENTF_UNICODE) vkey = VK_PACKET;
|
||||
msg->lparam = (input->kbd.scan << 16) | vkey;
|
||||
}
|
||||
|
@ -2102,6 +2103,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
|||
struct message *msg;
|
||||
struct thread *foreground;
|
||||
unsigned char vkey = input->kbd.vkey;
|
||||
hw_input_t hook_input = *input;
|
||||
unsigned int message_code, time;
|
||||
int wait;
|
||||
|
||||
|
@ -2171,6 +2173,27 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
|||
break;
|
||||
}
|
||||
|
||||
/* send numpad vkeys if NumLock is active */
|
||||
if ((input->kbd.vkey & KBDNUMPAD) && (desktop->keystate[VK_NUMLOCK] & 0x01) &&
|
||||
!(desktop->keystate[VK_SHIFT] & 0x80))
|
||||
{
|
||||
switch (vkey)
|
||||
{
|
||||
case VK_INSERT: hook_input.kbd.vkey = vkey = VK_NUMPAD0; break;
|
||||
case VK_END: hook_input.kbd.vkey = vkey = VK_NUMPAD1; break;
|
||||
case VK_DOWN: hook_input.kbd.vkey = vkey = VK_NUMPAD2; break;
|
||||
case VK_NEXT: hook_input.kbd.vkey = vkey = VK_NUMPAD3; break;
|
||||
case VK_LEFT: hook_input.kbd.vkey = vkey = VK_NUMPAD4; break;
|
||||
case VK_CLEAR: hook_input.kbd.vkey = vkey = VK_NUMPAD5; break;
|
||||
case VK_RIGHT: hook_input.kbd.vkey = vkey = VK_NUMPAD6; break;
|
||||
case VK_HOME: hook_input.kbd.vkey = vkey = VK_NUMPAD7; break;
|
||||
case VK_UP: hook_input.kbd.vkey = vkey = VK_NUMPAD8; break;
|
||||
case VK_PRIOR: hook_input.kbd.vkey = vkey = VK_NUMPAD9; break;
|
||||
case VK_DELETE: hook_input.kbd.vkey = vkey = VK_DECIMAL; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((foreground = get_foreground_thread( desktop, win )))
|
||||
{
|
||||
struct rawinput_message raw_msg = {0};
|
||||
|
@ -2217,7 +2240,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
|||
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, &hook_input, sender )))
|
||||
queue_hardware_message( desktop, msg, 1 );
|
||||
|
||||
return wait;
|
||||
|
|
Loading…
Reference in a new issue