From 1b6e5b491ae717eb096a7d4a68df9f772de577ae Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Sun, 13 Sep 2020 12:47:51 +0200 Subject: winkbd: Make Windows driver compileable with MingGW Automate the process via GitHub Actions as well. kbd.h can be simplified. Fixes #11. --- .github/workflows/ci.yml | 4 +- README.rst | 25 +- gen.sh | 18 +- lulua/data/winkbd/build.ninja | 32 + lulua/data/winkbd/kbd.h | 2478 +++++++++++++++++++++++++++++++++++++++++ lulua/data/winkbd/keyboard.c | 1 - lulua/data/winkbd/keyboard.rc | 8 +- lulua/data/winkbd/linker.ld | 36 + lulua/data/winkbd/make.bat | 22 - lulua/render.py | 5 +- 10 files changed, 2571 insertions(+), 58 deletions(-) create mode 100644 lulua/data/winkbd/build.ninja create mode 100644 lulua/data/winkbd/kbd.h create mode 100644 lulua/data/winkbd/linker.ld delete mode 100755 lulua/data/winkbd/make.bat diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8886753..eb34f05 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | - sudo apt install ninja-build libxml2-dev libxslt1-dev + sudo apt install ninja-build libxml2-dev libxslt1-dev mingw-w64 pip install . pip install flake8 pytest pytest-cov - name: Lint with flake8 @@ -37,7 +37,7 @@ jobs: # Due to the lack of corpora, we can’t run the entire thing here. run: | ./gen.sh > build.ninja - ninja _build/report/ar-lulua.svg _build/report/ar-lulua.xmodmap + ninja _build/report/ar-lulua.svg _build/report/ar-lulua.xmodmap _build/report/ar-lulua-w64.zip - name: Upload results uses: actions/upload-artifact@v2 with: diff --git a/README.rst b/README.rst index 6ed53eb..7234524 100644 --- a/README.rst +++ b/README.rst @@ -51,9 +51,10 @@ issues. Also the following software is required: - Python/`PyPy 3`_ - Ninja_ (for the build process) -- GNU autotools and a C compiler (for ``3rdparty/osmctools``) +- GNU autotools and a host C compiler (for ``3rdparty/osmctools``) - GNU bash and zip (for ``makezip.sh``) - librsvg (``rsvg-convert`` is used to create PDF’s from SVG images) +- MinGW (to compile the Windows keyboard driver) .. _Ninja: https://ninja-build.org/ @@ -68,28 +69,6 @@ to run the analysis and create pretty pictures as well as statistics in .. _me: lars+lulua@6xq.net -Building Windows drivers ------------------------- - -There is no easy way to build Windows keyboard drivers, but the following -instructions have worked in the past: - -.. code:: bash - - ninja _build/_temp/winkbd/customization.h - -Share the folder `doc/_temp/winkbd` with a Windows system, install `Microsoft -Keyboard Layout Creator 1.4`_ (MSKLC; the Windows Driver Kit (WDK) would work -too, but is much larger), adjust ``make.bat`` pointing to your MSKLC -installation and run it. This should generate two directories, ``System32`` and -``SysWOW64``, which must be copied back to `_build/_temp/winkbd`. Then run: - -.. code:: bash - - ninja _build/report/ar-lulua-w64.zip - -.. _Microsoft Keyboard Layout Creator 1.4: https://www.microsoft.com/en-us/download/details.aspx?id=22339 - Acknowledgements ---------------- diff --git a/gen.sh b/gen.sh index 490a198..5f4878d 100755 --- a/gen.sh +++ b/gen.sh @@ -108,9 +108,6 @@ rule report rule cp command = cp \$in \$out -rule cpR - command = cp -R \$in \$out - rule gz command = gzip -c \$in > \$out @@ -123,6 +120,9 @@ rule zipR rule render-winkbd command = lulua-render -l ar-lulua winkbd \$out +rule ninjaC + command = ninja -C \$dir + ### build targets ### build \$reportdir: mkdir build \$reportdir/fonts: mkdir @@ -142,9 +142,19 @@ build \$reportdir/fonts/IBMPlexSansArabic-Thin.woff2: cp \$fontdir/IBMPlexSansAr build \$osmconvert: configure-make 3rdparty/osmctools # windows drivers -build \$tempdir/winkbd: cpR lulua/data/winkbd +build \$tempdir/winkbd: mkdir lulua/data/winkbd +EOF +# Create dependencies for the non-customized files +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" +cat < + +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 +* 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 +* 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 - Associate a Virtual Key with 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 index dcc89c3..3398bd7 100644 --- a/lulua/data/winkbd/keyboard.c +++ b/lulua/data/winkbd/keyboard.c @@ -7,7 +7,6 @@ * KBDTOOL v3.40 - Created Sat Jan 04 14:19:07 2020 \***************************************************************************/ -#include #include "kbd.h" #include "keyboard.h" diff --git a/lulua/data/winkbd/keyboard.rc b/lulua/data/winkbd/keyboard.rc index ca9ef38..891861f 100644 --- a/lulua/data/winkbd/keyboard.rc +++ b/lulua/data/winkbd/keyboard.rc @@ -1,7 +1,7 @@ #include "winver.h" 1 VERSIONINFO - FILEVERSION 1,0,0,04 - PRODUCTVERSION 1,0,0,04 + FILEVERSION 1,0,0,05 + PRODUCTVERSION 1,0,0,05 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -14,12 +14,12 @@ BEGIN BEGIN VALUE "CompanyName", "6xq.net\0" VALUE "FileDescription", "Ergonomic Arabic Keyboard Layout lulua\0" - VALUE "FileVersion", "0.4\0" + VALUE "FileVersion", "0.5\0" VALUE "InternalName", "kbdarlulua\0" VALUE "ProductName","lulua\0" VALUE "LegalCopyright", "see https://opensource.org/licenses/MIT\0" VALUE "OriginalFilename","kbdarlulua\0" - VALUE "ProductVersion", "0.4\0" + VALUE "ProductVersion", "0.5\0" END END BLOCK "VarFileInfo" diff --git a/lulua/data/winkbd/linker.ld b/lulua/data/winkbd/linker.ld new file mode 100644 index 0000000..e7d9669 --- /dev/null +++ b/lulua/data/winkbd/linker.ld @@ -0,0 +1,36 @@ +/* taken from https://github.com/reactos/reactos/blob/893a3c9d030fd8b078cbd747eeefd3f6ce57e560/dll/keyboard/kbdlayout.lds */ +SECTIONS +{ + .data __image_base__ + __section_alignment__ : + { + *(.data) + *(SORT(.data*)) + *(.rdata) + *(SORT(.rdata*)) + *(.text) + *(SORT(.text*)) + *(.bss) + *(COMMON) + } + + .rsrc BLOCK(__section_alignment__) : + { + *(.rsrc) + *(SORT(.rsrc*)) + } + + .reloc BLOCK(__section_alignment__) : + { + *(.reloc) + } + + .edata BLOCK(__section_alignment__) : + { + *(.edata) + } + + /DISCARD/ : + { + *(*) + } +} diff --git a/lulua/data/winkbd/make.bat b/lulua/data/winkbd/make.bat deleted file mode 100755 index 4c66cc0..0000000 --- a/lulua/data/winkbd/make.bat +++ /dev/null @@ -1,22 +0,0 @@ -REM taken from https://levicki.net/articles/2006/09/29/HOWTO_Build_keyboard_layouts_for_Windows_x64.php - -SET OUTNAME=kbdarlulua -SET MSKLC="C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4" - -mkdir System32 - -%MSKLC%\bin\i386\rc.exe -r -i%MSKLC%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST=0 -DWIN32=100 -D_NT1X_=100 -DWINNT=1 -D_WIN32_WINNT=0x0502 /DWINVER=0x0502 -D_WIN32_IE=0x0600 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 409 -Fokeyboard.res keyboard.rc || exit /b - -REM build 64 bit -%MSKLC%\bin\i386\amd64\cl.exe -nologo -I%MSKLC%\inc -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0502 /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Zl /Oxs -Fokeyboard64.obj keyboard.c || exit /b - -REM XXX: why use the 32 bit linker here? the one in amd64\ does not work -%MSKLC%\bin\i386\link.exe -nologo -base:0x5FFE0000 -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -MACHINE:AMD64 -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:4039,4078 -noentry -dll -subsystem:native,5.2 -merge:.rdata=.text -PDBPATH:NONE -STACK:0x40000,0x1000 /opt:nowin98 -debugtype:cv,fixup -debug -osversion:5.2 -version:5.2 /release -def:keyboard.def -out:system32\%OUTNAME%.dll keyboard.res keyboard64.obj || exit /b - -REM and now 32 bit -mkdir SysWOW64 - -%MSKLC%\bin\i386\cl.exe -nologo -I%MSKLC%\inc -DBUILD_WOW6432 -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0502 /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Zl /Oxs -Fokeyboard32.obj keyboard.c || exit /b - -%MSKLC%\bin\i386\link.exe -nologo -base:0x5FFF0000 -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -MACHINE:IX86 -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:4039,4078 -noentry -dll -subsystem:native,5.2 -merge:.rdata=.text -PDBPATH:NONE -STACK:0x40000,0x1000 /opt:nowin98 -debugtype:cv,fixup -debug -osversion:5.2 -version:5.2 /release -def:keyboard.def -out:SysWOW64\%OUTNAME%.dll keyboard.res keyboard32.obj || exit /b - diff --git a/lulua/render.py b/lulua/render.py index e195c99..78e2b17 100644 --- a/lulua/render.py +++ b/lulua/render.py @@ -667,8 +667,9 @@ def renderWinKbd (args): lines.append (f'#undef {k}') if len (v) == 1: # character value if not symbolic - v = f"'{v}'" - lines.append (f'#define {k} _EQ({v})') + lines.append (f'#define {k} \'{v}\'') + else: + lines.append (f'#define {k} _EQ({v})') lines.append ('') lines.append ('#define VK_TO_WCH6 \\') -- cgit v1.2.3