From 3d4aff5d628a7dac28087aa2849ff02253e883ac Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 6 Nov 2018 20:24:43 +1100 Subject: [PATCH] [Common] Continue refactoring, add support for supplying context from command line --- .../src/kmx/kmxtest/.gitignore | 3 + .../src/kmx/kmxtest/inc/aiWin2000Unicode.h | 1 + .../src/kmx/kmxtest/inc/appint.h | 1 + .../src/kmx/kmxtest/inc/keyman64.h | 1 - .../src/kmx/kmxtest/inc/rc4.h | 17 -- .../src/kmx/kmxtest/kmxtest.vcxproj | 10 +- .../src/kmx/kmxtest/kmxtest.vcxproj.filters | 6 - .../kmxtest/src/appint/aiWin2000Unicode.cpp | 30 ++- .../src/kmx/kmxtest/src/capsstate.cpp | 39 +--- .../src/kmx/kmxtest/src/common/rc4.cpp | 196 ------------------ .../src/kmx/kmxtest/src/kmxtest.cpp | 95 +++++++-- .../src/kmx/kmxtest/test.bat | 4 + 12 files changed, 119 insertions(+), 284 deletions(-) create mode 100644 common/engine/keyboardprocessor/src/kmx/kmxtest/.gitignore delete mode 100644 common/engine/keyboardprocessor/src/kmx/kmxtest/inc/rc4.h delete mode 100644 common/engine/keyboardprocessor/src/kmx/kmxtest/src/common/rc4.cpp create mode 100644 common/engine/keyboardprocessor/src/kmx/kmxtest/test.bat diff --git a/common/engine/keyboardprocessor/src/kmx/kmxtest/.gitignore b/common/engine/keyboardprocessor/src/kmx/kmxtest/.gitignore new file mode 100644 index 0000000000..f549f096ad --- /dev/null +++ b/common/engine/keyboardprocessor/src/kmx/kmxtest/.gitignore @@ -0,0 +1,3 @@ +.vs/ +Debug/ +x64/ diff --git a/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/aiWin2000Unicode.h b/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/aiWin2000Unicode.h index 4cc39c66f6..d7ab49702f 100644 --- a/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/aiWin2000Unicode.h +++ b/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/aiWin2000Unicode.h @@ -52,6 +52,7 @@ public: virtual void AddContext(WCHAR ch); //I2436 virtual WCHAR *ContextBuf(int n); virtual WCHAR *ContextBufMax(int n); + void SetContext(PWCHAR ctxt); /* Queue and sending functions */ diff --git a/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/appint.h b/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/appint.h index e9f383a30e..ba590d9116 100644 --- a/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/appint.h +++ b/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/appint.h @@ -40,6 +40,7 @@ typedef struct #define QIT_DEADKEY 5 #define QIT_BELL 6 #define QIT_BACK 7 +#define QIT_CAPSLOCK 8 // QueueDebugInformation ItemTypes #define QID_BEGIN_UNICODE 0 diff --git a/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/keyman64.h b/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/keyman64.h index 49b5c48dc6..ca990e1cfd 100644 --- a/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/keyman64.h +++ b/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/keyman64.h @@ -305,7 +305,6 @@ PWSTR GetSystemStore(LPKEYBOARD kb, DWORD SystemID); #ifndef _KEYMAN64_LIGHT #include "syskbd.h" #include "vkscancodes.h" -#include "rc4.h" #include "crc32.h" diff --git a/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/rc4.h b/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/rc4.h deleted file mode 100644 index 095ed859e2..0000000000 --- a/common/engine/keyboardprocessor/src/kmx/kmxtest/inc/rc4.h +++ /dev/null @@ -1,17 +0,0 @@ - - -class CryptRC4 -{ -private: - BOOL fInitialized; - BYTE KeyData[256], KeyOrg[256]; - void EncryptBuffer(PBYTE InData, PBYTE OutData, DWORD Size); - void DecryptBuffer(PBYTE InData, PBYTE OutData, DWORD Size); -public: - static BOOL SelfTest(); - void Init(PBYTE Key, DWORD Size, PVOID InitVector); - void Burn(); - void Reset(); - void Encrypt(PBYTE InData, PBYTE OutData, DWORD Size); - void Decrypt(PBYTE InData, PBYTE OutData, DWORD Size); -}; diff --git a/common/engine/keyboardprocessor/src/kmx/kmxtest/kmxtest.vcxproj b/common/engine/keyboardprocessor/src/kmx/kmxtest/kmxtest.vcxproj index ae4a97bc58..fcb1e087fa 100644 --- a/common/engine/keyboardprocessor/src/kmx/kmxtest/kmxtest.vcxproj +++ b/common/engine/keyboardprocessor/src/kmx/kmxtest/kmxtest.vcxproj @@ -75,7 +75,7 @@ Level3 ProgramDatabase Disabled - C:\Projects\keyman\kmxtest\inc;%(AdditionalIncludeDirectories) + $(ProjectDir)inc;%(AdditionalIncludeDirectories) Use pch.h @@ -91,7 +91,7 @@ MultiThreadedDLL Level3 ProgramDatabase - C:\Projects\keyman\kmxtest\inc;%(AdditionalIncludeDirectories) + $(ProjectDir)inc;%(AdditionalIncludeDirectories) Use pch.h @@ -105,14 +105,14 @@ - C:\Projects\keyman\kmxtest\inc;%(AdditionalIncludeDirectories) + $(ProjectDir)inc;%(AdditionalIncludeDirectories) Use pch.h - C:\Projects\keyman\kmxtest\inc;%(AdditionalIncludeDirectories) + $(ProjectDir)inc;%(AdditionalIncludeDirectories) Use pch.h @@ -121,7 +121,6 @@ - @@ -164,7 +163,6 @@ - diff --git a/common/engine/keyboardprocessor/src/kmx/kmxtest/kmxtest.vcxproj.filters b/common/engine/keyboardprocessor/src/kmx/kmxtest/kmxtest.vcxproj.filters index 0ab8acc046..bfc667b544 100644 --- a/common/engine/keyboardprocessor/src/kmx/kmxtest/kmxtest.vcxproj.filters +++ b/common/engine/keyboardprocessor/src/kmx/kmxtest/kmxtest.vcxproj.filters @@ -57,9 +57,6 @@ Source Files - - Source Files - Source Files @@ -125,9 +122,6 @@ Header Files - - Header Files - Header Files diff --git a/common/engine/keyboardprocessor/src/kmx/kmxtest/src/appint/aiWin2000Unicode.cpp b/common/engine/keyboardprocessor/src/kmx/kmxtest/src/appint/aiWin2000Unicode.cpp index 041e4c2149..c12f7a28bf 100644 --- a/common/engine/keyboardprocessor/src/kmx/kmxtest/src/appint/aiWin2000Unicode.cpp +++ b/common/engine/keyboardprocessor/src/kmx/kmxtest/src/appint/aiWin2000Unicode.cpp @@ -57,6 +57,10 @@ AIWin2000Unicode::~AIWin2000Unicode() void AIWin2000Unicode::ReadContext() { } + +void AIWin2000Unicode::SetContext(WCHAR *ctxt) { + context->Set(ctxt); +} void AIWin2000Unicode::AddContext(WCHAR ch) //I2436 { @@ -143,14 +147,22 @@ BOOL AIWin2000Unicode::PostKeys() for(; n < QueueSize; n++) { switch(Queue[n].ItemType) { - case QIT_VKEYDOWN: + case QIT_CAPSLOCK: + if (Queue[n].dwData == 0) { + wprintf(L"CAPSLOCK off\n"); + } + else { + wprintf(L"CAPSLOCK on\n"); + } + break; + case QIT_VKEYDOWN: if((Queue[n].dwData & QVK_KEYMASK) == 0x05) Queue[n].dwData = (Queue[n].dwData & QVK_FLAGMASK) | VK_RETURN; // I649 // I3438 /* 6.0.153.0: Fix repeat state for virtual keys */ if((Queue[n].dwData & QVK_KEYMASK) <= VK__MAX) // I3438 { - printf("KEYDOWN: %x (flags=%x)\n", Queue[n].dwData & 0xFF, (Queue[n].dwData & QVK_FLAGMASK) >> 16); + wprintf(L"KEYDOWN: %x (flags=%x)\n", Queue[n].dwData & 0xFF, (Queue[n].dwData & QVK_FLAGMASK) >> 16); } break; @@ -159,27 +171,27 @@ BOOL AIWin2000Unicode::PostKeys() if((Queue[n].dwData & QVK_KEYMASK) <= VK__MAX) // I3438 { - printf("KEYUP: %x (flags=%x)\n", Queue[n].dwData & 0xFF, (Queue[n].dwData & QVK_FLAGMASK) >> 16); + wprintf(L"KEYUP: %x (flags=%x)\n", Queue[n].dwData & 0xFF, (Queue[n].dwData & QVK_FLAGMASK) >> 16); } break; case QIT_VSHIFTDOWN: - printf("VSHIFTDOWN\n"); + wprintf(L"VSHIFTDOWN\n"); break; case QIT_VSHIFTUP: - printf("VSHIFTUP\n"); + wprintf(L"VSHIFTUP\n"); break; case QIT_CHAR: - wprintf(L"CHAR %x (%lc)\n", Queue[n].dwData, Queue[n].dwData); + wprintf(L"CHAR %x (%c)\n", Queue[n].dwData, Queue[n].dwData); break; case QIT_DEADKEY: - printf("DEADKEY\n"); + wprintf(L"DEADKEY\n"); break; case QIT_BELL: - printf("BELL\n"); + wprintf(L"BELL\n"); break; case QIT_BACK: - printf("BKSP (%x)\n", Queue[n].dwData); + wprintf(L"BKSP (%x)\n", Queue[n].dwData); if(Queue[n].dwData == BK_DEADKEY) break; if(Queue[n].dwData == BK_SUPP2) break; // I1389 - supp chars on vista default to single backspace //TODO: eliminate BK_SUPP2 break; diff --git a/common/engine/keyboardprocessor/src/kmx/kmxtest/src/capsstate.cpp b/common/engine/keyboardprocessor/src/kmx/kmxtest/src/capsstate.cpp index e4d6c75a1e..6a35ac8402 100644 --- a/common/engine/keyboardprocessor/src/kmx/kmxtest/src/capsstate.cpp +++ b/common/engine/keyboardprocessor/src/kmx/kmxtest/src/capsstate.cpp @@ -26,29 +26,17 @@ */ #include "pch.h" -static BYTE kbstate[256]; -extern BOOL FShouldIgnoreNextKey[256]; - -//extern "C" void FAR PASCAL keybd_event(void); - - void ResetCapsLock(void) { - PKEYMAN64THREADDATA _td = ThreadGlobals(); - if(!_td) return; - - if(!_td->lpActiveKeyboard) return; - SendDebugMessageFormat(0, sdmGlobal, 0, "ResetCapsLock: enter"); - if(_td->lpActiveKeyboard->Keyboard->dwFlags & KF_CAPSALWAYSOFF) + if(g_keyboard.Keyboard->dwFlags & KF_CAPSALWAYSOFF) { SendDebugMessageFormat(0, sdmGlobal, 0, "ResetCapsLock: caps lock should be always off"); if(GetKeyState(VK_CAPITAL) & 1) { SendDebugMessageFormat(0, sdmGlobal, 0, "ResetCapsLock: caps lock is on, switching off caps lock"); - keybd_event(VK_CAPITAL, 0x3A, 0, 0); - keybd_event(VK_CAPITAL, 0x3A, 0 | KEYEVENTF_KEYUP, 0); + GetApp()->QueueAction(QIT_CAPSLOCK, 0); } } SendDebugMessageFormat(0, sdmGlobal, 0, "ResetCapsLock: exit"); @@ -57,24 +45,18 @@ void ResetCapsLock(void) void KeyCapsLockPress(BOOL FIsUp) // I3284 - void // I3529 { - PKEYMAN64THREADDATA _td = ThreadGlobals(); - if(!_td) return; - if(!_td->lpActiveKeyboard) return; // pass through to window - - if(_td->lpActiveKeyboard->Keyboard->dwFlags & KF_CAPSONONLY) + if(g_keyboard.Keyboard->dwFlags & KF_CAPSONONLY) { if(FIsUp && !(GetKeyState(VK_CAPITAL) & 1)) // I267 - 24/11/2006 invert GetKeyState test { - keybd_event(VK_CAPITAL, SCAN_FLAG_KEYMAN_KEY_EVENT, 0, 0); - keybd_event(VK_CAPITAL, SCAN_FLAG_KEYMAN_KEY_EVENT, KEYEVENTF_KEYUP, 0); + GetApp()->QueueAction(QIT_CAPSLOCK, 1); } } - else if(_td->lpActiveKeyboard->Keyboard->dwFlags & KF_CAPSALWAYSOFF) + else if(g_keyboard.Keyboard->dwFlags & KF_CAPSALWAYSOFF) { if(!FIsUp && (GetKeyState(VK_CAPITAL) & 1)) { // I267 - 24/11/2006 invert GetKeyState test - keybd_event(VK_CAPITAL, SCAN_FLAG_KEYMAN_KEY_EVENT, KEYEVENTF_KEYUP, 0); - keybd_event(VK_CAPITAL, SCAN_FLAG_KEYMAN_KEY_EVENT, 0, 0); + GetApp()->QueueAction(QIT_CAPSLOCK, 0); } } } @@ -82,18 +64,13 @@ void KeyCapsLockPress(BOOL FIsUp) // I3284 - void // I3529 void KeyShiftPress(BOOL FIsUp) // I3284 - void // I3529 { - PKEYMAN64THREADDATA _td = ThreadGlobals(); - if(!_td) return; - if(!_td->lpActiveKeyboard) return; // pass through to window - if((GetKeyState(VK_CAPITAL) & 1) == 0) return; - if(_td->lpActiveKeyboard->Keyboard->dwFlags & KF_SHIFTFREESCAPS) + if(g_keyboard.Keyboard->dwFlags & KF_SHIFTFREESCAPS) { if(!FIsUp) { - keybd_event(VK_CAPITAL, SCAN_FLAG_KEYMAN_KEY_EVENT, 0, 0); - keybd_event(VK_CAPITAL, SCAN_FLAG_KEYMAN_KEY_EVENT, KEYEVENTF_KEYUP, 0); + GetApp()->QueueAction(QIT_CAPSLOCK, 0); } } } diff --git a/common/engine/keyboardprocessor/src/kmx/kmxtest/src/common/rc4.cpp b/common/engine/keyboardprocessor/src/kmx/kmxtest/src/common/rc4.cpp deleted file mode 100644 index dc455745cc..0000000000 --- a/common/engine/keyboardprocessor/src/kmx/kmxtest/src/common/rc4.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* - Name: rc4 - Copyright: Copyright (C) SIL International. - Documentation: - Description: - Create Date: 30 Nov 2009 - - Modified Date: 11 Dec 2009 - Authors: mcdurdin - Related Files: - Dependencies: - - Bugs: - Todo: - Notes: - History: 30 Nov 2009 - mcdurdin - I934 - Prep for x64 - Unreferenced parameters - 11 Dec 2009 - mcdurdin - I934 - x64 - Initial version -*/ - -#include "pch.h" - -BOOL CryptRC4::SelfTest() -{ - const BYTE Key1[5] = {0x61,0x8A,0x63,0xD2,0xFB}; - const BYTE InData1[5] = {0xDC,0xEE,0x4C,0xF9,0x2C}; - const BYTE OutData1[5] = {0xF1,0x38,0x29,0xC9,0xDE}; - - CryptRC4 rc4; - BYTE Data[5]; - - rc4.Init((PBYTE)Key1, sizeof(Key1)*8, NULL); - rc4.Encrypt((PBYTE)InData1,Data,sizeof(Data)); - if(memcmp(Data, OutData1, sizeof(Data)) != 0) return FALSE; - rc4.Reset(); - rc4.Decrypt(Data,Data,sizeof(Data)); - if(memcmp(Data, InData1, sizeof(Data)) != 0) return FALSE; - rc4.Burn(); - return TRUE; -} - -void CryptRC4::Init(PBYTE Key, DWORD Size, PVOID InitVector) -{ - UNREFERENCED_PARAMETER(InitVector); - DWORD i, j, t; - BYTE xKey[256]; - - if(fInitialized) Burn(); - - //inherited Init(Key,Size,nil); - Size /= 8; - i = 0; - - while(i < 255) - { - KeyData[i] = (BYTE) i; xKey[i] = Key[i % Size]; - KeyData[i+1] = (BYTE) i+1; xKey[i+1] = Key[(i+1) % Size]; - KeyData[i+2] = (BYTE) i+2; xKey[i+2] = Key[(i+2) % Size]; - KeyData[i+3] = (BYTE) i+3; xKey[i+3] = Key[(i+3) % Size]; - KeyData[i+4] = (BYTE) i+4; xKey[i+4] = Key[(i+4) % Size]; - KeyData[i+5] = (BYTE) i+5; xKey[i+5] = Key[(i+5) % Size]; - KeyData[i+6] = (BYTE) i+6; xKey[i+6] = Key[(i+6) % Size]; - KeyData[i+7] = (BYTE) i+7; xKey[i+7] = Key[(i+7) % Size]; - i += 8; - } - - j = 0; - i = 0; - - while(i < 255) - { - j = (j+KeyData[i]+xKey[i]) & 0xFF; - t = KeyData[i]; - KeyData[i] = KeyData[j]; - KeyData[j] = (BYTE) t; - j = (j+KeyData[i+1]+xKey[i+1]) & 0xFF; - t = KeyData[i+1]; - KeyData[i+1] = KeyData[j]; - KeyData[j] = (BYTE) t; - j = (j+KeyData[i+2]+xKey[i+2]) & 0xFF; - t = KeyData[i+2]; - KeyData[i+2] = KeyData[j]; - KeyData[j] = (BYTE) t; - j = (j+KeyData[i+3]+xKey[i+3]) & 0xFF; - t = KeyData[i+3]; - KeyData[i+3] = KeyData[j]; - KeyData[j] = (BYTE) t; - j = (j+KeyData[i+4]+xKey[i+4]) & 0xFF; - t = KeyData[i+4]; - KeyData[i+4] = KeyData[j]; - KeyData[j] = (BYTE) t; - j = (j+KeyData[i+5]+xKey[i+5]) & 0xFF; - t = KeyData[i+5]; - KeyData[i+5] = KeyData[j]; - KeyData[j] = (BYTE) t; - j = (j+KeyData[i+6]+xKey[i+6]) & 0xFF; - t = KeyData[i+6]; - KeyData[i+6] = KeyData[j]; - KeyData[j] = (BYTE) t; - j = (j+KeyData[i+7]+xKey[i+7]) & 0xFF; - t = KeyData[i+7]; - KeyData[i+7] = KeyData[j]; - KeyData[j] = (BYTE) t; - i += 8; - } - memcpy(KeyOrg, KeyData, sizeof(KeyOrg)); - - fInitialized = TRUE; -} - -void CryptRC4::Reset() -{ - memcpy(KeyData, KeyOrg, sizeof(KeyData)); -} - -void CryptRC4::Burn() -{ - memset(KeyOrg,0xFF,sizeof(KeyOrg)); - memset(KeyData,0xFF,sizeof(KeyData)); - // inherited Burn; -} - -void CryptRC4::Encrypt(PBYTE InData, PBYTE OutData, DWORD Size) -{ - DWORD BufferSize=8192; - DWORD i, Read; - - i = 0; - while(i < Size/BufferSize) - { - Read=8192; - EncryptBuffer(InData+i*BufferSize, OutData+i*BufferSize, Read); - i++; - } - - if(Size % BufferSize != 0) - { - Read=Size % BufferSize; - EncryptBuffer(InData+i*BufferSize, OutData+i*BufferSize, Read); - } -} - -void CryptRC4::EncryptBuffer(PBYTE InData, PBYTE OutData, DWORD Size) -{ - DWORD i, j, t, k; - - if(!fInitialized) return; //raise EDCP_cipher.Create('Cipher not initialized'); - i = 0; j = 0; - for(k = 0; k < Size; k++) - { - i = (i+1) & 0xFF; - t = KeyData[i]; - j = (j+t) & 0xFF; - KeyData[i] = KeyData[j]; - KeyData[j] = (BYTE) t; - t = (t + KeyData[i]) & 0xFF; - OutData[k] = InData[k] ^ KeyData[t]; - } -} - -void CryptRC4::Decrypt(PBYTE InData, PBYTE OutData, DWORD Size) -{ - DWORD BufferSize=8192; - DWORD i, Read; - - i = 0; - while(i < Size/BufferSize) - { - Read=8192; - DecryptBuffer(InData+i*BufferSize, OutData+i*BufferSize, Read); - i++; - } - - if(Size % BufferSize != 0) - { - Read=Size % BufferSize; - DecryptBuffer(InData+i*BufferSize, OutData+i*BufferSize, Read); - } -} - -void CryptRC4::DecryptBuffer(PBYTE InData, PBYTE OutData, DWORD Size) -{ - DWORD i, j, t, k; - - if(!fInitialized) return; //raise EDCP_cipher.Create('Cipher not initialized'); - i = 0; j = 0; - for(k = 0; k < Size; k++) - { - i = (i + 1) & 0xFF; - t = KeyData[i]; - j = (j + t) & 0xFF; - KeyData[i] = KeyData[j]; - KeyData[j] = (BYTE) t; - t = (t + KeyData[i]) & 0xFF; - OutData[k] = InData[k] ^ KeyData[t]; - } -} diff --git a/common/engine/keyboardprocessor/src/kmx/kmxtest/src/kmxtest.cpp b/common/engine/keyboardprocessor/src/kmx/kmxtest/src/kmxtest.cpp index d3b00bd932..711a0974d6 100644 --- a/common/engine/keyboardprocessor/src/kmx/kmxtest/src/kmxtest.cpp +++ b/common/engine/keyboardprocessor/src/kmx/kmxtest/src/kmxtest.cpp @@ -1,5 +1,8 @@ #include "pch.h" +#include +#include +#include AIWin2000Unicode *g_app = NULL; INTKEYBOARDINFO g_keyboard = { 0 }; @@ -11,6 +14,8 @@ char g_baseKeyboard[16] = "kbdus.dll"; wchar_t g_baseLayout[260] = L"", g_baseLayoutAlt[34] = L""; BOOL g_simulateAltGr = FALSE; char g_platform[128] = "windows desktop hardware native"; // TODO +WCHAR g_context[512] = L""; +int g_contextLength = 0; struct KeyEvent { UINT vkey; @@ -317,16 +322,16 @@ const char *VKeyNames[256] = { void print_default_environment() { - printf(" env.simulate_altgr=%d\n", g_simulateAltGr); - printf(" env.base_keyboard=%s\n", g_baseKeyboard); - printf(" env.base_layout=%ls\n", g_baseLayout); - printf(" env.base_layout_alt=%ls\n", g_baseLayoutAlt); - printf(" env.platform=%s\n", g_platform); + wprintf(L" env.simulate_altgr=%d\n", g_simulateAltGr); + wprintf(L" env.base_keyboard=%hs\n", g_baseKeyboard); + wprintf(L" env.base_layout=%s\n", g_baseLayout); + wprintf(L" env.base_layout_alt=%s\n", g_baseLayoutAlt); + wprintf(L" env.platform=%hs\n", g_platform); } BOOL addOption(char *val) { //TODO - printf("TODO: support %s\n", val); + wprintf(L"TODO: support %hs\n", val); return TRUE; } @@ -501,7 +506,48 @@ BOOL setKeys(char *val) { return TRUE; } +BOOL addContext(DWORD ch) { + if (ch > 0x10FFFF) return FALSE; + if (ch >= 0x10000) { + g_context[g_contextLength++] = (WCHAR) Uni_UTF32ToSurrogate1(ch); + g_context[g_contextLength++] = (WCHAR) Uni_UTF32ToSurrogate2(ch); + } + else { + g_context[g_contextLength++] = (WCHAR) ch; + } + g_context[g_contextLength] = 0; + return TRUE; +} + +BOOL addContextDeadkey(DWORD dk) { + g_context[g_contextLength++] = UC_SENTINEL; + g_context[g_contextLength++] = CODE_DEADKEY; + g_context[g_contextLength++] = (WCHAR) (dk + 1); + g_context[g_contextLength] = 0; + return TRUE; +} + BOOL setContext(char *val) { + while (*val) { + if (*val == '\\') { + val++; + if (*val == '\\') { + if (!addContext(*val)) return FALSE; + } + else if (*val == 'u') { + val++; + char *p = NULL; + if (!addContext(strtol(val, &p, 16))) return FALSE; + val = p; + } + else if (*val == 'd') { + val++; + char *p = NULL; + if (!addContextDeadkey(strtol(val, &p, 10))) return FALSE; + val = p; + } + } + } return TRUE; } @@ -509,6 +555,8 @@ int main(int argc, char *argv[]) { char *filename = NULL; BOOL invalid = FALSE; + _setmode(_fileno(stdout), _O_U16TEXT); + for (int i = 1; i < argc-1; i += 2) { char *arg = argv[i], *val = argv[i + 1]; if (!strcmp(arg, "-kmx")) { @@ -531,16 +579,16 @@ int main(int argc, char *argv[]) { } if (invalid || g_nKeyEvents == 0 || filename == NULL) { - printf("Usage: kmxtest -kmx -context context -keys key-sequence -d a=b\n"); - printf(" file.kmx must exist. No translation is done for mnemonic layout, etc.\n"); - printf(" context should be a string of unicode characters and/or deadkeys:\n"); - printf(" e.g. \"ABC\\u1234\\dxxxx\" (where xxxx is the integer deadkey value or deadkey name if keyboard is compiled with debug)\n"); - printf(" key-sequence is one or more Keyman keystrokes:\n"); - printf(" e.g. \"[SHIFT K_A] [K_B]\"\n"); - printf(" -d allows for definition of environment and keyboard options\n"); - printf(" keyboard option is opt.store_name=\"value\"\n"); - printf(" environment is env.name=\"\"\n"); - printf(" default environment is:\n"); + wprintf(L"Usage: kmxtest -kmx -context context -keys key-sequence -d a=b\n"); + wprintf(L" file.kmx must exist. No translation is done for mnemonic layout, etc.\n"); + wprintf(L" context should be a string of unicode characters and/or deadkeys:\n"); + wprintf(L" e.g. \"ABC\\u1234\\dxxxx\\d{name}\" (where xxxx is the integer deadkey value or {name} is the deadkey name if keyboard is compiled with debug)\n"); + wprintf(L" key-sequence is one or more Keyman keystrokes:\n"); + wprintf(L" e.g. \"[SHIFT K_A] [K_B]\"\n"); + wprintf(L" -d allows for definition of environment and keyboard options\n"); + wprintf(L" keyboard option is opt.store_name=\"value\"\n"); + wprintf(L" environment is env.name=\"\"\n"); + wprintf(L" default environment is:\n"); print_default_environment(); return 2; @@ -554,14 +602,23 @@ int main(int argc, char *argv[]) { // run; if (!LoadlpKeyboard(filename)) { - printf("Failed to load %s\n", filename); + wprintf(L"Failed to load %hs\n", filename); return 1; } PKEYMAN64THREADDATA _td = ThreadGlobals(); + g_app->SetContext(g_context); + + wprintf(L"============ Starting test ============\n"); + for (int i = 0; i < g_nKeyEvents; i++) { - printf("== [%d] == %x\n", i, g_keyEvents[i].vkey); + if (g_keyEvents[i].vkey < 256) { + wprintf(L"[%d] == %hs\n", i, VKeyNames[g_keyEvents[i].vkey]); + } + else { + wprintf(L"[%d] == %x\n", i, g_keyEvents[i].vkey); + } _td->state.vkey = g_keyEvents[i].vkey; _td->state.charCode = VKeyToChar(g_keyEvents[i].vkey); g_shiftState = g_keyEvents[i].modifiers; @@ -569,6 +626,8 @@ int main(int argc, char *argv[]) { ProcessHook(); } + wprintf(L"============ Stopping test ============\n"); + delete g_app; return 0; } diff --git a/common/engine/keyboardprocessor/src/kmx/kmxtest/test.bat b/common/engine/keyboardprocessor/src/kmx/kmxtest/test.bat new file mode 100644 index 0000000000..ef14fa4083 --- /dev/null +++ b/common/engine/keyboardprocessor/src/kmx/kmxtest/test.bat @@ -0,0 +1,4 @@ +@echo off + +debug\kmxtest -kmx khmer_angkor.kmx -keys "xEjmr" +debug\kmxtest -kmx khmer_angkor.kmx -keys "jmr" -context "\u1781\u17c2"