summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2020-10-17 10:27:36 +0200
committerLars-Dominik Braun <lars@6xq.net>2020-10-17 10:27:36 +0200
commit6a2262a7f9bf2ab16ecfdfc52e548ef010c76e00 (patch)
tree5bde18ebb75f52a28758d86dd27e2e759af58b09
parent0d31404e538bc3ed60dfa78a8d9df757f98b82c3 (diff)
downloadlulua-6a2262a7f9bf2ab16ecfdfc52e548ef010c76e00.tar.gz
lulua-6a2262a7f9bf2ab16ecfdfc52e548ef010c76e00.tar.bz2
lulua-6a2262a7f9bf2ab16ecfdfc52e548ef010c76e00.zip
winkbd: Improve rendering
Create self-containted, minimal, but still human-readable C file with all typedefs. Gets rid of the copied header file and all of its weird ifdef logic. Simplifies virtual scancode to virtual key mapping.
-rwxr-xr-xgen.sh4
-rw-r--r--lulua/data/winkbd/build.ninja2
-rw-r--r--lulua/data/winkbd/kbd.h2478
-rw-r--r--lulua/data/winkbd/keyboard.c349
-rw-r--r--lulua/data/winkbd/keyboard.h36
-rw-r--r--lulua/keyboard.py130
-rw-r--r--lulua/render.py247
-rw-r--r--lulua/winkbd.py825
8 files changed, 914 insertions, 3157 deletions
diff --git a/gen.sh b/gen.sh
index 5f4878d..f02a89c 100755
--- a/gen.sh
+++ b/gen.sh
@@ -149,9 +149,9 @@ for f in $(ls lulua/data/winkbd/); do
echo "build \$tempdir/winkbd/$f: cp lulua/data/winkbd/$f || \$tempdir/winkbd"
w64infiles+=" \$tempdir/winkbd/$f"
done
-w64infiles+=" \$tempdir/winkbd/customization.h"
+w64infiles+=" \$tempdir/winkbd/keyboard.c"
cat <<EOF
-build \$tempdir/winkbd/customization.h: render-winkbd || \$tempdir/winkbd
+build \$tempdir/winkbd/keyboard.c: render-winkbd || \$tempdir/winkbd
build \$tempdir/ar-lulua-w64: mkdir
build \$tempdir/winkbd/System32/kbdarlulua.dll \$tempdir/winkbd/SysWOW64/kbdarlulua.dll: ninjaC | $w64infiles
dir = \$tempdir/winkbd
diff --git a/lulua/data/winkbd/build.ninja b/lulua/data/winkbd/build.ninja
index 4b80e3d..faf8945 100644
--- a/lulua/data/winkbd/build.ninja
+++ b/lulua/data/winkbd/build.ninja
@@ -1,7 +1,7 @@
# based on https://github.com/reactos/reactos/blob/893a3c9d030fd8b078cbd747eeefd3f6ce57e560/dll/keyboard/CMakeLists.txt
imageBase=0x5FFF0000
ldflags=-shared -nostartfiles -nodefaultlibs -s -Wl,--subsystem,native:5.01 -Wl,--image-base,$imageBase -Wl,-entry,0 -Wl,-T,linker.ld
-cflags=
+cflags=-Wall -Wextra -Werror
rule mkdir
command = mkdir -p $out
diff --git a/lulua/data/winkbd/kbd.h b/lulua/data/winkbd/kbd.h
deleted file mode 100644
index 1c7478c..0000000
--- a/lulua/data/winkbd/kbd.h
+++ /dev/null
@@ -1,2478 +0,0 @@
-/****************************** Module Header ******************************\
-* Module Name: kbd.h
-*
-* Copyright (c) Microsoft Corporation. All rights reserved.
-*
-* Keyboard table values that form the basis for languages and keyboard types.
-* The basis is US, kbd type 4 - all others are a variation on this.
-* This file is included by all kbd**.h files.
-*
-* History:
-@@BEGIN_DDKSPLIT
-* 10-Jan-1991 GregoryW
-* 23-Apr-1991 IanJa VSC_TO_VK _* macros from oemtab.c
-@@END_DDKSPLIT
-\***************************************************************************/
-
-#ifndef _KBD_
-#define _KBD_
-
-#include <wchar.h>
-
-typedef void VOID;
-typedef unsigned char BYTE;
-typedef unsigned short WORD;
-typedef unsigned short USHORT;
-typedef unsigned long DWORD;
-typedef unsigned long DWORD_PTR;
-typedef unsigned long ULONG;
-typedef long LONG;
-typedef unsigned int UINT;
-typedef int INT;
-typedef wchar_t WCHAR;
-#define MAKELONG(a, b) ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16))
-
-/*
- * Virtual Keys, Standard Set
- */
-#define VK_LBUTTON 0x01
-#define VK_RBUTTON 0x02
-#define VK_CANCEL 0x03
-#define VK_MBUTTON 0x04 /* NOT contiguous with L & RBUTTON */
-
-#if(_WIN32_WINNT >= 0x0500)
-#define VK_XBUTTON1 0x05 /* NOT contiguous with L & RBUTTON */
-#define VK_XBUTTON2 0x06 /* NOT contiguous with L & RBUTTON */
-#endif /* _WIN32_WINNT >= 0x0500 */
-
-/*
- * 0x07 : unassigned
- */
-
-#define VK_BACK 0x08
-#define VK_TAB 0x09
-
-/*
- * 0x0A - 0x0B : reserved
- */
-
-#define VK_CLEAR 0x0C
-#define VK_RETURN 0x0D
-
-#define VK_SHIFT 0x10
-#define VK_CONTROL 0x11
-#define VK_MENU 0x12
-#define VK_PAUSE 0x13
-#define VK_CAPITAL 0x14
-
-#define VK_KANA 0x15
-#define VK_HANGEUL 0x15 /* old name - should be here for compatibility */
-#define VK_HANGUL 0x15
-#define VK_JUNJA 0x17
-#define VK_FINAL 0x18
-#define VK_HANJA 0x19
-#define VK_KANJI 0x19
-
-#define VK_ESCAPE 0x1B
-
-#define VK_CONVERT 0x1C
-#define VK_NONCONVERT 0x1D
-#define VK_ACCEPT 0x1E
-#define VK_MODECHANGE 0x1F
-
-#define VK_SPACE 0x20
-#define VK_PRIOR 0x21
-#define VK_NEXT 0x22
-#define VK_END 0x23
-#define VK_HOME 0x24
-#define VK_LEFT 0x25
-#define VK_UP 0x26
-#define VK_RIGHT 0x27
-#define VK_DOWN 0x28
-#define VK_SELECT 0x29
-#define VK_PRINT 0x2A
-#define VK_EXECUTE 0x2B
-#define VK_SNAPSHOT 0x2C
-#define VK_INSERT 0x2D
-#define VK_DELETE 0x2E
-#define VK_HELP 0x2F
-
-/*
- * VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
- * 0x40 : unassigned
- * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
- */
-
-#define VK_LWIN 0x5B
-#define VK_RWIN 0x5C
-#define VK_APPS 0x5D
-
-/*
- * 0x5E : reserved
- */
-
-#define VK_SLEEP 0x5F
-
-#define VK_NUMPAD0 0x60
-#define VK_NUMPAD1 0x61
-#define VK_NUMPAD2 0x62
-#define VK_NUMPAD3 0x63
-#define VK_NUMPAD4 0x64
-#define VK_NUMPAD5 0x65
-#define VK_NUMPAD6 0x66
-#define VK_NUMPAD7 0x67
-#define VK_NUMPAD8 0x68
-#define VK_NUMPAD9 0x69
-#define VK_MULTIPLY 0x6A
-#define VK_ADD 0x6B
-#define VK_SEPARATOR 0x6C
-#define VK_SUBTRACT 0x6D
-#define VK_DECIMAL 0x6E
-#define VK_DIVIDE 0x6F
-#define VK_F1 0x70
-#define VK_F2 0x71
-#define VK_F3 0x72
-#define VK_F4 0x73
-#define VK_F5 0x74
-#define VK_F6 0x75
-#define VK_F7 0x76
-#define VK_F8 0x77
-#define VK_F9 0x78
-#define VK_F10 0x79
-#define VK_F11 0x7A
-#define VK_F12 0x7B
-#define VK_F13 0x7C
-#define VK_F14 0x7D
-#define VK_F15 0x7E
-#define VK_F16 0x7F
-#define VK_F17 0x80
-#define VK_F18 0x81
-#define VK_F19 0x82
-#define VK_F20 0x83
-#define VK_F21 0x84
-#define VK_F22 0x85
-#define VK_F23 0x86
-#define VK_F24 0x87
-
-/*
- * 0x88 - 0x8F : unassigned
- */
-
-#define VK_NUMLOCK 0x90
-#define VK_SCROLL 0x91
-
-/*
- * NEC PC-9800 kbd definitions
- */
-#define VK_OEM_NEC_EQUAL 0x92 // '=' key on numpad
-
-/*
- * Fujitsu/OASYS kbd definitions
- */
-#define VK_OEM_FJ_JISHO 0x92 // 'Dictionary' key
-#define VK_OEM_FJ_MASSHOU 0x93 // 'Unregister word' key
-#define VK_OEM_FJ_TOUROKU 0x94 // 'Register word' key
-#define VK_OEM_FJ_LOYA 0x95 // 'Left OYAYUBI' key
-#define VK_OEM_FJ_ROYA 0x96 // 'Right OYAYUBI' key
-
-/*
- * 0x97 - 0x9F : unassigned
- */
-
-/*
- * VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys.
- * Used only as parameters to GetAsyncKeyState() and GetKeyState().
- * No other API or message will distinguish left and right keys in this way.
- */
-#define VK_LSHIFT 0xA0
-#define VK_RSHIFT 0xA1
-#define VK_LCONTROL 0xA2
-#define VK_RCONTROL 0xA3
-#define VK_LMENU 0xA4
-#define VK_RMENU 0xA5
-
-#if(_WIN32_WINNT >= 0x0500)
-#define VK_BROWSER_BACK 0xA6
-#define VK_BROWSER_FORWARD 0xA7
-#define VK_BROWSER_REFRESH 0xA8
-#define VK_BROWSER_STOP 0xA9
-#define VK_BROWSER_SEARCH 0xAA
-#define VK_BROWSER_FAVORITES 0xAB
-#define VK_BROWSER_HOME 0xAC
-
-#define VK_VOLUME_MUTE 0xAD
-#define VK_VOLUME_DOWN 0xAE
-#define VK_VOLUME_UP 0xAF
-#define VK_MEDIA_NEXT_TRACK 0xB0
-#define VK_MEDIA_PREV_TRACK 0xB1
-#define VK_MEDIA_STOP 0xB2
-#define VK_MEDIA_PLAY_PAUSE 0xB3
-#define VK_LAUNCH_MAIL 0xB4
-#define VK_LAUNCH_MEDIA_SELECT 0xB5
-#define VK_LAUNCH_APP1 0xB6
-#define VK_LAUNCH_APP2 0xB7
-
-#endif /* _WIN32_WINNT >= 0x0500 */
-
-/*
- * 0xB8 - 0xB9 : reserved
- */
-
-#define VK_OEM_1 0xBA // ';:' for US
-#define VK_OEM_PLUS 0xBB // '+' any country
-#define VK_OEM_COMMA 0xBC // ',' any country
-#define VK_OEM_MINUS 0xBD // '-' any country
-#define VK_OEM_PERIOD 0xBE // '.' any country
-#define VK_OEM_2 0xBF // '/?' for US
-#define VK_OEM_3 0xC0 // '`~' for US
-
-/*
- * 0xC1 - 0xD7 : reserved
- */
-
-/*
- * 0xD8 - 0xDA : unassigned
- */
-
-#define VK_OEM_4 0xDB // '[{' for US
-#define VK_OEM_5 0xDC // '\|' for US
-#define VK_OEM_6 0xDD // ']}' for US
-#define VK_OEM_7 0xDE // ''"' for US
-#define VK_OEM_8 0xDF
-
-/*
- * 0xE0 : reserved
- */
-
-/*
- * Various extended or enhanced keyboards
- */
-#define VK_OEM_AX 0xE1 // 'AX' key on Japanese AX kbd
-#define VK_OEM_102 0xE2 // "<>" or "\|" on RT 102-key kbd.
-#define VK_ICO_HELP 0xE3 // Help key on ICO
-#define VK_ICO_00 0xE4 // 00 key on ICO
-
-#if(WINVER >= 0x0400)
-#define VK_PROCESSKEY 0xE5
-#endif /* WINVER >= 0x0400 */
-
-#define VK_ICO_CLEAR 0xE6
-
-
-#if(_WIN32_WINNT >= 0x0500)
-#define VK_PACKET 0xE7
-#endif /* _WIN32_WINNT >= 0x0500 */
-
-/*
- * 0xE8 : unassigned
- */
-
-/*
- * Nokia/Ericsson definitions
- */
-#define VK_OEM_RESET 0xE9
-#define VK_OEM_JUMP 0xEA
-#define VK_OEM_PA1 0xEB
-#define VK_OEM_PA2 0xEC
-#define VK_OEM_PA3 0xED
-#define VK_OEM_WSCTRL 0xEE
-#define VK_OEM_CUSEL 0xEF
-#define VK_OEM_ATTN 0xF0
-#define VK_OEM_FINISH 0xF1
-#define VK_OEM_COPY 0xF2
-#define VK_OEM_AUTO 0xF3
-#define VK_OEM_ENLW 0xF4
-#define VK_OEM_BACKTAB 0xF5
-
-#define VK_ATTN 0xF6
-#define VK_CRSEL 0xF7
-#define VK_EXSEL 0xF8
-#define VK_EREOF 0xF9
-#define VK_PLAY 0xFA
-#define VK_ZOOM 0xFB
-#define VK_NONAME 0xFC
-#define VK_PA1 0xFD
-#define VK_OEM_CLEAR 0xFE
-
-/*
- * 0xFF : reserved
- */
-
-
-#if defined(BUILD_WOW6432)
- #define KBD_LONG_POINTER __ptr64
-#else
- #define KBD_LONG_POINTER
-#endif
-
-
-/****************************************************************************\
-*
-* Keyboard Layers. Used in kdb??.dll and in usersrv.dll
-*
-\****************************************************************************/
-
-/*
- * KE.usFlaggedVk values, also used in the keyboard layer tables.
- */
-#define KBDEXT (USHORT)0x0100
-#define KBDMULTIVK (USHORT)0x0200
-#define KBDSPECIAL (USHORT)0x0400
-#define KBDNUMPAD (USHORT)0x0800
-#define KBDUNICODE (USHORT)0x1000
-#define KBDINJECTEDVK (USHORT)0x2000
-#if (NTDDI_VERSION >= NTDDI_WINXP)
-#define KBDMAPPEDVK (USHORT)0x4000
-#endif
-#define KBDBREAK (USHORT)0x8000
-
-/*
- * Key message lParam bits
- */
-#define EXTENDED_BIT 0x01000000
-#define DONTCARE_BIT 0x02000000
-#define FAKE_KEYSTROKE 0x02000000
-#define ALTNUMPAD_BIT 0x04000000 // copied from windows\inc\wincon.w
-
-/*
- * Keyboard Shift State defines. These correspond to the bit mask defined
- * by the VkKeyScan() API.
- */
-#define KBDBASE 0
-#define KBDSHIFT 1
-#define KBDCTRL 2
-#define KBDALT 4
-// three symbols KANA, ROYA, LOYA are for FE
-#define KBDKANA 8
-#define KBDROYA 0x10
-#define KBDLOYA 0x20
-#define KBDGRPSELTAP 0x80
-
-/*
- * Handy diacritics
- */
-#define GRAVE 0x0300
-#define ACUTE 0x0301
-#define CIRCUMFLEX 0x0302
-#define TILDE 0x0303
-#define MACRON 0x0304
-#define OVERSCORE 0x0305
-#define BREVE 0x0306
-#define DOT_ABOVE 0x0307
-#define UMLAUT 0x0308
-#define DIARESIS UMLAUT
-#define HOOK_ABOVE 0x0309
-#define RING 0x030A
-#define DOUBLE_ACUTE 0x030B
-#define HACEK 0x030C
-
-#define CEDILLA 0x0327
-#define OGONEK 0x0328
-#define TONOS 0x0384
-#define DIARESIS_TONOS 0x0385
-
-
-#define wszGRAVE L"\x0300"
-#define wszACUTE L"\x0301"
-#define wszCIRCUMFLEX L"\x0302"
-#define wszTILDE L"\x0303"
-#define wszMACRON L"\x0304"
-#define wszOVERSCORE L"\x0305"
-#define wszBREVE L"\x0306"
-#define wszDOT_ABOVE L"\x0307"
-#define wszUMLAUT L"\x0308"
-#define wszHOOK_ABOVE L"\x0309"
-#define wszRING L"\x030A"
-#define wszDOUBLE_ACUTE L"\x030B"
-#define wszHACEK L"\x030C"
-
-#define wszCEDILLA L"\x0327"
-#define wszOGONEK L"\x0328"
-#define wszTONOS L"\x0384"
-#define wszDIARESIS_TONOS L"\x0385"
-
-#define IDS_FROM_SCANCODE(prefix, base) \
- (0xc000 + ((0x ## prefix) >= 0xE0 ? 0x100 : 0) + (0x ## base))
-
-/***************************************************************************\
-* MODIFIER KEYS
-*
-* All keyboards have "Modifier" keys which are used to alter the behaviour of
-* some of the other keys. These shifter keys are usually:
-* Shift (left and/or right Shift key)
-* Ctrl (left and/or right Ctrl key)
-* Alt (left and/or right Alt key)
-* AltGr (right Alt key only)
-*
-* NOTE:
-* All keyboards use the Shift key.
-* All keyboards use a Ctrl key to generate ASCII control characters.
-* All keyboards with a number pad use the Alt key and the NumPad to
-* generate characters by number.
-* Keyboards using AltGr as a Modifier Key usually translate the Virtual
-* ScanCode to Virtual Keys VK_CTRL + VK_ALT at input time: the Modifier
-* tables should be written to treat Ctrl + Alt as a valid shifter
-* key combination in these cases.
-*
-* By holding down 0 or more of these Modifier keys, a "shift state" is
-* obtained : the shift state may affect the translation of Virtual Scancodes
-* to Virtual Keys and/or the translation of Virtuals Key to Characters.
-*
-* EXAMPLES:
-*
-* Each key on a particular keyboard may be marked with up to five different
-* characters in five different positions:
-*
-* .-------.
-* /| |\
-* : | 2 4 | :
-* | | | |
-* | | | |
-* | | 1 3 | |
-* | |_______| |
-* | / \ |
-* |/ 5 \|
-* `-----------'
-*
-* A key may also be able to generate a character that is not marked on it:
-* these are ASCII Control chars, lower-case letters and/or "invisible keys".
-* .-------.
-* An example of an "Invisible Key": /| |\
-* : | > | :
-* The German M24 keyboard 2 should produce the | | | |
-* '|' character when ALT SHIFT is is held down | | | |
-* while the '<' key (shown here) is pressed: | | < \ | |
-* This keyboard has four other invisible | |_______| |
-* characters. France, Italy and Spain also | / \ |
-* support invisible characters on the M24 |/ \|
-* Keyboard 2 with ALT SHIFT depressed. `-----------'
-*
-* The keyboard table must list the keys that contribute to it's shift state,
-* and indicate which combinations are valid. This is done with
-* aCharModifiers[] - convert combinations of Modifier Keys to Bitmasks.
-* and
-* aModification[]; - convert Modifier Bitmasks to enumerated Modifications
-*
-* AN EXAMPLE OF VALID AND INVALID MODIFIER KEY COMBINATIONS
-*
-* The US English keyboard has 3 Modifier keys:
-* Shift (left or right); Ctrl (left or right); and Alt (left or right).
-*
-* The only valid combinations of these Modifier Keys are:
-* none pressed : Character at position (1) on the key.
-* Shift : Character at position (2) on the key.
-* Ctrl : Ascii Control characters
-* Shift + Ctrl : Ascii Control characters
-* Alt : Character-by-number on the numpad
-*
-* The invalid combinations (that do not generate any characters) are:
-* Shift + Alt
-* Alt + Ctrl
-* Shift + Alt + Ctrl
-*
-* Something (???) :
-* -----------------
-* Modifier keys Character produced
-* ------------------------- ------------------
-* 0 No shifter key depressed position 1
-* 1 Shift key is depressed position 2
-* 2 AltGr (r.h. Alt) depressed position 4 or 5 (whichever is marked)
-*
-* However, note that 3 shifter keys (SHIFT, can be combined in a
-* characters, depending on the Keyboards
-* Consider the following keyboards:
-*
-* .-------. STRANGE KBD PECULIAR KBD
-* /| |\ ================== ==================
-* : | 2 4 | : 1 -
-* | | | | 2 - SHIFT SHIFT
-* | | | | 3 - MENU MENU
-* | | 1 3 | | 4 - SHIFT + MENU SHIFT + MENU
-* | |_______| | 5 - no such keys CTRL + MENU
-* | / \ |
-* |/ 5 \|
-* `-----------'
-* Both STRANGE and PECULIAR keyboards could have aVkToBits[] =
-* { VK_SHIFT , KBDSHIFT }, // 0x01
-* { VK_CONTROL, KBDCTRL }, // 0x02
-* { VK_MENU , KBDALT }, // 0x04
-* { 0, 0 }
-*
-* The STRANGE keyboard has 4 distinct shift states, while the PECULIAR kbd
-* has 5. However, note that 3 shifter bits can be combined in a
-* total of 2^3 == 8 ways. Each such combination must be related to one (or
-* none) of the enumerated shift states.
-* Each shifter key combination can be represented by three binary bits:
-* Bit 0 is set if VK_SHIFT is down
-* Bit 1 is set if VK_CONTROL is down
-* Bit 2 is set if VK_MENU is down
-*
-* Example: If the STRANGE keyboard generates no characters in combination
-* when just the ALT key is held down, nor when the SHIFT, CTRL and ALT keys
-* are all held down, then the tables might look like this:
-*
-* VK_MENU,
-* VK_CTRL, 0
-* };
-* aModification[] = {
-* 0, // 0 0 0 = 000 <none>
-* 1, // 0 0 1 = 001 SHIFT
-* SHFT_INVALID, // 0 1 0 = 010 ALT
-* 2, // 0 1 1 = 011 SHIFT ALT
-* 3, // 1 0 0 = 100 CTRL
-* 4, // 1 0 1 = 101 SHIFT CTRL
-* 5, // 1 1 0 = 110 CTRL ALT
-* SHFT_INVALID // 1 1 1 = 111 SHIFT CTRL ALT
-* };
-*
-*
-\***************************************************************************/
-
-/***************************************************************************\
-* VK_TO_BIT - associate a Virtual Key with a Modifier bitmask.
-*
-* Vk - the Virtual key (eg: VK_SHIFT, VK_RMENU, VK_CONTROL etc.)
-* Special Values:
-* 0 null terminator
-* ModBits - a combination of KBDALT, KBDCTRL, KBDSHIFT and kbd-specific bits
-* Any kbd-specific shift bits must be the lowest-order bits other
-* than KBDSHIFT, KBDCTRL and KBDALT (0, 1 & 2)
-*
-* Those languages that use AltGr (VK_RMENU) to shift keys convert it to
-* CTRL+ALT with the KBDSPECIAL bit in the ausVK[] entry for VK_RMENU
-* and by having an entry in aVkToPfnOem[] to simulate the right Vk sequence.
-*
-\***************************************************************************/
-typedef struct {
- BYTE Vk;
- BYTE ModBits;
-} VK_TO_BIT, *KBD_LONG_POINTER PVK_TO_BIT;
-
-/***************************************************************************\
-* pModNumber - a table to map shift bits to enumerated shift states
-*
-* Table attributes: Ordered table
-*
-* Maps all possible shifter key combinations to an enumerated shift state.
-* The size of the table depends on the value of the highest order bit used
-* in aCharModifiers[*].ModBits
-*
-* Special values for aModification[*]
-* SHFT_INVALID - no characters produced with this shift state.
-LATER: (ianja) no SHFT_CTRL - control characters encoded in tables like others
-* SHFT_CTRL - standard control character production (all keyboards must
-* be able to produce CTRL-C == 0x0003 etc.)
-* Other - enumerated shift state (not less than 0)
-*
-* This table is indexed by the Modifier Bits to obtain an Modification Number.
-*
-* CONTROL MENU SHIFT
-*
-* aModification[] = {
-* 0, // 0 0 0 = 000 <none>
-* 1, // 0 0 1 = 001 SHIFT
-* SHFT_INVALID, // 0 1 0 = 010 ALT
-* 2, // 0 1 1 = 011 SHIFT ALT
-* 3, // 1 0 0 = 100 CTRL
-* 4, // 1 0 1 = 101 SHIFT CTRL
-* 5, // 1 1 0 = 110 CTRL ALT
-* SHFT_INVALID // 1 1 1 = 111 SHIFT CTRL ALT
-* };
-*
-\***************************************************************************/
-
-#pragma warning(push)
-#pragma warning(disable : 4200) // zero-sized array in struct/union
-
-typedef struct {
- PVK_TO_BIT pVkToBit; // Virtual Keys -> Mod bits
- WORD wMaxModBits; // max Modification bit combination value
- BYTE ModNumber[]; // Mod bits -> Modification Number
-} MODIFIERS, *KBD_LONG_POINTER PMODIFIERS;
-
-#pragma warning(pop)
-
-
-#define SHFT_INVALID 0x0F
-
-/***************************************************************************\
-* VSC_VK - Associate a Virtual Scancode with a Virtual Key
-* Vsc - Virtual Scancode
-* Vk - Virtual Key | flags
-* Used by VKFromVSC() for scancodes prefixed 0xE0 or 0xE1
-\***************************************************************************/
-typedef struct _VSC_VK {
- BYTE Vsc;
- USHORT Vk;
-} VSC_VK, *KBD_LONG_POINTER PVSC_VK;
-
-/***************************************************************************\
-* VK_VSC - Associate a Virtual Key with a Virtual Scancode
-* Vk - Virtual Key
-* Vsc - Virtual Scancode
-* Used by MapVirtualKey for Virtual Keys not appearing in ausVK[]
-\***************************************************************************/
-typedef struct _VK_VSC {
- BYTE Vk;
- BYTE Vsc;
-} VK_VSC, *KBD_LONG_POINTER PVK_VSC;
-
-/***************************************************************************\
-*
-* VK_TO_WCHARS<n> - Associate a Virtual Key with <n> UNICODE characters
-*
-* VirtualKey - The Virtual Key.
-* wch[] - An array of characters, one for each shift state that
-* applies to the specified Virtual Key.
-*
-* Special values for VirtualKey:
-* -1 - This entry contains dead chars for the previous entry
-* 0 - Terminates a VK_TO_WCHARS[] table
-*
-* Special values for Attributes:
-* CAPLOK - The CAPS-LOCK key affects this key like SHIFT
-* SGCAPS - CapsLock uppercases the unshifted char (Swiss-German)
-*
-* Special values for wch[*]:
-* WCH_NONE - No character is generated by pressing this key with the
-* current shift state.
-* WCH_DEAD - The character is a dead-key: the next VK_TO_WCHARS[] entry
-* will contain the values of the dead characters (diaresis)
-* that can be produced by the Virtual Key.
-* WCH_LGTR - The character is a ligature. The characters generated by
-* this keystroke are found in the ligature table.
-*
-\***************************************************************************/
-#define WCH_NONE 0xF000
-#define WCH_DEAD 0xF001
-#define WCH_LGTR 0xF002
-
-#define CAPLOK 0x01
-#define SGCAPS 0x02
-#define CAPLOKALTGR 0x04
-// KANALOK is for FE
-#define KANALOK 0x08
-#define GRPSELTAP 0x80
-
-/*
- * Macro for VK to WCHAR with "n" shift states
- */
-#define TYPEDEF_VK_TO_WCHARS(n) typedef struct _VK_TO_WCHARS##n { \
- BYTE VirtualKey; \
- BYTE Attributes; \
- WCHAR wch[n]; \
- } VK_TO_WCHARS##n, *KBD_LONG_POINTER PVK_TO_WCHARS##n;
-
-/*
- * To facilitate coding the table scanning routine.
- */
-
-/*
- * Table element types (for various numbers of shift states), used
- * to facilitate static initializations of tables.
- * VK_TO_WCHARS1 and PVK_TO_WCHARS1 may be used as the generic type
- */
-TYPEDEF_VK_TO_WCHARS(1) // VK_TO_WCHARS1, *PVK_TO_WCHARS1;
-TYPEDEF_VK_TO_WCHARS(2) // VK_TO_WCHARS2, *PVK_TO_WCHARS2;
-TYPEDEF_VK_TO_WCHARS(3) // VK_TO_WCHARS3, *PVK_TO_WCHARS3;
-TYPEDEF_VK_TO_WCHARS(4) // VK_TO_WCHARS4, *PVK_TO_WCHARS4;
-TYPEDEF_VK_TO_WCHARS(5) // VK_TO_WCHARS5, *PVK_TO_WCHARS5;
-TYPEDEF_VK_TO_WCHARS(6) // VK_TO_WCHARS6, *PVK_TO_WCHARS5;
-TYPEDEF_VK_TO_WCHARS(7) // VK_TO_WCHARS7, *PVK_TO_WCHARS7;
-// these three (8,9,10) are for FE
-TYPEDEF_VK_TO_WCHARS(8) // VK_TO_WCHARS8, *PVK_TO_WCHARS8;
-TYPEDEF_VK_TO_WCHARS(9) // VK_TO_WCHARS9, *PVK_TO_WCHARS9;
-TYPEDEF_VK_TO_WCHARS(10) // VK_TO_WCHARS10, *PVK_TO_WCHARS10;
-
-/***************************************************************************\
-*
-* VK_TO_WCHAR_TABLE - Describe a table of VK_TO_WCHARS1
-*
-* pVkToWchars - points to the table.
-* nModifications - the number of shift-states supported by this table.
-* (this is the number of elements in pVkToWchars[*].wch[])
-*
-* A keyboard may have several such tables: all keys with the same number of
-* shift-states are grouped together in one table.
-*
-* Special values for pVktoWchars:
-* NULL - Terminates a VK_TO_WCHAR_TABLE[] list.
-*
-\***************************************************************************/
-
-typedef struct _VK_TO_WCHAR_TABLE {
- PVK_TO_WCHARS1 pVkToWchars;
- BYTE nModifications;
- BYTE cbSize;
-} VK_TO_WCHAR_TABLE, *KBD_LONG_POINTER PVK_TO_WCHAR_TABLE;
-
-/***************************************************************************\
-*
-* Dead Key (diaresis) tables
-*
-\***************************************************************************/
-typedef struct {
- DWORD dwBoth; // diacritic & char
- WCHAR wchComposed;
- USHORT uFlags;
-} DEADKEY, *KBD_LONG_POINTER PDEADKEY;
-
-#define DEADTRANS(ch, accent, comp, flags) { MAKELONG(ch, accent), comp, flags}
-
-/*
- * Bit values for uFlags
- */
-#define DKF_DEAD 0x0001
-
-/***************************************************************************\
-*
-* Ligature table
-*
-\***************************************************************************/
-/*
- * Macro for ligature with "n" characters
- */
-#define TYPEDEF_LIGATURE(n) typedef struct _LIGATURE##n { \
- BYTE VirtualKey; \
- WORD ModificationNumber; \
- WCHAR wch[n]; \
- } LIGATURE##n, *KBD_LONG_POINTER PLIGATURE##n;
-
-/*
- * To facilitate coding the table scanning routine.
- */
-
-/*
- * Table element types (for various numbers of ligatures), used
- * to facilitate static initializations of tables.
- *
- * LIGATURE1 and PLIGATURE1 are used as the generic type
- */
-TYPEDEF_LIGATURE(1) // LIGATURE1, *PLIGATURE1;
-TYPEDEF_LIGATURE(2) // LIGATURE2, *PLIGATURE2;
-TYPEDEF_LIGATURE(3) // LIGATURE3, *PLIGATURE3;
-TYPEDEF_LIGATURE(4) // LIGATURE4, *PLIGATURE4;
-TYPEDEF_LIGATURE(5) // LIGATURE5, *PLIGATURE5;
-
-/***************************************************************************\
-* VSC_LPWSTR - associate a Virtual Scancode with a Text string
-*
-* Uses:
-* GetKeyNameText(), aKeyNames[] Map virtual scancode to name of key
-*
-\***************************************************************************/
-typedef struct {
- BYTE vsc;
- WCHAR *KBD_LONG_POINTER pwsz;
-} VSC_LPWSTR, *KBD_LONG_POINTER PVSC_LPWSTR;
-
-typedef WCHAR *KBD_LONG_POINTER DEADKEY_LPWSTR;
-
-/*
- * Along with ligature support we're adding a proper version number.
- * The previous version number (actually just unused bits...) was
- * always zero. The version number will live in the high word of
- * fLocaleFlags.
- */
-#define KBD_VERSION 1
-#define GET_KBD_VERSION(p) (HIWORD((p)->fLocaleFlags))
-
-/*
- * Attributes such as AltGr, LRM_RLM, ShiftLock are stored in the the low word
- * of fLocaleFlags (layout specific) or in gdwKeyboardAttributes (all layouts)
- */
-#define KLLF_ALTGR 0x0001
-#define KLLF_SHIFTLOCK 0x0002
-#define KLLF_LRM_RLM 0x0004
-
-/*
- * Some attributes are per-layout (specific to an individual layout), some
- * attributes are per-user (apply globally to all layouts). Some are both.
- */
-#define KLLF_LAYOUT_ATTRS (KLLF_SHIFTLOCK | KLLF_ALTGR | KLLF_LRM_RLM)
-#define KLLF_GLOBAL_ATTRS (KLLF_SHIFTLOCK)
-
-/*
- * Flags passed in to the KeyboardLayout API (KLF_*) as can be converted to
- * internal (KLLF_*) attributes:
- */
-#define KLL_ATTR_FROM_KLF(x) ((x) >> 15)
-#define KLL_LAYOUT_ATTR_FROM_KLF(x) (KLL_ATTR_FROM_KLF(x) & KLLF_LAYOUT_ATTRS)
-#define KLL_GLOBAL_ATTR_FROM_KLF(x) (KLL_ATTR_FROM_KLF(x) & KLLF_GLOBAL_ATTRS)
-
-/*
- * If KLF_SHIFTLOCK & KLF_LRM_RLM are defined, we can check the KLLF_* values
- */
-#ifdef KLF_SHIFTLOCK
-#if KLLF_SHIFTLOCK != KLL_ATTR_FROM_KLF(KLF_SHIFTLOCK)
- #error KLLF_SHIFTLOCK != KLL_ATTR_FROM_KLF(KLF_SHIFTLOCK)
-#endif
-#endif // KLF_SHIFTLOCK
-#ifdef KLF_LRM_RLM
-#if KLLF_LRM_RLM != KLL_ATTR_FROM_KLF(KLF_LRM_RLM)
- #error KLLF_LRM_RLM != KLL_ATTR_FROM_KLF(KLF_LRM_RLM)
-#endif
-#endif // KLF_LRM_RLM
-
-/***************************************************************************\
-* KBDTABLES
-*
-* This structure describes all the tables that implement the keyboard layer.
-*
-* When switching to a new layer, we get a new KBDTABLES structure: all key
-* processing tables are accessed indirectly through this structure.
-*
-\***************************************************************************/
-
-typedef struct tagKbdLayer {
- /*
- * Modifier keys
- */
- PMODIFIERS pCharModifiers;
-
- /*
- * Characters
- */
- PVK_TO_WCHAR_TABLE pVkToWcharTable; // ptr to tbl of ptrs to tbl
-
- /*
- * Diacritics
- */
- PDEADKEY pDeadKey;
-
- /*
- * Names of Keys
- */
- PVSC_LPWSTR pKeyNames;
- PVSC_LPWSTR pKeyNamesExt;
- WCHAR *KBD_LONG_POINTER *KBD_LONG_POINTER pKeyNamesDead;
-
- /*
- * Scan codes to Virtual Keys
- */
- USHORT *KBD_LONG_POINTER pusVSCtoVK;
- BYTE bMaxVSCtoVK;
- PVSC_VK pVSCtoVK_E0; // Scancode has E0 prefix
- PVSC_VK pVSCtoVK_E1; // Scancode has E1 prefix
-
- /*
- * Locale-specific special processing
- */
- DWORD fLocaleFlags;
-
- /*
- * Ligatures
- */
- BYTE nLgMax;
- BYTE cbLgEntry;
- PLIGATURE1 pLigature;
-
-#if (NTDDI_VERSION >= NTDDI_WINXP)
-
- /*
- * Type and subtype. These are optional.
- */
- DWORD dwType; // Keyboard Type
- DWORD dwSubType; // Keyboard SubType: may contain OemId
-
-#endif
-
-} KBDTABLES, *KBD_LONG_POINTER PKBDTABLES;
-
-/*
- * FarEast-specific special...
- */
-typedef struct _VK_FUNCTION_PARAM {
- BYTE NLSFEProcIndex;
- ULONG NLSFEProcParam;
-} VK_FPARAM, *KBD_LONG_POINTER PVK_FPARAM;
-
-typedef struct _VK_TO_FUNCTION_TABLE {
- BYTE Vk;
- BYTE NLSFEProcType;
- BYTE NLSFEProcCurrent;
- // Index[0] : Base
- // Index[1] : Shift
- // Index[2] : Control
- // Index[3] : Shift+Control
- // Index[4] : Alt
- // Index[5] : Shift+Alt
- // Index[6] : Control+Alt
- // Index[7] : Shift+Control+Alt
- BYTE NLSFEProcSwitch; // 8 bits
- VK_FPARAM NLSFEProc[8];
- VK_FPARAM NLSFEProcAlt[8];
-} VK_F, *KBD_LONG_POINTER PVK_F;
-
-typedef struct tagKbdNlsLayer {
- USHORT OEMIdentifier;
- USHORT LayoutInformation;
- UINT NumOfVkToF;
- PVK_F pVkToF;
- //
- // The pusMouseVKey array provides a translation from the virtual key
- // value to an index. The index is used to select the appropriate
- // routine to process the virtual key, as well as to select extra
- // information that is used by this routine during its processing.
- // If this value is NULL, following default will be used.
- //
- // ausMouseVKey[] = {
- // VK_CLEAR, // Numpad 5: Click active button
- // VK_PRIOR, // Numpad 9: Up & Right
- // VK_NEXT, // Numpad 3: Down & Right
- // VK_END, // Numpad 1: Down & Left
- // VK_HOME, // Numpad 7: Up & Left
- // VK_LEFT, // Numpad 4: Left
- // VK_UP, // Numpad 8: Up
- // VK_RIGHT, // Numpad 6: Right
- // VK_DOWN, // Numpad 2: Down
- // VK_INSERT, // Numpad 0: Active button down
- // VK_DELETE, // Numpad .: Active button up
- // VK_MULTIPLY, // Numpad *: Select both buttons
- // VK_ADD, // Numpad +: Double click active button
- // VK_SUBTRACT, // Numpad -: Select right button
- // VK_DEVIDE|KBDEXT, // Numpad /: Select left button
- // VK_NUMLOCK|KBDEXT}; // Num Lock
- //
- INT NumOfMouseVKey;
- USHORT *KBD_LONG_POINTER pusMouseVKey;
-} KBDNLSTABLES, *KBD_LONG_POINTER PKBDNLSTABLES;
-
-#if (NTDDI_VERSION >= NTDDI_WINXP)
-/*
- * The maximum number of layout tables in a DLL
- */
-#define KBDTABLE_MULTI_MAX (8)
-
-/*
- * Multiple keyboard layout table in a DLL
- */
-typedef struct tagKBDTABLE_DESC {
- WCHAR wszDllName[32];
- DWORD dwType; // Keyboard type ID
- DWORD dwSubType; // Combined SubType ID (OEMID : SubType)
-} KBDTABLE_DESC, *KBD_LONG_POINTER PKBDTABLE_DESC;
-
-typedef struct tagKBDTABLE_MULTI {
- UINT nTables;
- KBDTABLE_DESC aKbdTables[KBDTABLE_MULTI_MAX];
-} KBDTABLE_MULTI, *KBD_LONG_POINTER PKBDTABLE_MULTI;
-
-
-/*
- * Format of the registry value for the Dynamic Layout Switching
- */
-typedef struct tagKBD_TYPE_INFO {
- DWORD dwVersion;
- DWORD dwType;
- DWORD dwSubType;
-} KBD_TYPE_INFO, *PKBD_TYPE_INFO;
-
-//
-// Keyboard type
-//
-#define KEYBOARD_TYPE_GENERIC_101 (4)
-//
-// Keyboard Type = 7 : Japanese Keyboard
-// Keyboard Type = 8 : Korean Keyboard
-//
-#define KEYBOARD_TYPE_JAPAN (7)
-#define KEYBOARD_TYPE_KOREA (8)
-
-// Unknown keyboard type
-#define KEYBOARD_TYPE_UNKNOWN (0x51)
-
-#endif
-
-
-//
-// OEM Ids - KBDNLSTABLES.OEMIdentifier
-//
-// PSS ID Number: Q130054
-// Article last modified on 05-16-1995
-//
-// 3.10 1.20 | 3.50 1.20
-// WINDOWS | WINDOWS NT
-//
-// ---------------------------------------------------------------------
-// The information in this article applies to:
-// - Microsoft Windows Software Development Kit (SDK) for Windows
-// version 3.1
-// - Microsoft Win32 Software Development Kit (SDK) version 3.5
-// - Microsoft Win32s version 1.2
-// ---------------------------------------------------------------------
-// SUMMARY
-// =======
-// Because of the variety of computer manufacturers (NEC, Fujitsu, IBMJ, and
-// so on) in Japan, sometimes Windows-based applications need to know which
-// OEM (original equipment manufacturer) manufactured the computer that is
-// running the application. This article explains how.
-//
-// MORE INFORMATION
-// ================
-// There is no documented way to detect the manufacturer of the computer that
-// is currently running an application. However, a Windows-based application
-// can detect the type of OEM Windows by using the return value of the
-// GetKeyboardType() function.
-//
-// If an application uses the GetKeyboardType API, it can get OEM ID by
-// specifying "1" (keyboard subtype) as argument of the function. Each OEM ID
-// is listed here:
-//
-// OEM Windows OEM ID
-// ------------------------------
-// Microsoft 00H (DOS/V)
-// all AX 01H
-// EPSON 04H
-// Fujitsu 05H
-// IBMJ 07H
-// Matsushita 0AH
-// NEC 0DH
-// Toshiba 12H
-//
-// Application programs can use these OEM IDs to distinguish the type of OEM
-// Windows. Note, however, that this method is not documented, so Microsoft
-// may not support it in the future version of Windows.
-//
-// As a rule, application developers should write hardware-independent code,
-// especially when making Windows-based applications. If they need to make a
-// hardware-dependent application, they must prepare the separated program
-// file for each different hardware architecture.
-//
-// Additional reference words: 3.10 1.20 3.50 1.20 kbinf
-// KBCategory: kbhw
-// KBSubcategory: wintldev
-// =============================================================================
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-#define NLSKBD_OEM_MICROSOFT 0x00
-#define NLSKBD_OEM_AX 0x01
-#define NLSKBD_OEM_EPSON 0x04
-#define NLSKBD_OEM_FUJITSU 0x05
-#define NLSKBD_OEM_IBM 0x07
-#define NLSKBD_OEM_MATSUSHITA 0x0A
-#define NLSKBD_OEM_NEC 0x0D
-#define NLSKBD_OEM_TOSHIBA 0x12
-#define NLSKBD_OEM_DEC 0x18 // only NT
-//
-// Microsoft (default) - keyboards hardware/layout
-//
-#define MICROSOFT_KBD_101_TYPE 0
-#define MICROSOFT_KBD_AX_TYPE 1
-#define MICROSOFT_KBD_106_TYPE 2
-#define MICROSOFT_KBD_002_TYPE 3
-#define MICROSOFT_KBD_001_TYPE 4
-#define MICROSOFT_KBD_FUNC 12
-//
-// AX consortium - keyboards hardware/layout
-//
-#define AX_KBD_DESKTOP_TYPE 1
-//
-// Fujitsu - keyboards hardware/layout
-//
-#define FMR_KBD_JIS_TYPE 0
-#define FMR_KBD_OASYS_TYPE 1
-#define FMV_KBD_OASYS_TYPE 2
-//
-// NEC - keyboards hardware/layout
-//
-#define NEC_KBD_NORMAL_TYPE 1
-#define NEC_KBD_N_MODE_TYPE 2
-#define NEC_KBD_H_MODE_TYPE 3
-#define NEC_KBD_LAPTOP_TYPE 4
-#define NEC_KBD_106_TYPE 5
-//
-// Toshiba - keyboards hardware/layout
-//
-#define TOSHIBA_KBD_DESKTOP_TYPE 13
-#define TOSHIBA_KBD_LAPTOP_TYPE 15
-//
-// DEC - keyboards hardware/layout
-//
-#define DEC_KBD_ANSI_LAYOUT_TYPE 1 // only NT
-#define DEC_KBD_JIS_LAYOUT_TYPE 2 // only NT
-
-#if (NTDDI_VERSION >= NTDDI_WINXP)
-//
-// Korean keyboard subtype
-//
-#define MICROSOFT_KBD_101A_TYPE MICROSOFT_KBD_101_TYPE
-#define MICROSOFT_KBD_101B_TYPE 4
-#define MICROSOFT_KBD_101C_TYPE 5
-#define MICROSOFT_KBD_103_TYPE 6
-#endif
-
-//
-// Keyboard layout information - KBDNLSTABLE.LayoutInformation
-//
-
-//
-// If this flag is on, System sends notification to keyboard
-// drivers (leyout/kernel mode). when IME (Input-Mehod-Editor)
-// status become changed.
-//
-#define NLSKBD_INFO_SEND_IME_NOTIFICATION 0x0001
-
-//
-// If this flag is on, System will use VK_HOME/VK_KANA instead of
-// VK_NUMLOCK/VK_SCROLL for Accessibility toggle keys.
-// + Typically, NEC PC-9800 Series will use this bit, because
-// they does not have 'NumLock' and 'ScrollLock' keys.
-//
-#define NLSKBD_INFO_ACCESSIBILITY_KEYMAP 0x0002
-
-//
-// If this flag is on, System will return 101 or 106 Japanese
-// keyboard type/subtype id, when GetKeyboardType() is called.
-//
-#define NLSKBD_INFO_EMURATE_101_KEYBOARD 0x0010
-#define NLSKBD_INFO_EMURATE_106_KEYBOARD 0x0020
-
-//
-// Keyboard layout function types
-//
-// - VK_F.NLSFEProcType
-//
-#define KBDNLS_TYPE_NULL 0
-#define KBDNLS_TYPE_NORMAL 1
-#define KBDNLS_TYPE_TOGGLE 2
-
-//
-// - VK_F.NLSFEProcCurrent
-//
-#define KBDNLS_INDEX_NORMAL 1
-#define KBDNLS_INDEX_ALT 2
-
-//
-// - VK_F.NLSFEProc[]
-//
-#define KBDNLS_NULL 0 // Invalid function
-#define KBDNLS_NOEVENT 1 // Drop keyevent
-#define KBDNLS_SEND_BASE_VK 2 // Send Base VK_xxx
-#define KBDNLS_SEND_PARAM_VK 3 // Send Parameter VK_xxx
-#define KBDNLS_KANALOCK 4 // VK_KANA (with hardware lock)
-#define KBDNLS_ALPHANUM 5 // VK_DBE_ALPHANUMERIC
-#define KBDNLS_HIRAGANA 6 // VK_DBE_HIRAGANA
-#define KBDNLS_KATAKANA 7 // VK_DBE_KATAKANA
-#define KBDNLS_SBCSDBCS 8 // VK_DBE_SBCSCHAR/VK_DBE_DBCSCHAR
-#define KBDNLS_ROMAN 9 // VK_DBE_ROMAN/VK_DBE_NOROMAN
-#define KBDNLS_CODEINPUT 10 // VK_DBE_CODEINPUT/VK_DBE_NOCODEINPUT
-#define KBDNLS_HELP_OR_END 11 // VK_HELP or VK_END [NEC PC-9800 Only]
-#define KBDNLS_HOME_OR_CLEAR 12 // VK_HOME or VK_CLEAR [NEC PC-9800 Only]
-#define KBDNLS_NUMPAD 13 // VK_NUMPAD? for Numpad key [NEC PC-9800 Only]
-#define KBDNLS_KANAEVENT 14 // VK_KANA [Fujitsu FMV oyayubi Only]
-#define KBDNLS_CONV_OR_NONCONV 15 // VK_CONVERT and VK_NONCONVERT [Fujitsu FMV oyayubi Only]
-
-#if (NTDDI_VERSION < NTDDI_WINXP)
-//
-// Keyboard Type = 7 : Japanese Keyboard
-// Keyboard Type = 8 : Korean Keyboard
-//
-#define JAPANESE_KEYBOARD(Id) ((Id).Type == 7)
-#define KOREAN_KEYBOARD(Id) ((Id).Type == 8)
-
-#else
-
-#define JAPANESE_KEYBOARD(Id) ((Id).Type == KEYBOARD_TYPE_JAPAN)
-#define KOREAN_KEYBOARD(Id) ((Id).Type == KEYBOARD_TYPE_KOREA)
-
-#endif
-
-// Fujitsu Oyayubi-shift keyboard
-#define FUJITSU_KBD_CONSOLE(Id) (JAPANESE_KEYBOARD(Id) && \
- (Id).Subtype == ((NLSKBD_OEM_FUJITSU<<4)|FMV_KBD_OASYS_TYPE))
- // This number 0x00020002 is registered in registry key as
- // HKLM\System\CurrentControlSet\Control\Terminal Server\KeyboardType Mapping\JPN
-#define FUJITSU_KBD_REMOTE(Id) (JAPANESE_KEYBOARD(Id) && \
- (Id).SubType == 0x00020002)
-
-#define KBD_LAYOUT_LANG(hkl) (PRIMARYLANGID(HandleToUlong(hkl)))
-
-#define JAPANESE_KBD_LAYOUT(hkl) (KBD_LAYOUT_LANG(hkl) == LANG_JAPANESE)
-#define KOREAN_KBD_LAYOUT(hkl) (KBD_LAYOUT_LANG(hkl) == LANG_KOREAN)
-
-// end of FE specific
-
-/***************************************************************************\
-* Macros for ausVK[] values (used below)
-*
-* These macros prefix each argument with VK_ to produce the name of a Virtual
-* Key defined in "winuser.h" (eg: ESCAPE becomes VK_ESCAPE).
-\***************************************************************************/
-#ifndef KBD_TYPE
-#define KBD_TYPE 4
-#endif
-
-/*
- * _NE() selects the Virtual Key according to keyboard type
- */
-#if (KBD_TYPE == 1)
-#define _NE(v1,v2,v3,v4,v5,v6) (VK_##v1)
-#elif (KBD_TYPE == 2)
-#define _NE(v1,v2,v3,v4,v5,v6) (VK_##v2)
-#elif (KBD_TYPE == 3)
-#define _NE(v1,v2,v3,v4,v5,v6) (VK_##v3)
-#elif (KBD_TYPE == 4)
-#define _NE(v1,v2,v3,v4,v5,v6) (VK_##v4)
-#elif (KBD_TYPE == 5)
-#define _NE(v1,v2,v3,v4,v5,v6) (VK_##v5)
-#elif (KBD_TYPE == 6)
-#define _NE(v1,v2,v3,v4,v5,v6) (VK_##v6)
-#elif (KBD_TYPE == 7)
-#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v7)
-#elif (KBD_TYPE == 8)
-#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v8)
-#elif (KBD_TYPE == 10)
-#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v10)
-#elif (KBD_TYPE == 11)
-#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v11)
-#elif (KBD_TYPE == 12)
-#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v12)
-#elif (KBD_TYPE == 13)
-#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v13)
-#elif (KBD_TYPE == 16)
-#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v16)
-#elif (KBD_TYPE == 20)
-#define _NE(v20,v21,v22) (VK_##v20)
-#elif (KBD_TYPE == 21)
-#define _NE(v20,v21,v22) (VK_##v21)
-#elif (KBD_TYPE == 22)
-#define _NE(v20,v21,v22) (VK_##v22)
-#elif (KBD_TYPE == 30)
-#define _NE(v30,v33,v34) (VK_##v30)
-#elif (KBD_TYPE == 33)
-#define _NE(v30,v33,v34) (VK_##v33)
-#elif (KBD_TYPE == 34)
-#define _NE(v30,v33,v34) (VK_##v34)
-#elif (KBD_TYPE == 40)
-#define _NE(v40,v41) (VK_##v40)
-#elif (KBD_TYPE == 41)
-#define _NE(v40,v41) (VK_##v41)
-#endif
-
-/*
- * _EQ() selects the same Virtual Key for all keyboard types
- */
-#if (KBD_TYPE <= 6)
-#define _EQ( v4 ) (VK_##v4)
-#elif (KBD_TYPE >= 7) && (KBD_TYPE <= 16)
-#define _EQ( v8 ) (VK_##v8)
-#elif (KBD_TYPE > 20) && (KBD_TYPE <= 22)
-#define _EQ(v20 ) (VK_##v20)
-#elif (KBD_TYPE >= 30) && (KBD_TYPE <= 34)
-#define _EQ( v30 ) (VK_##v30)
-#elif (KBD_TYPE == 37)
-#define _EQ( v37 ) (VK_##v37)
-#elif (KBD_TYPE >= 40) && (KBD_TYPE <= 41)
-#define _EQ( v40 ) (VK_##v40)
-#endif
-
-/*
- * A bit of trickery for virtual key names 'A' to 'Z' and '0' to '9' so
- * that they are not converted to a VK_* name.
- * With this macro, VK_'A' equates to 'A' etc.
- */
-#define VK_
-#define VK__none_ 0xFF
-#define VK_ABNT_C1 0xC1
-#define VK_ABNT_C2 0xC2
-
-#if (KBD_TYPE <= 6)
-/***************************************************************************\
-* T** - Values for ausVK[] (Virtual Scan Code to Virtual Key conversion)
-*
-* These values are for Scancode Set 3 and the USA.
-* Other languages substitute their own values where required (files kbd**.h)
-*
-* Six sets of keyboards are supported, according to KBD_TYPE:
-*
-* KBD_TYPE Keyboard (examples)
-* ======== =======================================================
-* 1 AT&T '301' & '302'; Olivetti 83-key; PC-XT 84-key; etc.
-* 2 Olivetti M24 102-key
-* 3 HP Vectra (DIN); Olivetti 86-key; etc.
-* 4 * Enhanced 101/102-key; Olivetti A; etc.
-* 5 Nokia (Ericsson) type 5 (1050, etc.)
-* 6 Nokia (Ericsson) type 6 (9140)
-*
-* * If KBD_TYPE is not defined, the default is type 4.
-*
-* KB3270 comments refers to KB 3270 keyboards in native emulation mode (DIP
-* switches all OFF), and the Scancode Map used to convert its scancodes to
-* standard scancode set 1.
-* KB3270 <= 57 - this entry is reached by mapping from scancode 0x57
-* to an arbitrary scancode: the VK is what counts
-* KB3270 => HOME - this scancode is mapped to the scancode for VK_HOME
-* KB3270 - no mapping involved, a scancode for KB3270 only
-*
-* _EQ() : all keyboard types have the same virtual key for this scancode
-* _NE() : different virtual keys for this scancode, depending on kbd type
-*
-* +------+ +--------+--------+--------+--------+--------+--------+
-* | Scan | | kbd | kbd | kbd | kbd | kbd | kbd |
-* | code | | type 1 | type 2 | type 3 | type 4 | type 5 | type 6 |
-\****+-------+-+--------+--------+--------+--------+--------+--------+******/
-#define T00 _EQ( _none_ )
-#define T01 _EQ( ESCAPE )
-#define T02 _EQ( '1' )
-#define T03 _EQ( '2' )
-#define T04 _EQ( '3' )
-#define T05 _EQ( '4' )
-#define T06 _EQ( '5' )
-#define T07 _EQ( '6' )
-#define T08 _EQ( '7' )
-#define T09 _EQ( '8' )
-#define T0A _EQ( '9' )
-#define T0B _EQ( '0' )
-#define T0C _EQ( OEM_MINUS )
-#define T0D _NE(OEM_PLUS,OEM_4, OEM_PLUS,OEM_PLUS,OEM_PLUS,OEM_PLUS)
-#define T0E _EQ( BACK )
-#define T0F _EQ( TAB )
-#define T10 _EQ( 'Q' )
-#define T11 _EQ( 'W' )
-#define T12 _EQ( 'E' )
-#define T13 _EQ( 'R' )
-#define T14 _EQ( 'T' )
-#define T15 _EQ( 'Y' )
-#define T16 _EQ( 'U' )
-#define T17 _EQ( 'I' )
-#define T18 _EQ( 'O' )
-#define T19 _EQ( 'P' )
-#define T1A _NE(OEM_4, OEM_6, OEM_4, OEM_4, OEM_4, OEM_4 )
-#define T1B _NE(OEM_6, OEM_1, OEM_6, OEM_6, OEM_6, OEM_6 )
-#define T1C _EQ( RETURN )
-#define T1D _EQ( LCONTROL )
-#define T1E _EQ( 'A' )
-#define T1F _EQ( 'S' )
-#define T20 _EQ( 'D' )
-#define T21 _EQ( 'F' )
-#define T22 _EQ( 'G' )
-#define T23 _EQ( 'H' )
-#define T24 _EQ( 'J' )
-#define T25 _EQ( 'K' )
-#define T26 _EQ( 'L' )
-#define T27 _NE(OEM_1, OEM_PLUS,OEM_1, OEM_1, OEM_1, OEM_1 )
-#define T28 _NE(OEM_7, OEM_3, OEM_7, OEM_7, OEM_3, OEM_3 )
-#define T29 _NE(OEM_3, OEM_7, OEM_3, OEM_3, OEM_7, OEM_7 )
-#define T2A _EQ( LSHIFT )
-#define T2B _EQ( OEM_5 )
-#define T2C _EQ( 'Z' )
-#define T2D _EQ( 'X' )
-#define T2E _EQ( 'C' )
-#define T2F _EQ( 'V' )
-#define T30 _EQ( 'B' )
-#define T31 _EQ( 'N' )
-#define T32 _EQ( 'M' )
-#define T33 _EQ( OEM_COMMA )
-#define T34 _EQ( OEM_PERIOD )
-#define T35 _EQ( OEM_2 )
-#define T36 _EQ( RSHIFT )
-#define T37 _EQ( MULTIPLY )
-#define T38 _EQ( LMENU )
-#define T39 _EQ( ' ' )
-#define T3A _EQ( CAPITAL )
-#define T3B _EQ( F1 )
-#define T3C _EQ( F2 )
-#define T3D _EQ( F3 )
-#define T3E _EQ( F4 )
-#define T3F _EQ( F5 )
-#define T40 _EQ( F6 )
-#define T41 _EQ( F7 )
-#define T42 _EQ( F8 )
-#define T43 _EQ( F9 )
-#define T44 _EQ( F10 )
-#define T45 _EQ( NUMLOCK )
-#define T46 _EQ( SCROLL )
-#define T47 _EQ( HOME )
-#define T48 _EQ( UP )
-#define T49 _EQ( PRIOR )
-#define T4A _EQ( SUBTRACT )
-#define T4B _EQ( LEFT )
-#define T4C _EQ( CLEAR )
-#define T4D _EQ( RIGHT )
-#define T4E _EQ( ADD )
-#define T4F _EQ( END )
-#define T50 _EQ( DOWN )
-#define T51 _EQ( NEXT )
-#define T52 _EQ( INSERT )
-#define T53 _EQ( DELETE )
-#define T54 _EQ( SNAPSHOT )
-#define T55 _EQ( _none_ ) // KB3270 => DOWN
-#define T56 _NE(OEM_102, HELP, OEM_102, OEM_102, _none_, OEM_PA2 ) // KB3270 => LEFT
-#define T57 _NE(F11, RETURN, F11, F11, _none_, HELP ) // KB3270 => ZOOM
-#define T58 _NE(F12, LEFT, F12, F12, _none_, OEM_102 ) // KB3270 => HELP
-#define T59 _EQ( CLEAR )
-#define T5A _EQ( OEM_WSCTRL )// WSCtrl
-#define T5B _EQ( OEM_FINISH )// Finish
-#define T5C _EQ( OEM_JUMP )// Jump
-#define T5D _EQ( EREOF )
-#define T5E _EQ( OEM_BACKTAB ) // KB3270 <= 7E
-#define T5F _EQ( OEM_AUTO ) // KB3270
-#define T60 _EQ( _none_ )
-#define T61 _EQ( _none_ )
-#define T62 _EQ( ZOOM ) // KB3270 <= 57
-#define T63 _EQ( HELP ) // KB3270 <= 58
-#define T64 _EQ( F13 )
-#define T65 _EQ( F14 )
-#define T66 _EQ( F15 )
-#define T67 _EQ( F16 )
-#define T68 _EQ( F17 )
-#define T69 _EQ( F18 )
-#define T6A _EQ( F19 )
-#define T6B _EQ( F20 )
-#define T6C _EQ( F21 )
-#define T6D _EQ( F22 )
-#define T6E _EQ( F23 )
-#define T6F _EQ( OEM_PA3 ) // KB3270
-#define T70 _EQ( _none_ )
-#define T71 _EQ( OEM_RESET ) // KB3270
-#define T72 _EQ( _none_ )
-#define T73 _EQ( ABNT_C1 )
-#define T74 _EQ( _none_ )
-#define T75 _EQ( _none_ ) // KB3270 => RETURN
-#define T76 _EQ( F24 )
-#define T77 _EQ( _none_ ) // KB3270 => HOME
-#define T78 _EQ( _none_ ) // KB3270 => UP
-#define T79 _EQ( _none_ ) // KB3270 => DELETE
-#define T7A _EQ( _none_ ) // KB3270 => INSERT
-#define T7B _EQ( OEM_PA1 ) // KB3270
-#define T7C _EQ( TAB ) // KB3270 => TAB
-#define T7D _EQ( _none_ ) // KB3270 => RIGHT
-#define T7E _EQ( ABNT_C2 ) // KB3270 => BACKTAB
-#define T7F _EQ( OEM_PA2 ) // KB3270
-
-#define X10 _EQ( MEDIA_PREV_TRACK ) // SpeedRacer
-#define X19 _EQ( MEDIA_NEXT_TRACK ) // SpeedRacer
-#define X1C _EQ( RETURN )
-#define X1D _EQ( RCONTROL )
-#define X20 _EQ( VOLUME_MUTE ) // SpeedRacer
-#define X21 _EQ( LAUNCH_APP2 ) // SpeedRacer (Calculator?)
-#define X22 _EQ( MEDIA_PLAY_PAUSE ) // SpeedRacer
-#define X24 _EQ( MEDIA_STOP ) // SpeedRacer
-#define X2E _EQ( VOLUME_DOWN ) // SpeedRacer
-#define X30 _EQ( VOLUME_UP ) // SpeedRacer
-#define X32 _EQ( BROWSER_HOME ) // SpeedRacer
-#define X35 _EQ( DIVIDE )
-#define X37 _EQ( SNAPSHOT )
-#define X38 _EQ( RMENU )
-#define X46 _EQ( CANCEL )
-#define X47 _EQ( HOME )
-#define X48 _EQ( UP )
-#define X49 _EQ( PRIOR )
-#define X4B _EQ( LEFT )
-#define X4D _EQ( RIGHT )
-#define X4F _EQ( END )
-#define X50 _EQ( DOWN )
-#define X51 _NE(NEXT, F1, NEXT, NEXT, _none_, OEM_PA2 )
-#define X52 _EQ( INSERT )
-#define X53 _EQ( DELETE )
-#define X5B _EQ( LWIN )
-#define X5C _EQ( RWIN )
-#define X5D _EQ( APPS )
-#define X5E _EQ( POWER )
-#define X5F _EQ( SLEEP ) // SpeedRacer
-#define X65 _EQ( BROWSER_SEARCH ) // SpeedRacer
-#define X66 _EQ( BROWSER_FAVORITES ) // SpeedRacer
-#define X67 _EQ( BROWSER_REFRESH ) // SpeedRacer
-#define X68 _EQ( BROWSER_STOP ) // SpeedRacer
-#define X69 _EQ( BROWSER_FORWARD ) // SpeedRacer
-#define X6A _EQ( BROWSER_BACK ) // SpeedRacer
-#define X6B _EQ( LAUNCH_APP1 ) // SpeedRacer (my computer?)
-#define X6C _EQ( LAUNCH_MAIL ) // SpeedRacer
-#define X6D _EQ( LAUNCH_MEDIA_SELECT ) // SpeedRacer
-
-
- /*
- * The break key is sent to us as E1,LCtrl,NumLock
- * We must convert the E1+LCtrl to BREAK, then ignore the Numlock
- */
-#define Y1D _EQ( PAUSE )
-
-#elif (KBD_TYPE >= 7) && (KBD_TYPE <= 16)
-/***********************************************************************************\
-* T** - Values for ausVK[] (Virtual Scan Code to Virtual Key conversion)
-*
-* Three sets of keyboards are supported, according to KBD_TYPE:
-*
-* KBD_TYPE Keyboard (examples)
-* ======== =====================================
-* 7 Japanese IBM type 002 keyboard.
-* 8 * Japanese OADG (106) keyboard.
-* 10 Korean 101 (type A) keyboard.
-* 11 Korean 101 (type B) keyboard.
-* 12 Korean 101 (type C) keyboard.
-* 13 Korean 103 keyboard.
-* 16 Japanese AX keyboard.
-*
-* +------+ +----------+----------+----------+----------+----------+----------+----------+
-* | Scan | | kbd | kbd | kbd | kbd | kbd | kbd | kbd |
-* | code | | type 7 | type 8 | type 16 | type 10 | type 11 | type 12 | type 13 |
-\****+-------+-+----------+----------+----------+----------+----------+----------+----------+*/
-#define T00 _EQ( _none_ )
-#define T01 _EQ( ESCAPE )
-#define T02 _EQ( '1' )
-#define T03 _EQ( '2' )
-#define T04 _EQ( '3' )
-#define T05 _EQ( '4' )
-#define T06 _EQ( '5' )
-#define T07 _EQ( '6' )
-#define T08 _EQ( '7' )
-#define T09 _EQ( '8' )
-#define T0A _EQ( '9' )
-#define T0B _EQ( '0' )
-#define T0C _EQ( OEM_MINUS )
-#define T0D _NE(OEM_7, OEM_7, OEM_PLUS, OEM_PLUS, OEM_PLUS, OEM_PLUS, OEM_PLUS )
-#define T0E _EQ( BACK )
-#define T0F _EQ( TAB )
-#define T10 _EQ( 'Q' )
-#define T11 _EQ( 'W' )
-#define T12 _EQ( 'E' )
-#define T13 _EQ( 'R' )
-#define T14 _EQ( 'T' )
-#define T15 _EQ( 'Y' )
-#define T16 _EQ( 'U' )
-#define T17 _EQ( 'I' )
-#define T18 _EQ( 'O' )
-#define T19 _EQ( 'P' )
-#define T1A _NE(OEM_4, OEM_3, OEM_4, OEM_4, OEM_4, OEM_4, OEM_4 )
-#define T1B _NE(OEM_6, OEM_4, OEM_6, OEM_6, OEM_6, OEM_6, OEM_6 )
-#define T1C _EQ( RETURN )
-#define T1D _EQ( LCONTROL )
-#define T1E _EQ( 'A' )
-#define T1F _EQ( 'S' )
-#define T20 _EQ( 'D' )
-#define T21 _EQ( 'F' )
-#define T22 _EQ( 'G' )
-#define T23 _EQ( 'H' )
-#define T24 _EQ( 'J' )
-#define T25 _EQ( 'K' )
-#define T26 _EQ( 'L' )
-#define T27 _NE(OEM_PLUS, OEM_PLUS, OEM_1, OEM_1, OEM_1, OEM_1, OEM_1 )
-#define T28 _NE(OEM_1, OEM_1, OEM_7, OEM_7, OEM_7, OEM_7, OEM_7 )
-#define T29 _NE(OEM_3, DBE_SBCSCHAR,OEM_3, OEM_3, OEM_3, OEM_3, OEM_3 )
-#define T2A _EQ( LSHIFT )
-#define T2B _NE(OEM_5, OEM_6, OEM_5, OEM_5, OEM_5, OEM_5, OEM_5 )
-#define T2C _EQ( 'Z' )
-#define T2D _EQ( 'X' )
-#define T2E _EQ( 'C' )
-#define T2F _EQ( 'V' )
-#define T30 _EQ( 'B' )
-#define T31 _EQ( 'N' )
-#define T32 _EQ( 'M' )
-#define T33 _EQ( OEM_COMMA )
-#define T34 _EQ( OEM_PERIOD )
-#define T35 _EQ( OEM_2 )
-#define T36 _EQ( RSHIFT )
-#define T37 _EQ( MULTIPLY )
-#define T38 _EQ( LMENU )
-#define T39 _EQ( ' ' )
-#define T3A _NE(DBE_ALPHANUMERIC,DBE_ALPHANUMERIC,CAPITAL,CAPITAL,CAPITAL,CAPITAL,CAPITAL )
-#define T3B _EQ( F1 )
-#define T3C _EQ( F2 )
-#define T3D _EQ( F3 )
-#define T3E _EQ( F4 )
-#define T3F _EQ( F5 )
-#define T40 _EQ( F6 )
-#define T41 _EQ( F7 )
-#define T42 _EQ( F8 )
-#define T43 _EQ( F9 )
-#define T44 _EQ( F10 )
-#define T45 _EQ( NUMLOCK )
-#define T46 _EQ( SCROLL )
-#define T47 _EQ( HOME )
-#define T48 _EQ( UP )
-#define T49 _EQ( PRIOR )
-#define T4A _EQ( SUBTRACT )
-#define T4B _EQ( LEFT )
-#define T4C _EQ( CLEAR )
-#define T4D _EQ( RIGHT )
-#define T4E _EQ( ADD )
-#define T4F _EQ( END )
-#define T50 _EQ( DOWN )
-#define T51 _EQ( NEXT )
-#define T52 _EQ( INSERT )
-#define T53 _EQ( DELETE )
-#define T54 _EQ( SNAPSHOT )
-#define T55 _EQ( _none_ )
-#define T56 _NE(_none_, _none_, OEM_102, OEM_102, OEM_102, OEM_102, OEM_102 )
-#define T57 _EQ( F11 )
-#define T58 _EQ( F12 )
-#define T59 _EQ( CLEAR )
-#define T5A _NE(NONAME, NONAME, NONCONVERT,OEM_WSCTRL,OEM_WSCTRL,OEM_WSCTRL,OEM_WSCTRL)
-#define T5B _NE(NONAME, NONAME, CONVERT, OEM_FINISH,OEM_FINISH,OEM_FINISH,OEM_FINISH)
-#define T5C _NE(NONAME, NONAME, OEM_AX, OEM_JUMP, OEM_JUMP, OEM_JUMP, OEM_JUMP )
-#define T5D _EQ( EREOF )
-#define T5E _NE(_none_, _none_, _none_, OEM_BACKTAB,OEM_BACKTAB,OEM_BACKTAB,OEM_BACKTAB)
-#define T5F _NE(NONAME, NONAME, NONAME, OEM_AUTO, OEM_AUTO, OEM_AUTO, OEM_AUTO )
-#define T60 _EQ( _none_ )
-#define T61 _NE(_none_, _none_, _none_, ZOOM, ZOOM, ZOOM, ZOOM )
-#define T62 _NE(_none_, _none_, _none_, HELP, HELP, HELP, HELP )
-#define T63 _EQ( _none_ )
-#define T64 _EQ( F13 )
-#define T65 _EQ( F14 )
-#define T66 _EQ( F15 )
-#define T67 _EQ( F16 )
-#define T68 _EQ( F17 )
-#define T69 _EQ( F18 )
-#define T6A _EQ( F19 )
-#define T6B _EQ( F20 )
-#define T6C _EQ( F21 )
-#define T6D _EQ( F22 )
-#define T6E _EQ( F23 )
-#define T6F _NE(_none_, _none_, _none_, OEM_PA3, OEM_PA3, OEM_PA3, OEM_PA3 )
-#define T70 _NE(DBE_KATAKANA,DBE_HIRAGANA,_none_,_none_, _none_, _none_, _none_ )
-#define T71 _NE(_none_, _none_, _none_, OEM_RESET, OEM_RESET, OEM_RESET, OEM_RESET )
-#define T72 _EQ( _none_ )
-#define T73 _NE(OEM_102, OEM_102, _none_, ABNT_C1, ABNT_C1, ABNT_C1, ABNT_C1 )
-#define T74 _EQ( _none_ )
-#define T75 _EQ( _none_ )
-#define T76 _EQ( F24 )
-#define T77 _NE(DBE_SBCSCHAR,_none_, _none_, _none_, _none_, _none_, _none_ )
-#define T78 _EQ( _none_ )
-#define T79 _NE(CONVERT, CONVERT, _none_, _none_, _none_, _none_, _none_ )
-#define T7A _EQ( _none_ )
-#define T7B _NE(NONCONVERT,NONCONVERT,_none_, OEM_PA1, OEM_PA1, OEM_PA1, OEM_PA1 )
-#define T7C _EQ( TAB )
-#define T7D _NE(_none_, OEM_5, _none_, _none_, _none_, _none_, _none_ )
-#define T7E _EQ( ABNT_C2 )
-#define T7F _EQ( OEM_PA2 )
-
-#define X10 _EQ( MEDIA_PREV_TRACK ) // SpeedRacer
-#define X19 _EQ( MEDIA_NEXT_TRACK ) // SpeedRacer
-#define X1C _EQ( RETURN )
-#define X1D _NE(RCONTROL, RCONTROL,DBE_KATAKANA,HANJA, HANGEUL, RCONTROL, RCONTROL )
-#define X20 _EQ( VOLUME_MUTE ) // SpeedRacer
-#define X21 _EQ( LAUNCH_APP2 ) // SpeedRacer
-#define X22 _EQ( MEDIA_PLAY_PAUSE ) // SpeedRacer
-#define X24 _EQ( MEDIA_STOP ) // SpeedRacer
-#define X2E _EQ( VOLUME_DOWN ) // SpeedRacer
-#define X30 _EQ( VOLUME_UP ) // SpeedRacer
-#define X32 _EQ( BROWSER_HOME ) // SpeedRacer
-#define X33 _NE(OEM_8, _none_, _none_, _none_, _none_, _none_, _none_ )
-#define X35 _EQ( DIVIDE )
-#define X37 _EQ( SNAPSHOT )
-#define X38 _NE(DBE_HIRAGANA,RMENU, KANJI, HANGEUL, HANJA, RMENU, RMENU )
-#define X42 _EQ( _none_ )
-#define X43 _EQ( _none_ )
-#define X44 _EQ( _none_ )
-#define X46 _EQ( CANCEL )
-#define X47 _EQ( HOME )
-#define X48 _EQ( UP )
-#define X49 _EQ( PRIOR )
-#define X4B _EQ( LEFT )
-#define X4D _EQ( RIGHT )
-#define X4F _EQ( END )
-#define X50 _EQ( DOWN )
-#define X51 _EQ( NEXT )
-#define X52 _EQ( INSERT )
-#define X53 _EQ( DELETE )
-#define X5B _EQ( LWIN )
-#define X5C _EQ( RWIN )
-#define X5D _EQ( APPS )
-#define X5E _EQ( POWER )
-#define X5F _EQ( SLEEP )
-#define X65 _EQ( BROWSER_SEARCH ) // SpeedRacer
-#define X66 _EQ( BROWSER_FAVORITES ) // SpeedRacer
-#define X67 _EQ( BROWSER_REFRESH ) // SpeedRacer
-#define X68 _EQ( BROWSER_STOP ) // SpeedRacer
-#define X69 _EQ( BROWSER_FORWARD ) // SpeedRacer
-#define X6A _EQ( BROWSER_BACK ) // SpeedRacer
-#define X6B _EQ( LAUNCH_APP1 ) // SpeedRacer
-#define X6C _EQ( LAUNCH_MAIL ) // SpeedRacer
-#define X6D _EQ( LAUNCH_MEDIA_SELECT ) // SpeedRacer
-#define XF1 _NE(_none_, _none_, _none_, HANJA, HANJA, HANJA, HANJA )
-#define XF2 _NE(_none_, _none_, _none_, HANGEUL, HANGEUL, HANGEUL, HANGEUL )
-
- /*
- * The break key is sent to us as E1,LCtrl,NumLock
- * We must convert the E1+LCtrl to BREAK, then ignore the Numlock
- */
-#define Y1D _EQ( PAUSE )
-
-#elif (KBD_TYPE > 20) && (KBD_TYPE <= 22)
-/***********************************************************************\
-* T** - Values for ausVK[] (Virtual Scan Code to Virtual Key conversion)
-*
-* Three sets of keyboards are supported, according to KBD_TYPE:
-*
-* KBD_TYPE Keyboard (examples)
-* ======== =====================================
-* 20 Fujitsu FMR JIS keyboard.
-* 21 Fujitsu FMR OYAYUBI keyboard.
-* 22 * Fujitsu FMV OYAYUBI keyboard.
-*
-* +------+ +----------+----------+----------+
-* | Scan | | kbd | kbd | kbd |
-* | code | | type 20 | type 21 | type 22 |
-\****+-------+-+----------+----------+----------+***********************/
-#define T00 _EQ( _none_ )
-#define T01 _EQ( ESCAPE )
-#define T02 _EQ( '1' )
-#define T03 _EQ( '2' )
-#define T04 _EQ( '3' )
-#define T05 _EQ( '4' )
-#define T06 _EQ( '5' )
-#define T07 _EQ( '6' )
-#define T08 _EQ( '7' )
-#define T09 _EQ( '8' )
-#define T0A _EQ( '9' )
-#define T0B _EQ( '0' )
-#define T0C _EQ( OEM_MINUS )
-#define T0D _EQ( OEM_7 )
-#define T0E _NE(OEM_5, OEM_5, BACK )
-#define T0F _NE(BACK, BACK, TAB )
-#define T10 _NE(TAB, TAB, 'Q' )
-#define T11 _NE('Q', 'Q', 'W' )
-#define T12 _NE('W', 'W', 'E' )
-#define T13 _NE('E', 'E', 'R' )
-#define T14 _NE('R', 'R', 'T' )
-#define T15 _NE('T', 'T', 'Y' )
-#define T16 _NE('Y', 'Y', 'U' )
-#define T17 _NE('U', 'U', 'I' )
-#define T18 _NE('I', 'I', 'O' )
-#define T19 _NE('O', 'O', 'P' )
-#define T1A _NE('P', 'P', OEM_3 )
-#define T1B _NE(OEM_3, OEM_3, OEM_4 )
-#define T1C _NE(OEM_4, OEM_4, RETURN )
-#define T1D _NE(RETURN, RETURN, LCONTROL )
-#define T1E _EQ( 'A' )
-#define T1F _EQ( 'S' )
-#define T20 _EQ( 'D' )
-#define T21 _EQ( 'F' )
-#define T22 _EQ( 'G' )
-#define T23 _EQ( 'H' )
-#define T24 _EQ( 'J' )
-#define T25 _EQ( 'K' )
-#define T26 _EQ( 'L' )
-#define T27 _EQ( OEM_PLUS )
-#define T28 _EQ( OEM_1 )
-#define T29 _NE(OEM_6, OEM_6, DBE_SBCSCHAR)
-#define T2A _NE('Z', 'Z', LSHIFT )
-#define T2B _NE('X', 'X', OEM_6 )
-#define T2C _NE('C', 'C', 'Z' )
-#define T2D _NE('V', 'V', 'X' )
-#define T2E _NE('B', 'B', 'C' )
-#define T2F _NE('N', 'N', 'V' )
-#define T30 _NE('M', 'M', 'B' )
-#define T31 _NE(OEM_COMMA, OEM_COMMA, 'N' )
-#define T32 _NE(OEM_PERIOD,OEM_PERIOD,'M' )
-#define T33 _NE(OEM_2, OEM_2, OEM_COMMA )
-#define T34 _NE(OEM_8, OEM_8, OEM_PERIOD)
-#define T35 _NE(' ', ' ', OEM_2 )
-#define T36 _NE(MULTIPLY, MULTIPLY, RSHIFT )
-#define T37 _NE(DIVIDE, DIVIDE, MULTIPLY )
-#define T38 _NE(ADD, ADD, LMENU )
-#define T39 _NE(SUBTRACT, SUBTRACT, ' ' )
-#define T3A _NE(NUMPAD7, NUMPAD7, DBE_ALPHANUMERIC)
-#define T3B _NE(NUMPAD8, NUMPAD8, F1 )
-#define T3C _NE(NUMPAD9, NUMPAD9, F2 )
-#define T3D _NE(EQUAL, EQUAL, F3 )
-#define T3E _NE(NUMPAD4, NUMPAD4, F4 )
-#define T3F _NE(NUMPAD5, NUMPAD5, F5 )
-#define T40 _NE(NUMPAD6, NUMPAD6, F6 )
-#define T41 _NE(SEPARATOR, SEPARATOR, F7 )
-#define T42 _NE(NUMPAD1, NUMPAD1, F8 )
-#define T43 _NE(NUMPAD2, NUMPAD2, F9 )
-#define T44 _NE(NUMPAD3, NUMPAD3, F10 )
-#define T45 _NE(RETURN, RETURN, NUMLOCK )
-#define T46 _NE(NUMPAD0, NUMPAD0, SCROLL )
-#define T47 _NE(DECIMAL, DECIMAL, HOME )
-#define T48 _NE(INSERT, INSERT, UP )
-#define T49 _NE(OEM_00, OEM_00, PRIOR )
-#define T4A _NE(OEM_000, OEM_000, SUBTRACT )
-#define T4B _NE(DELETE, DELETE, LEFT )
-#define T4C _NE(_none_, _none_, CLEAR )
-#define T4D _NE(UP, UP, RIGHT )
-#define T4E _NE(HOME, HOME, ADD )
-#define T4F _NE(LEFT, LEFT, END )
-#define T50 _EQ( DOWN )
-#define T51 _NE(RIGHT, RIGHT, NEXT )
-#define T52 _NE(LCONTROL, LCONTROL, INSERT )
-#define T53 _NE(LSHIFT, LSHIFT, DELETE )
-#define T54 _NE(_none_, _none_, SNAPSHOT )
-#define T55 _NE(CAPITAL, _none_, _none_ )
-#define T56 _NE(DBE_HIRAGANA,_none_, _none_ )
-#define T57 _NE(NONCONVERT,NONCONVERT,F11 )
-#define T58 _NE(CONVERT, CONVERT, F12 )
-#define T59 _NE(KANJI, KANJI, CLEAR )
-#define T5A _NE(DBE_KATAKANA,_none_, NONAME )
-#define T5B _NE(F12, F12, NONAME )
-#define T5C _NE(LMENU, LMENU, NONAME )
-#define T5D _NE(F1, F1, EREOF )
-#define T5E _NE(F2, F2, _none_ )
-#define T5F _NE(F3, F3, NONAME )
-#define T60 _NE(F4, F4, _none_ )
-#define T61 _NE(F5, F5, _none_ )
-#define T62 _NE(F6, F6, _none_ )
-#define T63 _NE(F7, F7, _none_ )
-#define T64 _NE(F8, F8, F13 )
-#define T65 _NE(F9, F9, F14 )
-#define T66 _NE(F10, F10, F15 )
-#define T67 _NE(_none_, OEM_LOYA, F16 )
-#define T68 _NE(_none_, OEM_ROYA, F17 )
-#define T69 _NE(F11, F11, F18 )
-#define T6A _NE(_none_, DBE_ALPHANUMERIC,F19 )
-#define T6B _NE(OEM_JISHO, OEM_JISHO, F20 )
-#define T6C _NE(OEM_MASSHOU,OEM_MASSHOU,F21 )
-#define T6D _NE(_none_, _none_, F22 )
-#define T6E _NE(PRIOR, PRIOR, F23 )
-#define T6F _NE(_none_, DBE_KATAKANA,_none_ )
-#define T70 _NE(NEXT, NEXT, DBE_HIRAGANA)
-#define T71 _EQ( _none_ )
-#define T72 _NE(CANCEL, CANCEL, _none_ )
-#define T73 _NE(EXECUTE, EXECUTE, OEM_102 )
-#define T74 _NE(F13, F13, _none_ )
-#define T75 _NE(F14, F14, _none_ )
-#define T76 _NE(F15, F15, F24 )
-#define T77 _NE(F16, F16, _none_ )
-#define T78 _NE(CLEAR, CLEAR, _none_ )
-#define T79 _NE(HELP, HELP, CONVERT )
-#define T7A _NE(END, END, _none_ )
-#define T7B _NE(SCROLL, SCROLL, NONCONVERT)
-#define T7C _NE(PAUSE, PAUSE, TAB )
-#define T7D _NE(SNAPSHOT, SNAPSHOT, OEM_5 )
-#define T7E _NE(_none_, _none_, ABNT_C2 )
-#define T7F _NE(_none_, _none_, OEM_PA2 )
-
-#define X1C _NE(_none_, _none_, RETURN )
-#define X1D _NE(_none_, _none_, RCONTROL )
-#define X33 _EQ( _none_ )
-#define X35 _NE(_none_, _none_, DIVIDE )
-#define X37 _NE(_none_, _none_, SNAPSHOT )
-#define X38 _NE(_none_, _none_, RMENU )
-#define X42 _EQ( _none_ )
-#define X43 _EQ( _none_ )
-#define X44 _EQ( _none_ )
-#define X46 _NE(_none_, _none_, CANCEL )
-#define X47 _NE(_none_, _none_, HOME )
-#define X48 _NE(_none_, _none_, UP )
-#define X49 _NE(_none_, _none_, PRIOR )
-#define X4B _NE(_none_, _none_, LEFT )
-#define X4D _NE(_none_, _none_, RIGHT )
-#define X4F _NE(_none_, _none_, END )
-#define X50 _NE(_none_, _none_, DOWN )
-#define X51 _NE(_none_, _none_, NEXT )
-#define X52 _NE(_none_, _none_, INSERT )
-#define X53 _NE(_none_, _none_, DELETE )
-#define X5B _NE(_none_, _none_, LWIN )
-#define X5C _NE(_none_, _none_, RWIN )
-#define X5D _NE(_none_, _none_, APPS )
-#define X5E _EQ( POWER )
-#define X5F _EQ( SLEEP )
-#define X60 _NE(SCROLL, SCROLL, _none_ )
-#define X61 _NE(HOME, HOME, _none_ )
-#define X62 _NE(END, END, _none_ )
-#define X63 _EQ( _none_ )
-#define X64 _EQ( _none_ )
-#define X65 _EQ( _none_ )
-#define X66 _EQ( _none_ )
-#define X6D _NE(OEM_TOUROKU,OEM_TOUROKU,_none_ )
-#define X71 _NE(DBE_SBCSCHAR,DBE_SBCSCHAR,_none_)
-#define X74 _EQ( _none_ )
-#define X75 _EQ( _none_ )
-#define X76 _EQ( _none_ )
-#define X77 _EQ( _none_ )
-#define X78 _EQ( _none_ )
-#define X79 _EQ( _none_ )
-#define X7A _EQ( _none_ )
-#define X7B _EQ( _none_ )
-
- /*
- * The break key is sent to us as E1,LCtrl,NumLock
- * We must convert the E1+LCtrl to BREAK, then ignore the Numlock
- * which must be ignored. Alternatively, translate Ctrl-Numlock
- * to break, but don't let the CTRL through as a WM_KEYUP/DOWN) ?
- */
-#define Y1D _EQ( PAUSE )
-
-#elif (KBD_TYPE >= 30) && (KBD_TYPE <= 34)
-/***********************************************************************\
-* T** - Values for ausVK[] (Virtual Scan Code to Virtual Key conversion)
-*
-* Three sets of keyboards are supported, according to KBD_TYPE:
-*
-* KBD_TYPE Keyboard (examples)
-* ======== =====================================
-* 30 * NEC PC-9800 Normal Keyboard.
-* 31 NEC PC-9800 Document processor Keyboard. - not supported on NT5
-* 32 NEC PC-9800 106 Keyboard. - same as KBD_TYPE 8
-* 33 NEC PC-9800 for Hydra: PC-9800 Keyboard on Windows NT 5.0.
-* NEC PC-98NX for Hydra: PC-9800 Keyboard on Windows 95/NT.
-* 34 NEC PC-9800 for Hydra: PC-9800 Keyboard on Windows NT 3.51/4.0.
-*
-* +------+ +----------+----------+----------+
-* | Scan | | kbd | kbd | kbd |
-* | code | | type 30 | type 33 | type 34 |
-\****+-------+-+----------+----------+----------+***********************/
-#define T00 _EQ(_none_ )
-#define T01 _EQ(ESCAPE )
-#define T02 _EQ('1' )
-#define T03 _EQ('2' )
-#define T04 _EQ('3' )
-#define T05 _EQ('4' )
-#define T06 _EQ('5' )
-#define T07 _EQ('6' )
-#define T08 _EQ('7' )
-#define T09 _EQ('8' )
-#define T0A _EQ('9' )
-#define T0B _EQ('0' )
-#define T0C _EQ(OEM_MINUS )
-#define T0D _NE(OEM_7, OEM_7, OEM_PLUS )
-#define T0E _EQ(BACK )
-#define T0F _EQ(TAB )
-#define T10 _EQ('Q' )
-#define T11 _EQ('W' )
-#define T12 _EQ('E' )
-#define T13 _EQ('R' )
-#define T14 _EQ('T' )
-#define T15 _EQ('Y' )
-#define T16 _EQ('U' )
-#define T17 _EQ('I' )
-#define T18 _EQ('O' )
-#define T19 _EQ('P' )
-#define T1A _NE(OEM_3, OEM_3, OEM_4 )
-#define T1B _NE(OEM_4, OEM_4, OEM_6 )
-#define T1C _EQ(RETURN )
-#define T1D _EQ(LCONTROL )
-#define T1E _EQ('A' )
-#define T1F _EQ('S' )
-#define T20 _EQ('D' )
-#define T21 _EQ('F' )
-#define T22 _EQ('G' )
-#define T23 _EQ('H' )
-#define T24 _EQ('J' )
-#define T25 _EQ('K' )
-#define T26 _EQ('L' )
-#define T27 _NE(OEM_PLUS, OEM_PLUS, OEM_1 )
-#define T28 _NE(OEM_1, OEM_1, OEM_7 )
-#define T29 _NE(DBE_SBCSCHAR, \
- DBE_SBCSCHAR, \
- OEM_3 )
-#define T2A _EQ(LSHIFT )
-#define T2B _NE(OEM_6, OEM_6, OEM_5 )
-#define T2C _EQ('Z' )
-#define T2D _EQ('X' )
-#define T2E _EQ('C' )
-#define T2F _EQ('V' )
-#define T30 _EQ('B' )
-#define T31 _EQ('N' )
-#define T32 _EQ('M' )
-#define T33 _EQ(OEM_COMMA )
-#define T34 _EQ(OEM_PERIOD )
-#define T35 _EQ(OEM_2 )
-#define T36 _EQ(RSHIFT )
-#define T37 _EQ(MULTIPLY )
-#define T38 _EQ(LMENU )
-#define T39 _EQ(' ' )
-#define T3A _EQ(CAPITAL )
-#define T3B _EQ(F1 )
-#define T3C _EQ(F2 )
-#define T3D _EQ(F3 )
-#define T3E _EQ(F4 )
-#define T3F _EQ(F5 )
-#define T40 _EQ(F6 )
-#define T41 _EQ(F7 )
-#define T42 _EQ(F8 )
-#define T43 _EQ(F9 )
-#define T44 _EQ(F10 )
-#define T45 _EQ(NUMLOCK )
-#define T46 _EQ(SCROLL )
-#define T47 _EQ(HOME )
-#define T48 _EQ(UP )
-#define T49 _EQ(PRIOR )
-#define T4A _EQ(SUBTRACT )
-#define T4B _EQ(LEFT )
-#define T4C _EQ(CLEAR )
-#define T4D _EQ(RIGHT )
-#define T4E _EQ(ADD )
-#define T4F _EQ(END )
-#define T50 _EQ(DOWN )
-#define T51 _EQ(NEXT )
-#define T52 _EQ(INSERT )
-#define T53 _EQ(DELETE )
-#define T54 _EQ(SNAPSHOT )
-#define T55 _NE(_none_, _none_, OEM_8 )
-#define T56 _EQ(_none_ )
-#define T57 _EQ(F11 )
-#define T58 _EQ(F12 )
-#define T59 _EQ(OEM_NEC_EQUAL )
-#define T5A _NE(NONAME, NONAME, NONCONVERT)
-#define T5B _NE(_none_, _none_, NONAME )
-#define T5C _EQ(SEPARATOR )
-#define T5D _EQ(F13 )
-#define T5E _EQ(F14 )
-#define T5F _EQ(F15 )
-#define T60 _EQ(_none_ )
-#define T61 _EQ(_none_ )
-#define T62 _EQ(_none_ )
-#define T63 _EQ(_none_ )
-#define T64 _NE(_none_, _none_, F13 )
-#define T65 _NE(_none_, _none_, F14 )
-#define T66 _NE(_none_, _none_, F15 )
-#define T67 _NE(_none_, _none_, F16 )
-#define T68 _NE(_none_, _none_, F17 )
-#define T69 _NE(_none_, _none_, F18 )
-#define T6A _NE(_none_, _none_, F19 )
-#define T6B _NE(_none_, _none_, F20 )
-#define T6C _NE(_none_, _none_, F21 )
-#define T6D _NE(_none_, _none_, F22 )
-#define T6E _NE(_none_, _none_, F23 )
-#define T6F _EQ(_none_ )
-#define T70 _NE(KANA, KANA, DBE_HIRAGANA)
-#define T71 _EQ(_none_ )
-#define T72 _EQ(_none_ )
-#define T73 _NE(OEM_8, OEM_8, _none_ )
-#define T74 _NE(_none_, OEM_NEC_EQUAL, \
- _none_ )
-#define T75 _NE(_none_, SEPARATOR, _none_ )
-#define T76 _NE(_none_, _none_, F24 )
-#define T77 _NE(_none_, _none_, DBE_SBCSCHAR)
-#define T78 _EQ(_none_ )
-#define T79 _EQ(CONVERT )
-#define T7A _EQ(_none_ )
-#define T7B _EQ(NONCONVERT )
-#define T7C _NE(TAB, _none_, _none_ )
-#define T7D _NE(OEM_5, OEM_5, _none_ )
-#define T7E _NE(ABNT_C2, ABNT_C2, _none_ )
-#define T7F _NE(OEM_PA2, OEM_PA2, _none_ )
-
-#define X1C _EQ(RETURN )
-#define X1D _NE(RCONTROL, RCONTROL, KANA )
-#define X33 _EQ(_none_ )
-#define X35 _EQ(DIVIDE )
-#define X37 _EQ(SNAPSHOT )
-#define X38 _NE(_none_, _none_, KANJI )
-#define X42 _NE(_none_, _none_, RCONTROL )
-#define X43 _NE(_none_, _none_, RMENU )
-#define X44 _EQ(_none_ )
-#define X46 _EQ(CANCEL )
-#define X47 _EQ(HOME )
-#define X48 _EQ(UP )
-#define X49 _EQ(PRIOR )
-#define X4B _EQ(LEFT )
-#define X4D _EQ(RIGHT )
-#define X4F _EQ(END )
-#define X50 _EQ(DOWN )
-#define X51 _EQ(NEXT )
-#define X52 _EQ(INSERT )
-#define X53 _EQ(DELETE )
-#define X5B _EQ(LWIN )
-#define X5C _EQ(RWIN )
-#define X5D _EQ(APPS )
-#define X5E _EQ(POWER )
-#define X5F _EQ(SLEEP )
-#define X60 _EQ(_none_ )
-#define X61 _EQ(_none_ )
-#define X62 _EQ(_none_ )
-#define X63 _EQ(_none_ )
-#define X64 _EQ(_none_ )
-#define X65 _EQ(_none_ )
-#define X66 _EQ(_none_ )
-#define X6D _EQ(_none_ )
-#define X71 _EQ(_none_ )
-#define X74 _EQ(_none_ )
-#define X75 _EQ(_none_ )
-#define X76 _EQ(_none_ )
-#define X77 _EQ(_none_ )
-#define X78 _EQ(_none_ )
-#define X79 _EQ(_none_ )
-#define X7A _EQ(_none_ )
-#define X7B _EQ(_none_ )
- /*
- * The break key is sent to us as E1,LCtrl,NumLock
- * We must convert the E1+LCtrl to BREAK, then ignore the Numlock
- * which must be ignored. Alternatively, translate Ctrl-Numlock
- * to break, but don't let the CTRL through as a WM_KEYUP/DOWN) ?
- */
-#define Y1D _EQ(PAUSE )
-
-#elif (KBD_TYPE == 37)
-/***********************************************************************\
-* T** - Values for ausVK[] (Virtual Scan Code to Virtual Key conversion)
-*
-* Three sets of keyboards are supported, according to KBD_TYPE:
-*
-* KBD_TYPE Keyboard (examples)
-* ======== =====================================
-* 37 * NEC PC-9800 for Hydra: PC-9800 Keyboard on Windows 95.
-*
-* +------+ +----------+
-* | Scan | | kbd |
-* | code | | type 37 |
-\****+-------+-+----------+*********************************************/
-#define T00 _EQ(ESCAPE )
-#define T01 _EQ('1' )
-#define T02 _EQ('2' )
-#define T03 _EQ('3' )
-#define T04 _EQ('4' )
-#define T05 _EQ('5' )
-#define T06 _EQ('6' )
-#define T07 _EQ('7' )
-#define T08 _EQ('8' )
-#define T09 _EQ('9' )
-#define T0A _EQ('0' )
-#define T0B _EQ(OEM_MINUS )
-#define T0C _EQ(OEM_7 )
-#define T0D _EQ(OEM_5 )
-#define T0E _EQ(BACK )
-#define T0F _EQ(TAB )
-#define T10 _EQ('Q' )
-#define T11 _EQ('W' )
-#define T12 _EQ('E' )
-#define T13 _EQ('R' )
-#define T14 _EQ('T' )
-#define T15 _EQ('Y' )
-#define T16 _EQ('U' )
-#define T17 _EQ('I' )
-#define T18 _EQ('O' )
-#define T19 _EQ('P' )
-#define T1A _EQ(OEM_3 )
-#define T1B _EQ(OEM_4 )
-#define T1C _EQ(RETURN )
-#define T1D _EQ('A' )
-#define T1E _EQ('S' )
-#define T1F _EQ('D' )
-#define T20 _EQ('F' )
-#define T21 _EQ('G' )
-#define T22 _EQ('H' )
-#define T23 _EQ('J' )
-#define T24 _EQ('K' )
-#define T25 _EQ('L' )
-#define T26 _EQ(OEM_PLUS )
-#define T27 _EQ(OEM_1 )
-#define T28 _EQ(OEM_6 )
-#define T29 _EQ('Z' )
-#define T2A _EQ('X' )
-#define T2B _EQ('C' )
-#define T2C _EQ('V' )
-#define T2D _EQ('B' )
-#define T2E _EQ('N' )
-#define T2F _EQ('M' )
-#define T30 _EQ(OEM_COMMA )
-#define T31 _EQ(OEM_PERIOD)
-#define T32 _EQ(OEM_2 )
-#define T33 _EQ(OEM_8 )
-#define T34 _EQ(' ' )
-#define T35 _EQ(CONVERT )
-#define T36 _EQ(NEXT )
-#define T37 _EQ(PRIOR )
-#define T38 _EQ(INSERT )
-#define T39 _EQ(DELETE )
-#define T3A _EQ(UP )
-#define T3B _EQ(LEFT )
-#define T3C _EQ(RIGHT )
-#define T3D _EQ(DOWN )
-#define T3E _EQ(HOME )
-#define T3F _EQ(END )
-#define T40 _EQ(SUBTRACT )
-#define T41 _EQ(DIVIDE )
-#define T42 _EQ(NUMPAD7 )
-#define T43 _EQ(NUMPAD8 )
-#define T44 _EQ(NUMPAD9 )
-#define T45 _EQ(MULTIPLY )
-#define T46 _EQ(NUMPAD4 )
-#define T47 _EQ(NUMPAD5 )
-#define T48 _EQ(NUMPAD6 )
-#define T49 _EQ(ADD )
-#define T4A _EQ(NUMPAD1 )
-#define T4B _EQ(NUMPAD2 )
-#define T4C _EQ(NUMPAD3 )
-#define T4D _EQ(OEM_NEC_EQUAL)
-#define T4E _EQ(NUMPAD0 )
-#define T4F _EQ(SEPARATOR )
-#define T50 _EQ(DECIMAL )
-#define T51 _EQ(NONCONVERT)
-#define T52 _EQ(F11 )
-#define T53 _EQ(F12 )
-#define T54 _EQ(F13 )
-#define T55 _EQ(F14 )
-#define T56 _EQ(F15 )
-#define T57 _EQ(_none_ )
-#define T58 _EQ(_none_ )
-#define T59 _EQ(_none_ )
-#define T5A _EQ(_none_ )
-#define T5B _EQ(_none_ )
-#define T5C _EQ(RETURN )
-#define T5D _EQ(_none_ )
-#define T5E _EQ(_none_ )
-#define T5F _EQ(_none_ )
-#define T60 _EQ(CANCEL )
-#define T61 _EQ(SNAPSHOT )
-#define T62 _EQ(F1 )
-#define T63 _EQ(F2 )
-#define T64 _EQ(F3 )
-#define T65 _EQ(F4 )
-#define T66 _EQ(F5 )
-#define T67 _EQ(F6 )
-#define T68 _EQ(F7 )
-#define T69 _EQ(F8 )
-#define T6A _EQ(F9 )
-#define T6B _EQ(F10 )
-#define T6C _EQ(_none_ )
-#define T6D _EQ(_none_ )
-#define T6E _EQ(_none_ )
-#define T6F _EQ(_none_ )
-#define T70 _EQ(LSHIFT )
-#define T71 _EQ(CAPITAL )
-#define T72 _EQ(KANA )
-#define T73 _EQ(LMENU )
-#define T74 _EQ(LCONTROL )
-#define T75 _EQ(_none_ )
-#define T76 _EQ(_none_ )
-#define T77 _EQ(LWIN )
-#define T78 _EQ(RWIN )
-#define T79 _EQ(APPS )
-#define T7A _EQ(_none_ )
-#define T7B _EQ(_none_ )
-#define T7C _EQ(_none_ )
-#define T7D _EQ(RSHIFT )
-#define T7E _EQ(ABNT_C2 )
-#define T7F _EQ(OEM_PA2 )
-
- /*
- * The break key is sent to us as E1,LCtrl,NumLock
- * We must conevrt the E1+LCtrl to BREAK, then ignore the Numlock
- * which must be ignored. Alternatively, translate Ctrl-Numlock
- * to break, but don't let the CTRL through as a WM_KEYUP/DOWN) ?
- */
-#define Y1D _EQ(PAUSE )
-
-#elif (KBD_TYPE >= 40) && (KBD_TYPE <= 41)
-/***********************************************************************\
-* T** - Values for ausVK[] (Virtual Scan Code to Virtual Key conversion)
-*
-* Two sets of keyboards are supported, according to KBD_TYPE:
-*
-* KBD_TYPE Keyboard (examples)
-* ======== =====================================
-* 40 * DEC LK411-JJ (JIS layout) keyboard
-* 41 DEC LK411-AJ (ANSI layout) keyboard
-*
-* +------+ +-----------+-----------+
-* | Scan | | kbd | kbd |
-* | code | | LK411-JJ | LK411-AJ |
-\*****+------+-+-----------+-----------+********************************/
-#define T00 _EQ( _none_ )
-#define T01 _EQ( ESCAPE )
-#define T02 _EQ( '1' )
-#define T03 _EQ( '2' )
-#define T04 _EQ( '3' )
-#define T05 _EQ( '4' )
-#define T06 _EQ( '5' )
-#define T07 _EQ( '6' )
-#define T08 _EQ( '7' )
-#define T09 _EQ( '8' )
-#define T0A _EQ( '9' )
-#define T0B _EQ( '0' )
-#define T0C _EQ( OEM_MINUS )
-#define T0D _NE( OEM_7, OEM_PLUS ) // "^"/"="
-#define T0E _EQ( BACK )
-#define T0F _EQ( TAB )
-#define T10 _EQ( 'Q' )
-#define T11 _EQ( 'W' )
-#define T12 _EQ( 'E' )
-#define T13 _EQ( 'R' )
-#define T14 _EQ( 'T' )
-#define T15 _EQ( 'Y' )
-#define T16 _EQ( 'U' )
-#define T17 _EQ( 'I' )
-#define T18 _EQ( 'O' )
-#define T19 _EQ( 'P' )
-#define T1A _NE( OEM_3, OEM_4 ) // "@"/"["
-#define T1B _NE( OEM_4, OEM_6 ) // "["/"]"
-#define T1C _EQ( RETURN )
-#define T1D _EQ( LCONTROL )
-#define T1E _EQ( 'A' )
-#define T1F _EQ( 'S' )
-#define T20 _EQ( 'D' )
-#define T21 _EQ( 'F' )
-#define T22 _EQ( 'G' )
-#define T23 _EQ( 'H' )
-#define T24 _EQ( 'J' )
-#define T25 _EQ( 'K' )
-#define T26 _EQ( 'L' )
-#define T27 _NE( OEM_PLUS, OEM_1 ) // ";"
-#define T28 _NE( OEM_1, OEM_7 ) // ":"/"'"
-#define T29 _NE( _none_, DBE_SBCSCHAR ) // LK411AJ uses "<>" as SBCS/DBCS key
-#define T2A _EQ( LSHIFT )
-#define T2B _NE( OEM_6, OEM_5 ) // "]"/"\"
-#define T2C _EQ( 'Z' )
-#define T2D _EQ( 'X' )
-#define T2E _EQ( 'C' )
-#define T2F _EQ( 'V' )
-#define T30 _EQ( 'B' )
-#define T31 _EQ( 'N' )
-#define T32 _EQ( 'M' )
-#define T33 _EQ( OEM_COMMA )
-#define T34 _EQ( OEM_PERIOD )
-#define T35 _EQ( OEM_2 ) // "/"
-#define T36 _EQ( RSHIFT )
-#define T37 _EQ( MULTIPLY ) // PF3 : "*"
-#define T38 _EQ( LMENU ) // Alt(Left)
-#define T39 _EQ( ' ' ) // Space
-#define T3A _EQ( CAPITAL ) // LOCK : Caps Lock
-#define T3B _EQ( F1 )
-#define T3C _EQ( F2 )
-#define T3D _EQ( F3 )
-#define T3E _EQ( F4 )
-#define T3F _EQ( F5 )
-#define T40 _EQ( F6 )
-#define T41 _EQ( F7 )
-#define T42 _EQ( F8 )
-#define T43 _EQ( F9 )
-#define T44 _EQ( F10 )
-#define T45 _EQ( NUMLOCK ) // PF1 : Num Lock
-#define T46 _EQ( SCROLL ) // F19 : Scroll Lock
-#define T47 _EQ( HOME ) // KP7 : Home
-#define T48 _EQ( UP ) // KP8 : Up
-#define T49 _EQ( PRIOR ) // KP9 : Page Up
-#define T4A _EQ( SUBTRACT ) // PF4 : "-"
-#define T4B _EQ( LEFT ) // KP4 : Left
-#define T4C _EQ( CLEAR ) // KP5 : Clear
-#define T4D _EQ( RIGHT ) // KP6 : Right
-#define T4E _EQ( ADD ) // KP, : Add
-#define T4F _EQ( END ) // KP1 : End
-#define T50 _EQ( DOWN ) // KP2 : Down
-#define T51 _EQ( NEXT ) // KP3 : Next
-#define T52 _EQ( INSERT ) // KP0 : Ins
-#define T53 _EQ( DELETE ) // KP. : Del
-#define T54 _EQ( SNAPSHOT )
-#define T55 _EQ( _none_ )
-#define T56 _EQ( _none_ )
-#define T57 _EQ( F11 )
-#define T58 _EQ( F12 )
-#define T59 _EQ( _none_ )
-#define T5A _EQ( _none_ )
-#define T5B _EQ( _none_ )
-#define T5C _EQ( _none_ )
-#define T5D _EQ( _none_ )
-#define T5E _EQ( _none_ )
-#define T5F _EQ( _none_ )
-#define T60 _EQ( _none_ )
-#define T61 _EQ( _none_ )
-#define T62 _EQ( _none_ )
-#define T63 _EQ( _none_ )
-#define T64 _EQ( _none_ )
-#define T65 _EQ( _none_ )
-#define T66 _EQ( _none_ )
-#define T67 _EQ( _none_ )
-#define T68 _EQ( _none_ )
-#define T69 _EQ( _none_ )
-#define T6A _EQ( _none_ )
-#define T6B _EQ( _none_ )
-#define T6C _EQ( _none_ )
-#define T6D _EQ( _none_ )
-#define T6E _EQ( _none_ )
-#define T6F _EQ( _none_ )
-#define T70 _EQ( DBE_HIRAGANA ) // Hiragana/Katakana
-#define T71 _EQ( _none_ )
-#define T72 _EQ( _none_ )
-#define T73 _NE( OEM_102, _none_ ) // LK411JJ, Katakana "Ro"
-#define T74 _EQ( _none_ )
-#define T75 _EQ( _none_ )
-#define T76 _EQ( _none_ )
-#define T77 _EQ( _none_ )
-#define T78 _EQ( _none_ )
-#define T79 _EQ( CONVERT ) // Henkan
-#define T7A _EQ( _none_ )
-#define T7B _EQ( NONCONVERT ) // Mu-Henkan
-#define T7C _EQ( _none_ )
-#define T7D _NE( OEM_5, _none_ ) // LK411JJ, Yen(Back-slash)
-#define T7E _EQ( _none_ )
-#define T7F _EQ( _none_ )
-
-#define X0F _EQ( KANA ) // Kana
-#define X1C _EQ( RETURN ) // Enter
-#define X1D _EQ( RCONTROL ) // Comp : Right Control
-#define X33 _EQ( _none_ )
-#define X35 _EQ( DIVIDE ) // PF2: "/"
-#define X37 _EQ( SNAPSHOT ) // F18: PrintScreen
-#define X38 _EQ( RMENU ) // Alt(Right)
-#define X3D _EQ( F13 )
-#define X3E _EQ( F14 )
-#define X3F _EQ( F15 ) // Help : F15
-#define X40 _EQ( F16 ) // Do : F16
-#define X41 _EQ( F17 )
-#define X42 _EQ( _none_ )
-#define X43 _EQ( _none_ )
-#define X44 _EQ( _none_ )
-#define X46 _EQ( CANCEL )
-#define X47 _EQ( HOME ) // Find : HOME
-#define X48 _EQ( UP )
-#define X49 _EQ( PRIOR ) // Prev : PageUp
-#define X4B _EQ( LEFT )
-#define X4D _EQ( RIGHT )
-#define X4E _EQ( ADD ) // KP- (Minus but "Add")
-#define X4F _EQ( END ) // Select : END
-#define X50 _EQ( DOWN )
-#define X51 _EQ( NEXT ) // Next : PageDown
-#define X52 _EQ( INSERT )
-#define X53 _EQ( DELETE ) // Remove
-#define X5B _EQ( _none_ )
-#define X5C _EQ( _none_ )
-#define X5D _EQ( _none_ )
-#define X5E _EQ( POWER )
-#define X5F _EQ( SLEEP )
- /*
- * The break key is sent to us as E1,LCtrl,NumLock
- * We must convert the E1+LCtrl to BREAK, then ignore the Numlock
- */
-#define Y1D _EQ( PAUSE )
-
-#endif // KBD_TYPE
-
-#define SCANCODE_LSHIFT 0x2A
-#define SCANCODE_RSHIFT 0x36
-#define SCANCODE_CTRL 0x1D
-#define SCANCODE_ALT 0x38
-#define SCANCODE_SIMULATED (FAKE_KEYSTROKE >> 16)
-
-#define SCANCODE_NUMPAD_FIRST 0x47
-#define SCANCODE_NUMPAD_LAST 0x52
-
-#define SCANCODE_LWIN 0x5B
-#define SCANCODE_RWIN 0x5C
-
-#define SCANCODE_THAI_LAYOUT_TOGGLE 0x29
-
-
-//@@BEGIN_DDKSPLIT
-/*
- * Hydra FarEast
- */
-
-/*
- * Structure for client keyboard information
- */
-typedef struct _CLIENTKEYBOARDTYPE {
- ULONG Type;
- ULONG SubType;
- ULONG FunctionKey;
-} CLIENTKEYBOARDTYPE, *KBD_LONG_POINTER PCLIENTKEYBOARDTYPE;
-//@@END_DDKSPLIT
-
-#if (NTDDI_VERSION >= NTDDI_WINXP)
-//@@BEGIN_DDKSPLIT
-#if !defined(VK_DBE_ALPHANUMERIC)
-//@@END_DDKSPLIT
-#define VK_DBE_ALPHANUMERIC 0x0f0
-#define VK_DBE_KATAKANA 0x0f1
-#define VK_DBE_HIRAGANA 0x0f2
-#define VK_DBE_SBCSCHAR 0x0f3
-#define VK_DBE_DBCSCHAR 0x0f4
-#define VK_DBE_ROMAN 0x0f5
-#define VK_DBE_NOROMAN 0x0f6
-#define VK_DBE_ENTERWORDREGISTERMODE 0x0f7
-#define VK_DBE_ENTERIMECONFIGMODE 0x0f8
-#define VK_DBE_FLUSHSTRING 0x0f9
-#define VK_DBE_CODEINPUT 0x0fa
-#define VK_DBE_NOCODEINPUT 0x0fb
-#define VK_DBE_DETERMINESTRING 0x0fc
-#define VK_DBE_ENTERDLGCONVERSIONMODE 0x0fd
-//@@BEGIN_DDKSPLIT
-#endif
-//@@END_DDKSPLIT
-
-#endif
-
-#endif // _KBD_
diff --git a/lulua/data/winkbd/keyboard.c b/lulua/data/winkbd/keyboard.c
deleted file mode 100644
index 3398bd7..0000000
--- a/lulua/data/winkbd/keyboard.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/***************************************************************************\
-* keyboard layout
-*
-* Copyright (c) 1985-2001, Microsoft Corporation
-*
-* History:
-* KBDTOOL v3.40 - Created Sat Jan 04 14:19:07 2020
-\***************************************************************************/
-
-#include "kbd.h"
-#include "keyboard.h"
-
-#if defined(_M_IA64)
-#pragma section(".data")
-#define ALLOC_SECTION_LDATA __declspec(allocate(".data"))
-#else
-#pragma data_seg(".data")
-#define ALLOC_SECTION_LDATA
-#endif
-
-/***************************************************************************\
-* ausVK[] - Virtual Scan Code to Virtual Key conversion table
-\***************************************************************************/
-
-static ALLOC_SECTION_LDATA USHORT ausVK[] = {
- 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,
-
- /*
- * Right-hand Shift key must have KBDEXT bit set.
- */
- T36 | KBDEXT,
-
- T37 | KBDMULTIVK, // numpad_* + Shift/Alt -> SnapShot
-
- T38, T39, T3A, T3B, T3C, T3D, T3E,
- T3F, T40, T41, T42, T43, T44,
-
- /*
- * NumLock Key:
- * KBDEXT - VK_NUMLOCK is an Extended key
- * KBDMULTIVK - VK_NUMLOCK or VK_PAUSE (without or with CTRL)
- */
- T45 | KBDEXT | KBDMULTIVK,
-
- T46 | KBDMULTIVK,
-
- /*
- * Number Pad keys:
- * KBDNUMPAD - digits 0-9 and decimal point.
- * KBDSPECIAL - require special processing by Windows
- */
- T47 | KBDNUMPAD | KBDSPECIAL, // Numpad 7 (Home)
- T48 | KBDNUMPAD | KBDSPECIAL, // Numpad 8 (Up),
- T49 | KBDNUMPAD | KBDSPECIAL, // Numpad 9 (PgUp),
- T4A,
- T4B | KBDNUMPAD | KBDSPECIAL, // Numpad 4 (Left),
- T4C | KBDNUMPAD | KBDSPECIAL, // Numpad 5 (Clear),
- T4D | KBDNUMPAD | KBDSPECIAL, // Numpad 6 (Right),
- T4E,
- T4F | KBDNUMPAD | KBDSPECIAL, // Numpad 1 (End),
- T50 | KBDNUMPAD | KBDSPECIAL, // Numpad 2 (Down),
- T51 | KBDNUMPAD | KBDSPECIAL, // Numpad 3 (PgDn),
- T52 | KBDNUMPAD | KBDSPECIAL, // Numpad 0 (Ins),
- T53 | KBDNUMPAD | KBDSPECIAL, // Numpad . (Del),
-
- 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 ALLOC_SECTION_LDATA VSC_VK aE0VscToVk[] = {
- { 0x10, X10 | KBDEXT }, // Speedracer: Previous Track
- { 0x19, X19 | KBDEXT }, // Speedracer: Next Track
- { 0x1D, X1D | KBDEXT }, // RControl
- { 0x20, X20 | KBDEXT }, // Speedracer: Volume Mute
- { 0x21, X21 | KBDEXT }, // Speedracer: Launch App 2
- { 0x22, X22 | KBDEXT }, // Speedracer: Media Play/Pause
- { 0x24, X24 | KBDEXT }, // Speedracer: Media Stop
- { 0x2E, X2E | KBDEXT }, // Speedracer: Volume Down
- { 0x30, X30 | KBDEXT }, // Speedracer: Volume Up
- { 0x32, X32 | KBDEXT }, // Speedracer: Browser Home
- { 0x35, X35 | KBDEXT }, // Numpad Divide
- { 0x37, X37 | KBDEXT }, // Snapshot
- { 0x38, X38 | KBDEXT }, // RMenu
- { 0x47, X47 | KBDEXT }, // Home
- { 0x48, X48 | KBDEXT }, // Up
- { 0x49, X49 | KBDEXT }, // Prior
- { 0x4B, X4B | KBDEXT }, // Left
- { 0x4D, X4D | KBDEXT }, // Right
- { 0x4F, X4F | KBDEXT }, // End
- { 0x50, X50 | KBDEXT }, // Down
- { 0x51, X51 | KBDEXT }, // Next
- { 0x52, X52 | KBDEXT }, // Insert
- { 0x53, X53 | KBDEXT }, // Delete
- { 0x5B, X5B | KBDEXT }, // Left Win
- { 0x5C, X5C | KBDEXT }, // Right Win
- { 0x5D, X5D | KBDEXT }, // Application
- { 0x5F, X5F | KBDEXT }, // Speedracer: Sleep
- { 0x65, X65 | KBDEXT }, // Speedracer: Browser Search
- { 0x66, X66 | KBDEXT }, // Speedracer: Browser Favorites
- { 0x67, X67 | KBDEXT }, // Speedracer: Browser Refresh
- { 0x68, X68 | KBDEXT }, // Speedracer: Browser Stop
- { 0x69, X69 | KBDEXT }, // Speedracer: Browser Forward
- { 0x6A, X6A | KBDEXT }, // Speedracer: Browser Back
- { 0x6B, X6B | KBDEXT }, // Speedracer: Launch App 1
- { 0x6C, X6C | KBDEXT }, // Speedracer: Launch Mail
- { 0x6D, X6D | KBDEXT }, // Speedracer: Launch Media Selector
- { 0x1C, X1C | KBDEXT }, // Numpad Enter
- { 0x46, X46 | KBDEXT }, // Break (Ctrl + Pause)
- { 0, 0 }
-};
-
-static ALLOC_SECTION_LDATA VSC_VK aE1VscToVk[] = {
- { 0x1D, Y1D }, // Pause
- { 0 , 0 }
-};
-
-/***************************************************************************\
-* aVkToBits[] - map Virtual Keys to Modifier Bits
-*
-* See kbd.h for a full description.
-*
-* The keyboard has only three shifter keys:
-* SHIFT (L & R) affects alphabnumeric keys,
-* CTRL (L & R) is used to generate control characters
-* ALT (L & R) used for generating characters by number with numpad
-\***************************************************************************/
-static ALLOC_SECTION_LDATA VK_TO_BIT aVkToBits[] = {
- MODIFIER_BITS
- {0, 0}
-};
-
-/***************************************************************************\
-* aModification[] - map character modifier bits to modification number
-*
-* See kbd.h for a full description.
-*
-\***************************************************************************/
-
-static ALLOC_SECTION_LDATA MODIFIERS CharModifiers = {
- &aVkToBits[0],
- CHAR_MODIFIERS_MASK,
- CHAR_MODIFIERS
-};
-
-/***************************************************************************\
-*
-* aVkToWch2[] - Virtual Key to WCHAR translation for 2 shift states
-* aVkToWch3[] - Virtual Key to WCHAR translation for 3 shift states
-* aVkToWch4[] - Virtual Key to WCHAR translation for 4 shift states
-* aVkToWch5[] - Virtual Key to WCHAR translation for 5 shift states
-* aVkToWch6[] - Virtual Key to WCHAR translation for 6 shift states
-*
-* Table attributes: Unordered Scan, null-terminated
-*
-* Search this table for an entry with a matching Virtual Key to find the
-* corresponding unshifted and shifted WCHAR characters.
-*
-* Special values for VirtualKey (column 1)
-* 0xff - dead chars for the previous entry
-* 0 - terminate the list
-*
-* Special values for Attributes (column 2)
-* CAPLOK bit - CAPS-LOCK affect this key like SHIFT
-*
-* Special values for wch[*] (column 3 & 4)
-* WCH_NONE - No character
-* WCH_DEAD - Dead Key (diaresis) or invalid (US keyboard has none)
-* WCH_LGTR - Ligature (generates multiple characters)
-*
-\***************************************************************************/
-
-static ALLOC_SECTION_LDATA VK_TO_WCHARS6 aVkToWch6[] = {
- VK_TO_WCH6
- {0,0,0,0,0,0,0,0}
- };
-
-// Put this last so that VkKeyScan interprets number characters
-// as coming from the main section of the kbd (aVkToWch2 and
-// aVkToWch5) before considering the numpad (aVkToWch1).
-
-static ALLOC_SECTION_LDATA VK_TO_WCHARS1 aVkToWch1[] = {
- { VK_NUMPAD0 , 0 , '0' },
- { VK_NUMPAD1 , 0 , '1' },
- { VK_NUMPAD2 , 0 , '2' },
- { VK_NUMPAD3 , 0 , '3' },
- { VK_NUMPAD4 , 0 , '4' },
- { VK_NUMPAD5 , 0 , '5' },
- { VK_NUMPAD6 , 0 , '6' },
- { VK_NUMPAD7 , 0 , '7' },
- { VK_NUMPAD8 , 0 , '8' },
- { VK_NUMPAD9 , 0 , '9' },
- { 0 , 0 , '\0' }
-};
-
-static ALLOC_SECTION_LDATA VK_TO_WCHAR_TABLE aVkToWcharTable[] = {
- { (PVK_TO_WCHARS1)aVkToWch6, 6, sizeof(aVkToWch6[0]) },
- { (PVK_TO_WCHARS1)aVkToWch1, 1, sizeof(aVkToWch1[0]) },
- { NULL, 0, 0 },
-};
-
-/***************************************************************************\
-* aKeyNames[], aKeyNamesExt[] - Virtual Scancode to Key Name tables
-*
-* Table attributes: Ordered Scan (by scancode), null-terminated
-*
-* Only the names of Extended, NumPad, Dead and Non-Printable keys are here.
-* (Keys producing printable characters are named by that character)
-\***************************************************************************/
-
-static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNames[] = {
- 0x01, L"Esc",
- 0x0e, L"Backspace",
- 0x0f, L"Tab",
- 0x1c, L"Enter",
- 0x1d, L"Ctrl",
- 0x2a, L"Shift",
- 0x36, L"Right Shift",
- 0x37, L"Num *",
- 0x38, L"Alt",
- 0x39, L"Space",
- 0x3a, L"Caps Lock",
- 0x3b, L"F1",
- 0x3c, L"F2",
- 0x3d, L"F3",
- 0x3e, L"F4",
- 0x3f, L"F5",
- 0x40, L"F6",
- 0x41, L"F7",
- 0x42, L"F8",
- 0x43, L"F9",
- 0x44, L"F10",
- 0x45, L"Pause",
- 0x46, L"Scroll Lock",
- 0x47, L"Num 7",
- 0x48, L"Num 8",
- 0x49, L"Num 9",
- 0x4a, L"Num -",
- 0x4b, L"Num 4",
- 0x4c, L"Num 5",
- 0x4d, L"Num 6",
- 0x4e, L"Num +",
- 0x4f, L"Num 1",
- 0x50, L"Num 2",
- 0x51, L"Num 3",
- 0x52, L"Num 0",
- 0x53, L"Num Del",
- 0x54, L"Sys Req",
- 0x57, L"F11",
- 0x58, L"F12",
- 0x7c, L"F13",
- 0x7d, L"F14",
- 0x7e, L"F15",
- 0x7f, L"F16",
- 0x80, L"F17",
- 0x81, L"F18",
- 0x82, L"F19",
- 0x83, L"F20",
- 0x84, L"F21",
- 0x85, L"F22",
- 0x86, L"F23",
- 0x87, L"F24",
- 0 , NULL
-};
-
-static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNamesExt[] = {
- 0x1c, L"Num Enter",
- 0x1d, L"Right Ctrl",
- 0x35, L"Num /",
- 0x37, L"Prnt Scrn",
- 0x38, L"Right Alt",
- 0x45, L"Num Lock",
- 0x46, L"Break",
- 0x47, L"Home",
- 0x48, L"Up",
- 0x49, L"Page Up",
- 0x4b, L"Left",
- 0x4d, L"Right",
- 0x4f, L"End",
- 0x50, L"Down",
- 0x51, L"Page Down",
- 0x52, L"Insert",
- 0x53, L"Delete",
- 0x54, L"<00>",
- 0x56, L"Help",
- 0x5b, L"Left Windows",
- 0x5c, L"Right Windows",
- 0x5d, L"Application",
- 0 , NULL
-};
-
-static ALLOC_SECTION_LDATA KBDTABLES KbdTables = {
- /*
- * Modifier keys
- */
- &CharModifiers,
-
- /*
- * Characters tables
- */
- aVkToWcharTable,
-
- /*
- * Diacritics
- */
- NULL,
-
- /*
- * Names of Keys
- */
- aKeyNames,
- aKeyNamesExt,
- NULL,
-
- /*
- * Scan codes to Virtual Keys
- */
- ausVK,
- sizeof(ausVK) / sizeof(ausVK[0]),
- aE0VscToVk,
- aE1VscToVk,
-
- /*
- * Locale-specific special processing
- */
- MAKELONG(0, KBD_VERSION),
-
- /*
- * Ligatures
- */
- 0,
- 0,
- NULL
-};
-
-PKBDTABLES KbdLayerDescriptor(VOID)
-{
- return &KbdTables;
-}
diff --git a/lulua/data/winkbd/keyboard.h b/lulua/data/winkbd/keyboard.h
deleted file mode 100644
index 0ef87d4..0000000
--- a/lulua/data/winkbd/keyboard.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/****************************** Module Header ******************************\
-* keyboard layout header
-*
-* Copyright (c) 1985-2001, Microsoft Corporation
-*
-* Various defines for use by keyboard input code.
-*
-* History:
-*
-* created by KBDTOOL v3.40 Sat Jan 04 14:19:07 2020
-*
-\***************************************************************************/
-
-/*
- * kbd type should be controlled by cl command-line argument
- */
-#define KBD_TYPE 4
-
-/*
-* Include the basis of all keyboard table values
-*/
-#include "kbd.h"
-/***************************************************************************\
-* The table below defines the virtual keys for various keyboard types where
-* the keyboard differ from the US keyboard.
-*
-* _EQ() : all keyboard types have the same virtual key for this scancode
-* _NE() : different virtual keys for this scancode, depending on kbd type
-*
-* +------+ +----------+----------+----------+----------+----------+----------+
-* | Scan | | kbd | kbd | kbd | kbd | kbd | kbd |
-* | code | | type 1 | type 2 | type 3 | type 4 | type 5 | type 6 |
-\****+-------+_+----------+----------+----------+----------+----------+----------+*/
-
-#include "customization.h"
-
diff --git a/lulua/keyboard.py b/lulua/keyboard.py
index 0a7e2e6..c9d3adb 100644
--- a/lulua/keyboard.py
+++ b/lulua/keyboard.py
@@ -157,72 +157,72 @@ _buttonToKeyman = {
'Fr_ctrl': 'RCTRL',
}
-# button to symbolic windows scancode usable in keyboard.c
-# see windows header kbd.h (#define TXX _EQ(YY))
+# button windows scancode. See Keyboard Scan Code Specification Revision 1.3a
+# (published in 2000) from the Windows Platform Design Notes for example.
_buttonToWinScancode = {
- 'Bl1': 'T29',
- 'Bl2': 'T02',
- 'Bl3': 'T03',
- 'Bl4': 'T04',
- 'Bl5': 'T05',
- 'Bl6': 'T06',
- 'Bl7': 'T07',
- 'Br6': 'T08',
- 'Br5': 'T09',
- 'Br4': 'T0A',
- 'Br3': 'T0B',
- 'Br2': 'T0C',
- 'Br1': 'T0D',
- 'Br_bs': 'T0E',
- 'Cl_tab': 'T0F',
- 'Cl1': 'T10',
- 'Cl2': 'T11',
- 'Cl3': 'T12',
- 'Cl4': 'T13',
- 'Cl5': 'T14',
- 'Cr7': 'T15',
- 'Cr6': 'T16',
- 'Cr5': 'T17',
- 'Cr4': 'T18',
- 'Cr3': 'T19',
- 'Cr2': 'T1A',
- 'Cr1': 'T1B',
- 'CD_ret': 'T1C',
- 'Dl_caps': 'T3A',
- 'Dl1': 'T1E',
- 'Dl2': 'T1F',
- 'Dl3': 'T20',
- 'Dl4': 'T21',
- 'Dl5': 'T22',
- 'Dr7': 'T23',
- 'Dr6': 'T24',
- 'Dr5': 'T25',
- 'Dr4': 'T26',
- 'Dr3': 'T27',
- 'Dr2': 'T28',
- 'Dr1': 'T2B',
- 'El_shift': 'T2A',
- 'El1': 'T56',
- 'El2': 'T2C',
- 'El3': 'T2D',
- 'El4': 'T2E',
- 'El5': 'T2F',
- 'El6': 'T30',
- 'Er5': 'T31',
- 'Er4': 'T32',
- 'Er3': 'T33',
- 'Er2': 'T34',
- 'Er1': 'T35',
- 'Er_shift': 'T36',
- 'Fl_ctrl': 'T1D',
- 'Fl_win': 'X5B',
- 'Fl_alt': 'T38',
- 'Fl_space': 'T39',
- 'Fr_space': 'T39',
- 'Fr_altgr': 'X38',
- 'Fr_win': 'X5C',
- 'Fr_menu': 'X5D',
- 'Fr_ctrl': 'X1D',
+ 'Bl1': (0x29, ),
+ 'Bl2': (0x02, ),
+ 'Bl3': (0x03, ),
+ 'Bl4': (0x04, ),
+ 'Bl5': (0x05, ),
+ 'Bl6': (0x06, ),
+ 'Bl7': (0x07, ),
+ 'Br6': (0x08, ),
+ 'Br5': (0x09, ),
+ 'Br4': (0x0A, ),
+ 'Br3': (0x0B, ),
+ 'Br2': (0x0C, ),
+ 'Br1': (0x0D, ),
+ 'Br_bs': (0x0E, ),
+ 'Cl_tab': (0x0F, ),
+ 'Cl1': (0x10, ),
+ 'Cl2': (0x11, ),
+ 'Cl3': (0x12, ),
+ 'Cl4': (0x13, ),
+ 'Cl5': (0x14, ),
+ 'Cr7': (0x15, ),
+ 'Cr6': (0x16, ),
+ 'Cr5': (0x17, ),
+ 'Cr4': (0x18, ),
+ 'Cr3': (0x19, ),
+ 'Cr2': (0x1A, ),
+ 'Cr1': (0x1B, ),
+ 'CD_ret': (0x1C, ),
+ 'Dl_caps': (0x3A, ),
+ 'Dl1': (0x1E, ),
+ 'Dl2': (0x1F, ),
+ 'Dl3': (0x20, ),
+ 'Dl4': (0x21, ),
+ 'Dl5': (0x22, ),
+ 'Dr7': (0x23, ),
+ 'Dr6': (0x24, ),
+ 'Dr5': (0x25, ),
+ 'Dr4': (0x26, ),
+ 'Dr3': (0x27, ),
+ 'Dr2': (0x28, ),
+ 'Dr1': (0x2B, ),
+ 'El_shift': (0x2A, ),
+ 'El1': (0x56, ),
+ 'El2': (0x2C, ),
+ 'El3': (0x2D, ),
+ 'El4': (0x2E, ),
+ 'El5': (0x2F, ),
+ 'El6': (0x30, ),
+ 'Er5': (0x31, ),
+ 'Er4': (0x32, ),
+ 'Er3': (0x33, ),
+ 'Er2': (0x34, ),
+ 'Er1': (0x35, ),
+ 'Er_shift': (0x36, ),
+ 'Fl_ctrl': (0x1D, ),
+ 'Fl_win': (0xe0, 0x5B, ),
+ 'Fl_alt': (0x38, ),
+ 'Fl_space': (0x39, ),
+ 'Fr_space': (0x39, ),
+ 'Fr_altgr': (0xe0, 0x38, ),
+ 'Fr_win': (0xe0, 0x5C, ),
+ 'Fr_menu': (0xe0, 0x5D, ),
+ 'Fr_ctrl': (0xe0, 0x1D, ),
}
class Button:
diff --git a/lulua/render.py b/lulua/render.py
index 78e2b17..b8514f0 100644
--- a/lulua/render.py
+++ b/lulua/render.py
@@ -32,6 +32,7 @@ from .layout import LITTLE, RING, MIDDLE, INDEX, THUMB, GenericLayout, defaultLa
from .writer import Writer
from .keyboard import defaultKeyboards, LetterButton
from .util import first, displayText
+from .winkbd import qwertyScancodeToVk, VirtualKey, WChar, makeDriverSources
RendererSettings = namedtuple ('RendererSetting', ['buttonMargin', 'middleGap', 'buttonWidth', 'rounded', 'shadowOffset', 'markerStroke'])
@@ -474,244 +475,38 @@ def renderWinKbd (args):
resPath = pkg_resources.resource_filename (__package__, 'data/winkbd')
with open (args.output, 'w') as fd:
- lines = []
- lines.append (f'/* This header was auto-generated by {__package__}. It is included by {resPath}/keyboard.h. Do not modify. */')
- lines.append ('')
-
- # copied from kbdneo2.c as well
- # XXX: modifier keys are fixed for now
- # maps virtual keys (first value) to shift bitfield value (second value)
- lines.append ('#define MODIFIER_BITS\\')
- lines.append (""" { VK_SHIFT , KBDSHIFT }, \\
- { VK_CONTROL , KBDCTRL }, \\
- { VK_MENU , KBDALT }, \\
- { VK_OEM_8 , KBDKANA }, \\
- { VK_OEM_102 , 16 },""")
-
- # copied from kbdneo2.c
- # maps a shift bitfield value (array index) to a layer number in
- # virtual key translation (VK_TO_WCHARS, array value)
- lines.append ('#define CHAR_MODIFIERS_MASK 24')
- lines.append ('#define CHAR_MODIFIERS\\')
- lines.append ('\t{ 0, 1, 6, 7, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, 3, 8, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, 2, 4, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, 5, }')
-
- # this is the standard layout from windows’ kbd.h (for KBD_TYPE == 4)
- scancodeToVk = {
- 'T01': 'ESCAPE',
- 'T02': '1',
- 'T03': '2',
- 'T04': '3',
- 'T05': '4',
- 'T06': '5',
- 'T07': '6',
- 'T08': '7',
- 'T09': '8',
- 'T0A': '9',
- 'T0B': '0',
- 'T0C': 'OEM_MINUS',
- 'T0D': 'OEM_PLUS',
- 'T0E': 'BACK',
- 'T0F': 'TAB',
- 'T10': 'Q',
- 'T11': 'W',
- 'T12': 'E',
- 'T13': 'R',
- 'T14': 'T',
- 'T15': 'Y',
- 'T16': 'U',
- 'T17': 'I',
- 'T18': 'O',
- 'T19': 'P',
- 'T1A': 'OEM_4',
- 'T1B': 'OEM_6',
- 'T1C': 'RETURN',
- 'T1D': 'LCONTROL',
- 'T1E': 'A',
- 'T1F': 'S',
- 'T20': 'D',
- 'T21': 'F',
- 'T22': 'G',
- 'T23': 'H',
- 'T24': 'J',
- 'T25': 'K',
- 'T26': 'L',
- 'T27': 'OEM_1',
- 'T28': 'OEM_7',
- 'T29': 'OEM_3',
- 'T2A': 'LSHIFT',
- 'T2B': 'OEM_5',
- 'T2C': 'Z',
- 'T2D': 'X',
- 'T2E': 'C',
- 'T2F': 'V',
- 'T30': 'B',
- 'T31': 'N',
- 'T32': 'M',
- 'T33': 'OEM_COMMA',
- 'T34': 'OEM_PERIOD',
- 'T35': 'OEM_2',
- 'T36': 'RSHIFT',
- 'T37': 'MULTIPLY',
- 'T38': 'LMENU',
- 'T39': 'SPACE',
- 'T3A': 'CAPITAL',
- 'T3B': 'F1',
- 'T3C': 'F2',
- 'T3D': 'F3',
- 'T3E': 'F4',
- 'T3F': 'F5',
- 'T40': 'F6',
- 'T41': 'F7',
- 'T42': 'F8',
- 'T43': 'F9',
- 'T44': 'F10',
- 'T45': 'NUMLOCK',
- 'T46': 'SCROLL',
- 'T47': 'HOME',
- 'T48': 'UP',
- 'T49': 'PRIOR',
- 'T4A': 'SUBTRACT',
- 'T4B': 'LEFT',
- 'T4C': 'CLEAR',
- 'T4D': 'RIGHT',
- 'T4E': 'ADD',
- 'T4F': 'END',
- 'T50': 'DOWN',
- 'T51': 'NEXT',
- 'T52': 'INSERT',
- 'T53': 'DELETE',
- 'T54': 'SNAPSHOT',
- 'T56': 'OEM_102',
- 'T57': 'F11',
- 'T58': 'F12',
- 'T59': 'CLEAR',
- 'T5A': 'OEM_WSCTRL',
- 'T5B': 'OEM_FINISH',
- 'T5C': 'OEM_JUMP',
- 'T5D': 'EREOF',
- 'T5E': 'OEM_BACKTAB',
- 'T5F': 'OEM_AUTO',
- 'T62': 'ZOOM',
- 'T63': 'HELP',
- 'T64': 'F13',
- 'T65': 'F14',
- 'T66': 'F15',
- 'T67': 'F16',
- 'T68': 'F17',
- 'T69': 'F18',
- 'T6A': 'F19',
- 'T6B': 'F20',
- 'T6C': 'F21',
- 'T6D': 'F22',
- 'T6E': 'F23',
- 'T6F': 'OEM_PA3',
- 'T71': 'OEM_RESET',
- 'T73': 'ABNT_C1',
- 'T76': 'F24',
- 'T7B': 'OEM_PA1',
- 'T7C': 'TAB',
- 'T7E': 'ABNT_C2',
- 'T7F': 'OEM_PA2',
-
- 'X10': 'MEDIA_PREV_TRACK',
- 'X19': 'MEDIA_NEXT_TRACK',
- 'X1C': 'RETURN',
- 'X1D': 'RCONTROL',
- 'X20': 'VOLUME_MUTE',
- 'X21': 'LAUNCH_APP2',
- 'X22': 'MEDIA_PLAY_PAUSE',
- 'X24': 'MEDIA_STOP',
- 'X2E': 'VOLUME_DOWN',
- 'X30': 'VOLUME_UP',
- 'X32': 'BROWSER_HOME',
- 'X35': 'DIVIDE',
- 'X37': 'SNAPSHOT',
- 'X38': 'RMENU',
- 'X46': 'CANCEL',
- 'X47': 'HOME',
- 'X48': 'UP',
- 'X49': 'PRIOR',
- 'X4B': 'LEFT',
- 'X4D': 'RIGHT',
- 'X4F': 'END',
- 'X50': 'DOWN',
- 'X51': 'NEXT',
- 'X52': 'INSERT',
- 'X53': 'DELETE',
- 'X5B': 'LWIN',
- 'X5C': 'RWIN',
- 'X5D': 'APPS',
- 'X5E': 'POWER',
- 'X5F': 'SLEEP',
- 'X65': 'BROWSER_SEARCH',
- 'X66': 'BROWSER_FAVORITES',
- 'X67': 'BROWSER_REFRESH',
- 'X68': 'BROWSER_STOP',
- 'X69': 'BROWSER_FORWARD',
- 'X6A': 'BROWSER_BACK',
- 'X6B': 'LAUNCH_APP1',
- 'X6C': 'LAUNCH_MAIL',
- 'X6D': 'LAUNCH_MEDIA_SELECT',
- }
- # modifications copied from kbdneo2.c
- # maps modifier keys to oem values used above.
+ fd.write (f'/* This header was auto-generated by {__package__}. Do not modify directly. */\n\n')
+
+ scancodeToVk = dict (qwertyScancodeToVk)
+ # Updates for 3rd and 4th layer modifier keys
scancodeToVk.update ({
# mod 3
- 'T2B': 'OEM_102',
- 'T3A': 'OEM_102',
+ (0x2B, ): (VirtualKey.OEM_102, ),
+ (0x3A, ): (VirtualKey.OEM_102, ),
# mod 4
- 'X38': 'OEM_8',
- 'T56': 'OEM_8',
+ (0x56, ): (VirtualKey.OEM_8, ),
+ (0xe0, 0x38): (VirtualKey.OEM_8, ),
})
- for k, v in scancodeToVk.items ():
- lines.append (f'#undef {k}')
- if len (v) == 1:
- # character value if not symbolic
- lines.append (f'#define {k} \'{v}\'')
- else:
- lines.append (f'#define {k} _EQ({v})')
- lines.append ('')
- lines.append ('#define VK_TO_WCH6 \\')
+ # translate keyboard buttons to text
+ def toWindows (s):
+ # convert to windows-convention
+ if s == '\n':
+ s = '\r'
+ return s
+ wcharMap = []
for btn in unique (keyboard.keys (), key=attrgetter ('windowsScancode')):
- def toUnicode (s):
- if s is None:
- return 'WCH_NONE'
- elif len (s) != 1:
- logging.error (f'only single-character strings are supported, ignoring {s}')
- return 'WCH_NONE'
- elif s == '\n':
- # convert to windows-convention
- s = '\r'
- return f'0x{ord (s):x} /*{repr (s)}*/'
-
text = list (layout.getButtonText (btn))
- assert len (text) < 7, "supporting six layers only right now"
# skip unused keys
- if sum (map (lambda x: 1 if x is not None else 0, text)) == 0:
+ if len (list (filter (lambda x: x is not None, text))) == 0:
continue
- # fixed-length array, need padding
- mappedText = [toUnicode (s) for s in text]
- while len (mappedText) < 6:
- mappedText.append ('WCH_NONE')
+ mappedText = [toWindows (s) for s in text]
+ vk = next (filter (lambda x: isinstance (x, VirtualKey), scancodeToVk[btn.windowsScancode]))
+ wcharMap.append ((vk, 0, mappedText))
- vk = scancodeToVk[btn.windowsScancode]
- if len (vk) == 1:
- # character value
- vk = f"'{vk}'"
- else:
- # symbolic value
- vk = f'VK_{vk}'
- mappingStr = ', '.join (mappedText)
- lines.append (f'\t{{ {vk}, 0, {mappingStr} }}, \\')
- # NUL-termination entry is already present in keyboard.c
- lines.append ('\n')
-
- fd.write ('\n'.join (lines))
- logging.info ('refer to README.rst on how to build a windows driver. '
- f'Template files are located in {resPath}')
+ fd.write (makeDriverSources (scancodeToVk, wcharMap))
def yamlload (s):
try:
diff --git a/lulua/winkbd.py b/lulua/winkbd.py
new file mode 100644
index 0000000..0f4dffc
--- /dev/null
+++ b/lulua/winkbd.py
@@ -0,0 +1,825 @@
+# Copyright (c) 2019 lulua contributors
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+"""
+Windows keyboard layout driver generation
+"""
+
+from enum import IntEnum
+from operator import attrgetter
+from itertools import groupby
+
+class CDefEnum (IntEnum):
+ @property
+ def cdefName (self):
+ return f'{self.__class__.__name__.upper()}_{self.name.upper()}'
+
+# Virtal key definitions, see
+# https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
+vkval = dict (
+ LBUTTON = 0x01,
+ RBUTTON = 0x02,
+ CANCEL = 0x03,
+ MBUTTON = 0x04,
+ XBUTTON1 = 0x05,
+ XBUTTON2 = 0x06,
+
+ BACK = 0x08,
+ TAB = 0x09,
+
+ CLEAR = 0x0C,
+ RETURN = 0x0D,
+
+ SHIFT = 0x10,
+ CONTROL = 0x11,
+ MENU = 0x12,
+ PAUSE = 0x13,
+ CAPITAL = 0x14,
+
+ KANA = 0x15,
+ HANGEUL = 0x15,
+ HANGUL = 0x15,
+ JUNJA = 0x17,
+ FINAL = 0x18,
+ HANJA = 0x19,
+ KANJI = 0x19,
+
+ ESCAPE = 0x1B,
+
+ CONVERT = 0x1C,
+ NONCONVERT = 0x1D,
+ ACCEPT = 0x1E,
+ MODECHANGE = 0x1F,
+
+ SPACE = 0x20,
+ PRIOR = 0x21,
+ NEXT = 0x22,
+ END = 0x23,
+ HOME = 0x24,
+ LEFT = 0x25,
+ UP = 0x26,
+ RIGHT = 0x27,
+ DOWN = 0x28,
+ SELECT = 0x29,
+ PRINT = 0x2A,
+ EXECUTE = 0x2B,
+ SNAPSHOT = 0x2C,
+ INSERT = 0x2D,
+ DELETE = 0x2E,
+ HELP = 0x2F,
+
+ LWIN = 0x5B,
+ RWIN = 0x5C,
+ APPS = 0x5D,
+
+ SLEEP = 0x5F,
+
+ NUMPAD0 = 0x60,
+ NUMPAD1 = 0x61,
+ NUMPAD2 = 0x62,
+ NUMPAD3 = 0x63,
+ NUMPAD4 = 0x64,
+ NUMPAD5 = 0x65,
+ NUMPAD6 = 0x66,
+ NUMPAD7 = 0x67,
+ NUMPAD8 = 0x68,
+ NUMPAD9 = 0x69,
+ MULTIPLY = 0x6A,
+ ADD = 0x6B,
+ SEPARATOR = 0x6C,
+ SUBTRACT = 0x6D,
+ DECIMAL = 0x6E,
+ DIVIDE = 0x6F,
+ F1 = 0x70,
+ F2 = 0x71,
+ F3 = 0x72,
+ F4 = 0x73,
+ F5 = 0x74,
+ F6 = 0x75,
+ F7 = 0x76,
+ F8 = 0x77,
+ F9 = 0x78,
+ F10 = 0x79,
+ F11 = 0x7A,
+ F12 = 0x7B,
+ F13 = 0x7C,
+ F14 = 0x7D,
+ F15 = 0x7E,
+ F16 = 0x7F,
+ F17 = 0x80,
+ F18 = 0x81,
+ F19 = 0x82,
+ F20 = 0x83,
+ F21 = 0x84,
+ F22 = 0x85,
+ F23 = 0x86,
+ F24 = 0x87,
+
+ NUMLOCK = 0x90,
+ SCROLL = 0x91,
+
+ OEM_NEC_EQUAL = 0x92,
+
+ OEM_FJ_JISHO = 0x92,
+ OEM_FJ_MASSHOU = 0x93,
+ OEM_FJ_TOUROKU = 0x94,
+ OEM_FJ_LOYA = 0x95,
+ OEM_FJ_ROYA = 0x96,
+
+ LSHIFT = 0xA0,
+ RSHIFT = 0xA1,
+ LCONTROL = 0xA2,
+ RCONTROL = 0xA3,
+ LMENU = 0xA4,
+ RMENU = 0xA5,
+
+ BROWSER_BACK = 0xA6,
+ BROWSER_FORWARD = 0xA7,
+ BROWSER_REFRESH = 0xA8,
+ BROWSER_STOP = 0xA9,
+ BROWSER_SEARCH = 0xAA,
+ BROWSER_FAVORITES = 0xAB,
+ BROWSER_HOME = 0xAC,
+
+ VOLUME_MUTE = 0xAD,
+ VOLUME_DOWN = 0xAE,
+ VOLUME_UP = 0xAF,
+ MEDIA_NEXT_TRACK = 0xB0,
+ MEDIA_PREV_TRACK = 0xB1,
+ MEDIA_STOP = 0xB2,
+ MEDIA_PLAY_PAUSE = 0xB3,
+ LAUNCH_MAIL = 0xB4,
+ LAUNCH_MEDIA_SELECT = 0xB5,
+ LAUNCH_APP1 = 0xB6,
+ LAUNCH_APP2 = 0xB7,
+
+ OEM_1 = 0xBA,
+ OEM_PLUS = 0xBB,
+ OEM_COMMA = 0xBC,
+ OEM_MINUS = 0xBD,
+ OEM_PERIOD = 0xBE,
+ OEM_2 = 0xBF,
+ OEM_3 = 0xC0,
+
+ ABNT_C1 = 0xC1,
+ ABNT_C2 = 0xC2,
+
+ OEM_4 = 0xDB,
+ OEM_5 = 0xDC,
+ OEM_6 = 0xDD,
+ OEM_7 = 0xDE,
+ OEM_8 = 0xDF,
+
+ OEM_AX = 0xE1,
+ OEM_102 = 0xE2,
+ ICO_HELP = 0xE3,
+ ICO_00 = 0xE4,
+
+ PROCESSKEY = 0xE5,
+
+ ICO_CLEAR = 0xE6,
+
+ PACKET = 0xE7,
+
+ OEM_RESET = 0xE9,
+ OEM_JUMP = 0xEA,
+ OEM_PA1 = 0xEB,
+ OEM_PA2 = 0xEC,
+ OEM_PA3 = 0xED,
+ OEM_WSCTRL = 0xEE,
+ OEM_CUSEL = 0xEF,
+ OEM_ATTN = 0xF0,
+ OEM_FINISH = 0xF1,
+ OEM_COPY = 0xF2,
+ OEM_AUTO = 0xF3,
+ OEM_ENLW = 0xF4,
+ OEM_BACKTAB = 0xF5,
+
+ ATTN = 0xF6,
+ CRSEL = 0xF7,
+ EXSEL = 0xF8,
+ EREOF = 0xF9,
+ PLAY = 0xFA,
+ ZOOM = 0xFB,
+ NONAME = 0xFC,
+ PA1 = 0xFD,
+ OEM_CLEAR = 0xFE,
+
+ # invalid
+ NULL = 0xFF,
+ )
+
+# Add ASCII numbers and letters
+for i in range (ord ('0'), ord ('9')+1):
+ vkval[f'NUMBER{chr (i)}'] = i
+for i in range (ord ('A'), ord ('Z')+1):
+ vkval[chr (i)] = i
+
+VirtualKey = CDefEnum ('VirtualKey', vkval)
+
+class VirtualKeyFlag (CDefEnum):
+ # The Windows API returns EXT as KEYEVENTF_EXTENDEDKEY, see
+ # https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-keybdinput
+ EXT = 0x0100
+ MULTIVK = 0x0200
+ SPECIAL = 0x0400
+ NUMPAD = 0x0800
+ UNICODE = 0x1000
+ INJECTEDVK = 0x2000
+ MAPPEDVK = 0x4000
+ BREAK = 0x8000
+
+class WChar (CDefEnum):
+ """ Wide character symbols """
+ NONE = 0xF000 # unused slot
+
+# Default scancode to VirtualKey translation for qwerty
+qwertyScancodeToVk = {
+ (0x01, ): (VirtualKey.ESCAPE, ),
+ (0x02, ): (VirtualKey.NUMBER1, ),
+ (0x03, ): (VirtualKey.NUMBER2, ),
+ (0x04, ): (VirtualKey.NUMBER3, ),
+ (0x05, ): (VirtualKey.NUMBER4, ),
+ (0x06, ): (VirtualKey.NUMBER5, ),
+ (0x07, ): (VirtualKey.NUMBER6, ),
+ (0x08, ): (VirtualKey.NUMBER7, ),
+ (0x09, ): (VirtualKey.NUMBER8, ),
+ (0x0A, ): (VirtualKey.NUMBER9, ),
+ (0x0B, ): (VirtualKey.NUMBER0, ),
+ (0x0C, ): (VirtualKey.OEM_MINUS, ),
+ (0x0D, ): (VirtualKey.OEM_PLUS, ),
+ (0x0E, ): (VirtualKey.BACK, ),
+ (0x0F, ): (VirtualKey.TAB, ),
+ (0x10, ): (VirtualKey.Q, ),
+ (0x11, ): (VirtualKey.W, ),
+ (0x12, ): (VirtualKey.E, ),
+ (0x13, ): (VirtualKey.R, ),
+ (0x14, ): (VirtualKey.T, ),
+ (0x15, ): (VirtualKey.Y, ),
+ (0x16, ): (VirtualKey.U, ),
+ (0x17, ): (VirtualKey.I, ),
+ (0x18, ): (VirtualKey.O, ),
+ (0x19, ): (VirtualKey.P, ),
+ (0x1A, ): (VirtualKey.OEM_4, ),
+ (0x1B, ): (VirtualKey.OEM_6, ),
+ (0x1C, ): (VirtualKey.RETURN, ),
+ (0x1D, ): (VirtualKey.LCONTROL, ),
+ (0x1E, ): (VirtualKey.A, ),
+ (0x1F, ): (VirtualKey.S, ),
+ (0x20, ): (VirtualKey.D, ),
+ (0x21, ): (VirtualKey.F, ),
+ (0x22, ): (VirtualKey.G, ),
+ (0x23, ): (VirtualKey.H, ),
+ (0x24, ): (VirtualKey.J, ),
+ (0x25, ): (VirtualKey.K, ),
+ (0x26, ): (VirtualKey.L, ),
+ (0x27, ): (VirtualKey.OEM_1, ),
+ (0x28, ): (VirtualKey.OEM_7, ),
+ (0x29, ): (VirtualKey.OEM_3, ),
+ (0x2A, ): (VirtualKey.LSHIFT, ),
+ (0x2B, ): (VirtualKey.OEM_5, ),
+ (0x2C, ): (VirtualKey.Z, ),
+ (0x2D, ): (VirtualKey.X, ),
+ (0x2E, ): (VirtualKey.C, ),
+ (0x2F, ): (VirtualKey.V, ),
+ (0x30, ): (VirtualKey.B, ),
+ (0x31, ): (VirtualKey.N, ),
+ (0x32, ): (VirtualKey.M, ),
+ (0x33, ): (VirtualKey.OEM_COMMA, ),
+ (0x34, ): (VirtualKey.OEM_PERIOD, ),
+ (0x35, ): (VirtualKey.OEM_2, ),
+ (0x36, ): (VirtualKey.RSHIFT, VirtualKeyFlag.EXT), # Right-hand shift needs ext bit (XXX why?)
+ (0x37, ): (VirtualKey.MULTIPLY, VirtualKeyFlag.MULTIVK),
+ (0x38, ): (VirtualKey.LMENU, ),
+ (0x39, ): (VirtualKey.SPACE, ),
+ (0x3A, ): (VirtualKey.CAPITAL, ),
+ (0x3B, ): (VirtualKey.F1, ),
+ (0x3C, ): (VirtualKey.F2, ),
+ (0x3D, ): (VirtualKey.F3, ),
+ (0x3E, ): (VirtualKey.F4, ),
+ (0x3F, ): (VirtualKey.F5, ),
+ (0x40, ): (VirtualKey.F6, ),
+ (0x41, ): (VirtualKey.F7, ),
+ (0x42, ): (VirtualKey.F8, ),
+ (0x43, ): (VirtualKey.F9, ),
+ (0x44, ): (VirtualKey.F10, ),
+ (0x45, ): (VirtualKey.NUMLOCK, VirtualKeyFlag.EXT, VirtualKeyFlag.MULTIVK),
+ (0x46, ): (VirtualKey.SCROLL, VirtualKeyFlag.MULTIVK),
+ (0x47, ): (VirtualKey.HOME, VirtualKeyFlag.NUMPAD, VirtualKeyFlag.SPECIAL),
+ (0x48, ): (VirtualKey.UP, VirtualKeyFlag.NUMPAD, VirtualKeyFlag.SPECIAL),
+ (0x49, ): (VirtualKey.PRIOR, VirtualKeyFlag.NUMPAD, VirtualKeyFlag.SPECIAL),
+ (0x4A, ): (VirtualKey.SUBTRACT, ),
+ (0x4B, ): (VirtualKey.LEFT, VirtualKeyFlag.NUMPAD, VirtualKeyFlag.SPECIAL),
+ (0x4C, ): (VirtualKey.CLEAR, VirtualKeyFlag.NUMPAD, VirtualKeyFlag.SPECIAL),
+ (0x4D, ): (VirtualKey.RIGHT, VirtualKeyFlag.NUMPAD, VirtualKeyFlag.SPECIAL),
+ (0x4E, ): (VirtualKey.ADD, ),
+ (0x4F, ): (VirtualKey.END, VirtualKeyFlag.NUMPAD, VirtualKeyFlag.SPECIAL),
+ (0x50, ): (VirtualKey.DOWN, VirtualKeyFlag.NUMPAD, VirtualKeyFlag.SPECIAL),
+ (0x51, ): (VirtualKey.NEXT, VirtualKeyFlag.NUMPAD, VirtualKeyFlag.SPECIAL),
+ (0x52, ): (VirtualKey.INSERT, VirtualKeyFlag.NUMPAD, VirtualKeyFlag.SPECIAL),
+ (0x53, ): (VirtualKey.DELETE, VirtualKeyFlag.NUMPAD, VirtualKeyFlag.SPECIAL),
+ (0x54, ): (VirtualKey.SNAPSHOT, ),
+ (0x56, ): (VirtualKey.OEM_102, ),
+ (0x57, ): (VirtualKey.F11, ),
+ (0x58, ): (VirtualKey.F12, ),
+ (0x59, ): (VirtualKey.CLEAR, ),
+ (0x5A, ): (VirtualKey.OEM_WSCTRL, ),
+ (0x5B, ): (VirtualKey.OEM_FINISH, ),
+ (0x5C, ): (VirtualKey.OEM_JUMP, ),
+ (0x5D, ): (VirtualKey.EREOF, ),
+ (0x5E, ): (VirtualKey.OEM_BACKTAB, ),
+ (0x5F, ): (VirtualKey.OEM_AUTO, ),
+ (0x62, ): (VirtualKey.ZOOM, ),
+ (0x63, ): (VirtualKey.HELP, ),
+ (0x64, ): (VirtualKey.F13, ),
+ (0x65, ): (VirtualKey.F14, ),
+ (0x66, ): (VirtualKey.F15, ),
+ (0x67, ): (VirtualKey.F16, ),
+ (0x68, ): (VirtualKey.F17, ),
+ (0x69, ): (VirtualKey.F18, ),
+ (0x6A, ): (VirtualKey.F19, ),
+ (0x6B, ): (VirtualKey.F20, ),
+ (0x6C, ): (VirtualKey.F21, ),
+ (0x6D, ): (VirtualKey.F22, ),
+ (0x6E, ): (VirtualKey.F23, ),
+ (0x6F, ): (VirtualKey.OEM_PA3, ),
+ (0x71, ): (VirtualKey.OEM_RESET, ),
+ (0x73, ): (VirtualKey.ABNT_C1, ),
+ (0x76, ): (VirtualKey.F24, ),
+ (0x7B, ): (VirtualKey.OEM_PA1, ),
+ (0x7C, ): (VirtualKey.TAB, ),
+ (0x7E, ): (VirtualKey.ABNT_C2, ),
+ (0x7F, ): (VirtualKey.OEM_PA2, ),
+
+ # Prefixed codes: E0
+ (0xe0, 0x10): (VirtualKey.MEDIA_PREV_TRACK, VirtualKeyFlag.EXT),
+ (0xe0, 0x19): (VirtualKey.MEDIA_NEXT_TRACK, VirtualKeyFlag.EXT),
+ (0xe0, 0x1C): (VirtualKey.RETURN, VirtualKeyFlag.EXT),
+ (0xe0, 0x1D): (VirtualKey.RCONTROL, VirtualKeyFlag.EXT),
+ (0xe0, 0x20): (VirtualKey.VOLUME_MUTE, VirtualKeyFlag.EXT),
+ (0xe0, 0x21): (VirtualKey.LAUNCH_APP2, VirtualKeyFlag.EXT),
+ (0xe0, 0x22): (VirtualKey.MEDIA_PLAY_PAUSE, VirtualKeyFlag.EXT),
+ (0xe0, 0x24): (VirtualKey.MEDIA_STOP, VirtualKeyFlag.EXT),
+ (0xe0, 0x2E): (VirtualKey.VOLUME_DOWN, VirtualKeyFlag.EXT),
+ (0xe0, 0x30): (VirtualKey.VOLUME_UP, VirtualKeyFlag.EXT),
+ (0xe0, 0x32): (VirtualKey.BROWSER_HOME, VirtualKeyFlag.EXT),
+ (0xe0, 0x35): (VirtualKey.DIVIDE, VirtualKeyFlag.EXT),
+ (0xe0, 0x37): (VirtualKey.SNAPSHOT, VirtualKeyFlag.EXT),
+ (0xe0, 0x38): (VirtualKey.RMENU, VirtualKeyFlag.EXT),
+ (0xe0, 0x46): (VirtualKey.CANCEL, VirtualKeyFlag.EXT),
+ (0xe0, 0x47): (VirtualKey.HOME, VirtualKeyFlag.EXT),
+ (0xe0, 0x48): (VirtualKey.UP, VirtualKeyFlag.EXT),
+ (0xe0, 0x49): (VirtualKey.PRIOR, VirtualKeyFlag.EXT),
+ (0xe0, 0x4B): (VirtualKey.LEFT, VirtualKeyFlag.EXT),
+ (0xe0, 0x4D): (VirtualKey.RIGHT, VirtualKeyFlag.EXT),
+ (0xe0, 0x4F): (VirtualKey.END, VirtualKeyFlag.EXT),
+ (0xe0, 0x50): (VirtualKey.DOWN, VirtualKeyFlag.EXT),
+ (0xe0, 0x51): (VirtualKey.NEXT, VirtualKeyFlag.EXT),
+ (0xe0, 0x52): (VirtualKey.INSERT, VirtualKeyFlag.EXT),
+ (0xe0, 0x53): (VirtualKey.DELETE, VirtualKeyFlag.EXT),
+ (0xe0, 0x5B): (VirtualKey.LWIN, VirtualKeyFlag.EXT),
+ (0xe0, 0x5C): (VirtualKey.RWIN, VirtualKeyFlag.EXT),
+ (0xe0, 0x5D): (VirtualKey.APPS, VirtualKeyFlag.EXT),
+ # XXX what is VK_POWER’s value?
+ #(0xe0, 0x5E): (VirtualKey.POWER, VirtualKeyFlag.EXT),
+ (0xe0, 0x5F): (VirtualKey.SLEEP, VirtualKeyFlag.EXT),
+ (0xe0, 0x65): (VirtualKey.BROWSER_SEARCH, VirtualKeyFlag.EXT),
+ (0xe0, 0x66): (VirtualKey.BROWSER_FAVORITES, VirtualKeyFlag.EXT),
+ (0xe0, 0x67): (VirtualKey.BROWSER_REFRESH, VirtualKeyFlag.EXT),
+ (0xe0, 0x68): (VirtualKey.BROWSER_STOP, VirtualKeyFlag.EXT),
+ (0xe0, 0x69): (VirtualKey.BROWSER_FORWARD, VirtualKeyFlag.EXT),
+ (0xe0, 0x6A): (VirtualKey.BROWSER_BACK, VirtualKeyFlag.EXT),
+ (0xe0, 0x6B): (VirtualKey.LAUNCH_APP1, VirtualKeyFlag.EXT),
+ (0xe0, 0x6C): (VirtualKey.LAUNCH_MAIL, VirtualKeyFlag.EXT),
+ (0xe0, 0x6D): (VirtualKey.LAUNCH_MEDIA_SELECT, VirtualKeyFlag.EXT),
+
+ # Prefixed codes: E1
+ (0xe1, 0x1d): (VirtualKey.PAUSE, ),
+ }
+
+def enumToCDefine (e):
+ """
+ Transform Python Enum into a bunch of #define statements
+ """
+ prefix = e.__name__.upper ()
+ ret = [f'/* {e.__name__} */']
+ for name, member in e.__members__.items ():
+ ret.append (f'#define {member.cdefName} (0x{member:X}u)')
+ ret.append ('')
+ return '\n'.join (ret)
+
+def enumOr (v):
+ """
+ Turn list of enum values v into C OR statement
+ """
+ return ' | '.join (map (attrgetter ('cdefName'), v))
+
+def scancodeToVkTables (m):
+ """
+ Transform scancode to virtual key map m into C arrays
+ """
+ # non-prefixed scancodes
+ ret = ['/* mappings from scancode to virtual key */',
+ '/* non-prefixed scancodes */',
+ 'static unsigned short ausVK[] = {']
+ for i in range (0, 0x7f+1):
+ v = m.get ((i, ), (VirtualKey.NULL, ))
+ ret.append (f'\t /* {i:02X} */ {enumOr (v)},')
+ ret.append ('\t};\n')
+
+ # now E0 and E1, must be sorted
+ for escape in (0xe0, 0xe1):
+ ret.extend ([f'/* scancodes prefixed by {escape:X} */', f'static VSC_VK a{escape:X}VscToVk[] = {{'])
+ f = lambda x: len (x[0]) == 2 and x[0][0] == escape
+ for k, v in sorted (filter (f, m.items ()), key=lambda x: x[0]):
+ ret.append (f'\t{{ 0x{k[1]:x}, {enumOr (v)} }},')
+ ret.append ('\t};\n')
+
+ return '\n'.join (ret)
+
+qwertyScancodeToName = {
+ (0x01, ): "Esc",
+ (0x0e, ): "Backspace",
+ (0x0f, ): "Tab",
+ (0x1c, ): "Enter",
+ (0x1d, ): "Ctrl",
+ (0x2a, ): "Shift",
+ (0x36, ): "Right Shift",
+ (0x37, ): "Num *",
+ (0x38, ): "Alt",
+ (0x39, ): "Space",
+ (0x3a, ): "Caps Lock",
+ (0x3b, ): "F1",
+ (0x3c, ): "F2",
+ (0x3d, ): "F3",
+ (0x3e, ): "F4",
+ (0x3f, ): "F5",
+ (0x40, ): "F6",
+ (0x41, ): "F7",
+ (0x42, ): "F8",
+ (0x43, ): "F9",
+ (0x44, ): "F10",
+ (0x45, ): "Pause",
+ (0x46, ): "Scroll Lock",
+ (0x47, ): "Num 7",
+ (0x48, ): "Num 8",
+ (0x49, ): "Num 9",
+ (0x4a, ): "Num -",
+ (0x4b, ): "Num 4",
+ (0x4c, ): "Num 5",
+ (0x4d, ): "Num 6",
+ (0x4e, ): "Num +",
+ (0x4f, ): "Num 1",
+ (0x50, ): "Num 2",
+ (0x51, ): "Num 3",
+ (0x52, ): "Num 0",
+ (0x53, ): "Num Del",
+ (0x54, ): "Sys Req",
+ (0x57, ): "F11",
+ (0x58, ): "F12",
+ (0x7c, ): "F13",
+ (0x7d, ): "F14",
+ (0x7e, ): "F15",
+ (0x7f, ): "F16",
+ (0x80, ): "F17",
+ (0x81, ): "F18",
+ (0x82, ): "F19",
+ (0x83, ): "F20",
+ (0x84, ): "F21",
+ (0x85, ): "F22",
+ (0x86, ): "F23",
+ (0x87, ): "F24",
+
+ # With E0 prefix
+ (0xe0, 0x1c): "Num Enter",
+ (0xe0, 0x1d): "Right Ctrl",
+ (0xe0, 0x35): "Num /",
+ (0xe0, 0x37): "Prnt Scrn",
+ (0xe0, 0x38): "Right Alt",
+ (0xe0, 0x45): "Num Lock",
+ (0xe0, 0x46): "Break",
+ (0xe0, 0x47): "Home",
+ (0xe0, 0x48): "Up",
+ (0xe0, 0x49): "Page Up",
+ (0xe0, 0x4b): "Left",
+ (0xe0, 0x4d): "Right",
+ (0xe0, 0x4f): "End",
+ (0xe0, 0x50): "Down",
+ (0xe0, 0x51): "Page Down",
+ (0xe0, 0x52): "Insert",
+ (0xe0, 0x53): "Delete",
+ (0xe0, 0x54): "<00>",
+ (0xe0, 0x56): "Help",
+ (0xe0, 0x5b): "Left Windows",
+ (0xe0, 0x5c): "Right Windows",
+ (0xe0, 0x5d): "Application",
+ }
+
+def scancodeToName (m):
+ """ Create virtual scancode to name mapping tables """
+
+ ret = []
+
+ # first unprefixed keys
+ ret.extend (['/* Virtual scancode to key name */',
+ 'static VSC_LPWSTR aKeyNames[] = {'])
+ f = lambda x: len (x[0]) == 1
+ for k, v in sorted (filter (f, m.items ()), key=lambda x: x[0]):
+ ret.append (f'\t{{0x{k[0]:02x}, L"{v}"}},')
+ ret.extend (['\t{0x00, NULL},', '};', ''])
+
+ ret.extend (['/* Virtual scan code (E0 prefixed) to key name */',
+ 'static VSC_LPWSTR aKeyNamesExt[] = {'])
+ f = lambda x: len (x[0]) == 2 and x[0][0] == 0xe0
+ for k, v in sorted (filter (f, m.items ()), key=lambda x: x[0]):
+ ret.append (f'\t{{0x{k[1]:02x}, L"{v}"}},')
+ ret.extend (['\t{0x00, NULL},', '};', ''])
+
+ return '\n'.join (ret)
+
+vkToBitsTable = [
+ (VirtualKey.SHIFT, (1<<0)),
+ (VirtualKey.CONTROL, (1<<1)),
+ (VirtualKey.MENU, (1<<2)),
+ (VirtualKey.OEM_8, (1<<3)),
+ (VirtualKey.OEM_102, (1<<4)),
+ ]
+
+def vkToBits ():
+ ret = ['/* maps virtual keys (first value) to shift bitfield value (second value) */',
+ 'static VK_TO_BIT aVkToBits[] = {']
+ for vk, bits in vkToBitsTable:
+ ret.append (f'\t{{{vk.cdefName}, 0x{bits:x}}},')
+ ret.append ('\t{0, 0x0}')
+ ret.append ('\t};\n')
+ return '\n'.join (ret)
+
+def charModifiers ():
+ # array index is layer number
+ vkToLayer = list (map (set, [
+ tuple (), # base
+ (VirtualKey.SHIFT, ),
+ (VirtualKey.OEM_102, ),
+ (VirtualKey.OEM_8, ),
+ (VirtualKey.SHIFT, VirtualKey.OEM_102),
+ (VirtualKey.OEM_8, VirtualKey.OEM_102),
+ (VirtualKey.CONTROL, ),
+ (VirtualKey.SHIFT, VirtualKey.CONTROL),
+ (VirtualKey.SHIFT, VirtualKey.OEM_8),
+ ]))
+ disabled = 0x0F
+
+ ret = ['/* maps a shift bitfield value (array index) to a layer number in',
+ 'virtual key translation (VK_TO_WCHARS, array value) */',
+ 'static MODIFIERS CharModifiers = {',
+ '\t&aVkToBits[0],',
+ '\t24,',
+ ]
+ ret.append ('\t{')
+ for i in range (25):
+ keys = set (map (lambda x: x[0], filter (lambda x: i & x[1], vkToBitsTable)))
+ try:
+ layer = vkToLayer.index (keys)
+ except ValueError:
+ layer = disabled
+ keysComment = enumOr (keys) if not layer == disabled else "disabled"
+ ret.append (f'\t\t0x{layer:x}, /* {keysComment} */')
+ ret.append ('\t}};\n')
+ return '\n'.join (ret)
+
+def vkToWchar (m):
+ """ Mapping from virtual key to character """
+
+ ret = []
+ retTbl = ['/* table of virtual key to wchar mapping tables */',
+ 'static VK_TO_WCHAR_TABLE aVkToWcharTable[] = {']
+
+ def generate (n, g, defPrefix=''):
+ defname = f'aVkToWch{defPrefix}{n}'
+ ret.extend ([f'/* map virtual key to flags and {n} unicode output characters */',
+ f'static VK_TO_WCHARS{n} {defname}[] = {{'])
+ for vk, flags, chars in g:
+ def toRepr (s):
+ if s is None:
+ return WChar.NONE.cdefName
+ elif len (s) != 1:
+ # everything else belongs to ligature tables, which we
+ # don’t support.
+ raise Exception (f'only single-character strings are supported ({s!r})')
+ else:
+ return f'0x{ord (s):04X}u /*{repr (s)}*/'
+ chars = ', '.join (map (toRepr, chars))
+ ret.append (f'\t{{{vk.cdefName}, {flags}, {{{chars}}}}},')
+ ret.extend ([f'\t{{0, 0, {{{("0, "*n)}}}}},', '\t};', ''])
+ # add the new table
+ retTbl.append (f'\t{{(PVK_TO_WCHARS1) {defname}, {n}, sizeof({defname}[0])}},')
+
+ f = lambda x: len (x[2])
+ m = groupby (sorted (m, key=f), key=f)
+ for n, g in m:
+ generate (n, g)
+
+ # We are almost always going to need the numpad keys. They also need to be
+ # last, so translation from string to virtual key does not map them.
+ numpad = [
+ (VirtualKey.NUMPAD0, 0, '0'),
+ (VirtualKey.NUMPAD1, 0, '1'),
+ (VirtualKey.NUMPAD2, 0, '2'),
+ (VirtualKey.NUMPAD3, 0, '3'),
+ (VirtualKey.NUMPAD4, 0, '4'),
+ (VirtualKey.NUMPAD5, 0, '5'),
+ (VirtualKey.NUMPAD6, 0, '6'),
+ (VirtualKey.NUMPAD7, 0, '7'),
+ (VirtualKey.NUMPAD8, 0, '8'),
+ (VirtualKey.NUMPAD9, 0, '9'),
+ ]
+ generate (1, numpad, 'Num')
+
+ retTbl.extend (['\t{NULL, 0, 0},', '\t};'])
+ return '\n'.join (ret + retTbl)
+
+typedefs = """
+#include <wchar.h>
+
+typedef struct {
+ unsigned char Vk;
+ unsigned char ModBits;
+} VK_TO_BIT, *PVK_TO_BIT;
+
+typedef struct {
+ PVK_TO_BIT pVkToBit;
+ unsigned short wMaxModBits;
+ unsigned char ModNumber[];
+} MODIFIERS, *PMODIFIERS;
+
+typedef struct _VSC_VK {
+ unsigned char Vsc;
+ unsigned short Vk;
+} VSC_VK, *PVSC_VK;
+"""
+
+for n in range (1, 9):
+ typedefs += f"""
+typedef struct _VK_TO_WCHARS{n} {{
+ unsigned char VirtualKey;
+ unsigned char Attributes;
+ wchar_t wch[{n}];
+}} VK_TO_WCHARS{n}, *PVK_TO_WCHARS{n};
+"""
+
+for n in (1, ):
+ typedefs += f"""
+typedef struct _LIGATURE{n} {{
+ unsigned char VirtualKey;
+ unsigned short ModificationNumber;
+ wchar_t wch[{n}];
+}} LIGATURE{n}, *PLIGATURE{n};
+"""
+
+typedefs += """
+typedef struct _VK_TO_WCHAR_TABLE {
+ PVK_TO_WCHARS1 pVkToWchars;
+ unsigned char nModifications;
+ unsigned char cbSize;
+} VK_TO_WCHAR_TABLE, *PVK_TO_WCHAR_TABLE;
+
+typedef struct {
+ unsigned long dwBoth;
+ wchar_t wchComposed;
+ unsigned short uFlags;
+} DEADKEY, *PDEADKEY;
+
+typedef struct {
+ unsigned char vsc;
+ wchar_t *pwsz;
+} VSC_LPWSTR, *PVSC_LPWSTR;
+
+typedef struct tagKbdLayer {
+ /*
+ * Modifier keys
+ */
+ PMODIFIERS pCharModifiers;
+
+ /*
+ * Characters
+ */
+ PVK_TO_WCHAR_TABLE pVkToWcharTable; // ptr to tbl of ptrs to tbl
+
+ /*
+ * Diacritics
+ */
+ PDEADKEY pDeadKey;
+
+ /*
+ * Names of Keys
+ */
+ PVSC_LPWSTR pKeyNames;
+ PVSC_LPWSTR pKeyNamesExt;
+ wchar_t **pKeyNamesDead;
+
+ /*
+ * Scan codes to Virtual Keys
+ */
+ unsigned short *pusVSCtoVK;
+ unsigned char bMaxVSCtoVK;
+ PVSC_VK pVSCtoVK_E0; // Scancode has E0 prefix
+ PVSC_VK pVSCtoVK_E1; // Scancode has E1 prefix
+
+ /*
+ * Locale-specific special processing
+ */
+ unsigned long fLocaleFlags;
+
+ /*
+ * Ligatures
+ */
+ unsigned char nLgMax;
+ unsigned char cbLgEntry;
+ PLIGATURE1 pLigature;
+
+ /*
+ * Type and subtype. These are optional.
+ */
+ unsigned long dwType; // Keyboard Type
+ unsigned long dwSubType; // Keyboard SubType: may contain OemId
+} KBDTABLES, *PKBDTABLES;
+"""
+
+entrypoint = """
+#define KBD_VERSION (1)
+
+static KBDTABLES KbdTables = {
+ pCharModifiers: &CharModifiers,
+
+ pVkToWcharTable: aVkToWcharTable,
+
+ pDeadKey: NULL,
+
+ pKeyNames: aKeyNames,
+ pKeyNamesExt: aKeyNamesExt,
+ pKeyNamesDead: NULL,
+
+ pusVSCtoVK: ausVK,
+ bMaxVSCtoVK: sizeof(ausVK) / sizeof(*ausVK),
+ pVSCtoVK_E0: aE0VscToVk,
+ pVSCtoVK_E1: aE1VscToVk,
+
+ fLocaleFlags: (0 & 0xffffUL) | ((KBD_VERSION & 0xffffUL) << 16),
+
+ nLgMax: 0,
+ cbLgEntry: 0,
+ pLigature: NULL,
+
+ dwType: 0,
+ dwSubType: 0,
+};
+
+/* The main entry point of the driver
+ */
+PKBDTABLES KbdLayerDescriptor() {
+ return &KbdTables;
+}
+"""
+
+def makeDriverSources (scancodes, charmap):
+ """
+ Create a single file keyboard driver.
+
+ scancodes is a mapping like qwertyScancodeToVk from virtual scancode to
+ virtual key. charmap is a list of triples (virtual key, flags, [list of
+ strings]).
+ """
+
+ ret = [
+ typedefs,
+ enumToCDefine (VirtualKey),
+ enumToCDefine (VirtualKeyFlag),
+ enumToCDefine (WChar),
+ scancodeToVkTables (scancodes),
+ scancodeToName (qwertyScancodeToName),
+ vkToBits (),
+ charModifiers (),
+ vkToWchar (charmap),
+ entrypoint
+ ]
+ return '\n'.join (ret)
+
+__all__ = ('VirtualKey', 'VirtualKeyFlag')
+