From 37de2cb434dcce61e8ae07ce4b81213ef97b5d45 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Bernon?= Date: Sat, 7 Jan 2023 17:25:20 +0100 Subject: [PATCH] win32u: Use KBDTABLES for NtUserMapVirtualKeyEx VSC / VK mapping. --- dlls/win32u/input.c | 181 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 111 insertions(+), 70 deletions(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 2b8453d4247..f3ff2182c11 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -207,15 +207,115 @@ static const VSC_LPWSTR key_names_ext[] = {0}, }; +static const USHORT vsc_to_vk[] = +{ + T00, T01, T02, T03, T04, T05, T06, T07, + T08, T09, T0A, T0B, T0C, T0D, T0E, T0F, + T10, T11, T12, T13, T14, T15, T16, T17, + T18, T19, T1A, T1B, T1C, T1D, T1E, T1F, + T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T2A, T2B, T2C, T2D, T2E, T2F, + T30, T31, T32, T33, T34, T35, T36 | KBDEXT, T37 | KBDMULTIVK, + T38, T39, T3A, T3B, T3C, T3D, T3E, T3F, + T40, T41, T42, T43, T44, T45 | KBDEXT | KBDMULTIVK, T46 | KBDMULTIVK, T47 | KBDNUMPAD | KBDSPECIAL, + T48 | KBDNUMPAD | KBDSPECIAL, T49 | KBDNUMPAD | KBDSPECIAL, T4A, T4B | KBDNUMPAD | KBDSPECIAL, + T4C | KBDNUMPAD | KBDSPECIAL, T4D | KBDNUMPAD | KBDSPECIAL, T4E, T4F | KBDNUMPAD | KBDSPECIAL, + T50 | KBDNUMPAD | KBDSPECIAL, T51 | KBDNUMPAD | KBDSPECIAL, T52 | KBDNUMPAD | KBDSPECIAL, + T53 | KBDNUMPAD | KBDSPECIAL, T54, T55, T56, T57, + T58, T59, T5A, T5B, T5C, T5D, T5E, T5F, + T60, T61, T62, T63, T64, T65, T66, T67, + T68, T69, T6A, T6B, T6C, T6D, T6E, T6F, + T70, T71, T72, T73, T74, T75, T76, T77, + T78, T79, T7A, T7B, T7C, T7D, T7E +}; + +static const VSC_VK vsc_to_vk_e0[] = +{ + {0x10, X10 | KBDEXT}, + {0x19, X19 | KBDEXT}, + {0x1d, X1D | KBDEXT}, + {0x20, X20 | KBDEXT}, + {0x21, X21 | KBDEXT}, + {0x22, X22 | KBDEXT}, + {0x24, X24 | KBDEXT}, + {0x2e, X2E | KBDEXT}, + {0x30, X30 | KBDEXT}, + {0x32, X32 | KBDEXT}, + {0x35, X35 | KBDEXT}, + {0x37, X37 | KBDEXT}, + {0x38, X38 | KBDEXT}, + {0x47, X47 | KBDEXT}, + {0x48, X48 | KBDEXT}, + {0x49, X49 | KBDEXT}, + {0x4b, X4B | KBDEXT}, + {0x4d, X4D | KBDEXT}, + {0x4f, X4F | KBDEXT}, + {0x50, X50 | KBDEXT}, + {0x51, X51 | KBDEXT}, + {0x52, X52 | KBDEXT}, + {0x53, X53 | KBDEXT}, + {0x5b, X5B | KBDEXT}, + {0x5c, X5C | KBDEXT}, + {0x5d, X5D | KBDEXT}, + {0x5f, X5F | KBDEXT}, + {0x65, X65 | KBDEXT}, + {0x66, X66 | KBDEXT}, + {0x67, X67 | KBDEXT}, + {0x68, X68 | KBDEXT}, + {0x69, X69 | KBDEXT}, + {0x6a, X6A | KBDEXT}, + {0x6b, X6B | KBDEXT}, + {0x6c, X6C | KBDEXT}, + {0x6d, X6D | KBDEXT}, + {0x1c, X1C | KBDEXT}, + {0x46, X46 | KBDEXT}, + {0}, +}; + +static const VSC_VK vsc_to_vk_e1[] = +{ + {0x1d, Y1D}, + {0}, +}; + static const KBDTABLES kbdus_tables = { .pKeyNames = (VSC_LPWSTR *)key_names, .pKeyNamesExt = (VSC_LPWSTR *)key_names_ext, + .pusVSCtoVK = (USHORT *)vsc_to_vk, + .bMaxVSCtoVK = sizeof(vsc_to_vk) / sizeof(vsc_to_vk[0]), + .pVSCtoVK_E0 = (VSC_VK *)vsc_to_vk_e0, + .pVSCtoVK_E1 = (VSC_VK *)vsc_to_vk_e1, }; LONG global_key_state_counter = 0; + +static void kbd_tables_init_vsc2vk( const KBDTABLES *tables, BYTE vsc2vk[0x300] ) +{ + const VSC_VK *entry; + WORD vsc; + + memset( vsc2vk, 0, 0x300 ); + + for (vsc = 0; tables->pusVSCtoVK && vsc <= tables->bMaxVSCtoVK; ++vsc) + { + if (tables->pusVSCtoVK[vsc] == VK__none_) continue; + vsc2vk[vsc] = (BYTE)tables->pusVSCtoVK[vsc]; + } + for (entry = tables->pVSCtoVK_E0; entry && entry->Vsc; entry++) + { + if (entry->Vk == VK__none_) continue; + vsc2vk[entry->Vsc + 0x100] = (BYTE)entry->Vk; + } + for (entry = tables->pVSCtoVK_E1; entry && entry->Vsc; entry++) + { + if (entry->Vk == VK__none_) continue; + vsc2vk[entry->Vsc + 0x200] = (BYTE)entry->Vk; + } +} + /********************************************************************** * NtUserAttachThreadInput (win32u.@) */ @@ -716,61 +816,6 @@ WORD WINAPI NtUserVkKeyScanEx( WCHAR chr, HKL layout ) return ret; } -/* English keyboard layout (0x0409) */ -static const UINT kbd_en_vsc2vk[] = -{ - 0x00, 0x1b, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0xbd, 0xbb, 0x08, 0x09, - 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4f, 0x50, 0xdb, 0xdd, 0x0d, 0xa2, 0x41, 0x53, - 0x44, 0x46, 0x47, 0x48, 0x4a, 0x4b, 0x4c, 0xba, 0xde, 0xc0, 0xa0, 0xdc, 0x5a, 0x58, 0x43, 0x56, - 0x42, 0x4e, 0x4d, 0xbc, 0xbe, 0xbf, 0xa1, 0x6a, 0xa4, 0x20, 0x14, 0x70, 0x71, 0x72, 0x73, 0x74, - 0x75, 0x76, 0x77, 0x78, 0x79, 0x90, 0x91, 0x24, 0x26, 0x21, 0x6d, 0x25, 0x0c, 0x27, 0x6b, 0x23, - 0x28, 0x22, 0x2d, 0x2e, 0x2c, 0x00, 0xe2, 0x7a, 0x7b, 0x0c, 0xee, 0xf1, 0xea, 0xf9, 0xf5, 0xf3, - 0x00, 0x00, 0xfb, 0x2f, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0xed, - 0x00, 0xe9, 0x00, 0xc1, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x09, 0x00, 0xc2, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 0xe000 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x0d, 0xa3, 0x00, 0x00, - 0xad, 0xb7, 0xb3, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0x00, - 0xaf, 0x00, 0xac, 0x00, 0x00, 0x6f, 0x00, 0x2c, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x24, 0x26, 0x21, 0x00, 0x25, 0x00, 0x27, 0x00, 0x23, - 0x28, 0x22, 0x2d, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x5c, 0x5d, 0x00, 0x5f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xab, 0xa8, 0xa9, 0xa7, 0xa6, 0xb6, 0xb4, 0xb5, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 0xe100 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - static const UINT kbd_en_vk2char[] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, @@ -796,18 +841,18 @@ static const UINT kbd_en_vk2char[] = */ UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout ) { - const UINT *vsc2vk, *vk2char; - UINT vsc2vk_size, vk2char_size; + const KBDTABLES *kbd_tables = &kbdus_tables; + const UINT *vk2char; + BYTE vsc2vk[0x300]; + UINT vk2char_size; UINT ret; TRACE_(keyboard)( "code %u, type %u, layout %p.\n", code, type, layout ); if ((ret = user_driver->pMapVirtualKeyEx( code, type, layout )) != -1) return ret; - /* FIXME: English keyboard layout specific */ + kbd_tables_init_vsc2vk( kbd_tables, vsc2vk ); - vsc2vk = kbd_en_vsc2vk; - vsc2vk_size = ARRAYSIZE(kbd_en_vsc2vk); vk2char = kbd_en_vk2char; vk2char_size = ARRAYSIZE(kbd_en_vk2char); @@ -833,8 +878,8 @@ UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout ) case VK_DECIMAL: code = VK_DELETE; break; } - for (ret = 0; ret < vsc2vk_size; ++ret) if (vsc2vk[ret] == code) break; - if (ret >= vsc2vk_size) ret = 0; + for (ret = 0; ret < ARRAY_SIZE(vsc2vk); ++ret) if (vsc2vk[ret] == code) break; + if (ret >= ARRAY_SIZE(vsc2vk)) ret = 0; if (type == MAPVK_VK_TO_VSC) { @@ -846,7 +891,7 @@ UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout ) case MAPVK_VSC_TO_VK: case MAPVK_VSC_TO_VK_EX: if (code & 0xe000) code -= 0xdf00; - if (code >= vsc2vk_size) ret = 0; + if (code >= ARRAY_SIZE(vsc2vk)) ret = 0; else ret = vsc2vk[code]; if (type == MAPVK_VSC_TO_VK) @@ -880,18 +925,14 @@ INT WINAPI NtUserGetKeyNameText( LONG lparam, WCHAR *buffer, INT size ) INT code = ((lparam >> 16) & 0x1ff), vkey, len; const KBDTABLES *kbd_tables = &kbdus_tables; VSC_LPWSTR *key_name; - const UINT *vsc2vk; - UINT vsc2vk_size; + BYTE vsc2vk[0x300]; TRACE_(keyboard)( "lparam %#x, buffer %p, size %d.\n", (int)lparam, buffer, size ); if (!buffer || !size) return 0; if ((len = user_driver->pGetKeyNameText( lparam, buffer, size )) >= 0) return len; - /* FIXME: English keyboard layout specific */ - - vsc2vk = kbd_en_vsc2vk; - vsc2vk_size = ARRAYSIZE(kbd_en_vsc2vk); + kbd_tables_init_vsc2vk( kbd_tables, vsc2vk ); if (lparam & 0x2000000) { @@ -900,7 +941,7 @@ INT WINAPI NtUserGetKeyNameText( LONG lparam, WCHAR *buffer, INT size ) case VK_RSHIFT: case VK_RCONTROL: case VK_RMENU: - for (code = 0; code < vsc2vk_size; ++code) + for (code = 0; code < ARRAY_SIZE(vsc2vk); ++code) if (vsc2vk[code] == (vkey - 1)) break; break; } -- 2.11.4.GIT