From 3ccaee0af99aaa6211215da2851d040fbd7885a1 Mon Sep 17 00:00:00 2001 From: SabinePlay <166697246+SabinePlay@users.noreply.github.com> Date: Thu, 18 Apr 2024 11:12:57 +0200 Subject: [PATCH 01/71] feat(mac): mcompile setup minimal VSCode project --- mac/mcompile/keymap.cpp | 46 +++ mac/mcompile/keymap.h | 20 ++ mac/mcompile/mcompile.cpp | 23 ++ mac/mcompile/mcompile.exe | Bin 0 -> 105984 bytes .../mcompile.exe.dSYM/Contents/Info.plist | 20 ++ .../Contents/Resources/DWARF/mcompile.exe | Bin 0 -> 273863 bytes .../Relocations/aarch64/mcompile.exe.yml | 300 ++++++++++++++++++ mac/mcompile/mcompile.h | 11 + 8 files changed, 420 insertions(+) create mode 100644 mac/mcompile/keymap.cpp create mode 100644 mac/mcompile/keymap.h create mode 100644 mac/mcompile/mcompile.cpp create mode 100755 mac/mcompile/mcompile.exe create mode 100644 mac/mcompile/mcompile.exe.dSYM/Contents/Info.plist create mode 100644 mac/mcompile/mcompile.exe.dSYM/Contents/Resources/DWARF/mcompile.exe create mode 100644 mac/mcompile/mcompile.exe.dSYM/Contents/Resources/Relocations/aarch64/mcompile.exe.yml create mode 100644 mac/mcompile/mcompile.h diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp new file mode 100644 index 00000000000..010ea93ef89 --- /dev/null +++ b/mac/mcompile/keymap.cpp @@ -0,0 +1,46 @@ +#include "keymap.h" + + +std::u16string get_character_From_Keycode(int dk, int ch , int shiftstate) { + + std::u16string character; + std::vector keyvals; + keyvals.push_back(dk); + keyvals.push_back(ch); + + TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); + CFDataRef layout_data = static_cast((TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData))); + const UCKeyboardLayout* keyboard_layout = reinterpret_cast(CFDataGetBytePtr(layout_data)); + + if (layout_data) + character = get_character_From_Keycode(keyvals, shiftstate, keyboard_layout); + + return character; +} + +std::u16string get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { + char16_t ch_array[3] = {L'\0'}; + UInt32 deadkeystate = 0; + UniCharCount maxStringlength = 5; + UniCharCount actualStringlength = 0; + UniChar unicodeString[maxStringlength]; + OSStatus status; + + for ( int i =0; i < keyval.size(); i++) { + + status = UCKeyTranslate(keyboard_layout, keyval[i] ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if( shiftstate %2 == 1 ) // uneven: seperate char -> `e + ch_array[i] = (char16_t) unicodeString[0]; + else + ch_array[0] = (char16_t) unicodeString[0]; // even: combine char -> è + } + + std::u16string returnString(ch_array); + return returnString; +} + + + +//-------------------------- + +void fun3() {std::cout << "Hier ist fun3 von keymap.cpp...\n";} \ No newline at end of file diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h new file mode 100644 index 00000000000..bd021d64601 --- /dev/null +++ b/mac/mcompile/keymap.h @@ -0,0 +1,20 @@ +#ifndef KEYMAP_H +#define KEYMAP_H + +// compile with. gcc -framework Carbon -o Bla.exe HW.cpp +// #import + +#include +#include +#include +#include + +std::u16string get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout); +std::u16string get_character_From_Keycode(int dk, int ch , int shiftstate); + + + +//-------------------------- +void fun3(); + +#endif // KEYMAP_H \ No newline at end of file diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp new file mode 100644 index 00000000000..99f54ad2ee2 --- /dev/null +++ b/mac/mcompile/mcompile.cpp @@ -0,0 +1,23 @@ + +#include +#include +#include "mcompile.h" + +//------------------------------- +int main () { + std::cout << "Hier ist main von mcompile-mac.cpp...\n"; + + std::u16string character; + + for (int i=0; i<8; i++) { + character = get_character_From_Keycode(24,14,i ); // all Shiftstates for ´` + e + //wprintf( L" ` + e for SHIFTSTATE %i -> ...\n", i, wstring_from_u16string(character);); + } + + printf("\n................................ END ..............................\n"); + return 0; +} + + +//-------------------------- +void fun2() { std::cout << "Hier ist fun2 von mcompile.cpp ...\n";} diff --git a/mac/mcompile/mcompile.exe b/mac/mcompile/mcompile.exe new file mode 100755 index 0000000000000000000000000000000000000000..b2be5f8ef9202f6664e12637dd09cf0009cd18a4 GIT binary patch literal 105984 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 + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.mcompile.exe + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/mac/mcompile/mcompile.exe.dSYM/Contents/Resources/DWARF/mcompile.exe b/mac/mcompile/mcompile.exe.dSYM/Contents/Resources/DWARF/mcompile.exe new file mode 100644 index 0000000000000000000000000000000000000000..422bf1b32c0496f3a420106b2d7cae1cd3e6ef7c GIT binary patch literal 273863 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 gE@Z7bwxLi7MJb2!=X6vi1#SKib Date: Thu, 18 Apr 2024 12:42:53 +0200 Subject: [PATCH 02/71] feat(mac): some edits --- mac/mcompile/keymap.cpp | 1 + mac/mcompile/keymap.h | 1 + mac/mcompile/mcompile.h | 1 + 3 files changed, 3 insertions(+) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 010ea93ef89..a66bb885cfb 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -1,6 +1,7 @@ #include "keymap.h" + std::u16string get_character_From_Keycode(int dk, int ch , int shiftstate) { std::u16string character; diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index bd021d64601..e2764918e66 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -14,6 +14,7 @@ std::u16string get_character_From_Keycode(int dk, int ch , int shiftstate); + //-------------------------- void fun3(); diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index debdb6d2bdb..9ff7f2f783f 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -5,6 +5,7 @@ + //-------------------------- void fun2(); From b2072483bcff0b42a2568befc8a3c0fb86f200d1 Mon Sep 17 00:00:00 2001 From: SabinePlay <166697246+SabinePlay@users.noreply.github.com> Date: Thu, 18 Apr 2024 15:26:09 +0200 Subject: [PATCH 03/71] feat(mac): new get_keyval_From_Keycode() feat(mac): include km_types and u16 feat(mac): include filesystem and some kmx feat(mac): include old functions in keymap feat(mac): include kmx_file, mc_kmxfile feat(mac): include deadkey, filesystem, km_types, import_rules,mc_kmxfile feat(mac): include functions in mcompile.cpp/h feat(mac): #includes out to be used --- common/include/km_types.h | 1 + mac/.gitignore | 3 + mac/mcompile/bu_phonetic.kmx | Bin 0 -> 73444 bytes mac/mcompile/deadkey.cpp | 477 +++++++++ mac/mcompile/deadkey.h | 33 + mac/mcompile/filesystem.cpp | 192 ++++ mac/mcompile/filesystem.h | 16 + mac/mcompile/keymap.cpp | 852 +++++++++++++++- mac/mcompile/keymap.h | 546 +++++++++- mac/mcompile/km_types.h | 120 +++ mac/mcompile/kmx_file.h | 393 ++++++++ mac/mcompile/mc_import_rules.cpp | 658 ++++++++++++ mac/mcompile/mc_import_rules.h | 42 + mac/mcompile/mc_kmxfile.cpp | 521 ++++++++++ mac/mcompile/mc_kmxfile.h | 90 ++ mac/mcompile/mcompile.cpp | 526 +++++++++- mac/mcompile/mcompile.exe | Bin 105984 -> 236784 bytes .../Contents/Resources/DWARF/mcompile.exe | Bin 273863 -> 561614 bytes .../Relocations/aarch64/mcompile.exe.yml | 950 ++++++++++++------ mac/mcompile/mcompile.h | 53 +- mac/mcompile/mcompiletest.kmx | Bin 0 -> 526 bytes mac/mcompile/sil_sahu.kmx | Bin 0 -> 1418 bytes mac/mcompile/u16.cpp | 334 ++++++ mac/mcompile/u16.h | 53 + 24 files changed, 5556 insertions(+), 304 deletions(-) create mode 100755 mac/mcompile/bu_phonetic.kmx create mode 100755 mac/mcompile/deadkey.cpp create mode 100755 mac/mcompile/deadkey.h create mode 100755 mac/mcompile/filesystem.cpp create mode 100755 mac/mcompile/filesystem.h create mode 100755 mac/mcompile/km_types.h create mode 100755 mac/mcompile/kmx_file.h create mode 100755 mac/mcompile/mc_import_rules.cpp create mode 100755 mac/mcompile/mc_import_rules.h create mode 100755 mac/mcompile/mc_kmxfile.cpp create mode 100755 mac/mcompile/mc_kmxfile.h create mode 100755 mac/mcompile/mcompiletest.kmx create mode 100755 mac/mcompile/sil_sahu.kmx create mode 100755 mac/mcompile/u16.cpp create mode 100755 mac/mcompile/u16.h diff --git a/common/include/km_types.h b/common/include/km_types.h index 113647d3a0a..b3b5c7b40ae 100644 --- a/common/include/km_types.h +++ b/common/include/km_types.h @@ -1,5 +1,6 @@ #pragma once +#include /* #if defined(_WIN32) || defined(_WIN64) #define snprintf _snprintf diff --git a/mac/.gitignore b/mac/.gitignore index 590a6ee1aad..4abfa6977db 100644 --- a/mac/.gitignore +++ b/mac/.gitignore @@ -15,3 +15,6 @@ setup/textinputsource/textinputsource setup/textinputsource/textinputsource.arm64 setup/textinputsource/textinputsource.x86_64 setup/Install Keyman.app + +//Sabine +**/*.exe diff --git a/mac/mcompile/bu_phonetic.kmx b/mac/mcompile/bu_phonetic.kmx new file mode 100755 index 0000000000000000000000000000000000000000..bf5f8b54a221a6431ae78976d1711c22ac6bc42c GIT binary patch literal 73444 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 BjVij5cR2;D{OOJaG@`C>D~`a<^; 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 bDc9P+-~P+0?d|gWvfb;u_HAFq`+5HlZ@II~ literal 0 HcmV?d00001 diff --git a/mac/mcompile/deadkey.cpp b/mac/mcompile/deadkey.cpp new file mode 100755 index 00000000000..08e3dbb9ece --- /dev/null +++ b/mac/mcompile/deadkey.cpp @@ -0,0 +1,477 @@ +#include "keymap.h" +#include "deadkey.h" +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + + +/* + +v_dw_1D createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult) { + v_dw_1D line; + line.push_back(convertNamesTo_DWORD_Value(first)); + line.push_back(convertNamesTo_DWORD_Value(second)); + //line.push_back(convertNamesTo_DWORD_Value(nameresult)); + line.push_back(number); + return line; +} + +std::vector create_alDead() { + std::vector alDead; + v_dw_2D dk_ComposeTable; + + create_DKTable(dk_ComposeTable); + + for( int i=0; i < (int) dk_ComposeTable.size()-1; i++) { + DeadKey *dk2 = new DeadKey(dk_ComposeTable[i][0]); + for ( int j=0; j< (int) dk_ComposeTable.size();j++) { + if(( dk_ComposeTable[i][0] == dk_ComposeTable[j][0]) && (IsKeymanUsedChar(dk_ComposeTable[j][1]))) + dk2->KMX_AddDeadKeyRow(dk_ComposeTable[j][1],dk_ComposeTable[j][2]); + } + alDead.push_back(dk2); + } + return alDead; +} + +void refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector *p_All_Vec) { + if( dk == 0) + return; + + for (int j=0; j < (int) (*p_All_Vec).size()-1;j++) { + if( dk == (*p_All_Vec)[j]->KMX_GetDeadCharacter()) { + if(! found_dk_inVector(dk, dkVec)) { + dkVec.push_back((*p_All_Vec)[j]); + return; + } + else return; + } + } +} + +bool found_dk_inVector(KMX_WCHAR dk, std::vector &dkVec) { + int i=0; + if( dkVec.size() > 0) { + do { + if( dk == dkVec[i]->KMX_GetDeadCharacter()) + return true; + i++; + } while (i < (int) dkVec.size()); + } + return false; +} + +bool query_dk_combinations_for_specific_dk(v_dw_2D * p_dk_ComposeTable, v_dw_2D &dk_SingleTable, KMX_DWORD dk) { + v_dw_1D line; + + for ( int i =0; i< (int) (*p_dk_ComposeTable).size(); i++) { + if (((*p_dk_ComposeTable)[i][0] == dk) && (IsKeymanUsedChar((*p_dk_ComposeTable)[i][1]))) { + line.push_back((*p_dk_ComposeTable)[i][0]); + line.push_back((*p_dk_ComposeTable)[i][1]); + line.push_back((*p_dk_ComposeTable)[i][2]); + dk_SingleTable.push_back(line); + line.clear(); + } + } + + if( dk_SingleTable.size()>0) + return true; + else + return false; +} + +KMX_DWORD KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap* keymap) { + guint Keyval = (guint) KVal; + GdkKeymapKey* keys; + gint n_keys; + + KMX_DWORD Cap = (KMX_DWORD) gdk_keyval_to_upper (KVal); + if( Keyval !=0) { + gdk_keymap_get_entries_for_keyval(keymap, Keyval, &keys, &n_keys); + for (int i = 0; i < n_keys; i++) { + if (keys[i].group == 0) { + shift = keys[i].level; + return Cap; + } + } + } + return Cap; +} + +void create_DKTable(v_dw_2D & dk_ComposeTable) { + //create a 2D-Vector which contains data for ALL existing deadkey combinations on a Linux Keyboard: + //dk_ComposeTable[i][0] : First (e.g. dead_circumflex) + //dk_ComposeTable[i][1] : Second (e.g. a) + //dk_ComposeTable[i][3] : Unicode-Value (e.g. 0x00E2) + + //values taken from: https://help.ubuntu.com/community/GtkDeadKeyTable#Accents + // _S2 Do we want to use GTK instead of this function? + + v_dw_1D line; + + line = createLine("dead_circumflex", "a", 0x00E2, "small A with circumflex"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_circumflex", "A", 0x00C2, "capital A with circumflex"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_circumflex", "e", 0x00EA, "small E with circumflex"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_circumflex", "E", 0x00CA, "capital E with circumflex"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_circumflex", "i", 0x00EE, "small I with circumflex"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_circumflex", "I", 0x00CE, "capital I with circumflex"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_circumflex", "o", 0x00F4, "small O with circumflex"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_circumflex", "O", 0x00D4, "capital O with circumflex"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_circumflex", "u", 0x00FB, "small U with circumflex"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_circumflex", "U", 0x00DB, "capital U with circumflex"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_acute", "a", 0x00E1, "small A with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "A", 0x00C1, "capital A with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "c", 0x0107, "small C with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "C", 0x0106, "capital C with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "e", 0x00E9, "small E with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "E", 0x00C9, "capital E with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "i", 0x00ED, "small I with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "I", 0x00CD, "capital I with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "l", 0x013A, "small L with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "L", 0x0139, "capital L with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "n", 0x0144, "small N with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "N", 0x0143, "capital N with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "o", 0x00F3, "small O with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "O", 0x00D3, "capital O with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "r", 0x0155, "small R with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "R", 0x0154, "capital R with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "s", 0x015B, "small S with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "S", 0x015A, "capital S with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "u", 0x00FA, "small U with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "U", 0x00DA, "capital U with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "y", 0x00FD, "small Y with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "Y", 0x00DD, "capital Y with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "z", 0x017A, "small Z with acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "Z", 0x0179, "capital Z with acute"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_grave", "a", 0x00E0, "small A with grave"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_grave", "A", 0x00C0, "capital A with grave"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_grave", "e", 0x00E8, "small E with grave"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_grave", "E", 0x00C8, "capital E with grave"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_grave", "i", 0x00EC, "small I with grave"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_grave", "I", 0x00CC, "capital I with grave"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_grave", "o", 0x00F2, "small O with grave"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_grave", "O", 0x00D2, "capital O with grave"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_grave", "u", 0x00F9, "small U with grave"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_grave", "U", 0x00D9, "capital U with grave"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_tilde", "a", 0x00E3, "small A with tilde"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_tilde", "A", 0x00C3, "capital A with tilde"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_tilde", "i", 0x0129, "small I with tilde"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_tilde", "I", 0x0128, "capital I with tilde"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_tilde", "n", 0x00F1, "small N with tilde"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_tilde", "N", 0x00D1, "capital N with tilde"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_tilde", "o", 0x00F5, "small O with tilde"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_tilde", "O", 0x00D5, "capital O with tilde"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_tilde", "u", 0x0169, "small U with tilde"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_tilde", "U", 0x0168, "capital U with tilde"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_macron", "a", 0x0101, "small A with macron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_macron", "A", 0x0100, "capital A with macron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_macron", "e", 0x0113, "small E with macron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_macron", "E", 0x0112, "capital E with macron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_macron", "i", 0x012B, "small I with macron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_macron", "I", 0x012A, "capital I with macron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_macron", "o", 0x014D, "small O with macron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_macron", "O", 0x014C, "capital O with macron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_macron", "u", 0x016B, "small U with macron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_macron", "U", 0x016A, "capital U with macron"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_breve", "a", 0x0103, "small A with breve"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_breve", "A", 0x0102, "capital A with breve"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_breve", "g", 0x011F, "small G with breve"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_breve", "G", 0x011E, "capital G with breve"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_abovedot", "e", 0x0117, "small E with dot above"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_abovedot", "E", 0x0116, "capital E with dot above"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_abovedot", "i", 0x0131, "small DOTLESS_I"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_abovedot", "I", 0x0130, "capital I with dot above"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_abovedot", "z", 0x017C, "small Z with dot above"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_abovedot", "Z", 0x017B, "capital Z with dot above"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_diaeresis", "a", 0x00E4, "small A with diaeresis"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "A", 0x00C4, "capital A with diaeresis"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "e", 0x00EB, "small E with diaeresis"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "E", 0x00CB, "capital E with diaeresis"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "i", 0x00EF, "small I with diaeresis"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "I", 0x00CF, "capital I with diaeresis"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "o", 0x00F6, "small O with diaeresis"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "O", 0x00D6, "capital O with diaeresis"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "u", 0x00FC, "small U with diaeresis"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "U", 0x00DC, "capital U with diaeresis"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "y", 0x00FF, "small Y with diaeresis"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "Y", 0x0178, "capital Y with diaeresis"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_abovering", "a", 0x00E5, "small A with ring above"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_abovering", "A", 0x00C5, "capital A with ring above"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_abovering", "u", 0x016F, "small U with ring above"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_abovering", "U", 0x016E, "capital U with ring above"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_doubleacute", "o", 0x0151, "small O with double acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_doubleacute", "O", 0x0150, "capital O with double acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_doubleacute", "u", 0x0171, "small U with double acute"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_doubleacute", "U", 0x0170, "capital U with double acute"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_caron", "c", 0x010D, "small C with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "C", 0x010C, "capital C with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "d", 0x010F, "small D with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "D", 0x010E, "capital D with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "e", 0x011B, "small E with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "E", 0x011A, "capital E with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "l", 0x013E, "small L with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "L", 0x013D, "capital L with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "n", 0x0148, "small N with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "N", 0x0147, "capital N with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "r", 0x0159, "small R with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "R", 0x0158, "capital R with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "s", 0x0161, "small S with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "S", 0x0160, "capital S with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "t", 0x0165, "small T with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "T", 0x0164, "capital T with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "z", 0x017E, "small Z with caron"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "Z", 0x017D, "capital Z with caron"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_cedilla", "c", 0x00E7, "small C with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "C", 0x00C7, "capital C with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "g", 0x0123, "small G with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "G", 0x0122, "capital G with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "k", 0x0137, "small K with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "K", 0x0136, "capital K with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "l", 0x013C, "small L with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "L", 0x013B, "capital L with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "n", 0x0146, "small N with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "N", 0x0145, "capital N with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "r", 0x0157, "small R with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "R", 0x0156, "capital R with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "s", 0x015F, "small S with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "S", 0x015E, "capital S with cedilla"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_ogonek", "a", 0x0105, "small A with ogonek"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_ogonek", "A", 0x0104, "capital A with ogonek"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_ogonek", "e", 0x0119, "small E with ogonek"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_ogonek", "E", 0x0118, "capital E with ogonek"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_ogonek", "i", 0x012F, "small I with ogonek"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_ogonek", "I", 0x012E, "capital I with ogonek"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_ogonek", "u", 0x0173, "small U with ogonek"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_ogonek", "U", 0x0172, "capital U with ogonek"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_circumflex", "space", 0x005E, "CIRCUMFLEX_ACCENT"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_acute", "space", 0x0027, "APOSTROPHE"); + dk_ComposeTable.push_back(line); line.clear(); + //line = createLine("dead_acute", "space", 0x00B4, "ACUTE_ACCENT"); // _S2 TOP_3 ToDo remove - this is not right: just for testing + // dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_grave", "space", 0x0060, "GRAVE_ACCENT"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_breve", "space", 0x02D8, "BREVE"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_abovedot", "space", 0x02D9, "DOT_ABOVE"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_abovering", "space", 0x02DA, "RING_ABOVE"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_doubleacute", "space", 0x02DD, "DOUBLE_ACUTE_ACCENT"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "space", 0x02C7, "CARON"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "space", 0x00B8, "CEDILLA"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_ogonek", "space", 0x02DB, "OGONEK"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_tilde", "space", 0x007E, "TILDE"); + dk_ComposeTable.push_back(line); line.clear(); + + line = createLine("dead_breve", "dead_breve", 0x02D8, "BREVE"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_abovedot", "abovedot", 0x02D9, "DOT_ABOVE"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_abovedot", "dead_abovedot", 0x02D9, "DOT_ABOVE"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_abovering", "dead_abovering", 0x02DA, "RING_ABOVE"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "apostrophe", 0x00B4, "ACUTE_ACCENT"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "acute", 0x00B4, "ACUTE_ACCENT"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_acute", "dead_acute", 0x00B4, "ACUTE_ACCENT"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_doubleacute", "dead_doubleacute", 0x02DD, "DOUBLE_ACUTE_ACCENT"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "caron", 0x02C7, "CARON"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_caron", "dead_caron", 0x02C7, "CARON"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "comma", 0x00B8, "CEDILLA"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "cedilla", 0x00B8, "CEDILLA"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_cedilla", "dead_cedilla", 0x00B8, "CEDILLA"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_circumflex", "minus", 0x00AF, "MACRON"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_circumflex", "asciicircum", 0x005E, "CIRCUMFLEX_ACCENT"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_circumflex", "underscore", 0x00AF, "MACRON"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_circumflex", "dead_circumflex", 0x005E, "CIRCUMFLEX_ACCENT"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "quotedbl", 0x00A8, "DIAERESIS"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "diaeresis", 0x00A8, "DIAERESIS"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_diaeresis", "dead_diaeresis", 0x00A8, "DIAERESIS"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_grave", "grave", 0x0060, "GRAVE_ACCENT"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_grave", "dead_grave", 0x0060, "GRAVE_ACCENT"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_macron", "macron", 0x00AF, "MACRON"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_macron", "dead_macron", 0x00AF, "MACRON"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_ogonek", "ogonek", 0x02DB, "OGONEK"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_ogonek", "dead_ogonek", 0x02DB, "OGONEK"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_tilde", "asciitilde", 0x007E, "TILDE"); + dk_ComposeTable.push_back(line); line.clear(); + line = createLine("dead_tilde", "dead_tilde", 0x007E, "TILDE"); + dk_ComposeTable.push_back(line); line.clear(); +} + +*/ \ No newline at end of file diff --git a/mac/mcompile/deadkey.h b/mac/mcompile/deadkey.h new file mode 100755 index 00000000000..0d2fee6d09c --- /dev/null +++ b/mac/mcompile/deadkey.h @@ -0,0 +1,33 @@ +#pragma once +#ifndef DEADKEY_H +#define DEADKEY_H + +#include +#include "mc_import_rules.h" +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + +/* + +// create a vector for a dk combination ( ` + a -> à ) +v_dw_1D createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult); + +// create a 2D-vector of all dk combinations ( ` + a -> à ; ^ + a -> â ; `+ e -> è; ...) +void create_DKTable(v_dw_2D & dk_ComposeTable); + +// find all possible dk combinations that exist +std::vector create_alDead(); + +// refine dk to those used in the underlying keyboard +void refine_alDead(KMX_WCHAR dk, std::vector &myVec, std::vector *p_All_Vec); +// check if entry is already there +bool found_dk_inVector(KMX_WCHAR dk, std::vector &myVec); + +// get all combination for a specific deadkey(dk) from the dk_vector query_dk_combinations_for_specific_dk which holds all possible dk: ^-> â,ê,î,ô,û,... +bool query_dk_combinations_for_specific_dk(v_dw_2D * dk_ComposeTable, v_dw_2D & dk_SingleTable, KMX_DWORD dk); + +// get the shifted character of a key and write shiftstate of KVal to shift +KMX_DWORD KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap* keymap); +*/ +# endif //DEADKEY_H \ No newline at end of file diff --git a/mac/mcompile/filesystem.cpp b/mac/mcompile/filesystem.cpp new file mode 100755 index 00000000000..8606c3576cc --- /dev/null +++ b/mac/mcompile/filesystem.cpp @@ -0,0 +1,192 @@ + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + +#ifdef __EMSCRIPTEN__ +#include +#include +#endif + +#include +#include +#include +#include "filesystem.h" + +#ifdef _MSC_VER +#include +#else +#include +#endif + +//#define _DEBUG_FOPEN 1 + +#ifdef __EMSCRIPTEN__ + +const std::string get_wasm_file_path(const std::string& filename) { + // Verify that we are passing a fully-qualified path + // TODO: we need to support relative paths based on CWD +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path ENTER (" << filename << ")" << std::endl; +#endif + + assert( + (filename.length() > 0 && filename.at(0) == '/') || + (filename.length() > 1 && filename.at(1) == ':') + ); + +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path assert passed " << std::endl; +#endif + + EM_ASM_({ + //console.log('EM_ASM enter'); + let path = Module.UTF8ToString($0); + const isWin32Path = path.match(/^[a-zA-Z]:/); + + //console.log('EM_ASM path = '+path); + let root = '/nodefs-mount'; + if(!FS.analyzePath(root).exists) { + //console.log('EM_ASM mkdir '+root); + FS.mkdir(root); + if(!isWin32Path) { + //console.log('EM_ASM mount '+root); + FS.mount(NODEFS, {root : '/'}, root); + } + } + + if(isWin32Path) { + // Win32 path, one mount per drive + root += "/" + path.charAt(0); + if(!FS.analyzePath(root).exists) { + //console.log('EM_ASM mkdir '+root); + FS.mkdir(root); + //console.log('EM_ASM mount '+root); + FS.mount(NODEFS, {root : path.substr(0,3) }, root); + } + } + }, filename.c_str()); + +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path EM_ASM_ passed " << std::endl; +#endif + + std::string f = std::string("/nodefs-mount"); + + if(filename.length() > 2 && filename.at(1) == ':') { + f += std::string("/") + filename.at(0) + filename.substr(2); + } else { + f += filename; + } + +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path opening virtual path: " << f << std::endl; +#endif + + return f; +} + +FILE* fopen_wasm(const std::string& filename, const std::string& mode) { + std::string f = get_wasm_file_path(filename); + FILE* fp = fopen(f.c_str(), mode.c_str()); + +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path fopen called, returned " << fp << std::endl; +#endif + + return fp; +} + +#endif + +#ifndef _MSC_VER +#ifdef __EMSCRIPTEN__ +#define fopen_wrapper fopen_wasm +#else +#define fopen_wrapper fopen +#endif +#endif + +FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode) { +#ifdef _MSC_VER + std::string cpath = Filename; //, cmode = mode; + std::replace(cpath.begin(), cpath.end(), '/', '\\'); + return fopen(cpath.c_str(), (const KMX_CHAR*) mode); +#else + return fopen_wrapper(Filename, mode); + std::string cpath, cmode; + cpath = (const KMX_CHAR*) Filename; + cmode = (const KMX_CHAR*) mode; + return fopen_wrapper(cpath.c_str(), cmode.c_str()); +#endif +}; + +FILE* Open_File(const KMX_WCHART* Filename, const KMX_WCHART* mode) { +#ifdef _MSC_VER + std::wstring cpath = Filename; //, cmode = mode; + std::replace(cpath.begin(), cpath.end(), '/', '\\'); + return _wfsopen(cpath.c_str(), mode, _SH_DENYWR); +#else + std::string cpath, cmode; + cpath = string_from_wstring(Filename); + cmode = string_from_wstring(mode); + return fopen_wrapper(cpath.c_str(), cmode.c_str()); +#endif +}; + +FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode) { +#ifdef _MSC_VER + std::wstring cpath = convert_pchar16T_To_wstr((KMX_WCHAR*) Filename); + std::wstring cmode = convert_pchar16T_To_wstr((KMX_WCHAR*) mode); + std::replace(cpath.begin(), cpath.end(), '/', '\\'); + return _wfsopen(cpath.c_str(), cmode.c_str(), _SH_DENYWR); +#else + std::string cpath, cmode; + cpath = string_from_u16string(Filename); + cmode = string_from_u16string(mode); + return fopen_wrapper(cpath.c_str(), cmode.c_str()); +#endif +}; + +KMX_BOOL kmcmp_FileExists(const KMX_CHAR *filename) { + +#ifdef _MSC_VER + intptr_t n; + _finddata_t fi; + if((n = _findfirst(filename, &fi)) != -1) { + _findclose(n); + return TRUE; + } +#else //!_MSC_VER + +#ifdef __EMSCRIPTEN__ + std::string f = get_wasm_file_path(filename); +#else //!__EMSCRIPTEN__ + std::string f = filename; +#endif // !__EMSCRIPTEN__ + + if(access(f.c_str(), F_OK) != -1) { + return TRUE; + } + +#endif // !_MSC_VER + + return FALSE; +} + +KMX_BOOL kmcmp_FileExists(const KMX_WCHAR* filename) { +#ifdef _MSC_VER + intptr_t n; + _wfinddata_t fi; + if((n = _wfindfirst((wchar_t*) filename, &fi)) != -1) { + _findclose(n); + return TRUE; + } +#else + std::string cpath; + cpath = string_from_u16string(filename); + return kmcmp_FileExists(cpath.c_str()); +#endif + + return FALSE; +}; diff --git a/mac/mcompile/filesystem.h b/mac/mcompile/filesystem.h new file mode 100755 index 00000000000..7e30f73b052 --- /dev/null +++ b/mac/mcompile/filesystem.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include "u16.h" + +// Open files on windows and non-windows platforms. Datatypes for Filename and mode must be the same. +// return FILE* if file could be opened; FILE must to be closed in calling function +FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); +FILE* Open_File(const KMX_WCHART* Filename, const KMX_WCHART* mode); +FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode); +KMX_BOOL kmcmp_FileExists(const KMX_CHAR *filename); +KMX_BOOL kmcmp_FileExists(const KMX_WCHAR *filename); + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index a66bb885cfb..c9085cd7006 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -1,6 +1,818 @@ #include "keymap.h" +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + + +/* +#include + +// unmodified, shift, RALT, shift+RALT +int map_VKShiftState_to_LinModifier(int VKShiftState) { + if (VKShiftState == 0 ) return 0; // 0000 0000 // + else if (VKShiftState == 16) return 1; // 0001 0000 // + else if (VKShiftState == 9 ) return 2; // 0000 1001 // + else if (VKShiftState == 25) return 3; // 0001 1001 // + else return VKShiftState; +} + +KMX_DWORD convertNamesTo_DWORD_Value(std::string tok_str) { + // more on https://manpages.ubuntu.com/manpages/jammy/man3/keysyms.3tk.html + std::map first; + + first["ampersand"] = 38; + first["apostrophe"] = 39; + first["asciicircum"] = 136; + first["asciitilde"] = 126; + first["asterisk"] = 42; + first["at"] = 64; + first["backslash"] = 92; + first["BackSpace"] = 65288; + first["bar"] = 124; + first["braceleft"] = 123; + first["braceright"] = 125; + first["bracketleft"] = 91; + first["bracketright"] = 93; + first["colon"] = 58; + first["comma"] = 44; + first["diaeresis"] = 168; + first["dollar"] = 36; + first["equal"] = 61; + first["exclam"] = 33; + first["grave"] = 96; + first["greater"] = 62; + first["less"] = 60; + first["minus"] = 45; + first["numbersign"] = 35; + first["parenleft"] = 40; + first["parenright"] = 41; + first["percent"] = 37; + first["period"] = 46; + first["plus"] = 43; + first["question"] = 63; + first["quotedbl"] = 34; + first["semicolon"] = 59; + first["slash"] = 47; + first["space"] = 32; + first["ssharp"] = 223; + first["underscore"] = 95; + + + first["nobreakspace"] = 160; + first["exclamdown"] = 161; + first["cent"] = 162; + first["sterling"] = 163; + first["currency"] = 164; + first["yen"] = 165; + first["brokenbar"] = 166; + first["section"] = 167; + first["copyright"] = 169; + first["ordfeminine"] = 170; + first["guillemotleft"] = 171; + first["notsign"] = 172; + first["hyphen"] = 173; + first["registered"] = 174; + first["macron"] = 175; + first["degree"] = 176; + first["plusminus"] = 177; + first["twosuperior"] = 178; + first["threesuperior"] = 179; + first["acute"] = 180; + first["mu"] = 181; + first["paragraph"] = 182; + first["periodcentered"] = 183; + first["cedilla"] = 184; + first["onesuperior"] = 185; + first["masculine"] = 186; + first["guillemotright"] = 187; + first["onequarter"] = 188; + first["onehalf"] = 189; + first["threequarters"] = 190; + first["questiondown"] = 191; + first["Agrave"] = 192; + first["Aacute"] = 193; + first["Acircumflex"] = 194; + first["Atilde"] = 195; + first["Adiaeresis"] = 196; + first["Aring"] = 197; + first["AE"] = 198; + first["Ccedilla"] = 199; + first["Egrave"] = 200; + first["Eacute"] = 201; + first["Ecircumflex"] = 202; + first["Ediaeresis"] = 203; + first["Igrave"] = 204; + first["Iacute"] = 205; + first["Icircumflex"] = 206; + first["Idiaeresis"] = 207; + first["ETH"] = 208; + first["Ntilde"] = 209; + first["Ograve"] = 210; + first["Oacute"] = 211; + first["Ocircumflex"] = 212; + first["Otilde"] = 213; + first["Odiaeresis"] = 214; + first["multiply"] = 215; + first["Oslash"] = 216; + first["Ugrave"] = 217; + first["Uacute"] = 218; + first["Ucircumflex"] = 219; + first["Udiaeresis"] = 220; + first["Yacute"] = 221; + first["THORN"] = 222; + first["agrave"] = 224; + first["aacute"] = 225; + first["acircumflex"] = 226; + first["atilde"] = 227; + first["adiaeresis"] = 228; + first["aring"] = 229; + first["ae"] = 230; + first["ccedilla"] = 231; + first["egrave"] = 232; + first["eacute"] = 233; + first["ecircumflex"] = 234; + first["ediaeresis"] = 235; + first["igrave"] = 236; + first["iacute"] = 237; + first["icircumflex"] = 238; + first["idiaeresis"] = 239; + first["eth"] = 240; + first["ntilde"] = 241; + first["ograve"] = 242; + first["oacute"] = 243; + first["ocircumflex"] = 244; + first["otilde"] = 245; + first["odiaeresis"] = 246; + first["division"] = 247; + first["oslash"] = 248; + first["ugrave"] = 249; + first["uacute"] = 250; + first["ucircumflex"] = 251; + first["udiaeresis"] = 252; + first["yacute"] = 253; + first["thorn"] = 254; + first["ydiaeresis"] = 255; + first["Aogonek"] = 417; + first["breve"] = 418; + first["Lstroke"] = 419; + first["Lcaron"] = 421; + first["Sacute"] = 422; + first["Scaron"] = 425; + first["Scedilla"] = 426; + first["Tcaron"] = 427; + first["Zacute"] = 428; + first["Zcaron"] = 430; + first["Zabovedot"] = 431; + first["aogonek"] = 433; + first["ogonek"] = 434; + first["lstroke"] = 435; + first["lcaron"] = 437; + first["sacute"] = 438; + first["caron"] = 439; + first["scaron"] = 441; + first["scedilla"] = 442; + first["tcaron"] = 443; + first["zacute"] = 444; + first["doubleacute"] = 445; + first["zcaron"] = 446; + first["zabovedot"] = 447; + first["Racute"] = 448; + first["Abreve"] = 451; + first["Lacute"] = 453; + first["Cacute"] = 454; + first["Ccaron"] = 456; + first["Eogonek"] = 458; + first["Ecaron"] = 460; + first["Dcaron"] = 463; + first["Dstroke"] = 464; + first["Nacute"] = 465; + first["Ncaron"] = 466; + first["Odoubleacute"] = 469; + first["Rcaron"] = 472; + first["Uring"] = 473; + first["Udoubleacute"] = 475; + first["Tcedilla"] = 478; + first["racute"] = 480; + first["abreve"] = 483; + first["lacute"] = 485; + first["cacute"] = 486; + first["ccaron"] = 488; + first["eogonek"] = 490; + first["ecaron"] = 492; + first["dcaron"] = 495; + first["dstroke"] = 496; + first["nacute"] = 497; + first["ncaron"] = 498; + first["odoubleacute"] = 501; + first["rcaron"] = 504; + first["uring"] = 505; + first["udoubleacute"] = 507; + first["tcedilla"] = 510; + first["abovedot"] = 511; + first["Hstroke"] = 673; + first["Hcircumflex"] = 678; + first["Iabovedot"] = 681; + first["Gbreve"] = 683; + first["Jcircumflex"] = 684; + first["hstroke"] = 689; + first["hcircumflex"] = 694; + first["idotless"] = 697; + first["gbreve"] = 699; + first["jcircumflex"] = 700; + first["Cabovedot"] = 709; + first["Ccircumflex"] = 710; + first["Gabovedot"] = 725; + first["Gcircumflex"] = 728; + first["Ubreve"] = 733; + first["Scircumflex"] = 734; + first["cabovedot"] = 741; + first["ccircumflex"] = 742; + first["gabovedot"] = 757; + first["gcircumflex"] = 760; + first["ubreve"] = 765; + first["scircumflex"] = 766; + first["kra"] = 930; + first["Rcedilla"] = 931; + first["Itilde"] = 933; + first["Lcedilla"] = 934; + first["Emacron"] = 938; + first["Gcedilla"] = 939; + first["Tslash"] = 940; + first["rcedilla"] = 947; + first["itilde"] = 949; + first["lcedilla"] = 950; + first["emacron"] = 954; + first["gcedilla"] = 955; + first["tslash"] = 956; + first["ENG"] = 957; + first["eng"] = 959; + first["Amacron"] = 960; + first["Iogonek"] = 967; + first["Eabovedot"] = 972; + first["Imacron"] = 975; + first["Ncedilla"] = 977; + first["Omacron"] = 978; + first["Kcedilla"] = 979; + first["Uogonek"] = 985; + first["Utilde"] = 989; + first["Umacron"] = 990; + first["amacron"] = 992; + first["iogonek"] = 999; + first["eabovedot"] = 1004; + first["imacron"] = 1007; + first["ncedilla"] = 1009; + first["omacron"] = 1010; + first["kcedilla"] = 1011; + first["uogonek"] = 1017; + first["utilde"] = 1021; + first["umacron"] = 1022; + first["overline"] = 1150; + + first["dead_abovedot"] = 729; + first["dead_abovering"] = 730; + first["dead_acute"] = 180; + first["dead_breve"] = 728; + first["dead_caron"] = 711; + first["dead_cedilla"] = 184; + first["dead_circumflex"] = 94; + first["dead_diaeresis"] = 168; + first["dead_doubleacute"] = 733; + first["dead_grave"] = 96; + first["dead_ogonek"] = 731; + first["dead_perispomeni"] = 126; + first["dead_tilde"] = 126; + + first["acute accent"] = 0xB4; + + if ( tok_str.size() == 1) { + return (KMX_DWORD) ( *tok_str.c_str() ); + } + else { + std::map ::iterator it; + for (it = first.begin(); it != first.end(); ++it) { + if (it->first == tok_str) + return it->second; + } + } + return returnIfCharInvalid; +} + +int createOneVectorFromBothKeyboards(v_dw_3D &All_Vector,GdkKeymap *keymap) { + // create a 3D-Vector which contains data of the US keyboard and the underlying Keyboard: + // All_Vector[ US_Keyboard ] + // [KeyCode_US ] + // [Keyval unshifted ] + // [Keyval shifted ] + // [Underlying Kbd] + // [KeyCode_underlying] + // [Keyval unshifted ] + // [Keyval shifted ] + + std::string US_language = "us"; + const char* text_us = "xkb_symbols \"basic\""; + + if(write_US_ToVector(All_Vector,US_language, text_us)) { + wprintf(L"ERROR: can't write US to Vector \n"); + return 1; + } + + // add contents of other keyboard to All_Vector + if( append_underlying_ToVector(All_Vector,keymap)) { + wprintf(L"ERROR: can't append underlying ToVector \n"); + return 2; + } + return 0; +} + +int write_US_ToVector( v_dw_3D &vec,std::string language, const char* text) { + + std::string FullPathName = "/usr/share/X11/xkb/symbols/" + language; + + const char* path = FullPathName.c_str(); + FILE* fp = fopen((path), "r"); + if ( !fp) { + wprintf(L"ERROR: could not open file!\n"); + return 1; + } + + // create 1D-vector of the complete line + v_str_1D Vector_completeUS; + if( createCompleteRow_US(Vector_completeUS,fp , text, language)) { + wprintf(L"ERROR: can't Create complete row US \n"); + return 1; + } + + // split contents of 1D Vector to 3D vector + if( split_US_To_3D_Vector( vec,Vector_completeUS)) { + return 1; + } + + fclose(fp); + return 0; +} + +bool createCompleteRow_US(v_str_1D &complete_List, FILE* fp, const char* text, std::string language) { + // in the Configuration file we find the appopriate paragraph between "xkb_symbol " and the next xkb_symbol + // and then copy all rows starting with "key <" to a 1D-Vector + + int buffer_size = 512; + char buffer[buffer_size]; + bool create_row = false; + const char* key = "key <"; + std::string str_txt(text); + std::string xbk_mark = "xkb_symbol"; + + if (fp) { + while (fgets(buffer, buffer_size, fp) != NULL) { + std::string str_buf(buffer); + + // stop when finding the mark xkb_symbol + if (std::string(str_buf).find(xbk_mark) != std::string::npos) + create_row = false; + + // start when finding the mark xkb_symbol + correct layout + if (std::string(str_buf).find(str_txt) != std::string::npos) + create_row = true; + + // as long as we are in the same xkb_symbol layout block and find "key <" we push the whole line into a 1D-vector + if (create_row && (std::string(str_buf).find(key) != std::string::npos)) { + complete_List.push_back(buffer); + } + } + } + complete_List.push_back(" key { [ space, space] };"); + + if (complete_List.size() <1) { + wprintf(L"ERROR: can't create row from US \n"); + return 1; + } + return 0; +} + +int replace_KeyName_with_Keycode(std::string in) { + int out = returnIfCharInvalid; + + if ( in == "key") out = 49; // VK_ BKQUOTE // + else if ( in == "key") out = 10; // VK_1 // + else if ( in == "key") out = 11; // VK_2 // + else if ( in == "key") out = 12; // VK_3 // + else if ( in == "key") out = 13; // VK_4 // + else if ( in == "key") out = 14; // VK_5 // + else if ( in == "key") out = 15; // VK_6 // + else if ( in == "key") out = 16; // VK_7 // + else if ( in == "key") out = 17; // VK_8 // + else if ( in == "key") out = 18; // VK_9 // + else if ( in == "key") out = 19; // VK_0 // + else if ( in == "key") out = 20; // VK_MINUS K_HYPHEN // + else if ( in == "key") out = 21; // VK_EQUAL // + + else if ( in == "key") out = 24; // VK_Q // + else if ( in == "key") out = 25; // VK_W // + else if ( in == "key") out = 26; // VK_E // + else if ( in == "key") out = 27; // VK_R // + else if ( in == "key") out = 28; // VK_T // + else if ( in == "key") out = 29; // VK_Y // + else if ( in == "key") out = 30; // VK_U // + else if ( in == "key") out = 31; // VK_I // + else if ( in == "key") out = 32; // VK_O // + else if ( in == "key") out = 33; // VK_P // + else if ( in == "key") out = 34; // VK_LEFTBRACE // + else if ( in == "key") out = 35; // VK_RIGHTBRACE // + + else if ( in == "key") out = 38; // VK_A // + else if ( in == "key") out = 39; // VK_S // + else if ( in == "key") out = 40; // VK_D // + else if ( in == "key") out = 41; // VK_F // + else if ( in == "key") out = 42; // VK_G // + else if ( in == "key") out = 43; // VK_H // + else if ( in == "key") out = 44; // VK_J // + else if ( in == "key") out = 45; // VK_K // + else if ( in == "key") out = 46; // VK_L // + else if ( in == "key") out = 47; // VK_SEMICOLON // + else if ( in == "key") out = 48; // VK_APOSTROPHE // + + else if ( in == "key") out = 52; // VK_Z // + else if ( in == "key") out = 53; // VK_X // + else if ( in == "key") out = 54; // VK_C // + else if ( in == "key") out = 55; // VK_V // + else if ( in == "key") out = 56; // VK_B // + else if ( in == "key") out = 57; // VK_N // + else if ( in == "key") out = 58; // VK_M // + else if ( in == "key") out = 59; // VK_ COMMA // + else if ( in == "key") out = 60; // VK_DOT // + else if ( in == "key") out = 61; // VK_SLASH // + else if ( in == "key") out = 51; // VK_BKSLASH // + else if ( in == "key") out = 63; // VK_RIGHTSHIFT // + else if ( in == "key") out = 65; // VK_SPACE // + + return out; +} + +int split_US_To_3D_Vector(v_dw_3D &all_US,v_str_1D completeList) { + // 1: take the whole line of the 1D-Vector and remove unwanted characters. + // 2: seperate the name e.g. key from the shiftstates + // 3: convert to KMX_DWORD + // 4: push Names/Shiftstates to shift_states and then shift_states to All_US, our 3D-Vector holding all Elements + + std::vector delim{' ', '[', ']', '}', ';', '\t', '\n'}; + char split_bracel = '{'; + char split_comma = ','; + int Keycde; + v_str_1D tokens; + v_dw_1D tokens_dw; + v_dw_2D shift_states; + KMX_DWORD tokens_int; + + // loop through the whole vector + for (int k = 0; k < (int)completeList.size(); k++) { + + // remove all unwanted char + for (int i = 0; i < (int) delim.size(); i++) { + completeList[k].erase(remove(completeList[k].begin(), completeList[k].end(), delim[i]), completeList[k].end()); + } + + // only lines with ("key<.. are of interest + if (completeList[k].find("key<") != std::string::npos) { + + //split off the key names + std::istringstream split1(completeList[k]); + for (std::string each; std::getline(split1, each, split_bracel); tokens.push_back(each)); + + // replace keys names with Keycode ( with 21,...) + Keycde = replace_KeyName_with_Keycode(tokens[0]); + tokens[0] = std::to_string(Keycde); + + // seperate rest of the vector to its elements and push to 'tokens' + std::istringstream split(tokens[1]); + tokens.pop_back(); + + for (std::string each; std::getline(split, each, split_comma); tokens.push_back(each)); + + // now convert all to KMX_DWORD and fill tokens + tokens_dw.push_back((KMX_DWORD) Keycde); + + for ( int i = 1; i< (int) tokens.size();i++) { + // replace a name with a single character ( a -> a ; equal -> = ) + tokens_int = convertNamesTo_DWORD_Value(tokens[i]); + tokens_dw.push_back(tokens_int); + } + + shift_states.push_back(tokens_dw); + tokens_dw.clear(); + tokens.clear(); + } + } + all_US.push_back(shift_states); + + if ( all_US.size() == 0) { + wprintf(L"ERROR: Can't split US to 3D-Vector\n"); + return 1; + } + return 0; +} + +v_dw_2D create_empty_2D_Vector( int dim_rows,int dim_ss) { + + v_dw_1D shifts; + v_dw_2D Vector_2D; + + for ( int i=0; i< dim_rows;i++) { + for ( int j=0; j< dim_ss;j++) { + shifts.push_back(returnIfCharInvalid); + } + Vector_2D.push_back(shifts); + shifts.clear(); + } + return Vector_2D; +} + +int append_underlying_ToVector(v_dw_3D &All_Vector,GdkKeymap *keymap) { + + // create a 2D vector all filled with " " and push to 3D-Vector + v_dw_2D underlying_Vector2D = create_empty_2D_Vector(All_Vector[0].size(),All_Vector[0][0].size()); + + if (underlying_Vector2D.size() == 0) { + wprintf(L"ERROR: can't create empty 2D-Vector\n"); + return 1; + } + All_Vector.push_back(underlying_Vector2D); + + if (All_Vector.size() < 2) { + wprintf(L"ERROR: creation of 3D-Vector failed\n"); + return 1; + } + + for(int i =0; i< (int) All_Vector[1].size();i++) { + + // get key name US stored in [0][i][0] and copy to name in "underlying"-block[1][i][0] + All_Vector[1][i][0] = All_Vector[0][i][0]; + + // get Keyvals of this key and copy to unshifted/shifted in "underlying"-block[1][i][1] / block[1][i][2] + All_Vector[1][i][0+1] = KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keymap,All_Vector[0][i][0],0); //shift state: unshifted:0 + All_Vector[1][i][1+1] = KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keymap,All_Vector[0][i][0],1); //shift state: shifted:1 + } + + return 0; +} + +bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]) { +// get keymap of underlying keyboard + + gdk_init(&argc, &argv); + GdkDisplay *display = gdk_display_get_default(); + if (!display) { + wprintf(L"ERROR: can't get display\n"); + return 1; + } + + *keymap = gdk_keymap_get_for_display(display); + if (!keymap) { + wprintf(L"ERROR: Can't get keymap\n"); + gdk_display_close(display); + return 2; + } + return 0; +} + +bool IsKeymanUsedChar(int KV) { + // 32 A-Z a-z + if ((KV == 0x20 ) || (KV >= 65 && KV <= 90) || (KV >= 97 && KV <= 122) ) + return true; + else + return false; +} + +std::u16string convert_DeadkeyValues_To_U16str(int in) { + + if (in == 0 ) + return u"\0"; + + std::string long_name((const char*) gdk_keyval_name (in)); // e.g. "dead_circumflex" , "U+017F" , "t" + + if ( long_name.substr (0,2) == "U+" ) // U+... Unicode value + return CodePointToU16String(in-0x1000000); + + if (in < (int) deadkey_min) { // no deadkey; no Unicode + return std::u16string(1, in); + } + + KMX_DWORD lname = convertNamesTo_DWORD_Value(long_name); // 65106 => "dead_circumflex" => 94 => "^" + + if (lname != returnIfCharInvalid) { + return std::u16string(1, lname ); + } + else + return u"\0"; +} + +int KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps) { + + GdkModifierType consumed; + GdkKeymapKey *maps; + guint *keyvals; + gint count; + + if (!gdk_keymap_get_entries_for_keycode(keymap, keycode, &maps, &keyvals, &count)) + return 0; + + //BASE (shiftstate: 0) + if (( ss == Base ) && ( caps == 0 )) { + GdkModifierType MOD_base = (GdkModifierType) ( ~GDK_MODIFIER_MASK ); + gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_base , 0, keyvals, NULL, NULL, & consumed); + } + + //BASE + CAPS (shiftstate: 0) + else if (( ss == Base ) && ( caps == 1 )) { + GdkModifierType MOD_Caps = (GdkModifierType) ( GDK_LOCK_MASK ); + gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_Caps, 0, keyvals, NULL, NULL, & consumed); + } + + //SHIFT (shiftstate: 1) + else if (( ss == Shft ) && ( caps == 0 )) { + GdkModifierType MOD_Shift = (GdkModifierType) ( GDK_SHIFT_MASK ); + gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_Shift , 0, keyvals, NULL, NULL, & consumed); + } + + //SHIFT + CAPS (shiftstate: 1) + else if ( ( ss == Shft ) && ( caps ==1 )) { + GdkModifierType MOD_ShiftCaps= (GdkModifierType) ((GDK_SHIFT_MASK | GDK_LOCK_MASK)); + gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_ShiftCaps , 0, keyvals, NULL, NULL, & consumed); + } + + // Ctrl (shiftstate: 2) + else if (( ss == Ctrl ) && ( caps == 0 )){ + GdkModifierType MOD_Ctrl = (GdkModifierType) ( GDK_MOD5_MASK ); + gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_Ctrl , 0, keyvals, NULL, NULL, & consumed); + } + + // Ctrl + CAPS (shiftstate: 2) + else if (( ss == Ctrl ) && ( caps == 1 )){ + GdkModifierType MOD_CtrlCaps = (GdkModifierType) (GDK_MOD5_MASK | GDK_LOCK_MASK); + gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_CtrlCaps , 0, keyvals, NULL, NULL, & consumed); + } + + // SHIFT+Ctrl (shiftstate: 3) + else if (( ss == ShftCtrl ) && ( caps == 0 )){ + GdkModifierType MOD_Ctrl = (GdkModifierType) (GDK_SHIFT_MASK | GDK_MOD5_MASK ); + gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_Ctrl , 0, keyvals, NULL, NULL, & consumed); + } + + // SHIFT+Ctrl + CAPS (shiftstate: 3) + else if (( ss == ShftCtrl ) && ( caps == 1 )){ + GdkModifierType MOD_CtrlCaps = (GdkModifierType) ( GDK_SHIFT_MASK | GDK_MOD5_MASK | GDK_LOCK_MASK); + gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_CtrlCaps , 0, keyvals, NULL, NULL, & consumed); + } + + //ALT-GR (shiftstate: 6) + else if (( ss == MenuCtrl ) && ( caps == 0 )){ + GdkModifierType MOD_AltGr = (GdkModifierType) (GDK_MOD2_MASK | GDK_MOD5_MASK); + gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_AltGr , 0, keyvals, NULL, NULL, & consumed); + } + + //ALT-GR + CAPS (shiftstate: 6) + else if (( ss == MenuCtrl ) && ( caps == 1 )){ + GdkModifierType MOD_AltGr = (GdkModifierType) (GDK_MOD2_MASK | GDK_MOD5_MASK | GDK_LOCK_MASK); + gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_AltGr , 0, keyvals, NULL, NULL, & consumed); + } + + //ALT-GR (shiftstate: 7) + else if (( ss == ShftMenuCtrl ) && ( caps == 0 )){ + GdkModifierType MOD_AltGr = (GdkModifierType) ( (GDK_SHIFT_MASK | GDK_MOD2_MASK | GDK_MOD5_MASK) ); + gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_AltGr , 0, keyvals, NULL, NULL, & consumed); + } + + //ALT-GR +CAPS (shiftstate: 7) + else if (( ss == ShftMenuCtrl ) && ( caps == 1 )){ + GdkModifierType MOD_AltGr = (GdkModifierType) ( (GDK_SHIFT_MASK | GDK_MOD2_MASK | GDK_MOD5_MASK | GDK_LOCK_MASK) ); + gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_AltGr , 0, keyvals, NULL, NULL, & consumed); + } + else + return 0; + + return (int) *keyvals; +} + +KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, guint keycode, int shift_state_pos) { + GdkKeymapKey *maps; + guint *keyvals; + gint count; + KMX_DWORD KVal; + + if (!gdk_keymap_get_entries_for_keycode(keymap, keycode, &maps, &keyvals, &count)) + return 0; + + if (!(shift_state_pos <= count)) + return 0; + + if (!(keycode <= keycode_max)) + return 0; + + KVal = (KMX_DWORD) KMX_get_KeyVal_From_KeyCode(keymap, keycode, (ShiftState) shift_state_pos, 0); + + g_free(keyvals); + g_free(maps); + + return KVal; +} + +KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey) { + + GdkKeymapKey *maps; + guint *keyvals; + gint count; + PKMX_WCHAR dky=NULL; + + + if (!gdk_keymap_get_entries_for_keycode(keymap, KC_underlying, &maps, &keyvals, &count)) + return 0; + + if (!(map_VKShiftState_to_LinModifier(VKShiftState) <= count)) + return 0; + + if (!(KC_underlying <= keycode_max)) + return 0; + + KMX_DWORD KeyV = KMX_get_KeyVal_From_KeyCode(keymap, KC_underlying, ShiftState(map_VKShiftState_to_LinModifier(VKShiftState)), 0); + + g_free(keyvals); + g_free(maps); + + if ((KeyV >= deadkey_min) && (KeyV <= deadkey_max) ){ // deadkey + dky = (PKMX_WCHAR) (convert_DeadkeyValues_To_U16str((int) KeyV)).c_str(); + *DeadKey = *dky; + return 0xFFFF; + } + else if((KeyV > deadkey_max) || ((KeyV < deadkey_min) && ( KeyV > 0xFF))) // out of range + return 0xFFFE; + else // usable char + return KeyV; +} + +KMX_WCHAR KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD VK_US) { + KMX_DWORD VK_underlying; + for( int i=0; i< (int)All_Vector[0].size()-1 ;i++) { + for( int j=1; j< (int)All_Vector[0][0].size();j++) { + if ( ( All_Vector[0][i][j] == VK_US ) ) { + VK_underlying = All_Vector[1][i][j]; + return VK_underlying; + } + } + } + return VK_US; +} + +KMX_DWORD KMX_get_KeyCodeUnderlying_From_KeyCodeUS(GdkKeymap *keymap, v_dw_3D &All_Vector, KMX_DWORD KC_US, ShiftState ss, int caps) { + KMX_DWORD KC_underlying; + std::u16string u16str = convert_DeadkeyValues_To_U16str(KMX_get_KeyVal_From_KeyCode(keymap, KC_US, ss, caps)); + + for( int i=0; i< (int)All_Vector[1].size()-1 ;i++) { + for( int j=1; j< (int)All_Vector[1][0].size();j++) { + if ( ( All_Vector[1][i][j] == (KMX_DWORD) *u16str.c_str() ) ) { + KC_underlying = All_Vector[1][i][0]; + return KC_underlying; + } + } + } + return KC_US; +} + +UINT KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS) { + return (8 + USVirtualKeyToScanCode[VirtualKeyUS]); +} + +KMX_DWORD KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { + if ( keycode >7) + return (KMX_DWORD) ScanCodeToUSVirtualKey[keycode-8]; + + return 0; +} + +std::u16string CodePointToU16String(unsigned int codepoint) { + std::u16string str; + + if constexpr (sizeof(wchar_t) > 2) { + str = static_cast(codepoint); + } + else if (codepoint <= 0xFFFF) { + str = static_cast(codepoint); + } + else { + codepoint -= 0x10000; + str.resize(2); + str[0] = static_cast(0xD800 + ((codepoint >> 10) & 0x3FF)); + str[1] = static_cast(0xDC00 + (codepoint & 0x3FF)); + } + + return str; +} +*/ + + +//################################################################################################################################################ +//################################################################################################################################################ + std::u16string get_character_From_Keycode(int dk, int ch , int shiftstate) { @@ -40,8 +852,46 @@ std::u16string get_character_From_Keycode(std::vector keyval, int shiftstat return returnString; } +KMX_DWORD get_keyval_From_Keycode(int dk, int ch , int shiftstate) { + + KMX_DWORD character; + std::vector keyvals; + keyvals.push_back(dk); + keyvals.push_back(ch); + + TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); + CFDataRef layout_data = static_cast((TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData))); + const UCKeyboardLayout* keyboard_layout = reinterpret_cast(CFDataGetBytePtr(layout_data)); + + if (layout_data) + character = get_keyval_From_Keycode(keyvals, shiftstate, keyboard_layout); + + return character; +} + +KMX_DWORD get_keyval_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { + + KMX_DWORD in_array[3] = {0,0,0}; + UInt32 deadkeystate = 0; + UniCharCount maxStringlength = 5; + UniCharCount actualStringlength = 0; + UniChar unicodeString[maxStringlength]; + OSStatus status; + int returnint; + + for ( int i =0; i < keyval.size(); i++) { + + status = UCKeyTranslate(keyboard_layout, keyval[i] ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + + if( shiftstate %2 == 1 ) + in_array[i] = (int) unicodeString[0]; // uneven: seperate char -> `e + else + in_array[0] = (int) unicodeString[0]; // even: combine char -> è + } + returnint = in_array[0]*1000 +(int) in_array[1]; + return returnint; +} -//-------------------------- void fun3() {std::cout << "Hier ist fun3 von keymap.cpp...\n";} \ No newline at end of file diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index e2764918e66..7fa8fd42ace 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -1,3 +1,5 @@ + +#pragma once #ifndef KEYMAP_H #define KEYMAP_H @@ -9,13 +11,555 @@ #include #include +#include "u16.h" + std::u16string get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout); std::u16string get_character_From_Keycode(int dk, int ch , int shiftstate); +KMX_DWORD get_keyval_From_Keycode(int dk, int ch , int shiftstate); +KMX_DWORD get_keyval_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout); + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + +// In ths program we use a 3D-Vector Vector[language][Keys][Shiftstates] +/* + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +enum ShiftState { + Base = 0, // 0 + Shft = 1, // 1 + Ctrl = 2, // 2 + ShftCtrl = Shft | Ctrl, // 3 + Menu = 4, // 4 -- NOT USED + ShftMenu = Shft | Menu, // 5 -- NOT USED + MenuCtrl = Menu | Ctrl, // 6 + ShftMenuCtrl = Shft | Menu | Ctrl, // 7 + Xxxx = 8, // 8 + ShftXxxx = Shft | Xxxx, // 9 +}; + +// Map of all US English virtual key codes that we can translate +const KMX_DWORD KMX_VKMap[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + + VK_SPACE, // 32 // + + VK_ACCENT, // 192 VK_OEM_3 K_BKQUOTE // + VK_HYPHEN, // - 189 VK_OEM_MINUS // + VK_EQUAL, // = 187 VK_OEM_PLUS // + + VK_LBRKT, // [ 219 VK_OEM_4 // + VK_RBRKT, // ] 221 VK_OEM_6 // + VK_BKSLASH, // \ 220 VK_OEM_5 // + + VK_COLON, // ; 186 VK_OEM_1 // + VK_QUOTE, // ' 222 VK_OEM_7 // + + VK_COMMA, // , 188 VK_OEM_COMMA // + VK_PERIOD, // . 190 VK_OEM_PERIOD // + VK_SLASH, // / 191 VK_OEM_2 //ˍ + + VK_xDF, // ß (?) 223// + VK_OEM_102, // < > | 226 // + 0 +}; + +typedef std::vector v_str_1D; + +typedef std::vector v_dw_1D; +typedef std::vector > v_dw_2D; +typedef std::vector > > v_dw_3D; + +static KMX_DWORD returnIfCharInvalid = 0; +static KMX_DWORD keycode_max = 94; +static KMX_DWORD deadkey_min = 0xfe50; +static KMX_DWORD deadkey_max = 0xfe93; +//static KMX_DWORD deadkey_max = 0xfe52; // _S2 TOP_6 TODO This has to go! my test: to only return 3 dk + +// map Shiftstate to modifier (e.g. 0->0; 16-1; 9->2; 25->3) +int map_VKShiftState_to_LinModifier(int VKShiftState); + +// take a std::string (=contents of line symbols-file ) and returns the (int) value of the character +KMX_DWORD convertNamesTo_DWORD_Value(std::string tok_str); + +// create a Vector with all entries of both keymaps +int createOneVectorFromBothKeyboards(v_dw_3D &All_Vector,GdkKeymap *keymap); + +// read configuration file, split and write to 3D-Vector (Data for US on Vector[0][ ][ ] ) +int write_US_ToVector(v_dw_3D &vec, std::string language, const char *text); + +// 1. step: read complete Row of Configuration file US +bool createCompleteRow_US(v_str_1D &complete_List, FILE *fpp, const char *text, std::string language); + +// replace Name of Key (e.g. ) wih Keycode ( e.g. 15 ) +int replace_KeyName_with_Keycode(std::string in); + +// 2. step: write contents to 3D vector +int split_US_To_3D_Vector(v_dw_3D &all_US, v_str_1D completeList); + +// create an empty 2D vector containing 0 in all fields +v_dw_2D create_empty_2D_Vector(int dim_rows, int dim_shifts); + +// append characters to 3D-Vector using GDK (Data for underlying Language on Vector[1][ ][ ] ) +int append_underlying_ToVector(v_dw_3D &All_Vector, GdkKeymap *keymap); + +// initialize GDK +bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]); + +//------------------------------ + +const UINT USVirtualKeyToScanCode[256] = { + 0x00, // L"K_?00", // &H0 + 0x00, // L"K_LBUTTON", // &H1 + 0x00, // L"K_RBUTTON", // &H2 + 0x46, // L"K_CANCEL", // &H3 + 0x00, // L"K_MBUTTON", // &H4 + 0x00, // L"K_?05", // &H5 + 0x00, // L"K_?06", // &H6 + 0x00, // L"K_?07", // &H7 + 0x0E, // L"K_BKSP", // &H8 + 0x0F, // L"K_TAB", // &H9 + 0x00, // L"K_?0A", // &HA + 0x00, // L"K_?0B", // &HB + 0x4C, // L"K_KP5", // &HC + 0x1C, // L"K_ENTER", // &HD + 0x00, // L"K_?0E", // &HE + 0x00, // L"K_?0F", // &HF + 0x2A, // L"K_SHIFT", // &H10 + 0x1D, // L"K_CONTRO0x00, // L", // &H11 + 0x38, // L"K_ALT", // &H12 + 0x00, // L"K_PAUSE", // &H13 + 0x3A, // L"K_CAPS", // &H14 + 0x00, // L"K_KANJI?15", // &H15 + 0x00, // L"K_KANJI?16", // &H16 + 0x00, // L"K_KANJI?17", // &H17 + 0x00, // L"K_KANJI?18", // &H18 + 0x00, // L"K_KANJI?19", // &H19 + 0x00, // L"K_?1A", // &H1A + 0x01, // L"K_ESC", // &H1B + 0x00, // L"K_KANJI?1C", // &H1C + 0x00, // L"K_KANJI?1D", // &H1D + 0x00, // L"K_KANJI?1E", // &H1E + 0x00, // L"K_KANJI?1F", // &H1F + 0x39, // L"K_SPACE", // &H20 + 0x49, // L"K_PGUP", // &H21 + 0x51, // L"K_PGDN", // &H22 + 0x4F, // L"K_END", // &H23 + 0x47, // L"K_HOME", // &H24 + 0x4B, // L"K_LEFT", // &H25 + 0x48, // L"K_UP", // &H26 + 0x4D, // L"K_RIGHT", // &H27 + 0x50, // L"K_DOWN", // &H28 + 0x00, // L"K_SEL", // &H29 + 0x00, // L"K_PRINT", // &H2A + 0x00, // L"K_EXEC", // &H2B + 0x54, // L"K_PRTSCN", // &H2C + 0x52, // L"K_INS", // &H2D + 0x53, // L"K_DEL", // &H2E + 0x63, // L"K_HELP", // &H2F + 0x0B, // L"K_0", // &H30 + 0x02, // L"K_1", // &H31 + 0x03, // L"K_2", // &H32 + 0x04, // L"K_3", // &H33 + 0x05, // L"K_4", // &H34 + 0x06, // L"K_5", // &H35 + 0x07, // L"K_6", // &H36 + 0x08, // L"K_7", // &H37 + 0x09, // L"K_8", // &H38 + 0x0A, // L"K_9", // &H39 + 0x00, // L"K_?3A", // &H3A + 0x00, // L"K_?3B", // &H3B + 0x00, // L"K_?3C", // &H3C + 0x00, // L"K_?3D", // &H3D + 0x00, // L"K_?3E", // &H3E + 0x00, // L"K_?3F", // &H3F + 0x00, // L"K_?40", // &H40 + 0x1E, // L"K_A", // &H41 + 0x30, // L"K_B", // &H42 + 0x2E, // L"K_C", // &H43 + 0x20, // L"K_D", // &H44 + 0x12, // L"K_E", // &H45 + 0x21, // L"K_F", // &H46 + 0x22, // L"K_G", // &H47 + 0x23, // L"K_H", // &H48 + 0x17, // L"K_I", // &H49 + 0x24, // L"K_J", // &H4A + 0x25, // L"K_K", // &H4B + 0x26, // L"K_L", // &H4C + 0x32, // L"K_M", // &H4D + 0x31, // L"K_N", // &H4E + 0x18, // L"K_O", // &H4F + 0x19, // L"K_P", // &H50 + 0x10, // L"K_Q", // &H51 + 0x13, // L"K_R", // &H52 + 0x1F, // L"K_S", // &H53 + 0x14, // L"K_T", // &H54 + 0x16, // L"K_U", // &H55 + 0x2F, // L"K_V", // &H56 + 0x11, // L"K_W", // &H57 + 0x2D, // L"K_X", // &H58 + 0x15, // L"K_Y", // &H59 + 0x2C, // L"K_Z", // &H5A + 0x5B, // L"K_?5B", // &H5B + 0x5C, // L"K_?5C", // &H5C + 0x5D, // L"K_?5D", // &H5D + 0x00, // L"K_?5E", // &H5E + 0x5F, // L"K_?5F", // &H5F + 0x52, // L"K_NP0", // &H60 + 0x4F, // L"K_NP1", // &H61 + 0x50, // L"K_NP2", // &H62 + 0x51, // L"K_NP3", // &H63 + 0x4B, // L"K_NP4", // &H64 + 0x4C, // L"K_NP5", // &H65 + 0x4D, // L"K_NP6", // &H66 + 0x47, // L"K_NP7", // &H67 + 0x48, // L"K_NP8", // &H68 + 0x49, // L"K_NP9", // &H69 + 0x37, // L"K_NPSTAR", // &H6A + 0x4E, // L"K_NPPLUS", // &H6B + 0x7E, // L"K_SEPARATOR", // &H6C // MCD 01-11-02: Brazilian Fix, 00 -> 7E + 0x4A, // L"K_NPMINUS", // &H6D + 0x53, // L"K_NPDOT", // &H6E + 0x135, // L"K_NPSLASH", // &H6F + 0x3B, // L"K_F1", // &H70 + 0x3C, // L"K_F2", // &H71 + 0x3D, // L"K_F3", // &H72 + 0x3E, // L"K_F4", // &H73 + 0x3F, // L"K_F5", // &H74 + 0x40, // L"K_F6", // &H75 + 0x41, // L"K_F7", // &H76 + 0x42, // L"K_F8", // &H77 + 0x43, // L"K_F9", // &H78 + 0x44, // L"K_F10", // &H79 + 0x57, // L"K_F11", // &H7A + 0x58, // L"K_F12", // &H7B + 0x64, // L"K_F13", // &H7C + 0x65, // L"K_F14", // &H7D + 0x66, // L"K_F15", // &H7E + 0x67, // L"K_F16", // &H7F + 0x68, // L"K_F17", // &H80 + 0x69, // L"K_F18", // &H81 + 0x6A, // L"K_F19", // &H82 + 0x6B, // L"K_F20", // &H83 + 0x6C, // L"K_F21", // &H84 + 0x6D, // L"K_F22", // &H85 + 0x6E, // L"K_F23", // &H86 + 0x76, // L"K_F24", // &H87 + + 0x00, // L"K_?88", // &H88 + 0x00, // L"K_?89", // &H89 + 0x00, // L"K_?8A", // &H8A + 0x00, // L"K_?8B", // &H8B + 0x00, // L"K_?8C", // &H8C + 0x00, // L"K_?8D", // &H8D + 0x00, // L"K_?8E", // &H8E + 0x00, // L"K_?8F", // &H8F + + 0x45, // L"K_NUMLOCK", // &H90 + 0x46, // L"K_SCROL0x00, // &H91 + + 0x00, // L"K_?92", // &H92 + 0x00, // L"K_?93", // &H93 + 0x00, // L"K_?94", // &H94 + 0x00, // L"K_?95", // &H95 + 0x00, // L"K_?96", // &H96 + 0x00, // L"K_?97", // &H97 + 0x00, // L"K_?98", // &H98 + 0x00, // L"K_?99", // &H99 + 0x00, // L"K_?9A", // &H9A + 0x00, // L"K_?9B", // &H9B + 0x00, // L"K_?9C", // &H9C + 0x00, // L"K_?9D", // &H9D + 0x00, // L"K_?9E", // &H9E + 0x00, // L"K_?9F", // &H9F + 0x2A, // L"K_?A0", // &HA0 + 0x36, // L"K_?A1", // &HA1 + 0x1D, // L"K_?A2", // &HA2 + 0x1D, // L"K_?A3", // &HA3 + 0x38, // L"K_?A4", // &HA4 + 0x38, // L"K_?A5", // &HA5 + 0x6A, // L"K_?A6", // &HA6 + 0x69, // L"K_?A7", // &HA7 + 0x67, // L"K_?A8", // &HA8 + 0x68, // L"K_?A9", // &HA9 + 0x65, // L"K_?AA", // &HAA + 0x66, // L"K_?AB", // &HAB + 0x32, // L"K_?AC", // &HAC + 0x20, // L"K_?AD", // &HAD + 0x2E, // L"K_?AE", // &HAE + 0x30, // L"K_?AF", // &HAF + 0x19, // L"K_?B0", // &HB0 + 0x10, // L"K_?B1", // &HB1 + 0x24, // L"K_?B2", // &HB2 + 0x22, // L"K_?B3", // &HB3 + 0x6C, // L"K_?B4", // &HB4 + 0x6D, // L"K_?B5", // &HB5 + 0x6B, // L"K_?B6", // &HB6 + 0x21, // L"K_?B7", // &HB7 + 0x00, // L"K_?B8", // &HB8 + 0x00, // L"K_?B9", // &HB9 + 0x27, // L"K_COLON", // &HBA + 0x0D, // L"K_EQUA0x00, // L", // &HBB + 0x33, // L"K_COMMA", // &HBC + 0x0C, // L"K_HYPHEN", // &HBD + 0x34, // L"K_PERIOD", // &HBE + 0x35, // L"K_SLASH", // &HBF + 0x29, // L"K_BKQUOTE", // &HC0 + + 0x73, // L"K_?C1", // &HC1 + 0x7E, // L"K_?C2", // &HC2 + 0x00, // L"K_?C3", // &HC3 + 0x00, // L"K_?C4", // &HC4 + 0x00, // L"K_?C5", // &HC5 + 0x00, // L"K_?C6", // &HC6 + 0x00, // L"K_?C7", // &HC7 + 0x00, // L"K_?C8", // &HC8 + 0x00, // L"K_?C9", // &HC9 + 0x00, // L"K_?CA", // &HCA + 0x00, // L"K_?CB", // &HCB + 0x00, // L"K_?CC", // &HCC + 0x00, // L"K_?CD", // &HCD + 0x00, // L"K_?CE", // &HCE + 0x00, // L"K_?CF", // &HCF + 0x00, // L"K_?D0", // &HD0 + 0x00, // L"K_?D1", // &HD1 + 0x00, // L"K_?D2", // &HD2 + 0x00, // L"K_?D3", // &HD3 + 0x00, // L"K_?D4", // &HD4 + 0x00, // L"K_?D5", // &HD5 + 0x00, // L"K_?D6", // &HD6 + 0x00, // L"K_?D7", // &HD7 + 0x00, // L"K_?D8", // &HD8 + 0x00, // L"K_?D9", // &HD9 + 0x00, // L"K_?DA", // &HDA + 0x1A, // L"K_LBRKT", // &HDB + 0x2B, // L"K_BKSLASH", // &HDC + 0x1B, // L"K_RBRKT", // &HDD + 0x28, // L"K_QUOTE", // &HDE + 0x73, // L"K_oDF", // &HDF // MCD 01-11-02: Brazilian fix: 00 -> 73 + 0x00, // L"K_oE0", // &HE0 + 0x00, // L"K_oE1", // &HE1 + 0x56, // L"K_oE2", // &HE2 + 0x00, // L"K_oE3", // &HE3 + 0x00, // L"K_oE4", // &HE4 + + 0x00, // L"K_?E5", // &HE5 + + 0x00, // L"K_oE6", // &HE6 + + 0x00, // L"K_?E7", // &HE7 + 0x00, // L"K_?E8", // &HE8 + + 0x71, // L"K_oE9", // &HE9 + 0x5C, // L"K_oEA", // &HEA + 0x7B, // L"K_oEB", // &HEB + 0x00, // L"K_oEC", // &HEC + 0x6F, // L"K_oED", // &HED + 0x5A, // L"K_oEE", // &HEE + 0x00, // L"K_oEF", // &HEF + 0x00, // L"K_oF0", // &HF0 + 0x5B, // L"K_oF1", // &HF1 + 0x00, // L"K_oF2", // &HF2 + 0x5F, // L"K_oF3", // &HF3 + 0x00, // L"K_oF4", // &HF4 + 0x5E, // L"K_oF5", // &HF5 + + 0x00, // L"K_?F6", // &HF6 + 0x00, // L"K_?F7", // &HF7 + 0x00, // L"K_?F8", // &HF8 + 0x5D, // L"K_?F9", // &HF9 + 0x00, // L"K_?FA", // &HFA + 0x62, // L"K_?FB", // &HFB + 0x00, // L"K_?FC", // &HFC + 0x00, // L"K_?FD", // &HFD + 0x00, // L"K_?FE", // &HFE + 0x00 // L"K_?FF" // &HFF +}; + +const UINT ScanCodeToUSVirtualKey[128] = { + 0x01, // 0x00 => K_LBUTTON + 0x1b, // 0x01 => K_ESC + 0x31, // 0x02 => K_1 + 0x32, // 0x03 => K_2 + 0x33, // 0x04 => K_3 + 0x34, // 0x05 => K_4 + 0x35, // 0x06 => K_5 + 0x36, // 0x07 => K_6 + 0x37, // 0x08 => K_7 + 0x38, // 0x09 => K_8 + 0x39, // 0x0a => K_9 + 0x30, // 0x0b => K_0 + 0xbd, // 0x0c => K_HYPHEN + 0xbb, // 0x0d => K_EQUAL + 0x08, // 0x0e => K_BKSP + 0x09, // 0x0f => K_TAB + 0x51, // 0x10 => K_Q + 0x57, // 0x11 => K_W + 0x45, // 0x12 => K_E + 0x52, // 0x13 => K_R + 0x54, // 0x14 => K_T 20 + 0x59, // 0x15 => K_Y + 0x55, // 0x16 => K_U + 0x49, // 0x17 => K_I + 0x4f, // 0x18 => K_O + 0x50, // 0x19 => K_P + 0xdb, // 0x1a => K_LBRKT + 0xdd, // 0x1b => K_RBRKT + 0x0d, // 0x1c => K_ENTER + 0x11, // 0x1d => K_CONTROL + 0x41, // 0x1e => K_A + 0x53, // 0x1f => K_S + 0x44, // 0x20 => K_D + 0x46, // 0x21 => K_F + 0x47, // 0x22 => K_G + 0x48, // 0x23 => K_H + 0x4a, // 0x24 => K_J + 0x4b, // 0x25 => K_K + 0x4c, // 0x26 => K_L + 0xba, // 0x27 => K_COLON 39 + 0xde, // 0x28 => K_QUOTE + 0xc0, // 0x29 => K_BKQUOTE + 0x10, // 0x2a => K_SHIFT + 0xdc, // 0x2b => K_BKSLASH + 0x5a, // 0x2c => K_Z + 0x58, // 0x2d => K_X + 0x43, // 0x2e => K_C + 0x56, // 0x2f => K_V + 0x42, // 0x30 => K_B + 0x4e, // 0x31 => K_N + 0x4d, // 0x32 => K_M + 0xbc, // 0x33 => K_COMMA + 0xbe, // 0x34 => K_PERIOD + 0xbf, // 0x35 => K_SLASH + 0xa1, // 0x36 => K_?A1 + 0x6a, // 0x37 => K_NPSTAR + 0x12, // 0x38 => K_ALT + 0x20, // 0x39 => K_SPACE + 0x14, // 0x3a => K_CAPS + 0x70, // 0x3b => K_F1 59 + 0x71, // 0x3c => K_F2 + 0x72, // 0x3d => K_F3 + 0x73, // 0x3e => K_F4 + 0x74, // 0x3f => K_F5 + 0x75, // 0x40 => K_F6 + 0x76, // 0x41 => K_F7 + 0x77, // 0x42 => K_F8 + 0x78, // 0x43 => K_F9 + 0x79, // 0x44 => K_F10 + 0x90, // 0x45 => K_NUMLOCK + 0x03, // 0x46 => K_CANCEL + 0x24, // 0x47 => K_HOME + 0x26, // 0x48 => K_UP + 0x21, // 0x49 => K_PGUP + 0x6d, // 0x4a => K_NPMINUS + 0x25, // 0x4b => K_LEFT + 0x0c, // 0x4c => K_KP5 + 0x27, // 0x4d => K_RIGHT + 0x6b, // 0x4e => K_NPPLUS + 0x23, // 0x4f => K_END + 0x28, // 0x50 => K_DOWN + 0x22, // 0x51 => K_PGDN + 0x2d, // 0x52 => K_INS + 0x2e, // 0x53 => K_DEL + 0x2c, // 0x54 => K_PRTSCN + 0x00, // 0x55 => No match + 0xe2, // 0x56 => K_oE2 + 0x7a, // 0x57 => K_F11 + 0x7b, // 0x58 => K_F12 + 0x00, // 0x59 => No match + 0xee, // 0x5a => K_oEE + 0x5b, // 0x5b => K_?5B + 0x5c, // 0x5c => K_?5C + 0x5d, // 0x5d => K_?5D + 0xf5, // 0x5e => K_oF5 + 0x5f, // 0x5f => K_?5F + 0x00, // 0x60 => No match + 0x00, // 0x61 => No match + 0xfb, // 0x62 => K_?FB + 0x2f, // 0x63 => K_HELP + 0x7c, // 0x64 => K_F13 + 0x7d, // 0x65 => K_F14 + 0x7e, // 0x66 => K_F15 + 0x7f, // 0x67 => K_F16 + 0x80, // 0x68 => K_F17 + 0x81, // 0x69 => K_F18 + 0x82, // 0x6a => K_F19 + 0x83, // 0x6b => K_F20 + 0x84, // 0x6c => K_F21 + 0x85, // 0x6d => K_F22 + 0x86, // 0x6e => K_F23 + 0xed, // 0x6f => K_oED + 0x00, // 0x70 => No match + 0xe9, // 0x71 => K_oE9 + 0x00, // 0x72 => No match + 0xc1, // 0x73 => K_?C1 + 0x00, // 0x74 => No match + 0x00, // 0x75 => No match + 0x87, // 0x76 => K_F24 + 0x00, // 0x77 => No match + 0x00, // 0x78 => No match + 0x00, // 0x79 => No match + 0x00, // 0x7a => No match + 0xeb, // 0x7b => K_oEB + 0x00, // 0x7c => No match + 0x00, // 0x7d => No match + 0x6c, // 0x7e => K_SEPARATOR + 0x00 // 0x7f => No match +}; + +bool IsKeymanUsedChar(int KV); +//------------------------------ +// take deadkey-value (e.g.65106) and return u16string (e.g. '^' ) +std::u16string convert_DeadkeyValues_To_U16str(int in); + +// use gdk_keymap_translate_keyboard_state to get keyval - base function to get keyvals +int KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps); + +// use KMX_get_KeyVal_From_KeyCode and prevent use of certain keycodes +KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, guint keycode, int shift_state_pos); + +// fill Deadkey with dk and return CATEGORY +KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey); + +// use Vector to return the Keyval of underlying Keyboard +KMX_WCHAR KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D &All_Vector,KMX_DWORD VK_underlying); + +// use Vector to return the Keycode of the underlying Keyboard for given VK_US using GDK +KMX_DWORD KMX_get_KeyCodeUnderlying_From_KeyCodeUS(GdkKeymap *keymap, v_dw_3D &All_Vector,KMX_DWORD KC_US, ShiftState ss, int caps); + +// return the Keycode of the underlying Keyboard for given VK_US +UINT KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS); + +// return the VirtualKey of the US Keyboard for a given Keyode using GDK +KMX_DWORD KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); + +// convert codePoint to u16string +std::u16string CodePointToU16String(unsigned int codepoint); + +# endif// //KEYMAP_H*/ + + + +//################################################################################################################################################ +//################################################################################################################################################ -//-------------------------- void fun3(); #endif // KEYMAP_H \ No newline at end of file diff --git a/mac/mcompile/km_types.h b/mac/mcompile/km_types.h new file mode 100755 index 00000000000..531bb2ccc06 --- /dev/null +++ b/mac/mcompile/km_types.h @@ -0,0 +1,120 @@ + + +#pragma once +#ifndef KM_TYPES +#define KM_TYPES + +#include + +/* +#if defined(_WIN32) || defined(_WIN64) +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#define strcasecmp _stricmp +#define strncasecmp _strnicmp +#endif +*/ + +#if defined(__LP64__) || defined(_LP64) +/* 64-bit, g++ */ +#define KMX_64BIT +#endif + +#if defined(_WIN64) && !defined(USE_64) +/* 64-bit, Windows */ +#define KMX_64BIT +#endif + +typedef uint32_t KMX_DWORD; +typedef int32_t KMX_BOOL; +typedef uint8_t KMX_BYTE; +typedef uint16_t KMX_WORD; + +#if defined(__cplusplus) +typedef char16_t km_kbp_cp; +typedef char32_t km_kbp_usv; +#else +typedef uint16_t km_kbp_cp; // code point +typedef uint32_t km_kbp_usv; // Unicode Scalar Value +#endif + +typedef unsigned int UINT; +typedef unsigned long DWORD; + +typedef unsigned char BYTE; +typedef char KMX_CHAR; + +typedef char16_t KMX_WCHAR; +typedef KMX_WCHAR* PKMX_WCHAR; + +typedef wchar_t WCHAR; +typedef WCHAR KMX_WCHART; +typedef wchar_t* PWSTR; +typedef WCHAR* PWCHAR; + +typedef uint8_t* LPKMX_BYTE; +typedef uint8_t* PKMX_BYTE; + +typedef KMX_BYTE* PKMX_BYTE; +typedef KMX_DWORD* PKMX_DWORD; +typedef int BOOL; + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +// Macros and types to support char16_t vs wchar_t depending on project + +#ifdef USE_CHAR16_T +#define lpuch(x) u ## x +typedef km_kbp_cp KMX_UCHAR; +#else +#define lpuch(x) L ## x +typedef wchar_t KMX_UCHAR; +#endif + +typedef KMX_UCHAR* KMX_PUCHAR; + +#define VK_SPACE 0x20 +#define VK_COLON 0xBA +#define VK_EQUAL 0xBB +#define VK_COMMA 0xBC +#define VK_HYPHEN 0xBD +#define VK_PERIOD 0xBE +#define VK_SLASH 0xBF +#define VK_ACCENT 0xC0 +#define VK_LBRKT 0xDB +#define VK_BKSLASH 0xDC +#define VK_RBRKT 0xDD +#define VK_QUOTE 0xDE +#define VK_xDF 0xDF +#define VK_OEM_102 0xE2 // "<>" or "\|" on RT 102-key kbd. + +#define VK_DIVIDE 0x6F +#define VK_CANCEL 3 +#define VK_DECIMAL 0x2E + +#define VK_OEM_CLEAR 0xFE +#define VK_LSHIFT 0xA0 +#define VK_RSHIFT 0xA1 +#define VK_LCONTROL 0xA2 +#define VK_RCONTROL 0xA3 +#define VK_LMENU 0xA4 +#define VK_RMENU 0xA5 + +#define VK_SHIFT 0x10 +#define VK_CONTROL 0x11 +#define VK_MENU 0x12 +#define VK_PAUSE 0x13 +#define VK_CAPITAL 0x14 + +#endif /*KM_TYPES*/ + + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ diff --git a/mac/mcompile/kmx_file.h b/mac/mcompile/kmx_file.h new file mode 100755 index 00000000000..e18b0022602 --- /dev/null +++ b/mac/mcompile/kmx_file.h @@ -0,0 +1,393 @@ + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + +/* + Copyright: Copyright (C) 2003-2018 SIL International. + Authors: mcdurdin +*/ +/* +#pragma once +#ifndef KMX_FILE_H +#define KMX_FILE_H + +#define UNREFERENCED_PARAMETER(P) (P) +#define TRUNCATE ((size_t)-1) +#ifdef KMN_KBP +// TODO: move this to a common namespace keyman::common::kmx_file or similar in the future +namespace km { +namespace kbp { +namespace kmx { +#endif + +#define KMX_MAX_ALLOWED_FILE_SIZE (128 * 1024 * 1024) // 128MB // + +#define KEYMAN_LAYOUT_DEFAULT 0x000005FE + +#define KEYMANID_NONKEYMAN 0xFFFFFFFF +#define KEYMANID_IGNORE 0xFFFFFFFE +#define KEYMANID_INVALID 0xFFFFFFFD + +// Shift flags for hotkeys (version 1.0) // + +#define SHIFTFLAG 0x2000 +#define CTRLFLAG 0x4000 +#define ALTFLAG 0x8000 + +// Miscellaneous flags and defines // + +#define MAXGROUPS 128 + +// File version identifiers // + +#define VERSION_30 0x00000300 +#define VERSION_31 0x00000301 +#define VERSION_32 0x00000302 +#define VERSION_40 0x00000400 +#define VERSION_50 0x00000500 +#define VERSION_501 0x00000501 +#define VERSION_60 0x00000600 +#define VERSION_70 0x00000700 +#define VERSION_80 0x00000800 +#define VERSION_90 0x00000900 +#define VERSION_100 0x00000A00 +#define VERSION_140 0x00000E00 +#define VERSION_150 0x00000F00 + +#define VERSION_160 0x00001000 + +#define VERSION_MIN VERSION_50 +#define VERSION_MAX VERSION_160 + +// +// Backspace types +// + +#define BK_DEFAULT 0 +#define BK_DEADKEY 1 + +// Different begin types +#define BEGIN_ANSI 0 +#define BEGIN_UNICODE 1 +#define BEGIN_NEWCONTEXT 2 +#define BEGIN_POSTKEYSTROKE 3 + +#define TSS_NONE 0 +#define TSS_BITMAP 1 +#define TSS_COPYRIGHT 2 +#define TSS_HOTKEY 3 +#define TSS_LANGUAGE 4 +#define TSS_LAYOUT 5 +#define TSS_MESSAGE 6 +#define TSS_NAME 7 +#define TSS_VERSION 8 +#define TSS_CAPSONONLY 9 +#define TSS_CAPSALWAYSOFF 10 +#define TSS_SHIFTFREESCAPS 11 +#define TSS_LANGUAGENAME 12 + +#define TSS_CALLDEFINITION 13 +#define TSS_CALLDEFINITION_LOADFAILED 14 + +#define TSS_ETHNOLOGUECODE 15 + +#define TSS_DEBUG_LINE 16 + +#define TSS_MNEMONIC 17 + +#define TSS_INCLUDECODES 18 + +#define TSS_OLDCHARPOSMATCHING 19 + +#define TSS_COMPILEDVERSION 20 +#define TSS_KEYMANCOPYRIGHT 21 + +#define TSS_CUSTOMKEYMANEDITION 22 +#define TSS_CUSTOMKEYMANEDITIONNAME 23 + +// Keyman 7.0 system stores // + +#define TSS__KEYMAN_60_MAX 23 + +#define TSS_VISUALKEYBOARD 24 +#define TSS_KMW_RTL 25 +#define TSS_KMW_HELPFILE 26 +#define TSS_KMW_HELPTEXT 27 +#define TSS_KMW_EMBEDJS 28 + +#define TSS_WINDOWSLANGUAGES 29 + +#define TSS__KEYMAN_70_MAX 29 + +// Keyman 8.0 system stores // + +#define TSS_COMPARISON 30 + +#define TSS__KEYMAN_80_MAX 30 + +// Keyman 9.0 system stores // + +#define TSS_PLATFORM 31 +#define TSS_BASELAYOUT 32 +#define TSS_LAYER 33 + +#define TSS_PLATFORM_NOMATCH 0x8001 // Reserved for internal use - after platform statement is run, set to either TSS_PLATFORM_NOMATCH or TSS_PLATFORM_MATCH +#define TSS_PLATFORM_MATCH 0x8002 // Reserved for internal use - as the result will never change for the lifetime of the process. + +#define TSS_VKDICTIONARY 34 // Dictionary of virtual key names for v9 dynamic layouts +#define TSS_LAYOUTFILE 35 // Keyman 9 layer-based JSON OSK +#define TSS_KEYBOARDVERSION 36 // &keyboardversion system store // I4140 +#define TSS_KMW_EMBEDCSS 37 + +#define TSS_TARGETS 38 + +#define TSS__KEYMAN_90_MAX 38 + +// Keyman 14.0 system stores // + +#define TSS_CASEDKEYS 39 + +#define TSS__KEYMAN_140_MAX 39 + +// Keyman 15.0 system stores // + +#define TSS_BEGIN_NEWCONTEXT 40 +#define TSS_BEGIN_POSTKEYSTROKE 41 +#define TSS_NEWLAYER 42 +#define TSS_OLDLAYER 43 + +#define TSS__KEYMAN_150_MAX 43 + +#define TSS__MAX 43 + +// wm_keyman_control_internal message control codes // + +#define KMCI_SELECTKEYBOARD 3 // I3933 +#define KMCI_SELECTKEYBOARD_TSF 4 // I3933 +#define KMCI_GETACTIVEKEYBOARD 5 // I3933 +#define KMCI_SETFOREGROUND 6 // I3933 +#define KMCI_SELECTKEYBOARD_BACKGROUND 7 // I4271 +#define KMCI_SELECTKEYBOARD_BACKGROUND_TSF 8 // I4271 + +#define FILEID_COMPILED 0x5354584B + +#define SZMAX_LANGUAGENAME 80 +#define SZMAX_KEYBOARDNAME 80 +#define SZMAX_COPYRIGHT 256 +#define SZMAX_MESSAGE 1024 + +#define UC_SENTINEL 0xFFFF +#define UC_SENTINEL_EXTENDEDEND 0x10 // was ((CODE_LASTCODE)+1)... what was I thinking? + +#define U_UC_SENTINEL u"\uFFFF" + +// + * VK__MAX defines the highest virtual key code defined in the system = 0xFF. Custom VK codes start at 256 + // +#define VK__MAX 255 + +#define CODE_ANY 0x01 +#define CODE_INDEX 0x02 +#define CODE_CONTEXT 0x03 +#define CODE_NUL 0x04 +#define CODE_USE 0x05 +#define CODE_RETURN 0x06 +#define CODE_BEEP 0x07 +#define CODE_DEADKEY 0x08 +// 0x09 = bkspace.-- we don't need to keep this separate though with UC_SENTINEL +#define CODE_EXTENDED 0x0A +//#define CODE_EXTENDEDEND 0x0B deprecated +#define CODE_SWITCH 0x0C +#define CODE_KEY 0x0D +#define CODE_CLEARCONTEXT 0x0E +#define CODE_CALL 0x0F +// UC_SENTINEL_EXTENDEDEND 0x10 +#define CODE_CONTEXTEX 0x11 + +#define CODE_NOTANY 0x12 + +#define CODE_KEYMAN70_LASTCODE 0x12 + +#define CODE_SETOPT 0x13 +#define CODE_IFOPT 0x14 +#define CODE_SAVEOPT 0x15 +#define CODE_RESETOPT 0x16 + +#define CODE_KEYMAN80_LASTCODE 0x16 + +// Keyman 9.0 codes // + +#define CODE_IFSYSTEMSTORE 0x17 +#define CODE_SETSYSTEMSTORE 0x18 + +#define CODE_LASTCODE 0x18 + +#define U_CODE_ANY u"\u0001" +#define U_CODE_INDEX u"\u0002" +#define U_CODE_CONTEXT u"\u0003" +#define U_CODE_NUL u"\u0004" +#define U_CODE_USE u"\u0005" +#define U_CODE_RETURN u"\u0006" +#define U_CODE_BEEP u"\u0007" +#define U_CODE_DEADKEY u"\u0008" +#define U_CODE_EXTENDED u"\u000A" +#define U_CODE_SWITCH u"\u000C" +#define U_CODE_CLEARCONTEXT u"\u000E" +#define U_CODE_CALL u"\u000F" +#define U_CODE_EXTENDEDEND u"\u0010" +#define U_CODE_CONTEXTEX u"\u0011" +#define U_CODE_NOTANY u"\u0012" +#define U_CODE_SETOPT u"\u0013" +#define U_CODE_IFOPT u"\u0014" +#define U_CODE_SAVEOPT u"\u0015" +#define U_CODE_RESETOPT u"\u0016" +#define U_CODE_IFSYSTEMSTORE u"\u0017" +#define U_CODE_SETSYSTEMSTORE u"\u0018" + +#define C_CODE_ANY(store) U_UC_SENTINEL U_CODE_ANY store +#define C_CODE_INDEX(val1, val2) U_UC_SENTINEL U_CODE_INDEX val1 val2 +#define C_CODE_CONTEXT() U_UC_SENTINEL U_CODE_CONTEXT +#define C_CODE_NUL() U_UC_SENTINEL U_CODE_NUL +#define C_CODE_USE(val) U_UC_SENTINEL U_CODE_USE val +#define C_CODE_RETURN() U_UC_SENTINEL U_CODE_RETURN +#define C_CODE_BEEP() U_UC_SENTINEL U_CODE_BEEP +#define C_CODE_DEADKEY(deadkey) U_UC_SENTINEL U_CODE_DEADKEY deadkey +#define C_CODE_EXTENDED(varargs) U_UC_SENTINEL U_CODE_EXTENDED varargs +#define C_CODE_SWITCH(val) U_UC_SENTINEL U_CODE_SWITCH val +#define C_CODE_CLEARCONTEXT() U_UC_SENTINEL U_CODE_CLEARCONTEXT +#define C_CODE_CALL(val) U_UC_SENTINEL U_CODE_CALL val +#define C_CODE_CONTEXTEX(val) U_UC_SENTINEL U_CODE_CONTEXTEX val +#define C_CODE_NOTANY(val) U_UC_SENTINEL U_CODE_NOTANY val +#define C_CODE_SETOPT(val1, val2) U_UC_SENTINEL U_CODE_SETOPT val1 val2 +#define C_CODE_IFOPT(opt, val1, val2) U_UC_SENTINEL U_CODE_IFOPT opt val1 val2 +#define C_CODE_SAVEOPT(opt) U_UC_SENTINEL U_CODE_SAVEOPT opt +#define C_CODE_RESETOPT(opt) U_UC_SENTINEL U_CODE_RESETOPT opt +#define C_CODE_IFSYSTEMSTORE(store, val1, val2) U_UC_SENTINEL U_CODE_IFSYSTEMSTORE store val1 val2 +#define C_CODE_SETSYSTEMSTORE(store, val) U_UC_SENTINEL U_CODE_SETSYSTEMSTORE store val + +#define KF_SHIFTFREESCAPS 0x0001 +#define KF_CAPSONONLY 0x0002 +#define KF_CAPSALWAYSOFF 0x0004 +#define KF_LOGICALLAYOUT 0x0008 +#define KF_AUTOMATICVERSION 0x0010 + +// 16.0: Support for LDML Keyboards in KMXPlus file format +#define KF_KMXPLUS 0x0020 + +#define HK_ALT 0x00010000 +#define HK_CTRL 0x00020000 +#define HK_SHIFT 0x00040000 + +#define LCTRLFLAG 0x0001 // Left Control flag +#define RCTRLFLAG 0x0002 // Right Control flag +#define LALTFLAG 0x0004 // Left Alt flag +#define RALTFLAG 0x0008 // Right Alt flag +#define K_SHIFTFLAG 0x0010 // Either shift flag +#define K_CTRLFLAG 0x0020 // Either ctrl flag +#define K_ALTFLAG 0x0040 // Either alt flag +//#define K_METAFLAG 0x0080 // Either Meta-key flag (tentative). Not usable in keyboard rules; + // Used internally (currently, only by KMW) to ensure Meta-key + // shortcuts safely bypass rules + // Meta key = Command key on macOS, Windows key on Windows +#define CAPITALFLAG 0x0100 // Caps lock on +#define NOTCAPITALFLAG 0x0200 // Caps lock NOT on +#define NUMLOCKFLAG 0x0400 // Num lock on +#define NOTNUMLOCKFLAG 0x0800 // Num lock NOT on +#define SCROLLFLAG 0x1000 // Scroll lock on +#define NOTSCROLLFLAG 0x2000 // Scroll lock NOT on +#define ISVIRTUALKEY 0x4000 // It is a Virtual Key Sequence +#define VIRTUALCHARKEY 0x8000 // Keyman 6.0: Virtual Key Cap Sequence NOT YET + +#define K_MODIFIERFLAG 0x007F +#define K_NOTMODIFIERFLAG 0xFF00 // I4548 + +struct KMX_COMP_STORE { + KMX_DWORD dwSystemID; + KMX_DWORD dpName; + KMX_DWORD dpString; + }; + +struct KMX_COMP_KEY { + KMX_WORD Key; + KMX_WORD _reserved; + KMX_DWORD Line; + KMX_DWORD ShiftFlags; + KMX_DWORD dpOutput; + KMX_DWORD dpContext; + }; + + +struct KMX_COMP_GROUP { + KMX_DWORD dpName; + KMX_DWORD dpKeyArray; // [LPKEY] address of first item in key array + KMX_DWORD dpMatch; + KMX_DWORD dpNoMatch; + KMX_DWORD cxKeyArray; // in array entries + KMX_BOOL fUsingKeys; // group(xx) [using keys] <-- specified or not + }; + +struct KMX_COMP_KEYBOARD { + KMX_DWORD dwIdentifier; // 0000 Keyman compiled keyboard id + + KMX_DWORD dwFileVersion; // 0004 Version of the file - Keyman 4.0 is 0x0400 + + KMX_DWORD dwCheckSum; // 0008 As stored in keyboard. DEPRECATED as of 16.0 + KMX_DWORD KeyboardID; // 000C as stored in HKEY_LOCAL_MACHINE//system//currentcontrolset//control//keyboard layouts + KMX_DWORD IsRegistered; // 0010 + KMX_DWORD version; // 0014 keyboard version + + KMX_DWORD cxStoreArray; // 0018 in array entries + KMX_DWORD cxGroupArray; // 001C in array entries + + KMX_DWORD dpStoreArray; // 0020 [LPSTORE] address of first item in store array + KMX_DWORD dpGroupArray; // 0024 [LPGROUP] address of first item in group array + + KMX_DWORD StartGroup[2]; // 0028 index of starting groups [2 of them] + + KMX_DWORD dwFlags; // 0030 Flags for the keyboard file + + KMX_DWORD dwHotKey; // 0034 standard windows hotkey (hiword=shift/ctrl/alt stuff, loword=vkey) + + KMX_DWORD dpBitmapOffset; // 0038 offset of the bitmaps in the file + KMX_DWORD dwBitmapSize; // 003C size in bytes of the bitmaps +}; + +struct KMX_COMP_KEYBOARD_KMXPLUSINFO { + KMX_DWORD dpKMXPlus; // 0040 offset of KMXPlus data, header is first + KMX_DWORD dwKMXPlusSize; // 0044 size in bytes of entire KMXPlus data +}; + +// + * Only valid if comp_keyboard.dwFlags&KF_KMXPLUS + // +struct KMX_COMP_KEYBOARD_EX { + KMX_COMP_KEYBOARD header; // 0000 see COMP_KEYBOARD + KMX_COMP_KEYBOARD_KMXPLUSINFO kmxplus; // 0040 see COMP_KEYBOARD_EXTRA +}; + +typedef KMX_COMP_KEYBOARD *PKMX_COMP_KEYBOARD; +typedef KMX_COMP_STORE *PKMX_COMP_STORE; +typedef KMX_COMP_KEY *PKMX_COMP_KEY; +typedef KMX_COMP_GROUP *PKMX_COMP_GROUP; + + +extern const int CODE__SIZE[]; +#define CODE__SIZE_MAX 5 + +#define KEYBOARDFILEHEADER_SIZE 64 +#define KEYBOARDFILESTORE_SIZE 12 +#define KEYBOARDFILEGROUP_SIZE 24 +#define KEYBOARDFILEKEY_SIZE 20 + +static_assert(sizeof(KMX_COMP_STORE) == KEYBOARDFILESTORE_SIZE, "COMP_STORE must be KEYBOARDFILESTORE_SIZE bytes"); +static_assert(sizeof(KMX_COMP_KEY) == KEYBOARDFILEKEY_SIZE, "COMP_KEY must be KEYBOARDFILEKEY_SIZE bytes"); +static_assert(sizeof(KMX_COMP_GROUP) == KEYBOARDFILEGROUP_SIZE, "COMP_GROUP must be KEYBOARDFILEGROUP_SIZE bytes"); +static_assert(sizeof(KMX_COMP_KEYBOARD) == KEYBOARDFILEHEADER_SIZE, "COMP_KEYBOARD must be KEYBOARDFILEHEADER_SIZE bytes"); + +#ifdef KMN_KBP +} // namespace kmx +} // namespace kbp +} // namespace km +#endif +#endif*/ /*KMX_FILE_H*/ diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp new file mode 100755 index 00000000000..5f52c64bac3 --- /dev/null +++ b/mac/mcompile/mc_import_rules.cpp @@ -0,0 +1,658 @@ + + +/* + Name: mc_import_rules + Copyright: Copyright (C) SIL International. + Documentation: + Description: + Create Date: 3 Aug 2014 + + Modified Date: 6 Feb 2015 + Authors: mcdurdin + Related Files: + Dependencies: + + Bugs: + Todo: + Notes: + History: 03 Aug 2014 - mcdurdin - I4327 - V9.0 - Mnemonic layout compiler follow-up + 03 Aug 2014 - mcdurdin - I4353 - V9.0 - mnemonic layout recompiler mixes up deadkey rules + 31 Dec 2014 - mcdurdin - I4550 - V9.0 - logical flaw in mnemonic layout recompiler means that AltGr base keys are never processed + 06 Feb 2015 - mcdurdin - I4552 - V9.0 - Add mnemonic recompile option to ignore deadkeys +*/ + +#include +#include +#include +//#include "km_types.h" +#include "mc_kmxfile.h" +#include "keymap.h" + +/*//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + +const int KMX_ShiftStateMap[] = { + ISVIRTUALKEY, + ISVIRTUALKEY | K_SHIFTFLAG, + ISVIRTUALKEY | K_CTRLFLAG, + ISVIRTUALKEY | K_SHIFTFLAG | K_CTRLFLAG, + 0, + 0, + ISVIRTUALKEY | RALTFLAG, + ISVIRTUALKEY | RALTFLAG | K_SHIFTFLAG, + 0, + 0 +}; + +DeadKey::DeadKey(KMX_WCHAR deadCharacter) { + this->m_deadchar = deadCharacter; +} + +KMX_WCHAR DeadKey::KMX_DeadCharacter() { + return this->m_deadchar; +} + +void DeadKey::KMX_AddDeadKeyRow(KMX_WCHAR baseCharacter, KMX_WCHAR combinedCharacter) { + this->m_rgbasechar.push_back(baseCharacter); + this->m_rgcombchar.push_back(combinedCharacter); +} + +bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { + std::vector::iterator it; + for(it=this->m_rgbasechar.begin(); it= deadkey_min) && (KeyVal <= deadkey_max)) // deadkeys + return -1; + else if(gdk_keyval_to_unicode(KeyVal) == 0) // NO UNICODE + return 0; + else // usable char + return 1; +} + +int KMX_DeadKeyMap(int index, std::vector *deadkeys, int deadkeyBase, std::vector *deadkeyMappings) { // I4327 // I4353 + for(size_t i = 0; i < deadkeyMappings->size(); i++) { + if((*deadkeyMappings)[i].deadkey == index) { + return (*deadkeyMappings)[i].dkid; + } + } + + for(size_t i = 0; i < deadkeys->size(); i++) { + if((*deadkeys)[i]->KMX_DeadCharacter() == index) { + return deadkeyBase + i; + } + } + return 0xFFFF; +} + +class KMX_VirtualKey { +private: + UINT m_vk; + UINT m_sc; + bool m_rgfDeadKey[10][2]; + std::u16string m_rgss[10][2]; + +public: + + KMX_VirtualKey(UINT scanCode) { + this->m_vk = KMX_get_VKUS_From_KeyCodeUnderlying(scanCode); + this->m_sc = scanCode; + memset(this->m_rgfDeadKey,0,sizeof(this->m_rgfDeadKey)); + } + + UINT VK() { + return this->m_vk; + } + + UINT SC() { + return this->m_sc; + } + + std::u16string KMX_GetShiftState(ShiftState shiftState, bool capsLock) { + return this->m_rgss[(UINT)shiftState][(capsLock ? 1 : 0)]; + } + + void KMX_SetShiftState(ShiftState shiftState, std::u16string value, bool isDeadKey, bool capsLock) { + this->m_rgfDeadKey[(UINT)shiftState][(capsLock ? 1 : 0)] = isDeadKey; + this->m_rgss[(UINT)shiftState][(capsLock ? 1 : 0)] = value; + } + + bool KMX_IsSGCAPS() { + std::u16string stBase = this->KMX_GetShiftState(Base, false); + std::u16string stShift = this->KMX_GetShiftState(Shft, false); + std::u16string stCaps = this->KMX_GetShiftState(Base, true); + std::u16string stShiftCaps = this->KMX_GetShiftState(Shft, true); + return ( + ((stCaps.size() > 0) && + (stBase.compare(stCaps) != 0) && + (stShift.compare(stCaps) != 0)) || + ((stShiftCaps.size() > 0) && + (stBase.compare(stShiftCaps) != 0) && + (stShift.compare(stShiftCaps) != 0))); + } + + bool KMX_IsCapsEqualToShift() { + std::u16string stBase = this->KMX_GetShiftState(Base, false); + std::u16string stShift = this->KMX_GetShiftState(Shft, false); + std::u16string stCaps = this->KMX_GetShiftState(Base, true); + return ( + (stBase.size() > 0) && + (stShift.size() > 0) && + (stBase.compare(stShift) != 0) && + (stShift.compare(stCaps) == 0)); + } + + bool KMX_IsAltGrCapsEqualToAltGrShift() { + std::u16string stBase = this->KMX_GetShiftState(MenuCtrl, false); + std::u16string stShift = this->KMX_GetShiftState(ShftMenuCtrl, false); + std::u16string stCaps = this->KMX_GetShiftState(MenuCtrl, true); + return ( + (stBase.size() > 0) && + (stShift.size() > 0) && + (stBase.compare(stShift) != 0) && + (stShift.compare(stCaps) == 0)); + } + + bool KMX_IsXxxxGrCapsEqualToXxxxShift() { + std::u16string stBase = this->KMX_GetShiftState(Xxxx, false); + std::u16string stShift = this->KMX_GetShiftState(ShftXxxx, false); + std::u16string stCaps = this->KMX_GetShiftState(Xxxx, true); + return ( + (stBase.size() > 0) && + (stShift.size() > 0) && + (stBase.compare(stShift) != 0) && + (stShift.compare(stCaps) == 0)); + } + + bool KMX_IsEmpty() { + for (int i = 0; i < 10; i++) { + for (int j = 0; j <= 1; j++) { + if (this->KMX_GetShiftState((ShiftState)i, (j == 1)).size() > 0) { + return (false); + } + } + } + return true; + } + + bool KMX_IsKeymanUsedKey() { + return (this->m_vk >= 0x20 && this->m_vk <= 0x5F) || (this->m_vk >= 0x88); + } + + UINT KMX_GetShiftStateValue(int capslock, int caps, ShiftState ss) { + return KMX_ShiftStateMap[(int)ss] | (capslock ? (caps ? CAPITALFLAG : NOTCAPITALFLAG) : 0); + } + + int KMX_GetKeyCount(int MaxShiftState) { + int nkeys = 0; + + // Get the CAPSLOCK value + for (int ss = 0; ss <= MaxShiftState; ss++) { + if (ss == Menu || ss == ShftMenu) { + // Alt and Shift+Alt don't work, so skip them + continue; + } + for (int caps = 0; caps <= 1; caps++) { + + std::u16string st = this->KMX_GetShiftState((ShiftState) ss, (caps == 1)); + + if (st.size() == 0) { + // No character assigned here + } else if (this->m_rgfDeadKey[(int)ss][caps]) { + // It's a dead key, append an @ sign. + nkeys++; + } else { + bool isvalid = true; + for (size_t ich = 0; ich < st.size(); ich++) { + if(st[ich] < 0x20 || st[ich] == 0x7F) { + isvalid=false; + + wprintf(L"invalid for: %i\n", st[ich]); + break; } + } + if(isvalid) { + nkeys++; + } + } + } + } + return nkeys; + } + + bool KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector *deadkeys, int deadkeyBase, BOOL bDeadkeyConversion,v_dw_3D &All_Vector, GdkKeymap *keymap) { // I4552 + // Get the CAPSLOCK value + int capslock = + (this->KMX_IsCapsEqualToShift() ? 1 : 0) | + (this->KMX_IsSGCAPS() ? 2 : 0) | + (this->KMX_IsAltGrCapsEqualToAltGrShift() ? 4 : 0) | + (this->KMX_IsXxxxGrCapsEqualToXxxxShift() ? 8 : 0); + + for (int ss = 0; ss <= MaxShiftState; ss++) { + if (ss == Menu || ss == ShftMenu) { + // Alt and Shift+Alt don't work, so skip them + continue; + } + for (int caps = 0; caps <= 1; caps++) { + std::u16string st = this->KMX_GetShiftState((ShiftState) ss, (caps == 1)); + + PKMX_WCHAR p; + + if (st.size() == 0) { + // No character assigned here + } + else if (this->m_rgfDeadKey[(int)ss][caps]) { + // It's a dead key, append an @ sign. + key->dpContext = new KMX_WCHAR[1]; + *key->dpContext = 0; + + key->ShiftFlags = this->KMX_GetShiftStateValue(capslock, caps, (ShiftState) ss); + // we already use VK_US so no need to convert it as we do on windows + key->Key = this->VK(); + key->Line = 0; + + if(bDeadkeyConversion) { // I4552 + p = key->dpOutput = new KMX_WCHAR[2]; + *p++ = st[0]; + *p = 0; + } else { + + p = key->dpOutput = new KMX_WCHAR[4]; + *p++ = UC_SENTINEL; + *p++ = CODE_DEADKEY; + *p++ = KMX_DeadKeyMap(st[0], deadkeys, deadkeyBase, &KMX_FDeadkeys); // I4353 + *p = 0; + } + key++; + } + else { + bool isvalid = true; + for (size_t ich = 0; ich < st.size(); ich++) { + if(st[ich] < 0x20 || st[ich] == 0x7F) { + isvalid=false; + wprintf(L"invalid 16 for: %i\n", st[ich]); + break; } + } + if(isvalid) { + // this is different to mcompile windows !!!! + // this->m_sc stores SC-US = SCUnderlying + // this->m_vk stores VK-US ( not underlying !!) + // key->Key stores VK-US ( not underlying !!) + // key->dpOutput stores character Underlying + + KMX_DWORD SC_Underlying = KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keymap, All_Vector, this->SC(), (ShiftState) ss, caps); + key->Key = KMX_get_VKUS_From_KeyCodeUnderlying( SC_Underlying); + + key->Line = 0; + key->ShiftFlags = this->KMX_GetShiftStateValue(capslock, caps, (ShiftState) ss); + + key->dpContext = new KMX_WCHAR; + *key->dpContext = 0; + p = key->dpOutput = new KMX_WCHAR[st.size() + 1]; + for(size_t ich = 0; ich < st.size(); ich++) { + *p++ = st[ich]; + } + *p = 0; + key++; + } + } + } + } + return true; + } +}; + +class KMX_Loader { +private: + KMX_BYTE lpKeyStateNull[256]; + UINT m_XxxxVk; + +public: + KMX_Loader() { + m_XxxxVk = 0; + memset(lpKeyStateNull, 0, sizeof(lpKeyStateNull)); + } + + UINT Get_XxxxVk() { + return m_XxxxVk; + } + + void Set_XxxxVk(UINT value) { + m_XxxxVk = value; + } + + ShiftState KMX_MaxShiftState() { + return (Get_XxxxVk() == 0 ? ShftMenuCtrl : ShftXxxx); + } + + bool KMX_IsControlChar(char16_t ch) { + return (ch < 0x0020) || (ch >= 0x007F && ch <= 0x009F); + } + +}; + +int KMX_GetMaxDeadkeyIndex(KMX_WCHAR *p) { + int n = 0; + while(p && *p) { + if(*p == UC_SENTINEL && *(p+1) == CODE_DEADKEY) + n = std::max(n, (int) *(p+2)); + p = KMX_incxstr(p); + } + return n; +} + +bool KMX_ImportRules(LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, GdkKeymap **keymap, std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4552 + KMX_Loader loader; + + std::vector rgKey; //= new VirtualKey[256]; + std::vector alDead; + std::vector alDead_cpl = create_alDead(); + + rgKey.resize(256); + + // Scroll through the Scan Code (SC) values and get the valid Virtual Key (VK) + // values in it. Then, store the SC in each valid VK so it can act as both a + // flag that the VK is valid, and it can store the SC value. + + for(UINT sc = 0x01; sc <= 0x7f; sc++) { + // fills m_vk with the VK of the US keyboard + // ( mcompile win uses MapVirtualKeyEx() to fill m_vk with the VK of the Underlying keyboard) + // Linux can get a VK for the US Keyboard using USVirtualKeyToScanCode/ScanCodeToUSVirtualKey + // Linux cannot get a VK for the underling Keyboard + // this "connection" is possible only when using All_Vector + + KMX_VirtualKey *key = new KMX_VirtualKey(sc); + + if((key->VK() != 0) ) { + rgKey[key->VK()] = key; + } else { + delete key; + } + } + +// // _S2 TODO I assume we do not need those... +// rgKey[VK_DIVIDE] = new KMX_VirtualKey(hkl, VK_DIVIDE); +// rgKey[VK_CANCEL] = new KMX_VirtualKey(hkl, VK_CANCEL); +// rgKey[VK_DECIMAL] = new KMX_VirtualKey(hkl, VK_DECIMAL); + + // in this part we skip shiftstates 4, 5, 8, 9 + for(UINT iKey = 0; iKey < rgKey.size(); iKey++) { + + if(rgKey[iKey] != NULL) { + KMX_WCHAR sbBuffer[256]; // Scratchpad we use many places + + for(ShiftState ss = Base; ss <= loader.KMX_MaxShiftState(); ss = (ShiftState)((int)ss + 1)) { + if(ss == Menu || ss == ShftMenu) { + // Alt and Shift+Alt don't work, so skip them (ss 4+5) + continue; + } + + // //_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! + // if(ss == MenuCtrl|| ss == ShftMenuCtrl) { + // continue; + // } + + KMX_DWORD KC_US = (KMX_DWORD) KMX_get_KeyCodeUnderlying_From_VKUS(iKey); + + for(int caps = 0; caps <= 1; caps++) { + int rc = KMX_ToUnicodeEx(KC_US, sbBuffer, ss, caps, *keymap); + + if(rc > 0) { + if(*sbBuffer == 0) { + rgKey[iKey]->KMX_SetShiftState(ss, u"", false, (caps)); // different to windows since behavior on Linux is different + } + else { + if( (ss == Ctrl || ss == ShftCtrl) ) { + continue; + } + sbBuffer[rc] = 0; + rgKey[iKey]->KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to windows since behavior on Linux is different + } + } + else if(rc < 0) { + sbBuffer[2] = 0; + rgKey[iKey]->KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on Linux is different + + refine_alDead(sbBuffer[0], alDead, &alDead_cpl); + } + } + } + } + } + + //------------------------------------------------------------- + // Now that we've collected the key data, we need to + // translate it to kmx and append to the existing keyboard + //------------------------------------------------------------- + + int nDeadkey = 0; + LPKMX_GROUP gp = new KMX_GROUP[kp->cxGroupArray+4]; // leave space for old + memcpy(gp, kp->dpGroupArray, sizeof(KMX_GROUP) * kp->cxGroupArray); + + // + // Find the current highest deadkey index + // + + kp->dpGroupArray = gp; + for(UINT i = 0; i < kp->cxGroupArray; i++, gp++) { + //if(gp->fUsingKeys && gp->dpNoMatch == NULL) { // I4550 + // WCHAR *p = gp->dpNoMatch = new WCHAR[4]; + // *p++ = UC_SENTINEL; + // *p++ = CODE_USE; + // *p++ = (WCHAR)(kp->cxGroupArray + 1); + // *p = 0; + //} + LPKMX_KEY kkp = gp->dpKeyArray; + + for(UINT j = 0; j < gp->cxKeyArray; j++, kkp++) { + nDeadkey = std::max(nDeadkey, KMX_GetMaxDeadkeyIndex(kkp->dpContext)); + nDeadkey = std::max(nDeadkey, KMX_GetMaxDeadkeyIndex(kkp->dpOutput)); + } + } + + kp->cxGroupArray++; + gp = &kp->dpGroupArray[kp->cxGroupArray-1]; + + UINT nkeys = 0; + for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { + if ((rgKey[iKey] != NULL) && rgKey[iKey]->KMX_IsKeymanUsedKey() && (!rgKey[iKey]->KMX_IsEmpty())) { + nkeys+= rgKey[iKey]->KMX_GetKeyCount(loader.KMX_MaxShiftState()); + } + } + + + nDeadkey++; // ensure a 1-based index above the max deadkey value already in the keyboard + + gp->fUsingKeys = TRUE; + gp->dpMatch = NULL; + gp->dpName = NULL; + gp->dpNoMatch = NULL; + gp->cxKeyArray = nkeys; + gp->dpKeyArray = new KMX_KEY[gp->cxKeyArray]; + nkeys = 0; + + + // + // Fill in the new rules + // + for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { + if ((rgKey[iKey] != NULL) && rgKey[iKey]->KMX_IsKeymanUsedKey() && (!rgKey[iKey]->KMX_IsEmpty())) { + if(rgKey[iKey]->KMX_LayoutRow(loader.KMX_MaxShiftState(), &gp->dpKeyArray[nkeys], &alDead, nDeadkey, bDeadkeyConversion, All_Vector,*keymap)) { // I4552 + nkeys+=rgKey[iKey]->KMX_GetKeyCount(loader.KMX_MaxShiftState()); + } + } + } + + gp->cxKeyArray = nkeys; + + // + // Add nomatch control to each terminating 'using keys' group // I4550 + // + LPKMX_GROUP gp2 = kp->dpGroupArray; + for(UINT i = 0; i < kp->cxGroupArray - 1; i++, gp2++) { + if(gp2->fUsingKeys && gp2->dpNoMatch == NULL) { + KMX_WCHAR *p = gp2->dpNoMatch = new KMX_WCHAR[4]; + *p++ = UC_SENTINEL; + *p++ = CODE_USE; + *p++ = (KMX_WCHAR)(kp->cxGroupArray); + *p = 0; + + // I4550 - Each place we have a nomatch > use(baselayout) (this last group), we need to add all + // the AltGr and ShiftAltGr combinations as rules to allow them to be matched as well. Yes, this + // loop is not very efficient but it's not worthy of optimisation. + // + UINT j; + LPKMX_KEY kkp; + for(j = 0, kkp = gp->dpKeyArray; j < gp->cxKeyArray; j++, kkp++) { + if((kkp->ShiftFlags & (K_CTRLFLAG|K_ALTFLAG|LCTRLFLAG|LALTFLAG|RCTRLFLAG|RALTFLAG)) != 0) { + gp2->cxKeyArray++; + LPKMX_KEY kkp2 = new KMX_KEY[gp2->cxKeyArray]; + memcpy(kkp2, gp2->dpKeyArray, sizeof(KMX_KEY)*(gp2->cxKeyArray-1)); + gp2->dpKeyArray = kkp2; + kkp2 = &kkp2[gp2->cxKeyArray-1]; + kkp2->dpContext = new KMX_WCHAR; + *kkp2->dpContext = 0; + kkp2->Key = kkp->Key; + kkp2->ShiftFlags = kkp->ShiftFlags; + kkp2->Line = 0; + KMX_WCHAR *p = kkp2->dpOutput = new KMX_WCHAR[4]; + *p++ = UC_SENTINEL; + *p++ = CODE_USE; + *p++ = (KMX_WCHAR)(kp->cxGroupArray); + *p = 0; + } + } + } + } + + // If we have deadkeys, then add a new group to translate the deadkeys per the deadkey tables + // We only do this if not in deadkey conversion mode + // + + if (alDead.size() > 0 && !bDeadkeyConversion) { // I4552 + kp->cxGroupArray++; + + KMX_WCHAR *p = gp->dpMatch = new KMX_WCHAR[4]; + *p++ = UC_SENTINEL; + *p++ = CODE_USE; + *p++ = (KMX_WCHAR) kp->cxGroupArray; + *p = 0; + + gp++; + + gp->fUsingKeys = FALSE; + gp->dpMatch = NULL; + gp->dpName = NULL; + gp->dpNoMatch = NULL; + gp->cxKeyArray = alDead.size(); + LPKMX_KEY kkp = gp->dpKeyArray = new KMX_KEY[alDead.size()]; + + LPKMX_STORE sp = new KMX_STORE[kp->cxStoreArray + alDead.size() * 2]; + memcpy(sp, kp->dpStoreArray, sizeof(KMX_STORE) * kp->cxStoreArray); + + kp->dpStoreArray = sp; + + sp = &sp[kp->cxStoreArray]; + int nStoreBase = kp->cxStoreArray; + kp->cxStoreArray += alDead.size() * 2; + + for(UINT i = 0; i < alDead.size(); i++) { + DeadKey *dk = alDead[i]; + + sp->dpName = NULL; + sp->dwSystemID = 0; + sp->dpString = new KMX_WCHAR[dk->KMX_Count() + 1]; + for(int j = 0; j < dk->KMX_Count(); j++) + sp->dpString[j] = dk->KMX_GetBaseCharacter(j); + sp->dpString[dk->KMX_Count()] = 0; + sp++; + + sp->dpName = NULL; + sp->dwSystemID = 0; + sp->dpString = new KMX_WCHAR[dk->KMX_Count() + 1]; + for(int j = 0; j < dk->KMX_Count(); j++) + sp->dpString[j] = dk->KMX_GetCombinedCharacter(j); + sp->dpString[dk->KMX_Count()] = 0; + sp++; + + kkp->Line = 0; + kkp->ShiftFlags = 0; + kkp->Key = 0; + KMX_WCHAR *p = kkp->dpContext = new KMX_WCHAR[8]; + *p++ = UC_SENTINEL; + *p++ = CODE_DEADKEY; + *p++ = KMX_DeadKeyMap(dk->KMX_DeadCharacter(), &alDead, nDeadkey, FDeadkeys); // I4353 + // *p++ = nDeadkey+i; + *p++ = UC_SENTINEL; + *p++ = CODE_ANY; + *p++ = nStoreBase + i*2 + 1; + *p = 0; + + p = kkp->dpOutput = new KMX_WCHAR[5]; + *p++ = UC_SENTINEL; + *p++ = CODE_INDEX; + *p++ = nStoreBase + i*2 + 2; + *p++ = 2; + *p = 0; + kkp++; + } + } + +return true; +} + +const int CODE__SIZE[] = { + -1, // undefined 0x00 + 1, // CODE_ANY 0x01 + 2, // CODE_INDEX 0x02 + 0, // CODE_CONTEXT 0x03 + 0, // CODE_NUL 0x04 + 1, // CODE_USE 0x05 + 0, // CODE_RETURN 0x06 + 0, // CODE_BEEP 0x07 + 1, // CODE_DEADKEY 0x08 + -1, // unused 0x09 + 2, // CODE_EXTENDED 0x0A + -1, // CODE_EXTENDEDEND 0x0B (unused) + 1, // CODE_SWITCH 0x0C + -1, // CODE_KEY 0x0D (never used) + 0, // CODE_CLEARCONTEXT 0x0E + 1, // CODE_CALL 0x0F + -1, // UC_SENTINEL_EXTENDEDEND 0x10 (not valid with UC_SENTINEL) + 1, // CODE_CONTEXTEX 0x11 + 1, // CODE_NOTANY 0x12 + 2, // CODE_SETOPT 0x13 + 3, // CODE_IFOPT 0x14 + 1, // CODE_SAVEOPT 0x15 + 1, // CODE_RESETOPT 0x16 + 3, // CODE_IFSYSTEMSTORE 0x17 + 2 // CODE_SETSYSTEMSTORE 0x18 +}; +*/ \ No newline at end of file diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h new file mode 100755 index 00000000000..161ddfcd6fc --- /dev/null +++ b/mac/mcompile/mc_import_rules.h @@ -0,0 +1,42 @@ + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ +/* +#pragma once +#ifndef MC_IMPORT_RULES_H +#define MC_IMPORT_RULES_H + +class DeadKey { +private: + KMX_WCHAR m_deadchar; + std::vector m_rgbasechar; + std::vector m_rgcombchar; + +public: + DeadKey(KMX_WCHAR deadCharacter); + + KMX_WCHAR KMX_DeadCharacter(); + + void KMX_AddDeadKeyRow(KMX_WCHAR baseCharacter, KMX_WCHAR combinedCharacter); + + int KMX_Count() { + return this->m_rgbasechar.size(); + } + + KMX_WCHAR KMX_GetDeadCharacter() { + return this->m_deadchar; + } + + KMX_WCHAR KMX_GetBaseCharacter(int index) { + return this->m_rgbasechar[index]; + } + + KMX_WCHAR KMX_GetCombinedCharacter(int index) { + return this->m_rgcombchar[index]; + } + + bool KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter); +}; + +# endif *//*MC_IMPORT_RULES_H*/ diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp new file mode 100755 index 00000000000..eed0adbf8ab --- /dev/null +++ b/mac/mcompile/mc_kmxfile.cpp @@ -0,0 +1,521 @@ + +#include "mc_kmxfile.h" +#include + +#define CERR_None 0x00000000 +#define CERR_CannotAllocateMemory 0x00008004 +#define CERR_UnableToWriteFully 0x00008007 +#define CERR_SomewhereIGotItWrong 0x00008009 + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + +/* +KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz); + +LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize); + +KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename) { + + FILE *fp; + fp = Open_File(filename, u"wb"); + + if(fp == NULL) + { + KMX_LogError(L"Failed to create output file (%d)", errno); + return FALSE; + } + + KMX_DWORD err = KMX_WriteCompiledKeyboard(kbd, fp, FALSE); + fclose(fp); + + if(err != CERR_None) { + KMX_LogError(L"Failed to write compiled keyboard with error %d", err); + + std::u16string u16_filname(filename); + std::string s = string_from_u16string(u16_filname); + + remove(s.c_str()); + return FALSE; + } + + return TRUE; +} + +KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug) { + + LPKMX_GROUP fgp; + LPKMX_STORE fsp; + LPKMX_KEY fkp; + + PKMX_COMP_KEYBOARD ck; + PKMX_COMP_GROUP gp; + PKMX_COMP_STORE sp; + PKMX_COMP_KEY kp; + PKMX_BYTE buf; + KMX_DWORD size, offset; + DWORD i, j; + + // Calculate how much memory to allocate + size = sizeof(KMX_COMP_KEYBOARD) + + fk->cxGroupArray * sizeof(KMX_COMP_GROUP) + + fk->cxStoreArray * sizeof(KMX_COMP_STORE) + + //wcslen(fk->szName)*2 + 2 + + //wcslen(fk->szCopyright)*2 + 2 + + //wcslen(fk->szLanguageName)*2 + 2 + + //wcslen(fk->szMessage)*2 + 2 + + fk->dwBitmapSize; + + for(i = 0, fgp = fk->dpGroupArray; i < fk->cxGroupArray; i++, fgp++) { + if(fgp->dpName) + size += u16len(fgp->dpName)*2 + 2; + size += fgp->cxKeyArray * sizeof(KMX_COMP_KEY); + for(j = 0, fkp = fgp->dpKeyArray; j < fgp->cxKeyArray; j++, fkp++) { + size += u16len(fkp->dpOutput)*2 + 2; + size += u16len(fkp->dpContext)*2 + 2; + } + + if( fgp->dpMatch ) size += u16len(fgp->dpMatch)*2 + 2; + if( fgp->dpNoMatch ) size += u16len(fgp->dpNoMatch)*2 + 2; + } + + for(i = 0; i < fk->cxStoreArray; i++) + { + size += u16len(fk->dpStoreArray[i].dpString)*2 + 2; + if(fk->dpStoreArray[i].dpName) + size += u16len(fk->dpStoreArray[i].dpName)*2 + 2; + } + + buf = new KMX_BYTE[size]; + if(!buf) return CERR_CannotAllocateMemory; + memset(buf, 0, size); + + ck = (PKMX_COMP_KEYBOARD) buf; + + ck->dwIdentifier = FILEID_COMPILED; + + ck->dwFileVersion = fk->dwFileVersion; + ck->dwCheckSum = 0; // No checksum in 16.0, see #7276 + ck->KeyboardID = fk->xxkbdlayout; + ck->IsRegistered = fk->IsRegistered; + ck->cxStoreArray = fk->cxStoreArray; + ck->cxGroupArray = fk->cxGroupArray; + ck->StartGroup[0] = fk->StartGroup[0]; + ck->StartGroup[1] = fk->StartGroup[1]; + ck->dwHotKey = fk->dwHotKey; + + ck->dwFlags = fk->dwFlags; + + offset = sizeof(KMX_COMP_KEYBOARD); + + // ck->dpLanguageName = offset; + //wcscpy((PWSTR)(buf + offset), fk->szLanguageName); + //offset += wcslen(fk->szLanguageName)*2 + 2; + + //ck->dpName = offset; + //wcscpy((PWSTR)(buf + offset), fk->szName); + //offset += wcslen(fk->szName)*2 + 2; + + //ck->dpCopyright = offset; + //wcscpy((PWSTR)(buf + offset), fk->szCopyright); + //offset += wcslen(fk->szCopyright)*2 + 2; + + //ck->dpMessage = offset; + //wcscpy((PWSTR)(buf + offset), fk->szMessage); + //offset += wcslen(fk->szMessage)*2 + 2; + + ck->dpStoreArray = offset; + sp = (PKMX_COMP_STORE)(buf+offset); + fsp = fk->dpStoreArray; + offset += sizeof(KMX_COMP_STORE) * ck->cxStoreArray; + for(i = 0; i < ck->cxStoreArray; i++, sp++, fsp++) { + sp->dwSystemID = fsp->dwSystemID; + sp->dpString = offset; + u16ncpy((PKMX_WCHAR)(buf+offset), fsp->dpString, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fsp->dpString)*2 + 2; + + if(!fsp->dpName) { + sp->dpName = 0; + } else { + sp->dpName = offset; + u16ncpy((PKMX_WCHAR)(buf+offset), fsp->dpName, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fsp->dpName)*2 + 2; + } + } + + ck->dpGroupArray = offset; + gp = (PKMX_COMP_GROUP)(buf+offset); + fgp = fk->dpGroupArray; + + offset += sizeof(KMX_COMP_GROUP) * ck->cxGroupArray; + + for(i = 0; i < ck->cxGroupArray; i++, gp++, fgp++) { + gp->cxKeyArray = fgp->cxKeyArray; + gp->fUsingKeys = fgp->fUsingKeys; + + gp->dpMatch = gp->dpNoMatch = 0; + + if(fgp->dpMatch) { + gp->dpMatch = offset; + u16ncpy((PKMX_WCHAR)(buf+offset), fgp->dpMatch, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fgp->dpMatch)*2 + 2; + } + if(fgp->dpNoMatch) { + gp->dpNoMatch = offset; + u16ncpy((PKMX_WCHAR)(buf+offset), fgp->dpNoMatch, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fgp->dpNoMatch)*2 + 2; + } + + if(fgp->dpName) { + gp->dpName = offset; + u16ncpy((PKMX_WCHAR)(buf+offset), fgp->dpName, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fgp->dpName)*2 + 2; + } else { + gp->dpName = 0; + } + + gp->dpKeyArray = offset; + kp = (PKMX_COMP_KEY) (buf + offset); + fkp = fgp->dpKeyArray; + offset += gp->cxKeyArray * sizeof(KMX_COMP_KEY); + for(j = 0; j < gp->cxKeyArray; j++, kp++, fkp++) { + kp->Key = fkp->Key; + kp->Line = fkp->Line; + kp->ShiftFlags = fkp->ShiftFlags; + kp->dpOutput = offset; + + u16ncpy((PKMX_WCHAR)(buf+offset), fkp->dpOutput, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fkp->dpOutput)*2 + 2; + + kp->dpContext = offset; + u16ncpy((PKMX_WCHAR)(buf+offset), fkp->dpContext, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fkp->dpContext)*2 + 2; + } + } + + if(fk->dwBitmapSize > 0) { + ck->dwBitmapSize = fk->dwBitmapSize; + ck->dpBitmapOffset = offset; + memcpy(buf + offset, ((PKMX_BYTE)fk) + fk->dpBitmapOffset, fk->dwBitmapSize); + offset += fk->dwBitmapSize; + } else { + ck->dwBitmapSize = 0; + ck->dpBitmapOffset = 0; + } + + if(offset != size) + { + delete[] buf; + return CERR_SomewhereIGotItWrong; + } + + fwrite(buf, size,1,hOutfile); + if(offset != size) + { + delete[] buf; + return CERR_UnableToWriteFully; + } + + delete[] buf; + + return CERR_None; +} + +PKMX_WCHAR KMX_StringOffset(PKMX_BYTE base, KMX_DWORD offset) { + if(offset == 0) return NULL; + return (PKMX_WCHAR)(base + offset); +} + +#ifdef KMX_64BIT +*/ +/** CopyKeyboard will copy the data read into bufp from x86-sized structures into + x64-sized structures starting at `base` + * After this function finishes, we still need to keep the original data because + we don't copy the strings + This method is used on 64-bit architectures. +*/ +/* +LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { + PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD) base; + + // Copy keyboard structure // + + LPKMX_KEYBOARD kbp = (LPKMX_KEYBOARD) bufp; + bufp += sizeof(KMX_KEYBOARD); + + kbp->dwIdentifier = ckbp->dwIdentifier; + kbp->dwFileVersion = ckbp->dwFileVersion; + kbp->dwCheckSum = ckbp->dwCheckSum; + kbp->xxkbdlayout = ckbp->KeyboardID; + kbp->IsRegistered = ckbp->IsRegistered; + kbp->version = ckbp->version; + kbp->cxStoreArray = ckbp->cxStoreArray; + kbp->cxGroupArray = ckbp->cxGroupArray; + kbp->StartGroup[0] = ckbp->StartGroup[0]; + kbp->StartGroup[1] = ckbp->StartGroup[1]; + kbp->dwFlags = ckbp->dwFlags; + kbp->dwHotKey = ckbp->dwHotKey; + + kbp->dpStoreArray = (LPKMX_STORE) bufp; + bufp += sizeof(KMX_STORE) * kbp->cxStoreArray; + + kbp->dpGroupArray = (LPKMX_GROUP) bufp; + bufp += sizeof(KMX_GROUP) * kbp->cxGroupArray; + + PKMX_COMP_STORE csp; + LPKMX_STORE sp; + KMX_DWORD i; + + for( + csp = (PKMX_COMP_STORE)(base + ckbp->dpStoreArray), sp = kbp->dpStoreArray, i = 0; + i < kbp->cxStoreArray; + i++, sp++, csp++) + { + sp->dwSystemID = csp->dwSystemID; + sp->dpName = KMX_StringOffset(base, csp->dpName); + sp->dpString = KMX_StringOffset(base, csp->dpString); + } + + PKMX_COMP_GROUP cgp; + LPKMX_GROUP gp; + + for( + cgp = (PKMX_COMP_GROUP)(base + ckbp->dpGroupArray), gp = kbp->dpGroupArray, i = 0; + i < kbp->cxGroupArray; + i++, gp++, cgp++) + { + gp->dpName = KMX_StringOffset(base, cgp->dpName); + gp->dpKeyArray = cgp->cxKeyArray > 0 ? (LPKMX_KEY) bufp : NULL; + gp->cxKeyArray = cgp->cxKeyArray; + bufp += sizeof(KMX_KEY) * gp->cxKeyArray; + gp->dpMatch = KMX_StringOffset(base, cgp->dpMatch); + gp->dpNoMatch = KMX_StringOffset(base, cgp->dpNoMatch); + gp->fUsingKeys = cgp->fUsingKeys; + + PKMX_COMP_KEY ckp; + LPKMX_KEY kp; + KMX_DWORD j; + + for( + ckp = (PKMX_COMP_KEY)(base + cgp->dpKeyArray), kp = gp->dpKeyArray, j = 0; + j < gp->cxKeyArray; + j++, kp++, ckp++) + { + kp->Key = ckp->Key; + kp->Line = ckp->Line; + kp->ShiftFlags = ckp->ShiftFlags; + kp->dpOutput = KMX_StringOffset(base, ckp->dpOutput); + kp->dpContext = KMX_StringOffset(base, ckp->dpContext); + } + } + return kbp; +} +*/ +// else KMX_FixupKeyboard +//#else /* Fixup the keyboard by expanding pointers. On disk the pointers are stored relative to the +// beginning of the file, but we need real pointers. This method is used on 32-bit architectures. +//*/ + +/* +LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize) { + + UNREFERENCED_PARAMETER(dwFileSize); + + KMX_DWORD i, j; + PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD) base; + PKMX_COMP_GROUP cgp; + PKMX_COMP_STORE csp; + PKMX_COMP_KEY ckp; + LPKMX_KEYBOARD kbp = (LPKMX_KEYBOARD) bufp; + LPKMX_STORE sp; + LPKMX_GROUP gp; + LPKMX_KEY kp; + + kbp->dpStoreArray = (LPKMX_STORE) (base + ckbp->dpStoreArray); + kbp->dpGroupArray = (LPKMX_GROUP) (base + ckbp->dpGroupArray); + + for(sp = kbp->dpStoreArray, csp = (PKMX_COMP_STORE) sp, i = 0; i < kbp->cxStoreArray; i++, sp++, csp++) { + sp->dpName = KMX_StringOffset(base, csp->dpName); + sp->dpString = KMX_StringOffset(base, csp->dpString); + } + + for(gp = kbp->dpGroupArray, cgp = (PKMX_COMP_GROUP) gp, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) { + gp->dpName = KMX_StringOffset(base, cgp->dpName); + gp->dpKeyArray = (LPKMX_KEY) (base + cgp->dpKeyArray); + if(cgp->dpMatch != NULL) gp->dpMatch = (PKMX_WCHAR) (base + cgp->dpMatch); + if(cgp->dpNoMatch != NULL) gp->dpNoMatch = (PKMX_WCHAR) (base + cgp->dpNoMatch); + + for(kp = gp->dpKeyArray, ckp = (PKMX_COMP_KEY) kp, j = 0; j < gp->cxKeyArray; j++, kp++, ckp++) { + kp->dpOutput = (PKMX_WCHAR) (base + ckp->dpOutput); + kp->dpContext = (PKMX_WCHAR) (base + ckp->dpContext); + } + } + + return kbp; +} + +#endif + +KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { + + PKMX_BYTE buf; + FILE* fp; + LPKMX_KEYBOARD kbp; + PKMX_BYTE filebase; + + if(!fileName || !lpKeyboard) { + KMX_LogError(L"Bad Filename\n" ); + return FALSE; + } + + fp = Open_File((const KMX_WCHAR*)fileName, u"rb"); + + if(fp == NULL) { + KMX_LogError(L"Could not open file\n" ); + return FALSE; + } + + if (fseek(fp, 0, SEEK_END) != 0) { + fclose(fp); + KMX_LogError(L"Could not fseek file\n" ); + return FALSE; + } + + auto sz = ftell(fp); + if (sz < 0) { + fclose(fp); + return FALSE; + } + + if (fseek(fp, 0, SEEK_SET) != 0) { + fclose(fp); + KMX_LogError(L"Could not fseek(set) file\n" ); + return FALSE; + } + + #ifdef KMX_64BIT + // allocate enough memory for expanded data structure + original data. + // Expanded data structure is double the size of data on disk (8-byte + // pointers) - on disk the "pointers" are relative to the beginning of + // the file. + // We save the original data at the end of buf; we don't copy strings, so + // those will remain in the location at the end of the buffer. + buf = new KMX_BYTE[sz * 3]; + #else + buf = new KMX_BYTE[sz]; + #endif + + if (!buf) { + fclose(fp); + KMX_LogError(L"Not allocmem\n" ); + return FALSE; + } + + #ifdef KMX_64BIT + filebase = buf + sz*2; + #else + filebase = buf; + #endif + + if (fread(filebase, 1, sz, fp) < (size_t)sz) { + KMX_LogError(L"Could not read file\n" ); + fclose(fp); + return FALSE; + } + + fclose(fp); + + if(*PKMX_DWORD(filebase) != KMX_DWORD(FILEID_COMPILED)) + { + delete [] buf; + KMX_LogError(L"Invalid file - signature is invalid\n"); + return FALSE; + } + + if (!KMX_VerifyKeyboard(filebase, sz)) { + KMX_LogError(L"errVerifyKeyboard\n" ); + return FALSE; + } + +#ifdef KMX_64BIT + kbp = KMX_CopyKeyboard(buf, filebase); +#else + kbp = KMX_FixupKeyboard(buf, filebase, sz); +#endif + + + if (!kbp) { + KMX_LogError(L"errFixupKeyboard\n" ); + return FALSE; + } + + if (kbp->dwIdentifier != FILEID_COMPILED) { + delete[] buf; + KMX_LogError(L"errNotFileID\n" ); + return FALSE; + } + *lpKeyboard = kbp; + return TRUE; +} + +KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz){ + KMX_DWORD i; + PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)filebase; + PKMX_COMP_STORE csp; + + // Check file version // + + if (ckbp->dwFileVersion < VERSION_MIN || ckbp->dwFileVersion > VERSION_MAX) { + // Old or new version -- identify the desired program version // + for (csp = (PKMX_COMP_STORE)(filebase + ckbp->dpStoreArray), i = 0; i < ckbp->cxStoreArray; i++, csp++) { + if (csp->dwSystemID == TSS_COMPILEDVERSION) { + if (csp->dpString == 0) { + KMX_LogError(L"errWrongFileVersion:NULL"); + } else { + KMX_LogError(L"errWrongFileVersion:%10.10ls",(const PKMX_WCHAR) KMX_StringOffset((PKMX_BYTE)filebase, csp->dpString)); + } + return FALSE; + } + } + KMX_LogError(L"errWrongFileVersion"); + return FALSE; + } + return TRUE; +} + +PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) { + + if (*p == 0) + return p; + if (*p != UC_SENTINEL) { + if (*p >= 0xD800 && *p <= 0xDBFF && *(p + 1) >= 0xDC00 && *(p + 1) <= 0xDFFF) + return p + 2; + return p + 1; + } + // UC_SENTINEL(FFFF) with UC_SENTINEL_EXTENDEDEND(0x10) == variable length + if (*(p + 1) == CODE_EXTENDED) { + p += 2; + while (*p && *p != UC_SENTINEL_EXTENDEDEND) + p++; + + if (*p == 0) return p; + return p + 1; + } + + if (*(p + 1) > CODE_LASTCODE || CODE__SIZE[*(p + 1)] == -1) { + return p + 1; + } + + int deltaptr = 2 + CODE__SIZE[*(p + 1)]; + + // check for \0 between UC_SENTINEL(FFFF) and next printable character + for (int i = 0; i < deltaptr; i++) { + if (*p == 0) + return p; + p++; + } + return p; +} + +*/ \ No newline at end of file diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h new file mode 100755 index 00000000000..0246b3baaa5 --- /dev/null +++ b/mac/mcompile/mc_kmxfile.h @@ -0,0 +1,90 @@ + +#pragma once +#ifndef MC_KMXFILE_H +#define MC_KMXFILE_H + + +#include "km_types.h" +#include "kmx_file.h" +#include "filesystem.h" +#include "mcompile.h" + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + +/* + + +#ifndef _KMXFILE_H +#define _KMXFILE_H + + +typedef struct KMX_tagSTORE { + KMX_DWORD dwSystemID; + PKMX_WCHAR dpName; + PKMX_WCHAR dpString; +} KMX_STORE, *LPKMX_STORE; + + +typedef struct KMX_tagKEY { + KMX_WCHAR Key; + KMX_DWORD Line; + KMX_DWORD ShiftFlags; + PKMX_WCHAR dpOutput; + PKMX_WCHAR dpContext; +} KMX_KEY, *LPKMX_KEY; + + +typedef struct KMX_tagGROUP { + KMX_WCHAR* dpName; + LPKMX_KEY dpKeyArray; // [LPKEY] address of first item in key array + PKMX_WCHAR dpMatch; + PKMX_WCHAR dpNoMatch; + KMX_DWORD cxKeyArray; // in array entries + int32_t fUsingKeys; // group(xx) [using keys] <-- specified or not +} KMX_GROUP, *LPKMX_GROUP; + + +typedef struct KMX_tagKEYBOARD { + KMX_DWORD dwIdentifier; // Keyman compiled keyboard id + + KMX_DWORD dwFileVersion; // Version of the file - Keyman 4.0 is 0x0400 + + KMX_DWORD dwCheckSum; // As stored in keyboard. DEPRECATED as of 16.0 + KMX_DWORD xxkbdlayout; // as stored in HKEY_LOCAL_MACHINE//system//currentcontrolset//control//keyboard layouts + KMX_DWORD IsRegistered; // layout id, from same registry key + KMX_DWORD version; // keyboard version + + KMX_DWORD cxStoreArray; // in array entries + KMX_DWORD cxGroupArray; // in array entries + + LPKMX_STORE dpStoreArray; // [LPSTORE] address of first item in store array, from start of file + LPKMX_GROUP dpGroupArray; // [LPGROUP] address of first item in group array, from start of file + + KMX_DWORD StartGroup[2]; // index of starting groups [2 of them] + // Ansi=0, Unicode=1 + + KMX_DWORD dwFlags; // Flags for the keyboard file + + KMX_DWORD dwHotKey; // standard windows hotkey (hiword=shift/ctrl/alt stuff, loword=vkey) + + //PWSTR dpName; // offset of name + //PWSTR dpLanguageName; // offset of language name; + //PWSTR dpCopyright; // offset of copyright + //PWSTR dpMessage; // offset of message in Keyboard About box + + KMX_DWORD dpBitmapOffset; // 0038 offset of the bitmaps in the file + KMX_DWORD dwBitmapSize; // 003C size in bytes of the bitmaps + //HBITMAP hBitmap; // handle to the bitmap in the file; +} KMX_KEYBOARD, *LPKMX_KEYBOARD; + +KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD *lpKeyboard); + +KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename); + +KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug); + +#endif // _KMXFILE_H +*/ +#endif /*MC_KMXFILE_H*/ diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 99f54ad2ee2..394e7437c66 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -1,23 +1,539 @@ +/* + Name: mcompile + Copyright: Copyright (C) SIL International. + Documentation: + Description: + Create Date: 24 Apr 2014 + + Modified Date: 8 Apr 2015 + Authors: mcdurdin + Related Files: + Dependencies: + + Bugs: + Todo: + Notes: + History: 24 Apr 2014 - mcdurdin - I4174 - V9 - mcompile logs should be stored in diag folder + 16 Jun 2014 - mcdurdin - I4273 - V9.0 - Convert keyboards to Unicode before installing + 23 Jun 2014 - mcdurdin - I4279 - V9.0 - mcompile fails to start when converting keyboard to Unicode + 03 Aug 2014 - mcdurdin - I4353 - V9.0 - mnemonic layout recompiler mixes up deadkey rules + 03 Aug 2014 - mcdurdin - I4327 - V9.0 - Mnemonic layout compiler follow-up + 31 Dec 2014 - mcdurdin - I4549 - V9.0 - Mnemonic layout recompiler does not translate Lctrl Ralt for deadkeys correctly + 06 Feb 2015 - mcdurdin - I4552 - V9.0 - Add mnemonic recompile option to ignore deadkeys + 08 Apr 2015 - mcdurdin - I4651 - V9.0 - Mnemonic layout recompiler maps AltGr+VK_BKSLASH rather than VK_OEM_102 +*/ #include #include #include "mcompile.h" +#include "u16.h" //------------------------------- int main () { std::cout << "Hier ist main von mcompile-mac.cpp...\n"; + testmyFunctions_S2(); + + std::wstring const wtr = L"abc"; + std::string str= string_from_wstring(wtr); - std::u16string character; - for (int i=0; i<8; i++) { - character = get_character_From_Keycode(24,14,i ); // all Shiftstates for ´` + e - //wprintf( L" ` + e for SHIFTSTATE %i -> ...\n", i, wstring_from_u16string(character);); - } printf("\n................................ END ..............................\n"); return 0; } +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + + +/* + +KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, gint argc, gchar *argv[]); + +bool KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, GdkKeymap **keymap,std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 + +std::vector KMX_FDeadkeys; // I4353 + +// Note: max is not a standard c api function or macro +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#define _countof(a) (sizeof(a)/sizeof(*(a))) + +#if defined(_WIN32) || defined(_WIN64) + int wmain(int argc, wchar_t* argv[]) { + std::vector str_argv_16 = convert_argvW_to_Vector_u16str( argc, argv); + run(argc, str_argv_16); + +#else // LINUX + int main(int argc, char* argv[]) { + std::vector str_argv_16 = convert_argv_to_Vector_u16str(argc, argv); + run(argc, str_argv_16, argv); +#endif + +} + +int run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ + + std::vector argv; + for (int i = 0; i < argc; i++) { + const char16_t* cmdl_par = str_argv[i].c_str(); + argv.push_back(cmdl_par); + } + + if(argc < 3 || (argc > 4)) { // I4273// I4273 + wprintf( + L"Usage: mcompile [-d] infile.kmx outfile.kmx\n" + L" mmcompile -u ... (not available for Linux)\n " + L" mcompile converts a Keyman mnemonic layout to a\n" + L" positional one based on the Linux keyboard\n" + L" layout on top position\n" + L" (-d convert deadkeys to plain keys) not available yet \n\n" + ); // I4552 + + return 1; + } + // -u option is not available for Linux + + + int bDeadkeyConversion = u16cmp(argv[1], u"-d") == 0; // I4552 + int n = (bDeadkeyConversion ? 2 : 1); + + char16_t* infile = (char16_t*) argv[n], *outfile = (char16_t*) argv[n+1]; + + wprintf(L"mcompile%ls \"%ls\" \"%ls\"\n", bDeadkeyConversion ? L" -d" : L"", u16fmt((const char16_t*) infile).c_str(), u16fmt((const char16_t*) outfile).c_str() ); // I4174 + + // 1. Load the keyman keyboard file + + // 2. For each key on the system layout, determine its output character and perform a + // 1-1 replacement on the keyman keyboard of that character with the base VK + shift + // state. This fixup will transform the char to a vk, which will avoid any issues + // with the key. + // + // --> deadkeys we will attack after the POC + // + // For each deadkey, we need to determine its possible outputs. Then we generate a VK + // rule for that deadkey, e.g. [K_LBRKT] > dk(c101) + // + // Next, update each rule that references the output from that deadkey to add an extra + // context deadkey at the end of the context match, e.g. 'a' dk(c101) + [K_SPACE] > 'b'. + // This will require a memory layout change for the .kmx file, plus fixups on the + // context+output index offsets + // + // --> virtual character keys + // + // [CTRL ' '] : we look at the character, and replace it in the same way, but merely + // switch the shift state from the VIRTUALCHARKEY to VIRTUALKEY, without changing any + // other properties of the key. + // + // 3. Write the new keyman keyboard file + + + LPKMX_KEYBOARD kmxfile; + + if(!KMX_LoadKeyboard(infile, &kmxfile)) { + KMX_LogError(L"Failed to load keyboard (%d)\n", errno ); + return 3; + } + + +#if defined(_WIN32) || defined(_WIN64) +// if(DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F +// KMX_SaveKeyboard(kmxfile, outfile); +// } + +#else // LINUX + if(KMX_DoConvert( kmxfile, bDeadkeyConversion, argc, (gchar**) argv_ch)) { // I4552F + KMX_SaveKeyboard(kmxfile, outfile); +} + +#endif + //DeleteReallocatedPointers(kmxfile); :TODO // _S2 not my ToDo :-) + delete kmxfile; + return 0; +} + +// Map of all shift states that we will work with +const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCTRLFLAG|RALTFLAG, 0xFFFF}; + +// +// TranslateKey +// +// For each key rule on the keyboard, remap its key to the +// correct shift state and key. Adjust the LCTRL+RALT -> RALT if necessary +// +void KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { + // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. + // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" + // to provide an alternate.. + if((shift & (LCTRLFLAG|RALTFLAG)) == (LCTRLFLAG|RALTFLAG)) + shift &= ~LCTRLFLAG; + + if(key->ShiftFlags == 0 && key->Key == ch) { + // Key is a mnemonic key with no shift state defined. + // Remap the key according to the character on the key cap. + //LogError(L"Converted mnemonic rule on line %d, + '%c' TO + [%x K_%d]", key->Line, key->Key, shift, vk); + key->ShiftFlags = ISVIRTUALKEY | shift; + key->Key = vk; + } else if(key->ShiftFlags & VIRTUALCHARKEY && key->Key == ch) { + // Key is a virtual character key with a hard-coded shift state. + // Do not remap the shift state, just move the key. + // This will not result in 100% wonderful mappings as there could + // be overlap, depending on how keys are arranged on the target layout. + // But that is up to the designer. + //LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, key->ShiftFlags & ~VIRTUALCHARKEY, vk); + key->ShiftFlags &= ~VIRTUALCHARKEY; + key->Key = vk; + } +} + +void KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { + for(unsigned int i = 0; i < group->cxKeyArray; i++) { + KMX_TranslateKey(&group->dpKeyArray[i], vk, shift, ch); + } +} + +void KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { + for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { + if(kbd->dpGroupArray[i].fUsingKeys) { + KMX_TranslateGroup(&kbd->dpGroupArray[i], vk, shift, ch); + } + } +} + +void KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { + if(key->ShiftFlags == 0) { + KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); + } else if(key->ShiftFlags & VIRTUALCHARKEY) { + KMX_LogError(L"Did not find a match for mnemonic virtual character key rule on line %d, + [%x '%c'] > ...", key->Line, key->ShiftFlags, key->Key); + } +} + +void KMX_ReportUnconvertedGroupRules(LPKMX_GROUP group) { + for(unsigned int i = 0; i < group->cxKeyArray; i++) { + KMX_ReportUnconvertedKeyRule(&group->dpKeyArray[i]); + } +} + +void KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { + for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { + if(kbd->dpGroupArray[i].fUsingKeys) { + KMX_ReportUnconvertedGroupRules(&kbd->dpGroupArray[i]); + } + } +} + +void KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { +// _S2 TOP_2 INFO this produces a different output due to different layouts for Lin<-> win ( for the same language!!) + + if((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) { + // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. + // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" + // to provide an alternate.. + if((shift & (LCTRLFLAG|RALTFLAG)) == (LCTRLFLAG|RALTFLAG)) // I4327 + shift &= ~LCTRLFLAG; + + if(key->ShiftFlags == 0) { + //KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO dk(%d) + [%x K_%d]", key->Line, key->Key, deadkey, shift, vk); + key->ShiftFlags = ISVIRTUALKEY | shift; + } else { + //KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO dk(%d) + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, deadkey, key->ShiftFlags & ~VIRTUALCHARKEY, vk); + key->ShiftFlags &= ~VIRTUALCHARKEY; + } + + int len = u16len(key->dpContext); + + PKMX_WCHAR context = new KMX_WCHAR[len + 4]; + memcpy(context, key->dpContext, len * sizeof(KMX_WCHAR)); + context[len] = UC_SENTINEL; + context[len+1] = CODE_DEADKEY; + context[len+2] = deadkey; + context[len+3] = 0; + key->dpContext = context; + key->Key = vk; + } +} + +void KMX_TranslateDeadkeyGroup(LPKMX_GROUP group,KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { + for(unsigned int i = 0; i < group->cxKeyArray; i++) { + KMX_TranslateDeadkeyKey(&group->dpKeyArray[i], deadkey, vk, shift, ch); + } +} + +void KMX_TranslateDeadkeyKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { + for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { + if(kbd->dpGroupArray[i].fUsingKeys) { + KMX_TranslateDeadkeyGroup(&kbd->dpGroupArray[i], deadkey, vk, shift, ch); + } + } +} + +void KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift) { + // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. + // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" + // to provide an alternate.. + if((shift & (LCTRLFLAG|RALTFLAG)) == (LCTRLFLAG|RALTFLAG)) // I4549 + shift &= ~LCTRLFLAG; + // If the first group is not a matching-keys group, then we need to add into + // each subgroup, otherwise just the match group + for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { + if(kbd->dpGroupArray[i].fUsingKeys) { + LPKMX_KEY keys = new KMX_KEY[kbd->dpGroupArray[i].cxKeyArray + 1]; + memcpy(keys+1, kbd->dpGroupArray[i].dpKeyArray, kbd->dpGroupArray[i].cxKeyArray * sizeof(KMX_KEY)); + keys[0].dpContext = new KMX_WCHAR[1]; + keys[0].dpContext[0] = 0; + keys[0].dpOutput = new KMX_WCHAR[4]; + keys[0].dpOutput[0] = UC_SENTINEL; + keys[0].dpOutput[1] = CODE_DEADKEY; + keys[0].dpOutput[2] = deadkey; // TODO: translate to unique index + keys[0].dpOutput[3] = 0; + keys[0].Key = vk; + keys[0].Line = 0; + keys[0].ShiftFlags = shift | ISVIRTUALKEY; + kbd->dpGroupArray[i].dpKeyArray = keys; + kbd->dpGroupArray[i].cxKeyArray++; + KMX_LogError(L"Add deadkey rule: + [%d K_%d] > dk(%d)", shift, vk, deadkey); + if(i == kbd->StartGroup[1]) break; // If this is the initial group, that's all we need to do. + } + } +} + +KMX_WCHAR KMX_ScanXStringForMaxDeadkeyID(PKMX_WCHAR str) { + KMX_WCHAR dkid = 0; + while(str && *str) { + if(*str == UC_SENTINEL) { + switch(*(str+1)) { + case CODE_DEADKEY: + dkid = max(dkid, *(str+2)); + } + } + str = KMX_incxstr(str); + } + return dkid; +} + +struct KMX_dkidmap { + KMX_WCHAR src_deadkey, dst_deadkey; +}; + +KMX_WCHAR KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { + LPKMX_GROUP gp; + LPKMX_KEY kp; + LPKMX_STORE sp; + UINT i, j; + KMX_WCHAR dkid = 0; + static KMX_WCHAR s_next_dkid = 0; + static KMX_dkidmap *s_dkids = NULL; + static int s_ndkids = 0; + + if(!kbd) { + if(s_dkids) { + delete s_dkids; + } + s_dkids = NULL; + s_ndkids = 0; + s_next_dkid = 0; + return 0; + } + + for(int i = 0; i < s_ndkids; i++) { + if(s_dkids[i].src_deadkey == deadkey) { + return s_dkids[i].dst_deadkey; + } + } + + if(s_next_dkid != 0) { + s_dkids = (KMX_dkidmap*) realloc(s_dkids, sizeof(KMX_dkidmap) * (s_ndkids+1)); + s_dkids[s_ndkids].src_deadkey = deadkey; + return s_dkids[s_ndkids++].dst_deadkey = ++s_next_dkid; + } + + for(i = 0, gp = kbd->dpGroupArray; i < kbd->cxGroupArray; i++, gp++) { + for(j = 0, kp = gp->dpKeyArray; j < gp->cxKeyArray; j++, kp++) { + dkid = max(dkid, KMX_ScanXStringForMaxDeadkeyID(kp->dpContext)); + dkid = max(dkid, KMX_ScanXStringForMaxDeadkeyID(kp->dpOutput)); + } + dkid = max(dkid, KMX_ScanXStringForMaxDeadkeyID(gp->dpMatch)); + dkid = max(dkid, KMX_ScanXStringForMaxDeadkeyID(gp->dpNoMatch)); + } + + for(i = 0, sp = kbd->dpStoreArray; i < kbd->cxStoreArray; i++, sp++) { + dkid = max(dkid, KMX_ScanXStringForMaxDeadkeyID(sp->dpString)); + } + + s_dkids = (KMX_dkidmap*) realloc(s_dkids, sizeof(KMX_dkidmap) * (s_ndkids+1)); + s_dkids[s_ndkids].src_deadkey = deadkey; + return s_dkids[s_ndkids++].dst_deadkey = s_next_dkid = ++dkid; +} + +void KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, v_dw_3D &All_Vector, GdkKeymap* keymap,v_dw_2D dk_Table) { + KMX_WORD deadkeys[512], *pdk; + + // Lookup the deadkey table for the deadkey in the physical keyboard + // Then for each character, go through and map it through + KMX_WCHAR dkid = KMX_GetUniqueDeadkeyID(kbd, deadkey); + + // Add the deadkey to the mapping table for use in the import rules phase + KMX_DeadkeyMapping KMX_deadkeyMapping = { deadkey, dkid, shift, vk_US}; // I4353 + + KMX_FDeadkeys.push_back(KMX_deadkeyMapping); //dkid, vk, shift); // I4353 + KMX_AddDeadkeyRule(kbd, dkid, vk_US, shift); + + KMX_GetDeadkeys(dk_Table, deadkey, pdk = deadkeys, keymap); // returns array of [usvk, ch_out] pairs + + while(*pdk) { + // Look up the ch + UINT KeyValUnderlying = KMX_get_KeyValUnderlying_From_KeyValUS(All_Vector, *pdk); + KMX_TranslateDeadkeyKeyboard(kbd, dkid, KeyValUnderlying, *(pdk+1), *(pdk+2)); + pdk+=3; + } +} + +KMX_BOOL KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { + LPKMX_STORE sp; + UINT i; + for(i = 0, sp = kbd->dpStoreArray; i < kbd->cxStoreArray; i++, sp++) { + if(sp->dwSystemID == TSS_MNEMONIC) { + if(!sp->dpString) { + KMX_LogError(L"Invalid &mnemoniclayout system store"); + return FALSE; + } + if(u16cmp((const KMX_WCHAR*)sp->dpString, u"1") != 0) { + KMX_LogError(L"Keyboard is not a mnemonic layout keyboard"); + return FALSE; + } + *sp->dpString = '0'; + return TRUE; + } + } + KMX_LogError(L"Keyboard is not a mnemonic layout keyboard"); + return FALSE; +} + +KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, gint argc, gchar *argv[]) { + + KMX_WCHAR DeadKey=0; + + if(!KMX_SetKeyboardToPositional(kbd)) return FALSE; + + // Go through each of the shift states - base, shift, ctrl+alt, ctrl+alt+shift, [caps vs ncaps?] + // Currently, we go in this order so the 102nd key works. But this is not ideal for keyboards without 102nd key: // I4651 + // it catches only the first key that matches a given rule, but multiple keys may match that rule. This is particularly + // evident for the 102nd key on UK, for example, where \ can be generated with VK_OEM_102 or AltGr+VK_QUOTE. + // For now, we get the least shifted version, which is hopefully adequate. + + GdkKeymap *keymap; + if(InitializeGDK(&keymap , argc, argv)) { + wprintf(L"ERROR: can't Initialize GDK\n"); + return FALSE; + } + + // create vector that contains Keycode, base, shift for US-KEyboard and underlying keyboard + v_dw_3D All_Vector; + if(createOneVectorFromBothKeyboards(All_Vector, keymap)){ + wprintf(L"ERROR: can't create one vector from both keyboards\n"); + return FALSE; + } + + v_dw_2D dk_Table; + create_DKTable(dk_Table); + + for (int j = 0; VKShiftState[j] != 0xFFFF; j++) { // I4651 + + // Loop through each possible key on the keyboard + for (int i = 0;KMX_VKMap[i]; i++) { // I4651 + + // windows uses VK, Linux uses SC/Keycode + UINT scUnderlying = KMX_get_KeyCodeUnderlying_From_VKUS(KMX_VKMap[i]); + KMX_WCHAR ch = KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keymap, VKShiftState[j], scUnderlying, &DeadKey); + + //wprintf(L"--- VK_%d -> SC_ [%c] dk=%d ( ss %i) \n", VKMap[i], ch == 0 ? 32 : ch, DeadKey, VKShiftState[j]); + + if(bDeadkeyConversion) { // I4552 + if(ch == 0xFFFF) { + ch = DeadKey; + } + } + + switch(ch) { + case 0x0000: break; + case 0xFFFF: KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keymap , dk_Table); break; + default: KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); + } + } + } + + KMX_ReportUnconvertedKeyboardRules(kbd); + + if(!KMX_ImportRules(kbd, All_Vector, &keymap, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 + return FALSE; + } + return TRUE; +} + +int KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap) { + + KMX_WORD *p = OutputPairs; + KMX_DWORD shift; + + v_dw_2D dk_SingleTable; + query_dk_combinations_for_specific_dk(&dk_Table, dk_SingleTable, DeadKey); + for ( int i=0; i< (int) dk_SingleTable.size();i++) { + KMX_WORD vk = KMX_changeKeynameToCapital(dk_SingleTable[i][1], shift, keymap); + if(vk != 0) { + *p++ = vk; + *p++ = shift; + *p++ = dk_SingleTable[i][2]; + } + else { + KMX_LogError(L"Warning: complex deadkey not supported."); + } + } + *p = 0; + return (p-OutputPairs); +} + +void KMX_LogError(const wchar_t* fmt, ...) { + WCHAR fmtbuf[256]; + const wchar_t* end = L"\0"; + const wchar_t* nl = L"\n"; + va_list vars; + int j=0; + + va_start(vars, fmt); + vswprintf (fmtbuf,_countof(fmtbuf), fmt, vars ); + fmtbuf[255] = 0; + + do { + putwchar(fmtbuf[j]); + j++; + } + while(fmtbuf[j] != *end); + putwchar(*nl); +} + +*/ + + + +//################################################################################################################################################ +//################################################################################################################################################ + + //-------------------------- void fun2() { std::cout << "Hier ist fun2 von mcompile.cpp ...\n";} + +void testmyFunctions_S2() { + std::u16string character; + KMX_DWORD val; + + for (int i=0; i<8; i++) { + character = get_character_From_Keycode(24,14,i ); // all Shiftstates for ´` + e + val = get_keyval_From_Keycode(24,14,i ); // all Shiftstates for ´` + e + wprintf( L" ` + e for SHIFTSTATE %i -> %i \n", i, val); + } +} + diff --git a/mac/mcompile/mcompile.exe b/mac/mcompile/mcompile.exe index b2be5f8ef9202f6664e12637dd09cf0009cd18a4..a07e49629f43c6140b7518a2db79cda50163f689 100755 GIT binary patch literal 236784 zcmeFa3!Ifzz5l5(~r-z0uDHD^sY<>d2E zo^qz1CjV^Vwp zz&!X?oJaS9EB{w!YV&ClH8l$sUUTt+{G;Of)(?*?a;nq`{&XMKmvQxhL;F`#bLq^P zHM1AZoIP)0&B7TM7uRP-#`QJ$0^Eo7xoYy4nwpsl7S6xy>Py{|;`$ms64#e;=+k}p zS6nys&Aoa-0fEK!Wsi&N+s{>_`{Fvn`fF;gx%#u0T|KMjva2td%ZuXr){k-h%fzL0 z-+g_v=hR#>f5ug_;Nt?$a)<%kIX^32rU_=6Fz3GjYPy2{qMco^f`} zeejnBvC8Fk{AS#}>eNqt?Z*$g&MjcA>-q+kky(G#7xoL0GV|<<_+Mu_B>OjTV%)#& zu8i)(`hu!#vLL6EPd(%GlP8`ULupK{htpx5d;M)66yNL4k=i~VO$ouPa{Uf5=2&;% zZ*63@^FpNt^2;o<+`Y2=wn~6 zJgeX*F&TBug88GayzJspvld@Di+lYY#83UWqvK<5nDdVveCz6t3HSXxwc;3_Rq%^p zqL#8fZQA0l@8Gh-cxU0`s=rF$Q$1r>*xUR+wR;{vy^AsRfK81$d+~yWv#%O8`Lc`W z&zQe>)W^lDpPf7ZiUp&pXUxBN?$t+H=GBu?=ggkJ;4-9b)CBjA8dUF5{POj7tc5kA z0*t^p^YFuuJo-q0z3gI}e{7IHHERNzD49R*(vc^*BIJ(Sks##TF$>F$x!rWv|GD#L ze|+vWSI?TUkY0BIMm?&%gGvnX?yk-HOj4VEFqGKTEfNk4y$) zj&%3pL;VeQ_eXs#ZPt5ZVc+cfw+jQiFt7^)yD+c|1G_M=3j@0_unPmbFt7^)yD+c| z1G_M=3j@0_unPmbFt7^)yD+c|1G_M=3j@0_unPmbFt7^)yD+c|1G_M=3j@0_unPmb zFt7^)yD+c|1G_NrzX1as)zPLMOUl;mNJsSzbwk@$rH8gP)YWjUX*>I4X2p&r6W5Wa zeto*;nU3l-dHa$#UC6t}Y`W5z6%FZV)8$-Qq1b;F0Q;nW65M_leV-`-;WE*Dc>>Secc6Z zkB&DhSUbIerNiKlthgt{c|4*k33l^>Vjl~Vj6eD>~Lf*0$gt9rq==qmJ-)eq1{cxL&&?fWdtE45RG z3I793lkk)qP}P*_Wsc4bxc9)NkzrSc>0fDTr(~OlHs%g8P3)uS-?Fc1m%QhOnx+=& zoC!>N{wR5rSNSZ?c{h!B4b3%;JC>Y`oW#1(zT3B|{iWm0imD#q;u^tcWw;3`t|jx9WT zR!LsuzG=sjk0Zk|Ji@8PM{m=_TJ-+my>wQ1ul5GG_ADM~^Q*2+-K&kg!uPcu4wbGi@EMvR1DJWvi2R&$rtF zA9M`hcaUkHqH?>hKY?u%C*%&QYR_a$`#C(TN*i_x8M;*aqp;iS7v0~ed-ADo|K!s=ulH&C$?gj)(+S&)PTH{~y>3TytcPW%H`9*q zx5rZ-SI>?m)$2Oa-fo*s>Zfqf0d1@;Z!X}j1)Z+`iKcA0u>DKm8Tys77dCIPy{M)w z>Jg0jwn~)0o_0bTkU_>wWcDf5w;X-TTxed;jk)*0IZl4xg1;I}Oov>m_Q@=^iT!;2 zH@NgZq*cy9k16mPd)HpiiKj&))z$mn12>ph7uaW_8}CI|-K)NscWc_Z!v*@@!rBTR z#2X<@rF7fM;yeytswa=H<^pX(n=5$K#|MGk_SqP0b->eIl(Vu**^%&Tru^r3!mI6f zQOC>ld7IFSN*FJw+DSU`mTg6`%7vKX}#z5a3u&^)imE4!%5l7cS;QDg<(Bk<7x|$tT zPhC%b;Z=4|?djPtaKpYD`@AP~SKrx})g`@6RQu!{+7a%*_|aIV&`}~CVFLFI; za#j0W-WT(T=O;EWCF^$hLFW|kQrB57CsF6lc#us?$vma#QKD|?mL8RDPV%qSQP6EK z%CC2{5dA8-cRHuP?vHf$!oTp_6|ad0JdeGB4e|7qorVYY(J%Yv(6QF8Q_sQFo0(QM zE^}S)vonLue93;8Pwi#jtQjl)lW4O94g>=m9_d@)BbUf0-G~lK;<-e=9^tdPgibAC z4?Lb%or3K=-E3kz;)*Q3u5?BNSN6xPXaygeCG+6>IPoRdgso^!(oX((9p!WF<$NppvWh-oxBj29bt{1>!7nA?+ZpYyD5BjL$Gvyj%_~K_ zbPAmJ#=j`U0an)yY0E-G`7;BNv)U-Ow=MW9kERE=JzB>vJ)~_J^);k_2dQgM$fl>a z$xc`qCSSI0dRq=2QXa{y*U?Lzj#gdYR(bM0%(WtDV-?SS%roVALD!*1I=8>>-_pJK znmm6a?ftI^JN`Sp!-s3dhr{=8$ER;^8H&$^54XR@xRh_@exOhDoUQKmx!N30+V-D3 z7m?ODV>Qp&mb@azvvs6RukvNBcbWQ*GtJ^@Jm0b86#T7J>|50(^>PO`O7&S=6ICsa z&{IE2<3~DQCMVk^|0BqkDUbb;H#<58wD5js{PREA7i9l^*Ybg%E8TSw#ZKzRU#kx_mkLgB>+yT&|{S9Dbkm-&K#^3-8t! z;9hmfNAk}t-N1j+9}Il!B3fU>c5_p^fBoL{t=P7ovIBogV@bwT*ep8^RsS;|rVk_T zJy6dbpEMb3ivka#u_vQ~Lv)woyos-5z!<{^!z9e`b&aR9cl&ta7p znsN7#cU|-JMr#+N@;>F(c9tKOnP$c%>_HKHvdgzpcAsLJH5crL5$J#`2zPqAI1Qk$CClBt?oppZi6o?BeOU^W++vzE~%Hr%RTYYI9VZ~pA_HR zkv8?j+<5+@tR1tu_7MMW{qvsqd-CyZoy`TA(s;!%wmlo1Xe_Uo(B2N0vJW>HvwYYh zJGNMUQdL#^dE~P;k$1AcHkN~*btcb+f63tSW591w8^!V6lJS6`40e2Z<{J~FNA37I z9IvXMigS#o9rdv!uRFYn7J1qQ^@}fx$9oS_UrhJpc&`Dz`{UmW;{mm2+OK~q4a|x0 z9?vGA=T}KrfY$;)24m^E&b-nS+IfDpunso$=Jo3e{1Cw9@g(2cj%C1=d_ehI+rX9L zRuMi%+-A_PE@Vz+<)>^$&f-{*a3Aa1P|iZ%TDH{t_tqzZR%$l`U)lI7xRLCN*WUL! zs^xEHkfRjy3Pb4o5PYn`%sovfJ-zKv^`UMM>A~P+njOPr(-&G_vZ3z6wo`a-$1?PJ zi^em*H}yyHOg>`k@YpYuk2jTPikDiugHNckt;4I@Kdt8~2fkYCcu(B#c%F5JdlGXj z&abNuV}?W8S}CLc&QV=6WBwOTTZjYC^!0v<+zke6h`>uFdd< zVrQNE*|kq1+1g5(gbx|;qPN%a*s!WyvE@g|-xE6>+WDu8+X&zhzlU>+ud9A|-|8az z7xI_&@iZ=U@q5wepdwvWs?Qpm_oUClM@4a81AK(CX~$(wk4ZKPG0#9I>#$KpvJ{VX ztSrTPFCvZo#3w8{Mo^!6reBggn4>=Vui{17-W&xyzyia-n9BOQ{8F{gI zl0N3yHtsVT%M6eCS2EO@w@UM<^0m_DX6m;(40_)3w~nt@xiOr#`_hFebnZ`%i{laA zAGbO(!sjApH_45K!ZMj&=JgEaQjCSZOIh)Xe)4y_^v44_mf{f(AS%rxLAn1f`u~LS zK|)5mksrl&-i`d64*p8ndON-^vOyQ)@5u&= zm?!<*RwZ>OXj0eNZy62_dJ?mg-{8jyiisz9u|&N+(pMp^oDGnkx)HoJxN*4Xx8fsa z1%7sarKOi5>l<6eX*feJpR<&^eXzX!?n4Jn8)T(=f zdbD{^V-_8gO%EcLeGvJkG4?X`>)^3+^v_7ne!d7$n* zn{Q;)=M|3RB>w^UBL`CNfjXfN9d;gd-PxE;4`^$Gzq09b#h0&W{yNh;=1ZH0u}HRV zfBfP*8k->(#bJ`{jHv8O9Up3a` zS^c+$N1INMO#7+5kdqV4J}Km~7r$>lWj38i9kQDZ)d$*ovE@_B_jvrkk=OM(NVYZ8 z%X~&LFY%S-G1|)zPkDeot%Hsud-YkyyTzhI*1gN72QO0IIRE*L)UkIK*ndo{x}ome zHt}$_dB3E7c=Ld%v>-}3yzGu!71_#&JBR2%Wa`bWV>J|@!@A7Zz~PYoIAkfiQRtcQeeR>3z`U*lhU zzgqgGayO@6kT3bwC+tpLr2m4ivp(%;%=0&N?|obDk7ORj>r{lUBd2uR>dG$7qZ^RB@pGK7Wn!1E2C=qWr+;^KWzcMN8pV zV}+z29r*cmrRDuDbWSJTP#wqUYz(fKe8!kYUqQAE_e@jycw{n$LX zaW(Bf3eP`EU*C8A*nB`iKQ@1(QTqBb^f!ylgIB8`b55>e9g2QLhpr;8@>%^@hkk6n zkl+4|9Y;I;SciUWcKR`W?z_^Df2EGRex%;6^dtQnBb<62_yB!cHZBXgmR<=5deT~~gPoqLJOcbDGGrq2hS{kTfs?Y~ofw-uT;phK|> zophe3Gx7KB=8y^PGmP0d?BV_EIYzb+t8VUWpNq$BilbbN?$Z2?)gQ=f7JU-h-eOEY#PfU%^lJdRF|0j+fpF*WdkF<%`zeU5jm~Dq4T{ImQxJr%I=29u;}M zl4qK8P<&rCroUntW?~8h9TeE&3(a-_<4cp&us*KU2}+iLp`y0g_9!0J#hAkfTj7)~$~9 zxrcEm^HT-=T;Ls#SJAB`jf-%m_T)1b;0^ps*QWB6YD;!bacDai0RB{ug#o--8dGj( z`1A0K_9OFf2XVYobc0T^Q}Hj>{kc@E3l#G*ycGRP-! zh=OdL%zeyrL4S(qkRyL4q(uq*M)=c;Z72A#I*b{{vZmPG3fl*KO87yvUe3Mb$d18* zdrWu_3`@g%>}tySGVz$*wATjjv)GUk+zZCnpv|k`>J{YdW$SZHm;Y?r`C|DV%c{$F zUsi?>fK8&`fe%tdk5C4zA4I)Z*)jpnif|%7LvmKU-n6T+PaXBiC&AWq@?*Ngsbbq! z&c!digq5b$m1 z@K~R&XD#6I9NsH_EB~~zmx2ES+!f)$%d+U9m_rhlSl$z|S6$Enp*-4kHS|R>oGrk* zmHuM~O2)J;?&0|ya3E^(4W8X)EDt7zsww;aA3#1^uf<Sg?5t-*)xcCFuPcx3TWF+a6X#;#}ITUXPr7)ZF6A>=jXm0Sw9p6~w8D6^vX zo5T;&o!5+c9Xo`!y-k)Z{FNA_zmKrdH&CbT8-12s|4DILXeVD|4f4>^Z0heLk6k|o zueA(^-#t9&5y5k^hevggKS!R7U>a`P?{|GxJvq|h`YiFV<(Uzz!{L34%WL6dOmPkH z{rZj4@sUonFU2>_1sho$x0T)Ux=XSikEH_r)lFGn?gZdY*t!z@r*n?iO80j;F785iNf&zF_w(>uz{?x1 zj|qL0?m}*WVLuB?Rr?vTt@Kg$A%Z4~_x*;kx1L4lRPpU5?xp+nzNOC8|59Uf@Ue<< z-|D&x+qP(I%pCZO;N&IvdYQ`0?!p7vG~+$wQe~`MQtvwI5`Ao)!%Y1Xyc3>uU%`EZ z9sQZw;MpeiQ!w*x0MERhdDOjE8QDQwXJp#{iq5uqDEkxgg!0&xE&e_+!p^aV&c2N1 za85*Kv+$edWaQga^UUiT(N#Lg$^(6toO^#Qw3(sa^SbUj>MicyMXcX9V+Yg^R16im zl!|pqR;Sa4gq(JhcTjQOy5x96bp43Ula%FfUyip=M-}DsV?xb+m5Pmtj`FK*tcZR$ z^p4k#H~4juv<)t0GcDefw)nx9NWe#*L%m>i2)rsCBH!1_F!E?Lmj}PDw|k0X9brsc zVVz6~*n6UP8S-{oHh(Lf2(7D^zeAxqezT5PDsv|L(9bFtkBR$A z3>F-H7W(*kcS z2jm-DyFJ~G)4%C_X~p>Ew|pYJr@ec^d-TxB;XQP?o%>c~vv^z%|Kb}=Z@_ii@v-_t(Pv_lft# zi}0T1#omq=)9@m^*9z}xoz)g#*-HB_0#B~l)E^?=-giA^?uDm4FP_RCa<{&)Iq6G? z54HAKefRcuKTC^(E{OGPau3y6AMWh42-ZeulE7E9c+TxNcXA?|wgz~&GA?|PwUiC% z-#a*g7dTt?T7N=IH*m%}sIZSbv8Vk5Yophux99G+ZpV`SnK$ZX*TZ#3w}$jL!2j>~ z-NEnE(D&2O_dMV}j~Gt0N%pHD{oMGL!$sHs8s9R)(RV2D9}j&`tZJ8jW8Bc*dJ4a@ zq4&Aa`*i4iCiJex-#$fS2_pyF!NdGp*eGzYItRnu_ys+rIjWr1x2fqyMwn4iZ-tSm)&bqhfeu_Dw zUa`NGE{r`SA6`Ftx?6gqTU*ejT0eUNb!6eo*smT8u2`chSi}qPxMJ**!%qFEqaWy= zZTLs3BjN7{e5ZA{(sirR(QDwnwea4H^#3L8*`lnqDb?7NI;(f*c z@Ohfh9r0Km{q{~gc4|_LQGGnL(Wk;06^VEaxDNH2t=rmEY^!XlqyJ{`v;}>p@s#wC#tEW{ zbhP56>!4jcf9UmDVIQ1qp^dWy>v%^V(OEayHJQ}69J+=2$&L@8yKlE84cr0W#lsice{4ixcT_lcVce7toDSkJa|pbeWB)p9_voF6q|@+H39va1OLLo zr#;2e^EQ4>-xOcoPjj#682L!zBfE!KJWjlCPC!rX3pt7RqL=i#-IJ9e*ZkutT^+v(y^W5@$tWFj@sFTo{T3; z;WhSC;YaF`&C;4R(arkA^jCDd#P&77Z3*77;}*)!QJWF zC&hI%xECJ#N>-e`lud5M-pEE`Q{t&Hc~dW19>}(T-HAMOY5Tsb5T3v z1L|504aEybBO{{Co~~cocda-ko6BuXK{T>5O{fm!_OO|`8v6WI>XzQh4Ug&9bx!K=+Z)Bh!PA8@Kao#vXbQC6>r@0HfryUzPd1)DE?dcN{{(Z*Pz zll(LBn*6~`IlO=zXdIHTWhHRv=dG=-r2cTOM&p!Xe1>={wtwbN}c7zJl@cYlKly3gnqDl z#iV2NG=e_XUwtogfC2wVH+q}qW969{RpYYWF40%0KijBR zJP?s?m}xfcF1sh*>J>k0nF)V8dndgq*|)J7bY<+f1$rsq89y$y>m1-?;nnsH`il2H zMx70AubbL~SM8YcQ#`kN272C(%=sxzKkUP{8enR-M7VDKmwOReI;o!EJ>5^x%JqcXcE-p`=vaRi?3N(?A~9=pD#oI z=WsrQWH>S3%X;~|KM!0N{>k|$f)RR%mLKJrY{6f+dVlaa<>Q&`fjy_?0_I~znZOF&aJ(l9r{4d`Js~<)oSLDl$vOHe@HI;Gu znsJ$$3B&BQ|l8xk*J zAL@u3xes+jfAs+x**-#>uJpe2wXgHkqB>b0lh8YRcc*ts$lo>8*OUFGSCB8ZzrmV@ z>ezRZe(P>LHcf31pGwGeU13Zi_`FPO?9i~rZ2H=VoGm6T{oitm+naGpRnw$C@t$Ej z&OpY}=r7S+XNSqw%Fh^i12lt{<cl#^PYh5foY)|m5Vm#c&d-YLkrNTWaTB{J=3$G`ESNyjA%CGy6IXr8eWS=2_ zS)LWQbG^%Vzq^Vb!*NsC&OI)VukWTq&5Dk%K%S2V<(B*}F;vqkv-{W|<=C?GD z$2|6%gT@N?R>uT7K+hC&T|)n3S&q+B5Z<(><`Ll(9h?Kl>(FIZ_y6qP13lgKOz-S- z@};S#gRABs6fpC7AOh{hSK)%SE&93w(c?1sMcdVDi^m+8H;AF>_WJREA<>GQDd zN_Yi+ZnE(;{EK|tjrMMXM&f~v;Oy+1c?RD%0rO`B&m0F2@reE@eh2fjI0sJ_f8F7T zJi?LIS?vr*8S3@CqZrj(%6K~4=S95Nf;_!>h*|Lo@mO=`F|gI0;7`8p=Y+G~MY^^+ z)??yJQ(o27l`hkJ*{+p>0lGx>RZUtak+(s5R#rRZcAjk`of%~It*m!)uY2+vPF>L2}_TY>$ z^{+u^wd33U6}0cvZZJ0V_C-2P^b;?IHexUJ8~zY)sUFc89t4iU9HD$lD=)$P*bL;O z)R?d+Slx1~SkyPHazgu|ZPnH^zbsyRHeG+2;)h)*lT_im_>J?mP!`ZVP&t``)Z8 zvhb6>(!HbJjb{6R`Z9Px@6=Wc`Kx%(9;f~xzc6Q=xL2L$yLz-|BFw8gM)6K_BkJQ> zq~q@w6y|Exp5C46>acx7w!SkQ9WL55i%;BI5oq{2{yb;D+P#k0w8qRZ^!a~qj*r{F zNj$$%=WdyF?UWxywNox9ziorEtvr93dTkq|ucv;cRmSIkXFKxf?1t<`wt7gT+Id-P zEUT%Taox7GsXr_-c1^j(UCV*>j|Kg={jz)0hcy1SXnxPGxeWMH_VGg35BW0U(@%3B z&JXF?RF}v09p1ehI39aR`QrVx3Es#YP=6nOYJSaaUBN$<&fu4r^RZ`ZFb2(FQ?ZZn zxf%#R)IE>esA~V~ z!DhuLX}6UAmGAUgsc(`rci|h5Uwa;8mukzcUbOoktWPth;K!*SvN>yk$HsZwy~lIH z?lqUO&S`JfIqkzbr!qUwA~|QxY;fMikhUDS*ZAI))js(c^|rw0@_D|`xJ9tG!nbz* zg1$9tEQ5}cucz3**8Io#i0ZeJmajUA`nx)N;YZZJW62cO7=4m8MrC%*gXL@5&^X8H zea0y($!F;tJX0Tj;o7rpG9J1e8f<^DYZ|;ziUxH(m#dL^Ug7KsWa~?;2g=J<_25{a z^+2}1M;~K6#j@2#zjg0r>*HRQL{IqnTH3MsNmo1GhUe>FbLE7Kmt9)aQ8itt=k=3#j>^BJ&$q390YZKPIRpnt>SYZB^#~iK#gHq zm}Ap?A=i5O8EeU}7-)74-@D4=GOAz2^H4wLevRFqY3vyc3tYeD6Y1G#k8{#<-Mdg% zsBG@nd>4SZLK_!GW-Pys!55|<|K!Tx`}CJQ`FF%a68CEBT$h(`B=na&J?{8J@HYU% znY`bzq;Qs`o}K2(SR65C|Lrid;%MRM-O72d+9w~UE-&YYJA8$5ek{*IInU!1dQauu z&gA@Ow*Nbq^VQ@lCFk1PAUG|o$oWcO{mWLt+J*iUZ$SS~?h*GpsRz3+^FXOG)dfFS zd?%iZ=cfzjyJ+q6E&arInopVDwoGaCtJ1fT7GJ4P8gtk+m*}{I%lj;QV^7hx;O};2 zKmLP!()S5}^gYm8yyR*9kmK=?)>`Kq(wZ@KUZYBPwpYDM|45!^{!8z*2AFn z64APcG-yRXc^bT+w4=d-u4oYTSvItP5e;_2S1%0&htTug@YRN#I+ES!y%^c9+*)BC_z8@uuqzDxZ*@fG+mT}d5M%vZ}Q%!(Jc z^qj8-YMq&rZM){o@zo%=j;WJubN1D`Aw@K(?wS3vaaU)*?soDZn=%nO=*oUI1CM0J z+pl)k!&(`_zC7yQy&L;AlD1U7C-&=pSHHJkKXdmgFI#ml_r><>&LEGzuQ7uA8$^$t z$limYP`Yysq#$x(yyPo(I^~<08 zrK=}F58mgluNpV0%#0Z7^}u#g5w=jH=@%Za9a zTQlFJtv2 zX@d_TeiRLCUhZ3Frs`|_J?&_Ho665HPA@czKT~!rf3eG#JDq&Uf!4;YC7=9h`OTZ@ zqaWYrR2M!EW90bkGCxNRzZ^@SY=0;}7}>RH+Fb+vY?}6bTk6Ztfn{erGoCs->M{wQ zv9bU@a$`))-0Uu%BzT_QPl-I@)g0j}{4DN-K96TsEJX}{f zxIAo!2Yf5|>K*Ou`!Vd_NB>X$2l)7S{P~i6jNdq`Z<3FtH?`g{f0noKWpx}l!Pm@i zE+aIw^Cr?u+lce#94*~C-`Dm18|{Tr{}un;;MXTnzMONkx54YGNAuE$asM*y!Pkpz zd959QKVKw%WOlElW~A}4>;nz4|T~Ht@P8F;24OQMZ`-%N)J3Y4((I|5HaVrLS_dPT1FPGd`>~^{dGL3beFvp=b4M zm@iBE5AIz;pHnvX?W%E086OT1?**}o;YIgq{}ZnLK}GM_Ly;(}wtwN;vvElJ^9bfo_$5@HvIVzHf9~zKE)y0$*;PsoCohz*An2U(J1>m#1h9Eqqy6EPU@>_UzmcvZlRKl0BVgD%pF0`b)`P zUY3!&tdno`Px5Bzi;RWyNE&a-7i#6~biG$BPwhYxt1JAxvVXpfv(@dK5cba3uXmDt z#X)R7`X}9^eK9(V-PTo{AG~W#1M>D{j1(($3}*gezBEX$NrKX7HY zOkd<-+TeAl@CMw{L9#U-m*PVWpdUx6efzU?bfGOnZ}Vvbwi-ZDO8Ta;kY%E2rf5@Pzfw@$~|` z)$8Qfd&M}ceV`87Ui^mmfM?=C(Ilj+<-IQIw|0vDforQ55^#Yt_1*SMu()#sJZ_~c zMp{0O=P&a(aQvNk&$(#Kxq5tC-VJf}ociBIIknIDr6~_n5kG1Fr@nEae6g-8$X4DC zd-%Xnh~NDCkjFfa2X;DB7Oy{2{RWtSI|zP{=Wumi;Nqva&&9r76Z`4yHxWEOe4j)! zk1u`OT;o3bPCSiVSiK_N0UnDBw^r~MdECVQ;m+#SdKS%13Lo)2Vqs2Oy2y{?bZ)QS zf8YA+!5T00w?8xI{o16p zmwN3wD6UrCShJS*6FqKDG>h%GWNg1;JCOB#jb+#F^N8z@-!FA?rEj(q(~fmE<)t6h zPD0K{9!-BcJg*7 z$om&pH|sW}cddODe^O@*k6;5mbC^Tp2a`Em(-W}F|{6+XkZ)(35s!s(xPf>XgLdo7%HvdeYy z7Yk=EnyqFO^9FA}iVv;4Kf*U@pnaV;5wGoweT7r;i8A{3612*%V-DthRW{97#-DMZ z^P()Dh`#7&z5hG)TG?}FV^_Mh74ik8(>{3+J}TdckUVHSH!@gN<=0BI-)=a#Ej2 z&NUC&Kt9FpG+vR5BT`o%R{9_}-o$=gZrC=%Fu% z`G|{ZT=Yj^QQZ7Be8*SOBd?%G9!P7gQQ?f{k=N~c*B2wsX^uFj86BYYGzl3lk}o*T+BnSU=N?mUdJDWOu4%`4_z6q>eiQniIH!3==X08u9T@XVSLZap%6r*! z*_p~-S_9hkT(Rdb@gwn#BrY5e3I|=SC${A&`@ruMGfMj0VQjIdXE$$Qek4(k>x0H# zmEe!@2IHLq?(_W${Sox8_F^c`@=q^dE1gdzUcVjO$j??*LQ!;^Rd)(^YeY= z9|b1CBiV|ekz(Cy@A z+8BH28>?s-00q`jCjk(^%s)g=ArCY z$&)w-j{f*qQE1!GO?!C>__@fAi$0aK|7~QLxmmkjKz`IuwiWczs+sY*&#QT+K8vp6 zeffMLZ55ZXdLsC?LI?F0>xBxf`{&%}J6lTY4CXMB_PPi@Z&z4jk<3T`E&Ojr->Ldk z>l=9+T2x*%?qrjES>6@O1wN*=Av(XZXJ-}5CzLKGu3_Wwc^RU9jhXCx6>0gS+JAop zSLqJnSFtVOS8)sRtM{#}9>5pYp4Va>BOR2{JL>Yf2fq9tcW&|N#WXFVouxf?n7w*Q z+BfgqhFovYW{P#KK^|Er-r1fwK0ww=k57VjEUnNl(%@R}{rO>JME(Fa#m3qE^9bMVamwgjL6-)$uM}>8t1I5NxI<MpoI6mcb;8=6DKT;m)O!^_6DVwGIn~@ROddWvE z`1kd0@NH1`Coa8}*h$N9yVrv1%|eV;?81w10!$)E9lp8EL*>3I5D%GO&Nq4z@?dH+MY zAOrn`59@o7mVL2$g8F={Ge7?V4Z@h4{9yG%XCXg>EXbZ{O|JU)B=_*Iz1KK-VQ?>g z+(w&zocy!ko$TOc+)H=)@_wBB1Dd#q_MKm&?E7ELP64)%hHoS(hpwT7A$NTh_+GTQ(2pwQ9|t&IPf$9=-fw;RJZ> z7z`bSzr)^$8ts9~x9wv@b6kwQ7Mz6N;S6O}V|UGI`Ej#iAi}rT`}mYA8vJ=9wCm&3 z$M9TwPCWVMer}A*d!4h{=?tlWww4cQ!^$)HMPCn#)&s^o9`Hq=qkJF58zac8^{~=g z@{e^MqH?S)vPHKpU`Fw8*Gfuc<(yCrE<(KCVil~q;Bv&336XQCg0~k zPmo{mS(|gij}m85=WR%U6TwxA-;d}4zwZF|rTD#*uTs>Woug6T(yZC!ymaY`4c12q zaop9@;L{HA4Hnp|Dtm_Tq^YB*3b-^hOOUO9QQ4vhw!Mr zNETw+g>)#`X^kP@?K#7LmtR4>;z@hXF!sol^L-0&U~vV{r<@FTb>%XY%g^SYwr-X~M3hBwmKPGYaIPYDbedwxNHw}6*y zy*KcE?x0>D^X2UFCgEPXNN2SDoxM8JL)OkK9wq;v2SVlSG|RCSW-6?^SAQ;$ibZG zZ-Bp0_ll1O{1%=9=hA`Fm+Fu1<#%$fS-WW^E(3j1{c4|lLv{0R=rn`>QtW@=Bc@oUbVT=Z<=J2O0gQhhs^d>+P(=9sZTXYx$@m`}2GpbMd)?x*OU zzDWM9uctK6Yy5L~V-acLr8_xP9r0XNK=S|}-q*?ONBo5O{yA=K#3cIf=RLCYU%FOj zI4pJPeMDdSW`N^yXo4Le{sK?Zo~?`Z85{f>GCdQ#y!U*e`jn3KZGpdw>FVu6EAXBJ zya|3Rp-Vc!T3xU+c{>%rAL@yJ`1yBq)@g$Gx@gb$Q+vT}Ke3mIat>zEJ`b~d zX7lf1>iL#a;rnGlJK_iVfMKlVZs=?6a#5^h9z60xWU(b!bEI!XJw<-u6LK0L_fEFM!SH^3doA>NWkVGQ7Txmx{sA#BWE59qewC|T52}7C{+H<`pZvsU z#KV@Sp|y11p}?+t>F9U%5gwBMgzzZ;Mc+Q*TO&;>GmtXqp8m046YIT{t5@~BNPh&P-IxxZirbmAZ=uiHpY&Dg_x0xHBA0Wan570gS}-qzvi`ah)8^%&w6Epy{|**5Z1A2G9i8*`Ux z-GT7Y$DUi;XOGA4th`Y5_gPkXA?@(v<rbtLVdO`aae1h}z9UXW_2Ox1lwEv=P!IHxpP!#ckO6 zmQl$z2DmnSeZhIx&x-37`!0$EjJeK&y1pOC`t;0?G zAfB}jr%&>4fJ^x)yG%6PPj$NIxeNVUzNGyTG*nhI`NJKXvw5@CeQ=LEdc_ zIQY(mSI!0QgG~D$^qv?1eOs10TlkFSKs;){*L1ey&6%nCFM)%WQLeA7O%+dt{FL+h zineY2jEU6;#a!+BJBLs4lh*F2E%D6wVpzj^&ZI7Mm+E;)_3Txkv+DV(s|Wp);FWC1 zE2;wl9!ayqmCT@Ua5lAn*S|zZK+L zADsRCwB|s;x3y!?^f`Age8^@d{FA!mm^$?FWOqgYV^8{U|1-(6W!s>&`XGAbQta^| zt@h>f7}kdNqz`Xeejz`+(vv>?Q&AuGmRtsSkRH{2Njy{s<9PfcjX!m!^A==vD{}TC zcz%hpe}L!ZNBHx?w-5u|itN1zo?imCKOhU%C)tC3+j9%Ucvgx1bhKf|K(zC?d`Rg6 z>eL*=ecU(H>6>Y^2aml4K6I{WmUBemUF!=Wzp?J8jQTVSo-)CCUiKTW=mUR7vc?rT zuSZmd^NQ@+V_PSC>bOslU*E-9%WpSy!;9(N9{4+LTf9-`X3{Dn8P3)XD!B$O>)L3j zn`UuEe{Fet#xvs&m5b;5gVjK&9(9@2WjEyCdzVrS4y?aF`tFZ-V7q&3$(7u;$Lr?o_??{e^F;iH_+3XxCL zf*r8qdUU($yUOL+jdvaw;oeHk^Zj`*zW?)-{J|hr=J?5fKVmEW^*p3`JbmkXEB&^7 zv!Cai!dSd`93~k)k^a+1%LCwrxM}GzrSybB{+_1q8uw~V*cmAYEBG3Q-Ws-Wg2uxe zPa0p<{-5NtJjgrQ1|Qeh=wKKA9s$Nuefljp_G2isqw1;d`eb>Y`oBS$P0W>2v4vqmz16`Tkk>=I=RI)rwtpF^AC?F#NK4Y?N$A0~F3x9#wo?6cO!X^q{dX~)>Od%$l! z)P=Tv@f3C0Z!IB5p)R}&K4}pj@m%w?vWuEmlPuSQ|3s{$x)2-4Q6|HA%yteg3cfee z1-_)ydjoTxkAw%>yOcJp4RrT{ReZEFym~qH_!WF!PA{?iC_W7E1&{c#y6l@^NSV58r%^N zLTBLvvF{Ik5ZeUKr`7w-GflnbqUfXbiQt7M^kVEgQJ3n^zF9Li)+0r5(N{Z<0FK2& z(1p3O!rI*&e!9w)gw^RiFY9((Pd&?k`(@!tx|cc`tBreQui7c!Vz0?*e0L!;;{f{B z=P<@@<7&yfj{W13BlxF}#td8!%SLT%>P3pW5@y!I{=Zx4>hbt}o`#)(T)R z!E1h=T6)yZivh!duCAW&l%1age%W)`9^>sj^+-;Ae`F7I-d9iH^E|r0c!_#cZy|OX zzyps+PP~7Y*Kg_0>vR3LEc{ycO6sol^NjSZV<<7#;rvFJ_JL}*u9=|<@zxRW2XQm; zljtfRL4M!I!I6!1xtP^b=Wi>|<-F7PwdQiI2-?v1`mO>$%A;?4$`%v1xAl%wo6tbz z%1C>AC4Dwe^uU+$-=Nc2PIg)6sf<=R>eJlraX!uS2`;TR&nN9=PW&3K>(6?*qP%GJ z6#cTYLpmd$2HCb_M$&3mK8KivN90apI^k~t zey#9#D!y2G=I3`xk4i^u@G)KK^a=X@%+NN)f;(zBd!nXl9Pi`(hweRiYPWGf?p2rK zqbjH8f7g+hEd=qpL`?FhoAL)PQLfX=}KG?S{ z-O-hw5b~>hyFDzOzzb=OeJw44B_Vr7{gg~}vhzL3g#%+of&NA+gMkZwkE(+U6Q|4 zmtg3LFDJai_sMZ;iTXP6K`DHedRC&Y9J;9|KHv-T)4THl>-7Ec{=|*>26;8#A0KX* zyD$%h=j>(E`?s|aPiZAyviVHtp%@jqw>W0JVUV-?!^JxV`s8X-<8o(WZ_j4^CAwo0 zvTygvkmoPpEywe1ytjIVxJ5oTNj>F^pR8|5TJbgU3w(*Lz;^R2cMAQ{{NR^O)2Z<8 zV|q6NnW@9q2;#+0@~*g@4L)8>J&Hl4X)9kZv2%O&6t?EathL}A5$&N~ruebdRkUGa zarAu)eSeX7%uC0kmuC_$UK7>-fpv`+h;uo{x*{%+fy=;>WfQhu2D1Hq>X5 z7v1O1b>|Lnwe+busqno)`hT;h+qs=%iT&uiVu|uuBoCTfdIh{RIQ?0{nlLl)!211I z|6%b@o`^ixxH?@-@gcuv&CBK-$CGc^^S?etOmXVEj=ElUoY8U$`we$DD@Oeqo7~*l zRxz&0ucfg5>t0n&PtqsZn}q%^(s$lxY$cy!f*-eScO7r=Ht1^no%KOn@^Q5Vf1ro^ zXW=v16pL4Q#q=;H_!H`o{WtJR!f)u|n6=08yS-`SUB>V3VC{_MW#m!uyYHd}mY&Sy$f1@AQpZAHQ?ozRkz)-XwlkJ*e>s z@)yVNHu9{i_}zBSb`yUU$M4jx{Jb%KJrrq;pHI*|I?BiI?g4KWzAdKye$uj0#qqmU zE>CyyyI$m}`Bi71R{lr@ZBlQKVs3WK9Ln1$#^HyvCUKL-F2DdB#1xt?rM;cWpW1$c zwR7(_wss3;Lixi-OZb3$yL*c_+UQOPs1K8&QBVA_lgNjRC;hQfepLw_CEX$1Tw%)x z{$Yvny&wBN#2LKSN1>16jR$omuly74Wn;dhd+N0I7@m3QUrma$V4s?LGXB^%q_yw>yl2w}zOnVobuU;&>ja%k;I+H>7xo7p60ao3 zhQ;wO@AGI+eaYAm<6R#I>xaE+`Ck|ZTlANn$HA^5?*|}O^!<*5y@Q_+ z%4--0JAghV`qKr!dR?&BMtDj5kDM3A;{mTaJ>-3wylnL#4t5E4p*Dz7g>kT6(C34W zgWU(7!Z_G)wMpDSaj-xB+2Ih|va>kY5S2q8C=OQP(~MURcWK4JCX$w}&~ImPuub&K z=gT;Mz{bHyC*oiWh=Z|D_9x^|?Bxw<8pOdi^X;234)(9u&i}u~!LS|M6$e{O--_d4 z&;7ECIGEOV7L8BLyNHAR6AsD7EC0x>?DcNQuQTgX{w(JJQ zq8LBu{>$8JylH(w>iAhEwsX=6rEF|o=6k5yrpo4l>xA8G77pAu&4Agj7w|Fj3!r^M zR}c^O`r=ozcYDRK+4Cq|%v`XffW0cvF{6YFH&3GYg4O}_<=Kb8g=E;zfB%>|ZOpJl zjQu6GN8aNoXY~bjjQ90AeKAz;pr6i<*4STdwV)HU$LT!1lfK~oe4pm|Y?oG_zCccCmr;+HZIY-fH1XoLY(i)pHMoRdHdD{++ZQHE1z1p>H%Ym2sX+Qc! zGHzk}aB~vZVZ2;A0$cYwdLe=55N>2WJ|BU;<>j7dw(c**bxV(Ue?Wb=FogS_>N>}! zB}dl3uzDe&O&57j1KwDN1bIWdSA^ehJ|4@n;zswmIVs6^sXZJwsBYf%WDmz9!ZUK} z@qQ}zYiKK^{rkBFdjK@GZGoq|X)D&r1%FJqmfi{1VE3Vn9k&GhqF9=*XIT*p1G%3s z7)r;|m%o=-`qChl9f`AD zwOfo=A3s(cz1p|6lQ{ant1WC=7_;|nX}z0x&)555U#E*hgU>ORH|dLw&BM2fqc^Bd zbepf!&%KP?W5b=>M#1x=&|j>w6PJ*H|Ttq5sL9{pMomUGBXehThn*q;m|t3_hCv^Q0~E^SzrnC*RsY z^uLYaalZX~iJ>1$8;SUJb246U+rU=8j_GaUHd<^{+V(2pmE&2`li(}~X=|fjB^pBChR1E!N;7mT=AAaZJ zr1Is_QLpJ9{p4flUjlCyK4R!2;eXku;u!jHo-0pxG4#>YbIS(V{U5N39=cfrCd`SN$k!t@$o> z+a*shZz%y8pHAHJ&BUZ%BKeS+Sf(y<#C2 zrPbyD$9F1oJZU{!&9^7|$UgB*KBd97wBAL0=1jAA40*bW&*ai6&dYJ*-P1WE4V+3> zsZROf!c(!27so2%{m~YW;O)E6tmGUeIIuKAzlvvvQKyaVLvPIu#q$aQo#8P%ZiOa_ zOR9cHm)Av?4SsHzvKh|3c4r4Iw)wzYM(47_54H?r35}2Jx-H(pzw!Fb>Jnp!62ALt zhYQhhfB0N*i(m5VI_XcP>yP|(|4#dLM2~El+k416;qx?y&qVyQl#cd%4bD_2JZa@? zgFEwEvN4C4TYe1482^vYi*JBiK9BG~AH)ZCo;lnjAUPwC{22Fsna)ep9)T@9(|TXO zM?hg$G%+?V-dFBpImLF*+kFcIv5n%r9}}RTU@A4= za~yr>X`kOB&YZXT@PhQ*hbSM;E2gxp3Z1UPkMNw5>s>twp!phmQLu^R^Za zaQzYLXh>s&fMs2JTH6EAVkB!~EDsdvv`b$JhG|z@}J~eB%HLv(}wSmkC&MbA~S6g|sG^cIxMDB3Y zek1vEhvPe=8$Y8m=taI?6n`(u$F0z75AZJj)_p7wOTFx&L)%pj{%GK=wZD+|{IQz- zFaOEC+LZ41`)0H+#=@ug82s;LY^h(DL!DcFd+_wXUv(jC z@XMENroKm9o1egL8rM%N%fOiVaNPgA?f@6n{w`8#O0_1O$Su9z6NcF;#37yo1{E2U`Eta(sdeibFw0QKt3UrWv z@_p_t&S+11`A52^&ip(s{ju}7=bi$_ znnPW~wIXOk^PvB#y2{?xowwvyHUZ?XpQv=pDMC)EKDQ!_gDL*i7oVc|EQx&VlzO&ocXomF)1*~@K6c8p z@XU%bc($uEEB=*t#qCV;u~X_%?Cp2dZ)wSWcxHwA@LtZWV6ps8&#aIS^+BCku}=Ly z*4a$Kh~Hl4aM;4VKeOU~7u)b>H@urOE0(K`QOPzgcWwCkm<3DI?vyaKp*@! zpIPw<-xu-Q1*W}HaJar6K-$Za;5;tKTk6b;kLo?Lj*iQpt&pq67dU{i^SQ{;+0c6? z>*Hsp>a`BNg?-JcAKEqb^vsI=)CT^l^}!rJ{pn9}Ki|!n6=~IjpAy#dJ6F$PMZChe zIImN*k3qhm@bL!u^Zp=xvAl9RymESBefkDhr+C8h3Oai$&lD%~JQ1E*p+5NMimkrr z?`1pwo6fBGHMFvH>cN>6*MQds7ca&iwr5s+o@f5diY8Z=9hY@;X2tpFgHmT!upnc_ z*PDs$b>SBmkC}VC-g*!Cw0OOB7ygF-{)~L^&|m3p4?XMgH}*@>Mr!CYHoaSr?h~Z< z4AT1q>HUNBfkApmkUls_e<(;F7Nn01(#HhpDzX^fFG&9|NdGuU|1?NH9;AO2q@N7Z&jjh`g7gbPdUKF|DM-H@r2iPC z-w4uw3DSQH((eT6)P#VygLI!Dy=Rc#CrIxfqz??zLxS|dLHfubeN2!(E=YegNPjFy zpA@7&9;8nT(q{zeDM9+2Aboz2o*twx4$_wd>C1!k)j@iGkiI8KuMX1R4AKt->F)&T z?*{4b1?e9K=^qE_p9bk)1?gvk^m9S_g&_S>kbXHx|1n6v5v2bTr2iJA-wD#GlLGz; z(tYA|$6Yg`bIc%P24!B2%n=zr*f_TDO(`>}@5+=pFGFh9K%Uh`eK(}c@~H2#Dbo;T zNIw`I#q*X(#j>fXkENrxQx(RnOb;aaaJs)Sn6~)u|4thRM0=Y`V=DVjGjlT8D4NGS zPuzu$yFL;f5yN;>M23}u@xjPU%8;5mh-dRA8Pgb5ZjYjtsL=C{yY`4O{WC{JgYa^% z_ptD6blK!+Z1Aij>T4>DsVJ*5hg2D3%MHqmjSdO&sIF4a#%Cr+6N~b7YV(uPsfLQH zGHX+2^7826l*vVXA4{3GsPEG$vow__OR<)xl{1^pkbWpl*EZVZvjwum zI2mos=%vy2$ZUxE)>1gikiIFEc{&xXNP)~pZ1S;G5l%|=c~;rHXwKLqo;u|l7VU39 z^`x?SX7W+Sd_J=xif#-rF5Dd&9R$0vJ~XOmj9@lamp&F{o{yp@!i*Nj<1^EuiPYn1 zQ;H7#GozzHK_1azeBXJ|B=G6W>6z_+NQc4EzGkX{KNguAqs${wbW;SnJX3evC0HgJ zGcj|enM}DwndMPb8+H*`l!vb%@hfA1|8SIPi=sy&TK3g+%`3$`))oJB;;9p&V+LiO zO+}U2R4x_0mC9^SM>nSRM}BL*3`oWxQ)CFokiv+ll{%MFR}X#V@lx zW!{G0%Bb@(pzwfLdQ|p3D;f=w@^~E_?Pq0j&@3Y!pO;x0MT_#x)N$7d(XlaKFOAIP zzIQ}s8ad3Iz7I$62C22tA+@P!LsVg4_zcPIA%Z*ZIyxF@Xm4~sx-zNn(~&uEDk<1_ zWh%-=Xtf(tO5RjpV72)_2S4y-Ct8SqOX!UE$}gQ{<`dCL=1OC(lwx1h7ahMel0mp5 zl10cyG6^s;&(}NMU%56NZA_tUZ$j&&qZLK`G%^}ycsU-OY$ig;S!IxD&Kz`7l*vWW zvjvKF+@-eXiBC{NpO;3uDeAjCWmZOg8)R`Zq#MNt(g>?1Coc!SVvTAfNB1{~uJ|_XCbk zM`s!I^VkexQq|9xv-*O;i-hEPO5Nz_+xJ0mjM`5}kEJrCpOyq+R)p_d3WfJzdZ1ng zn3jD%7v}&fL}hC^lrW)(JwvseHLQ&%?W@E$qmuy z=Ti}4PkIFaL}q1bpcL0Y9zRhatnAF-e0`(IGFfcV7#(s`Dtf-4>8)NXW!tJUXGN3f zPhQvcR963Q+rYsH*hR)%bR~30Gd?8EI61GlEqtYHWT|JJY-9_#yYz3+xLA@zDWPKDpR8R@j@nJjwF~!4C+4{&l z9hEiqMQPOXgd=i}n~>cAmMitQOxk zFB$J2j#1Aj#4=F5Au4+!gS%DBlP6N!C6bT4XV@#ts-h!8IT4;8qUML9GK6>|E%uF` zwrxEPJ$bY>r02ym7F;&7X2HVwmtB3SnRMCg`4yKfSXgn%HCG>7aqZlzE3TNm_^KK6 zj+{Af-jPQh*~eTvd*;Hq^9%W|nsM3HHs4h<=Uz4MvMXnQ_^KH*^SS#_rrW=Ylh2q~ z(QOXe3_Ep9qA@k3;(g3#V*qMq&b|8D+4C2Ev|{1hnu`}NoV}o8_Wb#DxYPSf=Fhz< zkz)qDeKEh8{Pb7B?;>|S++An8YlXWqcW&nLoA2(==86=WQ~7JljiA3W z)6XWS()kotNuZ{12~x|eIRJf>F|}m8h==QktETwgCfvU&@)!;WzT;>-7q07%HD&|X zhSA1s<$4i;(?J}_eHMs2it9rlb|Tk#r_-43&oE{V*M*;CxWlz^3RaTqAs~J&*R>p8 z*v54-#GQCJ&K3kdk89&BTrjR@LDc13AA=Z;TpJ+f^IXkmnaJb%&|-i*g7%geGmz_| z>%aroo3KmMxIS15Ok7)*;c#)?&Z752K8y!&8@#}^|38zD>(~|akL&oap)R@B-fm34 zQNVi#_~H8OH_*;pZ@i24xn@_w4@Y5R@4<3%eYJrh5Z8&Tfs5)1yLM00(lnSOA6^=HPkaDDp;=x{9e1kL+% z9r&a%m0Vk%!js{;{Au9eI_*D!gKNce#x!u9xEZ*)KDd>3xt_P3Q-?=Kri=rU#&W%> zjJ|T+$~DV%>TbZywS{X7*R{RL`w^UtJt8xj>)ZWkgX^<{z&Y16-Rf&DjB0zqNc^Gc zQg1}685yTLoXO{9-EoRu-rtPGxK#`MzR7PaLj zT2YRv>|>&}2v~M^6Fss!H12Dnfqjjs;yRV<@;yw{xCgl3)1+4H35-YmqbmalmG03DIM93x%Ht9u!v8;nl^bpsHL%AQy{ZNy7mFrCvCVIGnJ{@eLiw-ua zjR(UE!+AFxUOL32-aeEvhnZ;kVJ5}Apy_{&l~n6*(JwtVunKoZ&`9 zM~pVRO-9xhjy9>STr(dr(V&kYQ(QmKb?rw?YW#5~HE0aD83S&(ZXaXP(>V3=^C*Oe zK59~j98aIdn{@4X;6gcY0DJTVU&4HvbiWhn!-?=T*SENio?xQM6HI#P1o-GAlg^%m z4Lr$2{i}hmntpM8Y@*3*KiQa9Pcf;5DAbjcOs|GXCjA&`lxuqQsb;r}PBqceQ+aoq zNgahQ=r`F!6_df`WcvCEWa<+pTEunM879?s2KAo_jAxqY4z7#NqF(gH9iIeGT&GPj z>E%=4sk5OadSfG3G+Fwhsqoc#CcXYV_+c9SGL61YGpY5{P4xV9;GTglnL!z@PjhYK zddS5l8h^1d4_|E3EnJV73IEIlCo_3J)ATa4OzI|d&mpr-s`3((nsh08=u(sFe;I9E zX3Flk9QZFcsd-mY?kZDOdo}zr*OXm34}a`4rtGo#=)nahHFY6$U1-WKVxib$*P60Q z^wdp@&2G~^NB+;5RLc^R+WvXoU1!pBzChmVP4w*bCf)xAXj^A?+wdi08omNQd<8!F zs);JUioA1D^d$6H%T378&GhGH6Rqc(yV>lPxrKIbG0}OqnA8)bx05cr75Tc=M6W($gZ7uKbsQ;$T~Xck9@TBH8Fwvr*FNsLySv71_N(2)-S6qHd%0`e?|!v=yZe3IbzgS{KK}aE z?&q%iyDMs&zkaCd_==k5uV3wf?s|~B4suu2HGlnThqx>1+TK^V>o9jc*jmlxX zsJnj1T}QZUrMr&&|JZvU__(S%{r@HnP@qDQphY4^%}UgWNt&i98!^xXTN*=_1gzL) zGEJt9t=g4}?fU&Z z_dHK>a+IKPB*JLKCm-46L~{yNSt<=hVSHccO>;`}ns zFXwzN=hd9oaDD~nZ{U0$=kqzglJfAIS@Ag)bJhEPmh%D5KgjuN&Tr@Z4$l9DbJcq@>s=GS z9u2tJJuuk=lRYrm1Cu>4*#nb3Fxdl>Juuk=lRYrm1Cu>4*#nb3Fxdl> zJuuk=lRYrm1Cu>4*#nb3Fxdl>Juuk=lRYrm1Cu>4*#nb3Fxdl>Juuk=lRYrm1Cu>4 z*#nb3Fxdl>Juuk=lRYrm1Cu>4*#nb3Fxdl>Juuk=lRYrm1Cu>4*#nb3@c(@e?A+o{XZy z|7&SRR&?0LlsR0O9UVSoX~z^BM8gJ#`IV&$ZD5$IExpsy7E42xEb;a{B- zWp8_alzr{FmfzC4+$ej=c~N#`1Hs&B=@J|CWv8WUXGDkhS=xBMwc$lJsKf=);eWHV z*am+odU2Hfu%$&8nrDN(++iut22}b;esuWxFO3fW+0xpVMTghFJUaZDg6Qzhe~1o0 z{fg-D2QISq7e-6lGsg6dmri^w!tda$Ou9e%Whn z87*CIgET#Dsj9>VimDj1FI479D=V28CHTD>{6mB@6`fsHJH(7)+g| z_gZ?~()8I;c9W&|&W;X$#nQu;eqw2_4HEN5dp)-z%ARMb!_qoS->~$bmU8CUKo^!8 zE!}8owWalQqO332{EwEhFR=kNEEQO~*wUqz>MUJvDPw8S2A;Xo($kjS{*TtKO6xaE zPg`nyU6lPJOQn}a*|%BRVX5`?QTC}-)~A+oE{n4JE#+JuWp~?#gefuiit1!0`G!>H zavM0TKGPi~YTszIU~x<1@~%{rXq?|Lx3g>c+}`f)R7Yk(YWd>MWOvK_j;`KJLuYSy zv&&+J_fma#XP1pfwmeE)GuMp9?qo+#TQXx=6W4U~r8`;@SEqV<+rih(&UE&6S?)BT zBGcJ7LUju`0$52R(cZZ%m1yhi?3#~3zh)=qwk3OP2)E1HmezN+rJI-6)HJtUUeTK> znO$65TpnjC?@rmMXg#S!I+N;7+5m3z>(ezg4dn^@zoy2DDeFq6yXQA18cU2DDiV#w ziH11|v}3sDQh%U08$1k^mo&E~yAzr2WIEGhFU3X8Nw&3hHpi9Vm70=SiA1ucr8|-C zNZ8UZO?hoYhQ(JeXgpd?%|}$!9M)qm9JLyYAFGzWBWmdjYq1xOT8qVxsHGfT(UzLi zYkj{Y*__JMTwT{toG4AV)cBoSk?!nCSpTNVm!>kN)GUjm4VjXXw$7zCJYPJB-Q3ce z`UTCyk+?Hmq`G9pC~Zr1EX}kY8JOAK+mT7Pr^YC(w0Lo{C6VmzPA*S$r1}!Bh`A%B zj-A1))(ubhTsM(o+eF&ZOFL})^tO)L_6qCr_I57uiB(aaunjPsN%W zg6baI=xb`0*&a}wI5`#0wq>&Y(iW1)Kz9EixP%SAx#!+>m6&(GL+B~r% z>I5qr*=w7Ra@;)5!rJv_I>uYe@fBrTZ1co+)`^zu_5|=MUU2|iVvgih7Y zb>f|R96Qzom()JWoSePt=pT6|*qUSS;}iWjI^I5Bc8pzoqU9fb7w?85WN^BQD8J((K{KPx;ICk*~F6ps% z@d*|b?&34uhpkQ0DAT^I9e08F-aWxn3nhv89D^O&YHDV;q-@DLm-|aqjutGtx?y&ro@W&J zdGS~a^&HzUW;e`MH_Se+etnKjm@~YFM|Z@PwjS)%j@KX6U02yxTmNAAcj}dKn{>hr z!fBo{`}{d>dUgt|=Kpl(L4{*%xM{bVN{@H5MR6y)KgL{pY1^FA+?e849{a>vmPWzC(v8F%*09Uf*iXYBOu{N|eBvvTfrp1YeBpSPjaN!M;y)VY;0L#etcfG24`KmdV5;!)L`=siJmq)|I(Grw7TfBt41Bx#kj_=U?2Dv0n-jnVMkZ8_w7l zg^9AJ%pM9Qbn|4nsW1CycVmnoe6McApNw?VNiSAUU)lLA8+6#uoSdO;$I8w*D3qC!23}EDhb?h_xar9a}HKq*vmjA#Rd!h^q z^)vL?FF+}5C-&pQ=xC{ZIra77$Ib+$j5^MaE@F5KK4O<(zOfehT6^(`MQ%yf$Gz0j z=H?yAcu(nwzZE5#TW{#e+>mHVcH2*Kwup)5{-m9=kAKIq-%I+NQ(gE7t;pikQu{H> ze&cFx)l2p(Pg|n5Bh}w!pTtuwdf5(`qw_84PK{AuylcT(+TWkBUjTbL?UZ*qvplh^ z7_ZuKz>fdcNc#;b-8TA_rM>nWBwpf=hfyNg+??vM^YKgUmq%;z4Ym#FSIBER(pV$* zLu74oxxEeI_s%HMo@#IIvR^1|j^7sJKkP6NCAvE8i(Z#K7%H9j^H z>*-Uduem1<4ZmPN8;N4YW8-I;Kk4UZ=Jar4OSt-Pf(fw$|cM;#FD%dG8> z@$V?j_GurV_^k&*y5opqnpI5S#EK~?wsLwqdRo&DM_=@>03 zDX}6_9kv?md0WR^{t|RRvaK(XGiuJ!LK8;Wsj$b^ zW!jft(c2N9xamnWlrD=3=R}v}L_-gvGq!&z>9_5Qk zO}c(TNqKzHPkfn>d&7HxCX*8HK)2=2-*aIAwCEF5L;CYAk#*g>^=-*GVZ^7|{5))mxgr}t3E_~=rp!aNh zjcz*?*P+-4j%0VzKFxHGme-z&&*pf_qFphvbeVndNL(8~6*9pNudi>8er}D~eJ_^q z346qCPPF%{SVG&5pFVBovgp8R7X4Yg{7>TFp|mT`3c-n%cG8 z+7$0DcTCNR)_ohoIumlDEkpQs?eFmK6aRtD$}%=2q906cNMQb$`P}@+&<6^7uX)%cZNOqx7iM) zYp%!9^m?n%RrTZ<&8YF$XY^sV?~I(BmH%ZMUe1m$AcxSQSrv1*_tT z_uHz@IrLtv>d_YqtvhSeHPM>s z-o+ri5N3nL4}KB7wes!}_o3MRuElnI#JP|9?#NGSdo0W94VGn!yV@waXS(|(F8b|s z{lI0dc-J{OIU7EQS~hI9W7jDq(Ra@(jkcd%9=+$BBY(ZR=bYgmbvK`5OV(rF?#FD0 z${ueW=`xI8pL6t;H2OMln6PoG;J4dmkJHqoP1^p$facp!@2f9?biGSP#%wjSPvZDe2--rr9A*M#q% zcg$1SyUw$Bguh^S+_@5+y5mm#yXqb2+VOt&`N0du{`KXt7erIW_(j4pdp{jT|Neq8 z8|DAh^_>@teZsChab@)L7fi|7W>2cj+3;r^=!U+9e>Xjbe>XgWf4A5(T%+tUe`0vw zjIn+lxP3;HbK-sdmluw)=%ap&`P&P}TyX#Qrdwx>x#0GbNp#l?Ti7qzYB?po5ITDN zyyG|%>i^goeei`7`t9q$3vr$>dU(c!ei9k7`w)V6qwnP&>qo)pkLTy)Z2ezsed`Zn ztsV0xiU%*4z$x)jza)J7f}EWF@uqU{S?pCuJ=Tmq)xRNc0>1~`lb4h8=y$QFp&ioI)cmj(s>a6~I?Ou+OXmeg^wA%hUj@5qj--Dt@E*RrChv;`NwqwDEaTM74 zP96oqQ{<0bc*Gg(pI>Olj_;!zcHYMQZ`3L3_q`-I>wLT2lyV%4GJ$jX(NhGUuBg>Pn|lm*#DyPrm?=M z^hNtlE3=2)N6(&Cj*r``PoEuq{EUj|{xjxWWv5T$Z|3%${P$P}Ub4;Qy6CC= zcDug5Kh@l8KhLzLlJ@&Z^!1nKL|buxQ+6VH;HB+$5k~a0mm>d~>x*_wDJq**uwzPD z(Wb1j16h@oo3ko&i;8j!rmf2=D#)$qs>sb7%ql1=%q=L$EzE7q6c!fb<}R$9=W;Eq z+?n0v{@j$6SKD7$Rj@7#R!eRH4EuL#OIdBM6_J})T~%GZC97#(K}Au0ML}g*LGD1- z`m753qrSerFq0`OEH23HDlRNoIIm!6N>NeUx}36=*+qo~yR-LADVS$XE2^%n%Cpv0 zmaWdpFWj0{R#>$@t0*@&zp%?%XaBFw+G90UmK9YO=5NWWUY%W(vHS(r@G>-|aaUGl zRbk=0{K2fk83p^Y%4Sq<%9>~K{Qla4mX=M~gVvzxibX543UjQ1MTG-dg;hmsvI+~< zWKFN!o>e`gYE#ylth}PKf`P22Ls?m<%Eo3>Wm}4EB;2?P%XUw#G}FZ5+Sqdz)^})awbimMyJ`m7GMH7LTZ{%h zl=bLH0Xwr7R=4E#ugR{;G;YkPFKVk^n~joK{nlwMQS@WGXYazSfoQ5dh}Mp}(aSD! zTt;3_ZYAGN&X9jYZkp-*szT?lA+IF2mAUvY6`$q!Vtart>bG0i;`+Zyw%gfaeu+I; z7x8W6d&vjMHLrH@Y4%`Tw0|SHg8Y4Q3wgRdm>1>slW!%jBX1*bB){M_E`N1}D?dT* zB5xtDA)jXt`bGI0$$jKKTWSvkM*fxLFOj#BpCmWg1AdYJdBraO8gd1B z8+i%&QS!&h2gtd$-ca8Rdr&aSYathr?;|&oe?x91Uv3X7hQE#c5puCTa2VwsA}=H- zY&$@HJdhai$H*JV*VuM}xILRbj;|)$bLwOM9l5|BWDNf%+fIMJGB zBfp8fhI~7DBl!Vx(LCo@SihjWdh&b71LV_cT>K$&IXP#(^H-DSkzZl$M0u;okC3ab zborle?Ld4zIZ56}{snp30+)Zj)r`7PwlE4tXK@FXUC^3M&`>X7UHg(N)g> z5xJh6YxN-idh+Gu9pv|tE9;&A8}erIEUPDOFZsjdY5(N%KTED8_gJ~e-$ed1IYWMx zl@pgoelt1uYFFM`awYl4uJzaQ?f=)30&-Gjb*QdFH`yB`+ZFf0N6< zoLux~$Db!JB>#pyKtA8ipN* zc7o;aBHu_}P5v6Wy4B_XBY7qHpKLpUzc%gSw~`+s-$$-^tBXgr-jTnNd=YtoTt|MC z{2uZ_@_poKH@Ncllbgsdv+V-quOZiyH ze@(6>H`{gve--(&&f%T?;x0830A0&b`6JIH14aQP3AyU6*r9^r2we~G-GJk{0{;;rv={=3M7{3LmZe6ejuC_jI_i{C?TB)8ahfcSRuFUY$;>GI#X%Eenh?f6&Z z%-xPVZ99QqxzX_-$z7jwJpThOzV$xGd&mdK^FQd~6zlHo4@}uMr z+IE2WA@V+Q;a6RG|7`0yZXfw!azDA+)+6GZ$PbV!zvlec*?L8M5qT4NkbKdHTzuiz zUH*H>tH|fy>Ec_+?TY&%AI+sKcQiyw0F1)p;9 zF7nsOYsq=G-NWBZUQ6Dk_y!l>M}7}^$G2Sh&%4{ja~^iQom@?x^BEU!BX1$EAy<6X z#h)N=Cm$l`+kS`kt^Bqte;s)^Ot` zPmp($bAIT`yUdO&h!2vtk~fiO+HoUp5BY2489#Dy%2VDFhc|E!Q z$IkyHc?-GFjsqxf5BY86id`=M*T^m8C&;VGSJ`m_e%@m)|HsMm$iF8KlCQMm2J)Bv z#N~g0ypVjp9XAj^KweDF|EbG=AGw-5!;S;UzmR+*c{TZ`3^XMM}%uOM$Bx00VC zPyd=pH^26lmzj65sY`;hTD)In%4f!eZHu7BC zuaSQ*`6lu~^5f+E-@5WIvHcqP8_6Fa50U>$Zu*_e{~FuRk$;eU8+kYRcjUZ%F8}qm zA0vMyc|G|6`6uMU|8V(d*?x-r>&bVL_mhikKSX@sKVANBlDCtwUn1T(#===Y9) zOwJ>}*7h^xZzX?`ypep0?N^BJB(EUvCqF{YdD@l#2XY1ZJloIU50dAS*OJ$hhsX!X zP5wPhLnavi%0}%?Dh3 z1$l`4C^_$cT>K*2uaLisyo|h_yq&!N8J9oz=PrN#LB}oRHu5*g>&O>A;qvb%-$I`8 z7w11kt|FiR3zxr<+)f@MKTd9X*7?((bomF#De`Xe!{ofby8N&ErORJUzJ+{<{AF_S zA(ubbjw9%wjpSbPLGqb)oIrf#VVD1t zi~IrdX7XP0F7jLKxP$r+l5rdYPs?)UA0+Q0fABXhUOUCbUtz}yDVCh|4^Uu8ZG6-uVK@&yw?A==dr- zZXo{_@)q*+^Ig2ijvI(qkh{qH$)6<`yvXIB_6L_gL%y4wbAgLr`bQV9CVz;$JI}>0 z_>+rIf4SpUa)$f`Y zNZv_)HTenh>&g4c4dk36*Pf;18RVPD732?+7m+_r9w6UGUPJyKc_aCk zjJ%FKMBYsP8~Gvfx%R$^^|hOP5qXIGkL2jJu02y`eui9K;>tV2-p8>#8_6#wA0!u(^GjX+x#TkPwd8r^GcaxVFF`&@zLDI~v`TuCk=*OP0=i^y*# zuOPRR*OT8tew6$n@)~H`Q$z1ek&?@Ym9x&HfY1 z5BtxL!`Jn)xPBJ(i{*#Q@5kZm`dVCX3tuchT>pL?{`Q$}*%sLH!57QlgoU>WTo=UQ z>v~>X-wR)i{OG%|{eB$&ddq;k){U_*mVdxr#{@?GejNUqSuTd_iR0xb%dd>>5nuTc zhp+36as4rT@p!%;hp+3CalJBpvHZ%g+t! z_v3N&xMb z@OAw;u1AM2M*gvmUw$0Eu2;wP>+r?$!~XZ<@O6DVu6K`@zrt-#@(tq&jP@%(7{0ED z$Mx~>#fYQ*U6wF`;rns;x_%zl)58}dKm4$MKMr5l+vECs_+t6t^80c4>*lz&t*{LR zzF2;qwE+_t?f2vGb$vgs_lGY=ezbqk5+*QwKMue05*NGW`OX*1M;Vyp`*HZXp8)q4 zpnkFZGN%vwejL8;KfwJ6@Wt}&upCcdwBL`z-^TXi{ss7A_iMlx z%Ma`KTK1hyCxz;cvA!c;v;4@9SLu;eH?ZV)>K7x9WpA>C2@Kzl!{1TmVz^%mz8Lx8hwb;{ z@N+J6KJM>=FP0y!KR*s%_kZDjF!*Bm;r8dp;a6Yg>c{1lm%F_3Yh!!FSAN9d>wY@iUk6_-zd!K(IDFlIhx_s1i{*#!e|{Xk?$^Wp zd+^2btAhIdIDFmThx`5Di{*#w&yT~`{eZYX5WZOcx}bhP9=E^R^)2ovjN4C^A8voT z-w<*5y5A7@AHo;Qx7|9Pz;!_!{zle^`xW7fksr(6726~0-;cxB{fxN35x!V{Sic{K zulpaTRykiRza^;OkHgpfl9lwu^27e~?zZoFP0zH@5kZm{?C_Q=6vyZz8{CL`$cj8DAu1?e%O9L4qx||;xVFJVVl!(Br(PIbSS4&&t3AM*V&qzV27X{mZCdjQptIUXCX)d_N9f_c!By zXZT{|hhJq06Bxc9hp+pgaep*?G4hX9zaNLM`=?ja7mw%rarnC58uwqLezE*5XuM5e zwBL`z*ZtYJUmLy{`O*F+OPIj${W$#fSGpMP?}jf%e)zU};|UDkkHgpf-%0vn`6vUE zd_N9f_lx8HanvuCAHM(jarnBw9QT{U7t0Sn|N3$Gx*r|e6@0P$de{8n_WN=8x_=$_ zv%?q558Lm@;p={P-2V<=EI;f&KMr5_$K!r^_+t6?u`r&%bwM1y?x)B7_3*{WkGjL- zryqx}`|oi-K76tKu>F1#xqW1#$Qqp8(?( zz!%FuV*Lfa#xub92Jpr5k63?!ukjBm?2Qt>Sbn(w_;Ivf<0WAH1o-0dd_N9f<11ji z1^D9ed_N9f<1t`-2KZw6h1MiY;JP3VU*k7mJO}t<U_1)=V)?~ZHYRXg5Qnev zDlmRUy!`*<^2!glKjlXpzQ(t}co*=+^26hYABV5;Ffcv_e6jp4G~OmK+V98V?`3;2 zo(6m|@}uqH^80c48gB#RZ@?GJ5BuMb!`Jv67_S4qSpE_HclAjB!q<2n7~ccFSpGs= z229|(AP!&Se_%Wi_+sQo-S)N^Phj|d9KOa2!T2HY#rP9`*nU6Wf=rxp5089Tz)Nok z_-bQZ|1uC<|5DK4mhILlu70uVA7UMtq5Xaw?brAw81Dq_7b8E~9)AAtD)ugZjnDKUV+yarg`0?8?UYGVsOn!~M^X z!yllJ@o3gzzaNLcIpJa$j|sjQ`N!&i zKMr5xHGP7h*u|E1@`Qh=;kHbGmALCD7b8F1u>buye2sVZ0DZCiaQXc>e2tHW_jS}SmLIm?kHcTl;+75LtHBq` z58Lm@;jgBT@z~&t<%jL}k&?@HM_1#+!pLMt-9KOcq!+3qDUo1Z#mD>bH{eB$2#`DAYe(=S}kLBND2@@E;ABV5; z|1cgPd@=IF50~GM!`FC$7(WocSpIbUVH0Mk-;cxB_<|U35WX1sQGdAp{5X7#M~LwW z;fv*GtPD(G)bGdPYy3itX9!=6{HQbuy{GB(rw%tWvEI+K@kHgpamiy?7=1g`V)gW>OE{Vz|tLhe-~t%!0`Pze2urcCh2@J@}vIn{lkyL*Z7>jrZ1LXWo2LjqkcaQ ze^tASHQVP{v|o(;V{QL_9KOc?#CV|a#pC&Y9KOa2#rUD{#q#H&@iu|cem@Rhk&?@HL+5I{ISy`(k^<_v7$2{wl^}Mg3y= zWr6R<;cL8Be6E8pmLD#^ABW#$Ul5S@UG&BB!~MsP!`FDQ7#|k(i{)<$+V98X_P@>5 zkMU&V_LJp@+wVLt4qxNVV*FY7V)^0wzaNLM@o6z$Eqt;3aQ*vn_!`d^wcQPSblBb`*HXhj~Cbrxe2w3W@qFQn<=bu*PvE*B4qxN_V*FqDV&q5Nq3_4xYkXjg7Ytu4--aiMC(Ka4 zABV5;gd_VL1z(K(sDCiFNA`a|4u55@i)Bu6zF7YH!1v?uHGVP1Ge-Sl`PG5%$Kh+d zV~l?cUo5{O@clS^jgO4+lHrTx+t;Fa0@np`_!>_c<151#<4^S8N=ul)@clS^jlYcX znBj|&6@Iw?`EmFfuNmVv!xziXu`)1$QNJIDukoER-ZOkL@}qtvOknta9KObb#`w_i z#mEmgJpTG|__?-&BQM62hA) z7{=R1{bJ-t{bB$4arhdK8{>1s7t3E`WncoMem@Rh<9A~`Z}?*5A8YyjIDC!wjq$(X zi{+yXOkmXS$Kh*yaEuoYUyS^4!}j}e_ysq)vVZV==Zob}w=yt+QNJIDukpw+J~`?a zBR}d7_a8qFzl-(%{ygW4K7wF>aVth2@Kzl!`FD}7(X4p z82RDPu!IQ=-;cxB`05yM9ljX(;a6G01cvX&;qP4GVi=ztz8Lx8Z?c354BwB#@4wl_ zF6H@0vHWoT`*HXh{~hDOqkggcytwv}`u#Y3jTevcBr$~JbH{z4__=FeTWHM7sTOf{CbRM4_}P@a0e`50>k&?@HO5&#=nOzMt=BBmN0?g z`*HZIZgH_!+UF4XV&sQ^$Py+nd_N9<<$#M}eEoR&$?{PKCi%(_hQDdR#V{U!y!>SO z^_CBleC3yaXu!p;r!SUY5!)laA4mOV?{Kjl^u_XzIDRlc;_$o3cs>ByFGd{89&SH= z9R3FS`F+k8%dZXE@5kZqr;q0kpnkFZ>cIEo@$$dZE&o5}I=_r8KWx7rhp*=wOzn5R zSbn(w`f>P!tPjseK>Nk=!~NHf!`Jf@4$v3N58Lm@;qPVrc>V(F7t1dW`p=KU*Yg?h zyaxDU`4xfh$Klt$%k}>oXEKDtmj|K4rt_$Mu^?V9EuL8ap`LX{XVFJVVp=Zt#IgK^mN0?g`*HYso(G=q0bh*#@Ea{*0>k&?@SnKN#SWh4e6jqn{eB$2o*#ne ziJ*S5d^;?~6BzaTark=P$m8_I^27b#kHeq3(zX9#_P<#EhV0Sx`*HYszRBy}?%FSw zANHRghp*?M;Q1(6e(`v|ABV5!r{H-i@Wt}O_3y{w>v=19{tA5Yc)lNpujjMic`fk8 z^27D#$KmUFE>i}aFP0y+-;cxJ^FFu!QuM|058w}*FsrkF{5X6)FXqt!SHBqfvHged zUw$0Eo-c#v&0zV(^5+HHj~|Dx=h56rUo1b|e*HLnJ-_AveX)FdTZt!dotGaBU(dV2 z^Ka08G2&SM7E74G@clS^Js$_p%YiROe)ve3!0`Pzd_7NR1AVdl@c8M+;p_Q3cpeYx z7t0Tq-;cxB^Lp_79{6JUm2vAw+V98Vue#mE8tIG2^Zht{Jr8IDeX;y-`TaP2JwNEX z^u_XPgZBGz_v|fz4XQM!{d)1Z$TzbA3Z#BtiVg(5BTTCW8HsH!TLX8 zD;n(=tNt9;fmvM;NBb*3KDr&3Vc5fU(XN2^Tgnb<%jL}Uo1atzaNLcoqmgb4u&t5ANIc=kC&gm4GZspU%%0n{WOo_v7&Od_+7i5%r6aAN3<)0>k&?@Yj6K#isH2EtcPe zKWxGbz8{Bw;2sydgY6e1Kk5#zANAw#b2d5uVfteEI4)rVqkcaQe>eRz>5JuWi0u*I zkHcT_c^7+;Et?V&^i6UD8^7r4&!aDvANIc=hhMna`7h)0i{)4151TNn^YVk?w|vRPKEwLOh!-%~ zY}ohX@K@5mm%dp30mwFiQNJIDzvACq>~Z>H`S!S!c)|?6ABVs8Ugx*b7b8E~UyVO( z!VJD2hyTPD7rTYN82RCc_h0&P_+?*l{`K_5@|*C7O_-s6KMsG*eJ+;E^(RJt)Q^No zz8{Cbl|G)&iv33{Km7jg$KfBKkLS6<7t619)eqP2$KmUFuXz3|e6jqnem@RBv(+sd zo)-&WEWawK-;cxJLLbkUg)f$$7x;c0zMeme=h4C!%P$IiKMr5dtHtwc;fu%f{WyF* z-xklig)f$$8`ST|;a7gu_1{0=;e4_Du>buy{C@g)o-XPa%P$M+_v7&Oyj?th7rt1& zb!$9<>wy@AH^x^H#kHgpVd|$W5)i0J`82El1{vhke^MKKQvHV?u z@5kXU{JLvDo*xWfEI;f&KMsEteLQa%zF2V-$P$4KkPq04!?@^<9XL;zgT|Q zem@Ssg+88-4PPujY`-6e-%tO%bXthG4jI?`_GTVucVLXg~J!i5BtxL!>^}*GkvlA zN^1iqFxv0O;jh~6Vo#sr>KDr|gKU$0KMsHUb{EU~xbuhE94vcy{PN@Qhv>h9zF76w zS{ayBzaNKR@t})+-p_?o_oChzsdeI5B*mi_{xv+;p=(tOV>MJtop<6uYMf9o)3SRzF2;^{`@$6Jx_kg zCtdww`I(^oejL7@KmQ1QvHZNi_v7$uA9DS*o9~}u`RGGT;5siq7=9Q11)p;57b6Zg zJpTA`_-pBZoxWK93@ZZ@81?&c_?zkH*?A>KDu3gUW3JqkcaQf5*36>^=0w^26hgABUgwu=AgHx2s<)zY3Mx1V;US9DX(Z z?exX+!}aIK;kVJB^BGsacs$>a!(T&x3w^Qtd2#DU+V98VKS96Zv#x%z{QSW8V(bX@OANHRghrgNrI{ISy;r8#x;qOrWb{-GgzgT`j(0)G- ze~A7^>5Ju;;SZZItMl@M;pczH#TxH%^@|Zl-QoM6ABW#a|3Ug<`Qh^WarkZYi~rTt zFP0zfKYkqkM*4Tq7t7ya%YX@7=j8{(@A|Hbow3Q)FGd{8AHM(karoQl@1rl4Uu|Vz z0;7IE4nO*yi>dBI}eHa#q!Yx zOkmXS$KkK1{|owJ`QiTK$KmgwKi|${#@jzxem*L<35@!c9}IsV^KYRqMjUMq-#`60 z{G6Sx>=m0`{bKn=Rt6?8>i6UDi|JqTCFhIfhyCxz;kVF#mcCei`1#F`!(T)HYjz$K z{U?@R5x0J%{eB$&PWlD>{3w$bT1#qz`b$B)C`LVw1WoiCPe#l{o3&dU#m-}-&m{(I?*5l7p*EMWq}_v7$) z({KEWt6wZXJpTD{__;rDW$&ObmfwWRZ33fyKMp@bzu`VtzgT|Q|9%|)TKX4lb-q}B zxc&HX_&ex-n7&wkSic{KKScj*I}eHNPb@#&{`@%nibq}Fe1^VQeptUBhrfva`CoJO zi{*#=zaNLcn*J*KV)^-4c{YLTy!>GJo9RD8UyL}~UStUq7``8e{{;OT>^vg+PmKKV z!{fIfhoAF9SN3lDV)+AB1|~4-_v7#f>0h?Z)i0JG*6+vRZ=%1IzF2-0Dz^!Y`u#Zk zA^J1zJXXB@kmZN{r~HV+pYbDC_Sfi(<*z~IHi1#UABVq*e&QRhezE*;`TaQjUG#rW zUo1b|e*HN7gY@5I=Yg>NV)+Z>){nH`kHfG3v5T#zFP7gD_F1GJ zd5^jFU-h6{elg->?f-rp{yh30r!STtzW?}f_=EI+PhTv5vupnF_V35xm;J=G|4KXW zgY8c&Kiq!(IQ)h5AD}Omzb>fXkHbGe|NMV<^^4_)>)(&V&;O}w|6=-L`CEWaS| zl^=2V(|_jr?NjrqwSTa+CMgd;rsEp{yi@CApJ#T`QiJgABR84{JA?^ z{bKozRxc(n>i6UDckgkrrS!$}iy_-2-;cwe`jm@(oxWIpSic{Kzli?x?K}wjPb@#I z-;cvzML$VjEI+K@kHguH4!@E9C3YSG{V$eZ6!?A|{s8@jcASGRmfsfmejNS~ z{SUByvHVQn`*HY9zjMp~SNdZ41%dC!;SbV(jh)9p`^ECZ?az9T%g+ydKMuc={`Gbq0qqyd-x~OS9R30N>*zmvXLe)##{kHatePuKn{dHfd357)mRhd)5S$i8>S z+do-;RnUIrM;!ik=Km&rvHTf<@5kZqrvHm+u70un75Kv@%<8=SVEBzgE{5;*XulY7 z>^qw*VFJVVqpw}$KmHZ?P8D6 z7t1dTd_NAqg8m=qi{*#?@5kW}(m&6>N2CA6^27G~arkTL&!sPx-x##tkHa6Lzn;EW zekSn!IQ*vncKvsdzF2KDro``?el-$(ym`r`3?KMwy8{io@R<%j*}$Ke<3cm4lH``(H6i{+OE>(7tFUr7J+ z^u_WQ=C}gDbzXij{LKek{YCaY5cP`@N8g9m=jZ<1)i0JG9>4rJ{5JY6^u_YS`u#Zkb@abUUo1ade||h( ze)<e{suy3w`l;z8{BQMgJ-KV)?nj`uF4T8|k0_3)geRUeX;!Np#6Rve%@bQ`yZw+mLG0EejI)^{n!1{wO=fMYf!%*hkuCvE%e3m z%L3nz!!JJM+W%$xV)^}n@5kY9q@TOTwO=g1KJfiG{Dbs+>5Ju82EHGMUv}8Ff7e;A zezE*;{rhqFE9sy4l=H>%tAhIdIQ$*-KS^IKe@5W@ark@aFJ=41^26^BejNUyzq#dq z<|)^HvHVRz{eB$&RC{Mc-a0#vhW9VA{Jg;T43L&=<=Oj~{*<{x14^>5Iqn{W$!C^xv}AwO=ehH)y{fhd(XL^*_$*q5sA5 z!~Nfn!+(hW?R@_i%by<9@5kfir+<+3?;^_&_dh=le|olSf6?i#{o-LCf7pasotGaB zzjliAKWOLSu>4}gvF@rYVFJVVHiH!}|R={Jr!)OJ6L%#rgmfxX#NDhClClZuwtxrmJ6!IQnl0f7pZ> zd_NAq>}==%iS>(-AAZ<=KMucz{*^jILG0tKUyRq#{_yza$Kf}g_4&m!fe+7aGjSQ41ebfT>W>jelg-${(4K8!0`Pz{Ja-B|5^HC`9-lk;`?#<^XNZ) zid%lM{I{oH=U@@L==n=q^M@`K?|Ki@6?7S=CD z9Q{{l2@@E;ABSH-zi7W}zgYg(*dFoyIQ;$eyXcGMmj%8bhhOj_*Z$Aa7t0UVzaNL6 zp+D^puKi;9;rpK-hrgMA3Hx6xKivNPIQ*OoT>I~4{bKo5!SefY_|^0;{iAEYSpJN_ z_v7#v(SP@8&KJuMzrXr%_`7X@73BR8>le$fu=7%wz;#}JF#PE+cm4%`a`lT5$M)A^ z2@@E;ABUfz-%4LBzc#imYVW^c8_ z<5j(gtnr9S$m?x`hqi#ceWqjd1AL9Ycr#h!;q4-8e79FyUgRHI@BDX@HGbe8vc}`X z_+iMe@x$&Sj5i3@c!L-} z5r!pyd&h-ct#jM39Rvvs>m8|4C6B)uJMS>u6W{3*mWz7)pu zLHTR$bIXtMnGo0bOtZ;rZNssbqgrzAYaKU{tH_y{2Zo=Qh4(9zulFNde*)I^B{-iP zGtUnf*zp0}GS8Kd;{{m91B_n|*7)QYj~%S>*fBmhSmS@=d;?hL8*V4(z223N&!dRz z^Cph3G4ptf_dBrO@9_Bvtj|aIJPy|9ZG1ih>+=^rZ-DiAqj;L*0{g&<{#-#`H^(uq z4?uohAAsu}z`C9R*RO$feHyMu1?zfKoF4@1{2$JDf^|N#=xoROeFx`*5ZC#hDbpQC zSGe|IycEROY;%nJzrniy8}|c(=Y7w`F}?wK)pp0XJl}EUC64j@AjI{2AUsbVtmnn! z`Lv=bL zJ~y~N<;uhJzQKClH|}2p>;5#1hXB@i2Y5a-SkHgP^CG}{9>n`%wobGO>mTFkVt>i{&OAMQO`{;cZ|1*cv=$hnt&e)_?dt&wKo`R z+;Dlf1^lgm&%R)E{_22l3i!(b=j4s{8w37Gzz+ue%Ygq9@HsCYUH+>Az9QhI0j~`B zv4Hb099@2Uz*_@8<0Yf>Hw3&k;HLtP@pep|pd z2mGOc9}M^x0skrByqAxzuR7qifbS0Y!GM1h@Sg&{pkQ=;#Q|Rta7(}+2>6QuKN9f& z1U&s8M%P~v@EZee4)}(Edjh^O;CDEl5+5w=pF4v1rhp#^_$LAXF5trfpYe*(%a`wX zxc<_BYXYthcwxW^$5~pQcLeeG1bj!p9|`yq0e?2&F9v*Hz~2n`y8+|S`rDjVlmR@A(0!w+8UTodRAFh3rAsXRqoqnqud{TcrJF2W zYU%Zssw`b*>2gbREv>M0v!%CNy2a9frD{txmaee$221a-^g&CjE!}SE4ohn+eaOn~~kVoO?& zDf|2XkL$9}maE^=$y%p_R@SYSZnLz~(t9ku*V6ket+MofOCPWluKRzn*T!4_AF&v= zfpwPr?O?s}M7ISTbMm7^;<}RJ-jed3uI_Y4W=VZ@Pka4>z8mA$XWHxC&8^*up0;F9 zYyARyS|YNS-_YLN-j%o_-Il89PxoYcjuvT-m5NNNC)2+Cir$XqOuDn9C(%&4EDp@+ z$ymKh6HB@~+Y@~b>KZaL6N!?N(#6T1baTSJIKQv1!Cq@_O?D?T-N|&OXMSHzjlDJ} z+1A$CoXm7~5rL9Q<=mKspZR(ZHX(ebu36NZ|-bKvGnp~sb;M6 z^yp0>js8s6FDNO$X08c~JCoflwaMk3y%}s5rQ;QvPN(B|S#xK{vQ&2_(S;4Iq`WcF z*coq@wqL{<%F!yslFgY^_sMJ6QOZ@@=BRDS?xo8Tna;$uaStTe@AdWZt~RsS&-SLV z^7Ua!%9iwYxP1_R&5ZZPax2PqckIq?apM=-yYNCoaROTWO4oAh4(;@KWl4L+$F@|5 zkC{#!R%B;7Z!j{yVYoo|QbS_YOKm8k-m=DPW_G5tx2r4F?ZB!`+aU-!*sj_3QimM{ z*sylg=3X1l=Djw&0K>20Fo)t?J1a7seIwOXplq+cSekQHSE?gE270aVUuJSl}Ot*7$5oSZM$zMPuTzQ5vHswneLu%8*hnmLq(#oIMFaC?(X55M;}}# zey}Q;l}IF8TDlYIjzo8|V`<838;)j+uU^o2w3;S(yggbqc04{-EfajRI9e_CW-?OC znD0o((P_ojX>IAH9k#~2{;F-Su%lIbygi-hL9?VhVXGvaN%W;Nt%;uWjsA*>H_-~) z7M9sIQJgqA70$M0vMtpXs-qK2m+YBeySUgE=<0@93Do#^tfu5-S5s3u?(ABg!24Gs)o=T7N3yNvr1cm#gp*%j z`^o79wr@TbxHgRq#+L`Ta>Ty_?CvX?#r@mQL|g@ zY(jVEa(}7H(Sl`HH_T4d^YbT&R=h%iZyJ5DvVfJzL>vL=Zz7V=KJh~&UwDn+L z1ib#J?z+l8_W4KLzf-S_+oTh25Kh93+2_x3)5D2^|I?iZ6^^mtrrl~PJ>Jb0#hvW_ z7<28VZF5R}h4d;Q&Nomidead%zx`!Sn5zJ7$=-fG{5Q_a1Z zRH8MNY)N%TiFW%u6D8(eQJu^r-;l~&zC4qv&)Dm=Z!}u4xTSG8?IupGeJ+0{_nVPFha6WHwPsYkgWa^vk zIB~V5V--RJAL*c3m>$Ov0SLw&buE`PM^wYo>)0^tQ;1eC%DB3aB-uULRR-&CbKXNUOU)*>r(~99%G1l4~ zzr5pFspa^6uPrsF*Uoq^v6FJPN!8hj^wM-ojlT(2q&s`;eYhuu-%?EBcHWRFDQW9m zYCj~Vy1P5O=a$;Zq4<{)JDFEf5}(3$k?N8WqttD1M+Rng_jY8`?Wr*eD=l7}Y)K@$ zyOYZk9jQKUvvWsE9Xo?p?HIp$PV`&8JFkdEJIYzt<1DOQ-E;!&;_0)K(=MIeI`MWL z$C<4OcABl{_+32SBF8+9H^G8V%Jy*VlWY?`X)(NE^&MryI?lq{<6j`hKAAqzqJ}rD zlhH11SSQ}D4{eg2r6XH9vJeWL1Kjz%=h^uI!s z9FHDUZNIYH=K^m}nbn-J4|4OHYle^MZV%#-e^z|d$2Su@%XMR_yED;azrd$jhL6`c zK#j^1QXvS=QQm~H)&7(fK)dc!*#=an*y_xuX#kl!`@`m53W?I90?1BP&<5+Az z-QkBPe4|U-XJ7jTD${B|NR3*KVR2S-TPoRI^H%g>LuQWsgw&qyuuq-wr^iP7k=R{9 zbL8jMxYvg>jQ{@3e8F2Js<0L`$;UzIIq|SvMu^6MKA7lYP$UZ%%dLnkhvVrCE!P zvSPey-)8L8hBeYYd!^e(zp}K~F0a8$ygDOFB%7O4J@#Aa68m;#O}@dl7JbvY#;&2T zFHiRM%w3R!?{xMJFV)`MW#7VVjw>PJKWvwX5?!5kG@#mV_OI5;Q=y*$CC93AJ! z7e6$2ws+YFhn`f6o%6HHZH_!8G{MH(MFDoXK@CpFj9Ly9XeZBFQcIG(Z5emrKqk4g z#(pfWsj(A!;W_>1w7rzrdxT%Z|MdcUJskJoaV)SqlQ(K5B<#nq_7h$c*iGY0Sw^k@ z@m5E?&$>6EXP~LsA5LR?#vP2`R%h(hkaPG>r*RJAR*+?tq zU)gS-!Rqa&mr*}hp+SF-_gnjVYhSp=JFXmU4Ubyvn&HFwIIB$8`#z@~wyecIDUWo~ zs17Z$U$g8|a9ojVA4Nto&0kU)oQo0VVb|)i%U2_GP!xoKWF*#>9^GI980b zo{M-w<>DxWMvrq8IteZRf89L?fK)}YdjwHYQSpp`pb`|=-3gnFAUg*G3d@2h3J$Zg zv&+EF?lQ9h31UtJIY3N^h$0wHMT{8m6#R$*P=ca>3JRWrA}WG`U)3*6_j}zh%^Upp z_dsrE-s`T^)m7D1)gBD?zzoTeHCQpAQ*`VU8IoYZekzmBNP-W6j`H|rswf#u5C?{n z81=&%ishw)JWPCvT`E?+Ey|o>ye&0#*Ag2n&L->Yv<-JnRa3rn_(0J{@)$FY15G@U zwJUHwYzUe?;;Ne=W9y2bqbv&}h$!U^2_&lWwmStg4D&LxnOd>MF^@$&0;n>Q=>ZX* zL`VvFh^2#FI5vEIn*BT8A zLV|I`>%huNLO=|L$eaip@5Gwj);j+<*=>gAk@b-=MlN{<^l3MxSQstlRIQ-#SOMj_ z5Wfl~lk|>n;Hp_i0#Aj|Ta%1119#0a1FV^Oa@++>Ld9dkbUZkvp@SV5nW8ogBB~ga z!71d|Akq&}i6jL4NEk~We;6DJ6vze?2s$R@xI#x*7X$*=*>5Gv;#jr}Lm6&WpqYd- z*qy~ODvm-LHr5GjwpOAVY>7QcC>++-QknJvy24gDs}nh)DB$RXvSkL0xeJfvOJ#(V zmc`@gceJu5aSfEh2LgF`iVzK8 zO}rnI4)DMY3*+1t79QXoq2Q@~M0* z1hNWHLKGdu35j6uyRBOdkdSO9v8c zbtNDtKst~U_`_C#fjW?3!nO?*$pAMb3YZzx_n}z4wkimmBdQJ74i-um4~|qN6EKDP zEdK6G)|F#vQKSkaoQOJsfQp3_#lxecr^NSLf1X~pyhtb&N4 z^edb~1IY$xYPW%Ei6{{fA?-HL4JCFi9v8 zUvwvwDl9ASlAk>{_HM6BtL4MOs1X)AaVm zd73Mk_%abqRTNVQV{s`poA``Eu@BkILU4v?Ek*d88azl=9>u)Ws`I0ERu-|OM$xlM zh0f$8BWkeXB;r997mR}%8n}$S0!svQ2_X9s-dEDg*{R!lR1 z6t8e_J!gSo4EZ$A>v*eup3hw)=CW~m@wx?ifFPI(K3TYAE2d>e6)UovOKY8$IZ0Qf zIEgZ+5j*Y>Da7<6z#h!vru9_3(J|DFO1B`z1as>8so9~*zT@=lRj?o8nT^|F-iHk=WwWSITR;OSz0Dz2;|4PNrIa>Zmz z7`zsv11_|VtD>_ia5K}eAA_*?v9=xpT~73^)MB&r*h}x@Gv7!o>_u(5xK75uQ*4W0-0n2*nQG!4n|4AxubW3Q9|Zwr8odx~w{Qe1QgoD%j2MGian)c+up}VR3rW`_BTzzbT|!qC$bkMKP#3GLuc;>q&{9Ju3h|PD4H#M?f5@I|KD<%>AcKQ|&m|0x zt*T_v>43yD2kK04HeilF*sD@06rCr`EG4TrIW*@fH7`KIRFDmDklsxb1rx5gfB}S# zdnw&&NVg5>pbUrII$dp1p9qHIn2e^h6%3_Q+i60k-`dPY*HVoF7;?#4sMrgY)mKzR zp(Qrjqs+oa0|{Cs3q5|P(BH{t2@O7a2_BE&h>O)6H(%N z=E+HD__>^$WJM#Gt_};Nbhuga2umq#F=2%=svl8u&fqMM-d%#AV{{H5yV?}KrTEO$ zB3YIc(Q1k5xdmqf{xM zA`l)uGejiPEa;t|7s5u2a0*{aI;6vqrsf=p`yOMwC}#(<;)1JFI9>Yv=#8XcWPC9{ zZn>%Nph+IYGyxuE2T~Nb_~r|Y>8OqbQ&+`EOEm=nw&KI|08sfrFAmTc$HMQt(n%HR zeL!vTB(jNJWh*;P(ais2Q9Pyl2t#Xjb7KPPj8D<1)1Hpn42*@Ta- z5yfOOr1(NbUk&lDrFh980wZ!z5hS4qF!bXwEp>p4*k&#b2Emo?*C29^&X-rN{VJHaMHv?*uqFlECdaYzMjjBK^g0DCwQ?rQ4?eloyFdL{Fg{Gd7Xs~!N zW;kiHonU(;+FVZVllBFY5Jglj?-f#f120KAOq%Q^bL8+256H8MK~b)B0Z$6Xl%5S5 zqT0Y5;PAv;OeiA#>MN-kapR!Q;G`8P9tI_vv0liroU$j%W|!L5M4)4E49Y;3HWzjb z?jjb0rC_Je&45fq20^|YG2kc$nGGjQO~tVBj?{~b;shI7wBq!bMYwUtG7a&dtxe8B zEQGn;7!SEvfXy8$6VPFV*n!ZjBUmQsXF4`*348;mO)*sfL2VO&5?-*&(3vneEr51z z+S6&i0|ThDo&~d(&{4#Vk<+4wivedeYE_9x6S|$c0l7zlK``lcUMG%8l10_NVnvGM{}UNCP`)`NXE4 zFvhX#a|)x`uFu5m1z^QdTZ#K~QPPd6($rko07&HN>l5wSH3*I@*(AVdfxAtJ8;@D_ za{uj=LKh{5OMWm2M#`GSRSf193nJ|QMj&d_RdtKe5}XjF6yy?P_5*iUh3(FbTye22 zNg@TNvlEJG4OFhZEk_HQFG(zwLP7eF6h=0P3uUs((9C5Kbutx85YYeF)Ri^ZOyB?>Ihh!9 z2&BzBE%oVa>NK>dvk4h8v)Ut5L`;AG_fqqiWA^;CVm!7+M^m|n>tU;1Yd|$ zz!(t)<-gl5{14Fk}p9u$F!GZocHef1$}My*E% zFBi55IV~LEh5AAGgP}sTv3o${uW*OqRx&Ul2rjiEu#d|rIx>yaY4a+o!j)8_yG#Q4 zu_EcF0JvX8fU&&c4kj1s{ie>@hCv^J)r5A#}JPw=bo5B=yKwE>ub(+!!mb z8%aIJ>}Giq!YT&^Xy+wC9H?|4to_Fh>1v}kR&8-n2IfNx6%3%@dSfvwT{$sLQ)GU0DCprci64jC02dJTAOfsJ770E9n`@eBXw^JbS)F8hK2L5%0{WR)ArN<00f}b`RHz6W z-dm{Nis!OKI-4XwbP6Sz*cHIGXl7z=*SWwIn@m7%NnSHCvDIZQ*hh2=n^gvaw^+r7 z;sd%AkMfu}7+;GXDk5O-0%{ZD1LLAf=P^QQBP<&Yj<;k?e(HMl76!6sb7Q|ywofOEUB)&?*h z^}^>=%QHq?L~NtPmD&z%%$&MvnwgIgPl#uj-V9@7N(xyv8Hk?L?ZqdIL%ThZKAV9t z(o5M6P??`yc$|^>sTqmNFyfddW2N-jhMdx_53vwv{}gq$nm3%(j7)*=gru2=;>_?!1xr*SroxvjIsX!a%gg`( z8FhxZ4U0?Ol{25}mtCCVY#>$!^Pz0Ph9WYds`V#X_88(y!MS7C;O=Y3l zzWApnvwiDotZYC<%aIftp-CoOeVG=Hzrb3g@un>Wv8V{`Mi`2ws||KgLLz7vQm8N7 za;6F>9jM5AYJD*ERGD3t4xLVSX>8~UWfp&d4=AlLSK6OAlRtcmlk`r~3#7P?rrPRa zI@5;tstq{kI<**`*o=7P!q+%LIwm**z z+UZve@pMdk`#{$Nl9)^#KpMutIVvG7D4~4Dt?oWOCD|Ax-v^X2-C(OTPb`>%a zewa05(r$f~{so19Hpp!q4`JZyzk&fCheBHMcfo!?H%F z!+Cs-ZmV^d4G{GTA5|%&cwqN4%94j%IM%js-&hj14EwKGADoO5CI0ePi?-Zq2qCCGo&*UGbYch!NQz@app{O*|U=|{ZKL&7dGpaW@E$An=y1C z)@Fk>*XA`#RLdM`G1y2_yZEi#G}&qyJDo8H18Hrs2|>o7G&m+uG??pIC5(7h#1cuW zDqKD~lut)&mUJ*HnNCeWVWVrff{kptbv#bwUU`Jn6f(Am@(mV%nb#r;yDARwvT35+Dn?)!b!r3km~3p2*`}NgM?0qJ z4~HU1mzsze%UNxDootaJa3+(8)?$}9(OsI#I#Wybp-whvadb=RF=iLwA>*vvf2S$8 zvIwHt>8m5bz_Nz2Xl1M#uEMB*`l~qAeH_#6cIx1od|!HW;o)z(@~&1d8JfjrMr_)9c-S}5j4(@{#EQ|Vqi8|lrwCoii7L7K^Mlh(tnI=Az1|;yesFu$0EYc zV^a5<^q3~?jgpO_Q4bPj(;FUaq!i}d@g>3*md9Y(u|3Q{Dy96sJiG@XTnF*_x6fyS(qR@}O;CwTrR2s7XwH>4uS!txy=o)LQvIH$)(W=tWk^#k$&ZQ4GgFt%eZV)K8D}s(m8o~k$Zt)BD zDQ`Y#rE=)h5{^XR&ONo$8@X+oA~6(0grMPp(wh$qZ=%goBo0PosLM*EYX{*U_Vzsx zN99^S`a}rv1r&96_N607=pGP8jjTyzf?bqbYQ`>0W~fE^gVmw?C zS(93#Y&xv13~{t!Nj6*RE!*kdN(pFMY!OBiluC(u%PKv!#TI-uB#ki+IzD z6a2+SC+@uie!1%2H_A{uaPJ!}yZ099>D0ZqI6STY%-EG7vyG7$+m1A^)DH)7v>Q;y zBtsb6P#GDUlzR_?o{oEOk;iu3dyB)Sp+k}u&8(kUNXRqeG0&`sD!Y9 zldpx?5Tk6FIqShpt5YU6hgyVA2vggg+sl}929-E*&f$2X{5jQgDo$z+e}#mRZ;r^T zfCHgA;Zvy$KkS;wJjPh;n1C}foQReKvFoeZ@tFHa93oDMDU+HaX0N4e3}?`oG^y9; z|8X-wnuFYtP^?@w}OmxfMFk(`iG!L0r z2hTWT!zq^-RioiNb3_f>i{6PXDNeHQ7qMuk8m5Y|sj#Le=%a zdq};A$Ew41QRv}B5e&tEI-BPQc+iAF_tu5Ws-m7O?I-!VPl|M(c=WI3 zB88Uk{(R zkTY+Qo)?@q^<>w5;?ck6(c|RPlh?23Ge>4PaC&m}(&q8#C*X>+Ur$>-0(!{wl;+{B zr>TcSdOdZ#`U$<97xh4J7OYP{R=)nl0zDZD^%CaE)x*kFCb=Byb0pitk!(*MhnpNt z;VI-$mnR)X9Ln)l9tUQxpYtw9TX^$0&v7(}&!cCC&#RX=ABP>jB0cT>x%%<^96^NZ zD|PGC@6q$u@8x}_mli*VZ+_mA2EM_?x`PMFcZ#KgRMzTQNneiC+YSRU1cV`JfdEDy zxfIPA0_xo9AfSTabda3OlF>vmCmAk_RY!B+9=1`@NL?~#bo82dxLWxq9**S1BQ^0_ zxX?K#3;gP6@|t8_G@c!)t<8d$Vh!M!Ntj-ynlNzUczNZZCY0j>pTsh4VoyELh+U0^sqXX;+=C$czCXLbE zQ(jS4j#xPWLm_v1fGDGMFUZT!FK`G-y(d3CC}4o@<@p7X{6e5b)`2ZYy^)pG;^nNY ztiQou{5b(WYXYAw$ZFCoE2|0oFDokwf3LtV;pg0}rg!DGZ<2MC^sCu_e|l1W;%^H6 z+0n7ltl>Xy-rcF=h-J(BKh^GtUEltYv-^l2=8haV^Us|^OON{W$16hr>~`)I zli!${Gj4xX>A)jPH+I_KTQDc_Q0rx5YhUnR-MP*41BbU*u&u+4&ean)emH4b@28G? z@xj`o-|T(C-a9H6ops$?oA2w_JXrDYf_KY1e%__W%njEL@O<;+jqAH@z2Ig4(t^Ae zZ(e=+*RAvO&z(BGc4D&KoUU0d+C9)@Zigx3yG^=c#j1sEXMC|U()8%jAKpH>ebzH(fo(}w;VetWJ>j~*{~{Nuz2FDr{o8G78viF0#yx5=8f;^1R#kMceF zYVZHqc}d>`hu_|1&yHDbciwx;*2};6^@%k%y>rArAAa=cJ^e1;_UZ12);vG_^+?kW z&%KvFdDi$6mRTFR7c-5M|Ge3H1eqQm|!7HamR@_s5@W+bhF6jQk#+v5i zDz`73`PmPjG%mh#V#Bq)-h1`Q{Vj5Ct9X4v;k$R<@Y%zY&ilUooo_#Q>%_!`_x+K* z=iQ^5p0WC#<=<`mpjG~=h4WsDPN-ZzWN*&+x8|*DI(1v0!a;wZxo+y%2lftYcEadw zpH2T`{_3wzzOpvws-<%)r#!Utq)+>_+tqN+GdFhXR@{HVnKPE}ntsx&z2?MpMOiy#>N{j+HNL) z>3%=t*ss6Y{%89U&nC{wUyWgK3 zICb*}W&0{BXU|@?CVPC{wOeP5`ZzdddFg?{MaPFH4>)m-Z`7|-dmb2l!m_@f@4Nkl zCEq;p=v#fV`hPiZ^rJU)UE8(s^C{Oxm#(_#_kJhWY}z$*{jom}ZgWD98y-HZ{*#^) zzkTbGerH^>@x^8z9lrGNWr?p_-qL&QU8j88;?%8ezdGyn7i*9C{Mhrq{`CE=9kPGS z{k}YV<*0R?=RRH1X=?A|N9=0d&DW~$u)yMwvM(>>Kp9+oN-uahx$3%-OyS~u=niJ*Xh~evbwh?4mhI4gx@OvoOfo^j$6yFeWlM2n_B1G=IP{HJ>vXRP6_WDI$_N8 zvU9FknC-c6efGJVhWUS}SaxxrE_-&(-?jhBH}5+5=nD_Mv$|^kt^YjrsZA&EduQ_8 zwd48>zW%P?O6GLG>+k=l*wSoPr^+iYc=)y6@5Mg8KX*p+NyB>lvZ+JsEY3Y*nEl9>zfFE&!{^%u&YVyZzGGgi zF{2yL`*>ooc${{HUk{zz{7UtasiJHuN}-SCgA z!sorXw_)+@lXpJz=iw`!x&A-5_4m!%e(?E?fvX06*uL+qZi~l1{rgEjO?&j=@-7!o z{^i!YU!B+a?0Mh!8$0^F(edlf`eJyqBftEz)%I7eTRUvgtE-0IdfSZsR}NWm<=&54 z9$2<7IR5wnZRdS_$ICyB`}O@dCp^FZq`5<04lEtq@tCz8YHq5&D}?(@+>^#C^@*-&{7IdIdlBwv zv|-^DbvM*4yPCgxFHQFTl!X{hDI$nQ8|$ub^g3&Pm-jbi@EH8e8%fevG@6R9PZ@v@ ze|XL3yP0|ZTGtOT^Oe2|BxLuOXtXo6c4cSU*&klzS~t8UCJcv6cSty6$kp>kqsBiS6)AFzJtIw5cV{WkNW>;+ z{mV&8t+B(Sp4^W+8m(Q}xG-9C_0r|8wsg7SsA@R!>eBy}V1~(?x-=0t%Aws-lbqr8 ziSl-N(?xwN$1PW;9xSO}y11^kUUc{wlPIJ2yAQ8{Zaa32cQjn8sAP?8SqeAdznvURey8bozU!>AetpQG_;J0Gj z)Z1BWJCn0o5-VplZ)ibO`Z^E)nT~6|uxt8VpQ`xR?eF~VrhoiI(`gm>tr)kPCxlXP zivF(4bi$N^i{Pg7hfiLm$RER*U>624?(1>W&DF2R^tV~dH*}`rt+SRSRwiS~4YMw% zYTePEysdLqO)R;xy=|seHvTf}+IX@v(cacMYoT#N2n@FjcRJi-J0L|TlSkyU>EerL zmd`|H6DzgFn2z}?FM+%S@)F2PATNQu1o9HdOCT?Syae(R$V(tEfxHCr639y+FM+%S@)F2P zATNQu1pdF1z_D<6-_eaH?L4|S)ZKrE8pPV?V|`~-559uWotvi)^wvz>y)8U-_x8Q# z?~bUhWf4c6&b#-k=U25TwY6uj+J|M=tyq>Q;`eQ{)jljsW^j$#x8C4~&s1CcPE~{S z+ka~HVDIMh26{H%IDmDiHzEhB2OXz+@U!%DlJRpA{Dk2reB;2U`TIEY`?%`C{#goc zHx3{zZ}y-4@VU>8QS%sX-y^Df8`5#q#JO$nExQlSg8#77O}7s7JM(w|zwJP{nuqTn zbj)}7yV88e8d6cu=E(!#Kh|3_c{kGP!RPvL#E1J3?sOBDq;IytST`&x^~sbnyx6$+ ze)X2BQb*0hqL-HKd(H3TfSLX?3_iMX@lKRu_cP(>kNNw_=6A-|v-zfhE0IU~J+>Kg z+34&%TBEut%Rb1lFRTWyfm>g=dhqDRg*)L#hm*_iwc!B2l=sHa&ZFS=KxYo1{CYM= z2N-sw0J2A1FBGV){fMtnRS!m-!q;?}DN|;M`vA(i4e4ZFnHJ*JrfiOGylm&Oy>7aW zZhU&@(Xi@1wl}n|ck|iMjY$Jo4|{(4Ppb!~Lw~f+hNnWW&L7xTbN=q_o2Lvs9iFoL z>6$6)pWZupcdzPtp*K8v;A!YyZ}_GG=y~@}=vd+4pZ;k2rK)@S>zh8abMvHuGK4wt z8`Xm<^uZrLw)uMPZ@M%7HRuTZpEJ?Z^nJrz&7}$zlf^d(;Gf(cW=!txX;@CVv*XqGyGwMb?xp)YOdY= zD(Ya*=4%IPr>N5(MOu&5sD1dY`%4!%`xZNDuzn2c!=>u<5Oin^?l1mG?fX8$fWPjZ znsarySK{}=lfQTF^pB1|4|2aPGDh9rKkngksaH&UFXD?h)f*l|ns%Zbr;izb58O7e z9K@|RJY_xoy8dt2jWAB@Mc)7Z*s-&FHeZMO+qJBB@0niv@YXq1tcQP%eD2(P&2EGV zyHPm47r*zu_2H^sQ}*P?Or2zX?hT(guoJq2diHz-Ws0<=^<|CWoC3Y*4PP@b6=m@> zF$BvY=hqPhNAfwsF5ziHiN8H`cg)ZaVt+X3h=wv1>!r7Vc=B8ESv?UV8yzjw=b z$O^kibX)7uyD;lt82t~o?Lc2+;2`3Wbc>wEn{bY9tU+66be4L;@<7-@dck_c^ik(f z2eR}bm+or62-DLZ8l7Yw({XLi)_rWDf*xerQTCY>Y@gpgF>TbR$R+5%pq*G_Y{rpe z$L{MFk@oIr=<+17vv>^rHQ#V;g3=6jXIb$dFZ!9;svs{V2 z_21GPUtU=Eba_G!)D1gNL2`S@@5jiC;iToYH`qSwdWAIZLf&WTDJbQG+{HF6YMRlt;Kl+&)zb%Apus=xuP90!AJbB%mt;5(~mb1JS^l&obq3rjb z?$)Vku&2{{s|VkM&&$fH2QPrTUq?iruo24}wvi8p02#Rir0H$MHJlD&^Oe_+3ENX1 zw!ML^=?SBss_o6xfwRCb4!L!&54P)a$QbEtQv?0=dppON4<+cHg{~wV?>@4%z!hrIjot8SKj#mHZgqIccTH1y$ zAx&ZOS~E)tzahtn~Q8$klHMVT=l-Z|vQGxvHb)1vU4{JESI~KYO+`DJ-5>CA z)8km?3;Kd_=CB-HZYZaSL%XeQx1OKq54mFmwjm0?W9$1?`Tkz(`_1M%?Q0?YaZHQ0 zOmkMi&F*v70aKSfb-2duV@o;ov;DBkVso~=cTm4SjIca))*cr@AE*Z$A8plXz_=9p zz&N%5qpi}oANihVW8~p(8?z7kHrjac54+oCx%Xo1bs;eG_&W6KFl6-_>hr65+;R)Y z;5wd<7oL1iP2oxR6kt4nHWBHz#xVh9=(l^=b3LTp)9oqhnZGaRZ_`)@s8gE}9>*sb z&+GEC$23F9l=dvGFJss@J715@IR3Q9o_8DFVZHemw)>E4FUEW7H1#IuIoQ6VEOdWo z48|qYiQiys-lymDVDqLLn+G}0hWjfBhjEm`u6ShU(+$xfmPf93n=(k(b4&Nqzo9(( zFzz^jw6I_QGIZn+(l7Hlewk|7L+AUEPmk9Yy#z;(6;I=*8st3c(T#POFLcLZ zwytrWmGzQ5&4u1gM>xOz!?F90g+oZ!IE?o)>5?|)e8f%Lz%;Qg9D#qq4#qKeB23Y9 z+UCP>*L@jq9zlKR+pD_206(l79IN(SfU%3@2X=({sge93jsx)D4?hv+=>j$Qs7W)! z>Bsk@8?V4vGvv;zLWemA+<&3kLwEGOGx>qf+>-c#zRJ!yY6Zu>b2NC|ukPGMknMP0lDx9O< zAP;Biyi^Y^#V7N__Q64!a4q2!&OhQe2R4;@J06&}pYDAqo3WgyLtNX!HxF#b{PfGP z0f(km5B>uA{w4JKS)@g`*U*>VFy_=DZ*p|KM7TQ<7RyJ6ISu_%xKU2T#lQ~QQ9MM1 zb)V|NeM~3w47Ub^tLrlIi$+holM_L@beN7BJo5X@`0E|`vFl?{J)`~}30j}9bp~Zg znRD!RDe7!5^o?UN_HAnLo7fwcD{YXj4@fiZnDp1|Hq*9yV(V@|xc>AZoGq$kX7?(@ zk!zlsbrpjxZ{GxE7__!Rznll~^!-pq{`H+X+K;y`+kT{d!g>e7%J`GHQjU3p=0;hL z>{sjYFVfO8PVGAxetWDr3CNOdrj{GOYx$rr;ZL(|7qmTruF{6E?<@6@<6FOtP-3&&s73!Qe_ZloP;hqmF;ccy>Z z;+~7I!@7P#R`uZ8_0w-(#2+33_xiKaldE5GnjVuOEl8)DmSb+A#;rRt zCJ@<4J+fscx@FI09z5B|+c%f_3T*s5+8v*EDQ;S^Hv(mG2g*n07<luuGWt`q_fMGrBJA3IB9K->LlEzo74=u1nefJ#ZoFH`?@< z(WW0loBj*by}v*h?pmjjBkCz_+|i9!Vx8UX@7m=ldLw-m+L?)_-{8^R8dpcOT*r9j zDmI>dkqBf?yO6f^_)XVi{opG>VV$VI)!@u1Z$R)FHz^<}!ah%b`Fmw^RcL2I~ z5czo-c{zmme}Q=V_p0s^>h>AWfb%ePT6D1%TAPyU>*HROJ8tDBllO57NG2Y&3Y_3f#+4-q)eL7o)tdMtRp@ zOmPLrNuhl`p9<}}5apruh?KW$)81j>o9q+&@EIeg)%pj`d$f*}a0Yi^Bcr#%p)J-F^+qV~jgK4QIwzuAJDH z$&|Y;Z`fAOksN?6y%b^e?v=5_6!@Lu>OOS=I?i^T^)M?Pn~@IKo>$O6Vi=w=jinRZ ze?nWg9cg$3b!`W9?-xk_FOh!Er|C8Y^>y23weKLtRn=zQst3PO_c_OjKF=Pmcj);F z*td7w@!=lMqcV-KvwOm{O-QSQ&%pP;Rz;(&H7ByTscUM!qe*OShettfdVP z>c{GF2hwcYPufXov&o^3uq{$%-;&#R!XA=>u1oFsL@y4)*1Sv}(?+?OI*K+jYmX1} z$a;cuazE`h$I?0K73Ilvp^iRA`C@;jp5KT#;G4am{bnx((>w$HH}(X*z?)U;bAvFtBLydGKF`9m3}*GW+BvL4#o1ltSwJ`KA_ zo%kNw|Gh{v`)}-Ha-DShYPFAR`g&do`oVISIVScG$-D7CkY}Vp_e+ePFdXWOCx10= z-!|PB+MBUsL)9(LzhuwXTKx-?KX)8KyT&p{y?I1+?;n6|hK*q#iF(u<=6*zsl`*He z#wyQk`28}t>%I`mm2-*PQT~tM_rEmdsMkGUFSXsldJx+Lwv$-bDbno&WOFCe3R!R- z)wcUOT-4txh6Q;A^>h7pWfRkmvY>1O?Te8o`|XS~NUkhj)^mo#Hj8_E_52F*$g*VE zoKN%EtpMF&J)&LG^AXUYx1n$DIK(2GDhHUY?BY5yxCa=jTeT|1BA65Wk_8ZK$w)%znFBfd^uOU zfMtffv5a(`hF`AFM0B0XwB2?cW_SwjXhrve_JL zV>Z{|0rJ;br%athIv8nK4#>IE-?gMMv4?fFB z_ghD^&S~inZKIy&LHcB_JQAy(-z)7BWeGX3zA%qonP&8Yve5M!;S@rDUO~9j0SDiE zn$*6N(6(va8sq-f*984G?H%nV>%N|wf$ehpZI)fKbVkOddM^iU9pckztAYK7?tK7Z z_Bif7O2!9W)nm$Q@VmA%D9;-sCO_b;#P4syrr7m0s6XBGpT2&gB}36c$-kB-Fuw!dt0?RAywT0o^Ito)YuT6fp1=Fb zbFgPQb`JI}kH4t&W;Oqt@Vj&GExYxeWjyaysP{D&UKF`W&G*#rfOy#kJpuj-WA}93 zf^MJ~TzI4?T*xa^;|Zf&5|| zhjlJIi->x(6VJjvhWzq5!|AAVS^HNYhfkTk6!(&c=N8@m-HijXe`WeY!-Ec&nlYl) z2fU}R26L$wE4{~J5$Y`WvK&C44f~n~e*!znz24WN3@B69uU@1ng0!&jO4;lFCF&rb zzx^2e_0Q7wq5Gpu7v?4pTmZRZew1SnJy&)C*0A7@&pzt0>)F_kBl9yDzud?9N9Y)z z@!g8=x_v--aWBdpz>KqZ^G#{)B8z)B+!?Mah}^Rc&qr>DKRy?sIbp8XFwVl)cIvn} z4}!FDoMz^U?v^n$(y`Wr6+u`#86WH;?Jv{S1~;j*IxM&`YzLoQ%f2cdC-<+YZg~zz z+V5k(J$7HQX%8vCGRR{a!ezP8mYxaS64@R=TIN#z@OJ>RTWG#BpE_Mm;XQh+iBG*B z2l;G-AMVZLnzy#=55lfrtv1vlUG}rVf%Rc;@H~dyezGlM`^i2X^X&EwEE}7nF4K-k zKN9l~+D7ZS4d_oUTVVIOv<%>v@uJTaFmB4&06Y_x9v6%{j2e!;B6t=Q>szR|?)om~ z^-(uD$MRmL0c%{_P>-pT?1%S44_G&PP(D|{U5_1*X7m>y>-)Lt<~{?d7kZr%b)yl# z^*@5~AnHHIQRK3$xd&V88Owe%+|e#^??d)@aS@)|G;3oucKuwAy?#2kLP8q#J$ql>9opcb9Nu#5I7ziYUv_v0&TQ}&#~B3@Xz)? zYb@pqn>^Zlj_qIc$6@8iZttk4Z!&zutLq~8wvJM#^w_}~KlY6oe*Adq2-D2;a_%9Q zJft7#pJ!v;fSopDB&$wBCjNTBIvsIzU2^AE_}w03`sBzoxph6WFD%f8_;j$Jy34YI z{<2MHA5!KZ>e=StSzqcN>o@zVoO{)BLV2WFbbr9jp znCjs-u|8((FXxD;KO75$@SM=cP=>U_Tuac;R^oTvK46Yj+8Ud~wlD%-s8DscgG*g; z+Z#6wey82Db;lkn2kG_ym^p@k^8d1b|H}~dhx`AIr~XXz)gRIEpfTJ^v}N`fPWN{> zhJ&8u8p910-Uj4rMB&-_W#1UOvJCnB0?xD0HbLu>($C0Jr>NhBk?*?ui0`wW#f3lY z+rv1@)w5$!HNQVvJ^wk`_hj5zZ#Y-adZ6nHo@*tKzf-sRQAZd?pq}~4Phr2Hs-D^X zUC!(7^|tfU$Nx9f4SQ^L447poW2;|d&e~h1mW{E(6ulO^ThDM<2X&n`Z3Xh=DJx%k z$;Env#|Fwi)YJ6u=A4HB-bm~eo@)=>>nXDMYo9Ez=UeNu$bxCeDT{zK{XN2Cf7)Zy z1N`lVzmcRrXij7&mk!Sl;H+-ngh%Zt2e z_>MZH=i(joxj%&P*!MbsaSF!-ct&cl4}CNCzduAC!s9-V<_`8m0T=gEMpC$IS`BT*f$Z7-f zw&9iYsyARj&2;dLB{xmO-Z&2fyFNx^#t!^NQ*{i^jY2g?c>$ z&)AT9XK5)+`&mSrTzsu~|vEyU@wxOKH!<}j5b0vEwNOabAC*}|6*8h*F3x?0%=%#;%zc9i%hEK|XHca}o{TCpN z3+NAZ3H*qeSCI8c?qz!vdZ7Jq&nM~)+I?NGpGJO|cBT`$qRY#T(+#WNoNIOf>Dd0( z{;Ix5u(ku)Zl_*Bw&cBFYw8=o5&7xgeLCESddX*=e)M{_u5vCyxBZYG=jMx9r^nHbX7tt8OI29C zCu8fp<5}u0ZS!RaqaWqsbXV`e>!C7j6@M$}TDAbcvELb)tj;LyHui%U{_!H8GdwoD z#+|D)b;8xJESu|12j+nH=spgU`%Am->i&dbpdtX=l1u!QTqpo^->XjAi+3St-&^ou^)xo{V-I zy!5>HaOrtJ&QF-9y4lZUdL(^cfUL687Zeua_2dn42adl3`d}Oji@v$@VbD#c17Udj zSvANnWXJTR_038P>$U8q&~aGZYj$di^~jjT1hdguAgil1$}&Ii)L zal1W!DAoDNj2~ti%)063(@LimrfwHdo-Eg|qOPKkqR*nDU4o6tIv0g~qfwoU5+EDq zVI=)@$`5k{S-R=p_cx-xd`*Ci19XOMHth;+oZSb~^Cgg#mMio`+X(%_UhfFv26vIYfZ*lb=%+;U`$nFcGpYNV|Rb$UjqV4XST1DN_ z`}dIkU63dB;v9aO_KLc_t@GzqQ?;9GBYT?EzMlXiJ;qLE=70LE_KNWrtQ^o!}mWREPhXi#d9AK z_NyFkpzL%X0r}Hwn-=C=?P0@ZzX568q9)Gj{-Oz+>1TW|!%xrN=x%#|6@UM!6)$DM zwu63UF2Ixb(z5O|kau}Tbt2?4F@&-SP5rU{KGym^-uixu_5F0~`&riabFJ^^Ti@Sf zeg6~d`%LTmT-%3=-#=r0|7+{}1J?J?Ti>@^-@jsg|GM@4@2u~CZ+-uc z_5FL+_a9o{U$DOa#QOeA>-($L_g}l;k3IMyr(RW~X^89ysU=&SCqk;OJLJ(_gfWMHqI{U)~aO=wyuB4|ZQszvyy~PrjCx8GiQ!h>*7tR_M}=F>r6D^oz(i3&uLO?EYYS(txfH%9f_9sC9Sch zG<7@z81gEvTUuK@qz@z@9T`$s;fah9k&bbM)}_h#9E%%Tq%katg5vQiz)NEJwGnlk zpCP=AH`IHlQhX2hWauL1fEC}N&5PK+=!fsaR+lLCB0irlhg#ut!fd79#^(Y=IB`AP z@L7q^Me`9JK3lMW-GR?Y4fyz6a|If6d``Mjsa|}(giTXV;j`~5)F*r%xf*d`P+x?} zkP>|EzaHl8@d>)_Ap9Vjt zA&xWPUWB|9DQ88I8qOtY zNh-W$65J;#b?96bx*n674CTtWO#uJKXU=Xxj;EHVA6J!sL&hu-2YxRE^;9hWx5L8I~{VJt_pTfSKkS_bI0c zdUW_w!-u17y>n!q4M#>xY!n z3!PLr&9`(J>dbQG+`C+bjx2|48kKW>qbgX@h_D(_uGgs0u4{G2H#`yI#H}yqBOtFo z-H=`@_U8s4A|BUG9$)yQs^=1?CguQjJ;f z`TIEY302m((0oFLHHHf7PdCnqT_+oSiur^ZAL)t|Igbced?Pna0}In{g?n@^}Ou8CdmF`rOfjiIvo z^S$QtPs}G&7}vzEQu7J*)fj54KQA_)P+yIqzWNhtt3PL%&oc8_Za$&9xF&W%W%Vai zR)0cW^(XeK>(6=Sv&wuzjd4xvdY}1(D)Z{n|MUOy639y+FM+%S@)F2PATNQu1o9Hd zOCT?Syae(R$V(tEfxHCr639y+FM+%S@)F2PATNQu1o9HdOCT?Syae(R$V(tEfxHCr z639y+FM+%S@)F2PATNQu1o9HdOCT?Syae(R$V(tEfxHCr639y+FM+%S@)F2PATNQu z1o9HdOCT?SyafKQkU%j~*?_wmhX5?Vr+XFvzTk47|98K;&)Qqxd9X#7i}|0t0vsUV z;30YEGTe77HRkVdF2>K4I{FR{1Np6^Le(J^+JyUY+y`-&gw@eixMvioqrb=f+!%Ef zC(Rz6J5Gguh`TwWLchk1Lo$vY!u`qd>gbx2)X}jM)X^{EzU5>UD#F1Sb8)XaMIHSN z?#ffu(eL1H|W&)?#nd4@WA1MXYTz=04rJmUe}Kg4|m z_j_<~MlJ3R+@CH|;jiQVNfGjRrV7{Mz83c?oJtU_xx6-(id_*;UA7?=Z%8Fobjejf zi&r)`Zs>@sXk-2In)Z$jHEWZ}cw1_5e8bB2ShBgktz&I!dHdRAlj{Wx>!*ffdq+Hp zvqz%W)PT{LjJ0*P#8U7Yy{7GsL|b!oS-f*?EAb6W7cWoEjz-JN%cIfO_I2@SOM81q z{nF*p@_EskmRKjwlUdlZx}m)#(X^qiuBqj+svNIk{q~ggK zj-aV;NYvFWpBu$rT^)j{?1&|j^^MWSa^U4v(Z;gq^7&Ca=D98HO|h2v{Iv*WRjetV zs#~^nd0Dg~(OhSHt4g$YMsdDPeD3Oa3Y5Ba+I4xVyu77-HBP;WCzI{Tnu@xH#ZBT; z(GqW4om%5M)t09z6=f@9&Cysg8QTzTi{BA-z10lo!3sf(tinESr@pq6QY&v-6H7)@ z$yg%QiJ!C#=Equ?M@omk)RmV-qp_C6>NZHtlIN1vDmb>bn$*9$DCQvw6dvMeYiDG! z&iW-Q%Mkvu<#VD9i)%aoh|!dv=x8dSoU4=VcSKiih{mA4$#_Q#GzGHa#oU|-nazzx z6K#nU6zBv=C$_w9*G#gq8fv4Id$Slg6Jw72&0(3MT? zYg4Z2cjYptDTSu6zNs$VB)GquhQp^;bKRrR>JwgNV%e9QdKA4QfkwfnR1FE#RFn&v zs6^yJpO=a;5ycJu0aFWbX&Bu1*WbemReKKVyIhpwMR{c zNKZwDou2l#xJi>$w7O&wCQH;V&~)=U8@8o0on5C#AtW6p-q)4D{%;_|t=bE>AifYBbh9AlGm9924kp2$xeX|COlM4yxH2mI1OP&kII z;9i_sjH5Z5@$c~z{`I!t$A@sjy9xyw-tUBhZ00|ORKdG%&%PcSu8DdoG;FK$?NF}j zt@dGnXKe4NiZerlWw zm#cp*7@}^ffw3d9yXwy|y#DVQJSN=sUws9+so-!BHZGQo!GI>CmnYj>qcCB#Wa^Ac zoJOjmOVvB$^vQ&w8&p?eE5?KC<4tQ*@#va(49%K)tgt}c+fM;T)!!EKv{dz+dm`bX z1&6~kX0$w1PICmV3)H9UW(T*DQRxr6}rpm zacZk>y4xu&C_zA_T~2BBjIB;-$yR6Lf@hrCN!7cYtvKknvZTvd@wQXaP_>|PNo^&5 zD61-6w5Fq^VbP33PHE#Ir>Jy&b5TjJlcev9z?P^!o3IRxBw!5?(a{GLr818{BU2a|ZVteAwXIa6l;i^K4szsulH8vLBWuNZv9;8Sr>Dg77YU{Hql zA%iOo{)E9D2LI6D9R?TSfK&1-%Uu4=1~(dfpTV09{;Bvccl}?CgHg#}V{qJHoTsbP zv&~?h$;|W}HuxbNSW0{j4pb!{=k98JxxvpG`~`y#8T?a&dA2k8rxv^XO$J|MaF4-X zF!%|B4;sAR;L>R>pNCR2yju+}GWd%IKQYI3f6d^R44&~Gmw(vcjRxO@16LW|cMQJU z;4@*znBOA?uQ0d>2eZFs$BPZuv_F$#=))hf1ANP)0+5m20vx+FAe5- z#dJUUy)M7teJ-vvxY6KtgEtxcIfJ(t{9}U;861I~V|pgx;8=z~*Weijf7IXxgMVmn zv%!V1TjcXBZt|-Pe%|1l4K7&Vx_{i@27|w8@D79DGI;%^uK&wm*BJg22LHXmM+_bd zyQSs%0oVT$gKG_b(BOLwe#78h22X+ABERf|F2C8}>ka;z!5s$w!Qib1e++hu{7uy^ z|H}qHZty{apEEcDyF~v53tj(<4Sw9Bzq;1tM`1^ZTk2f=4THB_?&7OpC+Pm7 z!T)UVgezS4$*==-=UMGc&z~9mhQX^)ujxK%k?a1F!IKT1iF!@|EZ-ee#GD{2A_<2PWPt_ z-eB+>2LHm~qN`ng9qKLpZ#DRCgL!s7)Bn1`Z#1}g4eBlZ^GtoZf6L%zgD*rqrTaq$ zFE{ulga6dv3CmpmMAS?Azuw^020w4`L4yw)yd3qA{wFPW`QI^kiNW)$UH44}Z!vhk z!OlY0y`<6QUv2Qc20vl&+XnyE;Nojs|Fcog7=MSspEG#3!DCU6=>FWbuK$}1e#79e z7+iY2>pma#jQ$rG{CR_$4OVroJKtU4K;D%GSAW>WD-CWm_&$Tz8~l5N8*Vau)KkXS zZ17hM?lt&;!TkomAN7>}XWZ=a_Zi$_@OsoUx|iJIx_`^yy9}OydPMi{8+^CHZy0>U z;L@nezZms~{`rmu=J!s6cNqM-!TSxq74?e#)e6`D{RS^E_&Wx77(5pBivG76JjdW( zgFkL?Y0M4pUk!fF;9Ar}9p6gVJ!S9$gLfF*Verca^Ia3n&-+jh$vjngIA!Q(tn@9dkij!yZm1nJjvh~>LvXzF!-wmHyHeD zgReJuDe58p?-Kt8zi99|sAqJ4+u&;qp18`5|4DAv6K)durjD=eRXF!=hUiwjWC>3@^K7aP3Q;1vcxW$--)^PMdW z?|TL}bh>!_3KO2eOGz8{D9O9t~jImAyJ%=hIG|HxpzH;4FF2J`(n#D6fD@6jPX6?TsD zT@T*q1bhM1mTk}nEuJ1ftwdG`L;Xxn~GgG&hL>g znEr$KwmbQ~hR^vx@&yaO1>x`_X8g80`9;%Qw-DUP7mTku{>gN}MNGc!PQJ`Ha{iHg z!Sv7cSK{VHOup?-e)9#c+gpf-e8KcjeuQ6e@q>KZoqUiWqy|Pwd4yH zKGVR9nCZ9O$(Q+D&hL^hnEuK2m!IuUe#3j+us=or78brge(_It@@4**^U3537XBjm z<3-H$+wSDcd^6{t$rnujjC%oYUc}_v?&J@c^mD$Ne8Kb|#JAnam-%eYZ<8-r_>VJk zT*Qpub|+uvzd0XHzF_(fir;o8U*^j>e@?z&;TJJ-T*Qpub|+uv*E!#=(|@7sSNJnD zJHr?MbSHm>@z42r@&)JO+wSDc{5|LM$rmhqfBJ2A@_S7Doc||Zu<-r*XSjPXb zAYZWX{q^5=CtubRxV}KXVBtUHlb`KQzN|lRJ%W6}!uQMHb|+ufE4Y3^zF^_|^KZM8 zFY6mz?;u~W@cr_)-F5z9py-$DBRc;E3%|;rf6JYGSwG==3i*PC-{Iri?&QmQ3)f%B z7c6{#{I)y!vOdH08uA4T-=BZmo&0B~yZJu}-^mv&{K>xb+wSDcdJxx#$QLa9yL^1x zoqW!t((ebuE?=f`wn{i{Ex9U)HO*enq}u;iI_qMZDDKPW~a2 zey(?sFPQ$BcE9{>ck*RDjO%0M3l_dV|F%2%vVO+(H1Y-K;@j@z%X%Bv-^dp%e1H0F zck*R@j_Y;g3l@G#OD|)8ZFllzJ&)^q!sui7QR3KwmbPfm$>=o`YQQ?h3}WY?M}X|zj8g6 ze8IxclAno>?&QmQE!S_!7cBf*_~S*q)aOpVtnYHYmwdtW&$#{lH`|?jSr6v=F!_Ro zUyU$$5i@?wPQI)+bN!io!NT{q-?lsXvOdlAYVrl=;@j@z z%X&7~x5*bQe82wM?&Qn*H`l|-7c6|g{B3vgWxbs1=j00(zTbY>?&Qn*I@jCD7cBfO zC<9)^OMUJ-{iq;x6^?&jO z3x7Al;6=>z+wMC3<*pm|3+VJ4EPTKGDlK>NWj_J;7mzPl`2O_U?&Qn<1MWv4U$F42 znRr~pOuy|;{_`e1+`mA+VEU*0dT{e1Cf{}^zoWu+a|&F38pA*N{`zCPlP~)txL<FX7wnaIVB!1aZ@ZH( z`%S)J_=1J+*I(P6eA%CJ(C`Hd-=BWloqXBP!u>6jpJ3tp({Hu~=L(=Qlb zHQz5k+ns#b-^2Yr$QUw*bb`LZ8~`-8|AEPQ|aW4n`II@irxPl3x9EPRMZU&Ko- z|HS0W{v+;3V*G;X&b<5WkL^yr>{sIcCGrIezZPNeB4+%yJNe%?>HiB;{(^D9UihRNJ&-_1un-?+pwmbQ<|BCyu$QMli$S=6~!T4==@@0P)_j{2qnEn~Rzx-@>@?}35_lJ=$SokS~!Hbyj z+wSDc{xR++BVRE6Gk$by^hHd*?M}YzH{<>@@&(gB`Tq3V?&Qn?&QmUJMO9^gL@2zgVZ=VB!1qSN0#%oqXAU%>BsZ3l=_p z))(DwnEd2F8zU@xF?6>CrYw`sPe~FK8yOS^bv$Mz-b0=T+mvg^4`GV=6dA|!c zFJkg-ckH-*zWo_WN`HKly^`pYikNMNGc!PQE-J zz~=?X7fk=;`t7gnPW~nsNc!dT1>_4BepdTo{L`I$dH#UUBakmx_ z$QLYpzx-`?^5yvkKJP%jVBvQmoxF&b`rOHv=OI#tFIf2g_-%Lc<@pIdPr>*F3%{C? z<05AKwmbQU>s>cKe?h)r`e*t1!DIbd z)Z}!T75A9X`J8PQE;^$mbWy7c6|Hffw;opF8>Td?TNCBwsMT>iGTk z!*(ZMo`>Y~k>m>&zF&T}JNfebB%h}wU$F4~`fIzBf9M)FZ~ubt%5A!Z&I@lu~V z`SQFbpWh^3F#S_@e*LlC$(QFl`Mf9jf`#9RFnAF&e%qb=+Us1mHhd>vFuv;e{pq*e z$(QFz`Ftt)f`wni$Z-)fe%qaVdH$5oqmnO}{)6&wyOS@^tMd6(@&yZjJtN0O%=m40 z^5ywfKJQAtVESkL&A53HlW)6|FVDmB`B?G=(?9wC{M+v2%k#4<4PUVE83r$6#&5fm zFVEZFXZV7J@3)_}JNdgl?1sG{Apax82E?=b!mJH2H$*pXpzLn-?+pwmbQE z-Qv3O`DyY6(?9us`)RwAFV9y`z&M(G!NO-4yoedU?M}WtkIm<^$rnuj$Q zUw*bb`7B_5@OgCd1q5!uQ(`+nxLl!{_tv$QKmE2l`CAR2 z&&QK5SonVXX}go(YxsPgo_xW=?^5nXywvATzC3Tw=kLiEO#e)K4{lz>Go=ljVQEc~qUGydsLzC8cW^8m;fEc~qU^YP`p0G=N}zF^^J zm7k9<=L@`S_=1J+uRpds(=X={@O%QsFE|(9b|+uXFW`9w#lDZ=1I%=m40^5y)CuNuDKTzuP|d^s`8g@1%!aPfoj+wSDc`6WEhgnYsD&-5?C&5M|P+nszl?}X={kT012$@kko z+nszlABE?okS|#Hi%_n-h#9}_PQIL{!t+(g7fk<*zY;euV)AWw^5y&$p2tGIVEQM2 z5^i3^ZeGOX+wSDc`7S)~g?z#MN7RUm{%v>i<-8f5KSRD?;rsh9wmbPd+T679yc+Ta z=i=M$|=;TJ&%co8r4xsxyF{qX!B@&(g> zkp9{39^g!)%(A|Sm-^hv?=$i9yd&}j(?8{x((H`WUO7c6|{ffw;opF8<-J`>MtB4055lj|=(+nszl&xz+dkuNwG-*zWo z&VO2M_=1JM25I0$%=FvtbaeDtsfr~pT zTz5VnLU(!ogU?$L%kx%TeJVyNgrHdgY_j<&| zEOvc;&xiYcI0Qq2$kYDM^Wg8oeLLa`)hoe5c%Ef8<-r;la_Te2q{7oPJz7HSt;otc1n3HsV((#||!xy6+`quBPzM~` zA>3iyzr=69!rhPi72L1lehv3nxE;pl>$rc7`!~49;kO9xH}IWxuMpo)#(fIziMUV0 zeLC(la2Me|6ZhG;&&7Qn?#Z}EnuntZpZPe3``zZH0P&8&J<>dlhu@QMPrxntI~Ct^ zL)NcwfhL0s>6G&&vvHxVKJ?>|2lD<=bu3Z(BVfuW8M{DfPeNO{tmIpnSAF z%bN1cD||g~-yNcT84YKC`X$6xe0T}5?w6alF6Vx~GT#rr*!P0)(dO8^)j8VK5^GzH zcj4kSx#^esjx05`*)lV)s~kdTmEN~Pk5tx)^_INsmq(wF60cv9;A?Ju@40X3%*0tA z^d9-Tx@G*?|BCiTyybfN+-Sq%Azmh5+nE(0JFs3Gt-G`}6`53cq*abL>o&Ewb|mAS zo$+S8&N`9QsT{3B%!%Ul(;anux3;a>I!wHjwK={jwzee|O|;>q)v4I(y5$RzPrT#W z|Kjq|#$R6PjpV-}+m@)0H{0%;!9ArBjkm;GPehSWJD044hI({?3KUc>R^=TkQC1I- zdbT7{jyUjk=i`mT8;*zV&Ni6AB?gIY?QPLiGO;cZYl$XS)ib*PAqqcdRU+A$%As+y z@rvt~#LA|Qj%cFOeI0$Q4X>hK7i(FIH=sA?ppDuxmE(=Z$vCQZE8bFW1@19>BO4CO ztJ1AdmMyP{dO{j)edUY2`6hNNY)^rYHe3$d+!wjGBv!>!iPpFkLql!n2}wL_PAA@L z+|rK5ucI9=UXLfe(OA`J^d$+CmX4(<)?vkPVsZhSoetmEu-Xv}Wd}x`In!RGjT125 z6m4bE)&{SYs0z?ao!;fC3KUFgO|t!t=*n1gG?q-pHbmRvcSKv_ZL3pjGNIdnvn4bY zG$>$K5~ge7OGs;Mebgs7J7mtEnULE%;>lR5J;~H$l2LzUD?1MBYCEvA-Rg(_@!ICO zoiGg^yWmN%e${z!Gvv*B#^MiIaHCd_+6vQKkyn_H)*j4{((JOLX2kC82#v@VmX|fh z1GIzY@I)FFzAQb5QE|)Z-HL`A;Ca5{ynM$^Ah`KWnwl>r)^G-Vq z5qWk%O)WVr_i=?{7wvH*hkDr(kJ-IDkDVMU4dBMw+S*g-gg$q^5L2wmShe? zq+6hbZCr*(5>ph|={Cl92x=7?i&#@4wc+>+gSBR5tdl~3f~;*yMPnHMcsd~s_7qk* z{HNNZvF2t@PGsV%hZq_fqiAxiDrt2~5_Q?@Uv(zr;WIcJowamvp^ubGtX|u`R*%?H zu|%7n%HNZR9Oc~LDdV8on;?^XLb`hpd)l1k=9LNa?BLk!x&Fh8fl(J*?+Lie2z>EJApbx9?Uew2%E7SS#Sf%*~pxL9AHFJ)86LR z!p3B*tuxk?O0>6S+3FG6lN`YXOzjRU+Z;h6 zpOvfGt%d#i&UzMk2w4xSPnm_2@(Nq!JT@+;C)++`JR!N|-Za&>j-Zf5mqt(rYbvr#LvYyz zniZ=u)V3|J3|?75>y;jEq63CrtvzSWl?IP)L2dC4 z*1N!NM|SjexvIITmAPjBvO`K|WXP`6h&6b~{!k^7wYH55hgkVZd<2V?MvXC>+SRC1h2!g+;vLrfakf5Fo98Cu>*7faMG}~?=X`8^1A4d6)C5YPu{^r0F$#OTe0~%w zuvUW;%=1{3<>em39?YoZFep=5J&i~u+xm=~PS`r6N18rqF>8!LTu1sLy<&M^7M{7H>7I||F@PgC8 zkWf5pq2p}i&1v_ZEVIqF&^^QGICO13N*aUiO!B#s%Z_DPCGV4O`Xr=Nw-BgQh*V?HV`fC?H%=6&nYg{68)=L zOCBn%^OznxtrgKmCLRW&5uMV7p0pyiwQYAK(P772ZaUe%l%h8bT}ZaH$C`D@JxOHh z0?EP6o_JaL0{n2cSS{zu8ru_5cOuQLFi_vD@N$%gcyT zqbp@PpWd`3hC_6An z*aS9W2_sM5jF9OQvMx*1N>5}}(R%p2x}!5!#jE3RS%>B`73@U>8%`7u+~&vIVk@x* zg1sHr!@5^s*$&c;C*y5RahQDC@GN`omTuh~827btqYv8TYm*y9(ff`Np<6h+yh8VO- zFe4r03^|w>Vr~mV@T~2zfpH@1p5a;6$|tK=(B8(8hGx|&4m*QG%Q@`KN?v+S#;zar z=+bA6IvJ*J8{N?qNBpbT#*)@HGFts1WSG5r=h}Ae%khPo!JWF(?roxniUaKnOfdG2 z!3JAK!XD!c6W{S?g3k_eyX+9Fcqcs0oYUwhJSIMqo~ zPG`<8vtHv1Y*o?R>8aD>?;3lGfW7tLzND5ALN*8Q^zhhOuIPbfIgP+LN{JW{71RO)YaLor07W=8=8h zVQLw>x!#P9CMvH$VE?%*!`opSCLK)asPcG1%;)H$eiv4BbP;;Q>@{$IEb-b6yU(VM zCJ&zAxWVMVPEi8(9-02%Xfk52sd*-{tYr<%D4C5*Lz!(_r{K8?lrW|zm+6UPv^Z8< z5ojr~h|lLF0>^O2!_FQf!M=F{7+%?i>SST6&xpnB=fZT0Z6rN|*wJpzWijY!Jx(94 zZp+%71WRmMCm95cHm2b1H}5*sAvS-Hdh7FughG8BX82_Wv7?n3lfj+Boom{Ysep$Z zPK*LT&G-m{8;MVvc89*aylD+~Kctc|uEyh$BRr^UcL?jSA(s!}c{sWDk@1P82K4Ma z8_BX_nCmKK#wye;tLbA(={P)jjO z=!{&V_o}^pbBM!RqPgZ584mg_l8bbA{g1eapyimgh@gL!MFgEHJhf?L zYf|;cST4vUM%#ewwHIBuoHOzy5E@UxRWXStW??{w$CVqTBV7t8R5NYtsU^PD*zIyX zl9iPt)XoOz33|QmHcL+@Klh3P@Aq+G$C6QxQ0rc~^@BY1yMD z&GyaE4>5#;0+i>T_m>gmag5=pQXUl;LB=cnqqsR3#Z`GaPPxawh|n8_wQf-{+7Ym4 zt=|j_P0l=>d2~lAxG-zkSf6jZhZNvDP%~MUx%-6PHY!((h9G3M-AY`#Ct<9Ve{upW zkG;y&x=PNRcpQUVBHrp--l^?mKHMkawN|nMv#c;wv`~r8rnLSJ(7Tud(|#5h)l+^L&%Ip-fcf=_$`j3?cff( zlhD%(8*MBsRrd3;pAz;2kIuGCY4hobp*QET(z>mDhBoTmdGEG>&~MZ!x4NO8ocVXs zwg&H{m1G30kx=hPD}ERsIhG>V<~I}b2-j06`}BeeLPy!=$T>H!n5Xo7n_OFSZ*mne zj5fc+soT2_AEton{KtJr^>~J!S;He3%bepQnIU=CVsJ~|6~j=2x6ziP-P#17FOxl9 z^*`k9KapnCm555U3gd2^-V*KXvUJ<|Dsv7KTSj`fjVeR094H(wrArx#r z>5SjLmU}%ioch3%$gm-i7QuIJj-G$hv*ZojnS}W0^@BycD&*#ibQ*7 zjvQC6O0;A@;3)+WD2m`b%v}{rwB$TaW!Q97VH&EFk7{PhsP0xR&a4dIk!ZHhlJJ)K z95=)163mh9Ih{}kYib5{wW-A}J+I*i%reT!S_9>ge4cV__3HGf0t}uub!Qec8sHbm z3CM^&kTMxD^O+;+AdFC6R`0+Tot}C^LpS0>tNvJNvZQdlX&S0K<7)_xPgoq{=}kU% z6U8|o4u7&FW~ua0De~%Zx_@=NQFwy!kUd>e*yUj#p4ZjMlE1f>=NyNF)}Tkfw&@t1 zyhqoS8)0Fhhn4GC6tTUdG8j~XQT7iOvO5jKw!(9g&FJ-5O|V;Uvzp*wZzd0(ekgKY9={zu zR~$Qt-Pu;q?h*I$2$hdCJKml%8N=rS4PxAG-0hc>2WA*k;J+Fs;3wp!xuanU@{j-0Wz} z=T>F=3&=$IyzKBQ$||$C6&2Z%tC*b~Z^fMKG*`^YmO;gw?DSPs1;ksGEvxL5Wal9} z^zv-l>}+0TK%r(6=V$vWFAIpWqC88G<+Cf*tZO>)B;Tyg*h(DEF{>llervob)j8|7 z_=eV4n|!p!nr5|f-zJ6zvy^u0n2Dnp6$puS=O`qnuKymyt%5mnVI|j&n7&Bx4rDat4QSCGe!6f?-2@rL51*oqmX{5P#o@f1Eapq zRn7y|#UVAp;9)+lecpI*B=(u{^>Ov3pZs)3_?x$te*S?+mrq{Z8{7Yft3L5`?1F1Q za^`hk{@?dKTL03mH#pxf9`|P-*mc#+)HAoe|3A<9>?QxuKIuOifBA!_U;fAOfA!LD z4}WLHx3`RW-!+w6{_szm&VK&izjk`_b*X!QaO~=7eb-fN_~(D>5B>Th|5nhJ{CInO z=EUNMp8W0Ng_^EsMzQ6L)L;X9h`CQFk&+4Dn^R<6o{rja|&euOXcjI3j?s;i- z_5M#(U-j5OY>72~>z$Kk?_4+L1GB#zJ@mO(UwO6dN7r`_7Cd|YqR8KDob|;q+dsDU zjIVuYb<0=&=1+Hh<@)yTyt3+4{Ar`NU7Yb4CM1J$Y*Z+3qH-GloYimB;R^0Y~0;U03{$YG3n@dI6 zNiwf7y_-leM(##+_A5)p=7IKy9A@SLp{eM+hz%Ac+)=iXo~dKE=a$nkB-ykbC=c^0 zqzIyxx2)WfQAvOwN9Tdob)0qsR$O>r`I>zh+a~&wPmL({s^lBkZU@_q^BNd{#Dk_w zTyN2J^fW%eILpA1E3cx>V(35uTEZ}~sibBy5_1~YViIpDeUvr|!Nk8mM71xHt2sl@ zN4w*KYg~J%)J`i!B)BQ#4T#G@So4sZb)<1<0&9q% zEUh|;nW~Q+bv?m6>X2Wbs!qlnx2oTBFf*_ zJ0jiV0*5wNBIDHbc47w=t!<2^ovy8=uxHY&fH%gDSLi0&BoX-kPyv0!x|&zy62=kDI!>~50w@6YB# z+55foI&<;rp4uK@q@@o)biLi~3WekS1GZ6BS{hPhmM_=mq-dG8wGa=i;sbf(Ky{a2Uk2)v()ev(b}$LDM42#12LE96alew)iUzx*VP5T7^lYisR@F)%*A zE#;iwSS`Q!Jfg(m!RPC2?FzOw`hu;?+Z499@6MS*9|@@ZrOq$VI zuV{;LEqQ(u@(@}6bh_Ml*KP&iH?bY;^i8N_`u1yS^!&8f>M_<&YpWO3R8>}UEnTiP zQqM`!pi~+Bt)9r3{x2cwJ>|0<1%Y1|&Rul2dZ+%kIhW%tlb$$-Q$2egWBNbQ2mY%+ zpRX}c-?_rq9BfrBnJmA`dnAG6Cn({^%FiG2x2_0uB+yq`WhnZdmz0&S>9tD84(XXb z$u1$kF=umr`=vd{yq;cu(hU;w%d6r1?mUHCG4C(w<=5QSpoov>-&a<;Reg6#)xI)L zQ&5T3jn>y+UmpsrOl)6Y7w5NjFemnnPcJ_xCzT+czE{_9e(ycWz5Ufmz2)a`Z*LCx zTG8`K8^`DO(piI5eYdwVeJ{N#a>y{@|306VU%S5{KEIp3!}(c#@}~1N1(lE+(Zl(L zSGPOT_ixE>E5=Rw`*)i8wbg${HE=wA_rJsRP2ucZ_urhFK8bet=P(BjbKo!s4s+lz z2M%-K|1by0syZfTjVs^7_WOB)O9gKc+$4CX;IQB^Fh42%vJy_;CU}$JhXps6a`-S5 zNbxt7G5(a`=LNqbxUihV7r@M=_&Wr@D)|3CxVM+bAG2_J%Zvd6?~K6HG=boa`@eX*9qP(_zA(!2p)%JCCYEg z>74)lf|m*Yjo>YUTZeP}y@F}dP3b=n+#q<$8Jyqsg6jnTOmL&%4+O6lym%z%w@2`w z1vky%{3ed#@LhtxCpd2|htD6);S&UJ6Ex|hkj~K_{rSmv`r{IeP|4r~+f)|YE_&WuEQ}D%=oPNXvDNpc9!CM5sBzQs< z$DfIX0cwvr!IubrQ1I=7cL{!0@IJwHM{@cpSW?JAf4oode8K-K_+r8Cql7-eYXol+ z{7b=G1P`6a@wW+{EqKg1T%KR>e8JZW-XwUZ;4OmR5H#K|0gsbH_*4T3)>c$?ry1V1I%J%!U(p3C`tQt)2Ey97^M zz~LVVUMhI%37md|;1z{`s}9}+y`e8%~w2z`QQ3vLp8nc)2wa{MiVr(eYQ6~RjdkD1Q-tr0w5aQ>$_ z{uc$;3I3Dd4T8`4n9%cSj(@Y@Cc#e&-YR(NsT}_e!8Zt=>f`j!39b}eJcHx63tlSt zF2Q#Q-X{22!TSV{FXHr*mT~@{61+|Dy@Hz{5`=N1-~u0XgTLsTE^*@2<{ZzB={-8y9E!29Z2Qnt>E;Z7ThlQKEWFW zzbUw~iQ^v!JCD+@7raLBZ9xuyQ1DZNUl&~Q84jNTyN=Q?5qyE*HG;1c{Jh}pfe;Hw315&R>;&j=n5JCEquBY2VEHw51xcy=?F_d~%WS{RQy zjnmf(zD4i`!7mAZQ1Har9RC%;mk6HH%K7aSTq*dkf_DinJ)P6<7krK2{5DSiGr`jZ zFF1qak7?)ds|C*&{9VDz1n(Anm*At$2>!I-{1B(V zQSem3zZAS#@QHId{XW4L2p-YF>3<|REI4!)$KNe@#yrM(ogDvjf~T%zd~_v;Hw*rX z;JXFy6YT2Z_!m`i{Plv%&t|+$Fxf#QKMxB2x8U7^&pL<0$E@P~t`$6A@b3kO1&^4| z@$V8`DR|;)NiVok@H2wf37%Lj^a=i);L6K5{VxPJ3!dQR_!|YEEx7b@j=xE8(G`qe z6&w~^Uc>1(2qrs+`0Gg{y@J;XUN86! z!M_q*cr<b1|o{5PX{8I>BoNZxH+|!Mg;1DEK|W)v(J*UgzAx`F}(37QwFzen#-n zPjmdeg3l6M_ytbiB6y5ovg0WK&4Tv{en#+UABX2{;`FlxPrZ%tJ%X1AK4KZi-+DWT zM+9&B662o<-X-`9KgT~Hc%R^=FLV5h>p6VQR~Qd%V7yQ8rvy*h%;CQlyhQL98ae(> z!G!_FyT8iupBCKob;cu?b9ne3#$OgZdkf>^R&aRxeT-KL-u^J-;Y}R=p5Rr2E4Fj^ zh@j*zc#Gf%1yB79hd(d)alr=!kH3V&r#`~@Z4f+L@cV*S3GQg-_*(_PC3to>r*CfI z@QVe%EO?#Z3t%^pd@OyGEuMaCqM1La*Qnf@{JYK1cA61UCwm#$*m^d#r^py2g_r>&O!f573l3SJ|4 z`ehux@rNA#MZr4+9}ryh6o+4SImd4o{AaDS;KPh;N;91vjc>7N|{rGDc?-2Z`VAsz${LJe( z{0hN^>ltqryh`vc!G9F|hTv~r&++q~;rxQ1V_YP7+6{~w1-~hHli(XSaQFeiM`N5L z{>=Y5=Xbr}X2Iv&#NiJLepPVOvmAfz=Q(`0;J*tV^BjjqFb-1wVZj$*+#-CNU>es{ z`v^V*;}YS0f?pI|@jT}@AL9;%Uo7}h!5amih;fL*w+X&O@GF7`eUZcSe!=;*3tlJq zPlC4!uD@025&Wj$3BTm@H~kNXZxvi{8{-!QUn}?n!Osb<`xU1jc00#^Q1FF<_XyrB zxZ(wl|EAzZ!9(ug^cw|VC3xbC9RKHn=L?>AC&ynWc(vftmpJ}gf|m-Oe;3DpPw>rx zC;czSe_e2;;B&sj@s|p|Pw+;;?k{t=Yd5EF6kH+rkAj;7kH9!i?K$Gt9RCc#Qv^RK zc)sAg%^d$?!C}FZe#7baTj6^c&-*IJUnlrh!Mg?jS#bUzIR4zPN&bR23f>_2kAn9I zKK1Jyzi2O~?+|>2;2#U#D)@cDBVOb9i|^+2a|C}|@Fu|{?&0tqfivEX%rzb|;V;Bi|x{=_#p{*8iX3w}=UdxFjT zIR4Z(Iew$y&4Qm6ykGDq@8|ey{><^;5xi6IIp5^)CHpx1%Yt2hWt_WJ=o9>D!A*jH zCwPnC(g!&HGlIVH8% zbNB_{|sOLm2-`a8V)Slb@3M2wo@nLBTHx-YfX{r#XJS* zM6dT54j(a@@&5=83;r$eFar_ge8$^?8wKb5oWpks9xZsU;1dN;Jel*KCAdg%t>8+* zKEX=_cL;70e4XGc1m7umqu_4~zFY8V@C3oP3a$`*zu=1nKQ4HU;9m;fB=~i~ zTLk|@@D9Plp5yvGFZg)DBR za(VwFxKi-_f|~?CCin`$R(swh_<0H6CistnpA!6c!Mg=p^0ZIzkmp6-XD~fheMSgA zR>GGF_6Xh}*s9Mfg022A3FmRBzs-~QwSq4Yyh?CT@ZEy15d4PV&kL^faDHDCyhZT$ z1%DuTm*7do9RFp(rGnoQJYR6mFSz~}3%2@WyWp`BzDe*j!8-(>F8F!D=Ly~;I3UHxm2Ha!AAohW5VB0&YOKw@Rfo$6CMozxk|3@?*y+BJn;n%-zeBGc)#F#frmq| zci+SI)Z>D$c!2SXf;X2kep~R)62|#2a{Ad{WPF_9Eq5_qC3q9&vDAN_6TELT<5OPZ z^gC~3yiV}CI~o5@a3$uEl>W5;<@g6a!ItW;!BduU`IG*@@$Z_&__Km{%Y6SW!P5nw{VK<=#4pkNO~EAhgopf*!}t7) z@hZWkf}aKT{3!ST0#hVfd#cQ0rBd%>j<#vgx^Ce}k2AhmaJ!WMs^C>ua`-8K;rMj{#v#Gm8yW8s{0!`Fs_z;5IDW;GjK3>* z{tCwL2(Derc*b8T{s^RGJWpYlt6~#lI>Gme1&hNaKA*=^T<`A)HsItp9jvZySg;uH z8k+neUpV9shC8Yos;cmAmcJRNFa6=R5WT3H=Q*pQGvJw7R8&-6wK92jT?yHB#b<{X zw(P2FgGG2%SJQ=TeGSbx;_7Qa={V~iY6-Ub!vR%XO<%|_Q}s=+3Y8rRb*Su!uLQku zu0O4CRaFa@_!cfH^7Xljo>F@W2fM-= zhZP4isBm#{LL>MB&4HFaw*+<5+In==c^Y-3Djb_bYl2i1+0{&K(1Rj8nHOQp#zvn_ zSC#vGt!=GPbitKDf3q*RyqZcw6>RC_inrx3KoVZIJQ(T-Cy}y}A|GxNsBdU*_XRun z1`B^{*cVvoZ|;P4Y)q0YyKd+4P`^VjZV9yNIk#vH>M4&74%VQN$ioVW6VS+8w7A%3 z%P1?&fHqKhYZ=?xD6338kd6AlieM{Py*v;Ow&--%HT0co>Lne4u&=od<6C=Muoc6b zR)e~}>t#|}(GnW`?ON{rKtA+wH1m$&WjcHG+*5V->?BeKf~fidUJ*#vS8N^GNdy(G zi^Iiejc`+_t;<*MZ}j;?A^&P$YoN>59B5q;Zi;cvCRh+W>4y%o-NIZDGsR9vi+`0b zj%Rwt#prXAaa(&JL`D}86QiQq+d>x7%F6a7wy|x1v{88n6o9Sw+o(-3z}Tu?6;=OYVSkn+hhrZ0*>Qm;k ze5C71SH!57D)uQ~(n3UZ5-rpZlzTurmC(`D7V4cj10=yo##3S4A=XizQc?fb;8_Q; z^b|#3wrNeiXtBrEIu%8l^2QuJs=PBT!j_FKu|A5Bz16ENu9gZk z{@ay2RGGTYEwHLR z2dyGnBM#t%He)6abU&hHqW;MW&BNFiv0h7wh^t`tia#HtNUc`W!T?UA_tu*6q2Qw%5w z`XU$~{ZdQxiwu?;(igI{R#~!^t&~d{l^y-UnckK&>?2FoRmo~eBZGFpV4KdWhJA+w z5?b2O*1lR(3U!qobv5y5g2Jq`eJwn3#&Rd5ZPX(6$?xG?HfXVXkK7r1l^a zX21~mWHVr!#M@bvbb-&>>pb|)ESybmjf^xw)I3bt%H^bQe3~|>R_X?7hj%6et^Rsk zAd4N1r5&LXRJ+OF;luU5jcqMHe?tRS!F)k1IIE>a?CJ(qw1rkzW6-QBqg{kR)e?`d zs+6vGr42Xipe-)fl~bIyQ)R275fh56%(u8ykB;%jt{&B(J<~U@nRHsi+~yT^ZOy@k z)sTwH4y?slwJ23PhLmS9C<6(gYVk}xXA<_tU`M+@+|Z=T@L{R6rER6Q8l9{xnjB-D zRq?U8t*yNpD=Uh3v}~^4%C-X>MQ>qPphbmvWq@lSZgd(DG372$)8>?nE1{#_n;Y!pM1zNMsYVltZP`lK6 zv8aMw9_>_w0?V=Y+~8NehkMKd)T)|l$Pl~GVA(%*5rY)8qY#7Z=yq8JmcsyKrWLxl4l1?hCM4`q`g zHiy!+lxpW#=GCg_X^j`_b)}@8txl|GhA$zgrL&emOPmU=?4WwETaF@xIxw{r#whY7 z2w?lUp{=tuT&1zkQK}XZM>6hDON#jgRl#x~Ur1 zzD}RK-+~_ygkA+-bzC(RYbXRf??UDnbqFe(F9kLhD&tSP!rS?VagJ#;>Vv9u`3f@am6%Gk*L%zSGEm= z6v=}6f{U)>nsu)V8qDIFAADRyuS?k3xD5>)@V8Vq(3BIlNZfKj*3GMr<9hSP33>Wj zinOEdTBV)LDS+q0ivqt97cRc_eh}=rW6*Wjfxg+F%e&v4fV*CY;hP8pG1e)U@wc|N zg|Yqx-q=S=TSaER2^Pqr%>`2-99+@a z)~Otz!+v~NO&5W>nw7G;Bs2QnvrpweXsbh#cCNFvv6Hpzq>_{E4v1Bl-m)>+9#v;a zR*ieFKkQXBIZoQ>e!?t3k~rNuWogc9YCcINm?JOu20Q!>VQh9M=;}1}Ns{awOvYY$ntC^*`v0OO{RWTOH0}#VKIi(jxH?nw{>FqD;R3%Y{scM&YrE^#4@29tMo-OvM+lj zD|+~=cUDAqI%WLoJw-BI$no33&Cc7w z96O#Kv^?6b8M|QBD``&5wNTp;*2=g=VJw<%=2W+!>h)B2{FAkGNnsPIXmiB4VQ-jp z6;iTsLJG~o?oFvxt>uQ;KHI^xxlhV-$z4neYSefNu>BLw~X(wlFQW;Imk*%4yqlMMbF$ohs zdvCMaE!NIe`f!xCq$KNYEU4L3BxP?)o31356_Zs8W3jW9&cEU;BMxNY7?X8mTWyKM z82}#E{4wqrgJ|p7#zZB}<@hXaAcPqKZNaHS-*u35nAAbE0CwRQEm2MZv*P!W9Mjp1 z7i;f86qm;_MJdfjVl>+HODPSxv9M|)Y$fQiMj%UZCtuK`F*iDqu$`;2NlU9n0ZIYk zO67xJ4n)&B)}opP7~a*+Z~PFiRyJj3rO_Vr2CImEnlzR8D%%szDks?zbf!UZqN=JB z%7J&Jc_W+-;KVi-eNBO8oGDWq;1~nxV1455I94A?IpWXSCrsH~jT)zHZRNly5ZSIZ zpDlW6+_q!#YJyvkLq}&5=jtZUYGswMA=WP1>TAk+wmQey6zm~k)!PwzRBh*`>G_g8X9{uJzeV>@C-XCRh_R96xPzaZ8r3PI^|aIG=q=JG zH<@1OfJTjXb0OCgXXlxedD$zX`J`A(R&5FAG@DONg|8Yz=fd_5<=f>Xtu$*@xskZW zlutF8L(YnmP0d+0-#$+-cA@El{OdWJ{}j8LzGgvPD#`W zHY8#nra14V-YZuOg9ma4NuU5uk|Scz4TQEj_`HEZ&0 zNTO}li`tg6#zZl@qSu-v(J_>VW+3z6V$UPX+9i5-z!T9{L1#I#kz*NT8BD^Wt{54l zDNDIZPbOKf%OJh2aHo|C+1lwYbEiX8Z~2jM&7{j6R)lcFh_VB5Sx0p}>t`j4mW`24 zaVaKkRyL?$yq`v$(_&Z3$wZ1pR!qU;cc+~vFsQnHW?}0~G*P61(cy|7#~L`~ruC}i zxh0*gC1e;~L)ZI9HB9=1StsSGoJDyyMW>NgboxWu{V1gMQ}8fx`-^ouT|*I4Q`x|-eZCE3OTyR&Hjm!(NJ z&Ahc?i!K04Hq%dZw72&`Ok~v{0i&f@rt#!eZ}ZnDMVibpoaez1jOeUH^oonmt|`Y;kp=bcmatVl1BJn`z4S6NbL|z)rYJi@p#RAm!EUhiLI>I?n}W%QpdZv{c18C=i)L4#jm>uL zF;MK)2lhCfnoS*S*^!^e!4nh*7a+0!vZ;u^wPjn8qs6q?DsqDJMq*DT?UZC5M2jA@ zP)o~pb_eq4L``==4_Y4RJQC@1xJ*(f&XMB%*LxSXR7Mt-`h+dwR)zCNx{|a_Vzc#Y zq-IcuJ@^c8f{ze1vE9!lYkx;)FBofTkuCkHyiKzvH7%x)Jf=DQ%C>T3%f~LbO5sDpwgsb+oU;JEB%);vKT7 z!zB1_V?VSt99rG5vOY$EeVjlaXs3%4;Xwv(7*HRJn2b~^X_h#G!)YeA)o9U6ZsDL8 z=Lhj0t%_Cz+d7n^VpZIH#W5SllMJ>c2xpgcjN{^>BRq;0TeiH}ze00#7ZymgS?t;l z8k5wxba}8@I~;3I?aT`2I+QQ>2b+`L^V%yN6}aJ|gPdMtZB+FceI+VZ;jUn#e*2}p z&C9sLa8`pWKUy$JwaYpn4w^d(Xq;Cd~F(=Z~=LXemEpK_5Dz)KD66P z&7}S8b|dwJ_+FSGgS|FtS*Q_BptY!NXo&H|Ihv@&xQ_4f1TMveM7U2I7XfHl2W`&4 zafwO-ZAr=Ky%rES+pTSS!_Ml2L&9=@gMQg7S)gSNM4!5r9xIdNl7*M$wC>d$;Ej0c zq0xwCsfvm6DtSL)c3Ea2HDI9U8JN9H4DXj9ujHt~@%}t%F}`4Datz-)8CRCXM5c@jw_- z*chg4u>z6(IoE!pOPf7pNLSKb?7BV?*WU+gGa$y}!_W$G#Gm8FJNkulvuWb04Tl+& zTof%ixp-ndqu1N0GbmE4tlb$%?-Tvq`I4?f_jf^w-V8P)eUbeJsDUp%>2}7z7j2WM z0j@Z?$)t1iIRiP>r#{>}wfQOO?5N*--_A>CK$6~dk{rEVggxIn81wpUu)mv{>YmQY z>#LTZnXqq(dAxnUtiQQglHpnP zxpaf1b)%UWp8ZWz%B{VAFD%9WMqk@Ai58$X)iuC?nwVLh5JT6+O`iJX}4KC{awM#Z>oT) zM^?3c{~-Q=Lcg&fx)3`+V^{PVhJlr%G_TSapi1^OL&?tYh%J^xnW*gq+cudGiNV#I z0RS1zuHqS3Trw&TSoh#dFKim3|9Nd!NwGGjlQpxT2prDoz)-Qym-PM_pA3|R#(F-z z8!IT|5C6=y4c`ez#4?~tmm^*q(OH(X_YJgg90F@mueWX~Bo~#Wb|bRV`Ijvq}-<=a!Y*jLzI+9bwHts(KZCWigOnf*NYi!jJRu*F@uueD|vR z=GlcZ?b^(?d}OnosLqKr^tE`kXryc^Fv>Ea=&^4m)B>Ew>pN@u&yu2M#h=|Ybzo=z zG^vA;liYUepCVID?=n%?{nl`fdRsmQH_*&*P~QVxaO=Xo-IbQXfRkv(=nJtKUa;10<@V;NHgK$^#YW}Y<^08xIB&H9 z+nwp14B~Z~mk$2&c>BhJ-n3WgedtrF~?cIpT6A$C#n>tp_Ep}ar06`m*vK|UoO)o+_APtZNU@qb z=Fg0+Xbhs;+3zreRI-0xne~|=>pnKD7kkPYgY=<3y7x?7Ktz{*Sv{#QjYXd(SV3K- zezmU)N9*b9eXyRJaj}rrV_MXoZh*zzb5zcEF=|N`H7u&p?<_3eOau%17Af{UAH;l`vm#)5|aYA=ja#pTdSjku}B-_U?>?nQ5UQ(v3bSd7CE zK3sTU-OUHXTWPZxi>n)i>iRnV>>z&ZU*Cf`TA%gPcZ8_EsA9r5`}!hBbn00(R8w1M zAeu{?miE?MX_=vE${%`%HJ7wW3>oWAw%3N2Z}14F&R^pYBHkP{!mO&<5^#A zsz!Bf9|Y)=_UzrIJ}c`g&2tES5`GNV%Y$L`=Wf=_{Z$8WX7{q zL|Ss2X5F-LB8gwNl$uIx<1CrXicW9&$5U$A6XB2_8Vh4-S5kvJ^;N%VlGpn^zgBx> z*Avn;xd;4qLjC49(h1g5i{rqOCi85%sHN{KpqVX-q)B9kiy~>}ntV|t=?X@%{+;bA zUchLu7BIRT7BI5xa4FXwvXWxmsH&27?pwFWYIP#brpan`BHg^x86^7BrP3QCq=W=* znOs@wozr=GuWnEEdHQF1pC&u|WqRLL4tcC1LjAEH(cL%esPHk&*q(yXxu;_K?nR(1*M^$pixh(Tb=06vmIaPMV zZT==@jC?twOnqr0X{?xsAKjX0i)P!f#H^$P-|-1Fg4vy|VOvDo_eip=xF)7H*OcVV zo0d05cGUE8NqwUKpQGo=K$LyRDxJ|9N&1>f*P2x=_Dj?47FhauX0}w4e!dy5mZYC? z8Ve=~-9F`tNo7axOD5@)m)c_^+g7q^khqq&ZBb)*Nu0#iRd(3Zl+#D4eA?%ksyT}K zKy5L7tP!8ov3+n617XH#XlGZx%0lPmt?!|0tL-WFx6|i1d8hSdFKTlGGS}J}gJwnPjCDNzkXqhm8_v&eR&b)cPz^aBoJHA`z zuWt@`T=8$p6W+{9c;iV-R#ub{Yi44?S&6YcMHLAtJ;jLycuI;B2e^Hd~?hR3P(W;t-lfxhBWhjZ@YeRUle+Un&qKp%0mOiaI^z9qst4XLvbHNU*PY8F9x`g7=|@ zCVU#Z+27G*eKyWheo0G1OS|uEd>*-K6&%hxQiUi#H%|q=t{HAweRgMSLm2Lc9lpiI zY5~tPOTH$mzA-7E7L9V%wzQt+R)7)?&n)XJr7B-8!#UeD9d=c=#U7nnVw(CCs&mHa zo4%5FG(TVe5?vgZaldi7xY)+!Xfgf6j}r2@yCkrBrN7yCHhqD#Ca{{8(j|B6_V%EC zZzV|kU%|Q>Px<-tkf6TJA8M@iug38MlIY@OnFjf5%f+SE`bj%|7v58jucWv6sFvs# zDuZ&OD)!Czej_YJz7}n>EZY2`6)S1&<$^#%xGm%pzSq^Mu2xc{N4wA|p7O6KUEbNs zeUP3?RBtRtR_N~3ow>T|MN2!qz-39q0QIJQHP~TwdU~_GC9K2dK&uYJZKPJL)Zw;E zfRKK1G(@wEYUNut|b%?6IgFQ3c*4f@32r)pBL8u^#A#}~etJVg8SO`;#D*P@Q zO?wxuK=d7{Im(Xd#1yP6R$K+;t(B(|&05$VXjM8;qe6e#Ae8Cvy5!vg%L$84%C)Tw zz$><`U2TBP^v#2=?Fcr^ZC+8=)*NhDT~%c}V?py_hkK+T_qd8fU4w-frS1M;2=_r@ zO%d-aXn`?q9vSCBkiN1aze|5(V~Bjx;}4F|oEn!=E#V79tvcG*<_HX>!fG;9O(x+NZR4U=@~zTm8*&?d>Oyi6HcUhW0&; ztTl+xr>%TKDlPTY$BtI+#~{(#*pGFW4Ew9@oSjy8>MW?fT&>pE>ht0B{@SagV-I|W zQ~E)F^a20k#Lr>dbx^uPL^7r7DepzArdvR2mD-S=MoqJ@Sg(-Nm%Vk0bn|72(?*@> zsnj$?FWqr8SyPnu(h}+BpSmTw(rbw{3yZacILh|c66xma&=OLDV@vdQ*$-J;RV6b! z0?n8Q_}W@&?>FoZwgy6YqTvPe>~ILzwqe4pH9xsM;fizosErQ2OQ%($gTEzx_Z(Ta zWSk)xv-ZB9)c(*ef~}gF@U78mSiYcOrTR#%*q@?Hd#hBIG&r(hro{&Py@vxt0!;|H zh4tnw_j%C{xDQw3M`im$>j?M2awREAeI|&`tvd2NOVOi+f`i(5s6Yq74RSLT`*4Oc zlfFpV^*28pTQ3N43W_i(Dl-=*qBU9GeaxEtoikvAwQ7_>r%&+Qg)c_*vw}2jXz%Q3 z!dIOeF2OP>F1%>>hnq+pK^x&~URsm(d)fFbMpOep|Et5_Hh-LIucD)BB{i87DGrNg zsppYF<&2v+i?r(Ilp$Q1Vr2Tm1pHg~&c8pRze0)QsvI`r z%Q;`lwcz33!yGuwfx{d)%z?ukILv{=95~E@!yGuwfx{d)%z?ukILv|n3=Z5m(dEi> z6=RB@lauq$VMFOB2c+X)&WyS3?QmA}E9c%BOUY03RBU(7n1?ONKx?>TMrB}Spt%hW zd^75r{o&m>_ZJ zjHSlghPIY=cn)^p{v2`~=crtoZ)GshMMJy>5$<-mtm`FsbJyQW1r9>#gqH_bP#Rw+ zB4I<3g8(80 zF0@p~Sfz%j*!V&mBEVo#{!p!W9_n&6`on(WP#cATU{J;Jh!zHlc92?Oagp8wTkoYx zU@u*=QBrJ0BUD}*MO1sv0+m<1kf;`vxC9ZkJ&X!~Cd!tQ>KKr|k|m5(!5Sv=pb?lY z^n_f%W9*(%9|0Jqs>uP=E)6v7aHIzHtZLSUQY;D@x?=Asa))Gz*YNu9h*HAQ;vmQ6 zAW0Yf9uP1pi0mQ4R4RS(P2v!f+vM3QbGXZ;qVj9&k(&w!)|8mBXmX6`v#KU)e@V1P zRFbMEJy>tasB4UUtq7SQVGCS1_^E*&wO7PdWa@9WxW|BE*j}ru&|AGuEB*M!U57L= zwHXfbP#j$J5`c0E2U<>TXm6*<0Paaw-2%PJ7g*_U?!?6*ji3nP+REM0e%&^LVx2qo z5deNo!jC72zUl_*ya{@IOPh3v&epDwznu?ra6C~0*zl7u>R=pnNlR4KfX+ZGo&EO( zr7K1IAsPBS7vNMb*WlbSGt^YUmFG47>dG-E6y%>}9`E*=1zywenlASb%;5$3mzm?- z5%XC0TDS49t9r~K#@d_+o+9Sp=#zmbFTJB*j(R{vU5BU#R8;H9FxDX|-dVrqF>d1; zr23e<+brld{&`imnd3ID!y6-a{xB-DTjiSLe%v(j|KLX2Zb@s!bQ>RDl|P%(;Gvt- zy7MdYa!i-;w&^uLUXUL)jdeif-2}Fp#$&mKm@9z=VGpyw*i@Kf&Me5EZ5Fw`c~p7h zy>K_x|8iCT;D#Ba2~4ui0L-|LiNWJ9=hq*G_3mHj^>mqqyD$&bek25 z8`n@Bjb~SNo1+ViVLj&X{4-6rJ7Vlc`NtSrkc9#f({vm6QSm$7J;?R5ZsV7z8CvMu zIbOx!f10^da;zd$rt2;vz8QnT%j0U?#?y)ukAf3VD^6HXhVdu}#yjg5j5Btir~?Zl{G>1XX#(B-5?srkleW3{PfA`RclE3j@v)o-{&IQko_L^h82&*wq02=BwC%M-m zk=LBazwSrP!8N8?ql&w;L$P(Qc@cWbWf3ax;j6pNWd+@!<>-i6N-SUIj^vpXG``!M zMK3NyWWeTbv%H{N_hrxxU&4xW4SYAEar$i*nAQPq5OSi~G!@UA(M=!xKGEh@0( z(umvm^)QIQH|Xi*VP13gHRhRA0e7`Iuf`l*Z4Rw9$8ws<5p#t5U2`yy>0X=X26gv$ z^q3>4%%kyg3>c|e)ool0eqBP{!H4%!AG5$vHG0DpF;Acx3`Y%+=QI@qy=8Ji{sZPo zcnMOE>jA5gFR{-=p)Lav?5U{EZsYb)w|PDoK)v+~NI0$_VjhV^CwR?aUgp>xXr`gm zc%zZ`NIXZ}Yikgt3~ezBzbC2|I@7(*oJR-|sLXY$g1d95g72AQ5Q56pQjvdzbeVWJ z1lgIW2VSj*q)lR>h5SMNamlYB=HP-yDH-$%YK2r1u84mf;Z~DTHZ`%jJUS#|Ruczj zBEKSU-nkV1#m;WCuwb2PVI`Mep{4{c-NyGW?KY1!evTF#83BMO>YzXYBvCHa32QdLM_1zv81r_cze zis%uY4?^&$Q9!iu8#MRvXcW|&`_e|RZE!*Elu>43E!r0q0J}*$aOeB^YOV9-Qf}Xb z+L;2;Ed8i>8KEn-e^8?TRmEVAAh++*C)29Ey;uSTHi5ZJ*HY4XK9}OesLGZx;v9(}26rmEn5h83RjdkxRRq*na zk*NAo>2Ju5m^By_D#6lfuURMRo>ST`Y^@jg2I0w}SOc=n(t6y%?Q4jVCtc#VG|1Jk%B7wwbd zuEXPHcybxHUfpAUl5D_>AtWyRyPzO<`Y6+jYJalZyqNX$BT`690 z{0$w^KGuyTM!a!p#5|%PzYAlX7gecI3jH)MsR@j;h1A>g7E(lXoN3f@#fbNDC6kpf z7L=gFsvA_0zf!g3snngS(O0_j>L}S*aKS@?RY!JU7a%KkjcWd-6*rw(%jLYMRq*)-M|-AwcdJi`ch zz&sVfn=z1qp6@W1gQxN zX9InAB)ulK6nKsAk_BZv>mrT#sA;^DhkP*=fZY&DBqZ@vOzt-4)8JGMO+yj` zb8a>&5HZj4nx~Q6bIFTgOY$H`ZKQ_#_n-`{;a+k7=Bp#-$rxMA5|9Uh9nlTVQfrF6ex>u`8cunmy*c9&?bgSWxgk@_N#@sMw|qgAHoTnE<9?=vMY7o9SPI;cPdz zjIM5TEY*w}VJftmD9IO-*j!LK#u=<}kN^{JWfjnPIim)B&}&xEAa48{HWMai>oEW8 zVYBwR92Su-a|U85RYA-J#zKODS0`qWD1Y%>T*F<`msqSqNIU*6fS<)in6lx2@8GE#tw3>-t*!?ba^VN_9US?}Ax- zb?4(EH8_WzulBTqYFiN-z4rZV+QZg%k+D(68?@HOsBFJt$BTB?)Q&PXf%Tnk?2|=d zY*QF-6L-4R4lq%dWTzXOvnV34B7|!QtvxwxYNfS>jfw=@)F!u2b`4|9Kpx0izFLE= zUSN>Yg2S(?D3Z3ZjGga!XIEm^8d0#X4X?Q+vLTCF(>|#$*a#mxxCk&^*wVyU6!z73 zE?j*-DpQ1#w5%WpFWwDh%3FR&9dIN@y<a3Rz2{wds(a$DJl={^0L6|vB~WAsrvw#8 zb4sAZE}q!--yAvQx?lM`ZjkCb}Vy?#$YYK8=G#}HGgI`)??kq_ubed z`Ppjx?;))49J3CKG1w>?Yi!3_#kpAAI3Mv#yvC35a;WhLUN+(7g;;O+5#AhSbmPq+ zcdfhIcnbMVcN>o(moogr3ggIb+l8$~#(Z!*aOsdsMKnAh&e1S+Ld|v9`uM zqDHOF40Y$u9!sf>hgM?+*7zy%IVNI`jhIFRuOis-F`mIY;sTb-u=jXj#9WP~ZR{Zy z(xNu48I3_8cAP=c_mBbXR{quN7YtGolGfy(`4ok*Vu-o_* z7R*NDABE&RibX@P=tWTV&DFW3IrPMfaQ9)+Fb6B^I~2FJgC)n%N-sA3P?quIW?G3f zx=|*!x3NmZJ6eVKrCpyPwAj5?t!Ba-VO#`l{jNE+hS!NB=4{Z6og7NL&OE6GYj~(O z?eLh0jU6Lw1;Kfs8N@z~0&>=>7W!5@)}Lvg`qSV6mc8D6{B$TgHAY{;VEySvR z?({JZQZi0S$xTX1dJsPWaepW7m3Ufw3z$ zKa6$Pb!JhuIe0Dhksi7-l2?dyuV5$JaxwwY-R60;Nl*d)Tx5BH?7;3rQ9+Nn2rp5s z37RWN0ljc`1)&AkuNx6_9_9CGwdr7BAJRv=R?AS1%e}*dV^XJD;Kv5(@Q88S6<9EK z8*gFEff}Vsj>INA z^%mn7tKg2|HnySnp8*-dW&t#gi9I6YTqwC!$ZU+;_zprzyD&p9?0>$1k+wf*$jNZqq}af3<2KaEjMFpLS!6 zZ((FZr~g$U_8*`dw*tZ+?8QQ_>J{G!Q;ulNXx+ApFA32~gLV~(wfQ&I9`|y4tW@3% z*uzpADYc66{|hl$M2t7DM?&;b>{Dac1&w(WMp5OgRN^&fdd)cy0Ejv@=7K!5iE%G< z_jqhplp`*0WkYyWp1($8jxE5Z1wzz7giSf)arpI2WDc-f0_~fTD^$eTj$I>E^(Xll zSRU>oCK^A5#F7gGjjbeE;}L`6LR<2PHU+=OqneYjp9KyPbJpe^g>vq@jK)Veq8O-% zBIi2nPr-zEz?^UmEE;TeVpxDtqq^w@UQ&zWAkRmT&NsKK4t=cqTs1~wQ|xGzLxdcM ziW5m(>WM(g?ou5O0i#GGz*7y`lTQc{@-8-WFi?lDRYZIT@z12@qV9M+I(K3IX>Q}G zu5M!os)`(Ppl;0lNOvtZFR`!Onb!dDI@JGoN=BX$Ja9Hb^d5Zv?%(A4Zks20+;vFG8`6rea8sfS<>rpGL?xtT1BuK%Q}&H!pyQPon$2i<)9E zC#L6d-^74VJ_Mw#oqY&UXw-**YV|DkLwhR@EX0l}YBUOV?nq@gpgRqQVKN*vLTc8- z^I#N4OZYgM*kipGUMcYR`6r-w79IyKlkAXtA<`IYkpQ;QM~E>6ua8$M4o2K)gdc+! z6OoZ}e4`em%6xcbPju+XTTb+lmQLoVq6jWQ=UGNQ=n`ajkr!#6pb=%Z`5EA)s_$Y@ z)&?>7++oy5Om=9b0%|Z;kaxf$Z=T{Wd~C9D%cB~=F9KTUbc|3+#!!QAp@55Flbw$@ zfIoI=&XAMo%|Eco3j=5>Ss-vs{L=W zx{idU2_b-Xh~za936H@8=(vI>@`C0^eSh$KsD8rF=!IZO~`i;N_-j$P=EoI-bycTHjxg_C9jLm3M?XvATmC{rU#TMPD}7rG%E#!w+KVm? zlMbH7iWUeQOqT@56|Z@gnmScSxcGSy)&!JJ3C*k?v=6ukp*d3xu~l9gINWgCBnrUO z!D}%&`~bRnircsz9f2f$7F-+1HJl9g{ZLT#q+RNeM+*`917b?2=|LBR*CNIoWCwA? z5YkB;A`1=az5$z?MnrTvXw5?7b*RLs#dinPBrLu^;oTf$6SMeoYLRsPRpf}Sx)8ZW zVk!YW<2H_r8BR3Z!KDw5h%oE_bb0<(jNr!qU>G9%7d}qtQG;mg+@S^=2-JyQl3kc3 zXkDsU9$B`3fYCg-V6D=_x4|N`rU0D#^{81fDJj)NL&#D`=0hUJKQOO?i|%zmG^76z za3b7}0Z+ickEtFt2)u(Z_ZaUX6n4iA5G<2Rdh0T@V|0Q6-5gcS7m*8FPu}q$4VD9X z4?2XB$Ou#P1}X?G{Q%@zjUjLyx#=?4fbYWR&A1UN6l2qSkfrF@1bL&u=~y%f>7w!Y zr8xvyQm6uE;Y1}h*1s_Zo}kL3E=JDSa}clEYr=LJ={2r{-^+00!+etA8b#mkF0u{l zAzC!(xG-W~NCuv94KjlqW3Ijx%9})kSlokIKKWSXDeZq_9w|3egIvL&9M6FEA$NPQ z;zsB_8Vb-z(1t|!G{j+>L}`LGuqxDKGr=iMW&J!gFWbxc$niW36_Y^$WPyaT0C~Zu z2<9Ss<1|!~d>tVZb&yo}Ov0(`VKe7EG}?2Qt97n#gHWvFU=4!$A)kp#j+ zD5Z-U`mUpk8l}BC4G%1cg4=)_Fk}I82>(3z-w79Qz!-WanrsxB3K|RY41Z)ObvQG{ z+u$TnTM(40x%Q&DBFIB!Fk5+6S?%>4xHXDemxjs{lnn!09bJEp7!S9gHz!)@RO(iY zw*^Ye(2zq$C+sa3_`jA!!FU4eOjud!RHMh#ZnHUJE<{^ETe2T7+^S$|g0MOLS1601~{2iTByW391vu%ecB#VC7Bf z_HhKBj7S;O4XLxO+jFQ$0mehDutHB`PJO0g4WEtx-TTlU;|g*sMk^gn6FTBIbPMcl zOee>Z!ZY4!fv(&*3c7MXI6WRcP}PO?;$*~!M;|ziSr}%5MG!L5Pag*_Bj&kk$py2x zlQ6bG*kJ=5MOG-KUE?<1LVm-ITQFZK#;lGOCFd#MT5`N4PL2aXVjf$QO(@`xp$J;5 zw0>uz@42hjDerzQ7>g*yYF-Q?(0(*oq`Xd4uhGupfv;w=u}nD?#{AP`1ysP7UXcd- zu@;$8VI-em4~EDS$e+>pJwytYz}LVU8Y!eCSe)Uxo$>6mYp86A@1HR1KCF z>`t3IZD(ZasbBmGip4qygC6cSK0g%m3hFz2vL^3jdigv?z0(WwSL0w(#E4*0f@Qgn zXsG?{W!>~(p5nfS&PY+?t|g6W96%Q=GuAhKTO97^tTs{oj#(Bo4U9hmug8$8fsi0I4&zDu=?I{S(MiM=9CAT~k72;|8h=0|mm6P!(#5)wo&y=J z252&ka1WOG!#&2`I6v@8I6q7eup~e>O*%)a*%nnI6VhrhZ^Wb%sc0Tb(oE&#O#@3e z;?Tn+GJ1}~RBROSbPH5cA*Pzt69Biv-aej&x^g5PjB`bQhGB^L$^QV3q*2#vyool% zyyP|{KqAT(xnQNK3Qct`UY-%*oS%RhsFu^J@$!=@_d7A;mcsH*pmfh-NQRo+s?Ohm zA%nVkIerg}TC581HI4TuGvg(6#&MX4pe=L6zXwAO(?&@tAMEhCRCVlypuN?75TyC7@()3CbaqnDpA01 z(E>Ps(WwM=ur$j$92&vu3a@6v7-Y4ie4KZ~?;_9j+JD{^O#ev^y9e2~?BMxxCf=fT zNbaeY5gN{_nT9n8}IPkO~VDoM+~+SNjiRzckU zA{Vv99OcB(6RutCteWalCfys7$7KJfaO!6{IxUmT@nV2MgtZ?mu z(_exgEBjQ!{S~E=n;358prJ`jlA{}apUmNE zC)6@_|C7~gWA%fRtMw98sjHk)c!d(xnpY^GvsWncar6pB0_EvOo^&v*qCE)^))uN0 z^NO{3kAibHk5R=IM7O~_33gajaN)MJzgO!OF~+$@h#_%B*+qADRe6Y_uz zB=;DlOsUJX=^mq$XUt<1)j$k5j3O`cm1jWlW9&+}4hnrYnQtisSA0vw?GjS&;OmLE zalW2-lk8?F1hG>p9-KT-MP;D|h@d-vf*7l>+xMXvA0%$%^cd!sG+qN zSrC4}9Dg>5Am@jLxa(z)8)?-ILU-h0J>~Vwah(U!z`u@`I53sQ!h9Gj{NCJroLT+D zxiq)i0G;z+aDLTsl$F6WgF{UJNz=;1)1HHV%k6)~O#Z)PZWlGn4(0?W+GVXF>W~y} zO+GTvi~V-0^^nYJ56!&N6+5mNv#VrCf~`fT78_RbAua7NUu+&@pUA;bgPq2PKaK%L zXK}EAV9!NiY|=xSezIG-~35 zmiWVnL`OP@5fLxizri3iHR_}{33&x@Kl1)m7!-$BJ;@lxP8!a+=R1vmUbSjAH zS9_?fr7cXSp+I2FgtyHCsfzmDwu-}OdE3iA%mOi`KyD7_22qfjI3%1KBnn~^JwYgb3#z!Fek*@*qrd-P6Kh4)Oi{hf17X`lRv6l zY{J*+DUYr^=_@sm=GaQjDt+#pFfl~bWD`TkvP=wlE{86_2MqBb2MqD#G`%A|#Rm-0 zg&J|kv7b*FQ$OwSSu_M&^-G3j@~QI10bu*J#CRJw`NSKUe4+^ZwZsU*70S)(46(|t z6(^H%lXV;Q1En0%g^_AD7#VCmgC>^x6cp9Al!<)`io9qFy5?4%g63Ud3|8k2;W2tF zCV6AwNJ0K~@Z^K5ig{x`F~I4; z9Lz0m#N-y9jq14IGuZOR0iFl2;cXok{31?KoD5f&LfR##2`OBAZs{OT8Dqb^BL~C_ zkkb!wp;Hwd7sRm<6jDa@d)IAv)eb*=eX4RRMwmJI--5I8{btTORr+Hn9qx7NC>&+t zHol5ITso-9jGF+)ky8hpU%8I!BN&Gpw1{!_-NrFqqaJkv8GPi8csfPVuQ9_*2nEBnCFfCdO#Xdl&SU10`LDW-^VD?TgQ6C8H0;^u5+`px z3MF7m`%#3plWQNj*O3p_GpB*F!uT#x=Z$p%br62+hZHfpu zBEu`;CXhL(aNZIe8!!3mhxD$&m%l&la^0PKZ$(!0mIX zbD=zbfKwDPavuS?mCUm$kb9btTdBx}+fb#&vr6U}k$VHk?S(BYlz&I&Cr6umPQ=(r zZhsKM>D1m&kRQJBq$@&C`1PtcX!IW-R;<;>Q>#A#-v;pShc2}HV^??61Acqxm)c$( zQGF7!*-Xqao=`3EBpe1H4n^o#+pk7>yIc`01+7(=IU7Ggu@9qI{6es=flEp^Zpl?L z_j9~Di3t22a4y^^n4H-L@~cEI&&iz*C#dgSjpZ-nInePP(8IrxI1Kk#{SAD{D36@$ zNzjbHL8~zr>3GrEa1?@wMVni7>J5$L!bs2-jI}F?~sB^<{0a?I%dbax- zTo_GN{IylZdqEQ}`ZexF73soX52`p7Rs1@tbiCX69b{n0S~zXMVFg_mu8U}tTsT>5 z22b~(PMZ-A{Qd*+`zy!;5AnZLn^oihEIh%9m#cI&??E^7WcRr9^Q*Zd>Y zoYoG>Gl#r(>8u8vfrrEO2@ZDSyhb-pP#DIK(0fOLbh^zKZgKF$%|~Qo`vRqPhaxRp zR}hXRMF}wr79d0MZ22*~_M?}?D~>-4ry_M-Cmna6?%n}U9B^VB&Kl!TCiw6M_&{$U zrGJK4C^^0rcmiMqmyu#E6EWxwV*JJBebgM6JAIgGJZ?@PF}@XIjDUT_)=g+4Jm5DX zzdiD+-jkmf7BSCbhoM3@)>tS2ZXpI2O}Ic2Qqc4F2V+X2Oz2@~VC`Ud$2IF4Z^^Wa0`^ zT1MCE00K3B(#^$i3xvsY4?Z6N4!sNxSsaEBUX;o3U4<~9(x@GVYG%0ddmpk836yIe zB2(`X7VjVr>`tp9(Sp?ZopBN4E-r7cNCmlwp)($*7&`%CioOY_J>^$htS&8`p&UgO zH&A)wA#+e2y4z5&k8T$Lo55I6zpT)DG@@`gN|>>c zDcYY6MezSm#s}Q72@2v%v)FJQ7y4mlY)^{;rfY|pkD>>GO;(eli;^r1CeD$%!JtqZ zFGx|2@R0}OeVpSlj2kd!s6O_HnSU+`vXV?CU2f!PvcEFSR2F!+;=>mjK7-^H=q3>) z<$%Xpk{0M9l4aEucR=JJCvK2rbrG~7sbnG?R|HT`5-M}?mV}MeHpCSrKpbHxLVkaL zC0^tjUj>os=@>G``UJgLX_Xp8P?j$hg3DB?-_U{1 zT>L6R-=`B2r_&kqDd$4x!K;@~XOibD9Tg^qFf$QG(+yHY@H9n-Am3K%`{?hJpd*x@ zI8?$($o@pUMu$R;a7Ba?6Z9=YFnr*OiCcW1R8`_|$`Y!Bh9^4b3Y!YL1ihq8`J2P% z8s;AiFdY2AO$yLo(4|CF?xVQQqZ4Wf9370qC-mgat0w*0jpH3!7nw}&o<+MISCBsk z=XrY60cI~vAaGd=<_pPgL%=bTKHi2fn2H$h_+bp1JpKQB8$vlG53bmlko1_R;h*tg51Zu1#mnKluj4n;U0c)sfT$+G3kxLVxjOo?{=oYJae~sonBv&R( z08#cU6R3iR;K~FdBz9#25s}4}3Dj=aUyjiVR}ImM3M>-jlz0n*>K-3q(l@x^-8>Qv z=X(o?raLf-4A>O}Y6!>pqF+IP0~IvM}yAjMZSPF$C{6(s=~jmG&0SEW*x% zA$tr6-G4c*QNp4NRw@#2DDV?qncPr70vvxsLEI=d8<(`uBGx?eris6-U=q^bgBwKb zr%M%k;!c->cATfc2@Z8An-2cy_Zpx_xQ$XAL`pn*N+ZwLFj3VmGf;U|roPMol;JuW zOrqw#%C(%>gkU(vy-;ki_{2uC;T0O4I>L@c1Vjp2cV|R6(bF#a=uYz6BjR{NSzryd zh)&gE$&yx1XL;%65p>jC-C05CAvE%IKD7!_rGl|y6@O!a(mDTGHx?)jsNYzi7ICq{ ze;gL|MnN<5&{bZiDUN&<0`xKHqLFIia1;*e&8=30H>qrza$*n%t6s&*9nN%x)hZ30 z)FuFBjqmO~g^4HD1jj-IT*w(m8N=Ws(%guwF$VymfyNX>0n&t_6`2l1%E+LozZ*_>o)!R zIi@`5EvK*MsnQP0SM!vRSYORUu?}C&Q`#!qujWw&*DeOn;F04sIDm zPP872We%)K{~U{*>g!J!SN$sd8H68&v!m~7NxzGvxIgH5lrb7f>1w8v(Hn5m9&_@c zkZ$9FdOFN%yoAJbGfD~l)TpDT$GhLb)m8QATL`7Y{Ix0u76^~VJM_%s5g)4+SbzNn ziowG7%gAJ8jd>&=lsz(Hd>!wP!*!u}KMlp7*h42)zlxWqVo@D0&q5AZgrjrZ>f|&^ zwxz$5)Bg!kX|M8RN*|3q60u`N-HNCu!1O>=x)1@gR*-fAqD)48QR){Ej_VQL0_`V3 zEu5eVJ`UkD$DIb&P{#CiHdKMODL)Us;E;0<;!{hY+!EXisJ@Og$7|eFkFV<>5Y0%- zBK#RTG}Q)_g1b=vh5&5sDSo5LjO+0l&F}%(cmiHeRxKOf7%22wZj65+c@YZ53H9Ug zomkZbcn9+6st@oxg8abOH6S|5SA^kQs?L&sK`s#M8d7Fa?$PPt7}q{TloN5;&HrQX zz2l=Q+PCpJn}jR`Y1zmoAjAZaD!m2-r1zcxf-H&%B%uk2jSd1*MFkYBC>B((AWe;c zT@ia%>=i3^9{pX{Ju_!#H;a$Y_x--_@1G~1PtHAa-Pg?AXU?2CbLQML3knByjpJ+W zXXv@9M2!>In$*^hW2LrMVd}}$7FsEb;#3k=w0}PqEqx72DT{Fiw-5VfEWXoRi4UV_ zypX{e454?&2LZCMMaI`ma&-+HzJdaaf!8B*&TH$%#usCkR{7qw7<;VzpYHX5JS zXU|7lna2C|LENi&kx%+i_KLV3vsXBY4`=mGx*oSJWXdpvV5i*MHDwpSS+brR#$&Dz zH#|Pj{^RW?^djJ|(GyjbZ`WK{UQ4zWX(t;2_SWmn&AR1h(D~!3_KEC_!By#;x8NQW zT_79ElrdIwqt!h)NgCrJbSV6&aS{f-l^07BswxxTuoY*u9V~p0e-SLUIecnwDKl<( z9(V1Xf}*hz=e?7-2S?IN;4}gUpXd-`C&iaO+-G=d;(FJ?^=2P}X=^U=Z;1v4Q*+R7 z@bd!RShyE%O%Tw$5u=ewcT6HV=`AT8KbMJq2G^k)i1l$_p7cY~tuPN0eD8qZElw%> zt?bTt%Ov!;?*S^ii*=W@6`L67t#0^*8r^8qm>RneV?g{q8Ga%T+S~|}^d zEw|woeq|ay=O%4KQE;SSq=!V%t@V`=*}pI&z&+Zqds*-do=4JrETre+eRdmoLg6gV z<=I`Rw`c@dv&`ja8FG!AEJ(_iU3412*QvV{oz&&0Ir$L_u-_Y z(EU$;xHYBBGWleMZUvtW@S&sz>Zle9LjPD3Jpmucm~hKNPr$9jQF9o;ltb%FT7`W@ zWCvK*D86;+y)+i2v_jW`*#GU{PfeC7oz^d_cyN0(VMu^!p>mIvD+~ z!b2lE`fZA4#`RU$QB$i|LmfZ({T3<=DAu6}4#v2JS_3pcd`dzqmBH_qdc3s}i5uYZ z;InK4koc64!S81>^4f^>?%zJ}5^RS>CkvOW|g6Hr^PM}6$H(qtI#cnw~uJ|D+!5jG{aGS-~7QEV5!xXq|Q+6wUQ##WW!&i{`_-27uGYoQ`#eTS$4wO0f zq-Xdu6%B>g9A^ZFA-IOalLr?4gx7$^<@O{O!02nRjUZmTw#nlbq}si;clQ#U44e|p zto_i~N&9!2D`tHEcLuE-7$^OA(E7KNjQW=3 z_p*O7X#EsU;s2d9w3CMDeg30C>+^7h#P>cvMLyGWFxR51kIun-$~l-#fGVO7#Y`wB zi9hBX%w|AU#gn=>rpsgw<|aU~b1-%x<8A#?t_uD&Fw9U4MC$1$Syp_Ruku&gFQZBDW08GM|R02s--m zcxvNOmplo{7UOrH@PlV|w&UwCJ`~Uf&RuiThf-#IlD-=c?`?dy$K#We0C-i$BM7gG z-vY;ilXbv(zS`;iGq|A0h1rv|s8GJK{D}no)Ws^}XEyfBW;PM|;C&lkY36~7N$2^P zKt3Immh#yPbDnMSMXGm7PvQK9H%@#PTL2FIYa1gQ&fa0}vIUl!n5}^269?zkL*_xx zPe>fO;M&0p4b=gMGmIZNUA+`JVZsY@i48a(%WKsE)g(goD;;zvnReM3%QZb9lTZiX@Yqto~;p@@dvC8o)+!-_rT26)4Mi7%6 zn4HEkJKTC4i1IChV^&^sej6nRSG%Enz2R-jPj{;enL*Nz$d0bwjU*3zH%8B+KUej_ z?`%m`u0+AuiTPNlw^YEc!r00E|0gf5^RS=ue<$zJ6P@V6@jslrrw>h13H%!WiBkg} zIP6H=5%PbX8t{y;^Sb|aYWS~H19woD`EGvDew3q+zx4&cn5qP0G;UNM_sv^2@NSPC z1+aw*{;;tF{z8rQ-U354sAe?P@$ILIy40Z|kbs&~V$<87LJoB3tXdK-JCjSjVFr)7I1I~m#6$bm)_{D=8%z}`drdjLCh$RBp;;U8wF68@DKes#mIYh*(sdm6dL zNcC^>Q(bj2GmM;PWRqSRpI~H>k?}@-Z1_)gH<}(=291p8FE#k*J+yFj3g^^v2 z)M)fLZ<-E&ZRD>;mdw!juSOm>GMZ9{MorhUuhB0ua>WVwq1l>WWaMlkml_$L|E?t( zse8GWEsXs53LUS$Ld$F;bu4<^VEC6V)7S$>?lUsV)S>pvwcKR#zum~~M#l4P{6ziT z#Uvw_vhD2d<{#{{{T>?=Ae>UY+qkYaEiwgIvZ-t_%@OO{vXTJseV#8{ruC zN&-RBE<&VinGB`oF>uw%N-ag8+&Ub-T!;rlxg;;GMp&s^0C?Whf%11FFb#m$BT1c< zavx%0uR~IWdytpcF-cWS2}6|M1^it?os(4geTX!`zjr1gB?z!kuM6+{lTr>M9QHm7 zlz$e18dQ7{P~~4nU_R4-83_ZszksSmi2M|&T8UYgXXNKV>MqGmV!udktdbx)Ue9|1xuqi%_Sz(s&qN@d zY1+Z)%BLbGl`}cX`^)}$Rq8NZzohhwKn!io!eKsg3(Y}PrLkt4li)oW$T$;$8yPt- ziKgomJa?701L?L4@7+MgZUkzgL~mkJ27>8JnR5<8Ds3ltEvfR}3#4^J9dwn*p}@&v z#?&NFa#d9&I?F`0F`6>ZVpq~YjV*OCm%PU+4lOk2Wl}s=N)hT2&F?9zm6~AXnq=Qt z1q;{pBors@FQqA3JD6wMJ=vUKID+VNg!(48qL5lrX?syYpE2$o41|9~ATJq_{>jgw zK%F!sCm!wwTy*ESx)(uH;j67~ysInXl?uNJT?0Ieyot%u{&anZn*tKJD4EyHm=j(E z_!Y9J#IWD6@bnmVJ!}wlDgM1#$>mUtIn}gaj#3K=d+!IrS6R+Q$)^j4twW`q1kUHe zIT8r}g}}g6B)HVgCp-+0z;oTC;jMuGAbVkqG1w|t4aL8=BnBP<=pMq$VlvqYsBBrl zD`Mb^fW{JDoy-eut7SZ(J%rcBz>fi{iml4Lbun-@pjm`ByKv@QKu;6C$utVxpyV=T z9=6JxU8Ty*O~Y1W`1iKN;xmE0LHyoW{2R;PVQ`gsW_hJHdBS ztkeeldw<4W<$HkrPCP5cRJ7(NS5ayN{=I4jSK)IIeSpv@nC62p_x~OX=ir+%VYw~C zC#5TOHvYZSV%XdD%zgJj_ps(@GmM|wF!L{@UOPyPa>X_RR&rd0FUP6`%UttOJOA#Ey zU$d+QDbY?l#Ev?o8*a<0rktxv5u9vp0PA!7d$%VnOohL(ggfK2QQ={DT1(<>@j5X? zg&zeWGZVSrn=p6t+&UEuVeLIJ%dO`NEdTMue5bPaTj~=hrmAoyJYmIvClj-r`WkJi z&$v{nb~)%qbI7t@Pt0;GJfoT^`<)Y0Rrqep`XDjOv9MZo?C6Mp@7ENf`nC;yV!IpD z=M;ibLe}w=0a2D@!-L9v63S|)fKa}S=|6b?s&F>23y5cw;aS*T;UYlK60RBp9|qL0 z2H+ZH9`~Z`c7WCrKDCTvBkRtXca0@r(M8lezuFAzL(8g{kfp+{YnpQEy9C}JCWm<- zyn%nOkxOt4dCwABxP*8^8f2SnS|wzu@O(>X?GhYAo&}-dsW7CSOK=Qn2c-}?yM%Z{ z)>u}Tge(>Q))Kn81jmrR7k=G8M%PyAG5mYuT!LfBOO{aR65qZOc)gbzptdc2ag9>_05pDq*Po2f1>E7$;IO#FMV>O54|1&F;)^w^NfN^XfsE&O}S{uzHcxL=XK;-BzCa$jY6t#Ik^?_J|0QdvcSo+Z4= zflcLo3cOEi=x#7Nc3~=O3?PBGIB=*6dU=)gq18R&>c)%iyf%1O#lLsh=wy75^{$2A zaA1?&n6@U#`>sy1%lH7gHtmqzN2$z6-z{>k8NC6E>f<<-xgl?c{ud_wEU~@}zH>~( zzxTbP_Xk9(+GWrkq5fZ~x>Z;E39;erfdqmYsUBR6`AYBGz$wLmtE!VPr1p*^uLgT! zl|FbIIu_0-sf^2^`Hb2@(sFBV0s1TAm9(`gJLNdFfgS#=<*5}q=og{D!=WOuL(`a1 z4(eWYgeGu*ZZC+543@BG44s}~4l1_@=rz>rkJoGj$|pkLNtzg1<{wru_uS{9=6prq zUB*SNa*qS#xGeBtEL~fad-@r8^}~PQi@TUc4novfo(mO6o`G)?s@Fly*S)|mQMHuK z(^0txp#GkjA8&RtGUq|%(DdI3K9C#es8lQb2mX}P7kx$-0J8`xPf|%%84G~yBpUFf zR-zf!+7I|^s*)vvs-5y3VqVHfxf-gIQgwDzMaicnBbaiYm;NAYt8N9v+7T(*gSbXR za@O^_0G>hB90QY~b#>xGB-T+J0t=w79L8aXI9^%>xRqqU-lklH% zm$92Bs`@;sTRhq_22FK32wuv7nykiK84hy#_b!AQ+>b-bp!Dr50?dQdmibEb-y@vy zD-N`(Oq$1;?a;R%hByJQa##}2z09{cb~d@p(VQ(nS#p_US)I<*by}vTr_)IeIx(w- zwNU1}jFq6hga0ypJ?foE4&Az)R@F`^hgdjuZ16h7u0dER*CJ5oY`ht&I>9U) z>s}9_N>_YQSn>=|FFl_fW8E+iL9h5y(6au;lBIwoE397ksiFOC~ z+Vhas3r&(7(t)fedi|6rTJH`ZeBVmFMdulsL2{#-Jpf(o1%HMK#RyAa8UkWu=x6pj zJn$0C1RPFnC@0I7d^+!*V*piSUccWMYErf*rUej4?V^&JRzW1SX?jf*6=DfWBh57O z7m?h0;A|zYBP&NVDyJ4xpv9)1o_n{|cVacAH>cS-^>AeKOl_>1r8Mk?lTWSNETy9a z>Sd=4lt2%;8Znl7zNKDsHVtcIzw{2wSDV*gBCf#$G@=c@0-1}!qj-gM!kja$!M$?d zvii}yR_T4kU{1)3!M#-rEDMLh-o8M~E(o+Nz#-=eP^TeKHZwKlGRR873ZCDA`=6cU zgUWhj6+G2*KB&kSp*skF7f@-faU$|%CRoLj&qJH2`92Ul`F>;^Y~Xq6_XANndb){* zb`c9d4hrY^gH65t05nzWG{1%Av$qH_Ym?C^SE0gbee~>p@I3F9YRu?KQq#60EMH@S zSzemo;RHiocrX%h-ak0OO%PrWm{aY+!Wj5{z?^Ci&WM3)_tl>Rf|q%jcv9F>lXA>d zfAAD9TnrB9^n>$UPWXPnoTU#gjDe2><}7`1NetYjpPr=;F85dmrl9aLz(}z zc+lc(L@N9Ua6Y+%hrLIk*4c;TLBf>`Zi%?f(GoT5amz{$ zI5x+!OkwFm^iV077I3PJh8w~tOGtMKy!j2`7E8!-2{c3qhIQ1kauTvsxYbZS_Y`d4 z5*$P3SweG{;283hCA4!1@rI-iGv%C_kfp+-LEsEku#Zb{4B2i8LtTPnh?j428153{ z4H;%xk%TN2z8wTkVFf3;1jmryEn&J#a17~PU~-t{65vM|{O0%xd#m%9YV zknY0`VU0_047tt{*1LpwLw>ZZ8xpcqxc3M>_Y}O{B{+uMXbC%9f@8=rOW5TS;tlCD z(v(w@kcCIfO<=Sv;o*B6a!$czs(TjPG;*?2nn8NyGJ+hda8MwF&VdA54aMv%agz;8DJ-$#C3L>5_uyuF`6B za9m9u0Iy~eik+A=kG$&4c_l(BEf+lB)#MQBptP$Ab9G!zq!2MC>S`ib9rB{CCO)Pu z*9y9th+-CMA;j}?TuovXp|?RXTDqEuR%(Kk>$sXk3lgmyoV0W`iKA$(?`lG=3fCCz zyPDio8+9eMq|)l5f_zt#Rp1y`lm1BLWDJ)Pt2-yz(G8Kj8=Y;^jdyjg^GbzhLf0UL z7blq)QRk_`&sex9nb*vi6V4vvyPCM{3oJZ6hW#X9<7zUqj-Pkh%&v~B$te-TxhQ#~ zaM(Ij+Qs1bt|l|UF|H;~KH;Ymb}~qRHVmm&K9|VWTDd z9#2r=&#mqcSI0IJ(ygM^B*)bxTA`U&0{2}_1lRlzf%~o|`nonL^j%G&*F}XFTR0~r zdKFaoZNSFW#AP=wGH}Bf_9DQ>)uhxVdC%%PrNrsn>T6PLa_Hr+vktNJ8 zm5pQgUdvjL677aV?ACO{2-lqIyPCukoNQKsWn4|-tszT=-?D@|LKj6?9N&2*d(SXRA+EEP_g?Yo*d*{~xtISd5BxSBWw$B>&Wp+&+XOg2AQ zR;z?86+ZJKQ%-A_;25$71iq)k)g-YYUs^(Emk?hgT`xA-bVi|&eYT{U0 zYq9TY!aNOm2~g{5;*dWDY+Owoat{<@T}`6oteXK_SCc55;a%>#nmBok1!`SQge-6F z8BYKfmY;)oE9gnyZc92wY7>C*y;xB^HLOi4U9X($<(Ha5ahQw5!P)=!~lg zGtzoF*Nm^M>f_W{l|HeI9&3G9lZ5&kp*OB3QN2GPQq@wgjJldgpHZzCh;=m)#JHLa zNj>Fds4A&g*ORnTt|#~0g*M9>CYA9%5_DdN$H$;lwi(~`B&e;&8nr>x2JZHPoL1uE zwXE}jh*!pLFLW}%&}q!7bu}Et`Q%wCsglhxHfP^kr}^Ea87848Oo?5%4pc2 z>b3%@9h50W=OFH-6E%(~=R!4uDmbDDOonkpxdysz)UCT3bE;nY`BdG6psG)n%mu>{ zWg6iMG-G+)$8D1JPeqfwB1zcVtRu=igsmgWPe>xhZHhC_IHJ^EAM1!hD^$H9K&>N+ z*i94T9Z}|k6zhn>$zj(KWjHf~7sM_y;fO-LIHG(3fL6f~h4bE_3Bg%ZxUc^5fQK*x$wIfQ?-L$H9%3sjZ5v2^C za^i@>^28D4vpf*$%x#Zj-Rm}5N0cFmd+A^Doa$D&);gkGAn3P(E(aRu1{aGpKRDdL zb=DE3N(bhkxt9>_4(_$TA*~nsQ*!V&Sx1y4bb|)1w-l&#L}B@%Ae4XSh$5sIM-*=} zPqv|)tm^bPjwq}R*AeA@mKWoQB8c|uSbIHF{ytOmnN?ID*Z#xB?Ggcm02cJd-~v2G`fxaJK=7et$P$QD0}*F!Wa=QXCF zdA)LL++fTb%`20Bgc;{>a^AR|w44G$%gb@dX%51z2$Ve~HRSF=CP z8sM6Vvk6oE8)uW2yuMLq6GlVrh=qSZ*~ZzVD*!J&s*5_C2*w^kf3VgHI-B?k6>fK< z?`%@(3})1e`KO(NulvB zwJWBQ0DE*cxeXlSY~paj-vBnwCNA9eX5ZPwg%<$kJiYI1BBvLA25^kCiH1YB#5tR2 zI088TBxGWpO*DK5VB>5uu%oRyUDauR-%DqcZ$LE8Ch^2@i!HvhNmQr8mjUMdDx6JR z_;J9-*@RcfT&>KLZp9@V2sWKf!}+;=u{@Oy##&L)Dh5n)XpaN}&!u#?R` zBo8a!(?X^3nJj*YbT;XBo02IcIGga^&=$E~5^F$+aW-M)g~(Omm#xk^n~2UY%CK^_ znjEaNNdlHz;sus(olS(#My$e*S)Fw@iOWl~D&KBOw9Y08So%VT&jEF94OD$vz^O8x zo*~?A3F$6@H@_kLVhLF;!M|+{tLq)6oScL#6e zC9CeYVDX__`OIyIyQN5hXRTsuO{EPyFr1wBHNM=3*B#lBKhe#2b?ePM7F#=xtU7jS^gh=a;aF#4Q{cca? z@B_ikh*W7;J7pWG6%I;{suNyES(RR=Hv!WZsKV0$uhZu?@@znL{sEDnkz0l50wt>R zZ#MRPAiZy!;t3Vam>Hn5S` z0$%49h)9922Lhej*~r^4rH75YgGj!Oyo<=WHu4@UnU08LeFTxYHu3=?D{bUMq`3hR zg_*JnA3<}c)qIS|9vk@*k%Kn!6%2jBM&R+&=}jB?0krpR1YSO!zeOa4S^pGJXa0dm z%Lfs8@hY^4z?p3kzJT$Ubo@euA7K1t9p8)aZ;Zd8>oX%8X(nU1$a_(H}%m$>Q@&Z`L9x`f-ak#q@n;C*ksSvumuSne-Q^qP}DwOPNnvQaT1%z zxy>%MC+!qb_`ZmuUqloKmr*x4Q^b_|BBu5dF>R8F>6eSR;ARms9u_h44H2_`6mj97 zB4(#y*0M|Oi%u1B@#!Ki=_umTVInRYC1TD6BIeE$F>j@a`PYkBaKDI!M@1|udj<1c zTtmc?#v(57Bx31E5zD5ESiVHW72Hs&OYId0M67&M#HwQy^`~ZHwy{h7X{U>r-bKU( z!$r&}7BO>yh*|4JT)0id?8ii0^tyL#N1St9yO6Vdld z5&gD`=)X_IfEPs!{8YrCKST_!w2HY5sV!n?I}yVMh{zu&qTnJC!&iwIal43-yG5LJ zNW`d*M2!B8qWOYyt0@*rn`pjhn8X%~oz0hgB(cl4tR-b>iHK#di&*}nh%0igq;AET zB36zNv1*2h)vHCUxlzR0y&|rBQN+5>L|pYR5m#4O$6T(dC1QO$5gUey*jOmy+W8`` z+azMsLn1c6B;xv`B5p{!in-iaL&QxjMBF?;#4YEE*m8-8Tdxsu+YS+1pA~WYCnE0n zOT?X-S2MG_+KAZJU&P&GMBFn|#Jy`oY`;syjweLi_koD}kBfMq{x!_y!8{Q=`-*tz zd=a}Y7qNS*h&}s7?EOr{!{sq?)TQ|&RYg47NW^0uMeH9a;=p){wgcqCwH-KHVuRL+ z7<`Y2AqPbaeP6_|pG4$W!gNrVwgnAD4DT#r#3&IXr;9jirHE16M2vny#M$qN81u7; zNF_`cb!j`cj)-$Qi8wc3#JFi9&Ras!q5FCfJ;lxrz3-M-A8BVD1{{#sz?Vb}`dq}| z0A`oEbQlsAF|?kDVO>S!4--)^o}yzW+ius+Lp{z%b?rRNyHVsAZ>PwJ_n63YJoXY@ zJD=x0C-L*W_e4(gz7tvKaptOP=VC8Ye_jQ*I49gue->#-f)pud6Pt5<6SCpqqj=r zChta(*L(MgywN)-@@DTfk+*uEi@e?YOXQti<;^T-o0lu{9c@ z*c&DCQ*W}!&%AjeKliQ_`GvPdNh5&5&XRpc+;BO-tG4vYNF`%vWX-Z7EKy)u~E>Du{U zURdOxUVV{&dF@52K!1^eKtyD6;6jlpfn_4g1g;aA8n|0zFz~3zvVqq`mJ9qKGA&T{ zW|mVvkS+40Kx>f|0=-0544fshQlMC5<-lB#RRU{8rUz~j845foG9&P$$ddzaimV#= zN@O_jFOiu6PAhfooE2ywvRdFwk<|ldi##PTRb-980+BTX8%1UZwu?M9uphEZ*EX++ zX#3|D#@dB$h3Gz0oNM6CE##L5a=naiqL zB35@5v37!pbqhsYeZ7eFkBHdtf{2aph`9C(5!d}LVpH1f%6Sd3hM0lRZSK1rOns zr+I4fa!6Taun(OjKhKrjdcIj@&}E{t%Am@fcoX7=md{U$TV9*Rh!RR-UZWmg#tX2fo2DG`5_fyDGGgNI-ozpf=ug8PsKN{wf2hoW!dPR)MHj8PLqoIz&|(Yt~<7@IJ1 zh!_)HWuQ$ZFS^RW$F$|qRR*G{h%s-7=jE(2h*g9}Mf2k-1JO!NuyUPM2GN2UuEzD5;+;GaDmmGlkDhT zk-WEB-FR2mfma~>6?6?!klDm!UPPUz3U}CJ;G$$+GhLtJZxzB1~_Jwfs;?T-aZ4*b(4lK0sKcQ zY+M*)%nN|cDg*b7PJP&4W#E(_o(0%!Xz9XF12(G+c%f~zRC~l)gCnq3Amx9G#P3`a+xyEvr4Wq@Rcfa7jS=-frDdKC%VeO!OsIOe6BJe zt}=H6+FTx1azjfEg&uQO83+^}4~U;!{0%L67pw4Yz-E=ff#J47^qrOV9vJ*!CmUJ@ z_Z#BF$zKaGYE;@sAj+q7ZfKbgqS??gKF9DTt2#s71Cpg*61Iw&3h_{9;6@J1)H{>ZYPOw4lXtH~i#_A@S3s$CBHjBc{5 z*AufG3oE~1GJNO6R280QSsx^3ITn5cD!&(Fl>t%xdFE-jOVj=}Lm1!^;tg4AS%VU?u-M-chPVXBkUp>L&#TzbGI5P;w}jCyA>NR3ZjtTIS!NV7NnRR#_r-jFLStJuxPXQ}W}OPJyk97FoOr9B}0 z4K3v@O7}RoS)E;FAUc|(pHQ0Ry=`)^s|*sb+$Y*l%eSixgio7Q_$I5fs|@1u(yZ?+ z%dRp=z%ut@r+4s{Uk~+cH?$;GWnKr^Uu7TzmaIPj<<+{0=36v9 zm9M7y-7V`ipmvpkV`+;c{wf3JX~^q<+EoS)`8&X7m4QR<{{g&_8^a20Xc;AE-3HjM zGKj(%fe-yv22LJhfZA0CLY6o8j1s_Rl>q^Bg4rMWs|@(!u5Hek57ewOaJU~@w0o+< z?fS95%D~~?V9~xV_Ya_ELrWTLF51vfqN@zVVE^_pgqth@s|;cZD(k4#VU>YjHF~g= z)%w%uDueiR>!Gu&45I0LtEA-UL1ldozTMFBpYVr%7F}iV@A)CQud*IQBD>1KPo%Oc ze;!?B;KQbFrb5@JHChZdv=p8630bdN7#mvpuvr!`{0ox=s|=z#Sr(A>Hgr$7L3UVW zAUYWzWOe+~z*uGA!zR1OtPZOTqB_Ygqsv$RDg$Pu^>VHm*IL!bsj(`3Vi`X`Z#J|{ zsPFN$zsex0_Xk9(+MUqb4K1b5sCLrP=qdw2;y1AT0VakxgT!C5nF_WSDDMUBG-TFd zAmTP3_Cjyp0qPMPRBP&Gl|ThAV<#xGN+47Fy1#fnXgsKlBT&gIfoi2x<-XA!c%Y_U zCGaIPmjh>+RmK_6(}yxpTdxwJN@WxSXt63-p0 z1ngWfRtXG&jt;8Wt}^$B=qdq8CpqZEtQNgW02gm6h+G9wgeQQk0$_f!3gBoVN~*KC z2*4h*w)xFfBS6n3MR6)N7s#gL0>Tt&&Gw9XfV&0LA0Cw2gp^g0$}B&Q=@X)G6h;BRsoFp#jXNiHKq3y{TVp2`C&WC?3DMw;3@#t zeT-f1DgaTM4Kn+s4`wcQ6#yfyc>_cp(&knF)f7L9*Fz`FDPRhk*DJTs>PPd+q>p9B zIh;Hf^Lne6dqHUV5)L_SLHHJdve~IA$021EfbEg}4?};q3Sb-Zl~n*t^>0=I?4%{p zRRD~J_7V%X`ORMi@HhZ3J*tbY0uW5TK!{U#bQOTFP~kbqh|}`ea`NQK%;*{BpO%ZT zd@tdalYXbcRRE78fmsFMBnX%L-CqUZ!h->GG8|h@y6^_TW);8+r_@<9%w#-Q0UQCx ztO9U2;W~f#s{mYh3ShJ4qzmr^9J2~QPA_~MaLg(I4R<{rw+cYRs{rStrTVJ?H2f-H zvkD-8imf{Bw4LVnty~2V{+GWBAf6Z=1)bS)GOEK@8o*{1fD3;C*sKEJ6*5;Vv+sf&W=R3oD`gmNQE>0@>c;gn`*NU$-~HZ&5v6Ja5j=~ zBMGbm;Ju+Ol1eb{>svvHSp~q#3z3W6ZLH3&0uY^Flwq}mldR-mR{Le7g!j z_%eU>{^BcnNmXPHV z{M**Bx&}-+ISE<#r3w(tDgdV($B@@8p}CubV@S;;lS4a~5O2sN%Q`b5ONAc*fs;&F z1(4W~)MP^#>Jl77hFijLmk@8rHp_}6WU269AaIfiTTUi6WKfDBOm_*6AvamVESC^( z$T7>BlaQst-OG4(6+mJ`He13PHwVX%A1q4C{oLLs&Ah6(-Qc%!vQ{1NBJ&*sLGB;RrkXtaV<$)7pgH-*Yy)$tD|%| z?|Bo#y%ft!DdX*3IEwCe**RTEen!WEzMK8 z**J{Ef4_}0X5yCTR>UfYS`J?OU7^~KJ42VF4LlFjwfJxTIM0UO{aYl)8dmK`bffsCe9h&AQU6x2EtZ(91nA$2`S|N@RqqG7=`8eVO-J$@@ZWD6R|Z5+ zi!p!Avr0|b3659cfam-D*J*??tEwFJ`}aJrkMHY$$n#26AK%&k1w57d_}>19(ce}6 z{C?wP{~}|)H~&k>rn2wO|1vZ6{rO+Lsy#(b~-_Zait`rl_d->?4&b-rW&2aN4O>9RE7Gsb+^{?BQ(@7wydGGb@;IUhvQ^_2cos3<0&GKa3w#Pd-vSrT#x210>?()aqvjSk*i&cT zNiwfl5$zHG17?^uDT`kQ%+QNp)=r%&I;xvXYDvB|5FkS*S~2 zJAr39uuzx2Ho`OYW5cENLY96;U~SLt>ChFOb(t(DYQy>+DD@S*7Y6l*@^9?Wzr3Q_ zcj~R{JtEeOK%&j~A2f`)qL&eC1`RWHkxgrKOtR(*BniBaG-yy?LU;qt$^8woM+ld1 zJWnck3GAJMsPt18AYgv>W!_#iGG?t0JT2xj8;nYW2T8{Anok8^^Yi$7666maq4N0J zPQ~Dn!3NhM#o$rtLzv%i9F#^zYvi0LGFA|y9;emkGu1S5a&JUFTs$_o@DjwG{IZ^b zhU4(Tc>xWRfTr}hslHl>c*Q@1H7&zaLppsnSDJ0`If>CuX@62-4?=esxVZ$~%lFZj zppE458Z@0x#`(M$VCC_td4Z0OE74EQ**ZEA(b9FK+IKbC;RyqiE(7^~{0|ywu3_*e zH>SL*R+r$4wx4S9!W#?n3W7Tt|3mumgt*v^dHJ!a%uC1QWcMRl`m9y=l9=;-4y@K; zIbXK96Q3_nKYG4A8@376{#TQoz69qXs}Jx$q*J>&?j;~UdWJ#hoJ)|M(k?Tu&Ds1* zwK*!BHuoJ{&rfU&w#^ChR}>kWPQ-6>qLwztgUUS@CF?eqyboPQvz5E1Hs+vgMOj67EznP@g1pDSUx2c(O8x!9M7vH38y0B?3y``6{=MRg zr+TUb{`+oM`TQlc{8=zCz);dizyU953`9zD0r8xTIGl@ka!pyHJqf|2?nxIzqy`I^ zsDQtOR=}TOD!@ClDmcj87|oX`Uq$nID0ml&;qEVo1=u|D)5Gx0EP{C>&p@=Q8c}|c z3B#bJC@1KRAW_sws(?Sqm46*mo(>|{gQ zWC=+M2@PPT3rTq#<`k@CNH7U;5-?`Jk%D_jC{qp8Cs^vkj7o@y0!H(hyx=t|c!v25 zf+XCd0sc5e(lxB(1}lnsaG9HG&L#O+L#5y9|i=`dMKca?yWWCR84`@4f+mb!&;cQCrIFu}Q3>%-z-T_n1;eS}iR3es z&rpFxCDU2J&YFwE%c!VP-2b6~cTfH*redgop@PkfvLh+rA)nEFiSoYA-%IUz-4J@5 zA;EYkV6=dJRQ`KZFqHERLLZ^9P;Syuh?L-H`6Z!%ENGvL+ymG1unMN+WMR1Q14vby zoqZf4r#|8pay*q;BPj!-jF;0M$f*cctC3U>A|)U{h}amx>NRpkK-n6>Q)(o2q%xSp z`>Pj%HEQPY_bLY=ShHr%eDFphm|ZjJT!_?QPE8=Q5IpIW9Il~X$Y70}E(oq=ux1X| z(%-;fb`ICm-_78uIb2M?m%-eeSqMJEU@gh)O$O^qW}h%vPcr*~!TOTfUko;o%*y8? z*iagDCWDP6-_sa8UGi%) z%6SaLwIq%u@oXWo?(2-vL2- zgb_KdHOD{Vd!QW<8q_4(CM3h6NG(QM`4kmtK%lJvQS_YVK6*V2l zbH{ZeyjI&et{Wqd8l(F#vQB>EOvVPeg8_^rxXZazV+pL3;`n2l;-V0>IP``T^)8O* zNg|)48cbx$8|7T$6XZ^TZa)6&E|5#agNiI>f~(}R@Sq~g32cyy!Gp?O1K<`W+rW(? zLQzd*E2&p=7m1LQ!8W2BqSp&5AK_RhT2;U~`J_joPf3nEN!mW4 zN!3xOB8P}>W~ZjV;6)QhUZ-lWs3d{R-!rNTLMzY{GK1VBAbpMhdap>%JgD4b090*& zZ#iHPK#1TG2doaDF2PS7unBwxnBti*rQW)64_fLqAy=z!Y*>?YX90rvxVf#4tqd;`EI1PdJS8vuV0 z9PNO~r(wK}|0d@;U>1PW2u^gsCIC7RoZ^7p0SqNL(*e&0P(-ks4~DoKh>FZ4x|w0q z9bXDy8No|fLm^#FR|2?!;QS~Uxg9{$i+mu&T}D*oKBAW}tTW8XSPiEDfX%XVvJpIp zU{YRA0|Z}Zu$`u%y;1?;C`9!zbajegwzgGD4fDvQvJArcH}Jd4E9i zOj`8C++tl5?w6cb)`t5B^D5i$fbw~nHaxIWUbYPn3gy+c;lbg&CN?~zdR`kF9-5uk z8DVxbEr!+2>w_?F?H2h>F#dtLLjbhgoSiZpazo2Gc@fCZ*WgRsT$Oh&!ZfnwykOpV z8=hZ2Zz94R?X+A_DQ~I`FRYR`3*n zN`z}Nyu4H1287!(d_~W^>k*#8@QQ(Xw<0Wgt{$Fu2g0j}ubGgy9bvI;?bN&n5azn% zmRHTl+k^0Rcxtu0`og>tgeC2U*?9*o|GK4l&m+v`@hvy4Q3V`_Wv9Ffs8Y*OdGA2V z>5o=^zQ4x00W_0X*R_p&4vsSKd?`I2BS2;vhuK^1TZfJhc~ z6XJD|9Ksg}ERPQ9?Agyxz%!e=S+Pk%6|TfdlnSwgp`-rZQv7i(*a2=Zkjg0K3>RuTK zMpcm#qB~@C;h;|uT_+<1A2sH^K-B{>q=;9&PSw?0*oNX&?^Cr?MtQdURo77iRj#TG=u1pSkz>53RSD5(MmCL zA~HhBtqs*c{I^*jH9$r@xdlKMQ*(V(BWIYq66kJfZjEYmn#X{CL(R6RMyL4+XifuY z?vHAunTZ*Z`cSo=@84G1Pdn0#=pr9gk+uX@_<*5xBDyx3ubiH=pGXg?)+el#0aR^> zOQo$TplV}6RfMW*qpIjRgiBzrn+y`bgETk3($50B~QtY2bH@G=v(B+ovO13eohR5f03eeuDLlvF!D0dA~8`qg2>whCJWF`XdQ732=@c3rZLNq zs3M;em>vake*kct;0!rO$;Ch0kQ9)Sayq8j@Zae{z2rjPz%yzBX-@P72hHK5wJp#y z8|CmsJ2QBCVQ-3-o;-JXP=y1Dv~`huA{|_06p_wRB&3s`OZcfMtO_R*>EZN3=+j$(e+&)^id1 zQuHEH5+$m_K}0_DWE`nEBZz$EBIgj9@1~kal3a}3T{RC_h@=k6`cwH83&tQrWbXuMRlrh0Fn1xB%jC) zQN;8zV+dd8!1^9KpYRh=SQSno@`Hn9r_2Hr>CzzYQb>-qx-?XI%Wb$(FmHnmpI#~N zCL3-X&f8(bO|tVIv*D(7^Io>$W=--wvEk-z@_w-47M=1`GgDT}o_Q4z=6qgWz6aq9TOW@uRBQi&*B9(}2_bJhtL-TGFrhZ*i&nAl3!fe7D7 z2oKV?TkPN&X_`>EQ__geWYvan^t+jy8`vEQ?~g4Z#9c2{4qtM6LftdFa3EQOb%AnL z%v93~hf_C9>jZXm5$c8}GE^syOd{dwSYwUq0;;a?EmM(;2&|NIie4gp1?Ez9m2jg8 zau)+#LCw_yid~w2B~kq;O#|x*+#Z)fWE0WH;?Y}(UbBidAg^>1l7r-xdk6G8$kCtM zcA(`CA##TxJgCT71oRZOHZ?-vfS*RU%l4th+M%l< z(s;!az_|qfy(iOn`YSKiF}P_WHg%OBgCD#}`4qmIdd2H(%1dKXUV7L~DKYrr55JB1 zEI6;5c;$E6=Eqb~u&Ha$p*yg13$%>`*l`i=kgBDpzC(^GpF0`ke*$%Yp#p{qB*g6r z3b>lOAn8tM8OrDERla=v<)$O~`#~AOZGq&IR*D)y)H)z>VSGMUi05}qJQc(WxDRdte?=%DAt6ghQb>r~gynA_g*$l_+{}<*3>EBP^rB*fxUMn3 zgi#6cP{3$D$pvpxLF4lo%4euRqLOI_C`Bzy9k!5bTIDWmuz-47fqE*&6=fa%ggS(K zX{CLB*OJ72koaI)wDNyv<+tBpIQr6`g$$+9EQ`7H%l>jNy~O-W zzb59=OH38ybcgMc=KA_;+Yh1mDagJ%9=O)_P)UsK^vpH37hPo%>&Be64QoqiTkWX* zOsv|M7#;{{x|LetYd-#aufNM!+*V?H5rYqO-7^`xl@_alsW=uD!8lZ$ae|zVT)Kkt zY$$3Y+o)5&yaA1k?Qb-Rk4f3rBB7MM!<0Q+%HF}cLv2OmM%g1}7hTm-7YlzkSp5Zx zy&tLdt)VZg+!|B3lR?qp81l(?BS~vaHbG_UaS}cn@&|XgRwDIc?xesad0Z-?V?pLq z+yh?F3`|2nO)lR`o3LF>n1EbYREp-v;-?Nbl;NOE3#<;`hGM-p%FNf%N_1%U-lVrQ z{)+Y)vOcAK$nUO%R<4~IV`cbnt(^X=$rTp_zWG(|K~=WF(nEdj_y*{y^KkAL1lCqe zZ7SP76qQH&qD2jvqPQzkynqyEX7SusS7M4OI>p@7{yIgQm=yets-|tR;`U@oA^lWl z2{M~L&hWG?*MpZ2-t$$Z)`VAsyvef-Pv3U?!P@{gQ`_h9TB#Yg8xCizyy6B`oHjNr z)l_hBJ+k*kOH|G1ijViv^E!%B=~VtJsvFyme2Z3zsH~+#v}o$V8Ktzl|@u?MU-Z#$+w#n5U~74XRpQmQ48sRGzMsJV>(ffA_eOn!L-9nbIrf&w%aGZ9-ZR+XU}2F5gIzFG4E+ zPH+NrU7pdtowi@s{Xjte)#~fr3R;lv$nra{YSunO)|USW?S)RG%0)qH^0AlSs7brJE3$AI&8{4-(l1j89B9R65Y1{$dC zY~;Byd7t6T5YAR`##9n}q;fQ;2^uHu(Pcdg&cl_XHfxUjeznix514&XiZjpTqboE0 zKJ2XFoO|68B%ig#aP+yi2Ip1h>Ng^1=B^mdn3*yV3YNgcej8=QbJ25#F&uQScs_Eu z54S?;$L-pwr60FNwcuXN(?uRg{0I^U+j(k#VYKSFYtDbzPtS;$Tzg8c%_m5coz3F0 zua#_RRdjny!L89CuS;0)f7bPWY;x5#x)Qmbo(E6hA~_xDdbt&l+x7lxQs}PtQKWbj zDIS#+y6fdOK}g|uy|v)o&nnX?zDJ5v+k5IP4D@WvZdL;I^nr$_ZOME9E+61sI!SDi z*4>)CqNRqXuU}{IE(fplki)-z?vUe%NvyBm93=h#iP_L?)8}s=|A*J_!s;FMDfY#A zdc`jx*K>or<$IEZAy|osYPhJ)x5>FMTmCW)66# z%JtXJOkRIH0S#vxB3|*$;GBJ$dsiiMLBv#i(UE4}6)8~pRTomX zA(@Ljkl#?Ft&WIS`~&g}V02*Z?_L6U##F=UE1YW0^);17@@W~Cp(gJ$l-WXQ`w;d- z1kEhxAuGUE>B zfD2`kOqC>kkmOK;B)l=a#->KX-P}^4vq>vXiKL|2D7Xn=OrLZq4bl*ynLGnjG}u02u&H!#I+?_`~U+N`6eA*yD5ZBppk ztF;@~P2W}0l6hCD{8m5%T&puf;bn|9C;1n@3CJ0X@JHsOzd5fa*NP#}g|>%OfWF+_ zOOVe+Jq<^SFW!71EE?rPQ+6Vma_+4@Og4FHOxACKbFOo54J2n4*SbX8#h>8(%Q>@Q z62CPT|Z<7m4FzXXc<`fGl){f{isT{o|GMVIm#55&o;e({P`r}*pkaDSV{%GVQ zYwf2#I>RMR1_>`l#4be-`HE*ilR{0HvzvBFuJQSyT36dx}Igrit)^e zgJf=axP|n16fYbG0)v7cSv(tQa@v04F7q_(ejyNlrO8g zXWnS|b(#N^hjg>7AU)h3k82ds;gy#jPDe2!F)3zJgNGNo}b+dCuymQ+t@q z)}VQ(gZB)cC1{Ltt937-YP;b`9Twl$PKui?Z_YKn-;)lTbB);FA+}?2Xg?JmB)_Kuf z^N~KKbD~Kvf0XP@dd=8n68DtED>9@o{XX*UGCt2_{oYx~aA+t?m&0pKM)9VmY{ z0$dK8)WiSHwxkY86`DT=sAH0N@&sq)S&c^6oFi-T$&&W z1gRn_AiW6)2q+=~A|eV3B6b873wA&Dg1vWaA5nkrduC^MZit`%_j&$#p6r?Po_Efa zot(MDf>b6HTw##$)GOWOYK%yQzu4AQcJyq`lqF2ADP5_EY)AttxA_Jx1kM zx8k9+kB~vM-(2T0d?ykH`R-`wDR|3t>FwN5N;VQtF^|7yn{>|UYqo_h3T3_lqF%F& z)eOH2RVA}$WzDwGF*obtVM^9)3ylp;If7r#OAfhuO#c2q-kNQp_uQ-l;MEAB7cL9k zNZx1kypjiU@=5UI8>FH4-Q*Y02lCdMG6Y@xXZ`++=- zEwM41{Gc%`VHMaeFURAj8N#mw{ruGee}^-6f?D8_;Gl1lyq9rQVvP6%tZT?Y<7nGouoP`y9yf&#}X@|LlU zvTb>wsYv5XynL71HvU{&MW(~nFp)bafjiMu=UD@nBygX3)rr&`p}!0pDve`LHSm-; z_A$Wx1Z-$V!m1~H-^pFx^VVz&ec(o_$2`ugg#E(d=upW$!I3rFLMPnFG;sKt*w9tB zpUBe&o?~Z?R3E87QyZEeSD9&m2PDDCqB!^&z;_c~8t0_eD9j_30I!IHX9DK8W<#qI zI2KH|90$yA&4$**!TF;xaw`K~8wXznm}|C$Znoj<{{Vi5@U7mU&|^tk zwlm=Kgl+SD8ryeeZNWsKBHi&gPCWc!vskk3q{t>i_-|PPzMX4qf7&*gg!HIrH9@c0 z7WzAWFJBLwYqo`Q61~x)`5yrvoB=%7!?E;MvHm!5sCr_sUsPnFf%6iB{fc#v0P~y0 zp?Y!bCM6!+D2}}VFhA!XIxq3G`RaXRYgg80cVE+qo`>!>%j&+lhR~xdK}B9Pww|^v z=)OqxNqS|oQ1NL5y^pUjglozr*fo95Q0JURwW@n&saN9Ma#<=;VhHn2BUlxG$gr+W z3?}U`C+e^sxHWKnbrUWxL+ef>SZ=NZi)*%pc9mP0io9(IyUV&!k;2Qp%zMh(q#`PE z3kccS@V>WP?_u4=rwr?%e`neK+;58K^~v)2R%h=p)TjQPsv^G{*0J(gR)2M!>XrSh zO_gq!jc(DyhV@4IEUSi1r+E(F{dX!p6mD1_md~<_{jfDpGj{o*)y?s=!v5lRykGKUp5C76;!4 zm}|C$&Z@w#!WedVrd~uOR7)PddUa&qdDRRLtha1Iqgtmn_yMsRzo<)CX}tnPlna1T$YM-nB|qz+9p^PSq(y?TBykRHo>aM zSBB8uCX}s6rz<@-9m{2@$jye(*(O*OISIlZjDS!#n_yMsB0PW*LLZw@wjw(Xt6#Y+ z75Uo``r8DnA_K0{i>-xy{_^I~WyW^3ZS#+3 zkM+J`&G~nh92wr>an4+?#HBW$EyLx3u`RQ0L5Z66reUr4ca~RJqj`AHTOZ9kSi!oy z%$^IFYqo_Bc@vS!c?%HNYztw{w%{5vtNFEh&9=}{aiDLXa#jH4nr)$HDuj7ws!PlH z0q~fHfd8X?sGL6Y^_p#=4?QI7AP}zE7Wzya>YQ2O1-RZNno+S3J)y6cvx*IxS&{e2 zUg1Z9a?Q3-)rxjaYcEvlb;4)KQ)Q352q@QV3)P7ue+HOqwuK68a@R$A&9)HMYzz7z zXB%Ly*%oSI!&%N^JX;{#()KYDDA#NYo$rz5&OPfXz%LQLpdtaUf%TVoXuFEMao2Uu z;&*SjW?QJE&Hd4!U2JaAQrz@32e-S;Jz&sYHaBybUb8KvUx0Z#trY0>E#P5{SK%@T zS>~-Fqu=Q*W8`f-- z_HznTIhogaFxG7IVQ-POO~!^b+X9V|LcUZGcY;t{&v&g_$v(1M+cgd^0 zELgKGu<141R>O8Kp8kYBu1H7PE^W>F+L%5mWAYBju50v~ZK2Q0w{M00vO>82(X#s& zL@Kx9^?J>=&|ekxsLq`TgpoBNH%TLB9zBf5mZ9(6>JtGcD^KrVvHGi^rYTv|Ep$i7 zIg2y1%Iq`?moj|9q_RE$q5WF;^4=g#2Fi!$NnY)r#G}xL9q>eMoz$*I6!wnL9ql9- zz*)V49w>+D6&Em7%hFr$P;D_bc?qxM07aro^@@oHAk$K-IHx}^m8Fb+LCLAL9OobN z=g6bX{}TSewH_&^W;iLYqHX+oW9pA?k}Nrt+7RFWPvEIRt7m&^xDv6*PbixYu2P#h znE*6Z+cf_i!^be-C#+fSptSsuR&YHq1U#t(B-jzY7HmSd8fYfNqyVlv7u{Z zu_LQN;AK|ohmO9?;s6Vit0J!&+t;>@J4$=dti0Pj4?q4p%Pw)M;s0*)W%`IbZft+s zwxC4KO5f#`nBZDQZ2_e815uGM9%xJS6l5Hf8-U(=^5@|z*#*aZKu_1tv2 z!z(ART$YNg27&ipsSRy{RgrfMp@mJbDpGH^=iz*tP_`ocDT0*Kpn`fcY1^YHo>Y$u^|ky31usC#IR!JvQ#9pN8ehdUS<=lij)|_6q{gGI5!v>pBwjvA`mvU|?m!%>vfxvsO z)Lk~gsz||Jk8qDouqrag5DwXdvK4vDunw2Y!l|YCK5PbZvkaSleKGMTJdcy{l8oO6 zybjr!^HIA`ks5?l#@~+9;OJp|6%2rr@mIUwjo}~1O+RH6<>2k6+tJH|6=jmrD;Ujn zoV4^aj23d7n(1MqB{)vI^oY?C9cQkSewI-yKy}mW8?_?Tg!JY{#T(eUN$G8jS_x`e zdMBe+hFUYdr%{ukwoC7C)D);FX}Hl-9cQ1Dewk6LI8KlBsYW})aTd7g*FYW44#`04 zlG!5*fjAlIPWnn?%5=~t>x>p=pKLZ-7G4;q?|?RnP9nz1E+9@uH7ETZW6GwJ`;3-D zCl4DfmmT|<(Xi}WTKZ9=RY%9BJOgbS_GrenPEyK$phP}_GT%u{`N${>oJh*oP!_!p z%R=P&)hLUc+9?U095snGTLNyzBz zRBwWWs$NK2^{&{uDrF$VYUW(#v`e`J3QuDh%bjj1B}Q4{^u1~plzdiqwUaU*>GjOA z&KZ=l(y-P$v6Rh5xxpEqvKz{cq-}5}ryMYrjm{M*M~$+{nHzZ-%5V73XzZ|aoXlI0 zM@9ZJ@Yx=G2jDOnDw5Y35uEtXXmYx(r?E9HYtxytCxdVUGdIIY-g0^~uw%qqINUF$ z9xogC91oT(WT?o0VXN5%Sz5+rsS8NpR;Op_3ELEAInODOQpDXO(&Q_Eucz&N&n7+5 zYcrrjgfGzN=E!4E-X?IN^ZfwqO5F;%C5W5={wHm1os(s3S36yScfbh7m-jidNIsRF z47e*zT}_89`T(bC@mH0TPeylR_yaCgWH89Q$j<2DEJww?^0jRmY&X(bFMUlI=9Qs} z><07-;oc61w%57YZv*1%zl=Vn1X@-0FTksJ1HEq?9;pkgC-IBDD^5LD`U2u2${GFR z;Awz2kv$*|-U8?d;em1RQ-FRV9F42uUj`l&SC#C7?)X(a{xgPnxXQj3>O+Kv`q2AO z(|Z8ABrdn^*71((?Sk5%v?Z)Eq1Mp*{PdE5l z>`9gVCa^z<&oH>`tZb*JBdcg<%rrRnCq7ROoY%n_SH$Cmz{lc0W46Jinli_f0#C@O z;Z&cAgsMIpTcIt50o~qyzflG|Zu%0f5a$5owWA+_LMjq=G1Ketg#Gt6579NluMkpg>OLF z&oURNmLDQrkCn+B>0};aZyCv6nfK6e|l>mBx=3YT-X~+WDXJ5L?ZIwV*DLc0{M^ zdo-fDSp_`-m(n!zG}D!UH_|jmW+|Pa!!1A_Bsy0LuXP0JU#TyWz7tk>Jqs9z%BgFP zBw$P=UWBitI+?3lP*YB0>Y3}@%>Cr?WTP%lCbWU`l6%HyXd6vxP6p5mXxR*lWl$4( z1D!z2;zMBOPepPQ)g^3)v^)F=UCeb7w*yD%w-oL~Vr?SKx2nRsk>J5WFNjLTz`i9Oqk0?Ndm@wDp4o;5^%KlY4;mK%Ge7XJA=wEZngg%d&VyLm)NshI`Cu9q;txTJ!=G_jy+>F z!_AlE6g)rn ztTX!H^w=|cwPMet5UETMdnQ?M_4j1KZ+&wd7nhaFeO%dPgjqOs~Rs#QsS%b}sJ>yQ)K2@X{PEP`tBygX3)rl+s%rh5a&usRa z2A&efu3y2AJxl)D_nmwQv)z1{9LAolGn`ooO@yP{{RlXI?Abryc(G@epUA+99z4g+ z8o3=XpDQBv%&xkdx7nT1aW?#G^4_;-fS*fZiPy92H= zZ^pmGo@wY#sJ!@;*fW75Aw0H>i#?P56d4BCi#_`ZgFtskn9WkjSHZm>d-jweK9Z2j zeQz})c^-&ZpEHi zd--nQe(agxnxBwi#h&T?IttJM{3G@(*e@#bpn>xegT0_4shNK4nav(;;6`!m`v7~f zXQy>vX4tc}ODtovyKj_Xb+=ho_uXv>J<1aBY}(j*+P0wkA{}wTAQ4){rxE0A64_=5 z*OW`JYx0Rktn9pHkx7a#<>}+z{rSMzAXWx?x?L7)--qPHTE#L|Rt!W6#PG zEH}4+<;9*^`#=cXsK|GQu)AzIDuNaCbml!}ZBh{xc?<+E_N+YbVco^G5S=Ehhstj- zS$029HT);b=Ubh9#8995cdCk{<#-i1RzAz>ui=LJtWA|}myK@G3x@SZ`7Eo37v_3p zzx(f06}ii>J}jSQ)i4*YV)!}+v1dfR>3C6@J}d^qi#_8NwKZw$Nh$jn2!8CD%pcr? zDpIq$AA81DnA6`Zz+UW`4Zj4~i#>Z1xefb#y!()tuv!(YI{N!rMQ$*JdN#rDHeJWa zM}}3uT$YNo#;Xl4_RK1W6QSo}E(l)inMJTF^1dOQQ*IHSn}#(#H?7KLsmMG-Xl)a$ ziaZBGqgvQ&=i3CUBIm;>g!VR}Y>%uqtd8ZfROEX@=xh_LiuB6!W6$O(v&ZB>_1gM? zA@s35l&wgWe9uk4a#@J5HH7{)!K%p9An?5eV$aI2NLv_%Fx)1Tt;iW+mVOS>itQ?l+Gbj4S@J;NQ@Yyni)E9Uqn%J{4zBFs2VVT&oa#-HL z`U2Fr*fUa9cHjC|?3rA!x>V$ZbK zsX*SqKV#1X$@&hO9ebvWi8k_M&z7Tx9(TV%Gb{4eRNuShBsC6V&#aox1nkA0(WgiL z9H@ysv&aL^_G8a1@)4jpO;B6Jo(1HbI)F^$k-5j7T9#`+1PV~*fX)o^+C>i21e|e4}0!LoEOBN1vVXf_91Lu>=_*edrxKc zKuDUHKB*XQ(hbYn2K#ULN9Qoz?4HNH4y6>=l)>x~`1^V_S@saTBc)%Ebhfj6$Xl@Hj;{N>Z5SKA|m``5ATvJ#! zD!&Bi4YV97YuN;p^LXMhKJO2IO2@L1XTkZ;!_21)iSJPti^@L*kXJd0AH~ykjq=aF z5I1c2PyF&LdXtUiax_f5UQGP1T=QC(c>|aDTVR&5*&LOB6y_i4{8V$?kc7EWd93;$ z1P|o9ZIx<;|HQwg`C`xN2w(<5y_mdDwd~jfj}oKUt05)g&g?n=De?b`xa)yIC=qwe zB@a^nJ>qTvxK_j+)$m|qktb0$AITx&ZZrVAyYX#7#GPRBIFi9aR>YleP?6-Ge#G7O zTwa!qr~l-ANc$0Ybm2$bU5pG~#GREPvH`Fcac9FH0OqeUQ>QsLT&I^GareyML87u#NEdj=ep~3fK>7y=rTXz?lus;h`X}H$d|D383`ip0vmp|*T;{zv*8(l zy@)&RA#ZPGKMdH9xRaeLJ3KqPuN84;;WL2y5qE-f5UI$cz`cmO$Eq9m;qQ5L`{8CP znMbL->|n%Q#eROo9ghvG6TDEdz94Yo@gwfod0}!@WR0(~iHJL^%h)`RFw77#Z2}K| zkFebka%_Ts*m|sQ4J)r)mWs3*;6=hUvQCX}s6=0LBU4&|~` zWH<=Cp+v-8`8~4F5C+%;t0GR3=V6ddC|i+%h7~K9r6RjP*n^u&MBJ5Mk^dUP6q{gG zq({{AFvBL4t;o%WbxpY}+#7@7MckENkuHNg!fM-tRgs$vVS`O5Talj)>y~m^D$--H zA8}WHMYbBkJ+=p{A}0;ukWDCCk)A`mat@cv!l~s}Fj^kw=0|M$$t&xDINPRWT|Zz9 zWM>|&O=lrB4ymk-Np3@$v({za$m!!2PFMNMfbb-kwf+w1mgV9-2lra%0i^ce6?oNtt_roDjLGu|kg6BC^Bt0^c5yS0Fq5Zt)oS<{v8)%s zU=yo$b6*A^Ol`s^Qoe#Q;?8lBBxtA|PJlP2A!rf#Qqub(7^(tdS3X5-|D+5ot_sv~ zS2!s-#`2k)lu`@I>`c%;chjmig5qvQ#LU7XkgJJ$i>HQ{5lg0jc}MFmax`I=AuLB} zDtQ5ll5>N*%+U__*o5#pal`t`rH{MNsoH|Yp7dBsXZqD-+Csj@ezURgE*c_*$jk0= z|8VXFpsOCXG9|elc7Na~&Bi=OQ;eew*K#D8vUkD8D^<6N$;h^bud2ufvq5sAcb7Vm zx4`66N%vfL0w_-A!&1wfe)ts#-e9?f?)}K*b#QWxs#x<4cf5|f%8B$doHp(|!jY`W zwZW0=Fn6^RSqhHC_FQ25i9BlH3+=3tlYsfF2DiQ2I4LN#K0L}BQg@9LX@ngioK9{( z;pkG&21nkIy4O1qp6+=a=61FHL~b&04?AmwA3x!BpxZmHGRZhNcpd2Wi-S7==Ea;l zAkN8EfO#?JM&sZEfcf(Ycc{xfV7m8f!2I5Zdr2Hz7spFcD&Uc>K4A6ExCAh-@!Zii zJ9`yierUrTWA9{@{U~t0!F0!ZxQd(v#OpqHoV&b|>DaIy|Bn}8WK`ikUE)OQ4fKfP zT@DsqUrme*g^kyQ?q#Pri7Yg>38&}V2OF;!-4ZLGihOS1%dIRbQUlfD4>#NyaqNKx zo*lT%k+~)+Aj?Df8X}$<_mzo}vBO<#Mg31J6Zt$1DRM}I2 z^Wzlm7QZLA0pcqwcdIp^!yNzm=!$%42-{90h||c~gFFwnpGF7{(#Q<3_%g~pUY3O) z2pHS*Wo=Rsm0fYLj+S&^GWE{B5D;IdyKk5#%HGc|G5DJ{uG^A*GmO0GcHcHe&NM1= z95^3Ox*yr&G{+r+2r~S;Ke{p@>v5CQ3(&QM|J1O`S`Cd)wA@oNpk>bS$S=ZFc__$# z#rdcXNZ@}gSl2RVC~V7_rE$nEcAbIGwqTtl>lkbmh9OJS5T`etjVB+Kl>t~x%|qO) zx^DNSaN@i(!@H?;S2{WU!MlepT6pgN!>-9XZs2o5^rt=36c+b6jfOjFJpSF5UN*vF z^9a*nJWfI@kH9YX9vZ!EZ0FiG{S2zvC74q1?-p8)Rn8JXpAjAw(oNZb*)ANvQ8^Vx zVEG;VyD^U?gCi#jXfxqUHLP;(hV~1Qk~m_en4@~*-<@j1SusHTX|j8B=wcie(iynO zG3eG1Ptp2}ll3alDkI@ydng)kBR~Y*85%}Zj^msGKv$BxTenr^tcUgik-Oqr|0^Iq z=X3A#U^&m`v>Szk0T1Wg2R&GZb?#EYeE8)a@tT|aG7vuea*vq~$R6!^JZ^dPcF#Ox zd&{=z-SZ`EQsjG9kzT&OV?5g@woUR?OuQe)B==({sU$q7PxrgJacz7(9eZ{}KKGf~j%8u$@3m&{tDao9bu)a!0r%)1+%4eEUEB4fc zUtx^6vqC8;mwFXghELC>L*dYMmxq#4B2d1X2W3SlErWb_b|~|E08%r3WY2fL;y{eahi`B{q+6}P-3raycpGXOd)2NP7t$!0t z(`dTJgQY^eBvA#&VcSF7TKwV!*^=Nad=`?b0a~{8Y@(($EK)V_L$>#+( zFpYEu_O!~`M`JPm>jng?gDh@XdMK+g$X78#FNdW`YbtcavxM-@1#p;k8*Ev4@0mQ( znH6XE2stBRe29e8N|Y|OOVoW_C-Du?lTt>?v2z2;l0t7pqVDx!lv%e+7PbY+6A^{q z3HN1-{s!t~j^Z9G=ws03XMyEpjuUhpP`5L3_tA*1 z`X)G+st@B{)fw}8o2qxu|H9aZbN^-zlB)MNRqxU4+{;n*{!%wxbru~q-CYW+lau9F zU5?DG12~APs+Kpx*zzuJp5o?LY-%Pnnt~OXa$ETma}w*a1g$9?2FsAD7%N>=o_TVR z+rE%b6a?;?RLExtlJ1sP$VUj@<$&Hj(r_%Y=Jw94$kS*FHY$G_5T1l``|z^OvS@BU zK~yuzI8d9bGGpE=I zRsKr`ydub7D{Z>IrOCb0YeYW)ytB@|iaqHy;(CC*fzF-FL)HUd1IU~0+-ogn_6*$2 z;y-th1x^9*Fu`RO_zVEvzUE$cIN~?=!YFnjj^Nx2zd2gG$I&hW0!hmanOtqc|$b0+TwR+F9KB`uQEA*Xx?mFEGwYmUUi2vO6 znnn+*)@mTUoz1<$M&B^p4H~^DN^aIHkGs)E`vJWH|G75{s%mY8!aL#IEgtX*0N#-0 zZq@m81?ykwp|=KTSXb(Dn2z8-_dadnfKjzxH|PTa8kQ^HT7{V7B*TN2DI*W_UahS# z@m?qQ;lQM7eQ(gi0qXf0c9oamam%EAJp&WZF}X*ziHDQQcdyoWxVcXS1F1gNC6{aX z+-E`oS6{=|-*0R$*fwbit|@C@gXhHdDVI~1b;^Aw7w4XW!C={^+%H*`f-MI1PPyL+ z`Uy~d%I%72$H~;(26H@g{Ww82_j01vDff5r@FY-u%KZzv6Be|7&RpFcJmu17*yS*3 zJQ8r+DVGh96RD8oluL*wrCY$|iB$A<)`>JYDd`g_3HFKfZI%~zA{9iRjoyV(oY9ZGF zn{kiP;)1hKlvDU$;5_x$YO9+5W76G{+pnFcsFbAf)nc;42VlBf@pgO9-o2W=O zI>@ONEjR=Ue{N7~U*K2M3O<7=3m3Ds?k($~pa$TJXgY9Ou0eqL#In}Gpm(%GjIhNp zIyECn(@=vKk@hbMD)EiRTR*sC13|X$n5{;Sx(kqvdZmTbyVqUk>9s}g zR(FT!%@fZPy-R9hFG<|#_+z3qy>d6z*yprnQQRRl_ByTk`&ITyjk_F`_XGTlM%KIq zH50Z#rscIys(%I+GC{g&rA3aSk~c(!nr1=aM3Xl(Dbz3zN?wP|!yF~eMCl|-m~^Gh z-8AwfIU4D$k!OkIw}lH{!{qgO4Z3aFW-NUJi+HJ(u-H*E@t=3G@KwWWsSMDH%6kNz zxs?bS^A}`IG-ggst1(o{G$!IV<_o(qRKleDjS=Kqa!g|c`H4vWSX|@j#+-tlX<1%0 zmcD^Sywo~(soxm#{lIrX)@H9MEGEAy81J(Ns>_MxI98B2iH$RH zA{cMrzrk1fgCrsRD^;>@q-80>H7&R^U3MS5b z^)Coas^Dzgg>fdUf1!;|F=*QW^=7hzylq>F4DEQ}IGNwDTpZLDfpKnFfckT8z_Hd2 zU-@u2D=c(4B`kDgK4_lUmDCzt^EQGy6zPJV9Gv%03n&2B9FB+vOzR~f9 zQJOjDUi<-+IxG2JSn8IUEdBcf(2m!^vPOR#f~fan?OuTSafmvbv?)z8To3eJX1F;A zx+8AFtZ`VrP*Lz1Y+Y8te(S+}-+lzi@NXX@?&G=l(YXzJ{DrXO-Z0l$++ZNm3^sG> zEGg)RjQg2+rXTY1xSCQ`}AitbjyYTxs~YsO>6ty28@kk z7@bpRQNb=)za`^Qi&1bA$hm8PK53&D0$D)xcu}9aMLi@`>uJC&p1FGO%zrV#sAmRUdF!Sh+V+ucKf-zw|2##a9i&O^Go3I-P_Xo6*aL9(Uw*dNxa0PrOLWZ!E zp8W-|voR^wsbp{&q}i>2T}?d2;C{8#V&_^|_{Eeu{D4oI>+(?6UilFMJSlh@gi0+y zsOrc;;HHHvlDLv`mN0TWgH1Gd&1VLwZM5ynlc7-w$}+cmT!jtz4U+L;vCt%1G7SqRoqGHW_A zQr)yl0TU%X4_n1eu-7v7%5nBo*m}}l+t`x>dzdcaWFQD@Nvdb6lVXwT4l>ir66Z#+ z-XOEUxJ$K|;!fq&!b#->NOfno{0btk1{|D1qF(L1HZWDV5f2_PM>CyJ1H zqnA3p8li0&71APSR>*Ul0qsDQIlJ)yq#8W$WR|dIgRoH-k0SJ<%&+t-CRI;}ueh3c zIf(_AgUF+^!RvfCYn$rtf{FK#4c_u#GCU{mdeCff@{Muwp5;WFYTx9jV*EGwlqRo^ z3nkYKWBSrEtryb^#`K+K+AXFUn>~j=S|*+>RY8Aa`pGgqD7h9J)6bS^rsR6am`++I zIbsXGH>O`K(@~rURYCsEUNwHTOuSB41yN)A%`!3ENEIwMrr#|S$Ac<(%$WYLOplA{ zXJh)WWqMjn^|pA`_|r1ID5jytbjmWlE~Zt+^p|DYz#2xLG^PrUWs^Y_3EzT+>G9tn z-M0PN0QrKeg9cAVdV{l+ybPQ79*Wkd<;W@+kCBjR5me-PK#5xcS96LQn!#e7pBp?K zNrrg{DcM%eFxmLJg0bb=wp(D6v%LyV?hT%)Du+T1Ot?H~@I{e?yO2B0Y4Bmn0VFt{ z8q~q9^@C7&A=>~iBC3(npgvwh{sAORSXDhttbvEAszTv6T7~jADUqi^kwdJJlZ1)T zwk>li-s-69hN1(Tcwb|}XG1Z*R9+NEdv6%)VQP@?;9U%5W5$5c=~F`s+VRAEE*PEA zoQ(V3B`J%cY=V!BL+8d$#c;sE+^69F%ao)4Hd!MeF7Y7dn zET68rHV(cX@R4q);`})H1;Fy@s)cb?%-G?ef0=ph?C(3DSKX; zgikaA-bvFcmmO=mYPW&cc(8N;8TjNrZ1T;jbuL|-ENyP{;2S(xvgqS#9c=P_s*Ub& z$s)E<;_i9a@S;&=+~iI;+jp1jUyNsrcOz%OE}WY^j^rm@MS8*}A6(n&>I-MF$)!VN z9c-`B_jXwcPFFR|eERz*k#}Isz8!?ytiru-qew5_;kvq~vTJ}QpYYn_LHb0LJp(v@ zo075D;B2DGzR%$I7<`=ICxP>%ld<36n%`oV_wB9w3@&}A@?JZPbyRVO8$Q2I;wq4w zv?r2e9&U%*6&}Y&$(nx*%Wh-& z1j>U(`3lMtM)?{QebFf2!19(+euDCWQBK13_fXVexcaS?M-W_;{K>by%kAeON^*6P?4SJ`8(BIPfr_fhX|5WR>cRT7$>YsV}q1U?~ z`sZ4|1NuzrUx=Cw^3=w;lh`4L5h`YCl*n5YFdk%=Ww@~u!e@wIk&x$zs9})MT5OL^h5fA(- z;vt8-qxHinA|9zG;?X=2hZ~D{yrYPty+u4Rn4*0j*|+Wc7P3X{`xS|}_;L~b7mFCM zO~k-MB8pxW5&cfYpoHPfH@Jp~AuUA=?JHtfsfgiAMO<==h!GEnh`lOe6 zBCZ-D;_As1UC(`OJ9?t)d5c6lpRsNodvw{b31E+I(mg$T+$CDifjmfh^w}enz7L7$ z_p*qKzZTKoi81?tGerz+EuyHKi0EL7-rYN|gqPkuhKlHUxrkm@i|wN8MfAR1M4yL6 z^nF=Gzt2Qm{HKWiX(Q=uKphbS&lgeDM?`dth(WVN3|=c@$PN)h9}qF@1rftPp%`$j z9Q_04OKS%#kY)~8DD@n$=og_Zo;sS$C96a%-6>+(5fRJZ6S3ki5i7%E$h@wJh*dpA ztR5<2%?uIOuMn|zn}~IXM67>C#0?*a*zk*pjcH@)Y*SqkH?|RRQ&hy}DI#uW^jgOO zTXu=KhHAU=bCE~VzB6gODxP6g`U0X%m@t}y^uZg(xXAyfU zjiZ;lazxzSRK(t%BKBP>;+}aT?%gb6|NSBkyd&biZ$upYOT_(=@pN|RToDfp67k?v z5f5z?@yH`09(`KGWABT2{09+7oXeQ~Xf=pVLk2kYMGkb@iX7n_yb-^h9};sO7dgt| zyw_>SSZAQv$2sFfUgpdaS?nwqInmiBveY>s@^a@Xk<*+vMb31-5;@B`CGsk#$^`nI zc#ucRBM#?snFT+~eFX@^0q=k^7wIMBd|kB=Ugsx5$GI z_i#i9F&g7x{#9v&g5My&|7>9vAtn^Qy?>&Zi=u zcYYK3l2d6S%X!7g75SReT;%Iccad*8F_CXOSBZSrxlZK!&Q_5pocl$7?Psv^I13PgV8v=#Za(@*3#&S;U}I@3jd=PVZay|YQ=56+z;e{_zB z{K9zB2PMQDa-lA35)#IX(;kHr-R7fodF{Ma4r@3U*`&ur<`RX|8h2q{M)%( zg?(-tga6b^4=Kd%$-3?t%{~2zU$V|7M$gq2!$Sk*~$g1vek=0yAE_E6bap#H5 zb~lR5arcVMbs4hMX~>!GMttdvcNZE;3Z%M;(*N=jaW0IeU1%+EQ86)$ z98TI%$G_vNJEsYHBt5v}a~!9qf0y@y(a4{Fz*ZlI1m5h z3bH`Kyc1a|8UqiYrLFO`3o$3HrzSrx@B^Dwn{JnDhk82P1j-5g*ZP|K3NEgo!&+b0 zTq->x4z(sOq?(-aSWUcv{{y1tz4)0)HF-wrPkq-pO$5zAy;P6YUXd~lmbQYW6#wI! zcynjk7F$cY5i{xdCcmKqxJ+#Cs2yHzyna#R&q-hHpw*uM4*H*sbUGsg8mTq~Q*_r{A-PJCV?X{U%-{|}*Tm{$c=%f1 z$!A!$cIW#x@hCq~VZLF&ah&`EN6x61{nFMr`E3rMh4>%!8fz71Wl;09sk#nhqz*U0 zo_HV1DQ($V>M&XAP-}(9j9^J7X#cm;-}FjvgsM0bo8OPPZ2T7& zd!WORE55*IyCe=kvdc*oZYND6PQ*9Ea z>z-dAJ^$JvyoP?jQ6&TI-Y6Mp_lDNQHKT_l@c|0M{$7Br&V)LC-{ju~pzed%lLb<* zfA5&g1sDin+Jg-}-h|9GC-sv;^e;C+;e1=juu<|S4OWE=3zhVcw1zi@fep(nroYJ? zT^bp#kt+jaq#&Moj5c#P>M@!BIZEc6nMuWS09yWX>OG_%Lr*GnHB15qR>2J2m8ckY z?PXy7iT~1etQqFnwBuPu3p#IZS4X`B+}j;pN<1IAVg;(yZ1F8hy{ZBwg? zdjCySSEXGMsHgXlYO}+0H%#1he*|$d_%9ivtF$Ke3$hz+RZXXw(Siz+DSNk#nyH(I zCuykK*YFd46b-t__T_7R=}T+k>j>1qscAKK@JaY^CUy&kOwMCiI063?ui$zqNeq+Z zFbgxGYSlZ87hU+Dc$shEFnI%zGr3w{d8VJlS(G7Ac}(!SWO4+Y@5w2x>(@eF0I2*% zk7J1DptAMY5Nq`1FM#DrS_*s%_VS9WbT`01D*hHYqmJOk{gO}5(tG(e(HOYsM?R`9 zd#=%$=1QgyK)LWJ&X^awoCLXBc}9lnolhsr`P8?Lm-DHw#^ije)yv&gHSeUW{%%PR z#3#F}BAf^E2Z-n3Y|C=|)7T@(ASX6CpS5W;M^`Q;m3sol3QuqfphKJh#&hy58R(rv zYI5?`njae~2^l0^R(QTniLZS4S&aYuy73LI8{bghsvGL7x}jQSxZmG&RZm=99$NLZ zI^#*`1@65#kNw|Tx@4|yX>F-pHDq6d|I&7!^pt&oUxG-%tsuvtfFn?0Tne1!@7 z|25<1|Go1pEdoff4E#Ypx zAhc$31${&@de#rWRlRF3(7AA-$ob=G{K^#n`IYej41Ilzq&b>6fT8jz=A1eC3?Wht zh7C3UbjB+N^kU0rIAb*R$AW%km_HD(%or`$dHUC!96>6NdK1nV&GOfSB$G#Lnsit^ zT)sk=qn0Ku!5KO?8TI%Xzz`%xZEDmDJT3x?wqyG(5~G%@EYzX4)V}IDke4QMX(N#PRM6^uhb6qW z-Okpqu1sXul^k!$G+$@*!zzvXTG1Ccb5Tc3KLuF?wEgSY~L_6TZ}#LocDhEXkYtOE% zH<=UNw3PKwcsj_OhUq|7 z=F&fIj@%CNbNJ7k?!^@pkx;oGHgCbH3SPHoPIe&# z8DF`TRw|BH1g7(dkkYrV_*cqK~JBG(z)O}2+pQyYBcAB6Xr`PS1j ze`IX8|4Zg7&+7<)%)9K&96Ty=j3zk5|(`WPDKuZ`ab?MpL4kjb&0CiCxDV(0DN4-S68L-jzn{~9AL875!hE9 zcw5@u)vaNuq}csBfz-p0-qU@;D9L~nbnFsmGMLxX-TTH}qQ#Wmv&6aCkUlW(Dp(}j z-BB<_`$&#WWvv-o%B*9I$)P%-X^P8CNIW}HeHOjIO$g!<4zjW(&rlecIXM| zi;TL9W;cC>(eHp>GyQs_?uP27Z#3$iP?OTP7!{wl!YZ0OjCvPT_`cKV_fbzuzsKkY zp*!i18ub^bmD8Uv>aS3HRAuWje@8G^SB_+rH?0X4XxqWfW+K%Zz%?%BKaGlTyh{S|EK5QC|WW}>XS5hQ}o}h4}ePM8`pQluGB~w(3n2K)3 zW{~?0eq>m*`FzA|ypfN^wjMr=c})#|3^qyQ!xT&4C&?L1qCg>4G@tnyVpH@XQf^aR zRYkvMN-#~G;-btP9S1PV zhd9w4*tlZg#^uU%(R;XIWK_`+TA7OOV|!nw%9Z4b`0?7J6I7XsG8L5+4@sA+Wfd`p zJ5Ql+OR(#t^Qu{W3!FyNsVC`yi!v0o8UU}jyj0P4ObNzRv=7w^__An}AC4^Ix3XMG zaTBFlL~?W{4J@;WsUoJLqKZ>CDa!L_l;_r>9VAPNnWp%UxT53aNs5~& z4Miu23FRxM=(LDETg09%V$bGP8i>cM7}}AHXcZ*gOl-zY0uZfEH4mG-#@NgRlyG;= zM9PAMorOyvrvgvdr3$y0^c`;Dex$Deusc?WvZ%rwj zWYV{$6)rXDZQ;W0CcQnPqWq#tl%FMtrs6W$WvWO7w&!kkoS#sNJYCRVu19fnVe)8c73FQQmjYTryr?Vxp6A$(*r4 z;WLa!Qt$?h7x|B3x44xPCgP@BwZtPDOy9hU?u$5EeAr5U3mqjddXP?;DiW1HZ7k)c z=tUYN#Z8nqCee?HNs7N3Eaj%?H)4|FCb|tXQs6){yrL#bfom2y)go4L#(d6ywIma*GmZZIOL z-$tDqRm7hWME4Su>5>~2s?Vyqq0taHp}d-p!zCfKg(4~Rp@`^5$l@~CyNH#I{z#Q6 zS0e7_bVA>5;f5!^OHRQM+k}iQ7BL!KE(lfZHUf)zOnAU<0!uiLc)(r)%NY@`f&BXb zJVNj`-%ofVuIp8lUqjA+0;c0M?_@l@+Qn3h>b6RuWl-mz|57Mv((R1~} zx3St(TKN)a*z$6xSxuLyy6pm=HTg+QUMVuA@!GULbn2bW54c zu{UUXNKBHU!7#7yRI~|_t~k%aAy>hPebW#Z(A|O^?02?`{Y+E$a!r5I)JL2Ldo$+Z z2=6d39`%}9nWmocCKXF3+CLukGGx=#HGT(srkXTe6m+HxrC2?p1L9FHLlc^M$D35F zHPN9#FVT(8klz-jV*Ga;8MI!q%g)K40@KYj_X?^`vx@Bi+M%!b6n9d!{5?S5CcjKm zRsKgnt2BmXNLf!+fp!>F)>Cz$J;)y)@OAV1k#Bj?=pdp!%5B65m@cEapSaTXpF-eb zzf_ff0z>H={C9dy+Apm9lK}8jMb+tT3rqqKCV0XE&je6F@G}c+3ZMgAi zgby(~)wa>kfc!+XfrZ9CYmVpOE&blqCz6pr0PWKK_7OOBF+6s{9q8hH`0q85fw8fJ zOqR+yhM}=xZdCqbK#$QfRlv`XTSXa68slQyy=Dk{N>CRhn4DZl1 zNlcB!)SM>C^&w4{(|K4-u`dWr34r{c0GuK?O~!;hl_!RZ!w34juUoqaIOFk}^*PV{D` z^*G4C3cyl=vsp*4qSphsh2XpZjO_x@f0hq~8Q!d7_Y$4Ww04-MMghQe*ua}>CJut! zIPjXn803F}51gY4MNH1$wxDo04OfT!uYxi1dEedHu}7!$?csjaL*tVfZ&KDSRGj zhV>2Hyjn&17$KT~-1=I8^;FStoUWIzU}?C0riGdHHG-tHrCWR+nZ31T6fEPC>f>3m z|I8wUQx|~fI5NV^KnU|3J6=T@b{NZ{ZG2feWfmWs_MFk0#>8{Z+Wm1r6x zTwYN~Kd9ImqIz#gb+ns}L@)I->-jmhh3I8gX*&p9Ue@JqqSFPnxc3rWEimSG^Z$Iv|&PWle9;v|g^v%bGr*>7ZPh zmo>572U3V9|LV2l^c? zdjgBj^9#^CTxJg1A6R6VNi|{(V2aN34=$gQXV=(l+DFQ;XQfnZ z9)VR-L82g~%)m$=V6zA^Z<64Egue z;p-=G3{o#X%p6OD9O1jg#vUntinhBfo9?IQ2zL))Rs0f>kv8%=k$Y_9T_P9R$cIG6 z+Q{cb`q{{LLfxV)e&=xLZQ^hR_M^1wa3EvSE={e~@c)h-z(YvBMk;4H|755|Z zxg#e;%^6JOYa1CwWS*VtG9p*oNGXwpHZq;an~t1?wdbpdoUoAvL=s*9ahxh%LL@=A zkn@cyUPuNvHL~cEYI^EHgpzUc$cz`Mu70knpK8u#USZK0@1TflU=ZP2^o0 zd6CG?0ivH36~9S%lLhNT?*!o|0$3G)LF5M;`JPB?$3N^;@h?OQZRAfPZEeJ93Z!Fz zgmtTv2tOOZs<;Y~t~QcMWQ2`m6DhWlvxscBk=jIFu#tvDehm<>3e5XX4^0=`$ zM8?_36e9g?WEPRAjm#x7)J7H)x!p!q5^-IBk9!@rf$;q{aWj#JY-AgeQXAPtWU7tq zC6aNP`}+u=RR;Eoevr1RWo(%B3Fn*!KSlV?ph(Zj^Mp6(c}MSx*N7Ymh^qKqB46rR zMsq$P@~w@0OJu&C>m-pmHu7I0i)}WwhstL_V^SGl*2s?a{MLn8+)(pBh9e zpVsCEgsYqew<7%CAiviY?Fs)~2KHu|?zFug*i>;JBJbNs5s_O0#G7SC5WdNR^)WP# z@KXV-ic5+7WFfIXo8y*Uzc0(`q+|ARIXB$M@Ky4G)vc+f{P+skH=GX)ho{6uaXPQdWa=$t%HjBVYX^3nr z(;S-C2@s(93xTenWxaq>FTIzFw!B@OzT$ zBWzvC`U35nC4&^x@HGN=c|-9XDvP|Q5T8(4;+LXgUlLdv01ba2u+w`u_ZyVI39ONV zr7O8X%;`B;tr!2pH^f`KaziXDfl1k@-X)podsPCLi;6vl`i)z%8s< z?0hD71h!aP0{VuC-o~rq&P4iK!%;?XtQXrdnkLAX(|p#<~;A!%AHM&PKQ zM~}-cwfpNA+}|LNGx6BVj`|Y+PP5Pl{p4--w1ihgWj?;#t{A75R1Vb3Lu;<6kVU

U`?wha!ljP$g*tb=7ou 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

?!5Gbp_||8^Be5{2g(H08UO$Q literal 273863 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 gE@Z7bwxLi7MJb2!=X6vi1#SKib +/* + Name: mcompile + Copyright: Copyright (C) 2003-2017 SIL International. + Documentation: + Description: + Create Date: 3 Aug 2014 + Modified Date: 3 Aug 2014 + Authors: mcdurdin + Related Files: + Dependencies: + Bugs: + Todo: + Notes: + History: 03 Aug 2014 - mcdurdin - I4353 - V9.0 - mnemonic layout recompiler mixes up deadkey rules + +*/ -//-------------------------- -void fun2(); +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + + +/* +#include "deadkey.h" +#include "mc_kmxfile.h" + +struct KMX_DeadkeyMapping { // I4353 + KMX_WCHAR deadkey, dkid; + UINT shift; + KMX_WORD vk; +}; + +extern std::vector KMX_FDeadkeys; // I4353 + +int run(int argc, std::vector str_argv, char* argv[]); + +PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); + +int KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap); + +void KMX_LogError(const wchar_t* fmt, ...); + +#endif*/ /*MCOMPILE_H*/ + + + +//################################################################################################################################################ +//################################################################################################################################################ + +void fun2(); +void testmyFunctions_S2(); #endif // MCOMPILE_H \ No newline at end of file diff --git a/mac/mcompile/mcompiletest.kmx b/mac/mcompile/mcompiletest.kmx new file mode 100755 index 0000000000000000000000000000000000000000..4f9224998a830a6671c848c8b6b192bdccff877e GIT binary patch literal 526 zcmaix%Su8~6o!AD7$Jgm(P5xC^WXuaX=pQ><)Eo}!AqwT$1d2jG-&GE_yi4lh^FWXLP4n59|ps^ApXfh|`=<7Yfus=L%C2p8j+aCzfIHNPQ|J`c3FNR2R*eE-lff wgUw&;$hI3>cAyzIneEB=eM_C1SWnCztIpgW-OabTVXFVHAgs*~8k=R%4*`ZgvH$=8 literal 0 HcmV?d00001 diff --git a/mac/mcompile/sil_sahu.kmx b/mac/mcompile/sil_sahu.kmx new file mode 100755 index 0000000000000000000000000000000000000000..e5548549a7b9ad70c5cb5f53fa0fd0b5d948a323 GIT binary patch literal 1418 zcmai!%}-NN5XDa)eh@VT{6NHnR3)`8XecX5NQ6?T&>{pXh%O4Hq)@RXP>i^6;gXdL z7j8`y_wL;KCm3V=6IdAI%CIoh-`saKBqnl`!^}B%-nlck?~%QipV294EB>J%R>c0W zT7cz)V53QDut@)|o#SEJPWT4)z(w#2d;;XUF{NeQT5@P zRKI#$)<+)oE>TXXQoGD^RnDmMbj@XJ&VQKmr!-G5W6J2Z@~BDIWrAoOWI26aDe8u( zO8?V&ST#YXBXnxhjL~b3>Ur2*=V&*u?cDOtB|~kV4y8@{SyO=+&Y#f3L$}sLzcp@U ziFtddTg1h9-FY28W0X^K?w*pa?+iB*b$7qY+2Y9}E+xFnoLE7tapo3&x7aPRzsa7> z@;I0Yc7wU#L9h_41aE_EBp_U@OEH+aj$j2yMX!G zdvA47cnqYV9j3A3@B~PcUvi4n2fqn2@J_D{z*Arxe%WiI@Ej<@&v|VMJ_}0l^Ip3T zUjSwJ1+SIh6$9M<2idB^>);uAms6xC@aG_=)| mc|#AIGIX)oLLZwbbh0@@FY7*Zvz{A`Kxf?V-e^R08s#_66QKbB literal 0 HcmV?d00001 diff --git a/mac/mcompile/u16.cpp b/mac/mcompile/u16.cpp new file mode 100755 index 00000000000..df604cf8c69 --- /dev/null +++ b/mac/mcompile/u16.cpp @@ -0,0 +1,334 @@ +#include "u16.h" + +//#include +//#include +#include +#include +#include + + +std::vector convert_argv_to_Vector_u16str(int argc, char* argv[]) { + std::vector vector_u16; + + // for each arg convert to u16string and push to vector + for (char** arg = argv, i=0; *arg; ++arg,i++) { + std::string S(*arg); + vector_u16.push_back(u16string_from_string(S)); + } + return vector_u16; +} + +std::vector convert_argvW_to_Vector_u16str(int argc, wchar_t* argv[]) { + std::vector vector_u16; + + // for each arg convert to u16string and push to vector + for (wchar_t** arg = argv, i=0; *arg; ++arg,i++) { + std::wstring S(*arg); + vector_u16.push_back(u16string_from_wstring(S)); + } + return vector_u16; +} + +//String <- wstring +std::string string_from_wstring(std::wstring const str) { + std::wstring_convert, wchar_t> converter; + return converter.to_bytes(str); +} + +//wstring <- string +std::wstring wstring_from_string(std::string const str) { + std::wstring_convert, wchar_t> converter; + return converter.from_bytes(str); +} + +// u16String <- wstring +std::u16string u16string_from_wstring(std::wstring const wstr) { + std::string str= string_from_wstring(wstr); + std::u16string str16 = u16string_from_string(str); + return str16; +} + +//u16String <- string +std::u16string u16string_from_string(std::string const str) { + std::wstring_convert, char16_t> converter; + return converter.from_bytes(str); +} + +//string <- u16string +std::string string_from_u16string(std::u16string const str) { + std::wstring_convert, char16_t> converter; + return converter.to_bytes(str); +} +//wstring <- u16string +std::wstring wstring_from_u16string(std::u16string const str16) { + std::string str = string_from_u16string(str16); + std::wstring wstr = wstring_from_string( str); + return wstr; +} + +// often used with c_str() e.g. u16fmt( DEBUGSTORE_MATCH).c_str() +// UTF16 (= const char16_t*) -> UTF8 (= std::string) -> UTF16 ( = std::wstring 16 bit) +std::wstring u16fmt(const KMX_WCHAR * str) { + std::wstring_convert, wchar_t> convert_wstring; + std::wstring_convert, char16_t> convert; + + // UTF16 (= const char16_t*) -> UTF8 (= std::string) -> UTF16 ( = std::wstring 16 bit) + std::string utf8str = convert.to_bytes(str); // UTF16 (= const char16_t*) -> UTF8 (= std::string) + std::wstring wstr = convert_wstring.from_bytes(utf8str); // UTF8 (= std::string) -> UTF16 ( = std::wstring 16 bit) + return wstr; +} + +void u16sprintf(KMX_WCHAR * dst, const size_t sz, const wchar_t* fmt, ...) { + // UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) + wchar_t* wbuf = new wchar_t[sz]; + va_list args; + va_start(args, fmt); + vswprintf(wbuf, sz, fmt, args); + va_end(args); + + std::wstring_convert, wchar_t> convert_wstring; + std::wstring_convert, char16_t> convert; + + // UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) + std::string utf8str = convert_wstring.to_bytes(wbuf); // UTF16 ( = const wchar_t*) -> std::string + std::u16string u16str = convert.from_bytes(utf8str); // std::string -> std::u16string + u16ncpy(dst, u16str.c_str(), sz); // std::u16string.c_str() -> char16_t* + delete[] wbuf; +} + + std::wstring convert_pchar16T_To_wstr(KMX_WCHAR *Name){ + // convert char16_t* -> std::u16string -> std::string -> std::wstring + // char16_t* -> std::u16string + std::u16string u16str(Name); + // std::u16string -> std::string + std::string stri = string_from_u16string(u16str); + // std::string -> std::wstring + std::wstring wstr = wstring_from_string(stri); + return wstr; + } + +long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) +{ + auto s = string_from_u16string(str); + char* t; + long int result = strtol(s.c_str(), &t, base); + if (endptr != nullptr) *endptr = (KMX_WCHAR*)str + (t - s.c_str()); + return result; +} +/* +std::string toHex(int num1) { + if (num1 == 0) + return "0"; + int num = num1; + std::string s = ""; + while (num) { + int temp = num % 16; + if (temp <= 9) + s += (48 + temp); + else + s += (87 + temp); + num = num / 16; + } + reverse(s.begin(), s.end()); + return s; +}*/ + +const KMX_WCHAR * u16ncat(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max) { + KMX_WCHAR* o = dst; + dst = (KMX_WCHAR*) u16chr(dst, 0); + //max -= (dst-o); + while (*src && max > 0) { + *dst++ = *src++; + max--; + } + if(max > 0) + *dst = 0; + return o; +} + +const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name) +{ + const KMX_WCHAR* cp = NULL; + cp = u16rchr(Name, '\\'); + if (cp == NULL) + cp = u16rchr(Name, '/'); + return cp; +} +/* +KMX_CHAR* strrchr_slash(KMX_CHAR* Name) +{ + KMX_CHAR* cp = NULL; + cp = strrchr(Name, '\\'); + if (cp == NULL) + cp = strrchr(Name, '/'); + return cp; +} +*/ +// u16rchr returns last occurence of ch in p; It returns NULL if ch = '\0' and NULL if ch is not found +const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch) { + const KMX_WCHAR* p_end = p + u16len(p) - 1; + + if (ch == '\0') return p_end + 1; + while (p_end >= p) { + if (*p_end == ch) return p_end; + p_end--; + } + return NULL; +} + +const KMX_WCHAR * u16chr(const KMX_WCHAR *p, KMX_WCHAR ch) { + while (*p) { + if (*p == ch) return p; + p++; + } + return ch == 0 ? p : NULL; +} + +const KMX_WCHAR * u16cpy(KMX_WCHAR *dst, const KMX_WCHAR *src) { + KMX_WCHAR *o = dst; + while (*src) { + *dst++ = *src++; + } + *dst = 0; + return o; +} + +const KMX_WCHAR * u16ncpy(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max) { + KMX_WCHAR *o = dst; + while (*src && max > 0) { + *dst++ = *src++; + max--; + } + while(max > 0) { + *dst++ = 0; + max--; + } + return o; +} + +size_t u16len(const KMX_WCHAR *p) { + int i = 0; + while (*p) { + p++; + i++; + } + return i; +} + +int u16cmp(const KMX_WCHAR *p, const KMX_WCHAR *q) { + while (*p && *q) { + if (*p != *q) return *p - *q; + p++; + q++; + } + return *p - *q; +} + +int u16nicmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count) { + while (*p && *q && count) { + if (toupper(*p) != toupper(*q)) return *p - *q; + p++; + q++; + count--; + } + if (count) + return *p - *q; + return 0; +} + +int u16icmp(const KMX_WCHAR *p, const KMX_WCHAR *q) { + while (*p && *q) { + if (toupper(*p) != toupper(*q)) return *p - *q; + p++; + q++; + } + return *p - *q; +} + +int u16ncmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count) { + while (*p && *q && count) { + if (*p != *q) return *p - *q; + p++; + q++; + count--; + } + if (count) + return *p - *q; + return 0; +} + +KMX_WCHAR * u16tok(KMX_WCHAR *p, KMX_WCHAR ch, KMX_WCHAR **ctx) { + if (!p) { + p = *ctx; + if (!p) return NULL; + } + + KMX_WCHAR *q = p; + while (*q && *q != ch) { + q++; + } + if (*q) { + *q = 0; + q++; + while (*q == ch) q++; + *ctx = q; + } + else { + *ctx = NULL; + } + return p; +} + +KMX_WCHAR * u16tok(KMX_WCHAR* p, KMX_WCHAR* delim, KMX_WCHAR** ctx) { + if (!p) { + p = *ctx; + if (!p) return NULL; + } + + KMX_WCHAR * q = p; + while (*q && !u16chr(delim, *q)) { + q++; + } + if (*q) { + *q = 0; + q++; + while (u16chr(delim, *q)) q++; + *ctx = q; + } + else { + *ctx = NULL; + } + return p; +} + +double u16tof( KMX_WCHAR* str) +{ + double val = 0; + int offsetdot=0; + char digit; + + PKMX_WCHAR q = (PKMX_WCHAR)u16chr(str, '.'); + size_t pos_dot = q-str ; + + if (pos_dot < 0) + pos_dot = u16len(str); + + for (size_t i = 0; i < u16len(str); i++) + { + digit = static_cast(towupper(*str)); + + if (i > pos_dot - 1) + offsetdot = 1; + + if (digit != '.') + val =val+ ((int(digit)) - 48) * pow(10, (pos_dot - 1- i + offsetdot)); + + str++; + } + return val; +} + + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ diff --git a/mac/mcompile/u16.h b/mac/mcompile/u16.h new file mode 100755 index 00000000000..7f18e03ec15 --- /dev/null +++ b/mac/mcompile/u16.h @@ -0,0 +1,53 @@ +#ifndef U16_H +#define U16_H + +#include +#include +#include +#include +#include +#include "km_types.h" + +std::vector convert_argvW_to_Vector_u16str(int argc, wchar_t* argv[]); +std::vector convert_argv_to_Vector_u16str(int argc, char* argv[]); + +std::string string_from_wstring(std::wstring const str); +std::wstring wstring_from_string(std::string const str); +std::wstring wstring_from_u16string(std::u16string const str16); +std::u16string u16string_from_string(std::string const str); +std::u16string u16string_from_wstring(std::wstring const wstr); +std::string string_from_u16string(std::u16string const str); + +std::wstring u16fmt(const KMX_WCHAR * str); +void u16sprintf(KMX_WCHAR * dst, const size_t sz, const wchar_t* fmt, ...); + +std::wstring convert_pchar16T_To_wstr(KMX_WCHAR *Name); + +size_t u16len(const KMX_WCHAR *p); +int u16cmp(const KMX_WCHAR *p, const KMX_WCHAR *q); +int u16icmp(const KMX_WCHAR *p, const KMX_WCHAR *q); +int u16ncmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count); +int u16nicmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count); +const KMX_WCHAR * u16ncpy(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max); +const KMX_WCHAR * u16cpy(KMX_WCHAR *dst, const KMX_WCHAR *src); +const KMX_WCHAR * u16rchr(const KMX_WCHAR *p, KMX_WCHAR ch); +const KMX_WCHAR * u16chr(const KMX_WCHAR *p, KMX_WCHAR ch); +const KMX_WCHAR * u16ncat(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max); +KMX_WCHAR * u16tok(KMX_WCHAR *p, KMX_WCHAR ch, KMX_WCHAR **ctx); +KMX_WCHAR * u16tok(KMX_WCHAR* p, KMX_WCHAR* ch, KMX_WCHAR** ctx); +long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base); +double u16tof( KMX_WCHAR* str); + +KMX_CHAR* strrchr_slash(KMX_CHAR* Name); +const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name); + +std::string toHex(int num1); + + +#endif /* U16_H */ + + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + From d6583f60d8ffc1728f2486c095be7024827e8415 Mon Sep 17 00:00:00 2001 From: SabinePlay <166697246+SabinePlay@users.noreply.github.com> Date: Thu, 18 Apr 2024 17:37:12 +0200 Subject: [PATCH 04/71] feat(mac): #ifndefs out to be used --- mac/mcompile/kmx_file.h | 11 ++++++----- mac/mcompile/mc_import_rules.h | 11 ++++++----- mac/mcompile/mc_kmxfile.h | 12 ++++++------ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/mac/mcompile/kmx_file.h b/mac/mcompile/kmx_file.h index e18b0022602..66dadedcad4 100755 --- a/mac/mcompile/kmx_file.h +++ b/mac/mcompile/kmx_file.h @@ -1,4 +1,8 @@ +#pragma once +#ifndef KMX_FILE_H +#define KMX_FILE_H + //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ @@ -8,9 +12,6 @@ Authors: mcdurdin */ /* -#pragma once -#ifndef KMX_FILE_H -#define KMX_FILE_H #define UNREFERENCED_PARAMETER(P) (P) #define TRUNCATE ((size_t)-1) @@ -389,5 +390,5 @@ static_assert(sizeof(KMX_COMP_KEYBOARD) == KEYBOARDFILEHEADER_SIZE, "COMP_KEYBOA } // namespace kmx } // namespace kbp } // namespace km -#endif -#endif*/ /*KMX_FILE_H*/ +#endif*/ +#endif //KMX_FILE_H diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h index 161ddfcd6fc..29968d3fb05 100755 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -1,11 +1,12 @@ +#pragma once +#ifndef MC_IMPORT_RULES_H +#define MC_IMPORT_RULES_H //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ /* -#pragma once -#ifndef MC_IMPORT_RULES_H -#define MC_IMPORT_RULES_H + class DeadKey { private: @@ -38,5 +39,5 @@ class DeadKey { bool KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter); }; - -# endif *//*MC_IMPORT_RULES_H*/ +*/ +# endif //MC_IMPORT_RULES_H diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index 0246b3baaa5..a380ed339c8 100755 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -9,6 +9,9 @@ #include "filesystem.h" #include "mcompile.h" + +#ifndef _KMXFILE_H +#define _KMXFILE_H //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ @@ -16,9 +19,6 @@ /* -#ifndef _KMXFILE_H -#define _KMXFILE_H - typedef struct KMX_tagSTORE { KMX_DWORD dwSystemID; @@ -84,7 +84,7 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD *lpKeyboard); KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename); KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug); - -#endif // _KMXFILE_H */ -#endif /*MC_KMXFILE_H*/ +#endif // _KMXFILE_H + +#endif //MC_KMXFILE_H From b1caaa68ae98f454f1e5d5a40a2229f1c35d6f22 Mon Sep 17 00:00:00 2001 From: SabinePlay <166697246+SabinePlay@users.noreply.github.com> Date: Fri, 19 Apr 2024 09:32:28 +0200 Subject: [PATCH 05/71] feat(mac): test rm --- mac/mcompile/x.bla | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 mac/mcompile/x.bla diff --git a/mac/mcompile/x.bla b/mac/mcompile/x.bla new file mode 100644 index 00000000000..e69de29bb2d From be0c9b441e2accf7c49026efa097d0c2142fddf1 Mon Sep 17 00:00:00 2001 From: SabinePlay <166697246+SabinePlay@users.noreply.github.com> Date: Fri, 19 Apr 2024 09:38:43 +0200 Subject: [PATCH 06/71] feat(mac): remove files --- mac/mcompile/mcompile.exe | Bin 236784 -> 0 bytes .../mcompile.exe.dSYM/Contents/Info.plist | 20 - .../Contents/Resources/DWARF/mcompile.exe | Bin 561614 -> 0 bytes .../Relocations/aarch64/mcompile.exe.yml | 660 ------------------ 4 files changed, 680 deletions(-) delete mode 100755 mac/mcompile/mcompile.exe delete mode 100644 mac/mcompile/mcompile.exe.dSYM/Contents/Info.plist delete mode 100644 mac/mcompile/mcompile.exe.dSYM/Contents/Resources/DWARF/mcompile.exe delete mode 100644 mac/mcompile/mcompile.exe.dSYM/Contents/Resources/Relocations/aarch64/mcompile.exe.yml diff --git a/mac/mcompile/mcompile.exe b/mac/mcompile/mcompile.exe deleted file mode 100755 index a07e49629f43c6140b7518a2db79cda50163f689..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236784 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 - - - - CFBundleDevelopmentRegion - English - CFBundleIdentifier - com.apple.xcode.dsym.mcompile.exe - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - dSYM - CFBundleSignature - ???? - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/mac/mcompile/mcompile.exe.dSYM/Contents/Resources/DWARF/mcompile.exe b/mac/mcompile/mcompile.exe.dSYM/Contents/Resources/DWARF/mcompile.exe deleted file mode 100644 index 100197685076f009c31b6f63b8a2eb0b0d8dabd5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 561614 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

U`?wha!ljP$g*tb=7ou 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

?!5Gbp_||8^Be5{2g(H08UO$Q diff --git a/mac/mcompile/mcompile.exe.dSYM/Contents/Resources/Relocations/aarch64/mcompile.exe.yml b/mac/mcompile/mcompile.exe.dSYM/Contents/Resources/Relocations/aarch64/mcompile.exe.yml deleted file mode 100644 index 76999777736..00000000000 --- a/mac/mcompile/mcompile.exe.dSYM/Contents/Resources/Relocations/aarch64/mcompile.exe.yml +++ /dev/null @@ -1,660 +0,0 @@ ---- -triple: 'arm64-apple-darwin' -binary-path: '/Users/sabine/projects/keyman/keyman/mac/mcompile/mcompile.exe' -relocations: - - { offsetInCU: 0x457C, offset: 0x457C, size: 0x8, addend: 0x0, symName: __ZNSt3__16copy_nB8ue170006IPKDsmPDsEENS_9enable_ifIXsr37__has_random_access_iterator_categoryIT_EE5valueET1_E4typeES5_T0_S6_, symObjAddr: 0x196C, symBinAddr: 0x100004880, symSize: 0x44 } - - { offsetInCU: 0x7486, offset: 0x7486, size: 0x8, addend: 0x0, symName: __ZNSt3__130__libcpp_is_constant_evaluatedB8ue170006Ev, symObjAddr: 0x888, symBinAddr: 0x10000379C, symSize: 0xC } - - { offsetInCU: 0x74A3, offset: 0x74A3, size: 0x8, addend: 0x0, symName: __ZNSt3__117__libcpp_allocateB8ue170006Emm, symObjAddr: 0xB80, symBinAddr: 0x100003A94, symSize: 0x28 } - - { offsetInCU: 0x74E0, offset: 0x74E0, size: 0x8, addend: 0x0, symName: __ZNSt3__121__libcpp_operator_newB8ue170006IJmEEEPvDpT_, symObjAddr: 0xBBC, symBinAddr: 0x100003AD0, symSize: 0x24 } - - { offsetInCU: 0x7519, offset: 0x7519, size: 0x8, addend: 0x0, symName: __ZNSt3__112__to_addressB8ue170006IKcEEPT_S3_, symObjAddr: 0xC40, symBinAddr: 0x100003B54, symSize: 0x14 } - - { offsetInCU: 0x7581, offset: 0x7581, size: 0x8, addend: 0x0, symName: __ZNSt3__118__constexpr_wcslenB8ue170006EPKw, symObjAddr: 0xF50, symBinAddr: 0x100003E64, symSize: 0x24 } - - { offsetInCU: 0x75AD, offset: 0x75AD, size: 0x8, addend: 0x0, symName: __ZNSt3__119__allocate_at_leastB8ue170006INS_9allocatorIDsEEEENS_19__allocation_resultINS_16allocator_traitsIT_E7pointerEEERS5_m, symObjAddr: 0x1448, symBinAddr: 0x10000435C, symSize: 0x40 } - - { offsetInCU: 0x75F0, offset: 0x75F0, size: 0x8, addend: 0x0, symName: __ZNSt3__112__to_addressB8ue170006IDsEEPT_S2_, symObjAddr: 0x16A0, symBinAddr: 0x1000045B4, symSize: 0x14 } - - { offsetInCU: 0x7827, offset: 0x7827, size: 0x8, addend: 0x0, symName: __ZNSt3__120__throw_length_errorB8ue170006EPKc, symObjAddr: 0x179C, symBinAddr: 0x1000046B0, symSize: 0x64 } - - { offsetInCU: 0x7884, offset: 0x7884, size: 0x8, addend: 0x0, symName: __ZNSt3__14copyB8ue170006IPKDsPDsEET0_T_S5_S4_, symObjAddr: 0x19B0, symBinAddr: 0x1000048C4, symSize: 0x40 } - - { offsetInCU: 0x78DE, offset: 0x78DE, size: 0x8, addend: 0x0, symName: __ZNSt3__16__copyB8ue170006INS_17_ClassicAlgPolicyEPKDsS3_PDsEENS_4pairIT0_T2_EES6_T1_S7_, symObjAddr: 0x19F0, symBinAddr: 0x100004904, symSize: 0x44 } - - { offsetInCU: 0x794A, offset: 0x794A, size: 0x8, addend: 0x0, symName: __ZNSt3__123__dispatch_copy_or_moveB8ue170006INS_17_ClassicAlgPolicyENS_11__copy_loopIS1_EENS_14__copy_trivialEPKDsS6_PDsEENS_4pairIT2_T4_EES9_T3_SA_, symObjAddr: 0x1A34, symBinAddr: 0x100004948, symSize: 0x44 } - - { offsetInCU: 0x79C8, offset: 0x79C8, size: 0x8, addend: 0x0, symName: __ZNSt3__121__unwrap_and_dispatchB8ue170006INS_10__overloadINS_11__copy_loopINS_17_ClassicAlgPolicyEEENS_14__copy_trivialEEEPKDsS8_PDsLi0EEENS_4pairIT0_T2_EESB_T1_SC_, symObjAddr: 0x1A78, symBinAddr: 0x10000498C, symSize: 0xB4 } - - { offsetInCU: 0x7A56, offset: 0x7A56, size: 0x8, addend: 0x0, symName: __ZNSt3__114__unwrap_rangeB8ue170006IPKDsS2_EENS_4pairIT0_S4_EET_S6_, symObjAddr: 0x1B2C, symBinAddr: 0x100004A40, symSize: 0x60 } - - { offsetInCU: 0x7B95, offset: 0x7B95, size: 0x8, addend: 0x0, symName: __ZNSt3__113__unwrap_iterB8ue170006IPDsNS_18__unwrap_iter_implIS1_Lb1EEELi0EEEDTclsrT0_8__unwrapclsr3stdE7declvalIT_EEEES5_, symObjAddr: 0x1BD4, symBinAddr: 0x100004AE8, symSize: 0x24 } - - { offsetInCU: 0x7BD9, offset: 0x7BD9, size: 0x8, addend: 0x0, symName: __ZNSt3__19make_pairB8ue170006IPKDsPDsEENS_4pairINS_18__unwrap_ref_decayIT_E4typeENS5_IT0_E4typeEEEOS6_OS9_, symObjAddr: 0x1BF8, symBinAddr: 0x100004B0C, symSize: 0x38 } - - { offsetInCU: 0x7C28, offset: 0x7C28, size: 0x8, addend: 0x0, symName: __ZNSt3__114__rewrap_rangeB8ue170006IPKDsS2_EET_S3_T0_, symObjAddr: 0x1C30, symBinAddr: 0x100004B44, symSize: 0x2C } - - { offsetInCU: 0x7C74, offset: 0x7C74, size: 0x8, addend: 0x0, symName: __ZNSt3__113__rewrap_iterB8ue170006IPDsS1_NS_18__unwrap_iter_implIS1_Lb1EEEEET_S4_T0_, symObjAddr: 0x1C5C, symBinAddr: 0x100004B70, symSize: 0x50 } - - { offsetInCU: 0x7CC9, offset: 0x7CC9, size: 0x8, addend: 0x0, symName: __ZNSt3__19make_pairB8ue170006IPKDsS2_EENS_4pairINS_18__unwrap_ref_decayIT_E4typeENS4_IT0_E4typeEEEOS5_OS8_, symObjAddr: 0x1CAC, symBinAddr: 0x100004BC0, symSize: 0x38 } - - { offsetInCU: 0x7D18, offset: 0x7D18, size: 0x8, addend: 0x0, symName: __ZNSt3__113__unwrap_iterB8ue170006IPKDsNS_18__unwrap_iter_implIS2_Lb1EEELi0EEEDTclsrT0_8__unwrapclsr3stdE7declvalIT_EEEES6_, symObjAddr: 0x1CE4, symBinAddr: 0x100004BF8, symSize: 0x24 } - - { offsetInCU: 0x7E5C, offset: 0x7E5C, size: 0x8, addend: 0x0, symName: __ZNSt3__112__to_addressB8ue170006IKDsEEPT_S3_, symObjAddr: 0x1D9C, symBinAddr: 0x100004CB0, symSize: 0x14 } - - { offsetInCU: 0x7E91, offset: 0x7E91, size: 0x8, addend: 0x0, symName: __ZNSt3__119__copy_trivial_implB8ue170006IKDsDsEENS_4pairIPT_PT0_EES4_S4_S6_, symObjAddr: 0x1DB0, symBinAddr: 0x100004CC4, symSize: 0x80 } - - { offsetInCU: 0x7EF9, offset: 0x7EF9, size: 0x8, addend: 0x0, symName: __ZNSt3__119__constexpr_memmoveB8ue170006IDsKDsLi0EEEPT_S3_PT0_NS_15__element_countE, symObjAddr: 0x1E30, symBinAddr: 0x100004D44, symSize: 0xA0 } - - { offsetInCU: 0x7F67, offset: 0x7F67, size: 0x8, addend: 0x0, symName: __ZNSt3__19make_pairB8ue170006IRPKDsPDsEENS_4pairINS_18__unwrap_ref_decayIT_E4typeENS6_IT0_E4typeEEEOS7_OSA_, symObjAddr: 0x1ED0, symBinAddr: 0x100004DE4, symSize: 0x38 } - - { offsetInCU: 0x8009, offset: 0x8009, size: 0x8, addend: 0x0, symName: __ZNSt3__113__rewrap_iterB8ue170006IPKDsS2_NS_18__unwrap_iter_implIS2_Lb1EEEEET_S5_T0_, symObjAddr: 0x1F9C, symBinAddr: 0x100004EB0, symSize: 0x50 } - - { offsetInCU: 0x805E, offset: 0x805E, size: 0x8, addend: 0x0, symName: __ZNSt3__119__libcpp_deallocateB8ue170006EPvmm, symObjAddr: 0x22D0, symBinAddr: 0x1000051E4, symSize: 0x30 } - - { offsetInCU: 0x80A6, offset: 0x80A6, size: 0x8, addend: 0x0, symName: __ZNSt3__127__do_deallocate_handle_sizeB8ue170006IJEEEvPvmDpT_, symObjAddr: 0x2300, symBinAddr: 0x100005214, symSize: 0x28 } - - { offsetInCU: 0x80E4, offset: 0x80E4, size: 0x8, addend: 0x0, symName: __ZNSt3__124__libcpp_operator_deleteB8ue170006IJPvEEEvDpT_, symObjAddr: 0x2328, symBinAddr: 0x10000523C, symSize: 0x24 } - - { offsetInCU: 0x8119, offset: 0x8119, size: 0x8, addend: 0x0, symName: __ZNSt3__118__constexpr_strlenB8ue170006EPKc, symObjAddr: 0x23EC, symBinAddr: 0x100005300, symSize: 0x24 } - - { offsetInCU: 0x8353, offset: 0x8353, size: 0x8, addend: 0x0, symName: __ZSt28__throw_bad_array_new_lengthB8ue170006v, symObjAddr: 0xB4C, symBinAddr: 0x100003A60, symSize: 0x34 } - - { offsetInCU: 0xA924, offset: 0xA924, size: 0x8, addend: 0x0, symName: __Z9Open_FilePKcS0_, symObjAddr: 0x0, symBinAddr: 0x100002F14, symSize: 0x2C } - - { offsetInCU: 0xA95E, offset: 0xA95E, size: 0x8, addend: 0x0, symName: __Z9Open_FilePKwS0_, symObjAddr: 0x2C, symBinAddr: 0x100002F40, symSize: 0x1C8 } - - { offsetInCU: 0xA9B4, offset: 0xA9B4, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1B8ue170006Ev, symObjAddr: 0x1F4, symBinAddr: 0x100003108, symSize: 0x2C } - - { offsetInCU: 0xAAF8, offset: 0xAAF8, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEC1B8ue170006ILi0EEEPKw, symObjAddr: 0x220, symBinAddr: 0x100003134, symSize: 0x34 } - - { offsetInCU: 0xAB35, offset: 0xAB35, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5c_strB8ue170006Ev, symObjAddr: 0x260, symBinAddr: 0x100003174, symSize: 0x24 } - - { offsetInCU: 0xAB59, offset: 0xAB59, size: 0x8, addend: 0x0, symName: __Z9Open_FilePKDsS0_, symObjAddr: 0x284, symBinAddr: 0x100003198, symSize: 0x1C8 } - - { offsetInCU: 0xABB4, offset: 0xABB4, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEC1B8ue170006ILi0EEEPKDs, symObjAddr: 0x44C, symBinAddr: 0x100003360, symSize: 0x34 } - - { offsetInCU: 0xABF1, offset: 0xABF1, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEED1Ev, symObjAddr: 0x480, symBinAddr: 0x100003394, symSize: 0x2C } - - { offsetInCU: 0xAC19, offset: 0xAC19, size: 0x8, addend: 0x0, symName: __Z16kmcmp_FileExistsPKc, symObjAddr: 0x4AC, symBinAddr: 0x1000033C0, symSize: 0xAC } - - { offsetInCU: 0xAC58, offset: 0xAC58, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1B8ue170006ILi0EEEPKc, symObjAddr: 0x558, symBinAddr: 0x10000346C, symSize: 0x34 } - - { offsetInCU: 0xAC95, offset: 0xAC95, size: 0x8, addend: 0x0, symName: __Z16kmcmp_FileExistsPKDs, symObjAddr: 0x58C, symBinAddr: 0x1000034A0, symSize: 0xF4 } - - { offsetInCU: 0xACCF, offset: 0xACCF, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2B8ue170006Ev, symObjAddr: 0x680, symBinAddr: 0x100003594, symSize: 0x3C } - - { offsetInCU: 0xACFC, offset: 0xACFC, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5__repES5_EC1B8ue170006INS_18__default_init_tagESA_EEOT_OT0_, symObjAddr: 0x6BC, symBinAddr: 0x1000035D0, symSize: 0x3C } - - { offsetInCU: 0xAD52, offset: 0xAD52, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE14__default_initB8ue170006Ev, symObjAddr: 0x6F8, symBinAddr: 0x10000360C, symSize: 0xB0 } - - { offsetInCU: 0xADA2, offset: 0xADA2, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5__repES5_EC2B8ue170006INS_18__default_init_tagESA_EEOT_OT0_, symObjAddr: 0x7A8, symBinAddr: 0x1000036BC, symSize: 0x3C } - - { offsetInCU: 0xADF8, offset: 0xADF8, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5__repELi0ELb0EEC2B8ue170006ENS_18__default_init_tagE, symObjAddr: 0x7E4, symBinAddr: 0x1000036F8, symSize: 0x14 } - - { offsetInCU: 0xAE2A, offset: 0xAE2A, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorIcEELi1ELb1EEC2B8ue170006ENS_18__default_init_tagE, symObjAddr: 0x7F8, symBinAddr: 0x10000370C, symSize: 0x2C } - - { offsetInCU: 0xAE5C, offset: 0xAE5C, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorIcEC2B8ue170006Ev, symObjAddr: 0x824, symBinAddr: 0x100003738, symSize: 0x2C } - - { offsetInCU: 0xAE84, offset: 0xAE84, size: 0x8, addend: 0x0, symName: __ZNSt3__116__non_trivial_ifILb1ENS_9allocatorIcEEEC2B8ue170006Ev, symObjAddr: 0x850, symBinAddr: 0x100003764, symSize: 0x14 } - - { offsetInCU: 0xAEAC, offset: 0xAEAC, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5__repES5_E5firstB8ue170006Ev, symObjAddr: 0x864, symBinAddr: 0x100003778, symSize: 0x24 } - - { offsetInCU: 0xAED0, offset: 0xAED0, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE11__recommendB8ue170006Em, symObjAddr: 0x894, symBinAddr: 0x1000037A8, symSize: 0x9C } - - { offsetInCU: 0xAF02, offset: 0xAF02, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIcEEE8allocateB8ue170006ERS2_m, symObjAddr: 0x930, symBinAddr: 0x100003844, symSize: 0x2C } - - { offsetInCU: 0xAF34, offset: 0xAF34, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7__allocB8ue170006Ev, symObjAddr: 0x95C, symBinAddr: 0x100003870, symSize: 0x24 } - - { offsetInCU: 0xAF58, offset: 0xAF58, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE16__begin_lifetimeB8ue170006EPcm, symObjAddr: 0x980, symBinAddr: 0x100003894, symSize: 0x14 } - - { offsetInCU: 0xAF8A, offset: 0xAF8A, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE18__set_long_pointerB8ue170006EPc, symObjAddr: 0x994, symBinAddr: 0x1000038A8, symSize: 0x38 } - - { offsetInCU: 0xAFBD, offset: 0xAFBD, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE14__set_long_capB8ue170006Em, symObjAddr: 0x9CC, symBinAddr: 0x1000038E0, symSize: 0x70 } - - { offsetInCU: 0xAFF0, offset: 0xAFF0, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE15__set_long_sizeB8ue170006Em, symObjAddr: 0xA3C, symBinAddr: 0x100003950, symSize: 0x38 } - - { offsetInCU: 0xB023, offset: 0xB023, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5__repELi0ELb0EE5__getB8ue170006Ev, symObjAddr: 0xA74, symBinAddr: 0x100003988, symSize: 0x14 } - - { offsetInCU: 0xB047, offset: 0xB047, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE10__align_itB8ue170006ILm16EEEmm, symObjAddr: 0xA88, symBinAddr: 0x10000399C, symSize: 0x1C } - - { offsetInCU: 0xB074, offset: 0xB074, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorIcE8allocateB8ue170006Em, symObjAddr: 0xAA4, symBinAddr: 0x1000039B8, symSize: 0x84 } - - { offsetInCU: 0xB0B0, offset: 0xB0B0, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIcEEE8max_sizeB8ue170006IS2_vEEmRKS2_, symObjAddr: 0xB28, symBinAddr: 0x100003A3C, symSize: 0x24 } - - { offsetInCU: 0xB0DD, offset: 0xB0DD, size: 0x8, addend: 0x0, symName: __ZNKSt3__19allocatorIcE8max_sizeB8ue170006Ev, symObjAddr: 0xBA8, symBinAddr: 0x100003ABC, symSize: 0x14 } - - { offsetInCU: 0xB101, offset: 0xB101, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5__repES5_E6secondB8ue170006Ev, symObjAddr: 0xBE0, symBinAddr: 0x100003AF4, symSize: 0x24 } - - { offsetInCU: 0xB125, offset: 0xB125, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorIcEELi1ELb1EE5__getB8ue170006Ev, symObjAddr: 0xC04, symBinAddr: 0x100003B18, symSize: 0x14 } - - { offsetInCU: 0xB149, offset: 0xB149, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4dataB8ue170006Ev, symObjAddr: 0xC18, symBinAddr: 0x100003B2C, symSize: 0x28 } - - { offsetInCU: 0xB16D, offset: 0xB16D, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE13__get_pointerB8ue170006Ev, symObjAddr: 0xC54, symBinAddr: 0x100003B68, symSize: 0x54 } - - { offsetInCU: 0xB191, offset: 0xB191, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__is_longB8ue170006Ev, symObjAddr: 0xCA8, symBinAddr: 0x100003BBC, symSize: 0x74 } - - { offsetInCU: 0xB1B5, offset: 0xB1B5, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE18__get_long_pointerB8ue170006Ev, symObjAddr: 0xD1C, symBinAddr: 0x100003C30, symSize: 0x28 } - - { offsetInCU: 0xB1D9, offset: 0xB1D9, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE19__get_short_pointerB8ue170006Ev, symObjAddr: 0xD44, symBinAddr: 0x100003C58, symSize: 0x28 } - - { offsetInCU: 0xB1FD, offset: 0xB1FD, size: 0x8, addend: 0x0, symName: __ZNKSt3__117__compressed_pairINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5__repES5_E5firstB8ue170006Ev, symObjAddr: 0xD6C, symBinAddr: 0x100003C80, symSize: 0x24 } - - { offsetInCU: 0xB221, offset: 0xB221, size: 0x8, addend: 0x0, symName: __ZNKSt3__122__compressed_pair_elemINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5__repELi0ELb0EE5__getB8ue170006Ev, symObjAddr: 0xD90, symBinAddr: 0x100003CA4, symSize: 0x14 } - - { offsetInCU: 0xB245, offset: 0xB245, size: 0x8, addend: 0x0, symName: __ZNSt3__114pointer_traitsIPKcE10pointer_toB8ue170006ERS1_, symObjAddr: 0xDA4, symBinAddr: 0x100003CB8, symSize: 0x14 } - - { offsetInCU: 0xB267, offset: 0xB267, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEC2B8ue170006ILi0EEEPKw, symObjAddr: 0xDB8, symBinAddr: 0x100003CCC, symSize: 0x58 } - - { offsetInCU: 0xB2A4, offset: 0xB2A4, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE5__repES5_EC1B8ue170006INS_18__default_init_tagESA_EEOT_OT0_, symObjAddr: 0xE10, symBinAddr: 0x100003D24, symSize: 0x3C } - - { offsetInCU: 0xB2FA, offset: 0xB2FA, size: 0x8, addend: 0x0, symName: __ZNSt3__111char_traitsIwE6lengthB8ue170006EPKw, symObjAddr: 0xE4C, symBinAddr: 0x100003D60, symSize: 0x48 } - - { offsetInCU: 0xB31D, offset: 0xB31D, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE5__repES5_EC2B8ue170006INS_18__default_init_tagESA_EEOT_OT0_, symObjAddr: 0xE94, symBinAddr: 0x100003DA8, symSize: 0x3C } - - { offsetInCU: 0xB373, offset: 0xB373, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE5__repELi0ELb0EEC2B8ue170006ENS_18__default_init_tagE, symObjAddr: 0xED0, symBinAddr: 0x100003DE4, symSize: 0x14 } - - { offsetInCU: 0xB3A5, offset: 0xB3A5, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorIwEELi1ELb1EEC2B8ue170006ENS_18__default_init_tagE, symObjAddr: 0xEE4, symBinAddr: 0x100003DF8, symSize: 0x2C } - - { offsetInCU: 0xB3D7, offset: 0xB3D7, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorIwEC2B8ue170006Ev, symObjAddr: 0xF10, symBinAddr: 0x100003E24, symSize: 0x2C } - - { offsetInCU: 0xB3FF, offset: 0xB3FF, size: 0x8, addend: 0x0, symName: __ZNSt3__116__non_trivial_ifILb1ENS_9allocatorIwEEEC2B8ue170006Ev, symObjAddr: 0xF3C, symBinAddr: 0x100003E50, symSize: 0x14 } - - { offsetInCU: 0xB427, offset: 0xB427, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEC2B8ue170006ILi0EEEPKDs, symObjAddr: 0xF74, symBinAddr: 0x100003E88, symSize: 0x58 } - - { offsetInCU: 0xB464, offset: 0xB464, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5__repES5_EC1B8ue170006INS_18__default_init_tagESA_EEOT_OT0_, symObjAddr: 0xFCC, symBinAddr: 0x100003EE0, symSize: 0x3C } - - { offsetInCU: 0xB4BA, offset: 0xB4BA, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE6__initEPKDsm, symObjAddr: 0x1008, symBinAddr: 0x100003F1C, symSize: 0x14C } - - { offsetInCU: 0xB52A, offset: 0xB52A, size: 0x8, addend: 0x0, symName: __ZNSt3__111char_traitsIDsE6lengthB8ue170006EPKDs, symObjAddr: 0x1154, symBinAddr: 0x100004068, symSize: 0x60 } - - { offsetInCU: 0xB55E, offset: 0xB55E, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5__repES5_EC2B8ue170006INS_18__default_init_tagESA_EEOT_OT0_, symObjAddr: 0x11B4, symBinAddr: 0x1000040C8, symSize: 0x3C } - - { offsetInCU: 0xB5B4, offset: 0xB5B4, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5__repELi0ELb0EEC2B8ue170006ENS_18__default_init_tagE, symObjAddr: 0x11F0, symBinAddr: 0x100004104, symSize: 0x14 } - - { offsetInCU: 0xB5E6, offset: 0xB5E6, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorIDsEELi1ELb1EEC2B8ue170006ENS_18__default_init_tagE, symObjAddr: 0x1204, symBinAddr: 0x100004118, symSize: 0x2C } - - { offsetInCU: 0xB618, offset: 0xB618, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorIDsEC2B8ue170006Ev, symObjAddr: 0x1230, symBinAddr: 0x100004144, symSize: 0x2C } - - { offsetInCU: 0xB640, offset: 0xB640, size: 0x8, addend: 0x0, symName: __ZNSt3__116__non_trivial_ifILb1ENS_9allocatorIDsEEEC2B8ue170006Ev, symObjAddr: 0x125C, symBinAddr: 0x100004170, symSize: 0x14 } - - { offsetInCU: 0xB668, offset: 0xB668, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5__repES5_E5firstB8ue170006Ev, symObjAddr: 0x1270, symBinAddr: 0x100004184, symSize: 0x24 } - - { offsetInCU: 0xB68C, offset: 0xB68C, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE8max_sizeB8ue170006Ev, symObjAddr: 0x1294, symBinAddr: 0x1000041A8, symSize: 0xAC } - - { offsetInCU: 0xB6DC, offset: 0xB6DC, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE20__throw_length_errorB8ue170006Ev, symObjAddr: 0x1340, symBinAddr: 0x100004254, symSize: 0x1C } - - { offsetInCU: 0xB700, offset: 0xB700, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE13__fits_in_ssoB8ue170006Em, symObjAddr: 0x135C, symBinAddr: 0x100004270, symSize: 0x4C } - - { offsetInCU: 0xB723, offset: 0xB723, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE16__set_short_sizeB8ue170006Em, symObjAddr: 0x13A8, symBinAddr: 0x1000042BC, symSize: 0x78 } - - { offsetInCU: 0xB756, offset: 0xB756, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE19__get_short_pointerB8ue170006Ev, symObjAddr: 0x1420, symBinAddr: 0x100004334, symSize: 0x28 } - - { offsetInCU: 0xB77A, offset: 0xB77A, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE7__allocB8ue170006Ev, symObjAddr: 0x1488, symBinAddr: 0x10000439C, symSize: 0x24 } - - { offsetInCU: 0xB79E, offset: 0xB79E, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE11__recommendB8ue170006Em, symObjAddr: 0x14AC, symBinAddr: 0x1000043C0, symSize: 0x9C } - - { offsetInCU: 0xB7D0, offset: 0xB7D0, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE16__begin_lifetimeB8ue170006EPDsm, symObjAddr: 0x1548, symBinAddr: 0x10000445C, symSize: 0x14 } - - { offsetInCU: 0xB802, offset: 0xB802, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE18__set_long_pointerB8ue170006EPDs, symObjAddr: 0x155C, symBinAddr: 0x100004470, symSize: 0x38 } - - { offsetInCU: 0xB835, offset: 0xB835, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE14__set_long_capB8ue170006Em, symObjAddr: 0x1594, symBinAddr: 0x1000044A8, symSize: 0x70 } - - { offsetInCU: 0xB868, offset: 0xB868, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE15__set_long_sizeB8ue170006Em, symObjAddr: 0x1604, symBinAddr: 0x100004518, symSize: 0x38 } - - { offsetInCU: 0xB89B, offset: 0xB89B, size: 0x8, addend: 0x0, symName: __ZNSt3__111char_traitsIDsE4copyB8ue170006EPDsPKDsm, symObjAddr: 0x163C, symBinAddr: 0x100004550, symSize: 0x64 } - - { offsetInCU: 0xB8DC, offset: 0xB8DC, size: 0x8, addend: 0x0, symName: __ZNSt3__111char_traitsIDsE6assignB8ue170006ERDsRKDs, symObjAddr: 0x16B4, symBinAddr: 0x1000045C8, symSize: 0x24 } - - { offsetInCU: 0xB90E, offset: 0xB90E, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5__repELi0ELb0EE5__getB8ue170006Ev, symObjAddr: 0x16D8, symBinAddr: 0x1000045EC, symSize: 0x14 } - - { offsetInCU: 0xB93C, offset: 0xB93C, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIDsEEE8max_sizeB8ue170006IS2_vEEmRKS2_, symObjAddr: 0x16EC, symBinAddr: 0x100004600, symSize: 0x24 } - - { offsetInCU: 0xB969, offset: 0xB969, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE7__allocB8ue170006Ev, symObjAddr: 0x1710, symBinAddr: 0x100004624, symSize: 0x24 } - - { offsetInCU: 0xB98D, offset: 0xB98D, size: 0x8, addend: 0x0, symName: __ZNSt3__114numeric_limitsImE3maxB8ue170006Ev, symObjAddr: 0x1734, symBinAddr: 0x100004648, symSize: 0x14 } - - { offsetInCU: 0xB9A0, offset: 0xB9A0, size: 0x8, addend: 0x0, symName: __ZNKSt3__19allocatorIDsE8max_sizeB8ue170006Ev, symObjAddr: 0x1748, symBinAddr: 0x10000465C, symSize: 0x14 } - - { offsetInCU: 0xB9C4, offset: 0xB9C4, size: 0x8, addend: 0x0, symName: __ZNKSt3__117__compressed_pairINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5__repES5_E6secondB8ue170006Ev, symObjAddr: 0x175C, symBinAddr: 0x100004670, symSize: 0x24 } - - { offsetInCU: 0xB9E8, offset: 0xB9E8, size: 0x8, addend: 0x0, symName: __ZNKSt3__122__compressed_pair_elemINS_9allocatorIDsEELi1ELb1EE5__getB8ue170006Ev, symObjAddr: 0x1780, symBinAddr: 0x100004694, symSize: 0x14 } - - { offsetInCU: 0xBA0C, offset: 0xBA0C, size: 0x8, addend: 0x0, symName: __ZNSt3__123__libcpp_numeric_limitsImLb1EE3maxB8ue170006Ev, symObjAddr: 0x1794, symBinAddr: 0x1000046A8, symSize: 0x8 } - - { offsetInCU: 0xBA1F, offset: 0xBA1F, size: 0x8, addend: 0x0, symName: __ZNSt12length_errorC1B8ue170006EPKc, symObjAddr: 0x1800, symBinAddr: 0x100004714, symSize: 0x34 } - - { offsetInCU: 0xBA55, offset: 0xBA55, size: 0x8, addend: 0x0, symName: __ZNSt12length_errorC2B8ue170006EPKc, symObjAddr: 0x1834, symBinAddr: 0x100004748, symSize: 0x4C } - - { offsetInCU: 0xBA8B, offset: 0xBA8B, size: 0x8, addend: 0x0, symName: __ZNSt3__114pointer_traitsIPDsE10pointer_toB8ue170006ERDs, symObjAddr: 0x1880, symBinAddr: 0x100004794, symSize: 0x14 } - - { offsetInCU: 0xBAAD, offset: 0xBAAD, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorIDsE8allocateB8ue170006Em, symObjAddr: 0x1894, symBinAddr: 0x1000047A8, symSize: 0x84 } - - { offsetInCU: 0xBADF, offset: 0xBADF, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5__repES5_E6secondB8ue170006Ev, symObjAddr: 0x1918, symBinAddr: 0x10000482C, symSize: 0x24 } - - { offsetInCU: 0xBB03, offset: 0xBB03, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorIDsEELi1ELb1EE5__getB8ue170006Ev, symObjAddr: 0x193C, symBinAddr: 0x100004850, symSize: 0x14 } - - { offsetInCU: 0xBB27, offset: 0xBB27, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE10__align_itB8ue170006ILm8EEEmm, symObjAddr: 0x1950, symBinAddr: 0x100004864, symSize: 0x1C } - - { offsetInCU: 0xBB8B, offset: 0xBB8B, size: 0x8, addend: 0x0, symName: __ZNKSt3__114__copy_trivialclB8ue170006IKDsDsLi0EEENS_4pairIPT_PT0_EES5_S5_S7_, symObjAddr: 0x1B8C, symBinAddr: 0x100004AA0, symSize: 0x48 } - - { offsetInCU: 0xBC0A, offset: 0xBC0A, size: 0x8, addend: 0x0, symName: __ZNSt3__14pairIPKDsS2_EC1B8ue170006ERKS2_S5_, symObjAddr: 0x1D08, symBinAddr: 0x100004C1C, symSize: 0x3C } - - { offsetInCU: 0xBC4E, offset: 0xBC4E, size: 0x8, addend: 0x0, symName: __ZNSt3__14pairIPKDsS2_EC2B8ue170006ERKS2_S5_, symObjAddr: 0x1D44, symBinAddr: 0x100004C58, symSize: 0x34 } - - { offsetInCU: 0xBC92, offset: 0xBC92, size: 0x8, addend: 0x0, symName: __ZNSt3__118__unwrap_iter_implIPKDsLb1EE8__unwrapB8ue170006ES2_, symObjAddr: 0x1D78, symBinAddr: 0x100004C8C, symSize: 0x24 } - - { offsetInCU: 0xBCB4, offset: 0xBCB4, size: 0x8, addend: 0x0, symName: __ZNSt3__14pairIPKDsPDsEC1B8ue170006ERKS2_RKS3_, symObjAddr: 0x1F08, symBinAddr: 0x100004E1C, symSize: 0x3C } - - { offsetInCU: 0xBCF8, offset: 0xBCF8, size: 0x8, addend: 0x0, symName: __ZNSt3__14pairIPKDsPDsEC2B8ue170006ERKS2_RKS3_, symObjAddr: 0x1F44, symBinAddr: 0x100004E58, symSize: 0x34 } - - { offsetInCU: 0xBD3C, offset: 0xBD3C, size: 0x8, addend: 0x0, symName: __ZNSt3__118__unwrap_iter_implIPDsLb1EE8__unwrapB8ue170006ES1_, symObjAddr: 0x1F78, symBinAddr: 0x100004E8C, symSize: 0x24 } - - { offsetInCU: 0xBD5E, offset: 0xBD5E, size: 0x8, addend: 0x0, symName: __ZNSt3__118__unwrap_iter_implIPKDsLb1EE8__rewrapB8ue170006ES2_S2_, symObjAddr: 0x1FEC, symBinAddr: 0x100004F00, symSize: 0x50 } - - { offsetInCU: 0xBD8E, offset: 0xBD8E, size: 0x8, addend: 0x0, symName: __ZNSt3__118__unwrap_iter_implIPDsLb1EE8__rewrapB8ue170006ES1_S1_, symObjAddr: 0x203C, symBinAddr: 0x100004F50, symSize: 0x50 } - - { offsetInCU: 0xBDBE, offset: 0xBDBE, size: 0x8, addend: 0x0, symName: __ZNSt3__111char_traitsIDsE2eqB8ue170006EDsDs, symObjAddr: 0x208C, symBinAddr: 0x100004FA0, symSize: 0x28 } - - { offsetInCU: 0xBDF0, offset: 0xBDF0, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEED2Ev, symObjAddr: 0x20B4, symBinAddr: 0x100004FC8, symSize: 0x74 } - - { offsetInCU: 0xBE18, offset: 0xBE18, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE9__is_longB8ue170006Ev, symObjAddr: 0x2128, symBinAddr: 0x10000503C, symSize: 0x74 } - - { offsetInCU: 0xBE3C, offset: 0xBE3C, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIDsEEE10deallocateB8ue170006ERS2_PDsm, symObjAddr: 0x219C, symBinAddr: 0x1000050B0, symSize: 0x34 } - - { offsetInCU: 0xBE7D, offset: 0xBE7D, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE18__get_long_pointerB8ue170006Ev, symObjAddr: 0x21D0, symBinAddr: 0x1000050E4, symSize: 0x28 } - - { offsetInCU: 0xBEA1, offset: 0xBEA1, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE14__get_long_capB8ue170006Ev, symObjAddr: 0x21F8, symBinAddr: 0x10000510C, symSize: 0x30 } - - { offsetInCU: 0xBEC5, offset: 0xBEC5, size: 0x8, addend: 0x0, symName: __ZNKSt3__117__compressed_pairINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5__repES5_E5firstB8ue170006Ev, symObjAddr: 0x2228, symBinAddr: 0x10000513C, symSize: 0x24 } - - { offsetInCU: 0xBEE9, offset: 0xBEE9, size: 0x8, addend: 0x0, symName: __ZNKSt3__122__compressed_pair_elemINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5__repELi0ELb0EE5__getB8ue170006Ev, symObjAddr: 0x224C, symBinAddr: 0x100005160, symSize: 0x14 } - - { offsetInCU: 0xBF0D, offset: 0xBF0D, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorIDsE10deallocateB8ue170006EPDsm, symObjAddr: 0x2260, symBinAddr: 0x100005174, symSize: 0x70 } - - { offsetInCU: 0xBF4D, offset: 0xBF4D, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2B8ue170006ILi0EEEPKc, symObjAddr: 0x234C, symBinAddr: 0x100005260, symSize: 0x58 } - - { offsetInCU: 0xBF8A, offset: 0xBF8A, size: 0x8, addend: 0x0, symName: __ZNSt3__111char_traitsIcE6lengthB8ue170006EPKc, symObjAddr: 0x23A4, symBinAddr: 0x1000052B8, symSize: 0x48 } - - { offsetInCU: 0x6077, offset: 0x120F5, size: 0x8, addend: 0x0, symName: __ZNSt3__124__put_character_sequenceB8ue170006IcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m, symObjAddr: 0x4D8C, symBinAddr: 0x100008BE0, symSize: 0x1F4 } - - { offsetInCU: 0x7BF2, offset: 0x13C70, size: 0x8, addend: 0x0, symName: __ZNSt3__1lsB8ue170006INS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc, symObjAddr: 0xA50, symBinAddr: 0x100005D08, symSize: 0x48 } - - { offsetInCU: 0x7C38, offset: 0x13CB6, size: 0x8, addend: 0x0, symName: __ZNSt3__112__to_addressB8ue170006IiEEPT_S2_, symObjAddr: 0x1778, symBinAddr: 0x100006318, symSize: 0x14 } - - { offsetInCU: 0x7C6D, offset: 0x13CEB, size: 0x8, addend: 0x0, symName: __ZNSt3__13maxB8ue170006ImEERKT_S3_S3_, symObjAddr: 0x1EB4, symBinAddr: 0x100006A54, symSize: 0x2C } - - { offsetInCU: 0x7CB0, offset: 0x13D2E, size: 0x8, addend: 0x0, symName: __ZNSt3__13minB8ue170006ImEERKT_S3_S3_, symObjAddr: 0x1EE0, symBinAddr: 0x100006A80, symSize: 0x2C } - - { offsetInCU: 0x7EF4, offset: 0x13F72, size: 0x8, addend: 0x0, symName: __ZNSt3__13minB8ue170006ImNS_6__lessIvvEEEERKT_S5_S5_T0_, symObjAddr: 0x1F6C, symBinAddr: 0x100006B0C, symSize: 0x54 } - - { offsetInCU: 0x7F95, offset: 0x14013, size: 0x8, addend: 0x0, symName: __ZNSt3__13maxB8ue170006ImNS_6__lessIvvEEEERKT_S5_S5_T0_, symObjAddr: 0x212C, symBinAddr: 0x100006BE8, symSize: 0x54 } - - { offsetInCU: 0x7FEF, offset: 0x1406D, size: 0x8, addend: 0x0, symName: __ZNSt3__119__allocate_at_leastB8ue170006INS_9allocatorIiEEEENS_19__allocation_resultINS_16allocator_traitsIT_E7pointerEEERS5_m, symObjAddr: 0x2290, symBinAddr: 0x100006D4C, symSize: 0x40 } - - { offsetInCU: 0x8032, offset: 0x140B0, size: 0x8, addend: 0x0, symName: __ZNSt3__142__uninitialized_allocator_move_if_noexceptB8ue170006INS_9allocatorIiEENS_16reverse_iteratorIPiEES5_ivEET1_RT_T0_S9_S6_, symObjAddr: 0x2470, symBinAddr: 0x100006F2C, symSize: 0xE8 } - - { offsetInCU: 0x80B0, offset: 0x1412E, size: 0x8, addend: 0x0, symName: __ZNSt3__14swapB8ue170006IPiEEvRT_S3_, symObjAddr: 0x25A4, symBinAddr: 0x100007060, symSize: 0x3C } - - { offsetInCU: 0x8101, offset: 0x1417F, size: 0x8, addend: 0x0, symName: __ZNSt3__1neB8ue170006IPiS1_EEbRKNS_16reverse_iteratorIT_EERKNS2_IT0_EE, symObjAddr: 0x268C, symBinAddr: 0x100007148, symSize: 0x48 } - - { offsetInCU: 0x8174, offset: 0x141F2, size: 0x8, addend: 0x0, symName: __ZNSt3__114__construct_atB8ue170006IiJiEPiEEPT_S3_DpOT0_, symObjAddr: 0x26D4, symBinAddr: 0x100007190, symSize: 0x2C } - - { offsetInCU: 0x81E6, offset: 0x14264, size: 0x8, addend: 0x0, symName: __ZNSt3__112__to_addressB8ue170006INS_16reverse_iteratorIPiEEvEEu7__decayIDTclsr19__to_address_helperIT_EE6__callclsr3stdE7declvalIRKS4_EEEEES6_, symObjAddr: 0x2700, symBinAddr: 0x1000071BC, symSize: 0x24 } - - { offsetInCU: 0x821C, offset: 0x1429A, size: 0x8, addend: 0x0, symName: __ZNSt3__14moveB8ue170006INS_16reverse_iteratorIPiEES3_EET0_T_S5_S4_, symObjAddr: 0x276C, symBinAddr: 0x100007228, symSize: 0x78 } - - { offsetInCU: 0x82A0, offset: 0x1431E, size: 0x8, addend: 0x0, symName: __ZNSt3__16__moveB8ue170006INS_17_ClassicAlgPolicyENS_16reverse_iteratorIPiEES4_S4_EENS_4pairIT0_T2_EES6_T1_S7_, symObjAddr: 0x2854, symBinAddr: 0x100007310, symSize: 0x64 } - - { offsetInCU: 0x830C, offset: 0x1438A, size: 0x8, addend: 0x0, symName: __ZNSt3__123__dispatch_copy_or_moveB8ue170006INS_17_ClassicAlgPolicyENS_11__move_loopIS1_EENS_14__move_trivialENS_16reverse_iteratorIPiEES7_S7_EENS_4pairIT2_T4_EES9_T3_SA_, symObjAddr: 0x28B8, symBinAddr: 0x100007374, symSize: 0x64 } - - { offsetInCU: 0x838A, offset: 0x14408, size: 0x8, addend: 0x0, symName: __ZNSt3__121__unwrap_and_dispatchB8ue170006INS_10__overloadINS_11__move_loopINS_17_ClassicAlgPolicyEEENS_14__move_trivialEEENS_16reverse_iteratorIPiEES9_S9_Li0EEENS_4pairIT0_T2_EESB_T1_SC_, symObjAddr: 0x291C, symBinAddr: 0x1000073D8, symSize: 0x12C } - - { offsetInCU: 0x841A, offset: 0x14498, size: 0x8, addend: 0x0, symName: __ZNSt3__114__unwrap_rangeB8ue170006INS_16reverse_iteratorIPiEES3_EENS_4pairIT0_S5_EET_S7_, symObjAddr: 0x2A48, symBinAddr: 0x100007504, symSize: 0x84 } - - { offsetInCU: 0x8565, offset: 0x145E3, size: 0x8, addend: 0x0, symName: __ZNSt3__113__unwrap_iterB8ue170006INS_16reverse_iteratorIPiEENS_18__unwrap_iter_implIS3_Lb0EEELi0EEEDTclsrT0_8__unwrapclsr3stdE7declvalIT_EEEES7_, symObjAddr: 0x2B6C, symBinAddr: 0x100007628, symSize: 0x44 } - - { offsetInCU: 0x85A9, offset: 0x14627, size: 0x8, addend: 0x0, symName: __ZNSt3__19make_pairB8ue170006INS_16reverse_iteratorIPiEES3_EENS_4pairINS_18__unwrap_ref_decayIT_E4typeENS5_IT0_E4typeEEEOS6_OS9_, symObjAddr: 0x2BB0, symBinAddr: 0x10000766C, symSize: 0x38 } - - { offsetInCU: 0x85F8, offset: 0x14676, size: 0x8, addend: 0x0, symName: __ZNSt3__114__rewrap_rangeB8ue170006INS_16reverse_iteratorIPiEES3_EET_S4_T0_, symObjAddr: 0x2BE8, symBinAddr: 0x1000076A4, symSize: 0x5C } - - { offsetInCU: 0x8644, offset: 0x146C2, size: 0x8, addend: 0x0, symName: __ZNSt3__113__rewrap_iterB8ue170006INS_16reverse_iteratorIPiEES3_NS_18__unwrap_iter_implIS3_Lb0EEEEET_S6_T0_, symObjAddr: 0x2C44, symBinAddr: 0x100007700, symSize: 0x88 } - - { offsetInCU: 0x874B, offset: 0x147C9, size: 0x8, addend: 0x0, symName: __ZNSt3__122__make_exception_guardB8ue170006INS_6vectorIiNS_9allocatorIiEEE16__destroy_vectorEEENS_28__exception_guard_exceptionsIT_EES7_, symObjAddr: 0x31D0, symBinAddr: 0x100007C8C, symSize: 0x40 } - - { offsetInCU: 0x8780, offset: 0x147FE, size: 0x8, addend: 0x0, symName: __ZNSt3__130__uninitialized_allocator_copyB8ue170006INS_9allocatorIiEEPiS3_S3_EET2_RT_T0_T1_S4_, symObjAddr: 0x33F0, symBinAddr: 0x100007EAC, symSize: 0x80 } - - { offsetInCU: 0x881D, offset: 0x1489B, size: 0x8, addend: 0x0, symName: __ZNSt3__114__unwrap_rangeB8ue170006IPiS1_EENS_4pairIT0_S3_EET_S5_, symObjAddr: 0x3470, symBinAddr: 0x100007F2C, symSize: 0x60 } - - { offsetInCU: 0x8869, offset: 0x148E7, size: 0x8, addend: 0x0, symName: __ZNSt3__135__uninitialized_allocator_copy_implB8ue170006INS_9allocatorIiEEPiS3_S3_EET2_RT_T0_T1_S4_, symObjAddr: 0x34D0, symBinAddr: 0x100007F8C, symSize: 0xFC } - - { offsetInCU: 0x8907, offset: 0x14985, size: 0x8, addend: 0x0, symName: __ZNSt3__113__unwrap_iterB8ue170006IPiNS_18__unwrap_iter_implIS1_Lb1EEELi0EEEDTclsrT0_8__unwrapclsr3stdE7declvalIT_EEEES5_, symObjAddr: 0x35CC, symBinAddr: 0x100008088, symSize: 0x24 } - - { offsetInCU: 0x894B, offset: 0x149C9, size: 0x8, addend: 0x0, symName: __ZNSt3__113__rewrap_iterB8ue170006IPiS1_NS_18__unwrap_iter_implIS1_Lb1EEEEET_S4_T0_, symObjAddr: 0x35F0, symBinAddr: 0x1000080AC, symSize: 0x50 } - - { offsetInCU: 0x89A0, offset: 0x14A1E, size: 0x8, addend: 0x0, symName: __ZNSt3__19make_pairB8ue170006IPiS1_EENS_4pairINS_18__unwrap_ref_decayIT_E4typeENS3_IT0_E4typeEEEOS4_OS7_, symObjAddr: 0x3640, symBinAddr: 0x1000080FC, symSize: 0x38 } - - { offsetInCU: 0x8A9C, offset: 0x14B1A, size: 0x8, addend: 0x0, symName: __ZNSt3__122__make_exception_guardB8ue170006INS_29_AllocatorDestroyRangeReverseINS_9allocatorIiEEPiEEEENS_28__exception_guard_exceptionsIT_EES7_, symObjAddr: 0x36E8, symBinAddr: 0x1000081A4, symSize: 0x4C } - - { offsetInCU: 0x8AD2, offset: 0x14B50, size: 0x8, addend: 0x0, symName: __ZNSt3__119__allocator_destroyB8ue170006INS_9allocatorIiEENS_16reverse_iteratorIPiEES5_EEvRT_T0_T1_, symObjAddr: 0x3968, symBinAddr: 0x100008424, symSize: 0x70 } - - { offsetInCU: 0x8BBB, offset: 0x14C39, size: 0x8, addend: 0x0, symName: __ZNSt3__116__pad_and_outputB8ue170006IcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_, symObjAddr: 0x4FE4, symBinAddr: 0x100008DF0, symSize: 0x248 } - - { offsetInCU: 0x8C8B, offset: 0x14D09, size: 0x8, addend: 0x0, symName: __ZNSt3__19use_facetB8ue170006INS_5ctypeIcEEEERKT_RKNS_6localeE, symObjAddr: 0x582C, symBinAddr: 0x1000093A0, symSize: 0x2C } - - { offsetInCU: 0x96EE, offset: 0x1576C, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE26__swap_out_circular_bufferERNS_14__split_bufferIiRS2_EE, symObjAddr: 0x1CE8, symBinAddr: 0x100006888, symSize: 0x110 } - - { offsetInCU: 0xB5CF, offset: 0x1764D, size: 0x8, addend: 0x0, symName: __Z26get_character_From_Keycodeiii, symObjAddr: 0x0, symBinAddr: 0x100005324, symSize: 0x1EC } - - { offsetInCU: 0xB66B, offset: 0x176E9, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEC1B8ue170006Ev, symObjAddr: 0x1EC, symBinAddr: 0x100005510, symSize: 0x2C } - - { offsetInCU: 0xB693, offset: 0x17711, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEEC1B8ue170006Ev, symObjAddr: 0x218, symBinAddr: 0x10000553C, symSize: 0x2C } - - { offsetInCU: 0xB6BA, offset: 0x17738, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE9push_backB8ue170006ERKi, symObjAddr: 0x244, symBinAddr: 0x100005568, symSize: 0x6C } - - { offsetInCU: 0xB6EF, offset: 0x1776D, size: 0x8, addend: 0x0, symName: __Z26get_character_From_KeycodeNSt3__16vectorIiNS_9allocatorIiEEEEiPK16UCKeyboardLayout, symObjAddr: 0x2B0, symBinAddr: 0x1000055D4, symSize: 0x21C } - - { offsetInCU: 0xB7D7, offset: 0x17855, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEEC1ERKS3_, symObjAddr: 0x4CC, symBinAddr: 0x1000057F0, symSize: 0x34 } - - { offsetInCU: 0xB810, offset: 0x1788E, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEaSERKS5_, symObjAddr: 0x500, symBinAddr: 0x100005824, symSize: 0x108 } - - { offsetInCU: 0xB846, offset: 0x178C4, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEED1B8ue170006Ev, symObjAddr: 0x640, symBinAddr: 0x10000592C, symSize: 0x2C } - - { offsetInCU: 0xB86E, offset: 0x178EC, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorIiNS_9allocatorIiEEE4sizeB8ue170006Ev, symObjAddr: 0x66C, symBinAddr: 0x100005958, symSize: 0x28 } - - { offsetInCU: 0xB892, offset: 0x17910, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEEixB8ue170006Em, symObjAddr: 0x694, symBinAddr: 0x100005980, symSize: 0x24 } - - { offsetInCU: 0xB8CC, offset: 0x1794A, size: 0x8, addend: 0x0, symName: __Z23get_keyval_From_Keycodeiii, symObjAddr: 0x6EC, symBinAddr: 0x1000059A4, symSize: 0x158 } - - { offsetInCU: 0xB965, offset: 0x179E3, size: 0x8, addend: 0x0, symName: __Z23get_keyval_From_KeycodeNSt3__16vectorIiNS_9allocatorIiEEEEiPK16UCKeyboardLayout, symObjAddr: 0x844, symBinAddr: 0x100005AFC, symSize: 0x1E8 } - - { offsetInCU: 0xBA4D, offset: 0x17ACB, size: 0x8, addend: 0x0, symName: __Z4fun3v, symObjAddr: 0xA2C, symBinAddr: 0x100005CE4, symSize: 0x24 } - - { offsetInCU: 0xBA68, offset: 0x17AE6, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEC2B8ue170006Ev, symObjAddr: 0xA98, symBinAddr: 0x100005D50, symSize: 0x3C } - - { offsetInCU: 0xBA95, offset: 0x17B13, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE14__default_initB8ue170006Ev, symObjAddr: 0xB10, symBinAddr: 0x100005D8C, symSize: 0xB0 } - - { offsetInCU: 0xBAE5, offset: 0x17B63, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIDsEEE8allocateB8ue170006ERS2_m, symObjAddr: 0xD48, symBinAddr: 0x100005E3C, symSize: 0x2C } - - { offsetInCU: 0xBB17, offset: 0x17B95, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEEC2B8ue170006Ev, symObjAddr: 0x12C8, symBinAddr: 0x100005E68, symSize: 0x44 } - - { offsetInCU: 0xBB44, offset: 0x17BC2, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPiNS_9allocatorIiEEEC1B8ue170006IDnNS_18__default_init_tagEEEOT_OT0_, symObjAddr: 0x130C, symBinAddr: 0x100005EAC, symSize: 0x3C } - - { offsetInCU: 0xBB9A, offset: 0x17C18, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPiNS_9allocatorIiEEEC2B8ue170006IDnNS_18__default_init_tagEEEOT_OT0_, symObjAddr: 0x1348, symBinAddr: 0x100005EE8, symSize: 0x40 } - - { offsetInCU: 0xBBF0, offset: 0x17C6E, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemIPiLi0ELb0EEC2B8ue170006IDnvEEOT_, symObjAddr: 0x1388, symBinAddr: 0x100005F28, symSize: 0x1C } - - { offsetInCU: 0xBC30, offset: 0x17CAE, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorIiEELi1ELb1EEC2B8ue170006ENS_18__default_init_tagE, symObjAddr: 0x13A4, symBinAddr: 0x100005F44, symSize: 0x2C } - - { offsetInCU: 0xBC62, offset: 0x17CE0, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorIiEC2B8ue170006Ev, symObjAddr: 0x13D0, symBinAddr: 0x100005F70, symSize: 0x2C } - - { offsetInCU: 0xBC8A, offset: 0x17D08, size: 0x8, addend: 0x0, symName: __ZNSt3__116__non_trivial_ifILb1ENS_9allocatorIiEEEC2B8ue170006Ev, symObjAddr: 0x13FC, symBinAddr: 0x100005F9C, symSize: 0x14 } - - { offsetInCU: 0xBCB2, offset: 0x17D30, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEED2B8ue170006Ev, symObjAddr: 0x1410, symBinAddr: 0x100005FB0, symSize: 0x3C } - - { offsetInCU: 0xBCDA, offset: 0x17D58, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE16__destroy_vectorC1B8ue170006ERS3_, symObjAddr: 0x144C, symBinAddr: 0x100005FEC, symSize: 0x34 } - - { offsetInCU: 0xBD11, offset: 0x17D8F, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE16__destroy_vectorclB8ue170006Ev, symObjAddr: 0x1480, symBinAddr: 0x100006020, symSize: 0x90 } - - { offsetInCU: 0xBD35, offset: 0x17DB3, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE16__destroy_vectorC2B8ue170006ERS3_, symObjAddr: 0x1510, symBinAddr: 0x1000060B0, symSize: 0x20 } - - { offsetInCU: 0xBD6C, offset: 0x17DEA, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE7__clearB8ue170006Ev, symObjAddr: 0x1530, symBinAddr: 0x1000060D0, symSize: 0x28 } - - { offsetInCU: 0xBD90, offset: 0x17E0E, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorIiNS_9allocatorIiEEE17__annotate_deleteB8ue170006Ev, symObjAddr: 0x1558, symBinAddr: 0x1000060F8, symSize: 0xB8 } - - { offsetInCU: 0xBDB4, offset: 0x17E32, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIiEEE10deallocateB8ue170006ERS2_Pim, symObjAddr: 0x1610, symBinAddr: 0x1000061B0, symSize: 0x34 } - - { offsetInCU: 0xBDF5, offset: 0x17E73, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE7__allocB8ue170006Ev, symObjAddr: 0x1644, symBinAddr: 0x1000061E4, symSize: 0x28 } - - { offsetInCU: 0xBE19, offset: 0x17E97, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorIiNS_9allocatorIiEEE8capacityB8ue170006Ev, symObjAddr: 0x166C, symBinAddr: 0x10000620C, symSize: 0x40 } - - { offsetInCU: 0xBE3D, offset: 0x17EBB, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE22__base_destruct_at_endB8ue170006EPi, symObjAddr: 0x16AC, symBinAddr: 0x10000624C, symSize: 0xA0 } - - { offsetInCU: 0xBE7F, offset: 0x17EFD, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIiEEE7destroyB8ue170006IivEEvRS2_PT_, symObjAddr: 0x174C, symBinAddr: 0x1000062EC, symSize: 0x2C } - - { offsetInCU: 0xBEBB, offset: 0x17F39, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorIiE7destroyB8ue170006EPi, symObjAddr: 0x178C, symBinAddr: 0x10000632C, symSize: 0x14 } - - { offsetInCU: 0xBEED, offset: 0x17F6B, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorIiNS_9allocatorIiEEE31__annotate_contiguous_containerB8ue170006EPKvS5_S5_S5_, symObjAddr: 0x17A0, symBinAddr: 0x100006340, symSize: 0x20 } - - { offsetInCU: 0xBF41, offset: 0x17FBF, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorIiNS_9allocatorIiEEE4dataB8ue170006Ev, symObjAddr: 0x17C0, symBinAddr: 0x100006360, symSize: 0x28 } - - { offsetInCU: 0xBF65, offset: 0x17FE3, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorIiE10deallocateB8ue170006EPim, symObjAddr: 0x17E8, symBinAddr: 0x100006388, symSize: 0x70 } - - { offsetInCU: 0xBFA5, offset: 0x18023, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPiNS_9allocatorIiEEE6secondB8ue170006Ev, symObjAddr: 0x1858, symBinAddr: 0x1000063F8, symSize: 0x24 } - - { offsetInCU: 0xBFC9, offset: 0x18047, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorIiEELi1ELb1EE5__getB8ue170006Ev, symObjAddr: 0x187C, symBinAddr: 0x10000641C, symSize: 0x14 } - - { offsetInCU: 0xBFED, offset: 0x1806B, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorIiNS_9allocatorIiEEE9__end_capB8ue170006Ev, symObjAddr: 0x1890, symBinAddr: 0x100006430, symSize: 0x28 } - - { offsetInCU: 0xC011, offset: 0x1808F, size: 0x8, addend: 0x0, symName: __ZNKSt3__117__compressed_pairIPiNS_9allocatorIiEEE5firstB8ue170006Ev, symObjAddr: 0x18B8, symBinAddr: 0x100006458, symSize: 0x24 } - - { offsetInCU: 0xC035, offset: 0x180B3, size: 0x8, addend: 0x0, symName: __ZNKSt3__122__compressed_pair_elemIPiLi0ELb0EE5__getB8ue170006Ev, symObjAddr: 0x18DC, symBinAddr: 0x10000647C, symSize: 0x14 } - - { offsetInCU: 0xC059, offset: 0x180D7, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE9__end_capB8ue170006Ev, symObjAddr: 0x18F0, symBinAddr: 0x100006490, symSize: 0x28 } - - { offsetInCU: 0xC07D, offset: 0x180FB, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE22__construct_one_at_endB8ue170006IJRKiEEEvDpOT_, symObjAddr: 0x1918, symBinAddr: 0x1000064B8, symSize: 0x98 } - - { offsetInCU: 0xC0C9, offset: 0x18147, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE21__push_back_slow_pathIRKiEEvOT_, symObjAddr: 0x19B0, symBinAddr: 0x100006550, symSize: 0xE0 } - - { offsetInCU: 0xC126, offset: 0x181A4, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPiNS_9allocatorIiEEE5firstB8ue170006Ev, symObjAddr: 0x1A90, symBinAddr: 0x100006630, symSize: 0x24 } - - { offsetInCU: 0xC14A, offset: 0x181C8, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemIPiLi0ELb0EE5__getB8ue170006Ev, symObjAddr: 0x1AB4, symBinAddr: 0x100006654, symSize: 0x14 } - - { offsetInCU: 0xC187, offset: 0x18205, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE21_ConstructTransactionC1B8ue170006ERS3_m, symObjAddr: 0x1AC8, symBinAddr: 0x100006668, symSize: 0x3C } - - { offsetInCU: 0xC1CD, offset: 0x1824B, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIiEEE9constructB8ue170006IiJRKiEvEEvRS2_PT_DpOT0_, symObjAddr: 0x1B04, symBinAddr: 0x1000066A4, symSize: 0x34 } - - { offsetInCU: 0xC223, offset: 0x182A1, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE21_ConstructTransactionD1B8ue170006Ev, symObjAddr: 0x1B38, symBinAddr: 0x1000066D8, symSize: 0x2C } - - { offsetInCU: 0xC24B, offset: 0x182C9, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE21_ConstructTransactionC2B8ue170006ERS3_m, symObjAddr: 0x1B64, symBinAddr: 0x100006704, symSize: 0x44 } - - { offsetInCU: 0xC291, offset: 0x1830F, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorIiE9constructB8ue170006IiJRKiEEEvPT_DpOT0_, symObjAddr: 0x1BA8, symBinAddr: 0x100006748, symSize: 0x28 } - - { offsetInCU: 0xC2E5, offset: 0x18363, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE21_ConstructTransactionD2B8ue170006Ev, symObjAddr: 0x1BD0, symBinAddr: 0x100006770, symSize: 0x20 } - - { offsetInCU: 0xC30C, offset: 0x1838A, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorIiNS_9allocatorIiEEE11__recommendB8ue170006Em, symObjAddr: 0x1BF0, symBinAddr: 0x100006790, symSize: 0xB4 } - - { offsetInCU: 0xC360, offset: 0x183DE, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferIiRNS_9allocatorIiEEEC1EmmS3_, symObjAddr: 0x1CA4, symBinAddr: 0x100006844, symSize: 0x44 } - - { offsetInCU: 0xC3B5, offset: 0x18433, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferIiRNS_9allocatorIiEEED1Ev, symObjAddr: 0x1DF8, symBinAddr: 0x100006998, symSize: 0x2C } - - { offsetInCU: 0xC3DF, offset: 0x1845D, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorIiNS_9allocatorIiEEE8max_sizeEv, symObjAddr: 0x1E24, symBinAddr: 0x1000069C4, symSize: 0x74 } - - { offsetInCU: 0xC406, offset: 0x18484, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorIiNS_9allocatorIiEEE20__throw_length_errorB8ue170006Ev, symObjAddr: 0x1E98, symBinAddr: 0x100006A38, symSize: 0x1C } - - { offsetInCU: 0xC434, offset: 0x184B2, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIiEEE8max_sizeB8ue170006IS2_vEEmRKS2_, symObjAddr: 0x1F0C, symBinAddr: 0x100006AAC, symSize: 0x24 } - - { offsetInCU: 0xC461, offset: 0x184DF, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorIiNS_9allocatorIiEEE7__allocB8ue170006Ev, symObjAddr: 0x1F30, symBinAddr: 0x100006AD0, symSize: 0x28 } - - { offsetInCU: 0xC485, offset: 0x18503, size: 0x8, addend: 0x0, symName: __ZNSt3__114numeric_limitsIlE3maxB8ue170006Ev, symObjAddr: 0x1F58, symBinAddr: 0x100006AF8, symSize: 0x14 } - - { offsetInCU: 0xC4AC, offset: 0x1852A, size: 0x8, addend: 0x0, symName: __ZNKSt3__16__lessIvvEclB8ue170006ImmEEbRKT_RKT0_, symObjAddr: 0x1FC0, symBinAddr: 0x100006B60, symSize: 0x34 } - - { offsetInCU: 0xC4FE, offset: 0x1857C, size: 0x8, addend: 0x0, symName: __ZNKSt3__19allocatorIiE8max_sizeB8ue170006Ev, symObjAddr: 0x1FF4, symBinAddr: 0x100006B94, symSize: 0x14 } - - { offsetInCU: 0xC522, offset: 0x185A0, size: 0x8, addend: 0x0, symName: __ZNKSt3__117__compressed_pairIPiNS_9allocatorIiEEE6secondB8ue170006Ev, symObjAddr: 0x2008, symBinAddr: 0x100006BA8, symSize: 0x24 } - - { offsetInCU: 0xC546, offset: 0x185C4, size: 0x8, addend: 0x0, symName: __ZNKSt3__122__compressed_pair_elemINS_9allocatorIiEELi1ELb1EE5__getB8ue170006Ev, symObjAddr: 0x202C, symBinAddr: 0x100006BCC, symSize: 0x14 } - - { offsetInCU: 0xC56A, offset: 0x185E8, size: 0x8, addend: 0x0, symName: __ZNSt3__123__libcpp_numeric_limitsIlLb1EE3maxB8ue170006Ev, symObjAddr: 0x2040, symBinAddr: 0x100006BE0, symSize: 0x8 } - - { offsetInCU: 0xC57D, offset: 0x185FB, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferIiRNS_9allocatorIiEEEC2EmmS3_, symObjAddr: 0x2180, symBinAddr: 0x100006C3C, symSize: 0xD4 } - - { offsetInCU: 0xC5EF, offset: 0x1866D, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPiRNS_9allocatorIiEEEC1B8ue170006IDnS4_EEOT_OT0_, symObjAddr: 0x2254, symBinAddr: 0x100006D10, symSize: 0x3C } - - { offsetInCU: 0xC645, offset: 0x186C3, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferIiRNS_9allocatorIiEEE7__allocB8ue170006Ev, symObjAddr: 0x22D0, symBinAddr: 0x100006D8C, symSize: 0x28 } - - { offsetInCU: 0xC669, offset: 0x186E7, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferIiRNS_9allocatorIiEEE9__end_capB8ue170006Ev, symObjAddr: 0x22F8, symBinAddr: 0x100006DB4, symSize: 0x28 } - - { offsetInCU: 0xC68D, offset: 0x1870B, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPiRNS_9allocatorIiEEEC2B8ue170006IDnS4_EEOT_OT0_, symObjAddr: 0x2320, symBinAddr: 0x100006DDC, symSize: 0x48 } - - { offsetInCU: 0xC6E3, offset: 0x18761, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemIRNS_9allocatorIiEELi1ELb0EEC2B8ue170006IS3_vEEOT_, symObjAddr: 0x2368, symBinAddr: 0x100006E24, symSize: 0x20 } - - { offsetInCU: 0xC723, offset: 0x187A1, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorIiE8allocateB8ue170006Em, symObjAddr: 0x2388, symBinAddr: 0x100006E44, symSize: 0x84 } - - { offsetInCU: 0xC755, offset: 0x187D3, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPiRNS_9allocatorIiEEE6secondB8ue170006Ev, symObjAddr: 0x240C, symBinAddr: 0x100006EC8, symSize: 0x28 } - - { offsetInCU: 0xC779, offset: 0x187F7, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemIRNS_9allocatorIiEELi1ELb0EE5__getB8ue170006Ev, symObjAddr: 0x2434, symBinAddr: 0x100006EF0, symSize: 0x18 } - - { offsetInCU: 0xC79D, offset: 0x1881B, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPiRNS_9allocatorIiEEE5firstB8ue170006Ev, symObjAddr: 0x244C, symBinAddr: 0x100006F08, symSize: 0x24 } - - { offsetInCU: 0xC7C1, offset: 0x1883F, size: 0x8, addend: 0x0, symName: __ZNSt3__116reverse_iteratorIPiEC1B8ue170006ES1_, symObjAddr: 0x2558, symBinAddr: 0x100007014, symSize: 0x34 } - - { offsetInCU: 0xC7F7, offset: 0x18875, size: 0x8, addend: 0x0, symName: __ZNKSt3__116reverse_iteratorIPiE4baseB8ue170006Ev, symObjAddr: 0x258C, symBinAddr: 0x100007048, symSize: 0x18 } - - { offsetInCU: 0xC81B, offset: 0x18899, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorIiNS_9allocatorIiEEE14__annotate_newB8ue170006Em, symObjAddr: 0x25E0, symBinAddr: 0x10000709C, symSize: 0xAC } - - { offsetInCU: 0xC84E, offset: 0x188CC, size: 0x8, addend: 0x0, symName: __ZNKSt3__116reverse_iteratorIPiEdeB8ue170006Ev, symObjAddr: 0x2724, symBinAddr: 0x1000071E0, symSize: 0x28 } - - { offsetInCU: 0xC880, offset: 0x188FE, size: 0x8, addend: 0x0, symName: __ZNSt3__116reverse_iteratorIPiEppB8ue170006Ev, symObjAddr: 0x274C, symBinAddr: 0x100007208, symSize: 0x20 } - - { offsetInCU: 0xC8A9, offset: 0x18927, size: 0x8, addend: 0x0, symName: __ZNSt3__119__to_address_helperINS_16reverse_iteratorIPiEEvE6__callB8ue170006ERKS3_, symObjAddr: 0x27E4, symBinAddr: 0x1000072A0, symSize: 0x4C } - - { offsetInCU: 0xC8CB, offset: 0x18949, size: 0x8, addend: 0x0, symName: __ZNKSt3__116reverse_iteratorIPiEptB8ue170006Ev, symObjAddr: 0x2830, symBinAddr: 0x1000072EC, symSize: 0x24 } - - { offsetInCU: 0xC912, offset: 0x18990, size: 0x8, addend: 0x0, symName: __ZNKSt3__111__move_loopINS_17_ClassicAlgPolicyEEclB8ue170006INS_16reverse_iteratorIPiEES6_S6_EENS_4pairIT_T1_EES8_T0_S9_, symObjAddr: 0x2ACC, symBinAddr: 0x100007588, symSize: 0xA0 } - - { offsetInCU: 0xC980, offset: 0x189FE, size: 0x8, addend: 0x0, symName: __ZNSt3__18_IterOpsINS_17_ClassicAlgPolicyEE11__iter_moveB8ue170006IRNS_16reverse_iteratorIPiEEEENS_9enable_ifIXsr12is_referenceIDTdeclsr3stdE7declvalIRT_EEEEE5valueEDTclsr3stdE4movedeclsr3stdE7declvalISA_EEEEE4typeEOS9_, symObjAddr: 0x2CCC, symBinAddr: 0x100007788, symSize: 0x28 } - - { offsetInCU: 0xC9AB, offset: 0x18A29, size: 0x8, addend: 0x0, symName: __ZNSt3__18_IterOpsINS_17_ClassicAlgPolicyEE25__validate_iter_referenceB8ue170006IRNS_16reverse_iteratorIPiEEEEvv, symObjAddr: 0x2CF4, symBinAddr: 0x1000077B0, symSize: 0x4 } - - { offsetInCU: 0xC9C8, offset: 0x18A46, size: 0x8, addend: 0x0, symName: __ZNSt3__118__unwrap_iter_implINS_16reverse_iteratorIPiEELb0EE8__unwrapB8ue170006ES3_, symObjAddr: 0x2CF8, symBinAddr: 0x1000077B4, symSize: 0x24 } - - { offsetInCU: 0xC9EA, offset: 0x18A68, size: 0x8, addend: 0x0, symName: __ZNSt3__14pairINS_16reverse_iteratorIPiEES3_EC1B8ue170006ERKS3_S6_, symObjAddr: 0x2D1C, symBinAddr: 0x1000077D8, symSize: 0x3C } - - { offsetInCU: 0xCA2E, offset: 0x18AAC, size: 0x8, addend: 0x0, symName: __ZNSt3__14pairINS_16reverse_iteratorIPiEES3_EC2B8ue170006ERKS3_S6_, symObjAddr: 0x2D58, symBinAddr: 0x100007814, symSize: 0x34 } - - { offsetInCU: 0xCA72, offset: 0x18AF0, size: 0x8, addend: 0x0, symName: __ZNSt3__118__unwrap_iter_implINS_16reverse_iteratorIPiEELb0EE8__rewrapB8ue170006ES3_S3_, symObjAddr: 0x2D8C, symBinAddr: 0x100007848, symSize: 0x2C } - - { offsetInCU: 0xCA9E, offset: 0x18B1C, size: 0x8, addend: 0x0, symName: __ZNSt3__116reverse_iteratorIPiEC2B8ue170006ES1_, symObjAddr: 0x2DB8, symBinAddr: 0x100007874, symSize: 0x28 } - - { offsetInCU: 0xCAD4, offset: 0x18B52, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferIiRNS_9allocatorIiEEED2Ev, symObjAddr: 0x2DE0, symBinAddr: 0x10000789C, symSize: 0x80 } - - { offsetInCU: 0xCAFF, offset: 0x18B7D, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferIiRNS_9allocatorIiEEE5clearB8ue170006Ev, symObjAddr: 0x2E60, symBinAddr: 0x10000791C, symSize: 0x28 } - - { offsetInCU: 0xCB23, offset: 0x18BA1, size: 0x8, addend: 0x0, symName: __ZNKSt3__114__split_bufferIiRNS_9allocatorIiEEE8capacityB8ue170006Ev, symObjAddr: 0x2E88, symBinAddr: 0x100007944, symSize: 0x40 } - - { offsetInCU: 0xCB47, offset: 0x18BC5, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferIiRNS_9allocatorIiEEE17__destruct_at_endB8ue170006EPi, symObjAddr: 0x2EC8, symBinAddr: 0x100007984, symSize: 0x2C } - - { offsetInCU: 0xCB78, offset: 0x18BF6, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferIiRNS_9allocatorIiEEE17__destruct_at_endB8ue170006EPiNS_17integral_constantIbLb0EEE, symObjAddr: 0x2EF4, symBinAddr: 0x1000079B0, symSize: 0x94 } - - { offsetInCU: 0xCBB7, offset: 0x18C35, size: 0x8, addend: 0x0, symName: __ZNKSt3__114__split_bufferIiRNS_9allocatorIiEEE9__end_capB8ue170006Ev, symObjAddr: 0x2F88, symBinAddr: 0x100007A44, symSize: 0x28 } - - { offsetInCU: 0xCBDB, offset: 0x18C59, size: 0x8, addend: 0x0, symName: __ZNKSt3__117__compressed_pairIPiRNS_9allocatorIiEEE5firstB8ue170006Ev, symObjAddr: 0x2FB0, symBinAddr: 0x100007A6C, symSize: 0x24 } - - { offsetInCU: 0xCBFF, offset: 0x18C7D, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEEC2ERKS3_, symObjAddr: 0x2FD4, symBinAddr: 0x100007A90, symSize: 0x94 } - - { offsetInCU: 0xCC39, offset: 0x18CB7, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIiEEE37select_on_container_copy_constructionB8ue170006IS2_vvEES2_RKS2_, symObjAddr: 0x3068, symBinAddr: 0x100007B24, symSize: 0x10 } - - { offsetInCU: 0xCC6C, offset: 0x18CEA, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPiNS_9allocatorIiEEEC1B8ue170006IDnS3_EEOT_OT0_, symObjAddr: 0x3078, symBinAddr: 0x100007B34, symSize: 0x3C } - - { offsetInCU: 0xCCC2, offset: 0x18D40, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE16__init_with_sizeB8ue170006IPiS5_EEvT_T0_m, symObjAddr: 0x30B4, symBinAddr: 0x100007B70, symSize: 0xC0 } - - { offsetInCU: 0xCD34, offset: 0x18DB2, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPiNS_9allocatorIiEEEC2B8ue170006IDnS3_EEOT_OT0_, symObjAddr: 0x3174, symBinAddr: 0x100007C30, symSize: 0x44 } - - { offsetInCU: 0xCD8A, offset: 0x18E08, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorIiEELi1ELb1EEC2B8ue170006IS2_vEEOT_, symObjAddr: 0x31B8, symBinAddr: 0x100007C74, symSize: 0x18 } - - { offsetInCU: 0xCDCA, offset: 0x18E48, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE11__vallocateB8ue170006Em, symObjAddr: 0x3210, symBinAddr: 0x100007CCC, symSize: 0xAC } - - { offsetInCU: 0xCE0B, offset: 0x18E89, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorIiNS_9allocatorIiEEE18__construct_at_endIPiS5_EEvT_T0_m, symObjAddr: 0x32BC, symBinAddr: 0x100007D78, symSize: 0x94 } - - { offsetInCU: 0xCE80, offset: 0x18EFE, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_6vectorIiNS_9allocatorIiEEE16__destroy_vectorEE10__completeB8ue170006Ev, symObjAddr: 0x3350, symBinAddr: 0x100007E0C, symSize: 0x1C } - - { offsetInCU: 0xCEA4, offset: 0x18F22, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_6vectorIiNS_9allocatorIiEEE16__destroy_vectorEED1B8ue170006Ev, symObjAddr: 0x336C, symBinAddr: 0x100007E28, symSize: 0x2C } - - { offsetInCU: 0xCECC, offset: 0x18F4A, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_6vectorIiNS_9allocatorIiEEE16__destroy_vectorEEC1B8ue170006ES5_, symObjAddr: 0x3398, symBinAddr: 0x100007E54, symSize: 0x34 } - - { offsetInCU: 0xCF02, offset: 0x18F80, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_6vectorIiNS_9allocatorIiEEE16__destroy_vectorEEC2B8ue170006ES5_, symObjAddr: 0x33CC, symBinAddr: 0x100007E88, symSize: 0x24 } - - { offsetInCU: 0xCF51, offset: 0x18FCF, size: 0x8, addend: 0x0, symName: __ZNSt3__14pairIPiS1_EC1B8ue170006ERKS1_S4_, symObjAddr: 0x3678, symBinAddr: 0x100008134, symSize: 0x3C } - - { offsetInCU: 0xCF95, offset: 0x19013, size: 0x8, addend: 0x0, symName: __ZNSt3__14pairIPiS1_EC2B8ue170006ERKS1_S4_, symObjAddr: 0x36B4, symBinAddr: 0x100008170, symSize: 0x34 } - - { offsetInCU: 0xCFD9, offset: 0x19057, size: 0x8, addend: 0x0, symName: __ZNSt3__129_AllocatorDestroyRangeReverseINS_9allocatorIiEEPiEC1B8ue170006ERS2_RS3_S6_, symObjAddr: 0x3734, symBinAddr: 0x1000081F0, symSize: 0x44 } - - { offsetInCU: 0xD02E, offset: 0x190AC, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIiEEE9constructB8ue170006IiJRiEvEEvRS2_PT_DpOT0_, symObjAddr: 0x3778, symBinAddr: 0x100008234, symSize: 0x34 } - - { offsetInCU: 0xD084, offset: 0x19102, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_29_AllocatorDestroyRangeReverseINS_9allocatorIiEEPiEEE10__completeB8ue170006Ev, symObjAddr: 0x37AC, symBinAddr: 0x100008268, symSize: 0x1C } - - { offsetInCU: 0xD0A8, offset: 0x19126, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_29_AllocatorDestroyRangeReverseINS_9allocatorIiEEPiEEED1B8ue170006Ev, symObjAddr: 0x37C8, symBinAddr: 0x100008284, symSize: 0x2C } - - { offsetInCU: 0xD0D0, offset: 0x1914E, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_29_AllocatorDestroyRangeReverseINS_9allocatorIiEEPiEEEC1B8ue170006ES5_, symObjAddr: 0x37F4, symBinAddr: 0x1000082B0, symSize: 0x34 } - - { offsetInCU: 0xD107, offset: 0x19185, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_29_AllocatorDestroyRangeReverseINS_9allocatorIiEEPiEEEC2B8ue170006ES5_, symObjAddr: 0x3828, symBinAddr: 0x1000082E4, symSize: 0x30 } - - { offsetInCU: 0xD13E, offset: 0x191BC, size: 0x8, addend: 0x0, symName: __ZNSt3__129_AllocatorDestroyRangeReverseINS_9allocatorIiEEPiEC2B8ue170006ERS2_RS3_S6_, symObjAddr: 0x3858, symBinAddr: 0x100008314, symSize: 0x38 } - - { offsetInCU: 0xD193, offset: 0x19211, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorIiE9constructB8ue170006IiJRiEEEvPT_DpOT0_, symObjAddr: 0x3890, symBinAddr: 0x10000834C, symSize: 0x28 } - - { offsetInCU: 0xD1E7, offset: 0x19265, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_29_AllocatorDestroyRangeReverseINS_9allocatorIiEEPiEEED2B8ue170006Ev, symObjAddr: 0x38B8, symBinAddr: 0x100008374, symSize: 0x48 } - - { offsetInCU: 0xD20F, offset: 0x1928D, size: 0x8, addend: 0x0, symName: __ZNKSt3__129_AllocatorDestroyRangeReverseINS_9allocatorIiEEPiEclB8ue170006Ev, symObjAddr: 0x3900, symBinAddr: 0x1000083BC, symSize: 0x68 } - - { offsetInCU: 0xD233, offset: 0x192B1, size: 0x8, addend: 0x0, symName: __ZNSt3__118__unwrap_iter_implIPiLb1EE8__unwrapB8ue170006ES1_, symObjAddr: 0x39D8, symBinAddr: 0x100008494, symSize: 0x24 } - - { offsetInCU: 0xD255, offset: 0x192D3, size: 0x8, addend: 0x0, symName: __ZNSt3__118__unwrap_iter_implIPiLb1EE8__rewrapB8ue170006ES1_S1_, symObjAddr: 0x39FC, symBinAddr: 0x1000084B8, symSize: 0x50 } - - { offsetInCU: 0xD285, offset: 0x19303, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_6vectorIiNS_9allocatorIiEEE16__destroy_vectorEED2B8ue170006Ev, symObjAddr: 0x3A4C, symBinAddr: 0x100008508, symSize: 0x48 } - - { offsetInCU: 0xD2AD, offset: 0x1932B, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE19__copy_assign_allocB8ue170006ERKS5_, symObjAddr: 0x3A94, symBinAddr: 0x100008550, symSize: 0x2C } - - { offsetInCU: 0xD2DF, offset: 0x1935D, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE17__assign_no_aliasILb1EEERS5_PKDsm, symObjAddr: 0x3AC0, symBinAddr: 0x10000857C, symSize: 0xE4 } - - { offsetInCU: 0xD377, offset: 0x193F5, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE4dataB8ue170006Ev, symObjAddr: 0x3BA4, symBinAddr: 0x100008660, symSize: 0x28 } - - { offsetInCU: 0xD39B, offset: 0x19419, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE4sizeB8ue170006Ev, symObjAddr: 0x3BCC, symBinAddr: 0x100008688, symSize: 0x54 } - - { offsetInCU: 0xD3BE, offset: 0x1943C, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE17__assign_no_aliasILb0EEERS5_PKDsm, symObjAddr: 0x3C20, symBinAddr: 0x1000086DC, symSize: 0xE4 } - - { offsetInCU: 0xD456, offset: 0x194D4, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE19__copy_assign_allocB8ue170006ERKS5_NS_17integral_constantIbLb0EEE, symObjAddr: 0x3D04, symBinAddr: 0x1000087C0, symSize: 0x14 } - - { offsetInCU: 0xD492, offset: 0x19510, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE16__get_short_sizeB8ue170006Ev, symObjAddr: 0x3E54, symBinAddr: 0x1000087D4, symSize: 0x34 } - - { offsetInCU: 0xD4B5, offset: 0x19533, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE21__grow_by_and_replaceEmmmmmmPKDs, symObjAddr: 0x3E88, symBinAddr: 0x100008808, symSize: 0x2A4 } - - { offsetInCU: 0xD5A2, offset: 0x19620, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE13__get_pointerB8ue170006Ev, symObjAddr: 0x4928, symBinAddr: 0x100008AAC, symSize: 0x54 } - - { offsetInCU: 0xD5C6, offset: 0x19644, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE13__get_pointerB8ue170006Ev, symObjAddr: 0x4A34, symBinAddr: 0x100008B00, symSize: 0x54 } - - { offsetInCU: 0xD5EA, offset: 0x19668, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE18__get_long_pointerB8ue170006Ev, symObjAddr: 0x4A88, symBinAddr: 0x100008B54, symSize: 0x28 } - - { offsetInCU: 0xD60E, offset: 0x1968C, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE19__get_short_pointerB8ue170006Ev, symObjAddr: 0x4AB0, symBinAddr: 0x100008B7C, symSize: 0x28 } - - { offsetInCU: 0xD632, offset: 0x196B0, size: 0x8, addend: 0x0, symName: __ZNSt3__114pointer_traitsIPKDsE10pointer_toB8ue170006ERS1_, symObjAddr: 0x4AD8, symBinAddr: 0x100008BA4, symSize: 0x14 } - - { offsetInCU: 0xD654, offset: 0x196D2, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE15__get_long_sizeB8ue170006Ev, symObjAddr: 0x4AEC, symBinAddr: 0x100008BB8, symSize: 0x28 } - - { offsetInCU: 0xD696, offset: 0x19714, size: 0x8, addend: 0x0, symName: __ZNKSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentrycvbB8ue170006Ev, symObjAddr: 0x4FC8, symBinAddr: 0x100008DD4, symSize: 0x1C } - - { offsetInCU: 0xD6BA, offset: 0x19738, size: 0x8, addend: 0x0, symName: __ZNSt3__119ostreambuf_iteratorIcNS_11char_traitsIcEEEC1B8ue170006ERNS_13basic_ostreamIcS2_EE, symObjAddr: 0x522C, symBinAddr: 0x100009038, symSize: 0x34 } - - { offsetInCU: 0xD6F0, offset: 0x1976E, size: 0x8, addend: 0x0, symName: __ZNKSt3__18ios_base5flagsB8ue170006Ev, symObjAddr: 0x5260, symBinAddr: 0x10000906C, symSize: 0x18 } - - { offsetInCU: 0xD716, offset: 0x19794, size: 0x8, addend: 0x0, symName: __ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE4fillB8ue170006Ev, symObjAddr: 0x5278, symBinAddr: 0x100009084, symSize: 0x64 } - - { offsetInCU: 0xD73D, offset: 0x197BB, size: 0x8, addend: 0x0, symName: __ZNKSt3__119ostreambuf_iteratorIcNS_11char_traitsIcEEE6failedB8ue170006Ev, symObjAddr: 0x52DC, symBinAddr: 0x1000090E8, symSize: 0x24 } - - { offsetInCU: 0xD761, offset: 0x197DF, size: 0x8, addend: 0x0, symName: __ZNSt3__19basic_iosIcNS_11char_traitsIcEEE8setstateB8ue170006Ej, symObjAddr: 0x5300, symBinAddr: 0x10000910C, symSize: 0x2C } - - { offsetInCU: 0xD794, offset: 0x19812, size: 0x8, addend: 0x0, symName: __ZNKSt3__18ios_base5widthB8ue170006Ev, symObjAddr: 0x532C, symBinAddr: 0x100009138, symSize: 0x18 } - - { offsetInCU: 0xD7BB, offset: 0x19839, size: 0x8, addend: 0x0, symName: __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5sputnB8ue170006EPKcl, symObjAddr: 0x5344, symBinAddr: 0x100009150, symSize: 0x3C } - - { offsetInCU: 0xD7FB, offset: 0x19879, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1B8ue170006Emc, symObjAddr: 0x5380, symBinAddr: 0x10000918C, symSize: 0x3C } - - { offsetInCU: 0xD841, offset: 0x198BF, size: 0x8, addend: 0x0, symName: __ZNSt3__18ios_base5widthB8ue170006El, symObjAddr: 0x53E4, symBinAddr: 0x1000091C8, symSize: 0x2C } - - { offsetInCU: 0xD886, offset: 0x19904, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2B8ue170006Emc, symObjAddr: 0x5410, symBinAddr: 0x1000091F4, symSize: 0x4C } - - { offsetInCU: 0xD8CC, offset: 0x1994A, size: 0x8, addend: 0x0, symName: __ZNSt3__119ostreambuf_iteratorIcNS_11char_traitsIcEEEC2B8ue170006ERNS_13basic_ostreamIcS2_EE, symObjAddr: 0x56CC, symBinAddr: 0x100009240, symSize: 0x68 } - - { offsetInCU: 0xD901, offset: 0x1997F, size: 0x8, addend: 0x0, symName: __ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE5rdbufB8ue170006Ev, symObjAddr: 0x5734, symBinAddr: 0x1000092A8, symSize: 0x24 } - - { offsetInCU: 0xD928, offset: 0x199A6, size: 0x8, addend: 0x0, symName: __ZNKSt3__18ios_base5rdbufB8ue170006Ev, symObjAddr: 0x5758, symBinAddr: 0x1000092CC, symSize: 0x18 } - - { offsetInCU: 0xD94C, offset: 0x199CA, size: 0x8, addend: 0x0, symName: __ZNSt3__111char_traitsIcE11eq_int_typeB8ue170006Eii, symObjAddr: 0x5770, symBinAddr: 0x1000092E4, symSize: 0x28 } - - { offsetInCU: 0xD97E, offset: 0x199FC, size: 0x8, addend: 0x0, symName: __ZNSt3__111char_traitsIcE3eofB8ue170006Ev, symObjAddr: 0x5798, symBinAddr: 0x10000930C, symSize: 0x8 } - - { offsetInCU: 0xD990, offset: 0x19A0E, size: 0x8, addend: 0x0, symName: __ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE5widenB8ue170006Ec, symObjAddr: 0x57A0, symBinAddr: 0x100009314, symSize: 0x8C } - - { offsetInCU: 0xD9F8, offset: 0x19A76, size: 0x8, addend: 0x0, symName: __ZNKSt3__15ctypeIcE5widenB8ue170006Ec, symObjAddr: 0x5858, symBinAddr: 0x1000093CC, symSize: 0x38 } - - { offsetInCU: 0xDA2A, offset: 0x19AA8, size: 0x8, addend: 0x0, symName: __ZNSt3__18ios_base8setstateB8ue170006Ej, symObjAddr: 0x5890, symBinAddr: 0x100009404, symSize: 0x34 } - - { offsetInCU: 0x7E9D, offset: 0x21AB4, size: 0x8, addend: 0x0, symName: _main, symObjAddr: 0x0, symBinAddr: 0x100009438, symSize: 0x104 } - - { offsetInCU: 0x7ED3, offset: 0x21AEA, size: 0x8, addend: 0x0, symName: __Z18testmyFunctions_S2v, symObjAddr: 0x14C, symBinAddr: 0x10000953C, symSize: 0x120 } - - { offsetInCU: 0x7FB8, offset: 0x21BCF, size: 0x8, addend: 0x0, symName: __Z4fun2v, symObjAddr: 0x2AC, symBinAddr: 0x10000965C, symSize: 0x24 } - - { offsetInCU: 0x941B, offset: 0x2B00E, size: 0x8, addend: 0x0, symName: __ZNSt3__112__to_addressB8ue170006INS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEEPT_S8_, symObjAddr: 0x2738, symBinAddr: 0x10000BCC0, symSize: 0x14 } - - { offsetInCU: 0x952A, offset: 0x2B11D, size: 0x8, addend: 0x0, symName: __ZNSt3__119__allocate_at_leastB8ue170006INS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEEEENS_19__allocation_resultINS_16allocator_traitsIT_E7pointerEEERSA_m, symObjAddr: 0x37A4, symBinAddr: 0x10000C604, symSize: 0x40 } - - { offsetInCU: 0x956D, offset: 0x2B160, size: 0x8, addend: 0x0, symName: __ZNSt3__142__uninitialized_allocator_move_if_noexceptB8ue170006INS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEENS_16reverse_iteratorIPS6_EESA_SA_EET2_RT_T0_T1_SB_, symObjAddr: 0x3A0C, symBinAddr: 0x10000C7EC, symSize: 0x134 } - - { offsetInCU: 0x960D, offset: 0x2B200, size: 0x8, addend: 0x0, symName: __ZNSt3__14swapB8ue170006IPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEEvRT_S9_, symObjAddr: 0x3B8C, symBinAddr: 0x10000C96C, symSize: 0x3C } - - { offsetInCU: 0x965E, offset: 0x2B251, size: 0x8, addend: 0x0, symName: __ZNSt3__122__make_exception_guardB8ue170006INS_29_AllocatorDestroyRangeReverseINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS2_IDsEEEEEENS_16reverse_iteratorIPS7_EEEEEENS_28__exception_guard_exceptionsIT_EESE_, symObjAddr: 0x3C90, symBinAddr: 0x10000CA70, symSize: 0x4C } - - { offsetInCU: 0x9694, offset: 0x2B287, size: 0x8, addend: 0x0, symName: __ZNSt3__1neB8ue170006IPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEES7_EEbRKNS_16reverse_iteratorIT_EERKNS8_IT0_EE, symObjAddr: 0x3D20, symBinAddr: 0x10000CB00, symSize: 0x48 } - - { offsetInCU: 0x96E0, offset: 0x2B2D3, size: 0x8, addend: 0x0, symName: __ZNSt3__112__to_addressB8ue170006INS_16reverse_iteratorIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEEvEEu7__decayIDTclsr19__to_address_helperIT_EE6__callclsr3stdE7declvalIRKSA_EEEEESC_, symObjAddr: 0x3D9C, symBinAddr: 0x10000CB7C, symSize: 0x24 } - - { offsetInCU: 0x9740, offset: 0x2B333, size: 0x8, addend: 0x0, symName: __ZNSt3__119__allocator_destroyB8ue170006INS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEENS_16reverse_iteratorINS8_IPS6_EEEESB_EEvRT_T0_T1_, symObjAddr: 0x4088, symBinAddr: 0x10000CE68, symSize: 0x70 } - - { offsetInCU: 0x97A5, offset: 0x2B398, size: 0x8, addend: 0x0, symName: __ZNSt3__1neB8ue170006INS_16reverse_iteratorIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEES9_EEbRKNS1_IT_EERKNS1_IT0_EE, symObjAddr: 0x4134, symBinAddr: 0x10000CF14, symSize: 0x60 } - - { offsetInCU: 0x97F1, offset: 0x2B3E4, size: 0x8, addend: 0x0, symName: __ZNSt3__112__to_addressB8ue170006INS_16reverse_iteratorINS1_IPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEEEEvEEu7__decayIDTclsr19__to_address_helperIT_EE6__callclsr3stdE7declvalIRKSB_EEEEESD_, symObjAddr: 0x4194, symBinAddr: 0x10000CF74, symSize: 0x24 } - - { offsetInCU: 0x9851, offset: 0x2B444, size: 0x8, addend: 0x0, symName: __ZNSt3__119__throw_range_errorB8ue170006EPKc, symObjAddr: 0x5D04, symBinAddr: 0x10000E4AC, symSize: 0x64 } - - { offsetInCU: 0x98AE, offset: 0x2B4A1, size: 0x8, addend: 0x0, symName: __ZNSt3__18distanceB8ue170006IPKcEENS_15iterator_traitsIT_E15difference_typeES4_S4_, symObjAddr: 0x5FA4, symBinAddr: 0x10000E654, symSize: 0x2C } - - { offsetInCU: 0x98F1, offset: 0x2B4E4, size: 0x8, addend: 0x0, symName: __ZNSt3__110__distanceB8ue170006IPKcEENS_15iterator_traitsIT_E15difference_typeES4_S4_NS_26random_access_iterator_tagE, symObjAddr: 0x6194, symBinAddr: 0x10000E81C, symSize: 0x20 } - - { offsetInCU: 0x993E, offset: 0x2B531, size: 0x8, addend: 0x0, symName: __ZNSt3__121__is_pointer_in_rangeB8ue170006IccLi0EEEbPKT_S3_PKT0_, symObjAddr: 0x61B4, symBinAddr: 0x10000E83C, symSize: 0xB8 } - - { offsetInCU: 0x999E, offset: 0x2B591, size: 0x8, addend: 0x0, symName: __ZNSt3__119__allocate_at_leastB8ue170006INS_9allocatorIcEEEENS_19__allocation_resultINS_16allocator_traitsIT_E7pointerEEERS5_m, symObjAddr: 0x66E0, symBinAddr: 0x10000ED68, symSize: 0x40 } - - { offsetInCU: 0x99E1, offset: 0x2B5D4, size: 0x8, addend: 0x0, symName: __ZNSt3__112__to_addressB8ue170006IKwEEPT_S3_, symObjAddr: 0x68E4, symBinAddr: 0x10000EE84, symSize: 0x14 } - - { offsetInCU: 0x9A7C, offset: 0x2B66F, size: 0x8, addend: 0x0, symName: __ZNSt3__18distanceB8ue170006IPKwEENS_15iterator_traitsIT_E15difference_typeES4_S4_, symObjAddr: 0x73B4, symBinAddr: 0x10000F954, symSize: 0x2C } - - { offsetInCU: 0x9ABF, offset: 0x2B6B2, size: 0x8, addend: 0x0, symName: __ZNSt3__110__distanceB8ue170006IPKwEENS_15iterator_traitsIT_E15difference_typeES4_S4_NS_26random_access_iterator_tagE, symObjAddr: 0x757C, symBinAddr: 0x10000FB1C, symSize: 0x28 } - - { offsetInCU: 0x9B0C, offset: 0x2B6FF, size: 0x8, addend: 0x0, symName: __ZNSt3__121__is_pointer_in_rangeB8ue170006IwwLi0EEEbPKT_S3_PKT0_, symObjAddr: 0x75A4, symBinAddr: 0x10000FB44, symSize: 0xB8 } - - { offsetInCU: 0x9B6C, offset: 0x2B75F, size: 0x8, addend: 0x0, symName: __ZNSt3__119__allocate_at_leastB8ue170006INS_9allocatorIwEEEENS_19__allocation_resultINS_16allocator_traitsIT_E7pointerEEERS5_m, symObjAddr: 0x7AD0, symBinAddr: 0x100010070, symSize: 0x40 } - - { offsetInCU: 0x9BAF, offset: 0x2B7A2, size: 0x8, addend: 0x0, symName: __ZNSt3__16fill_nB8ue170006IPDsmDsEET_S2_T0_RKT1_, symObjAddr: 0x9B1C, symBinAddr: 0x100011154, symSize: 0x44 } - - { offsetInCU: 0x9C12, offset: 0x2B805, size: 0x8, addend: 0x0, symName: __ZNSt3__18__fill_nB8ue170006IPDsmDsEET_S2_T0_RKT1_, symObjAddr: 0x9B60, symBinAddr: 0x100011198, symSize: 0x64 } - - { offsetInCU: 0x9C75, offset: 0x2B868, size: 0x8, addend: 0x0, symName: __ZNSt3__121__convert_to_integralB8ue170006Em, symObjAddr: 0x9BC4, symBinAddr: 0x1000111FC, symSize: 0x14 } - - { offsetInCU: 0x9CA1, offset: 0x2B894, size: 0x8, addend: 0x0, symName: __ZNSt3__18distanceB8ue170006IPKDsEENS_15iterator_traitsIT_E15difference_typeES4_S4_, symObjAddr: 0xA16C, symBinAddr: 0x10001171C, symSize: 0x2C } - - { offsetInCU: 0x9CE4, offset: 0x2B8D7, size: 0x8, addend: 0x0, symName: __ZNSt3__110__distanceB8ue170006IPKDsEENS_15iterator_traitsIT_E15difference_typeES4_S4_NS_26random_access_iterator_tagE, symObjAddr: 0xA388, symBinAddr: 0x100011910, symSize: 0x28 } - - { offsetInCU: 0x9D31, offset: 0x2B924, size: 0x8, addend: 0x0, symName: __ZNSt3__121__is_pointer_in_rangeB8ue170006IDsDsLi0EEEbPKT_S3_PKT0_, symObjAddr: 0xA3B0, symBinAddr: 0x100011938, symSize: 0xB8 } - - { offsetInCU: 0xA426, offset: 0x2C019, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE26__swap_out_circular_bufferERNS_14__split_bufferIS6_RS7_EE, symObjAddr: 0x31EC, symBinAddr: 0x10000C280, symSize: 0x110 } - - { offsetInCU: 0xA4E6, offset: 0x2C0D9, size: 0x8, addend: 0x0, symName: __Z3powB8ue170006IimENSt3__19enable_ifIXaasr3std13is_arithmeticIT_EE5valuesr3std13is_arithmeticIT0_EE5valueENS0_9__promoteIS2_S3_vEEE4type4typeES2_S3_, symObjAddr: 0x2230, symBinAddr: 0x10000B7B8, symSize: 0x3C } - - { offsetInCU: 0xABEA, offset: 0x2C7DD, size: 0x8, addend: 0x0, symName: __Z7toupperi, symObjAddr: 0x1BDC, symBinAddr: 0x10000B164, symSize: 0x24 } - - { offsetInCU: 0xAE4B, offset: 0x2CA3E, size: 0x8, addend: 0x0, symName: __Z8towupperi, symObjAddr: 0x220C, symBinAddr: 0x10000B794, symSize: 0x24 } - - { offsetInCU: 0xC2EE, offset: 0x2DEE1, size: 0x8, addend: 0x0, symName: __Z29convert_argv_to_Vector_u16striPPc, symObjAddr: 0x0, symBinAddr: 0x100009680, symSize: 0x1A8 } - - { offsetInCU: 0xC371, offset: 0x2DF64, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEEC1B8ue170006Ev, symObjAddr: 0x1A8, symBinAddr: 0x100009828, symSize: 0x2C } - - { offsetInCU: 0xC39D, offset: 0x2DF90, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE9push_backB8ue170006EOS6_, symObjAddr: 0x208, symBinAddr: 0x100009854, symSize: 0x6C } - - { offsetInCU: 0xC3D2, offset: 0x2DFC5, size: 0x8, addend: 0x0, symName: __Z21u16string_from_stringNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE, symObjAddr: 0x274, symBinAddr: 0x1000098C0, symSize: 0xEC } - - { offsetInCU: 0xC40F, offset: 0x2E002, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEED1B8ue170006Ev, symObjAddr: 0x398, symBinAddr: 0x1000099AC, symSize: 0x2C } - - { offsetInCU: 0xC436, offset: 0x2E029, size: 0x8, addend: 0x0, symName: __Z30convert_argvW_to_Vector_u16striPPw, symObjAddr: 0x3C4, symBinAddr: 0x1000099D8, symSize: 0x1AC } - - { offsetInCU: 0xC4BD, offset: 0x2E0B0, size: 0x8, addend: 0x0, symName: __Z22u16string_from_wstringNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEE, symObjAddr: 0x5A4, symBinAddr: 0x100009B84, symSize: 0x124 } - - { offsetInCU: 0xC507, offset: 0x2E0FA, size: 0x8, addend: 0x0, symName: __Z19string_from_wstringNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEE, symObjAddr: 0x6C8, symBinAddr: 0x100009CA8, symSize: 0xEC } - - { offsetInCU: 0xC5EF, offset: 0x2E1E2, size: 0x8, addend: 0x0, symName: __ZNSt3__112codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EEC1B8ue170006Em, symObjAddr: 0x7B4, symBinAddr: 0x100009D94, symSize: 0x34 } - - { offsetInCU: 0xC657, offset: 0x2E24A, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_12codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EEEwNS_9allocatorIwEENS4_IcEEEC1EPS3_, symObjAddr: 0x7E8, symBinAddr: 0x100009DC8, symSize: 0x34 } - - { offsetInCU: 0xC691, offset: 0x2E284, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_12codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EEEwNS_9allocatorIwEENS4_IcEEE8to_bytesB8ue170006ERKNS_12basic_stringIwNS_11char_traitsIwEES5_EE, symObjAddr: 0x81C, symBinAddr: 0x100009DFC, symSize: 0x6C } - - { offsetInCU: 0xC6C4, offset: 0x2E2B7, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_12codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EEEwNS_9allocatorIwEENS4_IcEEED1Ev, symObjAddr: 0x888, symBinAddr: 0x100009E68, symSize: 0x2C } - - { offsetInCU: 0xC6EE, offset: 0x2E2E1, size: 0x8, addend: 0x0, symName: __Z19wstring_from_stringNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE, symObjAddr: 0x8B4, symBinAddr: 0x100009E94, symSize: 0xEC } - - { offsetInCU: 0xC72B, offset: 0x2E31E, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_12codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EEEwNS_9allocatorIwEENS4_IcEEE10from_bytesB8ue170006ERKNS_12basic_stringIcNS_11char_traitsIcEES6_EE, symObjAddr: 0x9A0, symBinAddr: 0x100009F80, symSize: 0x6C } - - { offsetInCU: 0xC7EF, offset: 0x2E3E2, size: 0x8, addend: 0x0, symName: __ZNSt3__118codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EEC1B8ue170006Em, symObjAddr: 0xA0C, symBinAddr: 0x100009FEC, symSize: 0x34 } - - { offsetInCU: 0xC858, offset: 0x2E44B, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_18codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EEEDsNS_9allocatorIDsEENS4_IcEEEC1EPS3_, symObjAddr: 0xA40, symBinAddr: 0x10000A020, symSize: 0x34 } - - { offsetInCU: 0xC892, offset: 0x2E485, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_18codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EEEDsNS_9allocatorIDsEENS4_IcEEE10from_bytesB8ue170006ERKNS_12basic_stringIcNS_11char_traitsIcEES6_EE, symObjAddr: 0xA74, symBinAddr: 0x10000A054, symSize: 0x6C } - - { offsetInCU: 0xC8C5, offset: 0x2E4B8, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_18codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EEEDsNS_9allocatorIDsEENS4_IcEEED1Ev, symObjAddr: 0xAE0, symBinAddr: 0x10000A0C0, symSize: 0x2C } - - { offsetInCU: 0xC8EF, offset: 0x2E4E2, size: 0x8, addend: 0x0, symName: __Z21string_from_u16stringNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEE, symObjAddr: 0xB0C, symBinAddr: 0x10000A0EC, symSize: 0xEC } - - { offsetInCU: 0xC92C, offset: 0x2E51F, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_18codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EEEDsNS_9allocatorIDsEENS4_IcEEE8to_bytesB8ue170006ERKNS_12basic_stringIDsNS_11char_traitsIDsEES5_EE, symObjAddr: 0xBF8, symBinAddr: 0x10000A1D8, symSize: 0x6C } - - { offsetInCU: 0xC95E, offset: 0x2E551, size: 0x8, addend: 0x0, symName: __Z22wstring_from_u16stringNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEE, symObjAddr: 0xC64, symBinAddr: 0x10000A244, symSize: 0x124 } - - { offsetInCU: 0xC9A9, offset: 0x2E59C, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEC1ERKS5_, symObjAddr: 0xD88, symBinAddr: 0x10000A368, symSize: 0x34 } - - { offsetInCU: 0xC9DF, offset: 0x2E5D2, size: 0x8, addend: 0x0, symName: __Z6u16fmtPKDs, symObjAddr: 0xDBC, symBinAddr: 0x10000A39C, symSize: 0x1D8 } - - { offsetInCU: 0xCA49, offset: 0x2E63C, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_18codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EEEDsNS_9allocatorIDsEENS4_IcEEE8to_bytesB8ue170006EPKDs, symObjAddr: 0xF94, symBinAddr: 0x10000A574, symSize: 0x64 } - - { offsetInCU: 0xCA7C, offset: 0x2E66F, size: 0x8, addend: 0x0, symName: __Z10u16sprintfPDsmPKwz, symObjAddr: 0xFF8, symBinAddr: 0x10000A5D8, symSize: 0x264 } - - { offsetInCU: 0xCB1E, offset: 0x2E711, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_12codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EEEwNS_9allocatorIwEENS4_IcEEE8to_bytesB8ue170006EPKw, symObjAddr: 0x125C, symBinAddr: 0x10000A83C, symSize: 0x64 } - - { offsetInCU: 0xCB50, offset: 0x2E743, size: 0x8, addend: 0x0, symName: __Z7u16ncpyPDsPKDsm, symObjAddr: 0x12C0, symBinAddr: 0x10000A8A0, symSize: 0xD0 } - - { offsetInCU: 0xCBA7, offset: 0x2E79A, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5c_strB8ue170006Ev, symObjAddr: 0x1390, symBinAddr: 0x10000A970, symSize: 0x24 } - - { offsetInCU: 0xCBCA, offset: 0x2E7BD, size: 0x8, addend: 0x0, symName: __Z24convert_pchar16T_To_wstrPDs, symObjAddr: 0x13B4, symBinAddr: 0x10000A994, symSize: 0x160 } - - { offsetInCU: 0xCC26, offset: 0x2E819, size: 0x8, addend: 0x0, symName: __Z6u16tolPKDsPPDsi, symObjAddr: 0x1548, symBinAddr: 0x10000AAF4, symSize: 0x110 } - - { offsetInCU: 0xCC98, offset: 0x2E88B, size: 0x8, addend: 0x0, symName: __Z7u16ncatPDsPKDsm, symObjAddr: 0x167C, symBinAddr: 0x10000AC04, symSize: 0xD4 } - - { offsetInCU: 0xCCEE, offset: 0x2E8E1, size: 0x8, addend: 0x0, symName: __Z6u16chrPKDsDs, symObjAddr: 0x1750, symBinAddr: 0x10000ACD8, symSize: 0xA4 } - - { offsetInCU: 0xCD28, offset: 0x2E91B, size: 0x8, addend: 0x0, symName: __Z13u16rchr_slashPKDs, symObjAddr: 0x17F4, symBinAddr: 0x10000AD7C, symSize: 0x5C } - - { offsetInCU: 0xCD62, offset: 0x2E955, size: 0x8, addend: 0x0, symName: __Z7u16rchrPKDsDs, symObjAddr: 0x1850, symBinAddr: 0x10000ADD8, symSize: 0xC4 } - - { offsetInCU: 0xCDAA, offset: 0x2E99D, size: 0x8, addend: 0x0, symName: __Z6u16lenPKDs, symObjAddr: 0x1914, symBinAddr: 0x10000AE9C, symSize: 0x50 } - - { offsetInCU: 0xCDE4, offset: 0x2E9D7, size: 0x8, addend: 0x0, symName: __Z6u16cpyPDsPKDs, symObjAddr: 0x1964, symBinAddr: 0x10000AEEC, symSize: 0x68 } - - { offsetInCU: 0xCE2C, offset: 0x2EA1F, size: 0x8, addend: 0x0, symName: __Z6u16cmpPKDsS0_, symObjAddr: 0x19CC, symBinAddr: 0x10000AF54, symSize: 0xD4 } - - { offsetInCU: 0xCE66, offset: 0x2EA59, size: 0x8, addend: 0x0, symName: __Z8u16nicmpPKDsS0_m, symObjAddr: 0x1AA0, symBinAddr: 0x10000B028, symSize: 0x13C } - - { offsetInCU: 0xCEAE, offset: 0x2EAA1, size: 0x8, addend: 0x0, symName: __Z7u16icmpPKDsS0_, symObjAddr: 0x1C00, symBinAddr: 0x10000B188, symSize: 0xF4 } - - { offsetInCU: 0xCEE8, offset: 0x2EADB, size: 0x8, addend: 0x0, symName: __Z7u16ncmpPKDsS0_m, symObjAddr: 0x1CF4, symBinAddr: 0x10000B27C, symSize: 0x11C } - - { offsetInCU: 0xCF31, offset: 0x2EB24, size: 0x8, addend: 0x0, symName: __Z6u16tokPDsDsPS_, symObjAddr: 0x1E10, symBinAddr: 0x10000B398, symSize: 0x144 } - - { offsetInCU: 0xCF8C, offset: 0x2EB7F, size: 0x8, addend: 0x0, symName: __Z6u16tokPDsS_PS_, symObjAddr: 0x1F54, symBinAddr: 0x10000B4DC, symSize: 0x158 } - - { offsetInCU: 0xCFE7, offset: 0x2EBDA, size: 0x8, addend: 0x0, symName: __Z6u16tofPDs, symObjAddr: 0x20AC, symBinAddr: 0x10000B634, symSize: 0x160 } - - { offsetInCU: 0xD07E, offset: 0x2EC71, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEEC2B8ue170006Ev, symObjAddr: 0x226C, symBinAddr: 0x10000B7F4, symSize: 0x44 } - - { offsetInCU: 0xD0B0, offset: 0x2ECA3, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEEC1B8ue170006IDnNS_18__default_init_tagEEEOT_OT0_, symObjAddr: 0x22B0, symBinAddr: 0x10000B838, symSize: 0x3C } - - { offsetInCU: 0xD106, offset: 0x2ECF9, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEEC2B8ue170006IDnNS_18__default_init_tagEEEOT_OT0_, symObjAddr: 0x22EC, symBinAddr: 0x10000B874, symSize: 0x40 } - - { offsetInCU: 0xD15C, offset: 0x2ED4F, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEELi0ELb0EEC2B8ue170006IDnvEEOT_, symObjAddr: 0x232C, symBinAddr: 0x10000B8B4, symSize: 0x1C } - - { offsetInCU: 0xD19C, offset: 0x2ED8F, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEELi1ELb1EEC2B8ue170006ENS_18__default_init_tagE, symObjAddr: 0x2348, symBinAddr: 0x10000B8D0, symSize: 0x2C } - - { offsetInCU: 0xD1CE, offset: 0x2EDC1, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS0_IDsEEEEEC2B8ue170006Ev, symObjAddr: 0x2374, symBinAddr: 0x10000B8FC, symSize: 0x2C } - - { offsetInCU: 0xD1F6, offset: 0x2EDE9, size: 0x8, addend: 0x0, symName: __ZNSt3__116__non_trivial_ifILb1ENS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEEEC2B8ue170006Ev, symObjAddr: 0x23A0, symBinAddr: 0x10000B928, symSize: 0x14 } - - { offsetInCU: 0xD21E, offset: 0x2EE11, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEED2B8ue170006Ev, symObjAddr: 0x23B4, symBinAddr: 0x10000B93C, symSize: 0x3C } - - { offsetInCU: 0xD246, offset: 0x2EE39, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE16__destroy_vectorC1B8ue170006ERS8_, symObjAddr: 0x23F0, symBinAddr: 0x10000B978, symSize: 0x34 } - - { offsetInCU: 0xD27D, offset: 0x2EE70, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE16__destroy_vectorclB8ue170006Ev, symObjAddr: 0x2424, symBinAddr: 0x10000B9AC, symSize: 0x90 } - - { offsetInCU: 0xD2A1, offset: 0x2EE94, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE16__destroy_vectorC2B8ue170006ERS8_, symObjAddr: 0x24B4, symBinAddr: 0x10000BA3C, symSize: 0x20 } - - { offsetInCU: 0xD2D8, offset: 0x2EECB, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE7__clearB8ue170006Ev, symObjAddr: 0x24D4, symBinAddr: 0x10000BA5C, symSize: 0x28 } - - { offsetInCU: 0xD2FC, offset: 0x2EEEF, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE17__annotate_deleteB8ue170006Ev, symObjAddr: 0x24FC, symBinAddr: 0x10000BA84, symSize: 0xD4 } - - { offsetInCU: 0xD320, offset: 0x2EF13, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEEE10deallocateB8ue170006ERS7_PS6_m, symObjAddr: 0x25D0, symBinAddr: 0x10000BB58, symSize: 0x34 } - - { offsetInCU: 0xD361, offset: 0x2EF54, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE7__allocB8ue170006Ev, symObjAddr: 0x2604, symBinAddr: 0x10000BB8C, symSize: 0x28 } - - { offsetInCU: 0xD385, offset: 0x2EF78, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE8capacityB8ue170006Ev, symObjAddr: 0x262C, symBinAddr: 0x10000BBB4, symSize: 0x40 } - - { offsetInCU: 0xD3A9, offset: 0x2EF9C, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE22__base_destruct_at_endB8ue170006EPS6_, symObjAddr: 0x266C, symBinAddr: 0x10000BBF4, symSize: 0xA0 } - - { offsetInCU: 0xD3EB, offset: 0x2EFDE, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEEE7destroyB8ue170006IS6_vEEvRS7_PT_, symObjAddr: 0x270C, symBinAddr: 0x10000BC94, symSize: 0x2C } - - { offsetInCU: 0xD427, offset: 0x2F01A, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS0_IDsEEEEE7destroyB8ue170006EPS5_, symObjAddr: 0x274C, symBinAddr: 0x10000BCD4, symSize: 0x28 } - - { offsetInCU: 0xD459, offset: 0x2F04C, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE31__annotate_contiguous_containerB8ue170006EPKvSA_SA_SA_, symObjAddr: 0x2774, symBinAddr: 0x10000BCFC, symSize: 0x20 } - - { offsetInCU: 0xD4AD, offset: 0x2F0A0, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE4dataB8ue170006Ev, symObjAddr: 0x2794, symBinAddr: 0x10000BD1C, symSize: 0x28 } - - { offsetInCU: 0xD4D1, offset: 0x2F0C4, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE4sizeB8ue170006Ev, symObjAddr: 0x27BC, symBinAddr: 0x10000BD44, symSize: 0x28 } - - { offsetInCU: 0xD4F5, offset: 0x2F0E8, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS0_IDsEEEEE10deallocateB8ue170006EPS5_m, symObjAddr: 0x27E4, symBinAddr: 0x10000BD6C, symSize: 0x74 } - - { offsetInCU: 0xD535, offset: 0x2F128, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE6secondB8ue170006Ev, symObjAddr: 0x28E0, symBinAddr: 0x10000BDE0, symSize: 0x24 } - - { offsetInCU: 0xD559, offset: 0x2F14C, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEELi1ELb1EE5__getB8ue170006Ev, symObjAddr: 0x2904, symBinAddr: 0x10000BE04, symSize: 0x14 } - - { offsetInCU: 0xD57D, offset: 0x2F170, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE9__end_capB8ue170006Ev, symObjAddr: 0x2918, symBinAddr: 0x10000BE18, symSize: 0x28 } - - { offsetInCU: 0xD5A1, offset: 0x2F194, size: 0x8, addend: 0x0, symName: __ZNKSt3__117__compressed_pairIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE5firstB8ue170006Ev, symObjAddr: 0x2940, symBinAddr: 0x10000BE40, symSize: 0x24 } - - { offsetInCU: 0xD5C5, offset: 0x2F1B8, size: 0x8, addend: 0x0, symName: __ZNKSt3__122__compressed_pair_elemIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEELi0ELb0EE5__getB8ue170006Ev, symObjAddr: 0x2964, symBinAddr: 0x10000BE64, symSize: 0x14 } - - { offsetInCU: 0xD5E9, offset: 0x2F1DC, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE9__end_capB8ue170006Ev, symObjAddr: 0x2DE4, symBinAddr: 0x10000BE78, symSize: 0x28 } - - { offsetInCU: 0xD612, offset: 0x2F205, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE22__construct_one_at_endB8ue170006IJS6_EEEvDpOT_, symObjAddr: 0x2E0C, symBinAddr: 0x10000BEA0, symSize: 0x98 } - - { offsetInCU: 0xD65E, offset: 0x2F251, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE21__push_back_slow_pathIS6_EEvOT_, symObjAddr: 0x2EA4, symBinAddr: 0x10000BF38, symSize: 0xE0 } - - { offsetInCU: 0xD6BB, offset: 0x2F2AE, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE5firstB8ue170006Ev, symObjAddr: 0x2F84, symBinAddr: 0x10000C018, symSize: 0x24 } - - { offsetInCU: 0xD6DF, offset: 0x2F2D2, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEELi0ELb0EE5__getB8ue170006Ev, symObjAddr: 0x2FA8, symBinAddr: 0x10000C03C, symSize: 0x14 } - - { offsetInCU: 0xD71C, offset: 0x2F30F, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE21_ConstructTransactionC1B8ue170006ERS8_m, symObjAddr: 0x2FBC, symBinAddr: 0x10000C050, symSize: 0x3C } - - { offsetInCU: 0xD762, offset: 0x2F355, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEEE9constructB8ue170006IS6_JS6_EvEEvRS7_PT_DpOT0_, symObjAddr: 0x2FF8, symBinAddr: 0x10000C08C, symSize: 0x34 } - - { offsetInCU: 0xD7B8, offset: 0x2F3AB, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE21_ConstructTransactionD1B8ue170006Ev, symObjAddr: 0x302C, symBinAddr: 0x10000C0C0, symSize: 0x2C } - - { offsetInCU: 0xD7E0, offset: 0x2F3D3, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE21_ConstructTransactionC2B8ue170006ERS8_m, symObjAddr: 0x3058, symBinAddr: 0x10000C0EC, symSize: 0x4C } - - { offsetInCU: 0xD826, offset: 0x2F419, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS0_IDsEEEEE9constructB8ue170006IS5_JS5_EEEvPT_DpOT0_, symObjAddr: 0x30A4, symBinAddr: 0x10000C138, symSize: 0x30 } - - { offsetInCU: 0xD87A, offset: 0x2F46D, size: 0x8, addend: 0x0, symName: __ZNSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE21_ConstructTransactionD2B8ue170006Ev, symObjAddr: 0x30D4, symBinAddr: 0x10000C168, symSize: 0x20 } - - { offsetInCU: 0xD8A1, offset: 0x2F494, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE11__recommendB8ue170006Em, symObjAddr: 0x30F4, symBinAddr: 0x10000C188, symSize: 0xB4 } - - { offsetInCU: 0xD8F5, offset: 0x2F4E8, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEEC1EmmS8_, symObjAddr: 0x31A8, symBinAddr: 0x10000C23C, symSize: 0x44 } - - { offsetInCU: 0xD94A, offset: 0x2F53D, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEED1Ev, symObjAddr: 0x32FC, symBinAddr: 0x10000C390, symSize: 0x2C } - - { offsetInCU: 0xD974, offset: 0x2F567, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE8max_sizeEv, symObjAddr: 0x3328, symBinAddr: 0x10000C3BC, symSize: 0x74 } - - { offsetInCU: 0xD99B, offset: 0x2F58E, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE20__throw_length_errorB8ue170006Ev, symObjAddr: 0x339C, symBinAddr: 0x10000C430, symSize: 0x1C } - - { offsetInCU: 0xD9C9, offset: 0x2F5BC, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEEE8max_sizeB8ue170006IS7_vEEmRKS7_, symObjAddr: 0x3410, symBinAddr: 0x10000C44C, symSize: 0x24 } - - { offsetInCU: 0xD9F6, offset: 0x2F5E9, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE7__allocB8ue170006Ev, symObjAddr: 0x3434, symBinAddr: 0x10000C470, symSize: 0x28 } - - { offsetInCU: 0xDA2E, offset: 0x2F621, size: 0x8, addend: 0x0, symName: __ZNKSt3__19allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS0_IDsEEEEE8max_sizeB8ue170006Ev, symObjAddr: 0x34F8, symBinAddr: 0x10000C498, symSize: 0x18 } - - { offsetInCU: 0xDA52, offset: 0x2F645, size: 0x8, addend: 0x0, symName: __ZNKSt3__117__compressed_pairIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE6secondB8ue170006Ev, symObjAddr: 0x3510, symBinAddr: 0x10000C4B0, symSize: 0x24 } - - { offsetInCU: 0xDA76, offset: 0x2F669, size: 0x8, addend: 0x0, symName: __ZNKSt3__122__compressed_pair_elemINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEELi1ELb1EE5__getB8ue170006Ev, symObjAddr: 0x3534, symBinAddr: 0x10000C4D4, symSize: 0x14 } - - { offsetInCU: 0xDA9A, offset: 0x2F68D, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEEC2EmmS8_, symObjAddr: 0x3688, symBinAddr: 0x10000C4E8, symSize: 0xE0 } - - { offsetInCU: 0xDB0C, offset: 0x2F6FF, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEEC1B8ue170006IDnS9_EEOT_OT0_, symObjAddr: 0x3768, symBinAddr: 0x10000C5C8, symSize: 0x3C } - - { offsetInCU: 0xDB62, offset: 0x2F755, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEE7__allocB8ue170006Ev, symObjAddr: 0x37E4, symBinAddr: 0x10000C644, symSize: 0x28 } - - { offsetInCU: 0xDB86, offset: 0x2F779, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEE9__end_capB8ue170006Ev, symObjAddr: 0x380C, symBinAddr: 0x10000C66C, symSize: 0x28 } - - { offsetInCU: 0xDBAA, offset: 0x2F79D, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEEC2B8ue170006IDnS9_EEOT_OT0_, symObjAddr: 0x3834, symBinAddr: 0x10000C694, symSize: 0x48 } - - { offsetInCU: 0xDC00, offset: 0x2F7F3, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemIRNS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEELi1ELb0EEC2B8ue170006IS8_vEEOT_, symObjAddr: 0x387C, symBinAddr: 0x10000C6DC, symSize: 0x20 } - - { offsetInCU: 0xDC40, offset: 0x2F833, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS0_IDsEEEEE8allocateB8ue170006Em, symObjAddr: 0x389C, symBinAddr: 0x10000C6FC, symSize: 0x8C } - - { offsetInCU: 0xDC72, offset: 0x2F865, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEE6secondB8ue170006Ev, symObjAddr: 0x39A8, symBinAddr: 0x10000C788, symSize: 0x28 } - - { offsetInCU: 0xDC96, offset: 0x2F889, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemIRNS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEELi1ELb0EE5__getB8ue170006Ev, symObjAddr: 0x39D0, symBinAddr: 0x10000C7B0, symSize: 0x18 } - - { offsetInCU: 0xDCBA, offset: 0x2F8AD, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEE5firstB8ue170006Ev, symObjAddr: 0x39E8, symBinAddr: 0x10000C7C8, symSize: 0x24 } - - { offsetInCU: 0xDCDE, offset: 0x2F8D1, size: 0x8, addend: 0x0, symName: __ZNSt3__116reverse_iteratorIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEC1B8ue170006ES7_, symObjAddr: 0x3B40, symBinAddr: 0x10000C920, symSize: 0x34 } - - { offsetInCU: 0xDD14, offset: 0x2F907, size: 0x8, addend: 0x0, symName: __ZNKSt3__116reverse_iteratorIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEE4baseB8ue170006Ev, symObjAddr: 0x3B74, symBinAddr: 0x10000C954, symSize: 0x18 } - - { offsetInCU: 0xDD38, offset: 0x2F92B, size: 0x8, addend: 0x0, symName: __ZNKSt3__16vectorINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEENS4_IS6_EEE14__annotate_newB8ue170006Em, symObjAddr: 0x3BC8, symBinAddr: 0x10000C9A8, symSize: 0xC8 } - - { offsetInCU: 0xDD6B, offset: 0x2F95E, size: 0x8, addend: 0x0, symName: __ZNSt3__129_AllocatorDestroyRangeReverseINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEENS_16reverse_iteratorIPS6_EEEC1B8ue170006ERS7_RSA_SD_, symObjAddr: 0x3CDC, symBinAddr: 0x10000CABC, symSize: 0x44 } - - { offsetInCU: 0xDDC0, offset: 0x2F9B3, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEEE9constructB8ue170006IS6_JRKS6_EvEEvRS7_PT_DpOT0_, symObjAddr: 0x3D68, symBinAddr: 0x10000CB48, symSize: 0x34 } - - { offsetInCU: 0xDE16, offset: 0x2FA09, size: 0x8, addend: 0x0, symName: __ZNKSt3__116reverse_iteratorIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEdeB8ue170006Ev, symObjAddr: 0x3DC0, symBinAddr: 0x10000CBA0, symSize: 0x28 } - - { offsetInCU: 0xDE48, offset: 0x2FA3B, size: 0x8, addend: 0x0, symName: __ZNSt3__116reverse_iteratorIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEppB8ue170006Ev, symObjAddr: 0x3DE8, symBinAddr: 0x10000CBC8, symSize: 0x20 } - - { offsetInCU: 0xDE6C, offset: 0x2FA5F, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_29_AllocatorDestroyRangeReverseINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS2_IDsEEEEEENS_16reverse_iteratorIPS7_EEEEE10__completeB8ue170006Ev, symObjAddr: 0x3E08, symBinAddr: 0x10000CBE8, symSize: 0x1C } - - { offsetInCU: 0xDE90, offset: 0x2FA83, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_29_AllocatorDestroyRangeReverseINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS2_IDsEEEEEENS_16reverse_iteratorIPS7_EEEEED1B8ue170006Ev, symObjAddr: 0x3E24, symBinAddr: 0x10000CC04, symSize: 0x2C } - - { offsetInCU: 0xDEB8, offset: 0x2FAAB, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_29_AllocatorDestroyRangeReverseINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS2_IDsEEEEEENS_16reverse_iteratorIPS7_EEEEEC1B8ue170006ESC_, symObjAddr: 0x3E50, symBinAddr: 0x10000CC30, symSize: 0x34 } - - { offsetInCU: 0xDEEF, offset: 0x2FAE2, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_29_AllocatorDestroyRangeReverseINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS2_IDsEEEEEENS_16reverse_iteratorIPS7_EEEEEC2B8ue170006ESC_, symObjAddr: 0x3E84, symBinAddr: 0x10000CC64, symSize: 0x30 } - - { offsetInCU: 0xDF26, offset: 0x2FB19, size: 0x8, addend: 0x0, symName: __ZNSt3__129_AllocatorDestroyRangeReverseINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEENS_16reverse_iteratorIPS6_EEEC2B8ue170006ERS7_RSA_SD_, symObjAddr: 0x3EB4, symBinAddr: 0x10000CC94, symSize: 0x38 } - - { offsetInCU: 0xDF7B, offset: 0x2FB6E, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS0_IDsEEEEE9constructB8ue170006IS5_JRKS5_EEEvPT_DpOT0_, symObjAddr: 0x3EEC, symBinAddr: 0x10000CCCC, symSize: 0x30 } - - { offsetInCU: 0xDFD4, offset: 0x2FBC7, size: 0x8, addend: 0x0, symName: __ZNSt3__119__to_address_helperINS_16reverse_iteratorIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEEvE6__callB8ue170006ERKS9_, symObjAddr: 0x3F1C, symBinAddr: 0x10000CCFC, symSize: 0x4C } - - { offsetInCU: 0xDFF6, offset: 0x2FBE9, size: 0x8, addend: 0x0, symName: __ZNKSt3__116reverse_iteratorIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEptB8ue170006Ev, symObjAddr: 0x3F68, symBinAddr: 0x10000CD48, symSize: 0x24 } - - { offsetInCU: 0xE01A, offset: 0x2FC0D, size: 0x8, addend: 0x0, symName: __ZNSt3__128__exception_guard_exceptionsINS_29_AllocatorDestroyRangeReverseINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS2_IDsEEEEEENS_16reverse_iteratorIPS7_EEEEED2B8ue170006Ev, symObjAddr: 0x3F8C, symBinAddr: 0x10000CD6C, symSize: 0x48 } - - { offsetInCU: 0xE042, offset: 0x2FC35, size: 0x8, addend: 0x0, symName: __ZNKSt3__129_AllocatorDestroyRangeReverseINS_9allocatorINS_12basic_stringIDsNS_11char_traitsIDsEENS1_IDsEEEEEENS_16reverse_iteratorIPS6_EEEclB8ue170006Ev, symObjAddr: 0x3FD4, symBinAddr: 0x10000CDB4, symSize: 0xB4 } - - { offsetInCU: 0xE067, offset: 0x2FC5A, size: 0x8, addend: 0x0, symName: __ZNSt3__116reverse_iteratorINS0_IPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEEEC1B8ue170006ES8_, symObjAddr: 0x40F8, symBinAddr: 0x10000CED8, symSize: 0x3C } - - { offsetInCU: 0xE09D, offset: 0x2FC90, size: 0x8, addend: 0x0, symName: __ZNSt3__116reverse_iteratorINS0_IPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEEEppB8ue170006Ev, symObjAddr: 0x41B8, symBinAddr: 0x10000CF98, symSize: 0x30 } - - { offsetInCU: 0xE0C1, offset: 0x2FCB4, size: 0x8, addend: 0x0, symName: __ZNKSt3__116reverse_iteratorINS0_IPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEEE4baseB8ue170006Ev, symObjAddr: 0x41E8, symBinAddr: 0x10000CFC8, symSize: 0x24 } - - { offsetInCU: 0xE0EA, offset: 0x2FCDD, size: 0x8, addend: 0x0, symName: __ZNSt3__119__to_address_helperINS_16reverse_iteratorINS1_IPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEEEEvE6__callB8ue170006ERKSA_, symObjAddr: 0x420C, symBinAddr: 0x10000CFEC, symSize: 0x4C } - - { offsetInCU: 0xE10C, offset: 0x2FCFF, size: 0x8, addend: 0x0, symName: __ZNKSt3__116reverse_iteratorINS0_IPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEEEptB8ue170006Ev, symObjAddr: 0x4258, symBinAddr: 0x10000D038, symSize: 0x24 } - - { offsetInCU: 0xE130, offset: 0x2FD23, size: 0x8, addend: 0x0, symName: __ZNKSt3__116reverse_iteratorINS0_IPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEEEdeB8ue170006Ev, symObjAddr: 0x427C, symBinAddr: 0x10000D05C, symSize: 0x34 } - - { offsetInCU: 0xE162, offset: 0x2FD55, size: 0x8, addend: 0x0, symName: __ZNSt3__116reverse_iteratorIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEmmB8ue170006Ev, symObjAddr: 0x42B0, symBinAddr: 0x10000D090, symSize: 0x20 } - - { offsetInCU: 0xE186, offset: 0x2FD79, size: 0x8, addend: 0x0, symName: __ZNSt3__116reverse_iteratorINS0_IPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEEEC2B8ue170006ES8_, symObjAddr: 0x42D0, symBinAddr: 0x10000D0B0, symSize: 0x2C } - - { offsetInCU: 0xE1BC, offset: 0x2FDAF, size: 0x8, addend: 0x0, symName: __ZNSt3__116reverse_iteratorIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEEEC2B8ue170006ES7_, symObjAddr: 0x42FC, symBinAddr: 0x10000D0DC, symSize: 0x28 } - - { offsetInCU: 0xE1F2, offset: 0x2FDE5, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEED2Ev, symObjAddr: 0x4324, symBinAddr: 0x10000D104, symSize: 0x80 } - - { offsetInCU: 0xE21D, offset: 0x2FE10, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEE5clearB8ue170006Ev, symObjAddr: 0x43A4, symBinAddr: 0x10000D184, symSize: 0x28 } - - { offsetInCU: 0xE241, offset: 0x2FE34, size: 0x8, addend: 0x0, symName: __ZNKSt3__114__split_bufferINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEE8capacityB8ue170006Ev, symObjAddr: 0x43CC, symBinAddr: 0x10000D1AC, symSize: 0x40 } - - { offsetInCU: 0xE265, offset: 0x2FE58, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEE17__destruct_at_endB8ue170006EPS6_, symObjAddr: 0x440C, symBinAddr: 0x10000D1EC, symSize: 0x2C } - - { offsetInCU: 0xE296, offset: 0x2FE89, size: 0x8, addend: 0x0, symName: __ZNSt3__114__split_bufferINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEE17__destruct_at_endB8ue170006EPS6_NS_17integral_constantIbLb0EEE, symObjAddr: 0x4438, symBinAddr: 0x10000D218, symSize: 0x94 } - - { offsetInCU: 0xE2D5, offset: 0x2FEC8, size: 0x8, addend: 0x0, symName: __ZNKSt3__114__split_bufferINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEE9__end_capB8ue170006Ev, symObjAddr: 0x44CC, symBinAddr: 0x10000D2AC, symSize: 0x28 } - - { offsetInCU: 0xE2F9, offset: 0x2FEEC, size: 0x8, addend: 0x0, symName: __ZNKSt3__117__compressed_pairIPNS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEERNS4_IS6_EEE5firstB8ue170006Ev, symObjAddr: 0x44F4, symBinAddr: 0x10000D2D4, symSize: 0x24 } - - { offsetInCU: 0xE31D, offset: 0x2FF10, size: 0x8, addend: 0x0, symName: __ZNSt3__112codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EEC2B8ue170006Em, symObjAddr: 0x46D4, symBinAddr: 0x10000D2F8, symSize: 0x58 } - - { offsetInCU: 0xE353, offset: 0x2FF46, size: 0x8, addend: 0x0, symName: __ZNSt3__114__codecvt_utf8IwEC2B8ue170006EmmNS_12codecvt_modeE, symObjAddr: 0x472C, symBinAddr: 0x10000D350, symSize: 0x64 } - - { offsetInCU: 0xE3A5, offset: 0x2FF98, size: 0x8, addend: 0x0, symName: __ZNSt3__112codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EED1B8ue170006Ev, symObjAddr: 0x4790, symBinAddr: 0x10000D3B4, symSize: 0x2C } - - { offsetInCU: 0xE3CD, offset: 0x2FFC0, size: 0x8, addend: 0x0, symName: __ZNSt3__112codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EED0B8ue170006Ev, symObjAddr: 0x47BC, symBinAddr: 0x10000D3E0, symSize: 0x58 } - - { offsetInCU: 0xE3F5, offset: 0x2FFE8, size: 0x8, addend: 0x0, symName: __ZNSt3__112codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EED2B8ue170006Ev, symObjAddr: 0x4814, symBinAddr: 0x10000D438, symSize: 0x2C } - - { offsetInCU: 0xE41D, offset: 0x30010, size: 0x8, addend: 0x0, symName: __ZNSt3__114__codecvt_utf8IwED2Ev, symObjAddr: 0x4840, symBinAddr: 0x10000D464, symSize: 0x2C } - - { offsetInCU: 0xE448, offset: 0x3003B, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_12codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EEEwNS_9allocatorIwEENS4_IcEEEC2EPS3_, symObjAddr: 0x486C, symBinAddr: 0x10000D490, symSize: 0x8C } - - { offsetInCU: 0xE482, offset: 0x30075, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEC1B8ue170006Ev, symObjAddr: 0x4924, symBinAddr: 0x10000D51C, symSize: 0x2C } - - { offsetInCU: 0xE4AA, offset: 0x3009D, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEC2B8ue170006Ev, symObjAddr: 0x4D64, symBinAddr: 0x10000D548, symSize: 0x3C } - - { offsetInCU: 0xE4D2, offset: 0x300C5, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE14__default_initB8ue170006Ev, symObjAddr: 0x4DA0, symBinAddr: 0x10000D584, symSize: 0xB0 } - - { offsetInCU: 0xE522, offset: 0x30115, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE5__repES5_E5firstB8ue170006Ev, symObjAddr: 0x4E50, symBinAddr: 0x10000D634, symSize: 0x24 } - - { offsetInCU: 0xE546, offset: 0x30139, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE11__recommendB8ue170006Em, symObjAddr: 0x4E74, symBinAddr: 0x10000D658, symSize: 0x9C } - - { offsetInCU: 0xE578, offset: 0x3016B, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIwEEE8allocateB8ue170006ERS2_m, symObjAddr: 0x4F10, symBinAddr: 0x10000D6F4, symSize: 0x2C } - - { offsetInCU: 0xE5AA, offset: 0x3019D, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7__allocB8ue170006Ev, symObjAddr: 0x4F3C, symBinAddr: 0x10000D720, symSize: 0x24 } - - { offsetInCU: 0xE5CE, offset: 0x301C1, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE16__begin_lifetimeB8ue170006EPwm, symObjAddr: 0x4F60, symBinAddr: 0x10000D744, symSize: 0x14 } - - { offsetInCU: 0xE600, offset: 0x301F3, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE18__set_long_pointerB8ue170006EPw, symObjAddr: 0x4F74, symBinAddr: 0x10000D758, symSize: 0x38 } - - { offsetInCU: 0xE633, offset: 0x30226, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE14__set_long_capB8ue170006Em, symObjAddr: 0x4FAC, symBinAddr: 0x10000D790, symSize: 0x70 } - - { offsetInCU: 0xE666, offset: 0x30259, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE15__set_long_sizeB8ue170006Em, symObjAddr: 0x501C, symBinAddr: 0x10000D800, symSize: 0x38 } - - { offsetInCU: 0xE699, offset: 0x3028C, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE5__repELi0ELb0EE5__getB8ue170006Ev, symObjAddr: 0x5054, symBinAddr: 0x10000D838, symSize: 0x14 } - - { offsetInCU: 0xE6BD, offset: 0x302B0, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE10__align_itB8ue170006ILm4EEEmm, symObjAddr: 0x5068, symBinAddr: 0x10000D84C, symSize: 0x1C } - - { offsetInCU: 0xE6EA, offset: 0x302DD, size: 0x8, addend: 0x0, symName: __ZNSt3__19allocatorIwE8allocateB8ue170006Em, symObjAddr: 0x5084, symBinAddr: 0x10000D868, symSize: 0x84 } - - { offsetInCU: 0xE726, offset: 0x30319, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIwEEE8max_sizeB8ue170006IS2_vEEmRKS2_, symObjAddr: 0x5108, symBinAddr: 0x10000D8EC, symSize: 0x24 } - - { offsetInCU: 0xE753, offset: 0x30346, size: 0x8, addend: 0x0, symName: __ZNKSt3__19allocatorIwE8max_sizeB8ue170006Ev, symObjAddr: 0x512C, symBinAddr: 0x10000D910, symSize: 0x14 } - - { offsetInCU: 0xE777, offset: 0x3036A, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE5__repES5_E6secondB8ue170006Ev, symObjAddr: 0x5140, symBinAddr: 0x10000D924, symSize: 0x24 } - - { offsetInCU: 0xE79B, offset: 0x3038E, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorIwEELi1ELb1EE5__getB8ue170006Ev, symObjAddr: 0x5164, symBinAddr: 0x10000D948, symSize: 0x14 } - - { offsetInCU: 0xE7BF, offset: 0x303B2, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_12codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EEEwNS_9allocatorIwEENS4_IcEEED2Ev, symObjAddr: 0x5178, symBinAddr: 0x10000D95C, symSize: 0xC4 } - - { offsetInCU: 0xE7E9, offset: 0x303DC, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_12codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EEEwNS_9allocatorIwEENS4_IcEEE8to_bytesEPKwS9_, symObjAddr: 0x523C, symBinAddr: 0x10000DA20, symSize: 0x63C } - - { offsetInCU: 0xE94F, offset: 0x30542, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE4dataB8ue170006Ev, symObjAddr: 0x5878, symBinAddr: 0x10000E05C, symSize: 0x28 } - - { offsetInCU: 0xE973, offset: 0x30566, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE4sizeB8ue170006Ev, symObjAddr: 0x58A0, symBinAddr: 0x10000E084, symSize: 0x54 } - - { offsetInCU: 0xE997, offset: 0x3058A, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6resizeB8ue170006Em, symObjAddr: 0x5930, symBinAddr: 0x10000E0D8, symSize: 0x30 } - - { offsetInCU: 0xE9CA, offset: 0x305BD, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE8capacityB8ue170006Ev, symObjAddr: 0x5960, symBinAddr: 0x10000E108, symSize: 0x54 } - - { offsetInCU: 0xE9EE, offset: 0x305E1, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEixB8ue170006Em, symObjAddr: 0x59B4, symBinAddr: 0x10000E15C, symSize: 0x30 } - - { offsetInCU: 0xEA21, offset: 0x30614, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4sizeB8ue170006Ev, symObjAddr: 0x59E4, symBinAddr: 0x10000E18C, symSize: 0x54 } - - { offsetInCU: 0xEA45, offset: 0x30638, size: 0x8, addend: 0x0, symName: __ZNKSt3__17codecvtIwc11__mbstate_tE3outB8ue170006ERS1_PKwS5_RS5_PcS7_RS7_, symObjAddr: 0x5A38, symBinAddr: 0x10000E1E0, symSize: 0x64 } - - { offsetInCU: 0xEAD1, offset: 0x306C4, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6appendB8ue170006IPKcLi0EEERS5_T_SA_, symObjAddr: 0x5A9C, symBinAddr: 0x10000E244, symSize: 0x1EC } - - { offsetInCU: 0xEB85, offset: 0x30778, size: 0x8, addend: 0x0, symName: __ZNKSt3__17codecvtIwc11__mbstate_tE7unshiftB8ue170006ERS1_PcS4_RS4_, symObjAddr: 0x5C88, symBinAddr: 0x10000E430, symSize: 0x4C } - - { offsetInCU: 0xEBE5, offset: 0x307D8, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5emptyB8ue170006Ev, symObjAddr: 0x5CD4, symBinAddr: 0x10000E47C, symSize: 0x30 } - - { offsetInCU: 0xEC09, offset: 0x307FC, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE14__get_long_capB8ue170006Ev, symObjAddr: 0x5E28, symBinAddr: 0x10000E510, symSize: 0x30 } - - { offsetInCU: 0xEC2D, offset: 0x30820, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE13__get_pointerB8ue170006Ev, symObjAddr: 0x5E90, symBinAddr: 0x10000E540, symSize: 0x54 } - - { offsetInCU: 0xEC51, offset: 0x30844, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE18__get_long_pointerB8ue170006Ev, symObjAddr: 0x5EE4, symBinAddr: 0x10000E594, symSize: 0x28 } - - { offsetInCU: 0xEC75, offset: 0x30868, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE19__get_short_pointerB8ue170006Ev, symObjAddr: 0x5F0C, symBinAddr: 0x10000E5BC, symSize: 0x28 } - - { offsetInCU: 0xEC99, offset: 0x3088C, size: 0x8, addend: 0x0, symName: __ZNSt3__114pointer_traitsIPcE10pointer_toB8ue170006ERc, symObjAddr: 0x5F34, symBinAddr: 0x10000E5E4, symSize: 0x14 } - - { offsetInCU: 0xECBB, offset: 0x308AE, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE15__get_long_sizeB8ue170006Ev, symObjAddr: 0x5F48, symBinAddr: 0x10000E5F8, symSize: 0x28 } - - { offsetInCU: 0xECDF, offset: 0x308D2, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE16__get_short_sizeB8ue170006Ev, symObjAddr: 0x5F70, symBinAddr: 0x10000E620, symSize: 0x34 } - - { offsetInCU: 0xED03, offset: 0x308F6, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE15__addr_in_rangeB8ue170006IcEEbRKT_, symObjAddr: 0x5FD0, symBinAddr: 0x10000E680, symSize: 0x6C } - - { offsetInCU: 0xED3E, offset: 0x30931, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE25__grow_by_without_replaceB8ue170006Emmmmmm, symObjAddr: 0x603C, symBinAddr: 0x10000E6EC, symSize: 0x74 } - - { offsetInCU: 0xEDBF, offset: 0x309B2, size: 0x8, addend: 0x0, symName: __ZNSt3__111char_traitsIcE6assignB8ue170006ERcRKc, symObjAddr: 0x60B0, symBinAddr: 0x10000E760, symSize: 0x24 } - - { offsetInCU: 0xEDEF, offset: 0x309E2, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE10__set_sizeB8ue170006Em, symObjAddr: 0x60D4, symBinAddr: 0x10000E784, symSize: 0x54 } - - { offsetInCU: 0xEE22, offset: 0x30A15, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1B8ue170006IPKcLi0EEET_S9_RKS4_, symObjAddr: 0x6128, symBinAddr: 0x10000E7D8, symSize: 0x44 } - - { offsetInCU: 0xEE90, offset: 0x30A83, size: 0x8, addend: 0x0, symName: __ZNKSt3__16__lessIvvEclB8ue170006IPKcS4_EEbRKT_RKT0_, symObjAddr: 0x626C, symBinAddr: 0x10000E8F4, symSize: 0x34 } - - { offsetInCU: 0xEEE2, offset: 0x30AD5, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE16__set_short_sizeB8ue170006Em, symObjAddr: 0x62A0, symBinAddr: 0x10000E928, symSize: 0x78 } - - { offsetInCU: 0xEF15, offset: 0x30B08, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2B8ue170006IPKcLi0EEET_S9_RKS4_, symObjAddr: 0x6318, symBinAddr: 0x10000E9A0, symSize: 0x50 } - - { offsetInCU: 0xEF79, offset: 0x30B6C, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5__repES5_EC1B8ue170006INS_18__default_init_tagERKS5_EEOT_OT0_, symObjAddr: 0x6368, symBinAddr: 0x10000E9F0, symSize: 0x3C } - - { offsetInCU: 0xEFCE, offset: 0x30BC1, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initIPKcLi0EEEvT_S9_, symObjAddr: 0x63A4, symBinAddr: 0x10000EA2C, symSize: 0x54 } - - { offsetInCU: 0xF031, offset: 0x30C24, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5__repES5_EC2B8ue170006INS_18__default_init_tagERKS5_EEOT_OT0_, symObjAddr: 0x63F8, symBinAddr: 0x10000EA80, symSize: 0x40 } - - { offsetInCU: 0xF087, offset: 0x30C7A, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorIcEELi1ELb1EEC2B8ue170006IRKS2_vEEOT_, symObjAddr: 0x6438, symBinAddr: 0x10000EAC0, symSize: 0x18 } - - { offsetInCU: 0xF0C6, offset: 0x30CB9, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE16__init_with_sizeB8ue170006IPKcS8_EEvT_T0_m, symObjAddr: 0x6450, symBinAddr: 0x10000EAD8, symSize: 0x17C } - - { offsetInCU: 0xF158, offset: 0x30D4B, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE8max_sizeB8ue170006Ev, symObjAddr: 0x65CC, symBinAddr: 0x10000EC54, symSize: 0xAC } - - { offsetInCU: 0xF1A8, offset: 0x30D9B, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE20__throw_length_errorB8ue170006Ev, symObjAddr: 0x6678, symBinAddr: 0x10000ED00, symSize: 0x1C } - - { offsetInCU: 0xF1CC, offset: 0x30DBF, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE13__fits_in_ssoB8ue170006Em, symObjAddr: 0x6694, symBinAddr: 0x10000ED1C, symSize: 0x4C } - - { offsetInCU: 0xF1EF, offset: 0x30DE2, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7__allocB8ue170006Ev, symObjAddr: 0x6720, symBinAddr: 0x10000EDA8, symSize: 0x24 } - - { offsetInCU: 0xF213, offset: 0x30E06, size: 0x8, addend: 0x0, symName: __ZNKSt3__117__compressed_pairINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5__repES5_E6secondB8ue170006Ev, symObjAddr: 0x6758, symBinAddr: 0x10000EDCC, symSize: 0x24 } - - { offsetInCU: 0xF237, offset: 0x30E2A, size: 0x8, addend: 0x0, symName: __ZNKSt3__122__compressed_pair_elemINS_9allocatorIcEELi1ELb1EE5__getB8ue170006Ev, symObjAddr: 0x677C, symBinAddr: 0x10000EDF0, symSize: 0x14 } - - { offsetInCU: 0xF25B, offset: 0x30E4E, size: 0x8, addend: 0x0, symName: __ZNSt11range_errorC1B8ue170006EPKc, symObjAddr: 0x6864, symBinAddr: 0x10000EE04, symSize: 0x34 } - - { offsetInCU: 0xF291, offset: 0x30E84, size: 0x8, addend: 0x0, symName: __ZNSt11range_errorC2B8ue170006EPKc, symObjAddr: 0x6898, symBinAddr: 0x10000EE38, symSize: 0x4C } - - { offsetInCU: 0xF2C7, offset: 0x30EBA, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE13__get_pointerB8ue170006Ev, symObjAddr: 0x68F8, symBinAddr: 0x10000EE98, symSize: 0x54 } - - { offsetInCU: 0xF2EB, offset: 0x30EDE, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9__is_longB8ue170006Ev, symObjAddr: 0x694C, symBinAddr: 0x10000EEEC, symSize: 0x74 } - - { offsetInCU: 0xF30F, offset: 0x30F02, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE18__get_long_pointerB8ue170006Ev, symObjAddr: 0x69C0, symBinAddr: 0x10000EF60, symSize: 0x28 } - - { offsetInCU: 0xF333, offset: 0x30F26, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE19__get_short_pointerB8ue170006Ev, symObjAddr: 0x69E8, symBinAddr: 0x10000EF88, symSize: 0x28 } - - { offsetInCU: 0xF357, offset: 0x30F4A, size: 0x8, addend: 0x0, symName: __ZNKSt3__117__compressed_pairINS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE5__repES5_E5firstB8ue170006Ev, symObjAddr: 0x6A10, symBinAddr: 0x10000EFB0, symSize: 0x24 } - - { offsetInCU: 0xF37B, offset: 0x30F6E, size: 0x8, addend: 0x0, symName: __ZNKSt3__122__compressed_pair_elemINS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE5__repELi0ELb0EE5__getB8ue170006Ev, symObjAddr: 0x6A34, symBinAddr: 0x10000EFD4, symSize: 0x14 } - - { offsetInCU: 0xF39F, offset: 0x30F92, size: 0x8, addend: 0x0, symName: __ZNSt3__114pointer_traitsIPKwE10pointer_toB8ue170006ERS1_, symObjAddr: 0x6A48, symBinAddr: 0x10000EFE8, symSize: 0x14 } - - { offsetInCU: 0xF3C1, offset: 0x30FB4, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE15__get_long_sizeB8ue170006Ev, symObjAddr: 0x6A5C, symBinAddr: 0x10000EFFC, symSize: 0x28 } - - { offsetInCU: 0xF3E5, offset: 0x30FD8, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE16__get_short_sizeB8ue170006Ev, symObjAddr: 0x6A84, symBinAddr: 0x10000F024, symSize: 0x34 } - - { offsetInCU: 0xF408, offset: 0x30FFB, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_12codecvt_utf8IwLm1114111ELNS_12codecvt_modeE0EEEwNS_9allocatorIwEENS4_IcEEE10from_bytesEPKcS9_, symObjAddr: 0x6AB8, symBinAddr: 0x10000F058, symSize: 0x458 } - - { offsetInCU: 0xF4FB, offset: 0x310EE, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEC1B8ue170006Emw, symObjAddr: 0x6F10, symBinAddr: 0x10000F4B0, symSize: 0x3C } - - { offsetInCU: 0xF541, offset: 0x31134, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6resizeB8ue170006Em, symObjAddr: 0x6F4C, symBinAddr: 0x10000F4EC, symSize: 0x30 } - - { offsetInCU: 0xF574, offset: 0x31167, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE8capacityB8ue170006Ev, symObjAddr: 0x6F7C, symBinAddr: 0x10000F51C, symSize: 0x54 } - - { offsetInCU: 0xF598, offset: 0x3118B, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEixB8ue170006Em, symObjAddr: 0x6FD0, symBinAddr: 0x10000F570, symSize: 0x30 } - - { offsetInCU: 0xF5CB, offset: 0x311BE, size: 0x8, addend: 0x0, symName: __ZNKSt3__17codecvtIwc11__mbstate_tE2inB8ue170006ERS1_PKcS5_RS5_PwS7_RS7_, symObjAddr: 0x7000, symBinAddr: 0x10000F5A0, symSize: 0x64 } - - { offsetInCU: 0xF657, offset: 0x3124A, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6appendB8ue170006IPKwLi0EEERS5_T_SA_, symObjAddr: 0x7064, symBinAddr: 0x10000F604, symSize: 0x1EC } - - { offsetInCU: 0xF70B, offset: 0x312FE, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE5emptyB8ue170006Ev, symObjAddr: 0x7250, symBinAddr: 0x10000F7F0, symSize: 0x30 } - - { offsetInCU: 0xF72F, offset: 0x31322, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEC2B8ue170006Emw, symObjAddr: 0x7280, symBinAddr: 0x10000F820, symSize: 0x4C } - - { offsetInCU: 0xF775, offset: 0x31368, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE14__get_long_capB8ue170006Ev, symObjAddr: 0x72CC, symBinAddr: 0x10000F86C, symSize: 0x30 } - - { offsetInCU: 0xF799, offset: 0x3138C, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE13__get_pointerB8ue170006Ev, symObjAddr: 0x72FC, symBinAddr: 0x10000F89C, symSize: 0x54 } - - { offsetInCU: 0xF7BD, offset: 0x313B0, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE18__get_long_pointerB8ue170006Ev, symObjAddr: 0x7350, symBinAddr: 0x10000F8F0, symSize: 0x28 } - - { offsetInCU: 0xF7E1, offset: 0x313D4, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE19__get_short_pointerB8ue170006Ev, symObjAddr: 0x7378, symBinAddr: 0x10000F918, symSize: 0x28 } - - { offsetInCU: 0xF805, offset: 0x313F8, size: 0x8, addend: 0x0, symName: __ZNSt3__114pointer_traitsIPwE10pointer_toB8ue170006ERw, symObjAddr: 0x73A0, symBinAddr: 0x10000F940, symSize: 0x14 } - - { offsetInCU: 0xF827, offset: 0x3141A, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE15__addr_in_rangeB8ue170006IwEEbRKT_, symObjAddr: 0x73E0, symBinAddr: 0x10000F980, symSize: 0x6C } - - { offsetInCU: 0xF862, offset: 0x31455, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE25__grow_by_without_replaceB8ue170006Emmmmmm, symObjAddr: 0x744C, symBinAddr: 0x10000F9EC, symSize: 0x74 } - - { offsetInCU: 0xF8E3, offset: 0x314D6, size: 0x8, addend: 0x0, symName: __ZNSt3__111char_traitsIwE6assignB8ue170006ERwRKw, symObjAddr: 0x74C0, symBinAddr: 0x10000FA60, symSize: 0x24 } - - { offsetInCU: 0xF915, offset: 0x31508, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE10__set_sizeB8ue170006Em, symObjAddr: 0x74E4, symBinAddr: 0x10000FA84, symSize: 0x54 } - - { offsetInCU: 0xF948, offset: 0x3153B, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEC1B8ue170006IPKwLi0EEET_S9_RKS4_, symObjAddr: 0x7538, symBinAddr: 0x10000FAD8, symSize: 0x44 } - - { offsetInCU: 0xF9B6, offset: 0x315A9, size: 0x8, addend: 0x0, symName: __ZNKSt3__16__lessIvvEclB8ue170006IPKwS4_EEbRKT_RKT0_, symObjAddr: 0x765C, symBinAddr: 0x10000FBFC, symSize: 0x34 } - - { offsetInCU: 0xFA08, offset: 0x315FB, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE16__set_short_sizeB8ue170006Em, symObjAddr: 0x7690, symBinAddr: 0x10000FC30, symSize: 0x78 } - - { offsetInCU: 0xFA3B, offset: 0x3162E, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEC2B8ue170006IPKwLi0EEET_S9_RKS4_, symObjAddr: 0x7708, symBinAddr: 0x10000FCA8, symSize: 0x50 } - - { offsetInCU: 0xFA9F, offset: 0x31692, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE5__repES5_EC1B8ue170006INS_18__default_init_tagERKS5_EEOT_OT0_, symObjAddr: 0x7758, symBinAddr: 0x10000FCF8, symSize: 0x3C } - - { offsetInCU: 0xFAF4, offset: 0x316E7, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6__initIPKwLi0EEEvT_S9_, symObjAddr: 0x7794, symBinAddr: 0x10000FD34, symSize: 0x54 } - - { offsetInCU: 0xFB57, offset: 0x3174A, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE5__repES5_EC2B8ue170006INS_18__default_init_tagERKS5_EEOT_OT0_, symObjAddr: 0x77E8, symBinAddr: 0x10000FD88, symSize: 0x40 } - - { offsetInCU: 0xFBAD, offset: 0x317A0, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorIwEELi1ELb1EEC2B8ue170006IRKS2_vEEOT_, symObjAddr: 0x7828, symBinAddr: 0x10000FDC8, symSize: 0x18 } - - { offsetInCU: 0xFBEC, offset: 0x317DF, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE16__init_with_sizeB8ue170006IPKwS8_EEvT_T0_m, symObjAddr: 0x7840, symBinAddr: 0x10000FDE0, symSize: 0x17C } - - { offsetInCU: 0xFC7E, offset: 0x31871, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE8max_sizeB8ue170006Ev, symObjAddr: 0x79BC, symBinAddr: 0x10000FF5C, symSize: 0xAC } - - { offsetInCU: 0xFCCE, offset: 0x318C1, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE20__throw_length_errorB8ue170006Ev, symObjAddr: 0x7A68, symBinAddr: 0x100010008, symSize: 0x1C } - - { offsetInCU: 0xFCF2, offset: 0x318E5, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE13__fits_in_ssoB8ue170006Em, symObjAddr: 0x7A84, symBinAddr: 0x100010024, symSize: 0x4C } - - { offsetInCU: 0xFD15, offset: 0x31908, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7__allocB8ue170006Ev, symObjAddr: 0x7B10, symBinAddr: 0x1000100B0, symSize: 0x24 } - - { offsetInCU: 0xFD39, offset: 0x3192C, size: 0x8, addend: 0x0, symName: __ZNKSt3__117__compressed_pairINS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE5__repES5_E6secondB8ue170006Ev, symObjAddr: 0x7B34, symBinAddr: 0x1000100D4, symSize: 0x24 } - - { offsetInCU: 0xFD5D, offset: 0x31950, size: 0x8, addend: 0x0, symName: __ZNKSt3__122__compressed_pair_elemINS_9allocatorIwEELi1ELb1EE5__getB8ue170006Ev, symObjAddr: 0x7B58, symBinAddr: 0x1000100F8, symSize: 0x14 } - - { offsetInCU: 0xFD81, offset: 0x31974, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEC2ERKS5_, symObjAddr: 0x7B6C, symBinAddr: 0x10001010C, symSize: 0xB8 } - - { offsetInCU: 0xFDC2, offset: 0x319B5, size: 0x8, addend: 0x0, symName: __ZNSt3__116allocator_traitsINS_9allocatorIDsEEE37select_on_container_copy_constructionB8ue170006IS2_vvEES2_RKS2_, symObjAddr: 0x7C24, symBinAddr: 0x1000101C4, symSize: 0x10 } - - { offsetInCU: 0xFDF5, offset: 0x319E8, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5__repES5_EC1B8ue170006INS_18__default_init_tagES5_EEOT_OT0_, symObjAddr: 0x7C58, symBinAddr: 0x1000101D4, symSize: 0x3C } - - { offsetInCU: 0xFE4A, offset: 0x31A3D, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE25__init_copy_ctor_externalEPKDsm, symObjAddr: 0x7C94, symBinAddr: 0x100010210, symSize: 0x13C } - - { offsetInCU: 0xFEBB, offset: 0x31AAE, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5__repES5_EC2B8ue170006INS_18__default_init_tagES5_EEOT_OT0_, symObjAddr: 0x7E6C, symBinAddr: 0x10001034C, symSize: 0x40 } - - { offsetInCU: 0xFF11, offset: 0x31B04, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorIDsEELi1ELb1EEC2B8ue170006IS2_vEEOT_, symObjAddr: 0x7EC0, symBinAddr: 0x10001038C, symSize: 0x18 } - - { offsetInCU: 0xFF5B, offset: 0x31B4E, size: 0x8, addend: 0x0, symName: __ZNSt3__118codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EEC2B8ue170006Em, symObjAddr: 0x8ACC, symBinAddr: 0x1000103A4, symSize: 0x58 } - - { offsetInCU: 0xFF92, offset: 0x31B85, size: 0x8, addend: 0x0, symName: __ZNSt3__120__codecvt_utf8_utf16IDsEC2B8ue170006EmmNS_12codecvt_modeE, symObjAddr: 0x8B24, symBinAddr: 0x1000103FC, symSize: 0x64 } - - { offsetInCU: 0xFFE7, offset: 0x31BDA, size: 0x8, addend: 0x0, symName: __ZNSt3__118codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EED1B8ue170006Ev, symObjAddr: 0x8B88, symBinAddr: 0x100010460, symSize: 0x2C } - - { offsetInCU: 0x1000F, offset: 0x31C02, size: 0x8, addend: 0x0, symName: __ZNSt3__118codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EED0B8ue170006Ev, symObjAddr: 0x8BB4, symBinAddr: 0x10001048C, symSize: 0x58 } - - { offsetInCU: 0x10037, offset: 0x31C2A, size: 0x8, addend: 0x0, symName: __ZNSt3__17codecvtIDsc11__mbstate_tEC2B8ue170006Em, symObjAddr: 0x8C0C, symBinAddr: 0x1000104E4, symSize: 0x84 } - - { offsetInCU: 0x1006E, offset: 0x31C61, size: 0x8, addend: 0x0, symName: __ZNSt3__16locale5facetC2B8ue170006Em, symObjAddr: 0x8C90, symBinAddr: 0x100010568, symSize: 0x50 } - - { offsetInCU: 0x100A4, offset: 0x31C97, size: 0x8, addend: 0x0, symName: __ZNSt3__112codecvt_baseC2B8ue170006Ev, symObjAddr: 0x8CE0, symBinAddr: 0x1000105B8, symSize: 0x14 } - - { offsetInCU: 0x100CC, offset: 0x31CBF, size: 0x8, addend: 0x0, symName: __ZNSt3__114__shared_countC2B8ue170006El, symObjAddr: 0x8CF4, symBinAddr: 0x1000105CC, symSize: 0x30 } - - { offsetInCU: 0x10102, offset: 0x31CF5, size: 0x8, addend: 0x0, symName: __ZNSt3__118codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EED2B8ue170006Ev, symObjAddr: 0x8D24, symBinAddr: 0x1000105FC, symSize: 0x2C } - - { offsetInCU: 0x1012A, offset: 0x31D1D, size: 0x8, addend: 0x0, symName: __ZNSt3__120__codecvt_utf8_utf16IDsED2Ev, symObjAddr: 0x8D50, symBinAddr: 0x100010628, symSize: 0x2C } - - { offsetInCU: 0x10156, offset: 0x31D49, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_18codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EEEDsNS_9allocatorIDsEENS4_IcEEEC2EPS3_, symObjAddr: 0x8D7C, symBinAddr: 0x100010654, symSize: 0x8C } - - { offsetInCU: 0x10190, offset: 0x31D83, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_18codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EEEDsNS_9allocatorIDsEENS4_IcEEED2Ev, symObjAddr: 0x9030, symBinAddr: 0x1000106E0, symSize: 0xC4 } - - { offsetInCU: 0x101BA, offset: 0x31DAD, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_18codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EEEDsNS_9allocatorIDsEENS4_IcEEE10from_bytesEPKcS9_, symObjAddr: 0x90F4, symBinAddr: 0x1000107A4, symSize: 0x450 } - - { offsetInCU: 0x102AD, offset: 0x31EA0, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEC1B8ue170006EmDs, symObjAddr: 0x9544, symBinAddr: 0x100010BF4, symSize: 0x3C } - - { offsetInCU: 0x102F3, offset: 0x31EE6, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE6resizeB8ue170006Em, symObjAddr: 0x9580, symBinAddr: 0x100010C30, symSize: 0x30 } - - { offsetInCU: 0x10326, offset: 0x31F19, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE8capacityB8ue170006Ev, symObjAddr: 0x95B0, symBinAddr: 0x100010C60, symSize: 0x54 } - - { offsetInCU: 0x1034A, offset: 0x31F3D, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEixB8ue170006Em, symObjAddr: 0x9604, symBinAddr: 0x100010CB4, symSize: 0x30 } - - { offsetInCU: 0x1037D, offset: 0x31F70, size: 0x8, addend: 0x0, symName: __ZNKSt3__17codecvtIDsc11__mbstate_tE2inB8ue170006ERS1_PKcS5_RS5_PDsS7_RS7_, symObjAddr: 0x9688, symBinAddr: 0x100010CE4, symSize: 0x64 } - - { offsetInCU: 0x10409, offset: 0x31FFC, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE6appendIPKDsLi0EEERS5_T_SA_, symObjAddr: 0x96EC, symBinAddr: 0x100010D48, symSize: 0x1EC } - - { offsetInCU: 0x104BD, offset: 0x320B0, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5emptyB8ue170006Ev, symObjAddr: 0x98D8, symBinAddr: 0x100010F34, symSize: 0x30 } - - { offsetInCU: 0x104E1, offset: 0x320D4, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEC2B8ue170006EmDs, symObjAddr: 0x9908, symBinAddr: 0x100010F64, symSize: 0x4C } - - { offsetInCU: 0x10526, offset: 0x32119, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE6__initEmDs, symObjAddr: 0x9954, symBinAddr: 0x100010FB0, symSize: 0x14C } - - { offsetInCU: 0x10597, offset: 0x3218A, size: 0x8, addend: 0x0, symName: __ZNSt3__111char_traitsIDsE6assignB8ue170006EPDsmDs, symObjAddr: 0x9AA0, symBinAddr: 0x1000110FC, symSize: 0x58 } - - { offsetInCU: 0x105D7, offset: 0x321CA, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE6resizeEmDs, symObjAddr: 0x9BD8, symBinAddr: 0x100011210, symSize: 0x78 } - - { offsetInCU: 0x1062A, offset: 0x3221D, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE6appendEmDs, symObjAddr: 0x9C50, symBinAddr: 0x100011288, symSize: 0x114 } - - { offsetInCU: 0x106AA, offset: 0x3229D, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE14__erase_to_endB8ue170006Em, symObjAddr: 0x9D64, symBinAddr: 0x10001139C, symSize: 0x40 } - - { offsetInCU: 0x106DC, offset: 0x322CF, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE25__grow_by_without_replaceB8ue170006Emmmmmm, symObjAddr: 0x9DA4, symBinAddr: 0x1000113DC, symSize: 0x74 } - - { offsetInCU: 0x1075D, offset: 0x32350, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE10__set_sizeB8ue170006Em, symObjAddr: 0x9E6C, symBinAddr: 0x100011450, symSize: 0x54 } - - { offsetInCU: 0x1078F, offset: 0x32382, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE9__grow_byEmmmmmm, symObjAddr: 0x9EC0, symBinAddr: 0x1000114A4, symSize: 0x228 } - - { offsetInCU: 0x1086C, offset: 0x3245F, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE19__null_terminate_atB8ue170006EPDsm, symObjAddr: 0xA0E8, symBinAddr: 0x1000116CC, symSize: 0x50 } - - { offsetInCU: 0x108AE, offset: 0x324A1, size: 0x8, addend: 0x0, symName: __ZNKSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE15__addr_in_rangeB8ue170006IDsEEbRKT_, symObjAddr: 0xA198, symBinAddr: 0x100011748, symSize: 0x6C } - - { offsetInCU: 0x108EA, offset: 0x324DD, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEC1B8ue170006IPKDsLi0EEET_S9_RKS4_, symObjAddr: 0xA204, symBinAddr: 0x1000117B4, symSize: 0x44 } - - { offsetInCU: 0x1094D, offset: 0x32540, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE6appendEPKDsm, symObjAddr: 0xA248, symBinAddr: 0x1000117F8, symSize: 0x118 } - - { offsetInCU: 0x109CD, offset: 0x325C0, size: 0x8, addend: 0x0, symName: __ZNKSt3__16__lessIvvEclB8ue170006IPKDsS4_EEbRKT_RKT0_, symObjAddr: 0xA468, symBinAddr: 0x1000119F0, symSize: 0x34 } - - { offsetInCU: 0x10A1F, offset: 0x32612, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEC2B8ue170006IPKDsLi0EEET_S9_RKS4_, symObjAddr: 0xA49C, symBinAddr: 0x100011A24, symSize: 0x50 } - - { offsetInCU: 0x10A83, offset: 0x32676, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5__repES5_EC1B8ue170006INS_18__default_init_tagERKS5_EEOT_OT0_, symObjAddr: 0xA4EC, symBinAddr: 0x100011A74, symSize: 0x3C } - - { offsetInCU: 0x10AD8, offset: 0x326CB, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE6__initIPKDsLi0EEEvT_S9_, symObjAddr: 0xA528, symBinAddr: 0x100011AB0, symSize: 0x54 } - - { offsetInCU: 0x10B3B, offset: 0x3272E, size: 0x8, addend: 0x0, symName: __ZNSt3__117__compressed_pairINS_12basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE5__repES5_EC2B8ue170006INS_18__default_init_tagERKS5_EEOT_OT0_, symObjAddr: 0xA57C, symBinAddr: 0x100011B04, symSize: 0x40 } - - { offsetInCU: 0x10B91, offset: 0x32784, size: 0x8, addend: 0x0, symName: __ZNSt3__122__compressed_pair_elemINS_9allocatorIDsEELi1ELb1EEC2B8ue170006IRKS2_vEEOT_, symObjAddr: 0xA5BC, symBinAddr: 0x100011B44, symSize: 0x18 } - - { offsetInCU: 0x10BD0, offset: 0x327C3, size: 0x8, addend: 0x0, symName: __ZNSt3__112basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEE16__init_with_sizeB8ue170006IPKDsS8_EEvT_T0_m, symObjAddr: 0xA5D4, symBinAddr: 0x100011B5C, symSize: 0x17C } - - { offsetInCU: 0x10C61, offset: 0x32854, size: 0x8, addend: 0x0, symName: __ZNSt3__115wstring_convertINS_18codecvt_utf8_utf16IDsLm1114111ELNS_12codecvt_modeE0EEEDsNS_9allocatorIDsEENS4_IcEEE8to_bytesEPKDsS9_, symObjAddr: 0xAA84, symBinAddr: 0x100011CD8, symSize: 0x638 } - - { offsetInCU: 0x10DC7, offset: 0x329BA, size: 0x8, addend: 0x0, symName: __ZNKSt3__17codecvtIDsc11__mbstate_tE3outB8ue170006ERS1_PKDsS5_RS5_PcS7_RS7_, symObjAddr: 0xB0BC, symBinAddr: 0x100012310, symSize: 0x64 } - - { offsetInCU: 0x10E54, offset: 0x32A47, size: 0x8, addend: 0x0, symName: __ZNKSt3__17codecvtIDsc11__mbstate_tE7unshiftB8ue170006ERS1_PcS4_RS4_, symObjAddr: 0xB120, symBinAddr: 0x100012374, symSize: 0x4C } -... From aae92899660735a192ea49ae5cd64d244ee5caab Mon Sep 17 00:00:00 2001 From: SabinePlay <166697246+SabinePlay@users.noreply.github.com> Date: Fri, 19 Apr 2024 09:41:38 +0200 Subject: [PATCH 07/71] feat(mac): enable some functions/makros --- mac/.gitignore | 2 +- mac/mcompile/deadkey.h | 8 ++++---- mac/mcompile/keymap.h | 17 ++++++++--------- mac/mcompile/kmx_file.h | 12 ++++++------ mac/mcompile/mc_import_rules.cpp | 11 ++++++----- mac/mcompile/mc_import_rules.h | 4 ++-- mac/mcompile/mc_kmxfile.cpp | 11 ++++++----- mac/mcompile/mc_kmxfile.h | 13 +++++-------- mac/mcompile/mcompile.h | 9 ++++----- 9 files changed, 42 insertions(+), 45 deletions(-) diff --git a/mac/.gitignore b/mac/.gitignore index 4abfa6977db..239a01b3ec2 100644 --- a/mac/.gitignore +++ b/mac/.gitignore @@ -17,4 +17,4 @@ setup/textinputsource/textinputsource.x86_64 setup/Install Keyman.app //Sabine -**/*.exe +**/mcompile/executable/*.* \ No newline at end of file diff --git a/mac/mcompile/deadkey.h b/mac/mcompile/deadkey.h index 0d2fee6d09c..e242d270c99 100755 --- a/mac/mcompile/deadkey.h +++ b/mac/mcompile/deadkey.h @@ -8,7 +8,7 @@ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ -/* + // create a vector for a dk combination ( ` + a -> à ) v_dw_1D createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult); @@ -28,6 +28,6 @@ bool found_dk_inVector(KMX_WCHAR dk, std::vector &myVec); bool query_dk_combinations_for_specific_dk(v_dw_2D * dk_ComposeTable, v_dw_2D & dk_SingleTable, KMX_DWORD dk); // get the shifted character of a key and write shiftstate of KVal to shift -KMX_DWORD KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap* keymap); -*/ -# endif //DEADKEY_H \ No newline at end of file +//KMX_DWORD KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap* keymap); + +# endif//DEADKEY_H \ No newline at end of file diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 7fa8fd42ace..2266cb2de2f 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -39,7 +39,7 @@ KMX_DWORD get_keyval_From_Keycode(std::vector keyval, int shiftstate,const #include #include #include - +*/ enum ShiftState { Base = 0, // 0 @@ -100,7 +100,7 @@ int map_VKShiftState_to_LinModifier(int VKShiftState); KMX_DWORD convertNamesTo_DWORD_Value(std::string tok_str); // create a Vector with all entries of both keymaps -int createOneVectorFromBothKeyboards(v_dw_3D &All_Vector,GdkKeymap *keymap); +//int createOneVectorFromBothKeyboards(v_dw_3D &All_Vector,GdkKeymap *keymap); // read configuration file, split and write to 3D-Vector (Data for US on Vector[0][ ][ ] ) int write_US_ToVector(v_dw_3D &vec, std::string language, const char *text); @@ -118,10 +118,10 @@ int split_US_To_3D_Vector(v_dw_3D &all_US, v_str_1D completeList); v_dw_2D create_empty_2D_Vector(int dim_rows, int dim_shifts); // append characters to 3D-Vector using GDK (Data for underlying Language on Vector[1][ ][ ] ) -int append_underlying_ToVector(v_dw_3D &All_Vector, GdkKeymap *keymap); +//int append_underlying_ToVector(v_dw_3D &All_Vector, GdkKeymap *keymap); // initialize GDK -bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]); +//bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]); //------------------------------ @@ -530,19 +530,19 @@ bool IsKeymanUsedChar(int KV); std::u16string convert_DeadkeyValues_To_U16str(int in); // use gdk_keymap_translate_keyboard_state to get keyval - base function to get keyvals -int KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps); +//int KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps); // use KMX_get_KeyVal_From_KeyCode and prevent use of certain keycodes -KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, guint keycode, int shift_state_pos); +//KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, guint keycode, int shift_state_pos); // fill Deadkey with dk and return CATEGORY -KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey); +//KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey); // use Vector to return the Keyval of underlying Keyboard KMX_WCHAR KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D &All_Vector,KMX_DWORD VK_underlying); // use Vector to return the Keycode of the underlying Keyboard for given VK_US using GDK -KMX_DWORD KMX_get_KeyCodeUnderlying_From_KeyCodeUS(GdkKeymap *keymap, v_dw_3D &All_Vector,KMX_DWORD KC_US, ShiftState ss, int caps); +//KMX_DWORD KMX_get_KeyCodeUnderlying_From_KeyCodeUS(GdkKeymap *keymap, v_dw_3D &All_Vector,KMX_DWORD KC_US, ShiftState ss, int caps); // return the Keycode of the underlying Keyboard for given VK_US UINT KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS); @@ -553,7 +553,6 @@ KMX_DWORD KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); // convert codePoint to u16string std::u16string CodePointToU16String(unsigned int codepoint); -# endif// //KEYMAP_H*/ diff --git a/mac/mcompile/kmx_file.h b/mac/mcompile/kmx_file.h index 66dadedcad4..9791d76919b 100755 --- a/mac/mcompile/kmx_file.h +++ b/mac/mcompile/kmx_file.h @@ -11,7 +11,7 @@ Copyright: Copyright (C) 2003-2018 SIL International. Authors: mcdurdin */ -/* + #define UNREFERENCED_PARAMETER(P) (P) #define TRUNCATE ((size_t)-1) @@ -183,9 +183,9 @@ namespace kmx { #define U_UC_SENTINEL u"\uFFFF" -// - * VK__MAX defines the highest virtual key code defined in the system = 0xFF. Custom VK codes start at 256 - // +/* + VK__MAX defines the highest virtual key code defined in the system = 0xFF. Custom VK codes start at 256 +*/ #define VK__MAX 255 #define CODE_ANY 0x01 @@ -360,7 +360,7 @@ struct KMX_COMP_KEYBOARD_KMXPLUSINFO { }; // - * Only valid if comp_keyboard.dwFlags&KF_KMXPLUS + //* Only valid if comp_keyboard.dwFlags&KF_KMXPLUS // struct KMX_COMP_KEYBOARD_EX { KMX_COMP_KEYBOARD header; // 0000 see COMP_KEYBOARD @@ -390,5 +390,5 @@ static_assert(sizeof(KMX_COMP_KEYBOARD) == KEYBOARDFILEHEADER_SIZE, "COMP_KEYBOA } // namespace kmx } // namespace kbp } // namespace km -#endif*/ +#endif #endif //KMX_FILE_H diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 5f52c64bac3..9e09997a1e9 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -1,5 +1,4 @@ - /* Name: mc_import_rules Copyright: Copyright (C) SIL International. @@ -28,10 +27,6 @@ #include "mc_kmxfile.h" #include "keymap.h" -/*//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - const int KMX_ShiftStateMap[] = { ISVIRTUALKEY, ISVIRTUALKEY | K_SHIFTFLAG, @@ -68,6 +63,12 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { return false; } +/*//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + + + int KMX_ToUnicodeEx(guint keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps,GdkKeymap *keymap) { GdkKeymapKey *maps; guint *keyvals; diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h index 29968d3fb05..da38fa65e38 100755 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -5,7 +5,7 @@ //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ -/* + class DeadKey { @@ -39,5 +39,5 @@ class DeadKey { bool KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter); }; -*/ + # endif //MC_IMPORT_RULES_H diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index eed0adbf8ab..bc4268e9013 100755 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -11,11 +11,11 @@ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ -/* + KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz); LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize); - +/* KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename) { FILE *fp; @@ -41,7 +41,7 @@ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename) { } return TRUE; -} +}*/ KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug) { @@ -227,6 +227,8 @@ PKMX_WCHAR KMX_StringOffset(PKMX_BYTE base, KMX_DWORD offset) { return (PKMX_WCHAR)(base + offset); } + +/* #ifdef KMX_64BIT */ /** CopyKeyboard will copy the data read into bufp from x86-sized structures into @@ -235,7 +237,6 @@ PKMX_WCHAR KMX_StringOffset(PKMX_BYTE base, KMX_DWORD offset) { we don't copy the strings This method is used on 64-bit architectures. */ -/* LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD) base; @@ -311,7 +312,7 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { } return kbp; } -*/ + // else KMX_FixupKeyboard //#else /* Fixup the keyboard by expanding pointers. On disk the pointers are stored relative to the // beginning of the file, but we need real pointers. This method is used on 32-bit architectures. diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index a380ed339c8..57395b492c2 100755 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -12,13 +12,6 @@ #ifndef _KMXFILE_H #define _KMXFILE_H -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - -/* - - typedef struct KMX_tagSTORE { KMX_DWORD dwSystemID; @@ -84,7 +77,11 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD *lpKeyboard); KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename); KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug); -*/ + #endif // _KMXFILE_H #endif //MC_KMXFILE_H + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 0398cb0b9d5..253dea6d5f6 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -3,6 +3,8 @@ #include "keymap.h" #include +#include "deadkey.h" +#include "mc_kmxfile.h" /* Name: mcompile @@ -29,9 +31,7 @@ //################################################################################################################################################ -/* -#include "deadkey.h" -#include "mc_kmxfile.h" + struct KMX_DeadkeyMapping { // I4353 KMX_WCHAR deadkey, dkid; @@ -45,11 +45,10 @@ int run(int argc, std::vector str_argv, char* argv[]); PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); -int KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap); +//int KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap); void KMX_LogError(const wchar_t* fmt, ...); -#endif*/ /*MCOMPILE_H*/ From 0c7e55e7fe010f633b0cca32f5d62fb9db24a59e Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 19 Apr 2024 13:27:52 +0200 Subject: [PATCH 08/71] Revert "feat(mac): some edits" This reverts commit d32e3521ba4f93f4e0862e41f1c612b6a7154953. # Conflicts: # mac/mcompile/keymap.cpp # mac/mcompile/keymap.h # mac/mcompile/mcompile.cpp # mac/mcompile/mcompile.h --- mac/mcompile/mcompile.h | 1 - 1 file changed, 1 deletion(-) diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 253dea6d5f6..ba347cc5e7b 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -51,7 +51,6 @@ void KMX_LogError(const wchar_t* fmt, ...); - //################################################################################################################################################ //################################################################################################################################################ From 11e7ddee78d988e88f8ead548a15c07baf3aea58 Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 19 Apr 2024 18:56:08 +0200 Subject: [PATCH 09/71] feat(mac): open run() --- mac/.gitignore | 3 +- mac/mcompile/deadkey.cpp | 24 ++++----- mac/mcompile/keymap.cpp | 73 +++++++++++++------------ mac/mcompile/mc_import_rules.cpp | 22 ++++---- mac/mcompile/mc_kmxfile.cpp | 25 +++++---- mac/mcompile/mcompile.cpp | 91 +++++++++++++++++++------------- 6 files changed, 127 insertions(+), 111 deletions(-) diff --git a/mac/.gitignore b/mac/.gitignore index 239a01b3ec2..258fda02525 100644 --- a/mac/.gitignore +++ b/mac/.gitignore @@ -17,4 +17,5 @@ setup/textinputsource/textinputsource.x86_64 setup/Install Keyman.app //Sabine -**/mcompile/executable/*.* \ No newline at end of file +**/mcompile/executable/*.* +**/mcompile/*.kmx \ No newline at end of file diff --git a/mac/mcompile/deadkey.cpp b/mac/mcompile/deadkey.cpp index 08e3dbb9ece..0614e85dde0 100755 --- a/mac/mcompile/deadkey.cpp +++ b/mac/mcompile/deadkey.cpp @@ -5,18 +5,16 @@ //################################################################################################################################################ -/* - -v_dw_1D createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult) { +/* v_dw_1D createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult) { v_dw_1D line; line.push_back(convertNamesTo_DWORD_Value(first)); line.push_back(convertNamesTo_DWORD_Value(second)); //line.push_back(convertNamesTo_DWORD_Value(nameresult)); line.push_back(number); return line; -} +}*/ -std::vector create_alDead() { +/*std::vector create_alDead() { std::vector alDead; v_dw_2D dk_ComposeTable; @@ -31,9 +29,9 @@ std::vector create_alDead() { alDead.push_back(dk2); } return alDead; -} +}*/ -void refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector *p_All_Vec) { +/*void refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector *p_All_Vec) { if( dk == 0) return; @@ -58,9 +56,9 @@ bool found_dk_inVector(KMX_WCHAR dk, std::vector &dkVec) { } while (i < (int) dkVec.size()); } return false; -} +}*/ -bool query_dk_combinations_for_specific_dk(v_dw_2D * p_dk_ComposeTable, v_dw_2D &dk_SingleTable, KMX_DWORD dk) { +/*bool query_dk_combinations_for_specific_dk(v_dw_2D * p_dk_ComposeTable, v_dw_2D &dk_SingleTable, KMX_DWORD dk) { v_dw_1D line; for ( int i =0; i< (int) (*p_dk_ComposeTable).size(); i++) { @@ -77,9 +75,9 @@ bool query_dk_combinations_for_specific_dk(v_dw_2D * p_dk_ComposeTable, v_dw_2D return true; else return false; -} +}*/ -KMX_DWORD KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap* keymap) { +/*KMX_DWORD KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap* keymap) { guint Keyval = (guint) KVal; GdkKeymapKey* keys; gint n_keys; @@ -95,9 +93,9 @@ KMX_DWORD KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap } } return Cap; -} +}*/ -void create_DKTable(v_dw_2D & dk_ComposeTable) { +/*void create_DKTable(v_dw_2D & dk_ComposeTable) { //create a 2D-Vector which contains data for ALL existing deadkey combinations on a Linux Keyboard: //dk_ComposeTable[i][0] : First (e.g. dead_circumflex) //dk_ComposeTable[i][1] : Second (e.g. a) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index c9085cd7006..2e3b841ca25 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -16,9 +16,9 @@ int map_VKShiftState_to_LinModifier(int VKShiftState) { else if (VKShiftState == 9 ) return 2; // 0000 1001 // else if (VKShiftState == 25) return 3; // 0001 1001 // else return VKShiftState; -} +}*/ -KMX_DWORD convertNamesTo_DWORD_Value(std::string tok_str) { +/* KMX_DWORD convertNamesTo_DWORD_Value(std::string tok_str) { // more on https://manpages.ubuntu.com/manpages/jammy/man3/keysyms.3tk.html std::map first; @@ -297,9 +297,9 @@ KMX_DWORD convertNamesTo_DWORD_Value(std::string tok_str) { } } return returnIfCharInvalid; -} +}*/ -int createOneVectorFromBothKeyboards(v_dw_3D &All_Vector,GdkKeymap *keymap) { +/* int createOneVectorFromBothKeyboards(v_dw_3D &All_Vector,GdkKeymap *keymap) { // create a 3D-Vector which contains data of the US keyboard and the underlying Keyboard: // All_Vector[ US_Keyboard ] // [KeyCode_US ] @@ -324,9 +324,9 @@ int createOneVectorFromBothKeyboards(v_dw_3D &All_Vector,GdkKeymap *keymap) { return 2; } return 0; -} +}*/ -int write_US_ToVector( v_dw_3D &vec,std::string language, const char* text) { +/*int write_US_ToVector( v_dw_3D &vec,std::string language, const char* text) { std::string FullPathName = "/usr/share/X11/xkb/symbols/" + language; @@ -351,9 +351,9 @@ int write_US_ToVector( v_dw_3D &vec,std::string language, const char* text) { fclose(fp); return 0; -} +}*/ -bool createCompleteRow_US(v_str_1D &complete_List, FILE* fp, const char* text, std::string language) { +/*bool createCompleteRow_US(v_str_1D &complete_List, FILE* fp, const char* text, std::string language) { // in the Configuration file we find the appopriate paragraph between "xkb_symbol " and the next xkb_symbol // and then copy all rows starting with "key <" to a 1D-Vector @@ -389,9 +389,9 @@ bool createCompleteRow_US(v_str_1D &complete_List, FILE* fp, const char* text, s return 1; } return 0; -} +}*/ -int replace_KeyName_with_Keycode(std::string in) { +/*int replace_KeyName_with_Keycode(std::string in) { int out = returnIfCharInvalid; if ( in == "key") out = 49; // VK_ BKQUOTE // @@ -448,9 +448,9 @@ int replace_KeyName_with_Keycode(std::string in) { else if ( in == "key") out = 65; // VK_SPACE // return out; -} +}*/ -int split_US_To_3D_Vector(v_dw_3D &all_US,v_str_1D completeList) { +/*int split_US_To_3D_Vector(v_dw_3D &all_US,v_str_1D completeList) { // 1: take the whole line of the 1D-Vector and remove unwanted characters. // 2: seperate the name e.g. key from the shiftstates // 3: convert to KMX_DWORD @@ -511,9 +511,9 @@ int split_US_To_3D_Vector(v_dw_3D &all_US,v_str_1D completeList) { return 1; } return 0; -} +}*/ -v_dw_2D create_empty_2D_Vector( int dim_rows,int dim_ss) { +/*v_dw_2D create_empty_2D_Vector( int dim_rows,int dim_ss) { v_dw_1D shifts; v_dw_2D Vector_2D; @@ -526,9 +526,9 @@ v_dw_2D create_empty_2D_Vector( int dim_rows,int dim_ss) { shifts.clear(); } return Vector_2D; -} +}*/ -int append_underlying_ToVector(v_dw_3D &All_Vector,GdkKeymap *keymap) { +/*int append_underlying_ToVector(v_dw_3D &All_Vector,GdkKeymap *keymap) { // create a 2D vector all filled with " " and push to 3D-Vector v_dw_2D underlying_Vector2D = create_empty_2D_Vector(All_Vector[0].size(),All_Vector[0][0].size()); @@ -574,17 +574,17 @@ bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]) { return 2; } return 0; -} +}*/ -bool IsKeymanUsedChar(int KV) { +/*bool IsKeymanUsedChar(int KV) { // 32 A-Z a-z if ((KV == 0x20 ) || (KV >= 65 && KV <= 90) || (KV >= 97 && KV <= 122) ) return true; else return false; -} +}*/ -std::u16string convert_DeadkeyValues_To_U16str(int in) { +/*std::u16string convert_DeadkeyValues_To_U16str(int in) { if (in == 0 ) return u"\0"; @@ -605,9 +605,9 @@ std::u16string convert_DeadkeyValues_To_U16str(int in) { } else return u"\0"; -} +}*/ -int KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps) { +/*int KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps) { GdkModifierType consumed; GdkKeymapKey *maps; @@ -692,9 +692,9 @@ int KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, return 0; return (int) *keyvals; -} +}*/ -KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, guint keycode, int shift_state_pos) { +/*KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, guint keycode, int shift_state_pos) { GdkKeymapKey *maps; guint *keyvals; gint count; @@ -715,9 +715,9 @@ KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, gui g_free(maps); return KVal; -} +}*/ -KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey) { +/*KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey) { GdkKeymapKey *maps; guint *keyvals; @@ -748,9 +748,9 @@ KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, UIN return 0xFFFE; else // usable char return KeyV; -} +}*/ -KMX_WCHAR KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD VK_US) { +/*KMX_WCHAR KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD VK_US) { KMX_DWORD VK_underlying; for( int i=0; i< (int)All_Vector[0].size()-1 ;i++) { for( int j=1; j< (int)All_Vector[0][0].size();j++) { @@ -761,9 +761,9 @@ KMX_WCHAR KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD } } return VK_US; -} +}*/ -KMX_DWORD KMX_get_KeyCodeUnderlying_From_KeyCodeUS(GdkKeymap *keymap, v_dw_3D &All_Vector, KMX_DWORD KC_US, ShiftState ss, int caps) { +/*KMX_DWORD KMX_get_KeyCodeUnderlying_From_KeyCodeUS(GdkKeymap *keymap, v_dw_3D &All_Vector, KMX_DWORD KC_US, ShiftState ss, int caps) { KMX_DWORD KC_underlying; std::u16string u16str = convert_DeadkeyValues_To_U16str(KMX_get_KeyVal_From_KeyCode(keymap, KC_US, ss, caps)); @@ -776,20 +776,20 @@ KMX_DWORD KMX_get_KeyCodeUnderlying_From_KeyCodeUS(GdkKeymap *keymap, v_dw_3D &A } } return KC_US; -} +}*/ -UINT KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS) { +/*UINT KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS) { return (8 + USVirtualKeyToScanCode[VirtualKeyUS]); -} +}*/ -KMX_DWORD KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { +/*KMX_DWORD KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { if ( keycode >7) return (KMX_DWORD) ScanCodeToUSVirtualKey[keycode-8]; return 0; -} +}*/ -std::u16string CodePointToU16String(unsigned int codepoint) { +/*std::u16string CodePointToU16String(unsigned int codepoint) { std::u16string str; if constexpr (sizeof(wchar_t) > 2) { @@ -893,5 +893,4 @@ KMX_DWORD get_keyval_From_Keycode(std::vector keyval, int shiftstate,const return returnint; } - void fun3() {std::cout << "Hier ist fun3 von keymap.cpp...\n";} \ No newline at end of file diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 9e09997a1e9..d7bfc8f393c 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -97,9 +97,9 @@ int KMX_ToUnicodeEx(guint keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int return 0; else // usable char return 1; -} +}*/ -int KMX_DeadKeyMap(int index, std::vector *deadkeys, int deadkeyBase, std::vector *deadkeyMappings) { // I4327 // I4353 +/*int KMX_DeadKeyMap(int index, std::vector *deadkeys, int deadkeyBase, std::vector *deadkeyMappings) { // I4327 // I4353 for(size_t i = 0; i < deadkeyMappings->size(); i++) { if((*deadkeyMappings)[i].deadkey == index) { return (*deadkeyMappings)[i].dkid; @@ -112,9 +112,9 @@ int KMX_DeadKeyMap(int index, std::vector *deadkeys, int deadkeyBase, } } return 0xFFFF; -} +}*/ -class KMX_VirtualKey { +/*class KMX_VirtualKey { private: UINT m_vk; UINT m_sc; @@ -329,8 +329,9 @@ class KMX_VirtualKey { return true; } }; +*/ -class KMX_Loader { +/* class KMX_Loader { private: KMX_BYTE lpKeyStateNull[256]; UINT m_XxxxVk; @@ -358,8 +359,9 @@ class KMX_Loader { } }; +*/ -int KMX_GetMaxDeadkeyIndex(KMX_WCHAR *p) { +/* int KMX_GetMaxDeadkeyIndex(KMX_WCHAR *p) { int n = 0; while(p && *p) { if(*p == UC_SENTINEL && *(p+1) == CODE_DEADKEY) @@ -367,9 +369,9 @@ int KMX_GetMaxDeadkeyIndex(KMX_WCHAR *p) { p = KMX_incxstr(p); } return n; -} +}*/ -bool KMX_ImportRules(LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, GdkKeymap **keymap, std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4552 +/*bool KMX_ImportRules(LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, GdkKeymap **keymap, std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4552 KMX_Loader loader; std::vector rgKey; //= new VirtualKey[256]; @@ -627,9 +629,9 @@ bool KMX_ImportRules(LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, GdkKeymap **keymap, } return true; -} +}*/ -const int CODE__SIZE[] = { +/*const int CODE__SIZE[] = { -1, // undefined 0x00 1, // CODE_ANY 0x01 2, // CODE_INDEX 0x02 diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index bc4268e9013..6fa81d66370 100755 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -15,7 +15,7 @@ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz); LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize); -/* + KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename) { FILE *fp; @@ -41,7 +41,7 @@ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename) { } return TRUE; -}*/ +} KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug) { @@ -228,9 +228,8 @@ PKMX_WCHAR KMX_StringOffset(PKMX_BYTE base, KMX_DWORD offset) { } -/* #ifdef KMX_64BIT -*/ + /** CopyKeyboard will copy the data read into bufp from x86-sized structures into x64-sized structures starting at `base` * After this function finishes, we still need to keep the original data because @@ -314,12 +313,11 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { } // else KMX_FixupKeyboard -//#else /* Fixup the keyboard by expanding pointers. On disk the pointers are stored relative to the -// beginning of the file, but we need real pointers. This method is used on 32-bit architectures. -//*/ +#else /* Fixup the keyboard by expanding pointers. On disk the pointers are stored relative to the + beginning of the file, but we need real pointers. This method is used on 32-bit architectures. +*/ -/* -LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize) { +/* LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize) { UNREFERENCED_PARAMETER(dwFileSize); @@ -354,7 +352,7 @@ LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFil } return kbp; -} +}*/ #endif @@ -461,7 +459,8 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { } KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz){ - KMX_DWORD i; +/* + KMX_DWORD i; PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)filebase; PKMX_COMP_STORE csp; @@ -481,11 +480,11 @@ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz){ } KMX_LogError(L"errWrongFileVersion"); return FALSE; - } + }*/ return TRUE; } -PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) { +/* PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) { if (*p == 0) return p; diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 394e7437c66..c4c270cf292 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -28,30 +28,19 @@ #include "mcompile.h" #include "u16.h" -//------------------------------- -int main () { - std::cout << "Hier ist main von mcompile-mac.cpp...\n"; - testmyFunctions_S2(); - - std::wstring const wtr = L"abc"; - std::string str= string_from_wstring(wtr); - - - - printf("\n................................ END ..............................\n"); - return 0; -} //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ -/* -KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, gint argc, gchar *argv[]); + +KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc, char *argv[]); +/*KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, gint argc, gchar *argv[]); bool KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, GdkKeymap **keymap,std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 +*/ std::vector KMX_FDeadkeys; // I4353 @@ -67,10 +56,27 @@ std::vector KMX_FDeadkeys; // I4353 std::vector str_argv_16 = convert_argvW_to_Vector_u16str( argc, argv); run(argc, str_argv_16); -#else // LINUX +#elif ((__linux__) || (__unix__ )) // LINUX, UNIX int main(int argc, char* argv[]) { std::vector str_argv_16 = convert_argv_to_Vector_u16str(argc, argv); run(argc, str_argv_16, argv); + +#elif (__APPLE__ && TARGET_OS_MAC) + #include + + int main(int argc, char* argv[]) { + std::vector str_argv_16 = convert_argv_to_Vector_u16str(argc, argv); + + // _S2 Sabines Stuff needs to go + std::cout << "Hier ist main von mcompile-mac.cpp...\n"; + testmyFunctions_S2(); + std::wstring const wtr = L"abc"; + std::string str= string_from_wstring(wtr); + // _S2 Sabines Stuff needs to go + + run(argc, str_argv_16, argv); + printf("\n.................................. END ..............................\n"); + #endif } @@ -95,7 +101,7 @@ int run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ return 1; } - // -u option is not available for Linux + // -u option is not available for Linux and macOS int bDeadkeyConversion = u16cmp(argv[1], u"-d") == 0; // I4552 @@ -139,17 +145,22 @@ int run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ } -#if defined(_WIN32) || defined(_WIN64) -// if(DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F -// KMX_SaveKeyboard(kmxfile, outfile); -// } + #if defined(_WIN32) || defined(_WIN64) //Windows + if(DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F + KMX_SaveKeyboard(kmxfile, outfile); + } -#else // LINUX - if(KMX_DoConvert( kmxfile, bDeadkeyConversion, argc, (gchar**) argv_ch)) { // I4552F - KMX_SaveKeyboard(kmxfile, outfile); -} + #elif ((__linux__) || (__unix__ )) // LINUX, UNIX + if(KMX_DoConvert( kmxfile, bDeadkeyConversion, argc, (gchar**) argv_ch)) { // I4552F + KMX_SaveKeyboard(kmxfile, outfile); + } + + #elif (__APPLE__ && TARGET_OS_MAC ) //macOS + if(KMX_DoConvert( kmxfile, bDeadkeyConversion, argc, (char**) argv_ch)) { // I4552F + KMX_SaveKeyboard(kmxfile, outfile); + } + #endif -#endif //DeleteReallocatedPointers(kmxfile); :TODO // _S2 not my ToDo :-) delete kmxfile; return 0; @@ -158,13 +169,14 @@ int run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ // Map of all shift states that we will work with const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCTRLFLAG|RALTFLAG, 0xFFFF}; + // // TranslateKey // // For each key rule on the keyboard, remap its key to the // correct shift state and key. Adjust the LCTRL+RALT -> RALT if necessary // -void KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { +/* void KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. @@ -187,23 +199,24 @@ void KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { key->ShiftFlags &= ~VIRTUALCHARKEY; key->Key = vk; } -} +}*/ -void KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { +/* void KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { for(unsigned int i = 0; i < group->cxKeyArray; i++) { KMX_TranslateKey(&group->dpKeyArray[i], vk, shift, ch); } -} +}*/ -void KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { +/* void KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { if(kbd->dpGroupArray[i].fUsingKeys) { KMX_TranslateGroup(&kbd->dpGroupArray[i], vk, shift, ch); } } } +*/ -void KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { +/* void KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { if(key->ShiftFlags == 0) { KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); } else if(key->ShiftFlags & VIRTUALCHARKEY) { @@ -411,8 +424,10 @@ KMX_BOOL KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { KMX_LogError(L"Keyboard is not a mnemonic layout keyboard"); return FALSE; } +*/ -KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, gint argc, gchar *argv[]) { +KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc, char *argv[]) { +/*KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, gint argc, gchar *argv[]) { KMX_WCHAR DeadKey=0; @@ -469,11 +484,11 @@ KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, gint arg if(!KMX_ImportRules(kbd, All_Vector, &keymap, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 return FALSE; - } + }*/ return TRUE; } -int KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap) { +/* int KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap) { KMX_WORD *p = OutputPairs; KMX_DWORD shift; @@ -494,9 +509,10 @@ int KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, *p = 0; return (p-OutputPairs); } +*/ void KMX_LogError(const wchar_t* fmt, ...) { - WCHAR fmtbuf[256]; + WCHAR fmtbuf[256]; const wchar_t* end = L"\0"; const wchar_t* nl = L"\n"; va_list vars; @@ -512,9 +528,10 @@ void KMX_LogError(const wchar_t* fmt, ...) { } while(fmtbuf[j] != *end); putwchar(*nl); + } -*/ + From 7d42f66a687f04f74895437d22d183be6b589f2e Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 19 Apr 2024 19:10:25 +0200 Subject: [PATCH 10/71] feat(mac): open all functions that are easy to open feat(mac): open more functions feat(mac): open DoConvert-InitializeUCHR feat(mac): open write_US_ToVector feat(mac): (temporarily) add mac_ to function names to be able to distinguish between linux-functions and mac functions if needed feat(mac): finished mac_createOneVectorFromBothKeyboards() feat(mac): started DoConvert feat(mac): mcompile tidy up --- mac/.gitignore | 3 +- mac/mcompile/deadkey.cpp | 377 ++++++++-------- mac/mcompile/deadkey.h | 17 +- mac/mcompile/filesystem.cpp | 8 +- mac/mcompile/keymap.cpp | 741 ++++++++----------------------- mac/mcompile/keymap.h | 468 +++++++++++++++++-- mac/mcompile/kmx_file.h | 8 +- mac/mcompile/mc_import_rules.cpp | 23 +- mac/mcompile/mc_import_rules.h | 2 - mac/mcompile/mc_kmxfile.cpp | 51 +-- mac/mcompile/mcompile.cpp | 193 ++++---- mac/mcompile/mcompile.h | 6 +- 12 files changed, 953 insertions(+), 944 deletions(-) diff --git a/mac/.gitignore b/mac/.gitignore index 258fda02525..defe8b84f51 100644 --- a/mac/.gitignore +++ b/mac/.gitignore @@ -18,4 +18,5 @@ setup/Install Keyman.app //Sabine **/mcompile/executable/*.* -**/mcompile/*.kmx \ No newline at end of file +**/mcompile/*.kmx +**/mcompile/X*.cpp \ No newline at end of file diff --git a/mac/mcompile/deadkey.cpp b/mac/mcompile/deadkey.cpp index 0614e85dde0..b911c939b97 100755 --- a/mac/mcompile/deadkey.cpp +++ b/mac/mcompile/deadkey.cpp @@ -5,25 +5,25 @@ //################################################################################################################################################ -/* v_dw_1D createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult) { +/* v_dw_1D mac_createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult) { v_dw_1D line; - line.push_back(convertNamesTo_DWORD_Value(first)); - line.push_back(convertNamesTo_DWORD_Value(second)); - //line.push_back(convertNamesTo_DWORD_Value(nameresult)); + line.push_back(mac_convertNamesTo_DWORD_Value(first)); + line.push_back(mac_convertNamesTo_DWORD_Value(second)); + //line.push_back(mac_convertNamesTo_DWORD_Value(nameresult)); line.push_back(number); return line; }*/ -/*std::vector create_alDead() { +/*std::vector mac_create_alDead() { std::vector alDead; v_dw_2D dk_ComposeTable; - create_DKTable(dk_ComposeTable); + mac_create_DKTable(dk_ComposeTable); for( int i=0; i < (int) dk_ComposeTable.size()-1; i++) { DeadKey *dk2 = new DeadKey(dk_ComposeTable[i][0]); for ( int j=0; j< (int) dk_ComposeTable.size();j++) { - if(( dk_ComposeTable[i][0] == dk_ComposeTable[j][0]) && (IsKeymanUsedChar(dk_ComposeTable[j][1]))) + if(( dk_ComposeTable[i][0] == dk_ComposeTable[j][0]) && (mac_IsKeymanUsedChar(dk_ComposeTable[j][1]))) dk2->KMX_AddDeadKeyRow(dk_ComposeTable[j][1],dk_ComposeTable[j][2]); } alDead.push_back(dk2); @@ -31,7 +31,7 @@ return alDead; }*/ -/*void refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector *p_All_Vec) { +/*void mac_refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector *p_All_Vec) { if( dk == 0) return; @@ -58,11 +58,11 @@ bool found_dk_inVector(KMX_WCHAR dk, std::vector &dkVec) { return false; }*/ -/*bool query_dk_combinations_for_specific_dk(v_dw_2D * p_dk_ComposeTable, v_dw_2D &dk_SingleTable, KMX_DWORD dk) { +/*bool mac_query_dk_combinations_for_specific_dk(v_dw_2D * p_dk_ComposeTable, v_dw_2D &dk_SingleTable, KMX_DWORD dk) { v_dw_1D line; for ( int i =0; i< (int) (*p_dk_ComposeTable).size(); i++) { - if (((*p_dk_ComposeTable)[i][0] == dk) && (IsKeymanUsedChar((*p_dk_ComposeTable)[i][1]))) { + if (((*p_dk_ComposeTable)[i][0] == dk) && (mac_IsKeymanUsedChar((*p_dk_ComposeTable)[i][1]))) { line.push_back((*p_dk_ComposeTable)[i][0]); line.push_back((*p_dk_ComposeTable)[i][1]); line.push_back((*p_dk_ComposeTable)[i][2]); @@ -77,7 +77,7 @@ bool found_dk_inVector(KMX_WCHAR dk, std::vector &dkVec) { return false; }*/ -/*KMX_DWORD KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap* keymap) { +/*KMX_DWORD mac_KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap* keymap) { guint Keyval = (guint) KVal; GdkKeymapKey* keys; gint n_keys; @@ -95,8 +95,8 @@ bool found_dk_inVector(KMX_WCHAR dk, std::vector &dkVec) { return Cap; }*/ -/*void create_DKTable(v_dw_2D & dk_ComposeTable) { - //create a 2D-Vector which contains data for ALL existing deadkey combinations on a Linux Keyboard: +void mac_create_DKTable(v_dw_2D & dk_ComposeTable) { +/* //create a 2D-Vector which contains data for ALL existing deadkey combinations on a Linux Keyboard: //dk_ComposeTable[i][0] : First (e.g. dead_circumflex) //dk_ComposeTable[i][1] : Second (e.g. a) //dk_ComposeTable[i][3] : Unicode-Value (e.g. 0x00E2) @@ -106,370 +106,369 @@ bool found_dk_inVector(KMX_WCHAR dk, std::vector &dkVec) { v_dw_1D line; - line = createLine("dead_circumflex", "a", 0x00E2, "small A with circumflex"); + line = mac_createLine("dead_circumflex", "a", 0x00E2, "small A with circumflex"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "A", 0x00C2, "capital A with circumflex"); + line = mac_createLine("dead_circumflex", "A", 0x00C2, "capital A with circumflex"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "e", 0x00EA, "small E with circumflex"); + line = mac_createLine("dead_circumflex", "e", 0x00EA, "small E with circumflex"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "E", 0x00CA, "capital E with circumflex"); + line = mac_createLine("dead_circumflex", "E", 0x00CA, "capital E with circumflex"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "i", 0x00EE, "small I with circumflex"); + line = mac_createLine("dead_circumflex", "i", 0x00EE, "small I with circumflex"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "I", 0x00CE, "capital I with circumflex"); + line = mac_createLine("dead_circumflex", "I", 0x00CE, "capital I with circumflex"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "o", 0x00F4, "small O with circumflex"); + line = mac_createLine("dead_circumflex", "o", 0x00F4, "small O with circumflex"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "O", 0x00D4, "capital O with circumflex"); + line = mac_createLine("dead_circumflex", "O", 0x00D4, "capital O with circumflex"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "u", 0x00FB, "small U with circumflex"); + line = mac_createLine("dead_circumflex", "u", 0x00FB, "small U with circumflex"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "U", 0x00DB, "capital U with circumflex"); + line = mac_createLine("dead_circumflex", "U", 0x00DB, "capital U with circumflex"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "a", 0x00E1, "small A with acute"); + line = mac_createLine("dead_acute", "a", 0x00E1, "small A with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "A", 0x00C1, "capital A with acute"); + line = mac_createLine("dead_acute", "A", 0x00C1, "capital A with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "c", 0x0107, "small C with acute"); + line = mac_createLine("dead_acute", "c", 0x0107, "small C with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "C", 0x0106, "capital C with acute"); + line = mac_createLine("dead_acute", "C", 0x0106, "capital C with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "e", 0x00E9, "small E with acute"); + line = mac_createLine("dead_acute", "e", 0x00E9, "small E with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "E", 0x00C9, "capital E with acute"); + line = mac_createLine("dead_acute", "E", 0x00C9, "capital E with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "i", 0x00ED, "small I with acute"); + line = mac_createLine("dead_acute", "i", 0x00ED, "small I with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "I", 0x00CD, "capital I with acute"); + line = mac_createLine("dead_acute", "I", 0x00CD, "capital I with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "l", 0x013A, "small L with acute"); + line = mac_createLine("dead_acute", "l", 0x013A, "small L with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "L", 0x0139, "capital L with acute"); + line = mac_createLine("dead_acute", "L", 0x0139, "capital L with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "n", 0x0144, "small N with acute"); + line = mac_createLine("dead_acute", "n", 0x0144, "small N with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "N", 0x0143, "capital N with acute"); + line = mac_createLine("dead_acute", "N", 0x0143, "capital N with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "o", 0x00F3, "small O with acute"); + line = mac_createLine("dead_acute", "o", 0x00F3, "small O with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "O", 0x00D3, "capital O with acute"); + line = mac_createLine("dead_acute", "O", 0x00D3, "capital O with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "r", 0x0155, "small R with acute"); + line = mac_createLine("dead_acute", "r", 0x0155, "small R with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "R", 0x0154, "capital R with acute"); + line = mac_createLine("dead_acute", "R", 0x0154, "capital R with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "s", 0x015B, "small S with acute"); + line = mac_createLine("dead_acute", "s", 0x015B, "small S with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "S", 0x015A, "capital S with acute"); + line = mac_createLine("dead_acute", "S", 0x015A, "capital S with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "u", 0x00FA, "small U with acute"); + line = mac_createLine("dead_acute", "u", 0x00FA, "small U with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "U", 0x00DA, "capital U with acute"); + line = mac_createLine("dead_acute", "U", 0x00DA, "capital U with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "y", 0x00FD, "small Y with acute"); + line = mac_createLine("dead_acute", "y", 0x00FD, "small Y with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "Y", 0x00DD, "capital Y with acute"); + line = mac_createLine("dead_acute", "Y", 0x00DD, "capital Y with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "z", 0x017A, "small Z with acute"); + line = mac_createLine("dead_acute", "z", 0x017A, "small Z with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "Z", 0x0179, "capital Z with acute"); + line = mac_createLine("dead_acute", "Z", 0x0179, "capital Z with acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_grave", "a", 0x00E0, "small A with grave"); + line = mac_createLine("dead_grave", "a", 0x00E0, "small A with grave"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_grave", "A", 0x00C0, "capital A with grave"); + line = mac_createLine("dead_grave", "A", 0x00C0, "capital A with grave"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_grave", "e", 0x00E8, "small E with grave"); + line = mac_createLine("dead_grave", "e", 0x00E8, "small E with grave"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_grave", "E", 0x00C8, "capital E with grave"); + line = mac_createLine("dead_grave", "E", 0x00C8, "capital E with grave"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_grave", "i", 0x00EC, "small I with grave"); + line = mac_createLine("dead_grave", "i", 0x00EC, "small I with grave"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_grave", "I", 0x00CC, "capital I with grave"); + line = mac_createLine("dead_grave", "I", 0x00CC, "capital I with grave"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_grave", "o", 0x00F2, "small O with grave"); + line = mac_createLine("dead_grave", "o", 0x00F2, "small O with grave"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_grave", "O", 0x00D2, "capital O with grave"); + line = mac_createLine("dead_grave", "O", 0x00D2, "capital O with grave"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_grave", "u", 0x00F9, "small U with grave"); + line = mac_createLine("dead_grave", "u", 0x00F9, "small U with grave"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_grave", "U", 0x00D9, "capital U with grave"); + line = mac_createLine("dead_grave", "U", 0x00D9, "capital U with grave"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_tilde", "a", 0x00E3, "small A with tilde"); + line = mac_createLine("dead_tilde", "a", 0x00E3, "small A with tilde"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_tilde", "A", 0x00C3, "capital A with tilde"); + line = mac_createLine("dead_tilde", "A", 0x00C3, "capital A with tilde"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_tilde", "i", 0x0129, "small I with tilde"); + line = mac_createLine("dead_tilde", "i", 0x0129, "small I with tilde"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_tilde", "I", 0x0128, "capital I with tilde"); + line = mac_createLine("dead_tilde", "I", 0x0128, "capital I with tilde"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_tilde", "n", 0x00F1, "small N with tilde"); + line = mac_createLine("dead_tilde", "n", 0x00F1, "small N with tilde"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_tilde", "N", 0x00D1, "capital N with tilde"); + line = mac_createLine("dead_tilde", "N", 0x00D1, "capital N with tilde"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_tilde", "o", 0x00F5, "small O with tilde"); + line = mac_createLine("dead_tilde", "o", 0x00F5, "small O with tilde"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_tilde", "O", 0x00D5, "capital O with tilde"); + line = mac_createLine("dead_tilde", "O", 0x00D5, "capital O with tilde"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_tilde", "u", 0x0169, "small U with tilde"); + line = mac_createLine("dead_tilde", "u", 0x0169, "small U with tilde"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_tilde", "U", 0x0168, "capital U with tilde"); + line = mac_createLine("dead_tilde", "U", 0x0168, "capital U with tilde"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_macron", "a", 0x0101, "small A with macron"); + line = mac_createLine("dead_macron", "a", 0x0101, "small A with macron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_macron", "A", 0x0100, "capital A with macron"); + line = mac_createLine("dead_macron", "A", 0x0100, "capital A with macron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_macron", "e", 0x0113, "small E with macron"); + line = mac_createLine("dead_macron", "e", 0x0113, "small E with macron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_macron", "E", 0x0112, "capital E with macron"); + line = mac_createLine("dead_macron", "E", 0x0112, "capital E with macron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_macron", "i", 0x012B, "small I with macron"); + line = mac_createLine("dead_macron", "i", 0x012B, "small I with macron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_macron", "I", 0x012A, "capital I with macron"); + line = mac_createLine("dead_macron", "I", 0x012A, "capital I with macron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_macron", "o", 0x014D, "small O with macron"); + line = mac_createLine("dead_macron", "o", 0x014D, "small O with macron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_macron", "O", 0x014C, "capital O with macron"); + line = mac_createLine("dead_macron", "O", 0x014C, "capital O with macron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_macron", "u", 0x016B, "small U with macron"); + line = mac_createLine("dead_macron", "u", 0x016B, "small U with macron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_macron", "U", 0x016A, "capital U with macron"); + line = mac_createLine("dead_macron", "U", 0x016A, "capital U with macron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_breve", "a", 0x0103, "small A with breve"); + line = mac_createLine("dead_breve", "a", 0x0103, "small A with breve"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_breve", "A", 0x0102, "capital A with breve"); + line = mac_createLine("dead_breve", "A", 0x0102, "capital A with breve"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_breve", "g", 0x011F, "small G with breve"); + line = mac_createLine("dead_breve", "g", 0x011F, "small G with breve"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_breve", "G", 0x011E, "capital G with breve"); + line = mac_createLine("dead_breve", "G", 0x011E, "capital G with breve"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovedot", "e", 0x0117, "small E with dot above"); + line = mac_createLine("dead_abovedot", "e", 0x0117, "small E with dot above"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovedot", "E", 0x0116, "capital E with dot above"); + line = mac_createLine("dead_abovedot", "E", 0x0116, "capital E with dot above"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovedot", "i", 0x0131, "small DOTLESS_I"); + line = mac_createLine("dead_abovedot", "i", 0x0131, "small DOTLESS_I"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovedot", "I", 0x0130, "capital I with dot above"); + line = mac_createLine("dead_abovedot", "I", 0x0130, "capital I with dot above"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovedot", "z", 0x017C, "small Z with dot above"); + line = mac_createLine("dead_abovedot", "z", 0x017C, "small Z with dot above"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovedot", "Z", 0x017B, "capital Z with dot above"); + line = mac_createLine("dead_abovedot", "Z", 0x017B, "capital Z with dot above"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "a", 0x00E4, "small A with diaeresis"); + line = mac_createLine("dead_diaeresis", "a", 0x00E4, "small A with diaeresis"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "A", 0x00C4, "capital A with diaeresis"); + line = mac_createLine("dead_diaeresis", "A", 0x00C4, "capital A with diaeresis"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "e", 0x00EB, "small E with diaeresis"); + line = mac_createLine("dead_diaeresis", "e", 0x00EB, "small E with diaeresis"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "E", 0x00CB, "capital E with diaeresis"); + line = mac_createLine("dead_diaeresis", "E", 0x00CB, "capital E with diaeresis"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "i", 0x00EF, "small I with diaeresis"); + line = mac_createLine("dead_diaeresis", "i", 0x00EF, "small I with diaeresis"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "I", 0x00CF, "capital I with diaeresis"); + line = mac_createLine("dead_diaeresis", "I", 0x00CF, "capital I with diaeresis"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "o", 0x00F6, "small O with diaeresis"); + line = mac_createLine("dead_diaeresis", "o", 0x00F6, "small O with diaeresis"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "O", 0x00D6, "capital O with diaeresis"); + line = mac_createLine("dead_diaeresis", "O", 0x00D6, "capital O with diaeresis"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "u", 0x00FC, "small U with diaeresis"); + line = mac_createLine("dead_diaeresis", "u", 0x00FC, "small U with diaeresis"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "U", 0x00DC, "capital U with diaeresis"); + line = mac_createLine("dead_diaeresis", "U", 0x00DC, "capital U with diaeresis"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "y", 0x00FF, "small Y with diaeresis"); + line = mac_createLine("dead_diaeresis", "y", 0x00FF, "small Y with diaeresis"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "Y", 0x0178, "capital Y with diaeresis"); + line = mac_createLine("dead_diaeresis", "Y", 0x0178, "capital Y with diaeresis"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovering", "a", 0x00E5, "small A with ring above"); + line = mac_createLine("dead_abovering", "a", 0x00E5, "small A with ring above"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovering", "A", 0x00C5, "capital A with ring above"); + line = mac_createLine("dead_abovering", "A", 0x00C5, "capital A with ring above"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovering", "u", 0x016F, "small U with ring above"); + line = mac_createLine("dead_abovering", "u", 0x016F, "small U with ring above"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovering", "U", 0x016E, "capital U with ring above"); + line = mac_createLine("dead_abovering", "U", 0x016E, "capital U with ring above"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_doubleacute", "o", 0x0151, "small O with double acute"); + line = mac_createLine("dead_doubleacute", "o", 0x0151, "small O with double acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_doubleacute", "O", 0x0150, "capital O with double acute"); + line = mac_createLine("dead_doubleacute", "O", 0x0150, "capital O with double acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_doubleacute", "u", 0x0171, "small U with double acute"); + line = mac_createLine("dead_doubleacute", "u", 0x0171, "small U with double acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_doubleacute", "U", 0x0170, "capital U with double acute"); + line = mac_createLine("dead_doubleacute", "U", 0x0170, "capital U with double acute"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "c", 0x010D, "small C with caron"); + line = mac_createLine("dead_caron", "c", 0x010D, "small C with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "C", 0x010C, "capital C with caron"); + line = mac_createLine("dead_caron", "C", 0x010C, "capital C with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "d", 0x010F, "small D with caron"); + line = mac_createLine("dead_caron", "d", 0x010F, "small D with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "D", 0x010E, "capital D with caron"); + line = mac_createLine("dead_caron", "D", 0x010E, "capital D with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "e", 0x011B, "small E with caron"); + line = mac_createLine("dead_caron", "e", 0x011B, "small E with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "E", 0x011A, "capital E with caron"); + line = mac_createLine("dead_caron", "E", 0x011A, "capital E with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "l", 0x013E, "small L with caron"); + line = mac_createLine("dead_caron", "l", 0x013E, "small L with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "L", 0x013D, "capital L with caron"); + line = mac_createLine("dead_caron", "L", 0x013D, "capital L with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "n", 0x0148, "small N with caron"); + line = mac_createLine("dead_caron", "n", 0x0148, "small N with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "N", 0x0147, "capital N with caron"); + line = mac_createLine("dead_caron", "N", 0x0147, "capital N with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "r", 0x0159, "small R with caron"); + line = mac_createLine("dead_caron", "r", 0x0159, "small R with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "R", 0x0158, "capital R with caron"); + line = mac_createLine("dead_caron", "R", 0x0158, "capital R with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "s", 0x0161, "small S with caron"); + line = mac_createLine("dead_caron", "s", 0x0161, "small S with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "S", 0x0160, "capital S with caron"); + line = mac_createLine("dead_caron", "S", 0x0160, "capital S with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "t", 0x0165, "small T with caron"); + line = mac_createLine("dead_caron", "t", 0x0165, "small T with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "T", 0x0164, "capital T with caron"); + line = mac_createLine("dead_caron", "T", 0x0164, "capital T with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "z", 0x017E, "small Z with caron"); + line = mac_createLine("dead_caron", "z", 0x017E, "small Z with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "Z", 0x017D, "capital Z with caron"); + line = mac_createLine("dead_caron", "Z", 0x017D, "capital Z with caron"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "c", 0x00E7, "small C with cedilla"); + line = mac_createLine("dead_cedilla", "c", 0x00E7, "small C with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "C", 0x00C7, "capital C with cedilla"); + line = mac_createLine("dead_cedilla", "C", 0x00C7, "capital C with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "g", 0x0123, "small G with cedilla"); + line = mac_createLine("dead_cedilla", "g", 0x0123, "small G with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "G", 0x0122, "capital G with cedilla"); + line = mac_createLine("dead_cedilla", "G", 0x0122, "capital G with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "k", 0x0137, "small K with cedilla"); + line = mac_createLine("dead_cedilla", "k", 0x0137, "small K with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "K", 0x0136, "capital K with cedilla"); + line = mac_createLine("dead_cedilla", "K", 0x0136, "capital K with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "l", 0x013C, "small L with cedilla"); + line = mac_createLine("dead_cedilla", "l", 0x013C, "small L with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "L", 0x013B, "capital L with cedilla"); + line = mac_createLine("dead_cedilla", "L", 0x013B, "capital L with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "n", 0x0146, "small N with cedilla"); + line = mac_createLine("dead_cedilla", "n", 0x0146, "small N with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "N", 0x0145, "capital N with cedilla"); + line = mac_createLine("dead_cedilla", "N", 0x0145, "capital N with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "r", 0x0157, "small R with cedilla"); + line = mac_createLine("dead_cedilla", "r", 0x0157, "small R with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "R", 0x0156, "capital R with cedilla"); + line = mac_createLine("dead_cedilla", "R", 0x0156, "capital R with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "s", 0x015F, "small S with cedilla"); + line = mac_createLine("dead_cedilla", "s", 0x015F, "small S with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "S", 0x015E, "capital S with cedilla"); + line = mac_createLine("dead_cedilla", "S", 0x015E, "capital S with cedilla"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_ogonek", "a", 0x0105, "small A with ogonek"); + line = mac_createLine("dead_ogonek", "a", 0x0105, "small A with ogonek"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_ogonek", "A", 0x0104, "capital A with ogonek"); + line = mac_createLine("dead_ogonek", "A", 0x0104, "capital A with ogonek"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_ogonek", "e", 0x0119, "small E with ogonek"); + line = mac_createLine("dead_ogonek", "e", 0x0119, "small E with ogonek"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_ogonek", "E", 0x0118, "capital E with ogonek"); + line = mac_createLine("dead_ogonek", "E", 0x0118, "capital E with ogonek"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_ogonek", "i", 0x012F, "small I with ogonek"); + line = mac_createLine("dead_ogonek", "i", 0x012F, "small I with ogonek"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_ogonek", "I", 0x012E, "capital I with ogonek"); + line = mac_createLine("dead_ogonek", "I", 0x012E, "capital I with ogonek"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_ogonek", "u", 0x0173, "small U with ogonek"); + line = mac_createLine("dead_ogonek", "u", 0x0173, "small U with ogonek"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_ogonek", "U", 0x0172, "capital U with ogonek"); + line = mac_createLine("dead_ogonek", "U", 0x0172, "capital U with ogonek"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "space", 0x005E, "CIRCUMFLEX_ACCENT"); + line = mac_createLine("dead_circumflex", "space", 0x005E, "CIRCUMFLEX_ACCENT"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "space", 0x0027, "APOSTROPHE"); + line = mac_createLine("dead_acute", "space", 0x0027, "APOSTROPHE"); dk_ComposeTable.push_back(line); line.clear(); - //line = createLine("dead_acute", "space", 0x00B4, "ACUTE_ACCENT"); // _S2 TOP_3 ToDo remove - this is not right: just for testing + //line = mac_createLine("dead_acute", "space", 0x00B4, "ACUTE_ACCENT"); // _S2 TOP_3 ToDo remove - this is not right: just for testing // dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_grave", "space", 0x0060, "GRAVE_ACCENT"); + line = mac_createLine("dead_grave", "space", 0x0060, "GRAVE_ACCENT"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_breve", "space", 0x02D8, "BREVE"); + line = mac_createLine("dead_breve", "space", 0x02D8, "BREVE"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovedot", "space", 0x02D9, "DOT_ABOVE"); + line = mac_createLine("dead_abovedot", "space", 0x02D9, "DOT_ABOVE"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovering", "space", 0x02DA, "RING_ABOVE"); + line = mac_createLine("dead_abovering", "space", 0x02DA, "RING_ABOVE"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_doubleacute", "space", 0x02DD, "DOUBLE_ACUTE_ACCENT"); + line = mac_createLine("dead_doubleacute", "space", 0x02DD, "DOUBLE_ACUTE_ACCENT"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "space", 0x02C7, "CARON"); + line = mac_createLine("dead_caron", "space", 0x02C7, "CARON"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "space", 0x00B8, "CEDILLA"); + line = mac_createLine("dead_cedilla", "space", 0x00B8, "CEDILLA"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_ogonek", "space", 0x02DB, "OGONEK"); + line = mac_createLine("dead_ogonek", "space", 0x02DB, "OGONEK"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_tilde", "space", 0x007E, "TILDE"); + line = mac_createLine("dead_tilde", "space", 0x007E, "TILDE"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_breve", "dead_breve", 0x02D8, "BREVE"); + line = mac_createLine("dead_breve", "dead_breve", 0x02D8, "BREVE"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovedot", "abovedot", 0x02D9, "DOT_ABOVE"); + line = mac_createLine("dead_abovedot", "abovedot", 0x02D9, "DOT_ABOVE"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovedot", "dead_abovedot", 0x02D9, "DOT_ABOVE"); + line = mac_createLine("dead_abovedot", "dead_abovedot", 0x02D9, "DOT_ABOVE"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_abovering", "dead_abovering", 0x02DA, "RING_ABOVE"); + line = mac_createLine("dead_abovering", "dead_abovering", 0x02DA, "RING_ABOVE"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "apostrophe", 0x00B4, "ACUTE_ACCENT"); + line = mac_createLine("dead_acute", "apostrophe", 0x00B4, "ACUTE_ACCENT"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "acute", 0x00B4, "ACUTE_ACCENT"); + line = mac_createLine("dead_acute", "acute", 0x00B4, "ACUTE_ACCENT"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_acute", "dead_acute", 0x00B4, "ACUTE_ACCENT"); + line = mac_createLine("dead_acute", "dead_acute", 0x00B4, "ACUTE_ACCENT"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_doubleacute", "dead_doubleacute", 0x02DD, "DOUBLE_ACUTE_ACCENT"); + line = mac_createLine("dead_doubleacute", "dead_doubleacute", 0x02DD, "DOUBLE_ACUTE_ACCENT"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "caron", 0x02C7, "CARON"); + line = mac_createLine("dead_caron", "caron", 0x02C7, "CARON"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_caron", "dead_caron", 0x02C7, "CARON"); + line = mac_createLine("dead_caron", "dead_caron", 0x02C7, "CARON"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "comma", 0x00B8, "CEDILLA"); + line = mac_createLine("dead_cedilla", "comma", 0x00B8, "CEDILLA"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "cedilla", 0x00B8, "CEDILLA"); + line = mac_createLine("dead_cedilla", "cedilla", 0x00B8, "CEDILLA"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_cedilla", "dead_cedilla", 0x00B8, "CEDILLA"); + line = mac_createLine("dead_cedilla", "dead_cedilla", 0x00B8, "CEDILLA"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "minus", 0x00AF, "MACRON"); + line = mac_createLine("dead_circumflex", "minus", 0x00AF, "MACRON"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "asciicircum", 0x005E, "CIRCUMFLEX_ACCENT"); + line = mac_createLine("dead_circumflex", "asciicircum", 0x005E, "CIRCUMFLEX_ACCENT"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "underscore", 0x00AF, "MACRON"); + line = mac_createLine("dead_circumflex", "underscore", 0x00AF, "MACRON"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_circumflex", "dead_circumflex", 0x005E, "CIRCUMFLEX_ACCENT"); + line = mac_createLine("dead_circumflex", "dead_circumflex", 0x005E, "CIRCUMFLEX_ACCENT"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "quotedbl", 0x00A8, "DIAERESIS"); + line = mac_createLine("dead_diaeresis", "quotedbl", 0x00A8, "DIAERESIS"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "diaeresis", 0x00A8, "DIAERESIS"); + line = mac_createLine("dead_diaeresis", "diaeresis", 0x00A8, "DIAERESIS"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_diaeresis", "dead_diaeresis", 0x00A8, "DIAERESIS"); + line = mac_createLine("dead_diaeresis", "dead_diaeresis", 0x00A8, "DIAERESIS"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_grave", "grave", 0x0060, "GRAVE_ACCENT"); + line = mac_createLine("dead_grave", "grave", 0x0060, "GRAVE_ACCENT"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_grave", "dead_grave", 0x0060, "GRAVE_ACCENT"); + line = mac_createLine("dead_grave", "dead_grave", 0x0060, "GRAVE_ACCENT"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_macron", "macron", 0x00AF, "MACRON"); + line = mac_createLine("dead_macron", "macron", 0x00AF, "MACRON"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_macron", "dead_macron", 0x00AF, "MACRON"); + line = mac_createLine("dead_macron", "dead_macron", 0x00AF, "MACRON"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_ogonek", "ogonek", 0x02DB, "OGONEK"); + line = mac_createLine("dead_ogonek", "ogonek", 0x02DB, "OGONEK"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_ogonek", "dead_ogonek", 0x02DB, "OGONEK"); + line = mac_createLine("dead_ogonek", "dead_ogonek", 0x02DB, "OGONEK"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_tilde", "asciitilde", 0x007E, "TILDE"); + line = mac_createLine("dead_tilde", "asciitilde", 0x007E, "TILDE"); dk_ComposeTable.push_back(line); line.clear(); - line = createLine("dead_tilde", "dead_tilde", 0x007E, "TILDE"); + line = mac_createLine("dead_tilde", "dead_tilde", 0x007E, "TILDE"); dk_ComposeTable.push_back(line); line.clear(); +*/ } - -*/ \ No newline at end of file diff --git a/mac/mcompile/deadkey.h b/mac/mcompile/deadkey.h index e242d270c99..e9f8d3a2efa 100755 --- a/mac/mcompile/deadkey.h +++ b/mac/mcompile/deadkey.h @@ -4,30 +4,29 @@ #include #include "mc_import_rules.h" + //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ - - // create a vector for a dk combination ( ` + a -> à ) -v_dw_1D createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult); +v_dw_1D mac_createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult); // create a 2D-vector of all dk combinations ( ` + a -> à ; ^ + a -> â ; `+ e -> è; ...) -void create_DKTable(v_dw_2D & dk_ComposeTable); +void mac_create_DKTable(v_dw_2D & dk_ComposeTable); // find all possible dk combinations that exist -std::vector create_alDead(); +std::vector mac_create_alDead(); // refine dk to those used in the underlying keyboard -void refine_alDead(KMX_WCHAR dk, std::vector &myVec, std::vector *p_All_Vec); +void mac_refine_alDead(KMX_WCHAR dk, std::vector &myVec, std::vector *p_All_Vec); // check if entry is already there bool found_dk_inVector(KMX_WCHAR dk, std::vector &myVec); -// get all combination for a specific deadkey(dk) from the dk_vector query_dk_combinations_for_specific_dk which holds all possible dk: ^-> â,ê,î,ô,û,... -bool query_dk_combinations_for_specific_dk(v_dw_2D * dk_ComposeTable, v_dw_2D & dk_SingleTable, KMX_DWORD dk); +// get all combination for a specific deadkey(dk) from the dk_vector mac_query_dk_combinations_for_specific_dk which holds all possible dk: ^-> â,ê,î,ô,û,... +bool mac_query_dk_combinations_for_specific_dk(v_dw_2D * dk_ComposeTable, v_dw_2D & dk_SingleTable, KMX_DWORD dk); // get the shifted character of a key and write shiftstate of KVal to shift -//KMX_DWORD KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap* keymap); +//KMX_DWORD mac_KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap* keymap); # endif//DEADKEY_H \ No newline at end of file diff --git a/mac/mcompile/filesystem.cpp b/mac/mcompile/filesystem.cpp index 8606c3576cc..459312448e7 100755 --- a/mac/mcompile/filesystem.cpp +++ b/mac/mcompile/filesystem.cpp @@ -1,8 +1,4 @@ -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - #ifdef __EMSCRIPTEN__ #include #include @@ -190,3 +186,7 @@ KMX_BOOL kmcmp_FileExists(const KMX_WCHAR* filename) { return FALSE; }; + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 2e3b841ca25..13b35b8f6ee 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -1,305 +1,15 @@ #include "keymap.h" - -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - - -/* -#include - // unmodified, shift, RALT, shift+RALT -int map_VKShiftState_to_LinModifier(int VKShiftState) { - if (VKShiftState == 0 ) return 0; // 0000 0000 // - else if (VKShiftState == 16) return 1; // 0001 0000 // - else if (VKShiftState == 9 ) return 2; // 0000 1001 // - else if (VKShiftState == 25) return 3; // 0001 1001 // +int mac_map_VKShiftState_to_LinModifier(int VKShiftState) { + if (VKShiftState == 0 ) return 0; // 0000 0000 // _S2 are the bits OK like that? + else if (VKShiftState == 16) return 2; // 0001 0000 // + else if (VKShiftState == 9 ) return 4; // 0000 1001 // + else if (VKShiftState == 25) return 6; // 0001 1001 // else return VKShiftState; -}*/ - -/* KMX_DWORD convertNamesTo_DWORD_Value(std::string tok_str) { - // more on https://manpages.ubuntu.com/manpages/jammy/man3/keysyms.3tk.html - std::map first; - - first["ampersand"] = 38; - first["apostrophe"] = 39; - first["asciicircum"] = 136; - first["asciitilde"] = 126; - first["asterisk"] = 42; - first["at"] = 64; - first["backslash"] = 92; - first["BackSpace"] = 65288; - first["bar"] = 124; - first["braceleft"] = 123; - first["braceright"] = 125; - first["bracketleft"] = 91; - first["bracketright"] = 93; - first["colon"] = 58; - first["comma"] = 44; - first["diaeresis"] = 168; - first["dollar"] = 36; - first["equal"] = 61; - first["exclam"] = 33; - first["grave"] = 96; - first["greater"] = 62; - first["less"] = 60; - first["minus"] = 45; - first["numbersign"] = 35; - first["parenleft"] = 40; - first["parenright"] = 41; - first["percent"] = 37; - first["period"] = 46; - first["plus"] = 43; - first["question"] = 63; - first["quotedbl"] = 34; - first["semicolon"] = 59; - first["slash"] = 47; - first["space"] = 32; - first["ssharp"] = 223; - first["underscore"] = 95; - - - first["nobreakspace"] = 160; - first["exclamdown"] = 161; - first["cent"] = 162; - first["sterling"] = 163; - first["currency"] = 164; - first["yen"] = 165; - first["brokenbar"] = 166; - first["section"] = 167; - first["copyright"] = 169; - first["ordfeminine"] = 170; - first["guillemotleft"] = 171; - first["notsign"] = 172; - first["hyphen"] = 173; - first["registered"] = 174; - first["macron"] = 175; - first["degree"] = 176; - first["plusminus"] = 177; - first["twosuperior"] = 178; - first["threesuperior"] = 179; - first["acute"] = 180; - first["mu"] = 181; - first["paragraph"] = 182; - first["periodcentered"] = 183; - first["cedilla"] = 184; - first["onesuperior"] = 185; - first["masculine"] = 186; - first["guillemotright"] = 187; - first["onequarter"] = 188; - first["onehalf"] = 189; - first["threequarters"] = 190; - first["questiondown"] = 191; - first["Agrave"] = 192; - first["Aacute"] = 193; - first["Acircumflex"] = 194; - first["Atilde"] = 195; - first["Adiaeresis"] = 196; - first["Aring"] = 197; - first["AE"] = 198; - first["Ccedilla"] = 199; - first["Egrave"] = 200; - first["Eacute"] = 201; - first["Ecircumflex"] = 202; - first["Ediaeresis"] = 203; - first["Igrave"] = 204; - first["Iacute"] = 205; - first["Icircumflex"] = 206; - first["Idiaeresis"] = 207; - first["ETH"] = 208; - first["Ntilde"] = 209; - first["Ograve"] = 210; - first["Oacute"] = 211; - first["Ocircumflex"] = 212; - first["Otilde"] = 213; - first["Odiaeresis"] = 214; - first["multiply"] = 215; - first["Oslash"] = 216; - first["Ugrave"] = 217; - first["Uacute"] = 218; - first["Ucircumflex"] = 219; - first["Udiaeresis"] = 220; - first["Yacute"] = 221; - first["THORN"] = 222; - first["agrave"] = 224; - first["aacute"] = 225; - first["acircumflex"] = 226; - first["atilde"] = 227; - first["adiaeresis"] = 228; - first["aring"] = 229; - first["ae"] = 230; - first["ccedilla"] = 231; - first["egrave"] = 232; - first["eacute"] = 233; - first["ecircumflex"] = 234; - first["ediaeresis"] = 235; - first["igrave"] = 236; - first["iacute"] = 237; - first["icircumflex"] = 238; - first["idiaeresis"] = 239; - first["eth"] = 240; - first["ntilde"] = 241; - first["ograve"] = 242; - first["oacute"] = 243; - first["ocircumflex"] = 244; - first["otilde"] = 245; - first["odiaeresis"] = 246; - first["division"] = 247; - first["oslash"] = 248; - first["ugrave"] = 249; - first["uacute"] = 250; - first["ucircumflex"] = 251; - first["udiaeresis"] = 252; - first["yacute"] = 253; - first["thorn"] = 254; - first["ydiaeresis"] = 255; - first["Aogonek"] = 417; - first["breve"] = 418; - first["Lstroke"] = 419; - first["Lcaron"] = 421; - first["Sacute"] = 422; - first["Scaron"] = 425; - first["Scedilla"] = 426; - first["Tcaron"] = 427; - first["Zacute"] = 428; - first["Zcaron"] = 430; - first["Zabovedot"] = 431; - first["aogonek"] = 433; - first["ogonek"] = 434; - first["lstroke"] = 435; - first["lcaron"] = 437; - first["sacute"] = 438; - first["caron"] = 439; - first["scaron"] = 441; - first["scedilla"] = 442; - first["tcaron"] = 443; - first["zacute"] = 444; - first["doubleacute"] = 445; - first["zcaron"] = 446; - first["zabovedot"] = 447; - first["Racute"] = 448; - first["Abreve"] = 451; - first["Lacute"] = 453; - first["Cacute"] = 454; - first["Ccaron"] = 456; - first["Eogonek"] = 458; - first["Ecaron"] = 460; - first["Dcaron"] = 463; - first["Dstroke"] = 464; - first["Nacute"] = 465; - first["Ncaron"] = 466; - first["Odoubleacute"] = 469; - first["Rcaron"] = 472; - first["Uring"] = 473; - first["Udoubleacute"] = 475; - first["Tcedilla"] = 478; - first["racute"] = 480; - first["abreve"] = 483; - first["lacute"] = 485; - first["cacute"] = 486; - first["ccaron"] = 488; - first["eogonek"] = 490; - first["ecaron"] = 492; - first["dcaron"] = 495; - first["dstroke"] = 496; - first["nacute"] = 497; - first["ncaron"] = 498; - first["odoubleacute"] = 501; - first["rcaron"] = 504; - first["uring"] = 505; - first["udoubleacute"] = 507; - first["tcedilla"] = 510; - first["abovedot"] = 511; - first["Hstroke"] = 673; - first["Hcircumflex"] = 678; - first["Iabovedot"] = 681; - first["Gbreve"] = 683; - first["Jcircumflex"] = 684; - first["hstroke"] = 689; - first["hcircumflex"] = 694; - first["idotless"] = 697; - first["gbreve"] = 699; - first["jcircumflex"] = 700; - first["Cabovedot"] = 709; - first["Ccircumflex"] = 710; - first["Gabovedot"] = 725; - first["Gcircumflex"] = 728; - first["Ubreve"] = 733; - first["Scircumflex"] = 734; - first["cabovedot"] = 741; - first["ccircumflex"] = 742; - first["gabovedot"] = 757; - first["gcircumflex"] = 760; - first["ubreve"] = 765; - first["scircumflex"] = 766; - first["kra"] = 930; - first["Rcedilla"] = 931; - first["Itilde"] = 933; - first["Lcedilla"] = 934; - first["Emacron"] = 938; - first["Gcedilla"] = 939; - first["Tslash"] = 940; - first["rcedilla"] = 947; - first["itilde"] = 949; - first["lcedilla"] = 950; - first["emacron"] = 954; - first["gcedilla"] = 955; - first["tslash"] = 956; - first["ENG"] = 957; - first["eng"] = 959; - first["Amacron"] = 960; - first["Iogonek"] = 967; - first["Eabovedot"] = 972; - first["Imacron"] = 975; - first["Ncedilla"] = 977; - first["Omacron"] = 978; - first["Kcedilla"] = 979; - first["Uogonek"] = 985; - first["Utilde"] = 989; - first["Umacron"] = 990; - first["amacron"] = 992; - first["iogonek"] = 999; - first["eabovedot"] = 1004; - first["imacron"] = 1007; - first["ncedilla"] = 1009; - first["omacron"] = 1010; - first["kcedilla"] = 1011; - first["uogonek"] = 1017; - first["utilde"] = 1021; - first["umacron"] = 1022; - first["overline"] = 1150; - - first["dead_abovedot"] = 729; - first["dead_abovering"] = 730; - first["dead_acute"] = 180; - first["dead_breve"] = 728; - first["dead_caron"] = 711; - first["dead_cedilla"] = 184; - first["dead_circumflex"] = 94; - first["dead_diaeresis"] = 168; - first["dead_doubleacute"] = 733; - first["dead_grave"] = 96; - first["dead_ogonek"] = 731; - first["dead_perispomeni"] = 126; - first["dead_tilde"] = 126; - - first["acute accent"] = 0xB4; - - if ( tok_str.size() == 1) { - return (KMX_DWORD) ( *tok_str.c_str() ); - } - else { - std::map ::iterator it; - for (it = first.begin(); it != first.end(); ++it) { - if (it->first == tok_str) - return it->second; - } - } - return returnIfCharInvalid; -}*/ +} -/* int createOneVectorFromBothKeyboards(v_dw_3D &All_Vector,GdkKeymap *keymap) { +int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { // create a 3D-Vector which contains data of the US keyboard and the underlying Keyboard: // All_Vector[ US_Keyboard ] // [KeyCode_US ] @@ -310,210 +20,49 @@ int map_VKShiftState_to_LinModifier(int VKShiftState) { // [Keyval unshifted ] // [Keyval shifted ] - std::string US_language = "us"; - const char* text_us = "xkb_symbols \"basic\""; - if(write_US_ToVector(All_Vector,US_language, text_us)) { + if(mac_write_US_ToVector(All_Vector)) { wprintf(L"ERROR: can't write US to Vector \n"); return 1; } - // add contents of other keyboard to All_Vector - if( append_underlying_ToVector(All_Vector,keymap)) { + // add contents of underlying keyboard to All_Vector + if( mac_append_underlying_ToVector(All_Vector,keyboard_layout)) { wprintf(L"ERROR: can't append underlying ToVector \n"); return 2; } return 0; -}*/ - -/*int write_US_ToVector( v_dw_3D &vec,std::string language, const char* text) { - - std::string FullPathName = "/usr/share/X11/xkb/symbols/" + language; - - const char* path = FullPathName.c_str(); - FILE* fp = fopen((path), "r"); - if ( !fp) { - wprintf(L"ERROR: could not open file!\n"); - return 1; - } - - // create 1D-vector of the complete line - v_str_1D Vector_completeUS; - if( createCompleteRow_US(Vector_completeUS,fp , text, language)) { - wprintf(L"ERROR: can't Create complete row US \n"); - return 1; - } - - // split contents of 1D Vector to 3D vector - if( split_US_To_3D_Vector( vec,Vector_completeUS)) { - return 1; - } - - fclose(fp); - return 0; -}*/ - -/*bool createCompleteRow_US(v_str_1D &complete_List, FILE* fp, const char* text, std::string language) { - // in the Configuration file we find the appopriate paragraph between "xkb_symbol " and the next xkb_symbol - // and then copy all rows starting with "key <" to a 1D-Vector - - int buffer_size = 512; - char buffer[buffer_size]; - bool create_row = false; - const char* key = "key <"; - std::string str_txt(text); - std::string xbk_mark = "xkb_symbol"; - - if (fp) { - while (fgets(buffer, buffer_size, fp) != NULL) { - std::string str_buf(buffer); - - // stop when finding the mark xkb_symbol - if (std::string(str_buf).find(xbk_mark) != std::string::npos) - create_row = false; - - // start when finding the mark xkb_symbol + correct layout - if (std::string(str_buf).find(str_txt) != std::string::npos) - create_row = true; - - // as long as we are in the same xkb_symbol layout block and find "key <" we push the whole line into a 1D-vector - if (create_row && (std::string(str_buf).find(key) != std::string::npos)) { - complete_List.push_back(buffer); - } - } - } - complete_List.push_back(" key { [ space, space] };"); - - if (complete_List.size() <1) { - wprintf(L"ERROR: can't create row from US \n"); - return 1; - } - return 0; -}*/ - -/*int replace_KeyName_with_Keycode(std::string in) { - int out = returnIfCharInvalid; - - if ( in == "key") out = 49; // VK_ BKQUOTE // - else if ( in == "key") out = 10; // VK_1 // - else if ( in == "key") out = 11; // VK_2 // - else if ( in == "key") out = 12; // VK_3 // - else if ( in == "key") out = 13; // VK_4 // - else if ( in == "key") out = 14; // VK_5 // - else if ( in == "key") out = 15; // VK_6 // - else if ( in == "key") out = 16; // VK_7 // - else if ( in == "key") out = 17; // VK_8 // - else if ( in == "key") out = 18; // VK_9 // - else if ( in == "key") out = 19; // VK_0 // - else if ( in == "key") out = 20; // VK_MINUS K_HYPHEN // - else if ( in == "key") out = 21; // VK_EQUAL // - - else if ( in == "key") out = 24; // VK_Q // - else if ( in == "key") out = 25; // VK_W // - else if ( in == "key") out = 26; // VK_E // - else if ( in == "key") out = 27; // VK_R // - else if ( in == "key") out = 28; // VK_T // - else if ( in == "key") out = 29; // VK_Y // - else if ( in == "key") out = 30; // VK_U // - else if ( in == "key") out = 31; // VK_I // - else if ( in == "key") out = 32; // VK_O // - else if ( in == "key") out = 33; // VK_P // - else if ( in == "key") out = 34; // VK_LEFTBRACE // - else if ( in == "key") out = 35; // VK_RIGHTBRACE // - - else if ( in == "key") out = 38; // VK_A // - else if ( in == "key") out = 39; // VK_S // - else if ( in == "key") out = 40; // VK_D // - else if ( in == "key") out = 41; // VK_F // - else if ( in == "key") out = 42; // VK_G // - else if ( in == "key") out = 43; // VK_H // - else if ( in == "key") out = 44; // VK_J // - else if ( in == "key") out = 45; // VK_K // - else if ( in == "key") out = 46; // VK_L // - else if ( in == "key") out = 47; // VK_SEMICOLON // - else if ( in == "key") out = 48; // VK_APOSTROPHE // - - else if ( in == "key") out = 52; // VK_Z // - else if ( in == "key") out = 53; // VK_X // - else if ( in == "key") out = 54; // VK_C // - else if ( in == "key") out = 55; // VK_V // - else if ( in == "key") out = 56; // VK_B // - else if ( in == "key") out = 57; // VK_N // - else if ( in == "key") out = 58; // VK_M // - else if ( in == "key") out = 59; // VK_ COMMA // - else if ( in == "key") out = 60; // VK_DOT // - else if ( in == "key") out = 61; // VK_SLASH // - else if ( in == "key") out = 51; // VK_BKSLASH // - else if ( in == "key") out = 63; // VK_RIGHTSHIFT // - else if ( in == "key") out = 65; // VK_SPACE // - - return out; -}*/ - -/*int split_US_To_3D_Vector(v_dw_3D &all_US,v_str_1D completeList) { - // 1: take the whole line of the 1D-Vector and remove unwanted characters. - // 2: seperate the name e.g. key from the shiftstates - // 3: convert to KMX_DWORD - // 4: push Names/Shiftstates to shift_states and then shift_states to All_US, our 3D-Vector holding all Elements - - std::vector delim{' ', '[', ']', '}', ';', '\t', '\n'}; - char split_bracel = '{'; - char split_comma = ','; - int Keycde; - v_str_1D tokens; - v_dw_1D tokens_dw; - v_dw_2D shift_states; - KMX_DWORD tokens_int; - - // loop through the whole vector - for (int k = 0; k < (int)completeList.size(); k++) { - - // remove all unwanted char - for (int i = 0; i < (int) delim.size(); i++) { - completeList[k].erase(remove(completeList[k].begin(), completeList[k].end(), delim[i]), completeList[k].end()); - } - - // only lines with ("key<.. are of interest - if (completeList[k].find("key<") != std::string::npos) { - - //split off the key names - std::istringstream split1(completeList[k]); - for (std::string each; std::getline(split1, each, split_bracel); tokens.push_back(each)); - - // replace keys names with Keycode ( with 21,...) - Keycde = replace_KeyName_with_Keycode(tokens[0]); - tokens[0] = std::to_string(Keycde); +} - // seperate rest of the vector to its elements and push to 'tokens' - std::istringstream split(tokens[1]); - tokens.pop_back(); +int mac_write_US_ToVector( v_dw_3D &vec) { - for (std::string each; std::getline(split, each, split_comma); tokens.push_back(each)); + v_dw_1D Values; + v_dw_2D Key; - // now convert all to KMX_DWORD and fill tokens - tokens_dw.push_back((KMX_DWORD) Keycde); + // _S2 unlike mcompile-linux we do not run a function to get the characters of the US keyboard but fix them like that: + // A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P, CR, L, J, ', K, ;, \, ,, /, N, M, . + std::vector US_Base = {97, 115, 100, 102, 104, 103, 122, 120, 99, 118, 167, 98, 113, 119, 101, 114, 121, 116, 49, 50, 51, 52, 54, 53, 61, 57, 55, 45, 56, 48, 93, 111, 117, 91, 105, 112, 13, 108, 106, 39, 107, 59, 92, 44, 47, 110, 109, 46}; + std::vector US_Shift = {65, 83, 68, 70, 72, 71, 90, 88, 67, 86, 177, 66, 81, 87, 69, 82, 89, 84, 33, 64, 35, 36, 94, 37, 43, 40, 38, 95, 42, 41, 125, 79, 85, 123, 73, 80, 13, 76, 74, 34, 75, 58, 124, 60, 63, 78, 77, 62}; + //std::vector US_Caps= {65, 83, 68, 70, 72, 71, 90, 88, 67, 86, 66, 81, 87, 69, 82, 89, 84, 49, 50, 51, 52, 54, 53, 61, 57, 55, 45, 56, 48, 93, 79, 85, 91, 73, 80, 76, 74, 39, 75, 59, 92, 44, 47, 78, 77, 46}; - for ( int i = 1; i< (int) tokens.size();i++) { - // replace a name with a single character ( a -> a ; equal -> = ) - tokens_int = convertNamesTo_DWORD_Value(tokens[i]); - tokens_dw.push_back(tokens_int); - } - - shift_states.push_back(tokens_dw); - tokens_dw.clear(); - tokens.clear(); - } + for ( int i=0; i< US_Base.size(); i++) { + Values.push_back( i ); + Values.push_back( US_Base[i]); + Values.push_back( US_Shift[i]); + Key.push_back(Values); + Values.clear(); } - all_US.push_back(shift_states); + vec.push_back(Key); - if ( all_US.size() == 0) { - wprintf(L"ERROR: Can't split US to 3D-Vector\n"); + if ( Key.size() == 0) { + wprintf(L"ERROR: can't Create Vector for US keyboard\n"); return 1; } - return 0; -}*/ + else + return 0; +} -/*v_dw_2D create_empty_2D_Vector( int dim_rows,int dim_ss) { +v_dw_2D mac_create_empty_2D_Vector( int dim_rows,int dim_ss) { v_dw_1D shifts; v_dw_2D Vector_2D; @@ -526,12 +75,12 @@ int map_VKShiftState_to_LinModifier(int VKShiftState) { shifts.clear(); } return Vector_2D; -}*/ +} -/*int append_underlying_ToVector(v_dw_3D &All_Vector,GdkKeymap *keymap) { +int mac_append_underlying_ToVector(v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { // create a 2D vector all filled with " " and push to 3D-Vector - v_dw_2D underlying_Vector2D = create_empty_2D_Vector(All_Vector[0].size(),All_Vector[0][0].size()); + v_dw_2D underlying_Vector2D = mac_create_empty_2D_Vector(All_Vector[0].size(),All_Vector[0][0].size()); if (underlying_Vector2D.size() == 0) { wprintf(L"ERROR: can't create empty 2D-Vector\n"); @@ -550,33 +99,36 @@ int map_VKShiftState_to_LinModifier(int VKShiftState) { All_Vector[1][i][0] = All_Vector[0][i][0]; // get Keyvals of this key and copy to unshifted/shifted in "underlying"-block[1][i][1] / block[1][i][2] - All_Vector[1][i][0+1] = KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keymap,All_Vector[0][i][0],0); //shift state: unshifted:0 - All_Vector[1][i][1+1] = KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keymap,All_Vector[0][i][0],1); //shift state: shifted:1 + All_Vector[1][i][0+1] = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout,All_Vector[0][i][0],0); //shift state: unshifted:0 + All_Vector[1][i][1+1] = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout,All_Vector[0][i][0],1); //shift state: shifted:1 } return 0; } -bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]) { -// get keymap of underlying keyboard +bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { - gdk_init(&argc, &argv); - GdkDisplay *display = gdk_display_get_default(); - if (!display) { - wprintf(L"ERROR: can't get display\n"); + TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); + if (!source) { + wprintf(L"ERROR: can't get source\n"); return 1; } - *keymap = gdk_keymap_get_for_display(display); - if (!keymap) { - wprintf(L"ERROR: Can't get keymap\n"); - gdk_display_close(display); + CFDataRef layout_data = static_cast((TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData))); + * keyboard_layout = reinterpret_cast(CFDataGetBytePtr(layout_data)); + if (!keyboard_layout) { + wprintf(L"ERROR: Can't get keyboard_layout\n"); return 2; } + return 0; -}*/ +} + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ -/*bool IsKeymanUsedChar(int KV) { +/*bool mac_IsKeymanUsedChar(int KV) { // 32 A-Z a-z if ((KV == 0x20 ) || (KV >= 65 && KV <= 90) || (KV >= 97 && KV <= 122) ) return true; @@ -584,7 +136,7 @@ bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]) { return false; }*/ -/*std::u16string convert_DeadkeyValues_To_U16str(int in) { +/*std::u16string mac_convert_DeadkeyValues_To_U16str(int in) { if (in == 0 ) return u"\0"; @@ -592,13 +144,13 @@ bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]) { std::string long_name((const char*) gdk_keyval_name (in)); // e.g. "dead_circumflex" , "U+017F" , "t" if ( long_name.substr (0,2) == "U+" ) // U+... Unicode value - return CodePointToU16String(in-0x1000000); + return mac_CodePointToU16String(in-0x1000000); if (in < (int) deadkey_min) { // no deadkey; no Unicode return std::u16string(1, in); } - KMX_DWORD lname = convertNamesTo_DWORD_Value(long_name); // 65106 => "dead_circumflex" => 94 => "^" + KMX_DWORD lname = mac_convertNamesTo_DWORD_Value(long_name); // 65106 => "dead_circumflex" => 94 => "^" if (lname != returnIfCharInvalid) { return std::u16string(1, lname ); @@ -607,7 +159,30 @@ bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]) { return u"\0"; }*/ -/*int KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps) { +int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { + // _S2 not finished yet - needs deadkeys... + KMX_DWORD in_array[2] = {0,0}; + UInt32 deadkeystate = 0; + UniCharCount maxStringlength = 5; + UniCharCount actualStringlength = 0; + UniChar unicodeString[maxStringlength]; + OSStatus status; + int returnint=0; + + status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // no deadkey yet + if( shiftstate %2 == 1) + return 0; // _S2 what to return if deadkeys are used?? + else { + in_array[0] = (int) unicodeString[0]; // even: combine char -> è + returnint = in_array[0]; + return returnint; + } + + return returnint; +} + +/*int mac_KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps) { GdkModifierType consumed; GdkKeymapKey *maps; @@ -694,63 +269,56 @@ bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]) { return (int) *keyvals; }*/ -/*KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, guint keycode, int shift_state_pos) { - GdkKeymapKey *maps; - guint *keyvals; - gint count; - KMX_DWORD KVal; +//KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, guint keycode, int shift_state_pos) { +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int keycode, int shift_state_pos) { - if (!gdk_keymap_get_entries_for_keycode(keymap, keycode, &maps, &keyvals, &count)) - return 0; + KMX_DWORD KVal = mac_get_keyval_From_Keycode(keycode, shift_state_pos*2 , keyboard_layout ); - if (!(shift_state_pos <= count)) + int count = max_shiftstate; + if (!(shift_state_pos <= count*2)) return 0; if (!(keycode <= keycode_max)) return 0; - KVal = (KMX_DWORD) KMX_get_KeyVal_From_KeyCode(keymap, keycode, (ShiftState) shift_state_pos, 0); - - g_free(keyvals); - g_free(maps); - return KVal; -}*/ +} -/*KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey) { +//KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey) { +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey) { - GdkKeymapKey *maps; - guint *keyvals; - gint count; + /*GdkKeymapKey *maps; + guint *keyvals;*/ + int count; PKMX_WCHAR dky=NULL; - - if (!gdk_keymap_get_entries_for_keycode(keymap, KC_underlying, &maps, &keyvals, &count)) + if (!keyboard_layout) return 0; - - if (!(map_VKShiftState_to_LinModifier(VKShiftState) <= count)) +/* + if (!(mac_map_VKShiftState_to_LinModifier(VKShiftState) <= count)) return 0; - +*/ if (!(KC_underlying <= keycode_max)) return 0; - KMX_DWORD KeyV = KMX_get_KeyVal_From_KeyCode(keymap, KC_underlying, ShiftState(map_VKShiftState_to_LinModifier(VKShiftState)), 0); - - g_free(keyvals); - g_free(maps); + KMX_DWORD KeyV = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, KC_underlying, ShiftState(mac_map_VKShiftState_to_LinModifier(VKShiftState)), 0); +// _S2 not finished - needs deadlkeys + /*g_free(keyvals); + g_free(maps);*/ - if ((KeyV >= deadkey_min) && (KeyV <= deadkey_max) ){ // deadkey - dky = (PKMX_WCHAR) (convert_DeadkeyValues_To_U16str((int) KeyV)).c_str(); + /*if ((KeyV >= deadkey_min) && (KeyV <= deadkey_max) ){ // deadkey + dky = (PKMX_WCHAR) (mac_convert_DeadkeyValues_To_U16str((int) KeyV)).c_str(); *DeadKey = *dky; return 0xFFFF; } else if((KeyV > deadkey_max) || ((KeyV < deadkey_min) && ( KeyV > 0xFF))) // out of range return 0xFFFE; else // usable char + return KeyV;*/ return KeyV; -}*/ +} -/*KMX_WCHAR KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD VK_US) { +/*KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD VK_US) { KMX_DWORD VK_underlying; for( int i=0; i< (int)All_Vector[0].size()-1 ;i++) { for( int j=1; j< (int)All_Vector[0][0].size();j++) { @@ -763,9 +331,9 @@ bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]) { return VK_US; }*/ -/*KMX_DWORD KMX_get_KeyCodeUnderlying_From_KeyCodeUS(GdkKeymap *keymap, v_dw_3D &All_Vector, KMX_DWORD KC_US, ShiftState ss, int caps) { +/*KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(GdkKeymap *keymap, v_dw_3D &All_Vector, KMX_DWORD KC_US, ShiftState ss, int caps) { KMX_DWORD KC_underlying; - std::u16string u16str = convert_DeadkeyValues_To_U16str(KMX_get_KeyVal_From_KeyCode(keymap, KC_US, ss, caps)); + std::u16string u16str = mac_convert_DeadkeyValues_To_U16str(mac_KMX_get_KeyVal_From_KeyCode(keymap, KC_US, ss, caps)); for( int i=0; i< (int)All_Vector[1].size()-1 ;i++) { for( int j=1; j< (int)All_Vector[1][0].size();j++) { @@ -778,18 +346,18 @@ bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]) { return KC_US; }*/ -/*UINT KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS) { - return (8 + USVirtualKeyToScanCode[VirtualKeyUS]); -}*/ +UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS) { + return (mac_USVirtualKeyToScanCode[VirtualKeyUS]); +} -/*KMX_DWORD KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { +/*KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { if ( keycode >7) return (KMX_DWORD) ScanCodeToUSVirtualKey[keycode-8]; return 0; }*/ -/*std::u16string CodePointToU16String(unsigned int codepoint) { +/*std::u16string mac_CodePointToU16String(unsigned int codepoint) { std::u16string str; if constexpr (sizeof(wchar_t) > 2) { @@ -806,15 +374,40 @@ bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]) { } return str; -} -*/ +}*/ + +std::vector mac_createVectorOfKeyboard( int shiftstate, const UCKeyboardLayout * keyboard_layout) { + + std::vector dw_vec; + + for ( int i=0; i < 49; i++) { + + std::vector keyval; + keyval.push_back(i); + keyval.push_back(i); + std::u16string str16 = mac_get_character_From_Keycode(keyval, shiftstate, keyboard_layout); + dw_vec.push_back((KMX_DWORD) *str16.c_str()); + } + + // _S2 can go later + for ( int k=0; k< dw_vec.size();k++) { + printf("%i,\t", dw_vec[k]); + } + printf("\n"); + + for ( int k=0; k< dw_vec.size();k++) { + printf("%c,\t", (char) dw_vec[k]); + } + printf("\n------------------------------\n"); + return dw_vec; +} //################################################################################################################################################ //################################################################################################################################################ -std::u16string get_character_From_Keycode(int dk, int ch , int shiftstate) { +std::u16string mac_get_character_From_Keycode(int dk, int ch , int shiftstate) { std::u16string character; std::vector keyvals; @@ -826,12 +419,11 @@ std::u16string get_character_From_Keycode(int dk, int ch , int shiftstate) { const UCKeyboardLayout* keyboard_layout = reinterpret_cast(CFDataGetBytePtr(layout_data)); if (layout_data) - character = get_character_From_Keycode(keyvals, shiftstate, keyboard_layout); + character = mac_get_character_From_Keycode(keyvals, shiftstate, keyboard_layout); return character; } - -std::u16string get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { +std::u16string mac_get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { char16_t ch_array[3] = {L'\0'}; UInt32 deadkeystate = 0; UniCharCount maxStringlength = 5; @@ -852,24 +444,8 @@ std::u16string get_character_From_Keycode(std::vector keyval, int shiftstat return returnString; } -KMX_DWORD get_keyval_From_Keycode(int dk, int ch , int shiftstate) { - KMX_DWORD character; - std::vector keyvals; - keyvals.push_back(dk); - keyvals.push_back(ch); - - TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); - CFDataRef layout_data = static_cast((TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData))); - const UCKeyboardLayout* keyboard_layout = reinterpret_cast(CFDataGetBytePtr(layout_data)); - - if (layout_data) - character = get_keyval_From_Keycode(keyvals, shiftstate, keyboard_layout); - - return character; -} - -KMX_DWORD get_keyval_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { +KMX_DWORD mac_get_keyval_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { KMX_DWORD in_array[3] = {0,0,0}; UInt32 deadkeystate = 0; @@ -892,5 +468,38 @@ KMX_DWORD get_keyval_From_Keycode(std::vector keyval, int shiftstate,const returnint = in_array[0]*1000 +(int) in_array[1]; return returnint; } +KMX_DWORD mac_get_keyval_From_Keycode(int keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { + + KMX_DWORD in_array[2] = {0,0}; + UInt32 deadkeystate = 0; + UniCharCount maxStringlength = 5; + UniCharCount actualStringlength = 0; + UniChar unicodeString[maxStringlength]; + OSStatus status; + int returnint=0; + + status = UCKeyTranslate(keyboard_layout, keyval ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // no deadkey yet + if( shiftstate %2 == 1) + return 0; // _S2 what to return if deadkeys are used?? + else { + in_array[0] = (int) unicodeString[0]; // even: combine char -> è + returnint = in_array[0]; + return returnint; + } + +return returnint; +} + + +void printoutKeyboards(v_dw_3D &All_Vector) { + printf(" values of US - Values of underlying"); + for ( int i=0; i< All_Vector[0].size(); i++) { + printf("-----------------------------\n"); + for ( int j=0; j< All_Vector[0][0].size(); j++) { + printf("i:%i\tUS: %i(%c)\t Underlying: %i(%c)\t \t\t\t%c \n" , i, All_Vector[0][i][j] , All_Vector[0][i][j] , All_Vector[1][i][j], All_Vector[1][i][j], (All_Vector[0][i][j] == All_Vector[1][i][j]) ? '.' : '*'); + } + } +} + -void fun3() {std::cout << "Hier ist fun3 von keymap.cpp...\n";} \ No newline at end of file diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 2266cb2de2f..6fe7b6f6383 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -13,13 +13,11 @@ #include "u16.h" -std::u16string get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout); -std::u16string get_character_From_Keycode(int dk, int ch , int shiftstate); +std::u16string mac_get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout); - - -KMX_DWORD get_keyval_From_Keycode(int dk, int ch , int shiftstate); -KMX_DWORD get_keyval_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout); +KMX_DWORD mac_get_keyval_From_Keycode(int dk, int ch , int shiftstate); +KMX_DWORD mac_get_keyval_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout); +KMX_DWORD mac_get_keyval_From_Keycode(int keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ); //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### @@ -88,41 +86,39 @@ typedef std::vector > v_dw_2D; typedef std::vector > > v_dw_3D; static KMX_DWORD returnIfCharInvalid = 0; +static KMX_DWORD max_shiftstate = 2; // _S2 only base+Shift static KMX_DWORD keycode_max = 94; static KMX_DWORD deadkey_min = 0xfe50; static KMX_DWORD deadkey_max = 0xfe93; //static KMX_DWORD deadkey_max = 0xfe52; // _S2 TOP_6 TODO This has to go! my test: to only return 3 dk // map Shiftstate to modifier (e.g. 0->0; 16-1; 9->2; 25->3) -int map_VKShiftState_to_LinModifier(int VKShiftState); +int mac_map_VKShiftState_to_LinModifier(int VKShiftState); // take a std::string (=contents of line symbols-file ) and returns the (int) value of the character -KMX_DWORD convertNamesTo_DWORD_Value(std::string tok_str); +KMX_DWORD mac_convertNamesTo_DWORD_Value(std::string tok_str); // create a Vector with all entries of both keymaps -//int createOneVectorFromBothKeyboards(v_dw_3D &All_Vector,GdkKeymap *keymap); +int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLayout * keykeyboard_layout); // read configuration file, split and write to 3D-Vector (Data for US on Vector[0][ ][ ] ) -int write_US_ToVector(v_dw_3D &vec, std::string language, const char *text); +int mac_write_US_ToVector(v_dw_3D &vec); // 1. step: read complete Row of Configuration file US -bool createCompleteRow_US(v_str_1D &complete_List, FILE *fpp, const char *text, std::string language); +bool mac_createCompleteRow_US(v_str_1D &complete_List, FILE *fpp, const char *text, std::string language); // replace Name of Key (e.g. ) wih Keycode ( e.g. 15 ) -int replace_KeyName_with_Keycode(std::string in); - -// 2. step: write contents to 3D vector -int split_US_To_3D_Vector(v_dw_3D &all_US, v_str_1D completeList); +int mac_replace_KeyName_with_Keycode(std::string in); // create an empty 2D vector containing 0 in all fields -v_dw_2D create_empty_2D_Vector(int dim_rows, int dim_shifts); +v_dw_2D mac_create_empty_2D_Vector(int dim_rows, int dim_shifts); // append characters to 3D-Vector using GDK (Data for underlying Language on Vector[1][ ][ ] ) -//int append_underlying_ToVector(v_dw_3D &All_Vector, GdkKeymap *keymap); +int mac_append_underlying_ToVector(v_dw_3D &All_Vector, const UCKeyboardLayout * keykeyboard_layout); -// initialize GDK +// initialize UCHR //bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]); - +bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout); //------------------------------ const UINT USVirtualKeyToScanCode[256] = { @@ -524,34 +520,445 @@ const UINT ScanCodeToUSVirtualKey[128] = { 0x00 // 0x7f => No match }; -bool IsKeymanUsedChar(int KV); +// _S2 many keys still need to be defined !! +const UINT mac_ScanCodeToUSVirtualKey[128] = { + 0x41 ,// L"K_A", // &H41 + 0x53 ,// L"K_S", // &H53 + 0x44 ,// L"K_D", // &H44 + 0x46 ,// L"K_F", // &H46 + 0x48 ,// L"K_H", // &H48 + 0x47 ,// L"K_G", // &H47 + 0x5A ,// L"K_Z", // &H5A + 0x58 ,// L"K_X", // &H58 + 0x43 ,// L"K_C", // &H43 + 0x56 ,// L"K_V", // &H56 + 0x00, + 0x42 ,// L"K_B", // &H42 + 0x51 ,// L"K_Q", // &H51 + 0x57 ,// L"K_W", // &H57 + 0x45 ,// L"K_E", // &H45 + 0x52 ,// L"K_R", // &H52 + 0x59 ,// L"K_Y", // &H59 + 0x54 ,// L"K_T", // &H54 + 0x31 ,// L"K_1", // &H31 + 0x32 ,// L"K_2", // &H32 + 0x33 ,// L"K_3", // &H33 + 0x34 ,// L"K_4", // &H34 + 0x36 ,// L"K_6", // &H36 + 0x35 ,// L"K_5", // &H35 + 187 ,// L"K_?00", // &HB8 + 0x39 ,// L"K_9", // &H39 + 0x37 ,// L"K_7", // &H37 + 189 ,// L"K_?00", // &HBA + 0x38 ,// L"K_8", // &H38 + 0x30 ,// L"K_0", // &H30 + 221 ,// 0 // &HD9 + 0x4F ,// L"K_O", // &H4F + + 0x55 ,// L"K_U", // &H55 + 219 ,// 0 // &HD7 + 0x49 ,// L"K_I", // &H49 + 0x50 ,// L"K_P", // &H50 + 0x00, + 0x4C ,// L"K_L", // &H4C + 0x4A ,// L"K_J", // &H4A + 222, //222 ,// 0 // &HDA + 0x4B ,// L"K_K", // &H4B + 186 ,// L"K_?00", // &HB7 + 220 ,// 0 // &HD8 + 188 ,// L"K_?00", // &HB9 + 191 ,// L"K_?00", // &HBC + 0x4E ,// L"K_N", // &H4E + 0x4D ,// L"K_M", // &H4D + 190 ,// L"K_?00", // L", + 0 ,// L"K_?00", // &H0 // 0x77 => No match + 32 ,// L"K_?00", // &H1 + 2 ,// L"K_?00", // &H2 + 3 ,// L"K_?00", // &H3 + 4 ,// L"K_?00", // &H4 + 5 ,// L"K_?00", // &H5 + 6 ,// L"K_?00", // &H6 + 7 ,// L"K_?00", // &H7 + 8 ,// L"K_?00", // &H8 + 9 ,// L"K_?00", // &H9 + 10 ,// L"K_?00", // &HA + 11 ,// L"K_?00", // &HB + 12 ,// L"K_?00", // &HC + 13 ,// L"K_?00", // &HD + 14 ,// L"K_?00", // &HE + 15 ,// L"K_?00", // &HF + 16 ,// L"K_?00", // &H10 + 17 ,// L"K_?00", // L", + 18 ,// L"K_?00", // &H12 + 19 ,// L"K_?00", // &H13 + 20 ,// L"K_?00", // &H14 + 21 ,// L"K_?00", // &H15 + 22 ,// L"K_?00", // &H16 + 23 ,// L"K_?00", // &H17 + 24 ,// L"K_?00", // &H18 + 25 ,// L"K_?00", // &H19 + 26 ,// L"K_?00", // &H1A + 27 ,// L"K_?00", // &H1B + 28 ,// L"K_?00", // &H1C + 29 ,// L"K_?00", // &H1D + 30 ,// L"K_?00", // &H1E + 31 ,// L"K_?00", // &H1F + 32 ,// L"K_?00", // &H20 + 33 ,// L"K_?00", // &H21 + 34 ,// L"K_?00", // &H22 + 35 ,// L"K_?00", // &H23 + 36 ,// L"K_?00", // &H24 + 37 ,// L"K_?00", // &H25 + 38 ,// L"K_?00", // &H26 + 39 ,// L"K_?00", // &H27 + 40 ,// L"K_?00", // &H28 + 41 ,// L"K_?00", // &H29 + 42 ,// L"K_?00", // &H2A + 43 ,// L"K_?00", // &H2B + 44 ,// L"K_?00", // &H2C + 45 ,// L"K_?00", // &H2D + 46 ,// L"K_?00", // &H2E + 47 ,// L"K_?00", // &H2F + 58 ,// L"K_?00", // &H3A + 59 ,// L"K_?00", // &H3B + 60 ,// L"K_?00", // &H3C + 61 ,// L"K_?00", // &H3D + 62 ,// L"K_?00", // &H3E + 63 ,// L"K_?00", // &H3F + 64 ,// L"K_?00", // &H40 + 91 ,// L"K_?00", // &H5B + 92 ,// L"K_?00", // &H5C + 93 ,// L"K_?00", // &H5D + 94 ,// L"K_?00", // &H5E + 95 ,// L"K_?00", // &H5F + 96 ,// L"K_?00", // &H60 + 97 ,// L"K_?00", // &H61 + 98 ,// L"K_?00", // &H62 + 99 ,// L"K_?00", // &H63 + 100 ,// L"K_?00", // &H64 + 101 ,// L"K_?00", // &H65 + 102 ,// L"K_?00", // &H66 + 103 ,// L"K_?00", // &H67 + 104 ,// L"K_?00", // &H68 + 105 ,// L"K_?00", // &H69 + 106 ,// L"K_?00", // &H6A + 107 ,// L"K_?00", // &H6B + 108 ,// L"K_?00", // &H6C + 109 ,// L"K_?00", // &H6D + 110 ,// L"K_?00", // &H6E + 111 ,// L"K_?00", // &H6F + 112 ,// L"K_?00", // &H70 + 113 ,// L"K_?00", // &H71 + 114 ,// L"K_?00", // &H72 + 115 // L"K_?00", // &H73 +}; + +const UINT mac_USVirtualKeyToScanCode[256] = { + 0x999, // L"K_?00", // &H0 ................................................... 0 ........................................... + 0x999, // L"K_LBUTTON", // &H1 + 0x999, // L"K_RBUTTON", // &H2 + 0x999, // 0x46, // L"K_CANCEL", // &H3 + 0x999, // L"K_MBUTTON", // &H4 + 0x999, // L"K_?05", // &H5 + 0x999, // L"K_?06", // &H6 + 0x999, // L"K_?07", // &H7 + 0x999, // 0x0E, // L"K_BKSP", // &H8 + 0x999, // 0x0F, // L"K_TAB", // &H9 + 0x999, // L"K_?0A", // &HA + + 0x999, // L"K_?0B", // &HB................................................... 10 ........................................... + 0x999, // 0x4C, // L"K_KP5", // &HC + 0x999, // 0x1C, // L"K_ENTER", // &HD + 0x999, // L"K_?0E", // &HE + 0x999, // L"K_?0F", // &HF + 0x999, // 0x2A, // L"K_SHIFT", // &H10 + 0x999, // 0x1D, // L"K_CONTRO 0x999, // L", // &H11 + 0x999, // 0x38, // L"K_ALT", // &H12 + 0x999, // L"K_PAUSE", // &H13 + 0x999, // 0x3A, // L"K_CAPS", // &H14 + + 0x999, // L"K_KANJI?15", // &H15 + 0x999, // L"K_KANJI?16", // &H16 + 0x999, // L"K_KANJI?17", // &H17 + 0x999, // L"K_KANJI?18", // &H18 + 0x999, // L"K_KANJI?19", // &H19 + 0x999, // L"K_?1A", // &H1A + 0x999, // L"K_ESC", // &H1B + 0x999, // L"K_KANJI?1C", // &H1C + 0x999, // L"K_KANJI?1D", // &H1D + 0x999, // L"K_KANJI?1E", // &H1E + + 0x999, // L"K_KANJI?1F", // &H1F................................................... 30 ........................................... +0x31, // L"K_SPACE", // &H20 + 0x999, // 0x49, // L"K_PGUP", // &H21 + 0x999, // 0x51, // L"K_PGDN", // &H22 + 0x999, // 0x4F, // L"K_END", // &H23 + 0x999, // 0x47, // L"K_HOME", // &H24 + 0x999, // 0x4B, // L"K_LEFT", // &H25 + 0x999, // 0x48, // L"K_UP", // &H26 + 0x999, // 0x4D, // L"K_RIGHT", // &H27 + 0x999, // 0x50, // L"K_DOWN", // &H28 + + 0x999, // L"K_SEL", // &H29 + 0x999, // L"K_PRINT", // &H2A + 0x999, // L"K_EXEC", // &H2B + 0x999, // 0x54, // L"K_PRTSCN", // &H2C + 0x999, // 0x52, // L"K_INS", // &H2D + 0x999, // 0x53, // L"K_DEL", // &H2E + 0x999, // 0x63, // L"K_HELP", // &H2F +0x1D, // L"K_0", // &H30 +0x12, // L"K_1", // &H31 +0x13, // L"K_2", // &H32 + +0x14, // L"K_3", // &H33................................................... 50 ........................................... +0x15, // L"K_4", // &H34 +0x17, // L"K_5", // &H35 +0x16, // L"K_6", // &H36 +0x1A, // L"K_7", // &H37 +0x1C, // L"K_8", // &H38 +0x19, // L"K_9", // &H39 + 0x999, // L"K_?3A", // &H3A + 0x999, // L"K_?3B", // &H3B + 0x999, // L"K_?3C", // &H3C + + 0x999, // L"K_?3D", // &H3D + 0x999, // L"K_?3E", // &H3E + 0x999, // L"K_?3F", // &H3F + 0x999, // L"K_?40", // &H40 +0x00, // L"K_A", // &H41 +0x0B, // L"K_B", // &H42 +0x08, // L"K_C", // &H43 +0x02, // L"K_D", // &H44 +0x0E, // L"K_E", // &H45 +0x03, // L"K_F", // &H46 + +0x05, // L"K_G", // &H47................................................... 70 ........................................... +0x04, // L"K_H", // &H48 +0x22, // L"K_I", // &H49 +0x26, // L"K_J", // &H4A +0x28, // L"K_K", // &H4B +0x25, // L"K_L", // &H4C +0x2E, // L"K_M", // &H4D +0x2D, // L"K_N", // &H4E +0x1F, // L"K_O", // &H4F + +0x23, // L"K_P", // &H50 +0x0C, // L"K_Q", // &H51 +0x0F, // L"K_R", // &H52 +0x01, // L"K_S", // &H53 +0x11, // L"K_T", // &H54 +0x20, // L"K_U", // &H55 +0x09, // L"K_V", // &H56 +0x0D, // L"K_W", // &H57 +0x07, // L"K_X", // &H58 + +0x10, // L"K_Y", // &H59................................................... 90 ........................................... +0x06, // L"K_Z", // &H5A + + 0x999, //0x5B, // L"K_?5B", // &H5B + 0x999, //0x5C, // L"K_?5C", // &H5C + 0x999, //0x5D, // L"K_?5D", // &H5D + 0x999, //0x00, // L"K_?5E", // &H5E + 0x999, //0x5F, // L"K_?5F", // &H5F + 0x999, //0x52, // L"K_NP0", // &H60 + 0x999, //0x4F, // L"K_NP1", // &H61 + 0x999, //0x50, // L"K_NP2", // &H62 + 0x999, //0x51, // L"K_NP3", // &H63 + 0x999, //0x4B, // L"K_NP4", // &H64 + 0x999, //0x4C, // L"K_NP5", // &H65 + 0x999, //0x4D, // L"K_NP6", // &H66 + 0x999, //0x47, // L"K_NP7", // &H67 + 0x999, //0x48, // L"K_NP8", // &H68 + 0x999, //0x49, // L"K_NP9", // &H69 + 0x999, //0x37, // L"K_NPSTAR", // &H6A + 0x999, //0x4E, // L"K_NPPLUS", // &H6B + 0x999, //0x7E, // L"K_SEPARATOR", // &H6C // MCD 01-11-02: Brazilian Fix, 00 -> 7E................................................... 110 ........................................... + 0x999, //0x4A, // L"K_NPMINUS", // &H6D + 0x999, //0x53, // L"K_NPDOT", // &H6E + 0x999, //0x135, // L"K_NPSLASH", // &H6F + 0x999, //0x3B, // L"K_F1", // &H70 + 0x999, //0x3C, // L"K_F2", // &H71 + 0x999, //0x3D, // L"K_F3", // &H72 + 0x999, //0x3E, // L"K_F4", // &H73 + 0x999, //0x3F, // L"K_F5", // &H74 + 0x999, //0x40, // L"K_F6", // &H75 + 0x999, //0x41, // L"K_F7", // &H76 + 0x999, //0x42, // L"K_F8", // &H77 + 0x999, //0x43, // L"K_F9", // &H78 + 0x999, //0x44, // L"K_F10", // &H79 + 0x999, //0x57, // L"K_F11", // &H7A + 0x999, //0x58, // L"K_F12", // &H7B + 0x999, //0x64, // L"K_F13", // &H7C + 0x999, //0x65, // L"K_F14", // &H7D + 0x999, //0x66, // L"K_F15", // &H7E + 0x999, //0x67, // L"K_F16", // &H7F + 0x999, //0x68, // L"K_F17", // &H80................................................... 130 ........................................... + 0x999, //0x69, // L"K_F18", // &H81 + 0x999, //0x6A, // L"K_F19", // &H82 + 0x999, //0x6B, // L"K_F20", // &H83 + 0x999, //0x6C, // L"K_F21", // &H84 + 0x999, //0x6D, // L"K_F22", // &H85 + 0x999, //0x6E, // L"K_F23", // &H86 + 0x999, //0x76, // L"K_F24", // &H87 ----- + 0x999, //0x00, // L"K_?88", // &H88 + 0x999, //0x00, // L"K_?89", // &H89 + 0x999, //0x00, // L"K_?8A", // &H8A + 0x999, //0x00, // L"K_?8B", // &H8B + 0x999, //0x00, // L"K_?8C", // &H8C + 0x999, //0x00, // L"K_?8D", // &H8D + 0x999, //0x00, // L"K_?8E", // &H8E + 0x999, //0x00, // L"K_?8F", // &H8F ----- + 0x999, //0x45, // L"K_NUMLOCK", // &H90 + 0x999, //0x46, // L"K_SCROL 0x999, //0x00, // L", // &H91 ----- + 0x999, //0x00, // L"K_?92", // &H92 + 0x999, //0x00, // L"K_?93", // &H93 + 0x999, //0x00, // L"K_?94", // &H94................................................... 150 ........................................... + 0x999, //0x00, // L"K_?95", // &H95 + 0x999, //0x00, // L"K_?96", // &H96 + 0x999, //0x00, // L"K_?97", // &H97 + 0x999, //0x00, // L"K_?98", // &H98 + 0x999, //0x00, // L"K_?99", // &H99 + 0x999, //0x00, // L"K_?9A", // &H9A + 0x999, //0x00, // L"K_?9B", // &H9B + 0x999, //0x00, // L"K_?9C", // &H9C + 0x999, //0x00, // L"K_?9D", // &H9D + 0x999, //0x00, // L"K_?9E", // &H9E + 0x999, //0x00, // L"K_?9F", // &H9F + 0x999, //0x2A, // L"K_?A0", // &HA0 + 0x999, //0x36, // L"K_?A1", // &HA1 + 0x999, //0x1D, // L"K_?A2", // &HA2 + 0x999, //0x1D, // L"K_?A3", // &HA3 + 0x999, //0x38, // L"K_?A4", // &HA4 + 0x999, //0x38, // L"K_?A5", // &HA5 + 0x999, //0x6A, // L"K_?A6", // &HA6 + 0x999, //0x69, // L"K_?A7", // &HA7 + 0x999, //0x67, // L"K_?A8", // &HA8................................................... 170 ........................................... + 0x999, //0x68, // L"K_?A9", // &HA9 + 0x999, //0x65, // L"K_?AA", // &HAA + 0x999, //0x66, // L"K_?AB", // &HAB + 0x999, //0x32, // L"K_?AC", // &HAC + 0x999, //0x20, // L"K_?AD", // &HAD + 0x999, //0x2E, // L"K_?AE", // &HAE + 0x999, //0x30, // L"K_?AF", // &HAF + 0x999, //0x19, // L"K_?B0", // &HB0 + 0x999, //0x10, // L"K_?B1", // &HB1 + 0x999, //0x24, // L"K_?B2", // &HB2 + 0x999, //0x22, // L"K_?B3", // &HB3 + 0x999, //0x6C, // L"K_?B4", // &HB4 + 0x999, //0x6D, // L"K_?B5", // &HB5 + 0x999, //0x6B, // L"K_?B6", // &HB6 + 0x999, //0x21, // L"K_?B7", // &HB7 + 0x999, //0x00, // L"K_?B8", // &HB8 + 0x999, //0x00, // L"K_?B9", // &HB9 ----- + 0x29, // L"K_COLON", // &HBA + 0x999, // 0x0D, // L"K_EQUA0x00, // L", // &HBB + 0x2B, // L"K_COMMA", // &HBC ................................................... 190 ........................................... + 0x1B, // L"K_HYPHEN", // &HBD + 0x2F, // L"K_PERIOD", // &HBE + 0x2C, // L"K_SLASH", // &HBF + 0x999, //0x77, // L"K_BKQUOTE", // &HC0 ----- + 0x999, //0x73, // L"K_?C1", // &HC1 + 0x999, //0x7E, // L"K_?C2", // &HC2 + 0x999, //0x00, // L"K_?C3", // &HC3 + 0x999, //0x00, // L"K_?C4", // &HC4 + 0x999, //0x00, // L"K_?C5", // &HC5 + 0x999, //0x00, // L"K_?C6", // &HC6 + 0x999, //0x00, // L"K_?C7", // &HC7 + 0x999, //0x00, // L"K_?C8", // &HC8 + 0x999, //0x00, // L"K_?C9", // &HC9 + 0x999, //0x00, // L"K_?CA", // &HCA + 0x999, //0x00, // L"K_?CB", // &HCB + 0x999, //0x00, // L"K_?CC", // &HCC + 0x999, //0x00, // L"K_?CD", // &HCD + 0x999, //0x00, // L"K_?CE", // &HCE + 0x999, //0x00, // L"K_?CF", // &HCF + 0x999, //0x00, // L"K_?D0", // &HD0................................................... 210 ........................................... + 0x999, //0x00, // L"K_?D1", // &HD1 + 0x999, //0x00, // L"K_?D2", // &HD2 + 0x999, //0x00, // L"K_?D3", // &HD3 + 0x999, //0x00, // L"K_?D4", // &HD4 + 0x999, //0x00, // L"K_?D5", // &HD5 + 0x999, //0x00, // L"K_?D6", // &HD6 + 0x999, //0x00, // L"K_?D7", // &HD7 + 0x999, //0x00, // L"K_?D8", // &HD8 + 0x999, //0x00, // L"K_?D9", // &HD9 + 0x999, //0x00, // L"K_?DA", // &HDA + + 0x21, // L"K_LBRKT", // &HDB + 0x2A, // L"K_BKSLASH", // &HDC + 0x1E, // L"K_RBRKT", // &HDD + 0x27, // L"K_QUOTE", // &HDE + 0x73, // L"K_oDF", // &HDF // MCD 01-11-02: Brazilian fix: 00 -> 73 + 0x999, //0x00, // L"K_oE0", // &HE0 + 0x999, //0x00, // L"K_oE1", // &HE1 + 0x999, //0x56, // L"K_oE2", // &HE2 + 0x999, //0x00, // L"K_oE3", // &HE3 + 0x999, //0x00, // L"K_oE4", // &HE4................................................... 220 ........................................... + + 0x999, //0x00, // L"K_?E5", // &HE5 + 0x999, //0x00, // L"K_oE6", // &HE6 + 0x999, //0x00, // L"K_?E7", // &HE7 + 0x999, //0x00, // L"K_?E8", // &HE8 + 0x999, //0x71, // L"K_oE9", // &HE9 + 0x999, //0x5C, // L"K_oEA", // &HEA + 0x999, //0x7B, // L"K_oEB", // &HEB + 0x999, //0x00, // L"K_oEC", // &HEC + 0x999, //0x6F, // L"K_oED", // &HED + 0x999, //0x5A, // L"K_oEE", // &HEE + 0x999, //0x00, // L"K_oEF", // &HEF + 0x999, //0x00, // L"K_oF0", // &HF0 + 0x999, //0x5B, // L"K_oF1", // &HF1 + 0x999, //0x00, // L"K_oF2", // &HF2 + 0x999, //0x5F, // L"K_oF3", // &HF3 + 0x999, //0x00, // L"K_oF4", // &HF4 + 0x999, //0x5E, // L"K_oF5", // &HF5 + 0x999, //0x00, // L"K_?F6", // &HF6 + 0x999, //0x00, // L"K_?F7", // &HF7 + 0x999, //0x00, // L"K_?F8", // &HF8 + 0x999, //0x5D, // L"K_?F9", // &HF9 + 0x999, //0x00, // L"K_?FA", // &HFA + 0x999, //0x62, // L"K_?FB", // &HFB + 0x999, //0x00, // L"K_?FC", // &HFC + 0x999, //0x00, // L"K_?FD", // &HFD + 0x999, //0x00, // L"K_?FE", // &HFE + 0x999, //0x00 // L"K_?FF" // &HFF +}; + + +bool mac_IsKeymanUsedChar(int KV); //------------------------------ + +std::vector mac_createVectorOfKeyboard( int shiftstate, const UCKeyboardLayout * keyboard_layout); // take deadkey-value (e.g.65106) and return u16string (e.g. '^' ) -std::u16string convert_DeadkeyValues_To_U16str(int in); +std::u16string mac_convert_DeadkeyValues_To_U16str(int in); // use gdk_keymap_translate_keyboard_state to get keyval - base function to get keyvals -//int KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps); +int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int ss, int caps); -// use KMX_get_KeyVal_From_KeyCode and prevent use of certain keycodes -//KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, guint keycode, int shift_state_pos); +// use mac_KMX_get_KeyVal_From_KeyCode and prevent use of certain keycodes +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int keycode, int shift_state_pos); // fill Deadkey with dk and return CATEGORY -//KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey); +//KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey); +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey); // use Vector to return the Keyval of underlying Keyboard -KMX_WCHAR KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D &All_Vector,KMX_DWORD VK_underlying); +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D &All_Vector,KMX_DWORD VK_underlying); // use Vector to return the Keycode of the underlying Keyboard for given VK_US using GDK -//KMX_DWORD KMX_get_KeyCodeUnderlying_From_KeyCodeUS(GdkKeymap *keymap, v_dw_3D &All_Vector,KMX_DWORD KC_US, ShiftState ss, int caps); +//KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(GdkKeymap *keymap, v_dw_3D &All_Vector,KMX_DWORD KC_US, ShiftState ss, int caps); // return the Keycode of the underlying Keyboard for given VK_US -UINT KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS); +UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS); // return the VirtualKey of the US Keyboard for a given Keyode using GDK -KMX_DWORD KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); +KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); // convert codePoint to u16string -std::u16string CodePointToU16String(unsigned int codepoint); +std::u16string mac_CodePointToU16String(unsigned int codepoint); + + +void printoutKeyboards(v_dw_3D &All_Vector); @@ -559,6 +966,5 @@ std::u16string CodePointToU16String(unsigned int codepoint); //################################################################################################################################################ //################################################################################################################################################ -void fun3(); #endif // KEYMAP_H \ No newline at end of file diff --git a/mac/mcompile/kmx_file.h b/mac/mcompile/kmx_file.h index 9791d76919b..74c573650eb 100755 --- a/mac/mcompile/kmx_file.h +++ b/mac/mcompile/kmx_file.h @@ -3,10 +3,6 @@ #ifndef KMX_FILE_H #define KMX_FILE_H -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - /* Copyright: Copyright (C) 2003-2018 SIL International. Authors: mcdurdin @@ -392,3 +388,7 @@ static_assert(sizeof(KMX_COMP_KEYBOARD) == KEYBOARDFILEHEADER_SIZE, "COMP_KEYBOA } // namespace km #endif #endif //KMX_FILE_H + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index d7bfc8f393c..9bc76837e54 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -63,13 +63,13 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { return false; } -/*//################################################################################################################################################ +//################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ -int KMX_ToUnicodeEx(guint keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps,GdkKeymap *keymap) { +/*int KMX_ToUnicodeEx(guint keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps,GdkKeymap *keymap) { GdkKeymapKey *maps; guint *keyvals; gint count; @@ -83,8 +83,8 @@ int KMX_ToUnicodeEx(guint keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int if (!(keycode <= keycode_max)) return 0; - KMX_DWORD KeyVal= (KMX_DWORD) KMX_get_KeyVal_From_KeyCode(keymap, keycode, ShiftState(shift_state_pos), caps); - std::u16string str = convert_DeadkeyValues_To_U16str(KeyVal); + KMX_DWORD KeyVal= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode(keymap, keycode, ShiftState(shift_state_pos), caps); + std::u16string str = mac_convert_DeadkeyValues_To_U16str(KeyVal); pwszBuff[0]= * (PKMX_WCHAR) str.c_str(); @@ -124,7 +124,7 @@ int KMX_ToUnicodeEx(guint keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int public: KMX_VirtualKey(UINT scanCode) { - this->m_vk = KMX_get_VKUS_From_KeyCodeUnderlying(scanCode); + this->m_vk = mac_KMX_get_VKUS_From_KeyCodeUnderlying(scanCode); this->m_sc = scanCode; memset(this->m_rgfDeadKey,0,sizeof(this->m_rgfDeadKey)); } @@ -308,8 +308,8 @@ int KMX_ToUnicodeEx(guint keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int // key->Key stores VK-US ( not underlying !!) // key->dpOutput stores character Underlying - KMX_DWORD SC_Underlying = KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keymap, All_Vector, this->SC(), (ShiftState) ss, caps); - key->Key = KMX_get_VKUS_From_KeyCodeUnderlying( SC_Underlying); + KMX_DWORD SC_Underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keymap, All_Vector, this->SC(), (ShiftState) ss, caps); + key->Key = mac_KMX_get_VKUS_From_KeyCodeUnderlying( SC_Underlying); key->Line = 0; key->ShiftFlags = this->KMX_GetShiftStateValue(capslock, caps, (ShiftState) ss); @@ -376,7 +376,7 @@ int KMX_ToUnicodeEx(guint keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int std::vector rgKey; //= new VirtualKey[256]; std::vector alDead; - std::vector alDead_cpl = create_alDead(); + std::vector alDead_cpl = mac_create_alDead(); rgKey.resize(256); @@ -422,7 +422,7 @@ int KMX_ToUnicodeEx(guint keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int // continue; // } - KMX_DWORD KC_US = (KMX_DWORD) KMX_get_KeyCodeUnderlying_From_VKUS(iKey); + KMX_DWORD KC_US = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); for(int caps = 0; caps <= 1; caps++) { int rc = KMX_ToUnicodeEx(KC_US, sbBuffer, ss, caps, *keymap); @@ -443,7 +443,7 @@ int KMX_ToUnicodeEx(guint keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int sbBuffer[2] = 0; rgKey[iKey]->KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on Linux is different - refine_alDead(sbBuffer[0], alDead, &alDead_cpl); + mac_refine_alDead(sbBuffer[0], alDead, &alDead_cpl); } } } @@ -631,7 +631,7 @@ int KMX_ToUnicodeEx(guint keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int return true; }*/ -/*const int CODE__SIZE[] = { +const int CODE__SIZE[] = { -1, // undefined 0x00 1, // CODE_ANY 0x01 2, // CODE_INDEX 0x02 @@ -658,4 +658,3 @@ return true; 3, // CODE_IFSYSTEMSTORE 0x17 2 // CODE_SETSYSTEMSTORE 0x18 }; -*/ \ No newline at end of file diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h index da38fa65e38..e8ff532991a 100755 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -6,8 +6,6 @@ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ - - class DeadKey { private: KMX_WCHAR m_deadchar; diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index 6fa81d66370..0c2d2cb70da 100755 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -7,11 +7,6 @@ #define CERR_UnableToWriteFully 0x00008007 #define CERR_SomewhereIGotItWrong 0x00008009 -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - - KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz); LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize); @@ -23,7 +18,7 @@ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename) { if(fp == NULL) { - KMX_LogError(L"Failed to create output file (%d)", errno); + mac_KMX_LogError(L"Failed to create output file (%d)", errno); return FALSE; } @@ -31,7 +26,7 @@ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename) { fclose(fp); if(err != CERR_None) { - KMX_LogError(L"Failed to write compiled keyboard with error %d", err); + mac_KMX_LogError(L"Failed to write compiled keyboard with error %d", err); std::u16string u16_filname(filename); std::string s = string_from_u16string(u16_filname); @@ -227,7 +222,6 @@ PKMX_WCHAR KMX_StringOffset(PKMX_BYTE base, KMX_DWORD offset) { return (PKMX_WCHAR)(base + offset); } - #ifdef KMX_64BIT /** CopyKeyboard will copy the data read into bufp from x86-sized structures into @@ -317,7 +311,7 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { beginning of the file, but we need real pointers. This method is used on 32-bit architectures. */ -/* LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize) { +LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize) { UNREFERENCED_PARAMETER(dwFileSize); @@ -352,7 +346,7 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { } return kbp; -}*/ +} #endif @@ -364,20 +358,20 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { PKMX_BYTE filebase; if(!fileName || !lpKeyboard) { - KMX_LogError(L"Bad Filename\n" ); + mac_KMX_LogError(L"Bad Filename\n" ); return FALSE; } fp = Open_File((const KMX_WCHAR*)fileName, u"rb"); if(fp == NULL) { - KMX_LogError(L"Could not open file\n" ); + mac_KMX_LogError(L"Could not open file\n" ); return FALSE; } if (fseek(fp, 0, SEEK_END) != 0) { fclose(fp); - KMX_LogError(L"Could not fseek file\n" ); + mac_KMX_LogError(L"Could not fseek file\n" ); return FALSE; } @@ -389,7 +383,7 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { if (fseek(fp, 0, SEEK_SET) != 0) { fclose(fp); - KMX_LogError(L"Could not fseek(set) file\n" ); + mac_KMX_LogError(L"Could not fseek(set) file\n" ); return FALSE; } @@ -407,7 +401,7 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { if (!buf) { fclose(fp); - KMX_LogError(L"Not allocmem\n" ); + mac_KMX_LogError(L"Not allocmem\n" ); return FALSE; } @@ -418,7 +412,7 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { #endif if (fread(filebase, 1, sz, fp) < (size_t)sz) { - KMX_LogError(L"Could not read file\n" ); + mac_KMX_LogError(L"Could not read file\n" ); fclose(fp); return FALSE; } @@ -428,12 +422,12 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { if(*PKMX_DWORD(filebase) != KMX_DWORD(FILEID_COMPILED)) { delete [] buf; - KMX_LogError(L"Invalid file - signature is invalid\n"); + mac_KMX_LogError(L"Invalid file - signature is invalid\n"); return FALSE; } if (!KMX_VerifyKeyboard(filebase, sz)) { - KMX_LogError(L"errVerifyKeyboard\n" ); + mac_KMX_LogError(L"errVerifyKeyboard\n" ); return FALSE; } @@ -445,13 +439,13 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { if (!kbp) { - KMX_LogError(L"errFixupKeyboard\n" ); + mac_KMX_LogError(L"errFixupKeyboard\n" ); return FALSE; } if (kbp->dwIdentifier != FILEID_COMPILED) { delete[] buf; - KMX_LogError(L"errNotFileID\n" ); + mac_KMX_LogError(L"errNotFileID\n" ); return FALSE; } *lpKeyboard = kbp; @@ -459,7 +453,7 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { } KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz){ -/* + KMX_DWORD i; PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)filebase; PKMX_COMP_STORE csp; @@ -471,20 +465,20 @@ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz){ for (csp = (PKMX_COMP_STORE)(filebase + ckbp->dpStoreArray), i = 0; i < ckbp->cxStoreArray; i++, csp++) { if (csp->dwSystemID == TSS_COMPILEDVERSION) { if (csp->dpString == 0) { - KMX_LogError(L"errWrongFileVersion:NULL"); + mac_KMX_LogError(L"errWrongFileVersion:NULL"); } else { - KMX_LogError(L"errWrongFileVersion:%10.10ls",(const PKMX_WCHAR) KMX_StringOffset((PKMX_BYTE)filebase, csp->dpString)); + mac_KMX_LogError(L"errWrongFileVersion:%10.10ls",(const PKMX_WCHAR) KMX_StringOffset((PKMX_BYTE)filebase, csp->dpString)); } return FALSE; } } - KMX_LogError(L"errWrongFileVersion"); + mac_KMX_LogError(L"errWrongFileVersion"); return FALSE; - }*/ + } return TRUE; } -/* PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) { +PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) { if (*p == 0) return p; @@ -518,4 +512,7 @@ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz){ return p; } -*/ \ No newline at end of file +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index c4c270cf292..01ccfe2a275 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -36,8 +36,8 @@ -KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc, char *argv[]); -/*KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, gint argc, gchar *argv[]); +KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc, char *argv[]); +/*KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, gint argc, gchar *argv[]); bool KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, GdkKeymap **keymap,std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 */ @@ -54,12 +54,12 @@ std::vector KMX_FDeadkeys; // I4353 #if defined(_WIN32) || defined(_WIN64) int wmain(int argc, wchar_t* argv[]) { std::vector str_argv_16 = convert_argvW_to_Vector_u16str( argc, argv); - run(argc, str_argv_16); + mac_run(argc, str_argv_16); #elif ((__linux__) || (__unix__ )) // LINUX, UNIX int main(int argc, char* argv[]) { std::vector str_argv_16 = convert_argv_to_Vector_u16str(argc, argv); - run(argc, str_argv_16, argv); + mac_run(argc, str_argv_16, argv); #elif (__APPLE__ && TARGET_OS_MAC) #include @@ -67,21 +67,14 @@ std::vector KMX_FDeadkeys; // I4353 int main(int argc, char* argv[]) { std::vector str_argv_16 = convert_argv_to_Vector_u16str(argc, argv); - // _S2 Sabines Stuff needs to go - std::cout << "Hier ist main von mcompile-mac.cpp...\n"; - testmyFunctions_S2(); - std::wstring const wtr = L"abc"; - std::string str= string_from_wstring(wtr); - // _S2 Sabines Stuff needs to go - run(argc, str_argv_16, argv); - printf("\n.................................. END ..............................\n"); + mac_run(argc, str_argv_16, argv); + printf("\n................................ END ..............................\n"); #endif - } -int run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ +int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ std::vector argv; for (int i = 0; i < argc; i++) { @@ -92,9 +85,9 @@ int run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ if(argc < 3 || (argc > 4)) { // I4273// I4273 wprintf( L"Usage: mcompile [-d] infile.kmx outfile.kmx\n" - L" mmcompile -u ... (not available for Linux)\n " + L" mmcompile -u ... (not available for mac)\n " L" mcompile converts a Keyman mnemonic layout to a\n" - L" positional one based on the Linux keyboard\n" + L" positional one based on the mac keyboard\n" L" layout on top position\n" L" (-d convert deadkeys to plain keys) not available yet \n\n" ); // I4552 @@ -103,7 +96,6 @@ int run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ } // -u option is not available for Linux and macOS - int bDeadkeyConversion = u16cmp(argv[1], u"-d") == 0; // I4552 int n = (bDeadkeyConversion ? 2 : 1); @@ -140,7 +132,7 @@ int run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ LPKMX_KEYBOARD kmxfile; if(!KMX_LoadKeyboard(infile, &kmxfile)) { - KMX_LogError(L"Failed to load keyboard (%d)\n", errno ); + mac_KMX_LogError(L"Failed to load keyboard (%d)\n", errno ); return 3; } @@ -151,12 +143,12 @@ int run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ } #elif ((__linux__) || (__unix__ )) // LINUX, UNIX - if(KMX_DoConvert( kmxfile, bDeadkeyConversion, argc, (gchar**) argv_ch)) { // I4552F + if(mac_KMX_DoConvert( kmxfile, bDeadkeyConversion, argc, (gchar**) argv_ch)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); } - +/* _S2 WORK FROM HERE */ #elif (__APPLE__ && TARGET_OS_MAC ) //macOS - if(KMX_DoConvert( kmxfile, bDeadkeyConversion, argc, (char**) argv_ch)) { // I4552F + if(mac_KMX_DoConvert( kmxfile, bDeadkeyConversion, argc, (char**) argv_ch)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); } #endif @@ -166,8 +158,10 @@ int run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ return 0; } +// _S2 is this correct?? which SS ??? // Map of all shift states that we will work with const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCTRLFLAG|RALTFLAG, 0xFFFF}; +//const UINT VKShiftState[] = {0, 2, 4,6, 0xFFFF}; // @@ -176,7 +170,7 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCT // For each key rule on the keyboard, remap its key to the // correct shift state and key. Adjust the LCTRL+RALT -> RALT if necessary // -/* void KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { +/* void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. @@ -201,44 +195,44 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCT } }*/ -/* void KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { +/* void mac_KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { for(unsigned int i = 0; i < group->cxKeyArray; i++) { - KMX_TranslateKey(&group->dpKeyArray[i], vk, shift, ch); + mac_KMX_TranslateKey(&group->dpKeyArray[i], vk, shift, ch); } }*/ -/* void KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { +/* void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { if(kbd->dpGroupArray[i].fUsingKeys) { - KMX_TranslateGroup(&kbd->dpGroupArray[i], vk, shift, ch); + mac_KMX_TranslateGroup(&kbd->dpGroupArray[i], vk, shift, ch); } } } */ -/* void KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { +/* void mac_KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { if(key->ShiftFlags == 0) { - KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); + mac_KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); } else if(key->ShiftFlags & VIRTUALCHARKEY) { - KMX_LogError(L"Did not find a match for mnemonic virtual character key rule on line %d, + [%x '%c'] > ...", key->Line, key->ShiftFlags, key->Key); + mac_KMX_LogError(L"Did not find a match for mnemonic virtual character key rule on line %d, + [%x '%c'] > ...", key->Line, key->ShiftFlags, key->Key); } -} +}*/ -void KMX_ReportUnconvertedGroupRules(LPKMX_GROUP group) { +/*void mac_KMX_ReportUnconvertedGroupRules(LPKMX_GROUP group) { for(unsigned int i = 0; i < group->cxKeyArray; i++) { - KMX_ReportUnconvertedKeyRule(&group->dpKeyArray[i]); + mac_KMX_ReportUnconvertedKeyRule(&group->dpKeyArray[i]); } -} +}*/ -void KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { +/*void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { if(kbd->dpGroupArray[i].fUsingKeys) { - KMX_ReportUnconvertedGroupRules(&kbd->dpGroupArray[i]); + mac_KMX_ReportUnconvertedGroupRules(&kbd->dpGroupArray[i]); } } -} +}*/ -void KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { +/*void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { // _S2 TOP_2 INFO this produces a different output due to different layouts for Lin<-> win ( for the same language!!) if((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) { @@ -249,10 +243,10 @@ void KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift &= ~LCTRLFLAG; if(key->ShiftFlags == 0) { - //KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO dk(%d) + [%x K_%d]", key->Line, key->Key, deadkey, shift, vk); + //mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO dk(%d) + [%x K_%d]", key->Line, key->Key, deadkey, shift, vk); key->ShiftFlags = ISVIRTUALKEY | shift; } else { - //KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO dk(%d) + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, deadkey, key->ShiftFlags & ~VIRTUALCHARKEY, vk); + //mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO dk(%d) + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, deadkey, key->ShiftFlags & ~VIRTUALCHARKEY, vk); key->ShiftFlags &= ~VIRTUALCHARKEY; } @@ -267,23 +261,23 @@ void KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT key->dpContext = context; key->Key = vk; } -} +}*/ -void KMX_TranslateDeadkeyGroup(LPKMX_GROUP group,KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { +/*void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group,KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { for(unsigned int i = 0; i < group->cxKeyArray; i++) { - KMX_TranslateDeadkeyKey(&group->dpKeyArray[i], deadkey, vk, shift, ch); + mac_KMX_TranslateDeadkeyKey(&group->dpKeyArray[i], deadkey, vk, shift, ch); } -} +}*/ -void KMX_TranslateDeadkeyKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { +/*void mac_KMX_TranslateDeadkeyKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { if(kbd->dpGroupArray[i].fUsingKeys) { - KMX_TranslateDeadkeyGroup(&kbd->dpGroupArray[i], deadkey, vk, shift, ch); + mac_KMX_TranslateDeadkeyGroup(&kbd->dpGroupArray[i], deadkey, vk, shift, ch); } } -} +}*/ -void KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift) { +/*void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. @@ -307,13 +301,13 @@ void KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT keys[0].ShiftFlags = shift | ISVIRTUALKEY; kbd->dpGroupArray[i].dpKeyArray = keys; kbd->dpGroupArray[i].cxKeyArray++; - KMX_LogError(L"Add deadkey rule: + [%d K_%d] > dk(%d)", shift, vk, deadkey); + mac_KMX_LogError(L"Add deadkey rule: + [%d K_%d] > dk(%d)", shift, vk, deadkey); if(i == kbd->StartGroup[1]) break; // If this is the initial group, that's all we need to do. } } -} +}*/ -KMX_WCHAR KMX_ScanXStringForMaxDeadkeyID(PKMX_WCHAR str) { +KMX_WCHAR mac_KMX_ScanXStringForMaxDeadkeyID(PKMX_WCHAR str) { KMX_WCHAR dkid = 0; while(str && *str) { if(*str == UC_SENTINEL) { @@ -331,7 +325,7 @@ struct KMX_dkidmap { KMX_WCHAR src_deadkey, dst_deadkey; }; -KMX_WCHAR KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { +/*KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { LPKMX_GROUP gp; LPKMX_KEY kp; LPKMX_STORE sp; @@ -365,73 +359,71 @@ KMX_WCHAR KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { for(i = 0, gp = kbd->dpGroupArray; i < kbd->cxGroupArray; i++, gp++) { for(j = 0, kp = gp->dpKeyArray; j < gp->cxKeyArray; j++, kp++) { - dkid = max(dkid, KMX_ScanXStringForMaxDeadkeyID(kp->dpContext)); - dkid = max(dkid, KMX_ScanXStringForMaxDeadkeyID(kp->dpOutput)); + dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(kp->dpContext)); + dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(kp->dpOutput)); } - dkid = max(dkid, KMX_ScanXStringForMaxDeadkeyID(gp->dpMatch)); - dkid = max(dkid, KMX_ScanXStringForMaxDeadkeyID(gp->dpNoMatch)); + dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(gp->dpMatch)); + dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(gp->dpNoMatch)); } for(i = 0, sp = kbd->dpStoreArray; i < kbd->cxStoreArray; i++, sp++) { - dkid = max(dkid, KMX_ScanXStringForMaxDeadkeyID(sp->dpString)); + dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(sp->dpString)); } s_dkids = (KMX_dkidmap*) realloc(s_dkids, sizeof(KMX_dkidmap) * (s_ndkids+1)); s_dkids[s_ndkids].src_deadkey = deadkey; return s_dkids[s_ndkids++].dst_deadkey = s_next_dkid = ++dkid; -} +}*/ -void KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, v_dw_3D &All_Vector, GdkKeymap* keymap,v_dw_2D dk_Table) { +/*void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, v_dw_3D &All_Vector, GdkKeymap* keymap,v_dw_2D dk_Table) { KMX_WORD deadkeys[512], *pdk; // Lookup the deadkey table for the deadkey in the physical keyboard // Then for each character, go through and map it through - KMX_WCHAR dkid = KMX_GetUniqueDeadkeyID(kbd, deadkey); + KMX_WCHAR dkid = mac_KMX_GetUniqueDeadkeyID(kbd, deadkey); // Add the deadkey to the mapping table for use in the import rules phase KMX_DeadkeyMapping KMX_deadkeyMapping = { deadkey, dkid, shift, vk_US}; // I4353 KMX_FDeadkeys.push_back(KMX_deadkeyMapping); //dkid, vk, shift); // I4353 - KMX_AddDeadkeyRule(kbd, dkid, vk_US, shift); + mac_KMX_AddDeadkeyRule(kbd, dkid, vk_US, shift); - KMX_GetDeadkeys(dk_Table, deadkey, pdk = deadkeys, keymap); // returns array of [usvk, ch_out] pairs + mac_KMX_GetDeadkeys(dk_Table, deadkey, pdk = deadkeys, keymap); // returns array of [usvk, ch_out] pairs while(*pdk) { // Look up the ch - UINT KeyValUnderlying = KMX_get_KeyValUnderlying_From_KeyValUS(All_Vector, *pdk); - KMX_TranslateDeadkeyKeyboard(kbd, dkid, KeyValUnderlying, *(pdk+1), *(pdk+2)); + UINT KeyValUnderlying = mac_KMX_get_KeyValUnderlying_From_KeyValUS(All_Vector, *pdk); + mac_KMX_TranslateDeadkeyKeyboard(kbd, dkid, KeyValUnderlying, *(pdk+1), *(pdk+2)); pdk+=3; } -} +}*/ -KMX_BOOL KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { +KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { LPKMX_STORE sp; UINT i; for(i = 0, sp = kbd->dpStoreArray; i < kbd->cxStoreArray; i++, sp++) { if(sp->dwSystemID == TSS_MNEMONIC) { if(!sp->dpString) { - KMX_LogError(L"Invalid &mnemoniclayout system store"); + mac_KMX_LogError(L"Invalid &mnemoniclayout system store"); return FALSE; } if(u16cmp((const KMX_WCHAR*)sp->dpString, u"1") != 0) { - KMX_LogError(L"Keyboard is not a mnemonic layout keyboard"); + mac_KMX_LogError(L"Keyboard is not a mnemonic layout keyboard"); return FALSE; } *sp->dpString = '0'; return TRUE; } } - KMX_LogError(L"Keyboard is not a mnemonic layout keyboard"); + mac_KMX_LogError(L"Keyboard is not a mnemonic layout keyboard"); return FALSE; } -*/ -KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc, char *argv[]) { -/*KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, gint argc, gchar *argv[]) { +KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc, char *argv[]) { KMX_WCHAR DeadKey=0; - if(!KMX_SetKeyboardToPositional(kbd)) return FALSE; + if(!mac_KMX_SetKeyboardToPositional(kbd)) return FALSE; // Go through each of the shift states - base, shift, ctrl+alt, ctrl+alt+shift, [caps vs ncaps?] // Currently, we go in this order so the 102nd key works. But this is not ideal for keyboards without 102nd key: // I4651 @@ -439,71 +431,80 @@ KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc // evident for the 102nd key on UK, for example, where \ can be generated with VK_OEM_102 or AltGr+VK_QUOTE. // For now, we get the least shifted version, which is hopefully adequate. - GdkKeymap *keymap; - if(InitializeGDK(&keymap , argc, argv)) { + const UCKeyboardLayout* keyboard_layout; + if(mac_InitializeUCHR(&keyboard_layout)) { wprintf(L"ERROR: can't Initialize GDK\n"); return FALSE; } - - // create vector that contains Keycode, base, shift for US-KEyboard and underlying keyboard + // _S2 deadkeys do not work yet - some result in 24(x18) + // create vector that contains Keycode, base, shift for US-Keyboard and underlying keyboard v_dw_3D All_Vector; - if(createOneVectorFromBothKeyboards(All_Vector, keymap)){ + if(mac_createOneVectorFromBothKeyboards(All_Vector, keyboard_layout)){ wprintf(L"ERROR: can't create one vector from both keyboards\n"); return FALSE; } + // _S2 printoutKeyboards(All_Vector); + v_dw_2D dk_Table; - create_DKTable(dk_Table); + mac_create_DKTable(dk_Table); + // _S2 which shiftstates?? for (int j = 0; VKShiftState[j] != 0xFFFF; j++) { // I4651 // Loop through each possible key on the keyboard for (int i = 0;KMX_VKMap[i]; i++) { // I4651 - // windows uses VK, Linux uses SC/Keycode - UINT scUnderlying = KMX_get_KeyCodeUnderlying_From_VKUS(KMX_VKMap[i]); - KMX_WCHAR ch = KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keymap, VKShiftState[j], scUnderlying, &DeadKey); + // windows uses VK, Linux, mac use SC/Keycode + UINT scUnderlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_VKMap[i]); + + KMX_WCHAR ch = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, VKShiftState[j], scUnderlying, &DeadKey); - //wprintf(L"--- VK_%d -> SC_ [%c] dk=%d ( ss %i) \n", VKMap[i], ch == 0 ? 32 : ch, DeadKey, VKShiftState[j]); + wprintf(L"--- VK_%d -> SC_ [%c] dk=%d ( ss %i) \n", KMX_VKMap[i], ch == 0 ? 32 : ch, DeadKey, VKShiftState[j]); if(bDeadkeyConversion) { // I4552 if(ch == 0xFFFF) { ch = DeadKey; } } - +int STOP =0;/* switch(ch) { case 0x0000: break; - case 0xFFFF: KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keymap , dk_Table); break; - default: KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); - } + case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keymap , dk_Table); break; + default: mac_KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); + }*/ } } - KMX_ReportUnconvertedKeyboardRules(kbd); +// #################### _S2 work here ########################################### + +/* + mac_KMX_ReportUnconvertedKeyboardRules(kbd); if(!KMX_ImportRules(kbd, All_Vector, &keymap, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 return FALSE; }*/ + return TRUE; + } -/* int KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap) { +/* int mac_KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap) { KMX_WORD *p = OutputPairs; KMX_DWORD shift; v_dw_2D dk_SingleTable; - query_dk_combinations_for_specific_dk(&dk_Table, dk_SingleTable, DeadKey); + mac_query_dk_combinations_for_specific_dk(&dk_Table, dk_SingleTable, DeadKey); for ( int i=0; i< (int) dk_SingleTable.size();i++) { - KMX_WORD vk = KMX_changeKeynameToCapital(dk_SingleTable[i][1], shift, keymap); + KMX_WORD vk = mac_KMX_changeKeynameToCapital(dk_SingleTable[i][1], shift, keymap); if(vk != 0) { *p++ = vk; *p++ = shift; *p++ = dk_SingleTable[i][2]; } else { - KMX_LogError(L"Warning: complex deadkey not supported."); + mac_KMX_LogError(L"Warning: complex deadkey not supported."); } } *p = 0; @@ -511,7 +512,7 @@ KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc } */ -void KMX_LogError(const wchar_t* fmt, ...) { +void mac_KMX_LogError(const wchar_t* fmt, ...) { WCHAR fmtbuf[256]; const wchar_t* end = L"\0"; const wchar_t* nl = L"\n"; @@ -541,16 +542,16 @@ void KMX_LogError(const wchar_t* fmt, ...) { //-------------------------- -void fun2() { std::cout << "Hier ist fun2 von mcompile.cpp ...\n";} +/*void fun2() { std::cout << "Hier ist fun2 von mcompile.cpp ...\n";} void testmyFunctions_S2() { std::u16string character; KMX_DWORD val; for (int i=0; i<8; i++) { - character = get_character_From_Keycode(24,14,i ); // all Shiftstates for ´` + e - val = get_keyval_From_Keycode(24,14,i ); // all Shiftstates for ´` + e + character = mac_get_character_From_Keycode(24,14,i ); // all Shiftstates for ´` + e + val = mac_get_keyval_From_Keycode(24,14,i ); // all Shiftstates for ´` + e wprintf( L" ` + e for SHIFTSTATE %i -> %i \n", i, val); } -} +}*/ diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index ba347cc5e7b..46a6879db72 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -41,13 +41,13 @@ struct KMX_DeadkeyMapping { // I4353 extern std::vector KMX_FDeadkeys; // I4353 -int run(int argc, std::vector str_argv, char* argv[]); +int mac_run(int argc, std::vector str_argv, char* argv[]); PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); -//int KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap); +//int mac_KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap); -void KMX_LogError(const wchar_t* fmt, ...); +void mac_KMX_LogError(const wchar_t* fmt, ...); From c19d0bea5b71725057fb5f0362adb30038fea0a2 Mon Sep 17 00:00:00 2001 From: Sabine Date: Sat, 27 Apr 2024 18:40:29 +0200 Subject: [PATCH 11/71] feat(mac): mcompile opened all non-deadkey-functions feat(mac): mcompile tidy up --- mac/mcompile/deadkey.cpp | 16 +-- mac/mcompile/deadkey.h | 8 +- mac/mcompile/keymap.cpp | 87 ++++++++++++----- mac/mcompile/keymap.h | 6 +- mac/mcompile/mc_import_rules.cpp | 163 ++++++++++++++++--------------- mac/mcompile/mcompile.cpp | 74 +++++++------- mac/mcompile/mcompile.h | 14 +-- 7 files changed, 204 insertions(+), 164 deletions(-) diff --git a/mac/mcompile/deadkey.cpp b/mac/mcompile/deadkey.cpp index b911c939b97..eeb6e13120c 100755 --- a/mac/mcompile/deadkey.cpp +++ b/mac/mcompile/deadkey.cpp @@ -14,9 +14,9 @@ return line; }*/ -/*std::vector mac_create_alDead() { +std::vector mac_create_alDead() { std::vector alDead; - v_dw_2D dk_ComposeTable; + /*v_dw_2D dk_ComposeTable; mac_create_DKTable(dk_ComposeTable); @@ -27,12 +27,12 @@ dk2->KMX_AddDeadKeyRow(dk_ComposeTable[j][1],dk_ComposeTable[j][2]); } alDead.push_back(dk2); - } + }*/ return alDead; -}*/ +} -/*void mac_refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector *p_All_Vec) { - if( dk == 0) +void mac_refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector *p_All_Vec) { + /*if( dk == 0) return; for (int j=0; j < (int) (*p_All_Vec).size()-1;j++) { @@ -43,10 +43,10 @@ } else return; } - } + }*/ } -bool found_dk_inVector(KMX_WCHAR dk, std::vector &dkVec) { +/* bool found_dk_inVector(KMX_WCHAR dk, std::vector &dkVec) { int i=0; if( dkVec.size() > 0) { do { diff --git a/mac/mcompile/deadkey.h b/mac/mcompile/deadkey.h index e9f8d3a2efa..c916323db42 100755 --- a/mac/mcompile/deadkey.h +++ b/mac/mcompile/deadkey.h @@ -5,10 +5,6 @@ #include #include "mc_import_rules.h" -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - // create a vector for a dk combination ( ` + a -> à ) v_dw_1D mac_createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult); @@ -26,6 +22,10 @@ bool found_dk_inVector(KMX_WCHAR dk, std::vector &myVec); // get all combination for a specific deadkey(dk) from the dk_vector mac_query_dk_combinations_for_specific_dk which holds all possible dk: ^-> â,ê,î,ô,û,... bool mac_query_dk_combinations_for_specific_dk(v_dw_2D * dk_ComposeTable, v_dw_2D & dk_SingleTable, KMX_DWORD dk); +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + // get the shifted character of a key and write shiftstate of KVal to shift //KMX_DWORD mac_KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap* keymap); diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 13b35b8f6ee..13c26f06e83 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -121,6 +121,15 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { return 2; } + // _S2 can go later + char layout[128]; + memset(layout, '\0', sizeof(layout)); + // get input source id - kTISPropertyInputSourceID + // get layout name - kTISPropertyLocalizedName + CFStringRef layoutID =static_cast( TISGetInputSourceProperty(source, kTISPropertyInputSourceID)); + CFStringGetCString(layoutID, layout, sizeof(layout), kCFStringEncodingUTF8); + printf("++++++++++++++++++ we use keyboardLayout *** %s *** as underlying keyboard ++++++++++++++++++\n", layout); + return 0; } @@ -136,8 +145,9 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { return false; }*/ -/*std::u16string mac_convert_DeadkeyValues_To_U16str(int in) { - +std::u16string mac_convert_DeadkeyValues_To_U16str(int in) { +// _S2 not finished yet - needs deadkeys... +/* if (in == 0 ) return u"\0"; @@ -156,8 +166,10 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { return std::u16string(1, lname ); } else - return u"\0"; -}*/ + return u"\0";*/ + + return std::u16string(1, in ); +} int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { // _S2 not finished yet - needs deadkeys... @@ -169,15 +181,39 @@ int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, in OSStatus status; int returnint=0; - status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - // no deadkey yet - if( shiftstate %2 == 1) - return 0; // _S2 what to return if deadkeys are used?? - else { - in_array[0] = (int) unicodeString[0]; // even: combine char -> è - returnint = in_array[0]; - return returnint; - } + status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + + // _S2 no deadkeys yet + if( shiftstate %2 == 1) + return 0; // _S2 what to return if deadkeys are used?? + else { + in_array[0] = (int) unicodeString[0]; // even: combine char -> è + returnint = in_array[0]; + return returnint; + } + return returnint; +} + +int mac_KMX_get_KeyVal_underlying_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { + // _S2 not finished yet - needs deadkeys... + KMX_DWORD in_array[2] = {0,0}; + UInt32 deadkeystate = 0; + UniCharCount maxStringlength = 5; + UniCharCount actualStringlength = 0; + UniChar unicodeString[maxStringlength]; + OSStatus status; + int returnint=0; + + status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + + // no deadkey yet + if( shiftstate %2 == 1) + return 0; // _S2 what to return if deadkeys are used?? + else { + in_array[0] = (int) unicodeString[0]; // even: combine char -> è + returnint = in_array[0]; + return returnint; + } return returnint; } @@ -269,7 +305,6 @@ int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, in return (int) *keyvals; }*/ -//KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, guint keycode, int shift_state_pos) { KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int keycode, int shift_state_pos) { KMX_DWORD KVal = mac_get_keyval_From_Keycode(keycode, shift_state_pos*2 , keyboard_layout ); @@ -284,11 +319,8 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa return KVal; } -//KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey) { KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey) { - - /*GdkKeymapKey *maps; - guint *keyvals;*/ + // _S2 not finished yet - needs deadkeys... int count; PKMX_WCHAR dky=NULL; @@ -331,31 +363,36 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa return VK_US; }*/ -/*KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(GdkKeymap *keymap, v_dw_3D &All_Vector, KMX_DWORD KC_US, ShiftState ss, int caps) { +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_DWORD KC_US, ShiftState ss, int caps) { KMX_DWORD KC_underlying; - std::u16string u16str = mac_convert_DeadkeyValues_To_U16str(mac_KMX_get_KeyVal_From_KeyCode(keymap, KC_US, ss, caps)); + std::u16string u16str = mac_convert_DeadkeyValues_To_U16str(mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, KC_US, ss, caps)); for( int i=0; i< (int)All_Vector[1].size()-1 ;i++) { for( int j=1; j< (int)All_Vector[1][0].size();j++) { - if ( ( All_Vector[1][i][j] == (KMX_DWORD) *u16str.c_str() ) ) { + if ( ((KMX_DWORD) All_Vector[1][i][j] == (KMX_DWORD) *u16str.c_str() ) ) { KC_underlying = All_Vector[1][i][0]; return KC_underlying; } } } return KC_US; -}*/ +} UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS) { + uint ret= (mac_USVirtualKeyToScanCode[VirtualKeyUS]); return (mac_USVirtualKeyToScanCode[VirtualKeyUS]); } -/*KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { - if ( keycode >7) +// _S2 OK?? +KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { + /*if ( keycode >7) return (KMX_DWORD) ScanCodeToUSVirtualKey[keycode-8]; + return 0;*/ + + return (KMX_DWORD) mac_ScanCodeToUSVirtualKey[keycode]; return 0; -}*/ +} /*std::u16string mac_CodePointToU16String(unsigned int codepoint) { std::u16string str; diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 6fe7b6f6383..58597ea65ae 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -117,7 +117,6 @@ v_dw_2D mac_create_empty_2D_Vector(int dim_rows, int dim_shifts); int mac_append_underlying_ToVector(v_dw_3D &All_Vector, const UCKeyboardLayout * keykeyboard_layout); // initialize UCHR -//bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]); bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout); //------------------------------ @@ -924,11 +923,11 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x00 // L"K_?FF" // &HFF }; - bool mac_IsKeymanUsedChar(int KV); //------------------------------ std::vector mac_createVectorOfKeyboard( int shiftstate, const UCKeyboardLayout * keyboard_layout); + // take deadkey-value (e.g.65106) and return u16string (e.g. '^' ) std::u16string mac_convert_DeadkeyValues_To_U16str(int in); @@ -939,14 +938,13 @@ int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, in KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int keycode, int shift_state_pos); // fill Deadkey with dk and return CATEGORY -//KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap *keymap, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey); KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey); // use Vector to return the Keyval of underlying Keyboard KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D &All_Vector,KMX_DWORD VK_underlying); // use Vector to return the Keycode of the underlying Keyboard for given VK_US using GDK -//KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(GdkKeymap *keymap, v_dw_3D &All_Vector,KMX_DWORD KC_US, ShiftState ss, int caps); +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector,KMX_DWORD KC_US, ShiftState ss, int caps); // return the Keycode of the underlying Keyboard for given VK_US UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS); diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 9bc76837e54..f639085b681 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -69,8 +69,9 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { -/*int KMX_ToUnicodeEx(guint keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps,GdkKeymap *keymap) { - GdkKeymapKey *maps; +int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps,const UCKeyboardLayout * keyboard_layout) { + + /*GdkKeymapKey *maps; guint *keyvals; gint count; @@ -82,11 +83,12 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { if (!(keycode <= keycode_max)) return 0; - - KMX_DWORD KeyVal= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode(keymap, keycode, ShiftState(shift_state_pos), caps); + */ + // _S2 is it shift_state_pos or shift_state_pos*2 ??? + KMX_DWORD KeyVal= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode, ShiftState(2*shift_state_pos), caps); std::u16string str = mac_convert_DeadkeyValues_To_U16str(KeyVal); pwszBuff[0]= * (PKMX_WCHAR) str.c_str(); - + /* g_free(keyvals); g_free(maps); @@ -95,11 +97,11 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { return -1; else if(gdk_keyval_to_unicode(KeyVal) == 0) // NO UNICODE return 0; - else // usable char + else */ // usable char return 1; -}*/ +} -/*int KMX_DeadKeyMap(int index, std::vector *deadkeys, int deadkeyBase, std::vector *deadkeyMappings) { // I4327 // I4353 +int mac_KMX_DeadKeyMap(int index, std::vector *deadkeys, int deadkeyBase, std::vector *deadkeyMappings) { // I4327 // I4353 for(size_t i = 0; i < deadkeyMappings->size(); i++) { if((*deadkeyMappings)[i].deadkey == index) { return (*deadkeyMappings)[i].dkid; @@ -112,9 +114,9 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { } } return 0xFFFF; -}*/ +} -/*class KMX_VirtualKey { +class mac_KMX_VirtualKey { private: UINT m_vk; UINT m_sc; @@ -123,7 +125,7 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { public: - KMX_VirtualKey(UINT scanCode) { + mac_KMX_VirtualKey(UINT scanCode) { this->m_vk = mac_KMX_get_VKUS_From_KeyCodeUnderlying(scanCode); this->m_sc = scanCode; memset(this->m_rgfDeadKey,0,sizeof(this->m_rgfDeadKey)); @@ -137,20 +139,20 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { return this->m_sc; } - std::u16string KMX_GetShiftState(ShiftState shiftState, bool capsLock) { + std::u16string mac_KMX_GetShiftState(ShiftState shiftState, bool capsLock) { return this->m_rgss[(UINT)shiftState][(capsLock ? 1 : 0)]; } - void KMX_SetShiftState(ShiftState shiftState, std::u16string value, bool isDeadKey, bool capsLock) { + void mac_KMX_SetShiftState(ShiftState shiftState, std::u16string value, bool isDeadKey, bool capsLock) { this->m_rgfDeadKey[(UINT)shiftState][(capsLock ? 1 : 0)] = isDeadKey; this->m_rgss[(UINT)shiftState][(capsLock ? 1 : 0)] = value; } - bool KMX_IsSGCAPS() { - std::u16string stBase = this->KMX_GetShiftState(Base, false); - std::u16string stShift = this->KMX_GetShiftState(Shft, false); - std::u16string stCaps = this->KMX_GetShiftState(Base, true); - std::u16string stShiftCaps = this->KMX_GetShiftState(Shft, true); + bool mac_KMX_IsSGCAPS() { + std::u16string stBase = this->mac_KMX_GetShiftState(Base, false); + std::u16string stShift = this->mac_KMX_GetShiftState(Shft, false); + std::u16string stCaps = this->mac_KMX_GetShiftState(Base, true); + std::u16string stShiftCaps = this->mac_KMX_GetShiftState(Shft, true); return ( ((stCaps.size() > 0) && (stBase.compare(stCaps) != 0) && @@ -160,10 +162,10 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { (stShift.compare(stShiftCaps) != 0))); } - bool KMX_IsCapsEqualToShift() { - std::u16string stBase = this->KMX_GetShiftState(Base, false); - std::u16string stShift = this->KMX_GetShiftState(Shft, false); - std::u16string stCaps = this->KMX_GetShiftState(Base, true); + bool mac_KMX_IsCapsEqualToShift() { + std::u16string stBase = this->mac_KMX_GetShiftState(Base, false); + std::u16string stShift = this->mac_KMX_GetShiftState(Shft, false); + std::u16string stCaps = this->mac_KMX_GetShiftState(Base, true); return ( (stBase.size() > 0) && (stShift.size() > 0) && @@ -171,10 +173,10 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { (stShift.compare(stCaps) == 0)); } - bool KMX_IsAltGrCapsEqualToAltGrShift() { - std::u16string stBase = this->KMX_GetShiftState(MenuCtrl, false); - std::u16string stShift = this->KMX_GetShiftState(ShftMenuCtrl, false); - std::u16string stCaps = this->KMX_GetShiftState(MenuCtrl, true); + bool mac_KMX_IsAltGrCapsEqualToAltGrShift() { + std::u16string stBase = this->mac_KMX_GetShiftState(MenuCtrl, false); + std::u16string stShift = this->mac_KMX_GetShiftState(ShftMenuCtrl, false); + std::u16string stCaps = this->mac_KMX_GetShiftState(MenuCtrl, true); return ( (stBase.size() > 0) && (stShift.size() > 0) && @@ -182,10 +184,10 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { (stShift.compare(stCaps) == 0)); } - bool KMX_IsXxxxGrCapsEqualToXxxxShift() { - std::u16string stBase = this->KMX_GetShiftState(Xxxx, false); - std::u16string stShift = this->KMX_GetShiftState(ShftXxxx, false); - std::u16string stCaps = this->KMX_GetShiftState(Xxxx, true); + bool mac_KMX_IsXxxxGrCapsEqualToXxxxShift() { + std::u16string stBase = this->mac_KMX_GetShiftState(Xxxx, false); + std::u16string stShift = this->mac_KMX_GetShiftState(ShftXxxx, false); + std::u16string stCaps = this->mac_KMX_GetShiftState(Xxxx, true); return ( (stBase.size() > 0) && (stShift.size() > 0) && @@ -193,10 +195,10 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { (stShift.compare(stCaps) == 0)); } - bool KMX_IsEmpty() { + bool mac_KMX_IsEmpty() { for (int i = 0; i < 10; i++) { for (int j = 0; j <= 1; j++) { - if (this->KMX_GetShiftState((ShiftState)i, (j == 1)).size() > 0) { + if (this->mac_KMX_GetShiftState((ShiftState)i, (j == 1)).size() > 0) { return (false); } } @@ -204,7 +206,7 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { return true; } - bool KMX_IsKeymanUsedKey() { + bool mac_KMX_IsKeymanUsedKey() { return (this->m_vk >= 0x20 && this->m_vk <= 0x5F) || (this->m_vk >= 0x88); } @@ -212,7 +214,7 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { return KMX_ShiftStateMap[(int)ss] | (capslock ? (caps ? CAPITALFLAG : NOTCAPITALFLAG) : 0); } - int KMX_GetKeyCount(int MaxShiftState) { + int mac_KMX_GetKeyCount(int MaxShiftState) { int nkeys = 0; // Get the CAPSLOCK value @@ -223,7 +225,7 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { } for (int caps = 0; caps <= 1; caps++) { - std::u16string st = this->KMX_GetShiftState((ShiftState) ss, (caps == 1)); + std::u16string st = this->mac_KMX_GetShiftState((ShiftState) ss, (caps == 1)); if (st.size() == 0) { // No character assigned here @@ -248,13 +250,13 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { return nkeys; } - bool KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector *deadkeys, int deadkeyBase, BOOL bDeadkeyConversion,v_dw_3D &All_Vector, GdkKeymap *keymap) { // I4552 + bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector *deadkeys, int deadkeyBase, BOOL bDeadkeyConversion,v_dw_3D &All_Vector, const UCKeyboardLayout *keyboard_layout ) { // I4552 // Get the CAPSLOCK value int capslock = - (this->KMX_IsCapsEqualToShift() ? 1 : 0) | - (this->KMX_IsSGCAPS() ? 2 : 0) | - (this->KMX_IsAltGrCapsEqualToAltGrShift() ? 4 : 0) | - (this->KMX_IsXxxxGrCapsEqualToXxxxShift() ? 8 : 0); + (this->mac_KMX_IsCapsEqualToShift() ? 1 : 0) | + (this->mac_KMX_IsSGCAPS() ? 2 : 0) | + (this->mac_KMX_IsAltGrCapsEqualToAltGrShift() ? 4 : 0) | + (this->mac_KMX_IsXxxxGrCapsEqualToXxxxShift() ? 8 : 0); for (int ss = 0; ss <= MaxShiftState; ss++) { if (ss == Menu || ss == ShftMenu) { @@ -262,7 +264,7 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { continue; } for (int caps = 0; caps <= 1; caps++) { - std::u16string st = this->KMX_GetShiftState((ShiftState) ss, (caps == 1)); + std::u16string st = this->mac_KMX_GetShiftState((ShiftState) ss, (caps == 1)); PKMX_WCHAR p; @@ -288,7 +290,7 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { p = key->dpOutput = new KMX_WCHAR[4]; *p++ = UC_SENTINEL; *p++ = CODE_DEADKEY; - *p++ = KMX_DeadKeyMap(st[0], deadkeys, deadkeyBase, &KMX_FDeadkeys); // I4353 + *p++ = mac_KMX_DeadKeyMap(st[0], deadkeys, deadkeyBase, &KMX_FDeadkeys); // I4353 *p = 0; } key++; @@ -308,7 +310,7 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { // key->Key stores VK-US ( not underlying !!) // key->dpOutput stores character Underlying - KMX_DWORD SC_Underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keymap, All_Vector, this->SC(), (ShiftState) ss, caps); + KMX_DWORD SC_Underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keyboard_layout, All_Vector, this->SC(), (ShiftState) ss, caps); key->Key = mac_KMX_get_VKUS_From_KeyCodeUnderlying( SC_Underlying); key->Line = 0; @@ -329,15 +331,15 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { return true; } }; -*/ -/* class KMX_Loader { + + class mac_KMX_Loader { private: KMX_BYTE lpKeyStateNull[256]; UINT m_XxxxVk; public: - KMX_Loader() { + mac_KMX_Loader() { m_XxxxVk = 0; memset(lpKeyStateNull, 0, sizeof(lpKeyStateNull)); } @@ -357,9 +359,8 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { bool KMX_IsControlChar(char16_t ch) { return (ch < 0x0020) || (ch >= 0x007F && ch <= 0x009F); } - }; -*/ + /* int KMX_GetMaxDeadkeyIndex(KMX_WCHAR *p) { int n = 0; @@ -371,10 +372,10 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { return n; }*/ -/*bool KMX_ImportRules(LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, GdkKeymap **keymap, std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4552 - KMX_Loader loader; +bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout,std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 + mac_KMX_Loader loader; - std::vector rgKey; //= new VirtualKey[256]; + std::vector rgKey; //= new VirtualKey[256]; std::vector alDead; std::vector alDead_cpl = mac_create_alDead(); @@ -384,14 +385,19 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { // values in it. Then, store the SC in each valid VK so it can act as both a // flag that the VK is valid, and it can store the SC value. - for(UINT sc = 0x01; sc <= 0x7f; sc++) { - // fills m_vk with the VK of the US keyboard - // ( mcompile win uses MapVirtualKeyEx() to fill m_vk with the VK of the Underlying keyboard) - // Linux can get a VK for the US Keyboard using USVirtualKeyToScanCode/ScanCodeToUSVirtualKey - // Linux cannot get a VK for the underling Keyboard - // this "connection" is possible only when using All_Vector + //for(UINT sc = 0x01; sc <= 0x7f; sc++) { _S2 winL lin keycode start with 1; mac with 0 + for(UINT sc = 0x00; sc <= 0x7f; sc++) { - KMX_VirtualKey *key = new KMX_VirtualKey(sc); + // HERE IS A BIG DIFFERENCE COMPARED TO MCOMPILE FOR WINDOWS: + // mcompile on Windows fills rgkey.m_vk with the VK of the Underlying keyboard + // mcompile for macOS fills rgkey.m_vk with the VK of the US keyboard + // this results in a different sorting order in rgkey[] ! + + // macOS cannot get a VK for the underling Keyboard since this does not exist + // macOS can only get a VK for the US Keyboard (by using USVirtualKeyToScanCode/ScanCodeToUSVirtualKey) + // therefore in rgkey[ ] we use VK_US which we get from All_Vector + + mac_KMX_VirtualKey *key = new mac_KMX_VirtualKey(sc); if((key->VK() != 0) ) { rgKey[key->VK()] = key; @@ -401,9 +407,9 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { } // // _S2 TODO I assume we do not need those... -// rgKey[VK_DIVIDE] = new KMX_VirtualKey(hkl, VK_DIVIDE); -// rgKey[VK_CANCEL] = new KMX_VirtualKey(hkl, VK_CANCEL); -// rgKey[VK_DECIMAL] = new KMX_VirtualKey(hkl, VK_DECIMAL); +// rgKey[VK_DIVIDE] = new mac_KMX_VirtualKey(hkl, VK_DIVIDE); +// rgKey[VK_CANCEL] = new mac_KMX_VirtualKey(hkl, VK_CANCEL); +// rgKey[VK_DECIMAL] = new mac_KMX_VirtualKey(hkl, VK_DECIMAL); // in this part we skip shiftstates 4, 5, 8, 9 for(UINT iKey = 0; iKey < rgKey.size(); iKey++) { @@ -425,23 +431,23 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { KMX_DWORD KC_US = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); for(int caps = 0; caps <= 1; caps++) { - int rc = KMX_ToUnicodeEx(KC_US, sbBuffer, ss, caps, *keymap); + int rc = mac_KMX_ToUnicodeEx(KC_US, sbBuffer, ss, caps, *keyboard_layout); if(rc > 0) { if(*sbBuffer == 0) { - rgKey[iKey]->KMX_SetShiftState(ss, u"", false, (caps)); // different to windows since behavior on Linux is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, u"", false, (caps)); // different to windows since behavior on Linux is different } else { if( (ss == Ctrl || ss == ShftCtrl) ) { continue; } sbBuffer[rc] = 0; - rgKey[iKey]->KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to windows since behavior on Linux is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to windows since behavior on Linux is different } } else if(rc < 0) { sbBuffer[2] = 0; - rgKey[iKey]->KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on Linux is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on Linux is different mac_refine_alDead(sbBuffer[0], alDead, &alDead_cpl); } @@ -474,23 +480,24 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { //} LPKMX_KEY kkp = gp->dpKeyArray; - for(UINT j = 0; j < gp->cxKeyArray; j++, kkp++) { + //_S2 + /*for(UINT j = 0; j < gp->cxKeyArray; j++, kkp++) { nDeadkey = std::max(nDeadkey, KMX_GetMaxDeadkeyIndex(kkp->dpContext)); nDeadkey = std::max(nDeadkey, KMX_GetMaxDeadkeyIndex(kkp->dpOutput)); - } + }*/ } + kp->cxGroupArray++; gp = &kp->dpGroupArray[kp->cxGroupArray-1]; UINT nkeys = 0; for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { - if ((rgKey[iKey] != NULL) && rgKey[iKey]->KMX_IsKeymanUsedKey() && (!rgKey[iKey]->KMX_IsEmpty())) { - nkeys+= rgKey[iKey]->KMX_GetKeyCount(loader.KMX_MaxShiftState()); + if ((rgKey[iKey] != NULL) && rgKey[iKey]->mac_KMX_IsKeymanUsedKey() && (!rgKey[iKey]->mac_KMX_IsEmpty())) { + nkeys+= rgKey[iKey]->mac_KMX_GetKeyCount(loader.KMX_MaxShiftState()); } } - nDeadkey++; // ensure a 1-based index above the max deadkey value already in the keyboard gp->fUsingKeys = TRUE; @@ -501,18 +508,18 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { gp->dpKeyArray = new KMX_KEY[gp->cxKeyArray]; nkeys = 0; - // // Fill in the new rules // for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { - if ((rgKey[iKey] != NULL) && rgKey[iKey]->KMX_IsKeymanUsedKey() && (!rgKey[iKey]->KMX_IsEmpty())) { - if(rgKey[iKey]->KMX_LayoutRow(loader.KMX_MaxShiftState(), &gp->dpKeyArray[nkeys], &alDead, nDeadkey, bDeadkeyConversion, All_Vector,*keymap)) { // I4552 - nkeys+=rgKey[iKey]->KMX_GetKeyCount(loader.KMX_MaxShiftState()); + if ((rgKey[iKey] != NULL) && rgKey[iKey]->mac_KMX_IsKeymanUsedKey() && (!rgKey[iKey]->mac_KMX_IsEmpty())) { + if(rgKey[iKey]->mac_KMX_LayoutRow(loader.KMX_MaxShiftState(), &gp->dpKeyArray[nkeys], &alDead, nDeadkey, bDeadkeyConversion, All_Vector,*keyboard_layout)) { // I4552 + nkeys+=rgKey[iKey]->mac_KMX_GetKeyCount(loader.KMX_MaxShiftState()); } } } + gp->cxKeyArray = nkeys; // @@ -559,6 +566,8 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { // We only do this if not in deadkey conversion mode // + int STOP=0; // _S2 up to here +/* if (alDead.size() > 0 && !bDeadkeyConversion) { // I4552 kp->cxGroupArray++; @@ -611,7 +620,7 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { KMX_WCHAR *p = kkp->dpContext = new KMX_WCHAR[8]; *p++ = UC_SENTINEL; *p++ = CODE_DEADKEY; - *p++ = KMX_DeadKeyMap(dk->KMX_DeadCharacter(), &alDead, nDeadkey, FDeadkeys); // I4353 + *p++ = mac_KMX_DeadKeyMap(dk->KMX_DeadCharacter(), &alDead, nDeadkey, FDeadkeys); // I4353 // *p++ = nDeadkey+i; *p++ = UC_SENTINEL; *p++ = CODE_ANY; @@ -627,9 +636,9 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { kkp++; } } - +*/ return true; -}*/ +} const int CODE__SIZE[] = { -1, // undefined 0x00 diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 01ccfe2a275..0c7ec02b059 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -29,18 +29,9 @@ #include "u16.h" -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - - - - KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc, char *argv[]); -/*KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, gint argc, gchar *argv[]); -bool KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, GdkKeymap **keymap,std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 -*/ +bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout,std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 std::vector KMX_FDeadkeys; // I4353 @@ -158,6 +149,14 @@ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NU return 0; } + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + + + + // _S2 is this correct?? which SS ??? // Map of all shift states that we will work with const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCTRLFLAG|RALTFLAG, 0xFFFF}; @@ -170,11 +169,11 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCT // For each key rule on the keyboard, remap its key to the // correct shift state and key. Adjust the LCTRL+RALT -> RALT if necessary // -/* void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { +void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. - if((shift & (LCTRLFLAG|RALTFLAG)) == (LCTRLFLAG|RALTFLAG)) + if((shift & (LCTRLFLAG|RALTFLAG)) == (LCTRLFLAG|RALTFLAG)) shift &= ~LCTRLFLAG; if(key->ShiftFlags == 0 && key->Key == ch) { @@ -193,44 +192,44 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCT key->ShiftFlags &= ~VIRTUALCHARKEY; key->Key = vk; } -}*/ +} -/* void mac_KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { + void mac_KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { for(unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_TranslateKey(&group->dpKeyArray[i], vk, shift, ch); } -}*/ +} -/* void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { + void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { if(kbd->dpGroupArray[i].fUsingKeys) { mac_KMX_TranslateGroup(&kbd->dpGroupArray[i], vk, shift, ch); } } } -*/ -/* void mac_KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { + +void mac_KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { if(key->ShiftFlags == 0) { - mac_KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); + // mac_KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); } else if(key->ShiftFlags & VIRTUALCHARKEY) { - mac_KMX_LogError(L"Did not find a match for mnemonic virtual character key rule on line %d, + [%x '%c'] > ...", key->Line, key->ShiftFlags, key->Key); + // mac_KMX_LogError(L"Did not find a match for mnemonic virtual character key rule on line %d, + [%x '%c'] > ...", key->Line, key->ShiftFlags, key->Key); } -}*/ +} -/*void mac_KMX_ReportUnconvertedGroupRules(LPKMX_GROUP group) { +void mac_KMX_ReportUnconvertedGroupRules(LPKMX_GROUP group) { for(unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_ReportUnconvertedKeyRule(&group->dpKeyArray[i]); } -}*/ +} -/*void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { +void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { if(kbd->dpGroupArray[i].fUsingKeys) { mac_KMX_ReportUnconvertedGroupRules(&kbd->dpGroupArray[i]); } } -}*/ +} /*void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { // _S2 TOP_2 INFO this produces a different output due to different layouts for Lin<-> win ( for the same language!!) @@ -375,8 +374,8 @@ struct KMX_dkidmap { return s_dkids[s_ndkids++].dst_deadkey = s_next_dkid = ++dkid; }*/ -/*void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, v_dw_3D &All_Vector, GdkKeymap* keymap,v_dw_2D dk_Table) { - KMX_WORD deadkeys[512], *pdk; +void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout,v_dw_2D dk_Table) { + /* KMX_WORD deadkeys[512], *pdk; // Lookup the deadkey table for the deadkey in the physical keyboard // Then for each character, go through and map it through @@ -395,8 +394,8 @@ struct KMX_dkidmap { UINT KeyValUnderlying = mac_KMX_get_KeyValUnderlying_From_KeyValUS(All_Vector, *pdk); mac_KMX_TranslateDeadkeyKeyboard(kbd, dkid, KeyValUnderlying, *(pdk+1), *(pdk+2)); pdk+=3; - } -}*/ + }*/ +} KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { LPKMX_STORE sp; @@ -460,33 +459,30 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int KMX_WCHAR ch = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, VKShiftState[j], scUnderlying, &DeadKey); - wprintf(L"--- VK_%d -> SC_ [%c] dk=%d ( ss %i) \n", KMX_VKMap[i], ch == 0 ? 32 : ch, DeadKey, VKShiftState[j]); + //wprintf(L"--- VK_%d -> SC_ [%c] dk=%d ( ss %i) \n", KMX_VKMap[i], ch == 0 ? 32 : ch, DeadKey, VKShiftState[j]); if(bDeadkeyConversion) { // I4552 if(ch == 0xFFFF) { ch = DeadKey; } } -int STOP =0;/* switch(ch) { case 0x0000: break; - case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keymap , dk_Table); break; + case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout , dk_Table); break; default: mac_KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); - }*/ + } } } + mac_KMX_ReportUnconvertedKeyboardRules(kbd); + -// #################### _S2 work here ########################################### -/* - mac_KMX_ReportUnconvertedKeyboardRules(kbd); - if(!KMX_ImportRules(kbd, All_Vector, &keymap, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 + if(!mac_KMX_ImportRules(kbd, All_Vector, &keyboard_layout, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 return FALSE; - }*/ + } return TRUE; - } /* int mac_KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap) { diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 46a6879db72..46eea28e6a0 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -26,13 +26,6 @@ */ -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - - - - struct KMX_DeadkeyMapping { // I4353 KMX_WCHAR deadkey, dkid; UINT shift; @@ -45,6 +38,13 @@ int mac_run(int argc, std::vector str_argv, char* argv[]); PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + + + //int mac_KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap); void mac_KMX_LogError(const wchar_t* fmt, ...); From 7b05fa7b70ebf49c0f3fb3893746943007e2c9df Mon Sep 17 00:00:00 2001 From: Sabine Date: Tue, 30 Apr 2024 17:27:45 +0200 Subject: [PATCH 12/71] feat(mac):finish filling rgkey[] for non-deadkey feat(mac): mcompile new X_find_Shiftstates to verify shiftstates feat(mac): mcompile fill rgkey for base, shift, opt, shift+opt including CAPS feat(mac): mcompile fill rgkey prevent writing x01 into rgkey[] feat(mac): mcompile tidy up code --- mac/mcompile/keymap.cpp | 53 ++++++++++++++++++++------------ mac/mcompile/keymap.h | 6 ++-- mac/mcompile/kmx_file.h | 2 +- mac/mcompile/mc_import_rules.cpp | 51 ++++++++++++++++++++---------- mac/mcompile/mcompile.cpp | 15 ++++++--- 5 files changed, 83 insertions(+), 44 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 13c26f06e83..b78ed620a6b 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -1,12 +1,18 @@ #include "keymap.h" -// unmodified, shift, RALT, shift+RALT -int mac_map_VKShiftState_to_LinModifier(int VKShiftState) { - if (VKShiftState == 0 ) return 0; // 0000 0000 // _S2 are the bits OK like that? - else if (VKShiftState == 16) return 2; // 0001 0000 // - else if (VKShiftState == 9 ) return 4; // 0000 1001 // - else if (VKShiftState == 25) return 6; // 0001 1001 // - else return VKShiftState; +// _S2 why not have 0,2,8,10 directly in VKShiftState ?? +// base, shift, OPT, shift+OPT, FF +int mac_map_VKShiftState_to_MacModifier(int VKShiftState) { + if (VKShiftState == 0 ) return 0; // 0000 0000 + else if (VKShiftState == 1) return 2; // 0000 0010 + // else if (VKShiftState == 3) return 3; // 0000 0011 + // else if (VKShiftState == 4) return 4; // 0000 0100 + // else if (VKShiftState == 5) return 4; // 0000 0101 + else if (VKShiftState == 6 ) return 8; // 0000 0110 + else if (VKShiftState == 7) return 10; // 0000 0111 + // else if (VKShiftState == 8) return 4; // 0000 1000 + // else if (VKShiftState == 9) return 4; // 0000 1001 + else return 99; // _S2 what to return if no match?? } int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { @@ -121,14 +127,14 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { return 2; } - // _S2 can go later + /*// _S2 can go later char layout[128]; memset(layout, '\0', sizeof(layout)); // get input source id - kTISPropertyInputSourceID // get layout name - kTISPropertyLocalizedName CFStringRef layoutID =static_cast( TISGetInputSourceProperty(source, kTISPropertyInputSourceID)); CFStringGetCString(layoutID, layout, sizeof(layout), kCFStringEncodingUTF8); - printf("++++++++++++++++++ we use keyboardLayout *** %s *** as underlying keyboard ++++++++++++++++++\n", layout); + printf("++++++++++++++++++ we use keyboardLayout *** %s *** as underlying keyboard ++++++++++++++++++\n", layout);*/ return 0; } @@ -179,19 +185,27 @@ int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, in UniCharCount actualStringlength = 0; UniChar unicodeString[maxStringlength]; OSStatus status; - int returnint=0; - status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // _S2 bette solution for 4*CAPS ???? + status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + + // UCKeyTranslate writes 0x01 into unicodeString[0] if there is no character assigned to the Key+Shift+CAPS + // ( then returnes 0 -> 0 is then propagated to ... mac_KMX_ToUnicodeEx (-> rc=0) .. ImportRules (rc=0-> do nothing ) ) // _S2 no deadkeys yet if( shiftstate %2 == 1) return 0; // _S2 what to return if deadkeys are used?? + else { - in_array[0] = (int) unicodeString[0]; // even: combine char -> è - returnint = in_array[0]; - return returnint; + if( (int) unicodeString[0] == 1 ) // impossible character + return 0; + else { + return (int) unicodeString[0]; // even: combine char -> è + } } - return returnint; + + + return 0; } int mac_KMX_get_KeyVal_underlying_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { @@ -327,17 +341,15 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa if (!keyboard_layout) return 0; /* - if (!(mac_map_VKShiftState_to_LinModifier(VKShiftState) <= count)) + if (!(mac_map_VKShiftState_to_MacModifier(VKShiftState) <= count)) return 0; */ if (!(KC_underlying <= keycode_max)) return 0; - KMX_DWORD KeyV = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, KC_underlying, ShiftState(mac_map_VKShiftState_to_LinModifier(VKShiftState)), 0); -// _S2 not finished - needs deadlkeys - /*g_free(keyvals); - g_free(maps);*/ + KMX_DWORD KeyV = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, KC_underlying, ShiftState(mac_map_VKShiftState_to_MacModifier(VKShiftState)), 0); + // _S2 not finished - needs deadlkeys /*if ((KeyV >= deadkey_min) && (KeyV <= deadkey_max) ){ // deadkey dky = (PKMX_WCHAR) (mac_convert_DeadkeyValues_To_U16str((int) KeyV)).c_str(); *DeadKey = *dky; @@ -347,6 +359,7 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa return 0xFFFE; else // usable char return KeyV;*/ + return KeyV; } diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 58597ea65ae..edd6244049e 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -92,8 +92,8 @@ static KMX_DWORD deadkey_min = 0xfe50; static KMX_DWORD deadkey_max = 0xfe93; //static KMX_DWORD deadkey_max = 0xfe52; // _S2 TOP_6 TODO This has to go! my test: to only return 3 dk -// map Shiftstate to modifier (e.g. 0->0; 16-1; 9->2; 25->3) -int mac_map_VKShiftState_to_LinModifier(int VKShiftState); +// map Shiftstate to modifier (e.g. 0->0; ) +int mac_map_VKShiftState_to_MacModifier(int VKShiftState); // take a std::string (=contents of line symbols-file ) and returns the (int) value of the character KMX_DWORD mac_convertNamesTo_DWORD_Value(std::string tok_str); @@ -652,6 +652,7 @@ const UINT mac_ScanCodeToUSVirtualKey[128] = { 115 // L"K_?00", // &H73 }; +// _S2 what instead x999? const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, // L"K_?00", // &H0 ................................................... 0 ........................................... 0x999, // L"K_LBUTTON", // &H1 @@ -964,5 +965,6 @@ void printoutKeyboards(v_dw_3D &All_Vector); //################################################################################################################################################ //################################################################################################################################################ +KMX_DWORD X_find_Shiftstates(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); #endif // KEYMAP_H \ No newline at end of file diff --git a/mac/mcompile/kmx_file.h b/mac/mcompile/kmx_file.h index 74c573650eb..1e7d76da8f5 100755 --- a/mac/mcompile/kmx_file.h +++ b/mac/mcompile/kmx_file.h @@ -27,7 +27,7 @@ namespace kmx { #define KEYMANID_INVALID 0xFFFFFFFD // Shift flags for hotkeys (version 1.0) // - +//_S2 here values for mac #define SHIFTFLAG 0x2000 #define CTRLFLAG 0x4000 #define ALTFLAG 0x8000 diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index f639085b681..981e4e87764 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -84,12 +84,18 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, i if (!(keycode <= keycode_max)) return 0; */ - // _S2 is it shift_state_pos or shift_state_pos*2 ??? - KMX_DWORD KeyVal= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode, ShiftState(2*shift_state_pos), caps); + + //rc>0: character + //rc==0: no translation + //rc<0: dk + + KMX_DWORD KeyVal= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode, mac_map_VKShiftState_to_MacModifier(ShiftState(shift_state_pos)), caps); + + // _S2 ToDo non-dk OK, but all others not std::u16string str = mac_convert_DeadkeyValues_To_U16str(KeyVal); pwszBuff[0]= * (PKMX_WCHAR) str.c_str(); - /* + /* g_free(keyvals); g_free(maps); @@ -98,7 +104,13 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, i else if(gdk_keyval_to_unicode(KeyVal) == 0) // NO UNICODE return 0; else */ // usable char - return 1; + + if ( 1!=1) // later for deadkeys + return -1; + else if (KeyVal ==0) // NO UNICODE + return 0; + else + return 1; // usable char } int mac_KMX_DeadKeyMap(int index, std::vector *deadkeys, int deadkeyBase, std::vector *deadkeyMappings) { // I4327 // I4353 @@ -238,7 +250,8 @@ class mac_KMX_VirtualKey { if(st[ich] < 0x20 || st[ich] == 0x7F) { isvalid=false; - wprintf(L"invalid for: %i\n", st[ich]); + // _S2 must be included later + // wprintf(L"invalid for: %i\n", st[ich]); break; } } if(isvalid) { @@ -300,7 +313,8 @@ class mac_KMX_VirtualKey { for (size_t ich = 0; ich < st.size(); ich++) { if(st[ich] < 0x20 || st[ich] == 0x7F) { isvalid=false; - wprintf(L"invalid 16 for: %i\n", st[ich]); + // _S2 must be included later + //wprintf(L"invalid 16 for: %i\n", st[ich]); break; } } if(isvalid) { @@ -427,28 +441,32 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar // if(ss == MenuCtrl|| ss == ShftMenuCtrl) { // continue; // } - + // _S2 ToDo what about not used keys?? KMX_DWORD KC_US = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); for(int caps = 0; caps <= 1; caps++) { + // _S2 shiftstates + // _S2 what is rc for mac? int rc = mac_KMX_ToUnicodeEx(KC_US, sbBuffer, ss, caps, *keyboard_layout); - + //rc>0: character + //rc==0: no translation + //rc<0: dk if(rc > 0) { if(*sbBuffer == 0) { rgKey[iKey]->mac_KMX_SetShiftState(ss, u"", false, (caps)); // different to windows since behavior on Linux is different } else { if( (ss == Ctrl || ss == ShftCtrl) ) { - continue; - } - sbBuffer[rc] = 0; - rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to windows since behavior on Linux is different - } + continue; + } + sbBuffer[rc] = 0; + rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to windows since behavior on Linux is different + } } else if(rc < 0) { sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on Linux is different - + // _S2 does not work - deadkeys mac_refine_alDead(sbBuffer[0], alDead, &alDead_cpl); } } @@ -567,7 +585,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar // int STOP=0; // _S2 up to here -/* + if (alDead.size() > 0 && !bDeadkeyConversion) { // I4552 kp->cxGroupArray++; @@ -620,7 +638,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar KMX_WCHAR *p = kkp->dpContext = new KMX_WCHAR[8]; *p++ = UC_SENTINEL; *p++ = CODE_DEADKEY; - *p++ = mac_KMX_DeadKeyMap(dk->KMX_DeadCharacter(), &alDead, nDeadkey, FDeadkeys); // I4353 + // _S2 needs to be in *p++ = mac_KMX_DeadKeyMap(dk->KMX_DeadCharacter(), &alDead, nDeadkey, FDeadkeys); // I4353 // *p++ = nDeadkey+i; *p++ = UC_SENTINEL; *p++ = CODE_ANY; @@ -636,7 +654,6 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar kkp++; } } -*/ return true; } diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 0c7ec02b059..23d77422d9b 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -137,7 +137,7 @@ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NU if(mac_KMX_DoConvert( kmxfile, bDeadkeyConversion, argc, (gchar**) argv_ch)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); } -/* _S2 WORK FROM HERE */ + #elif (__APPLE__ && TARGET_OS_MAC ) //macOS if(mac_KMX_DoConvert( kmxfile, bDeadkeyConversion, argc, (char**) argv_ch)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); @@ -161,6 +161,7 @@ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NU // Map of all shift states that we will work with const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCTRLFLAG|RALTFLAG, 0xFFFF}; //const UINT VKShiftState[] = {0, 2, 4,6, 0xFFFF}; +//const UINT VKShiftState[] = {0, 2, 8,10, 0xFFFF}; // @@ -445,6 +446,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int // _S2 printoutKeyboards(All_Vector); + // _S2 ToDo v_dw_2D dk_Table; mac_create_DKTable(dk_Table); @@ -455,8 +457,9 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int for (int i = 0;KMX_VKMap[i]; i++) { // I4651 // windows uses VK, Linux, mac use SC/Keycode + // _S2 ToDo unused vk`s ?? UINT scUnderlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_VKMap[i]); - + // _S2 ToDo non-dk OK, but all others not KMX_WCHAR ch = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, VKShiftState[j], scUnderlying, &DeadKey); //wprintf(L"--- VK_%d -> SC_ [%c] dk=%d ( ss %i) \n", KMX_VKMap[i], ch == 0 ? 32 : ch, DeadKey, VKShiftState[j]); @@ -468,15 +471,19 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int } switch(ch) { case 0x0000: break; + // _S2 ToDo case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout , dk_Table); break; + // _S2 ToDo non-dk OK, but all others not default: mac_KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); } } } + // _S2 ToDo non-dk OK, but all others are not mac_KMX_ReportUnconvertedKeyboardRules(kbd); - - + // _S2 has to go later + /*KMX_DWORD out = X_find_Shiftstates(0, keyboard_layout,12) ;*/ + //KMX_DWORD out2= X_find_Shiftstates(0, keyboard_layout,0) ; if(!mac_KMX_ImportRules(kbd, All_Vector, &keyboard_layout, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 return FALSE; From 5139ba463d7389ae72d6985ae419fe36f93ecf8d Mon Sep 17 00:00:00 2001 From: Sabine Date: Thu, 2 May 2024 12:22:22 +0200 Subject: [PATCH 13/71] feat(mac): add function to test rgkey --- mac/mcompile/X_helpers.h | 6 +++ mac/mcompile/mc_import_rules.cpp | 77 ++++++++++++++++++++++++++++++++ mac/mcompile/mcompile.cpp | 1 + 3 files changed, 84 insertions(+) create mode 100644 mac/mcompile/X_helpers.h diff --git a/mac/mcompile/X_helpers.h b/mac/mcompile/X_helpers.h new file mode 100644 index 00000000000..0897afb8671 --- /dev/null +++ b/mac/mcompile/X_helpers.h @@ -0,0 +1,6 @@ + +#pragma once +#ifndef X_HELPERS_H +#define X_HELPERS_H + +#endif //X_HELPERS_H \ No newline at end of file diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 981e4e87764..2e00e03d926 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -386,6 +386,8 @@ class mac_KMX_VirtualKey { return n; }*/ +bool run_verify_S2(std::vector rgKey); + bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout,std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 mac_KMX_Loader loader; @@ -479,6 +481,11 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar // translate it to kmx and append to the existing keyboard //------------------------------------------------------------- + if ( ! run_verify_S2(rgKey)) + printf(" ::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG ENTRIES ::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); + else + printf(" ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :) :) :) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); + int nDeadkey = 0; LPKMX_GROUP gp = new KMX_GROUP[kp->cxGroupArray+4]; // leave space for old memcpy(gp, kp->dpGroupArray, sizeof(KMX_GROUP) * kp->cxGroupArray); @@ -684,3 +691,73 @@ const int CODE__SIZE[] = { 3, // CODE_IFSYSTEMSTORE 0x17 2 // CODE_SETSYSTEMSTORE 0x18 }; + + + + +bool verify_entries_S2(int i, std::vector rgKey, int res1,int res2,int res3,int res4 ,int res5=0, int res6=0, int res7=0, int res8=0 ) { + std::vector st_vec; + std::vector r_vec; + bool all_OK=true;; + + r_vec.push_back(res1); r_vec.push_back(res2); + r_vec.push_back(res3); r_vec.push_back(res4); + r_vec.push_back(res5); r_vec.push_back(res6); + r_vec.push_back(res7); r_vec.push_back(res8); + + st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(Base,0)); + st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(Base,1)); + st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(Shft,0)); + st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(Shft,1)); + st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(MenuCtrl,0)); + st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(MenuCtrl,1)); + st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(ShftMenuCtrl,0)); + st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(ShftMenuCtrl,1)); + + for ( int k=0; k< st_vec.size();k++) + if (r_vec[k] !=0 ) all_OK = ( *st_vec[k].c_str() == r_vec[k] ) && all_OK; + + if( !all_OK) + printf(" ERROR FOR i= Nr:%i, %i(%c) - %i (%c) - %i (%c) - %i (%c) \n",i, *st_vec[0].c_str(),*st_vec[1].c_str(),*st_vec[2].c_str(),*st_vec[3].c_str(),*st_vec[4].c_str(),*st_vec[5].c_str(),*st_vec[6].c_str(),*st_vec[7].c_str()); + return all_OK; +} + +bool run_verify_S2(std::vector rgKey) { + + bool allOK= true; + allOK = verify_entries_S2(48, rgKey, 48,48,61,61) && allOK; + allOK = verify_entries_S2(48, rgKey, 48,48,61,61) && allOK; + allOK = verify_entries_S2(49, rgKey, 49,49,33,33) && allOK; + allOK = verify_entries_S2(50, rgKey, 50,50,34,34) && allOK; + allOK = verify_entries_S2(51, rgKey, 51,51,167,167) && allOK; + allOK = verify_entries_S2(52, rgKey, 52,52,36,36) && allOK; + allOK = verify_entries_S2(53, rgKey, 53,53,37,37) && allOK; + allOK = verify_entries_S2(54, rgKey, 54,54,38,38) && allOK; + allOK = verify_entries_S2(55, rgKey, 55,55,47,47) && allOK; + allOK = verify_entries_S2(56, rgKey, 56,56,40,40) && allOK; + allOK = verify_entries_S2(57, rgKey, 57,57,41,41) && allOK; + + allOK = verify_entries_S2(65, rgKey,97,65,65,65, 0x263A, 0xC5, 0, 0) && allOK; + + for( int i=65; i<89;i++) + allOK = verify_entries_S2(i, rgKey,i+32,i,i,i) && allOK; + + allOK = verify_entries_S2(89, rgKey, 90+32,90,90,90) && allOK; + allOK = verify_entries_S2(90, rgKey, 89+32,89,89,89) && allOK; + + allOK = verify_entries_S2(186, rgKey, 246,214,214,214) && allOK; + //allOK = verify_entries_S2(187, rgKey, 48,48,61,61) && allOK; // dk ´ ` + allOK = verify_entries_S2(188, rgKey,44,44,59,59) && allOK; + allOK = verify_entries_S2(189, rgKey, 223,223,63,63) && allOK; + allOK = verify_entries_S2(190, rgKey, 46,46,58,58) && allOK; + allOK = verify_entries_S2(191, rgKey, 45,45,95,95) && allOK; + + //allOK = verify_entries_S2(192, rgKey, 48,48,61,61) && allOK; // dk ^ ° + allOK = verify_entries_S2(219, rgKey, 252,220,220,220) && allOK; + allOK = verify_entries_S2(220, rgKey, 35,35,39,39) && allOK; + allOK = verify_entries_S2(221, rgKey, 43,43,42,42) && allOK; + allOK = verify_entries_S2(222, rgKey, 228,196,196,196) && allOK; + //allOK = verify_entries_S2(226, rgKey, 48,48,61,61) && allOK; // < > + + return allOK; +} diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 23d77422d9b..8cf43d46305 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -62,6 +62,7 @@ std::vector KMX_FDeadkeys; // I4353 mac_run(argc, str_argv_16, argv); printf("\n................................ END ..............................\n"); + #endif } From 6ae7927abf1bc8e1c6e671f43f8f8dd67486359e Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 3 May 2024 16:23:57 +0200 Subject: [PATCH 14/71] feat(mac): Arrays for mapping VK<->SC --- mac/mcompile/keymap.h | 191 +++++++++++++++---------------- mac/mcompile/mc_import_rules.cpp | 67 +++++++++-- 2 files changed, 150 insertions(+), 108 deletions(-) diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index edd6244049e..1177221de39 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -519,7 +519,10 @@ const UINT ScanCodeToUSVirtualKey[128] = { 0x00 // 0x7f => No match }; -// _S2 many keys still need to be defined !! +// _S2 many keys still need to be defined !! +//( on x. place there is key e.g. +// on (US) position 24 we find key xBB ( = + ) +// on (US) position 0 we find key x41 ( A a ) const UINT mac_ScanCodeToUSVirtualKey[128] = { 0x41 ,// L"K_A", // &H41 0x53 ,// L"K_S", // &H53 @@ -531,7 +534,7 @@ const UINT mac_ScanCodeToUSVirtualKey[128] = { 0x58 ,// L"K_X", // &H58 0x43 ,// L"K_C", // &H43 0x56 ,// L"K_V", // &H56 - 0x00, +0xC0, // ^° // 10 0x42 ,// L"K_B", // &H42 0x51 ,// L"K_Q", // &H51 0x57 ,// L"K_W", // &H57 @@ -541,28 +544,27 @@ const UINT mac_ScanCodeToUSVirtualKey[128] = { 0x54 ,// L"K_T", // &H54 0x31 ,// L"K_1", // &H31 0x32 ,// L"K_2", // &H32 - 0x33 ,// L"K_3", // &H33 +0x33 ,// L"K_3", // &H33 // 20 0x34 ,// L"K_4", // &H34 0x36 ,// L"K_6", // &H36 0x35 ,// L"K_5", // &H35 - 187 ,// L"K_?00", // &HB8 + 0xBB ,// L"K_?00",// &HB8 0x39 ,// L"K_9", // &H39 0x37 ,// L"K_7", // &H37 - 189 ,// L"K_?00", // &HBA + 0xBD ,// L"K_?00",// &HBA 0x38 ,// L"K_8", // &H38 0x30 ,// L"K_0", // &H30 - 221 ,// 0 // &HD9 +0xDD ,// 0 // &HD9 // 30 0x4F ,// L"K_O", // &H4F - 0x55 ,// L"K_U", // &H55 - 219 ,// 0 // &HD7 + 0xDB , // 0 // &HD7 0x49 ,// L"K_I", // &H49 0x50 ,// L"K_P", // &H50 0x00, 0x4C ,// L"K_L", // &H4C 0x4A ,// L"K_J", // &H4A - 222, //222 ,// 0 // &HDA - 0x4B ,// L"K_K", // &H4B + 0xDE, //222 ,// 0 // &HDA +0x4B ,// L"K_K", // &H4B // 40 186 ,// L"K_?00", // &HB7 220 ,// 0 // &HD8 188 ,// L"K_?00", // &HB9 @@ -572,7 +574,7 @@ const UINT mac_ScanCodeToUSVirtualKey[128] = { 190 ,// L"K_?00", // L", 0 ,// L"K_?00", // &H0 // 0x77 => No match 32 ,// L"K_?00", // &H1 - 2 ,// L"K_?00", // &H2 +0xE2 ,// L"K_?00", // &H2 // 50 // NEU xxx 3 ,// L"K_?00", // &H3 4 ,// L"K_?00", // &H4 5 ,// L"K_?00", // &H5 @@ -582,7 +584,7 @@ const UINT mac_ScanCodeToUSVirtualKey[128] = { 9 ,// L"K_?00", // &H9 10 ,// L"K_?00", // &HA 11 ,// L"K_?00", // &HB - 12 ,// L"K_?00", // &HC +12 ,// L"K_?00", // &HC // 60 13 ,// L"K_?00", // &HD 14 ,// L"K_?00", // &HE 15 ,// L"K_?00", // &HF @@ -652,7 +654,16 @@ const UINT mac_ScanCodeToUSVirtualKey[128] = { 115 // L"K_?00", // &H73 }; + + + + // _S2 what instead x999? +//( on character-.st index we find the keycode e.g. +// for character A (65) we look at pos 65 and find keycode 0 +// for character X (87) we look at pos 87 and find keycode 7 +// for character + (187) we look at pos 187 and find keycode 24 + const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, // L"K_?00", // &H0 ................................................... 0 ........................................... 0x999, // L"K_LBUTTON", // &H1 @@ -664,9 +675,8 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, // L"K_?07", // &H7 0x999, // 0x0E, // L"K_BKSP", // &H8 0x999, // 0x0F, // L"K_TAB", // &H9 - 0x999, // L"K_?0A", // &HA - - 0x999, // L"K_?0B", // &HB................................................... 10 ........................................... + 0x999, // L"K_?0A", // &HA + 0x999, // L"K_?0B", // &HB................................................... 11 ........................................... 0x999, // 0x4C, // L"K_KP5", // &HC 0x999, // 0x1C, // L"K_ENTER", // &HD 0x999, // L"K_?0E", // &HE @@ -675,8 +685,7 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, // 0x1D, // L"K_CONTRO 0x999, // L", // &H11 0x999, // 0x38, // L"K_ALT", // &H12 0x999, // L"K_PAUSE", // &H13 - 0x999, // 0x3A, // L"K_CAPS", // &H14 - + 0x999, // 0x3A, // L"K_CAPS", // &H14 0x999, // L"K_KANJI?15", // &H15 0x999, // L"K_KANJI?16", // &H16 0x999, // L"K_KANJI?17", // &H17 @@ -686,10 +695,9 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, // L"K_ESC", // &H1B 0x999, // L"K_KANJI?1C", // &H1C 0x999, // L"K_KANJI?1D", // &H1D - 0x999, // L"K_KANJI?1E", // &H1E - - 0x999, // L"K_KANJI?1F", // &H1F................................................... 30 ........................................... -0x31, // L"K_SPACE", // &H20 +0x999, // L"K_KANJI?1E", // &H1E + 0x999, // L"K_KANJI?1F", // &H1F................................................... 31 ........................................... + 0x31, // L"K_SPACE", // &H20 0x999, // 0x49, // L"K_PGUP", // &H21 0x999, // 0x51, // L"K_PGDN", // &H22 0x999, // 0x4F, // L"K_END", // &H23 @@ -697,8 +705,7 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, // 0x4B, // L"K_LEFT", // &H25 0x999, // 0x48, // L"K_UP", // &H26 0x999, // 0x4D, // L"K_RIGHT", // &H27 - 0x999, // 0x50, // L"K_DOWN", // &H28 - +0x999, // 0x50, // L"K_DOWN", // &H28 0x999, // L"K_SEL", // &H29 0x999, // L"K_PRINT", // &H2A 0x999, // L"K_EXEC", // &H2B @@ -706,55 +713,49 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, // 0x52, // L"K_INS", // &H2D 0x999, // 0x53, // L"K_DEL", // &H2E 0x999, // 0x63, // L"K_HELP", // &H2F -0x1D, // L"K_0", // &H30 -0x12, // L"K_1", // &H31 + 0x1D, // L"K_0", // &H30 + 0x12, // L"K_1", // &H31 0x13, // L"K_2", // &H32 - -0x14, // L"K_3", // &H33................................................... 50 ........................................... -0x15, // L"K_4", // &H34 -0x17, // L"K_5", // &H35 -0x16, // L"K_6", // &H36 -0x1A, // L"K_7", // &H37 -0x1C, // L"K_8", // &H38 -0x19, // L"K_9", // &H39 + 0x14, // L"K_3", // &H33................................................... 51 ........................................... + 0x15, // L"K_4", // &H34 + 0x17, // L"K_5", // &H35 + 0x16, // L"K_6", // &H36 + 0x1A, // L"K_7", // &H37 + 0x1C, // L"K_8", // &H38 + 0x19, // L"K_9", // &H39 0x999, // L"K_?3A", // &H3A 0x999, // L"K_?3B", // &H3B - 0x999, // L"K_?3C", // &H3C - +0x999, // L"K_?3C", // &H3C 0x999, // L"K_?3D", // &H3D 0x999, // L"K_?3E", // &H3E 0x999, // L"K_?3F", // &H3F 0x999, // L"K_?40", // &H40 -0x00, // L"K_A", // &H41 -0x0B, // L"K_B", // &H42 -0x08, // L"K_C", // &H43 -0x02, // L"K_D", // &H44 -0x0E, // L"K_E", // &H45 + 0x00, // L"K_A", // &H41 + 0x0B, // L"K_B", // &H42 + 0x08, // L"K_C", // &H43 + 0x02, // L"K_D", // &H44 + 0x0E, // L"K_E", // &H45 0x03, // L"K_F", // &H46 - -0x05, // L"K_G", // &H47................................................... 70 ........................................... -0x04, // L"K_H", // &H48 -0x22, // L"K_I", // &H49 -0x26, // L"K_J", // &H4A -0x28, // L"K_K", // &H4B -0x25, // L"K_L", // &H4C -0x2E, // L"K_M", // &H4D -0x2D, // L"K_N", // &H4E -0x1F, // L"K_O", // &H4F - + 0x05, // L"K_G", // &H47................................................... 71 ........................................... + 0x04, // L"K_H", // &H48 + 0x22, // L"K_I", // &H49 + 0x26, // L"K_J", // &H4A + 0x28, // L"K_K", // &H4B + 0x25, // L"K_L", // &H4C + 0x2E, // L"K_M", // &H4D + 0x2D, // L"K_N", // &H4E + 0x1F, // L"K_O", // &H4F 0x23, // L"K_P", // &H50 -0x0C, // L"K_Q", // &H51 -0x0F, // L"K_R", // &H52 -0x01, // L"K_S", // &H53 -0x11, // L"K_T", // &H54 -0x20, // L"K_U", // &H55 -0x09, // L"K_V", // &H56 -0x0D, // L"K_W", // &H57 -0x07, // L"K_X", // &H58 - -0x10, // L"K_Y", // &H59................................................... 90 ........................................... + 0x0C, // L"K_Q", // &H51 + 0x0F, // L"K_R", // &H52 + 0x01, // L"K_S", // &H53 + 0x11, // L"K_T", // &H54 + 0x20, // L"K_U", // &H55 + 0x09, // L"K_V", // &H56 + 0x0D, // L"K_W", // &H57 + 0x07, // L"K_X", // &H58 + 0x10, // L"K_Y", // &H59................................................... 89 ........................................... 0x06, // L"K_Z", // &H5A - 0x999, //0x5B, // L"K_?5B", // &H5B 0x999, //0x5C, // L"K_?5C", // &H5C 0x999, //0x5D, // L"K_?5D", // &H5D @@ -764,7 +765,7 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x4F, // L"K_NP1", // &H61 0x999, //0x50, // L"K_NP2", // &H62 0x999, //0x51, // L"K_NP3", // &H63 - 0x999, //0x4B, // L"K_NP4", // &H64 + 0x999, //0x4B, // L"K_NP4", // &H64 0x999, //0x4C, // L"K_NP5", // &H65 0x999, //0x4D, // L"K_NP6", // &H66 0x999, //0x47, // L"K_NP7", // &H67 @@ -772,9 +773,9 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x49, // L"K_NP9", // &H69 0x999, //0x37, // L"K_NPSTAR", // &H6A 0x999, //0x4E, // L"K_NPPLUS", // &H6B - 0x999, //0x7E, // L"K_SEPARATOR", // &H6C // MCD 01-11-02: Brazilian Fix, 00 -> 7E................................................... 110 ........................................... + 0x999, //0x7E, // L"K_SEPARATOR", // &H6C // MCD 01-11-02: Brazilian Fix, 00 -> 7E 0x999, //0x4A, // L"K_NPMINUS", // &H6D - 0x999, //0x53, // L"K_NPDOT", // &H6E + 0x999, //0x53, // L"K_NPDOT", // &H6E // ................................................. 110 ........... 0x999, //0x135, // L"K_NPSLASH", // &H6F 0x999, //0x3B, // L"K_F1", // &H70 0x999, //0x3C, // L"K_F2", // &H71 @@ -784,7 +785,7 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x40, // L"K_F6", // &H75 0x999, //0x41, // L"K_F7", // &H76 0x999, //0x42, // L"K_F8", // &H77 - 0x999, //0x43, // L"K_F9", // &H78 + 0x999, //0x43, // L"K_F9", // &H78 0x999, //0x44, // L"K_F10", // &H79 0x999, //0x57, // L"K_F11", // &H7A 0x999, //0x58, // L"K_F12", // &H7B @@ -792,9 +793,9 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x65, // L"K_F14", // &H7D 0x999, //0x66, // L"K_F15", // &H7E 0x999, //0x67, // L"K_F16", // &H7F - 0x999, //0x68, // L"K_F17", // &H80................................................... 130 ........................................... + 0x999, //0x68, // L"K_F17", // &H80..... 0x999, //0x69, // L"K_F18", // &H81 - 0x999, //0x6A, // L"K_F19", // &H82 + 0x999, //0x6A, // L"K_F19", // &H82.................................................. 130 ....................................... 0x999, //0x6B, // L"K_F20", // &H83 0x999, //0x6C, // L"K_F21", // &H84 0x999, //0x6D, // L"K_F22", // &H85 @@ -804,7 +805,7 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x00, // L"K_?89", // &H89 0x999, //0x00, // L"K_?8A", // &H8A 0x999, //0x00, // L"K_?8B", // &H8B - 0x999, //0x00, // L"K_?8C", // &H8C + 0x999, //0x00, // L"K_?8C", // &H8C 0x999, //0x00, // L"K_?8D", // &H8D 0x999, //0x00, // L"K_?8E", // &H8E 0x999, //0x00, // L"K_?8F", // &H8F ----- @@ -812,9 +813,9 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x46, // L"K_SCROL 0x999, //0x00, // L", // &H91 ----- 0x999, //0x00, // L"K_?92", // &H92 0x999, //0x00, // L"K_?93", // &H93 - 0x999, //0x00, // L"K_?94", // &H94................................................... 150 ........................................... + 0x999, //0x00, // L"K_?94", // &H94................. 0x999, //0x00, // L"K_?95", // &H95 - 0x999, //0x00, // L"K_?96", // &H96 + 0x999, //0x00, // L"K_?96", // &H96............................................. 150 ................................ 0x999, //0x00, // L"K_?97", // &H97 0x999, //0x00, // L"K_?98", // &H98 0x999, //0x00, // L"K_?99", // &H99 @@ -824,7 +825,7 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x00, // L"K_?9D", // &H9D 0x999, //0x00, // L"K_?9E", // &H9E 0x999, //0x00, // L"K_?9F", // &H9F - 0x999, //0x2A, // L"K_?A0", // &HA0 + 0x999, //0x2A, // L"K_?A0", // &HA0 0x999, //0x36, // L"K_?A1", // &HA1 0x999, //0x1D, // L"K_?A2", // &HA2 0x999, //0x1D, // L"K_?A3", // &HA3 @@ -832,9 +833,9 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x38, // L"K_?A5", // &HA5 0x999, //0x6A, // L"K_?A6", // &HA6 0x999, //0x69, // L"K_?A7", // &HA7 - 0x999, //0x67, // L"K_?A8", // &HA8................................................... 170 ........................................... + 0x999, //0x67, // L"K_?A8", // &HA8...................... 0x999, //0x68, // L"K_?A9", // &HA9 - 0x999, //0x65, // L"K_?AA", // &HAA + 0x999, //0x65, // L"K_?AA", // &HAA....................................... 170 ................................. 0x999, //0x66, // L"K_?AB", // &HAB 0x999, //0x32, // L"K_?AC", // &HAC 0x999, //0x20, // L"K_?AD", // &HAD @@ -844,27 +845,27 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x10, // L"K_?B1", // &HB1 0x999, //0x24, // L"K_?B2", // &HB2 0x999, //0x22, // L"K_?B3", // &HB3 - 0x999, //0x6C, // L"K_?B4", // &HB4 + 0x999, //0x6C, // L"K_?B4", // &HB4 0x999, //0x6D, // L"K_?B5", // &HB5 0x999, //0x6B, // L"K_?B6", // &HB6 0x999, //0x21, // L"K_?B7", // &HB7 0x999, //0x00, // L"K_?B8", // &HB8 0x999, //0x00, // L"K_?B9", // &HB9 ----- 0x29, // L"K_COLON", // &HBA - 0x999, // 0x0D, // L"K_EQUA0x00, // L", // &HBB - 0x2B, // L"K_COMMA", // &HBC ................................................... 190 ........................................... + 24, // 0x0D, // L"K_EQUA0x00, // L", // &HBB 187 + 0x2B, // L"K_COMMA", // &HBC ........ 0x1B, // L"K_HYPHEN", // &HBD - 0x2F, // L"K_PERIOD", // &HBE +0x2F, // L"K_PERIOD", // &HBE................................................ 190 ...................................... 0x2C, // L"K_SLASH", // &HBF - 0x999, //0x77, // L"K_BKQUOTE", // &HC0 ----- + 0x0A, //0x77, // L"K_BKQUOTE", // &HC0 ----- 0x999, //0x73, // L"K_?C1", // &HC1 0x999, //0x7E, // L"K_?C2", // &HC2 0x999, //0x00, // L"K_?C3", // &HC3 - 0x999, //0x00, // L"K_?C4", // &HC4 + 0x999, //0x00, // L"K_?C4", // &HC4 196 0x999, //0x00, // L"K_?C5", // &HC5 0x999, //0x00, // L"K_?C6", // &HC6 0x999, //0x00, // L"K_?C7", // &HC7 - 0x999, //0x00, // L"K_?C8", // &HC8 + 0x999, //0x00, // L"K_?C8", // &HC8 0x999, //0x00, // L"K_?C9", // &HC9 0x999, //0x00, // L"K_?CA", // &HCA 0x999, //0x00, // L"K_?CB", // &HCB @@ -872,9 +873,9 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x00, // L"K_?CD", // &HCD 0x999, //0x00, // L"K_?CE", // &HCE 0x999, //0x00, // L"K_?CF", // &HCF - 0x999, //0x00, // L"K_?D0", // &HD0................................................... 210 ........................................... + 0x999, //0x00, // L"K_?D0", // &HD0............... 0x999, //0x00, // L"K_?D1", // &HD1 - 0x999, //0x00, // L"K_?D2", // &HD2 + 0x999, //0x00, // L"K_?D2", // &HD2............................................... 210 ................................ 0x999, //0x00, // L"K_?D3", // &HD3 0x999, //0x00, // L"K_?D4", // &HD4 0x999, //0x00, // L"K_?D5", // &HD5 @@ -883,30 +884,28 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x00, // L"K_?D8", // &HD8 0x999, //0x00, // L"K_?D9", // &HD9 0x999, //0x00, // L"K_?DA", // &HDA - - 0x21, // L"K_LBRKT", // &HDB + 0x21, // L"K_LBRKT", // &HDB 0x2A, // L"K_BKSLASH", // &HDC - 0x1E, // L"K_RBRKT", // &HDD - 0x27, // L"K_QUOTE", // &HDE - 0x73, // L"K_oDF", // &HDF // MCD 01-11-02: Brazilian fix: 00 -> 73 + 0x1E, // L"K_RBRKT", // &HDD + 0x27, // L"K_QUOTE", // &HDE + 0x32, // L"K_oDF", // &HDF // MCD 01-11-02: Brazilian fix: 00 -> 73 0x999, //0x00, // L"K_oE0", // &HE0 0x999, //0x00, // L"K_oE1", // &HE1 - 0x999, //0x56, // L"K_oE2", // &HE2 + 50, //0x56, // L"K_oE2", // &HE2 0x999, //0x00, // L"K_oE3", // &HE3 - 0x999, //0x00, // L"K_oE4", // &HE4................................................... 220 ........................................... - + 0x999, //0x00, // L"K_oE4", // &HE4..... 0x999, //0x00, // L"K_?E5", // &HE5 - 0x999, //0x00, // L"K_oE6", // &HE6 +0x999, //0x00, // L"K_oE6", // &HE6.................................................. 230 ....................................... 0x999, //0x00, // L"K_?E7", // &HE7 - 0x999, //0x00, // L"K_?E8", // &HE8 + 0x999, //0x00, // L"K_?E8", // &HE8 222 0x999, //0x71, // L"K_oE9", // &HE9 0x999, //0x5C, // L"K_oEA", // &HEA 0x999, //0x7B, // L"K_oEB", // &HEB - 0x999, //0x00, // L"K_oEC", // &HEC + 0x999, //0x00, // L"K_oEC", // &HEC 226 0x999, //0x6F, // L"K_oED", // &HED 0x999, //0x5A, // L"K_oEE", // &HEE 0x999, //0x00, // L"K_oEF", // &HEF - 0x999, //0x00, // L"K_oF0", // &HF0 + 0x999, //0x00, // L"K_oF0", // &HF0 0x999, //0x5B, // L"K_oF1", // &HF1 0x999, //0x00, // L"K_oF2", // &HF2 0x999, //0x5F, // L"K_oF3", // &HF3 @@ -916,7 +915,7 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x00, // L"K_?F7", // &HF7 0x999, //0x00, // L"K_?F8", // &HF8 0x999, //0x5D, // L"K_?F9", // &HF9 - 0x999, //0x00, // L"K_?FA", // &HFA + 0x999, //0x00, // L"K_?FA", // &HFA 0x999, //0x62, // L"K_?FB", // &HFB 0x999, //0x00, // L"K_?FC", // &HFC 0x999, //0x00, // L"K_?FD", // &HFD diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 2e00e03d926..74988729407 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -386,6 +386,7 @@ class mac_KMX_VirtualKey { return n; }*/ +void print_All_Entries(std::vector rgKey); bool run_verify_S2(std::vector rgKey); bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout,std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 @@ -480,11 +481,12 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar // Now that we've collected the key data, we need to // translate it to kmx and append to the existing keyboard //------------------------------------------------------------- + print_All_Entries(rgKey); if ( ! run_verify_S2(rgKey)) - printf(" ::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG ENTRIES ::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); + printf(" \n::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG ENTRIES ::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); else - printf(" ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :) :) :) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); + printf("\n ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :) :) :) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); int nDeadkey = 0; LPKMX_GROUP gp = new KMX_GROUP[kp->cxGroupArray+4]; // leave space for old @@ -695,6 +697,14 @@ const int CODE__SIZE[] = { +void print_entries_S2(int i, std::vector rgKey , std::string comp1,std::string comp2,std::string erg) { + std::string b0 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 0 )); + std::string b1 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 1 )); + std::string s0 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Shft, 0 )); + std::string s1 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Shft, 1 )); + printf("\n entry nr %i has characters %-30s:(%s|%s|%s|%s)",i, erg.c_str(), (const char * ) b0.c_str(),(const char * ) b1.c_str(),(const char * ) s0.c_str(),(const char * ) s1.c_str()); +} + bool verify_entries_S2(int i, std::vector rgKey, int res1,int res2,int res3,int res4 ,int res5=0, int res6=0, int res7=0, int res8=0 ) { std::vector st_vec; std::vector r_vec; @@ -722,6 +732,28 @@ bool verify_entries_S2(int i, std::vector rgKey, int res1,i return all_OK; } +void print_All_Entries( std::vector rgKey) { + for ( int i=48; i<58; i++) + print_entries_S2(i, rgKey," ","",""); + + for ( int i=65; i<91; i++) + print_entries_S2(i, rgKey, " ","", "" ); + + print_entries_S2(186, rgKey, "ö", "Ö", "xc3 xb6"); + print_entries_S2(187, rgKey, "´", ";", "´ ´ ` `"); + print_entries_S2(188, rgKey, ".", ":", ", , ; ;"); + print_entries_S2(189, rgKey, "ß", "?", "ß ß ? ?"); + print_entries_S2(190, rgKey, ".", ":", ". . : :"); + print_entries_S2(191, rgKey, "-", "_", "- - _ _"); + print_entries_S2(192, rgKey, "^", "°", "^ ^ ° °"); + + print_entries_S2(219, rgKey, "ü", "Ü", "ü,Ü;Ü;Ü"); + print_entries_S2(220, rgKey, "#", "'", "# # ' '"); + print_entries_S2(221, rgKey, "+", "*", "+ + * *"); + print_entries_S2(222, rgKey, "ä", "Ä", "ä Ä Ä Ä"); + print_entries_S2(226, rgKey, "<", ">", "< < > >"); +} + bool run_verify_S2(std::vector rgKey) { bool allOK= true; @@ -737,8 +769,6 @@ bool run_verify_S2(std::vector rgKey) { allOK = verify_entries_S2(56, rgKey, 56,56,40,40) && allOK; allOK = verify_entries_S2(57, rgKey, 57,57,41,41) && allOK; - allOK = verify_entries_S2(65, rgKey,97,65,65,65, 0x263A, 0xC5, 0, 0) && allOK; - for( int i=65; i<89;i++) allOK = verify_entries_S2(i, rgKey,i+32,i,i,i) && allOK; @@ -746,18 +776,31 @@ bool run_verify_S2(std::vector rgKey) { allOK = verify_entries_S2(90, rgKey, 89+32,89,89,89) && allOK; allOK = verify_entries_S2(186, rgKey, 246,214,214,214) && allOK; - //allOK = verify_entries_S2(187, rgKey, 48,48,61,61) && allOK; // dk ´ ` - allOK = verify_entries_S2(188, rgKey,44,44,59,59) && allOK; + //allOK = verify_entries_S2(187, rgKey, 180,180,96,96) && allOK; // dk ´ ` + allOK = verify_entries_S2(187, rgKey, 0,0,0,0) && allOK; // dk ´ ` + allOK = verify_entries_S2(188, rgKey, 44,44,59,59) && allOK; allOK = verify_entries_S2(189, rgKey, 223,223,63,63) && allOK; allOK = verify_entries_S2(190, rgKey, 46,46,58,58) && allOK; allOK = verify_entries_S2(191, rgKey, 45,45,95,95) && allOK; - //allOK = verify_entries_S2(192, rgKey, 48,48,61,61) && allOK; // dk ^ ° - allOK = verify_entries_S2(219, rgKey, 252,220,220,220) && allOK; - allOK = verify_entries_S2(220, rgKey, 35,35,39,39) && allOK; - allOK = verify_entries_S2(221, rgKey, 43,43,42,42) && allOK; - allOK = verify_entries_S2(222, rgKey, 228,196,196,196) && allOK; - //allOK = verify_entries_S2(226, rgKey, 48,48,61,61) && allOK; // < > + //allOK = verify_entries_S2(192, rgKey, 94,94,176,176) && allOK; // dk ^ ° + allOK = verify_entries_S2(192, rgKey, 0,0,176,176) && allOK; // dk ^ ° + allOK = verify_entries_S2(219, rgKey, 252,220,220,220) && allOK; + allOK = verify_entries_S2(220, rgKey, 35,35,39,39) && allOK; + allOK = verify_entries_S2(221, rgKey, 43,43,42,42) && allOK; + allOK = verify_entries_S2(222, rgKey, 228,196,196,196) && allOK; + allOK = verify_entries_S2(226, rgKey, 60,60,62,62) && allOK; // < > +// ------------------------------------------- + allOK = verify_entries_S2(48, rgKey, 48,48,61,61,L'}',0,0,0) && allOK; + allOK = verify_entries_S2(49, rgKey, 49,49,33,33,L'’',0,0,0) && allOK; + allOK = verify_entries_S2(50, rgKey, 50,50,34,34,L'²',0,0,0) && allOK; + allOK = verify_entries_S2(51, rgKey, 51,51,167,167,L'³',0,0,0) && allOK; + allOK = verify_entries_S2(52, rgKey, 52,52,36,36,L'—',0,0,0) && allOK; + allOK = verify_entries_S2(53, rgKey, 53,53,37,37,L'¡',0,0,0) && allOK; + allOK = verify_entries_S2(54, rgKey, 54,54,38,38,L'¿',0,0,0) && allOK; + allOK = verify_entries_S2(55, rgKey, 55,55,47,47,L'{',0,0,0) && allOK; + allOK = verify_entries_S2(56, rgKey, 56,56,40,40,L'[',0,0,0) && allOK; + allOK = verify_entries_S2(57, rgKey, 57,57,41,41,L']',0,0,0) && allOK; return allOK; } From b0e338c4cb6bd1a4ceb12f03a30c49633ff1df4a Mon Sep 17 00:00:00 2001 From: Sabine Date: Mon, 6 May 2024 20:43:41 +0200 Subject: [PATCH 15/71] feat(mac): start dk --- mac/mcompile/deadkey.cpp | 1 + mac/mcompile/deadkey.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mac/mcompile/deadkey.cpp b/mac/mcompile/deadkey.cpp index eeb6e13120c..bf27bdb8a84 100755 --- a/mac/mcompile/deadkey.cpp +++ b/mac/mcompile/deadkey.cpp @@ -4,6 +4,7 @@ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ +// _S2 TODO dk /* v_dw_1D mac_createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult) { v_dw_1D line; diff --git a/mac/mcompile/deadkey.h b/mac/mcompile/deadkey.h index c916323db42..56170f2a16c 100755 --- a/mac/mcompile/deadkey.h +++ b/mac/mcompile/deadkey.h @@ -4,7 +4,7 @@ #include #include "mc_import_rules.h" - +// _S2 TODO dk // create a vector for a dk combination ( ` + a -> à ) v_dw_1D mac_createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult); From c206128c8b2703683a24dc8b506b94dd8df28c58 Mon Sep 17 00:00:00 2001 From: Sabine Date: Mon, 6 May 2024 21:08:42 +0200 Subject: [PATCH 16/71] feat(mac): start dk fill All_Vector with dk --- mac/.gitignore | 3 +- mac/mcompile/keymap.cpp | 108 +++++++++++++++---------------- mac/mcompile/keymap.h | 12 ++-- mac/mcompile/mc_import_rules.cpp | 13 ++-- mac/mcompile/mcompile.cpp | 28 ++++++-- 5 files changed, 87 insertions(+), 77 deletions(-) diff --git a/mac/.gitignore b/mac/.gitignore index defe8b84f51..62da38b8ba0 100644 --- a/mac/.gitignore +++ b/mac/.gitignore @@ -19,4 +19,5 @@ setup/Install Keyman.app //Sabine **/mcompile/executable/*.* **/mcompile/*.kmx -**/mcompile/X*.cpp \ No newline at end of file +**/mcompile/X*.cpp +**/mcompile/X_bak \ No newline at end of file diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index b78ed620a6b..6e8da34f2cd 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -26,7 +26,6 @@ int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLa // [Keyval unshifted ] // [Keyval shifted ] - if(mac_write_US_ToVector(All_Vector)) { wprintf(L"ERROR: can't write US to Vector \n"); return 1; @@ -142,7 +141,7 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ - +// _S2 TODO all /*bool mac_IsKeymanUsedChar(int KV) { // 32 A-Z a-z if ((KV == 0x20 ) || (KV >= 65 && KV <= 90) || (KV >= 97 && KV <= 122) ) @@ -151,6 +150,7 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { return false; }*/ +// _S2 TODO all std::u16string mac_convert_DeadkeyValues_To_U16str(int in) { // _S2 not finished yet - needs deadkeys... /* @@ -177,6 +177,7 @@ std::u16string mac_convert_DeadkeyValues_To_U16str(int in) { return std::u16string(1, in ); } +// _S2 TODO dk/non-dk int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { // _S2 not finished yet - needs deadkeys... KMX_DWORD in_array[2] = {0,0}; @@ -192,7 +193,7 @@ int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, in // UCKeyTranslate writes 0x01 into unicodeString[0] if there is no character assigned to the Key+Shift+CAPS // ( then returnes 0 -> 0 is then propagated to ... mac_KMX_ToUnicodeEx (-> rc=0) .. ImportRules (rc=0-> do nothing ) ) - // _S2 no deadkeys yet + // _S2 no deadkeys yet or check last bit if( shiftstate %2 == 1) return 0; // _S2 what to return if deadkeys are used?? @@ -208,6 +209,7 @@ int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, in return 0; } +// _S2 TODO dk/non-dk int mac_KMX_get_KeyVal_underlying_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { // _S2 not finished yet - needs deadkeys... KMX_DWORD in_array[2] = {0,0}; @@ -319,9 +321,12 @@ int mac_KMX_get_KeyVal_underlying_From_KeyCode(const UCKeyboardLayout * keyboard return (int) *keyvals; }*/ +// _S2 TODO dk KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int keycode, int shift_state_pos) { - KMX_DWORD KVal = mac_get_keyval_From_Keycode(keycode, shift_state_pos*2 , keyboard_layout ); + //KMX_DWORD KVal = mac_get_keyval_From_Keycode(keycode, shift_state_pos*2 , keyboard_layout ); + + KMX_DWORD KVal= mac_get_keyval_From_Keycode_new(keycode,keyboard_layout , shift_state_pos*2); int count = max_shiftstate; if (!(shift_state_pos <= count*2)) @@ -333,6 +338,8 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa return KVal; } + +// _S2 TODO dk KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey) { // _S2 not finished yet - needs deadkeys... int count; @@ -362,7 +369,7 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa return KeyV; } - +// _S2 TODO dk /*KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD VK_US) { KMX_DWORD VK_underlying; for( int i=0; i< (int)All_Vector[0].size()-1 ;i++) { @@ -426,32 +433,7 @@ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { return str; }*/ -std::vector mac_createVectorOfKeyboard( int shiftstate, const UCKeyboardLayout * keyboard_layout) { - - std::vector dw_vec; - - for ( int i=0; i < 49; i++) { - - std::vector keyval; - keyval.push_back(i); - keyval.push_back(i); - std::u16string str16 = mac_get_character_From_Keycode(keyval, shiftstate, keyboard_layout); - dw_vec.push_back((KMX_DWORD) *str16.c_str()); - } - - // _S2 can go later - for ( int k=0; k< dw_vec.size();k++) { - printf("%i,\t", dw_vec[k]); - } - printf("\n"); - - for ( int k=0; k< dw_vec.size();k++) { - printf("%c,\t", (char) dw_vec[k]); - } - printf("\n------------------------------\n"); - return dw_vec; -} //################################################################################################################################################ //################################################################################################################################################ @@ -495,52 +477,66 @@ std::u16string mac_get_character_From_Keycode(std::vector keyval, int shift } -KMX_DWORD mac_get_keyval_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { - - KMX_DWORD in_array[3] = {0,0,0}; +KMX_DWORD mac_get_keyval_From_Keycode_new(int charVal,const UCKeyboardLayout* keyboard_layout , KMX_DWORD shiftstate) { + UInt32 deadkeystate = 0; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; UniChar unicodeString[maxStringlength]; OSStatus status; - int returnint; - for ( int i =0; i < keyval.size(); i++) { + status = UCKeyTranslate(keyboard_layout, charVal ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - status = UCKeyTranslate(keyboard_layout, keyval[i] ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - - if( shiftstate %2 == 1 ) - in_array[i] = (int) unicodeString[0]; // uneven: seperate char -> `e - else - in_array[0] = (int) unicodeString[0]; // even: combine char -> è - } + // If this was a deadkey, append a space + if(deadkeystate !=0) - returnint = in_array[0]*1000 +(int) in_array[1]; - return returnint; + status = UCKeyTranslate(keyboard_layout, 49 ,kUCKeyActionDown, 0, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + + return unicodeString[0]; } -KMX_DWORD mac_get_keyval_From_Keycode(int keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { - + +/* +KMX_DWORD mac_get_keyval_From_Keycode(int keyval, int shiftstate, const UCKeyboardLayout* keyboard_layout ) { + + UInt32 deadkeystate = 0; + UniCharCount maxStringlength = 5; + UniCharCount actualStringlength = 0; + UniChar unicodeString[maxStringlength]; + OSStatus status; + int treat_dk_as_Character = 1; // e.g. ^ = 94 + + //status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + + status = UCKeyTranslate(keyboard_layout, keyval ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + //status = UCKeyTranslate(keyboard_layout, keyval ,kUCKeyActionDown, shiftstate , LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + return unicodeString[0]; +} +*/ + +/*KMX_DWORD mac_get_keyval_From_Keycode_old(int keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { + KMX_DWORD in_array[2] = {0,0}; UInt32 deadkeystate = 0; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; UniChar unicodeString[maxStringlength]; OSStatus status; + int treat_dk_as_Character = 1; // e.g. ^ = 94 int returnint=0; - status = UCKeyTranslate(keyboard_layout, keyval ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - // no deadkey yet - if( shiftstate %2 == 1) - return 0; // _S2 what to return if deadkeys are used?? - else { - in_array[0] = (int) unicodeString[0]; // even: combine char -> è - returnint = in_array[0]; - return returnint; - } + status = UCKeyTranslate(keyboard_layout, keyval ,kUCKeyActionDown, shiftstate + treat_dk_as_Character, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // no deadkey yet + if( shiftstate %2 == 1) + return 0; // _S2 what to return if deadkeys are used?? + else { + in_array[0] = (int) unicodeString[0]; // even: combine char -> è + returnint = in_array[0]; + return returnint; + } return returnint; } - +*/ void printoutKeyboards(v_dw_3D &All_Vector) { printf(" values of US - Values of underlying"); diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 1177221de39..fcc7a13200f 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -15,9 +15,7 @@ std::u16string mac_get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout); -KMX_DWORD mac_get_keyval_From_Keycode(int dk, int ch , int shiftstate); -KMX_DWORD mac_get_keyval_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout); -KMX_DWORD mac_get_keyval_From_Keycode(int keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ); +KMX_DWORD mac_get_keyval_From_Keycode_new(int charVal,const UCKeyboardLayout* keyboard_layout , KMX_DWORD shiftstate); //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### @@ -926,8 +924,6 @@ const UINT mac_USVirtualKeyToScanCode[256] = { bool mac_IsKeymanUsedChar(int KV); //------------------------------ -std::vector mac_createVectorOfKeyboard( int shiftstate, const UCKeyboardLayout * keyboard_layout); - // take deadkey-value (e.g.65106) and return u16string (e.g. '^' ) std::u16string mac_convert_DeadkeyValues_To_U16str(int in); @@ -964,6 +960,10 @@ void printoutKeyboards(v_dw_3D &All_Vector); //################################################################################################################################################ //################################################################################################################################################ +// _S2 need to go +KMX_DWORD X_playWithDK(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal) ; +KMX_DWORD X_playWithDK_one(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal); +KMX_DWORD X_compare_Shiftstates(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); KMX_DWORD X_find_Shiftstates(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); - +KMX_DWORD printout_dk(const UCKeyboardLayout* keyboard_layout);/**/ #endif // KEYMAP_H \ No newline at end of file diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 74988729407..19dd3e0ca60 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -481,8 +481,9 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar // Now that we've collected the key data, we need to // translate it to kmx and append to the existing keyboard //------------------------------------------------------------- - print_All_Entries(rgKey); + // _S2 needs to go + //print_All_Entries(rgKey); if ( ! run_verify_S2(rgKey)) printf(" \n::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG ENTRIES ::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); else @@ -507,7 +508,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar //} LPKMX_KEY kkp = gp->dpKeyArray; - //_S2 + //_S2 deadkeys /*for(UINT j = 0; j < gp->cxKeyArray; j++, kkp++) { nDeadkey = std::max(nDeadkey, KMX_GetMaxDeadkeyIndex(kkp->dpContext)); nDeadkey = std::max(nDeadkey, KMX_GetMaxDeadkeyIndex(kkp->dpOutput)); @@ -695,7 +696,7 @@ const int CODE__SIZE[] = { }; - +// _S2 need to go void print_entries_S2(int i, std::vector rgKey , std::string comp1,std::string comp2,std::string erg) { std::string b0 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 0 )); @@ -776,15 +777,13 @@ bool run_verify_S2(std::vector rgKey) { allOK = verify_entries_S2(90, rgKey, 89+32,89,89,89) && allOK; allOK = verify_entries_S2(186, rgKey, 246,214,214,214) && allOK; - //allOK = verify_entries_S2(187, rgKey, 180,180,96,96) && allOK; // dk ´ ` - allOK = verify_entries_S2(187, rgKey, 0,0,0,0) && allOK; // dk ´ ` + allOK = verify_entries_S2(187, rgKey, 180,180,96,96) && allOK; // dk ´ ` allOK = verify_entries_S2(188, rgKey, 44,44,59,59) && allOK; allOK = verify_entries_S2(189, rgKey, 223,223,63,63) && allOK; allOK = verify_entries_S2(190, rgKey, 46,46,58,58) && allOK; allOK = verify_entries_S2(191, rgKey, 45,45,95,95) && allOK; - //allOK = verify_entries_S2(192, rgKey, 94,94,176,176) && allOK; // dk ^ ° - allOK = verify_entries_S2(192, rgKey, 0,0,176,176) && allOK; // dk ^ ° + allOK = verify_entries_S2(192, rgKey, 94,94,176,176) && allOK; // dk ^ ° allOK = verify_entries_S2(219, rgKey, 252,220,220,220) && allOK; allOK = verify_entries_S2(220, rgKey, 35,35,39,39) && allOK; allOK = verify_entries_S2(221, rgKey, 43,43,42,42) && allOK; diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 8cf43d46305..e46dcb8c185 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -326,7 +326,7 @@ struct KMX_dkidmap { KMX_WCHAR src_deadkey, dst_deadkey; }; -/*KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { +KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { LPKMX_GROUP gp; LPKMX_KEY kp; LPKMX_STORE sp; @@ -374,15 +374,15 @@ struct KMX_dkidmap { s_dkids = (KMX_dkidmap*) realloc(s_dkids, sizeof(KMX_dkidmap) * (s_ndkids+1)); s_dkids[s_ndkids].src_deadkey = deadkey; return s_dkids[s_ndkids++].dst_deadkey = s_next_dkid = ++dkid; -}*/ +} void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout,v_dw_2D dk_Table) { - /* KMX_WORD deadkeys[512], *pdk; + KMX_WORD deadkeys[512], *pdk; // Lookup the deadkey table for the deadkey in the physical keyboard // Then for each character, go through and map it through KMX_WCHAR dkid = mac_KMX_GetUniqueDeadkeyID(kbd, deadkey); - +/* // Add the deadkey to the mapping table for use in the import rules phase KMX_DeadkeyMapping KMX_deadkeyMapping = { deadkey, dkid, shift, vk_US}; // I4353 @@ -437,7 +437,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int wprintf(L"ERROR: can't Initialize GDK\n"); return FALSE; } - // _S2 deadkeys do not work yet - some result in 24(x18) + // _S2 deadkeys do not work yet - some result in 24(x18) ( this is key 10; key 24) // create vector that contains Keycode, base, shift for US-Keyboard and underlying keyboard v_dw_3D All_Vector; if(mac_createOneVectorFromBothKeyboards(All_Vector, keyboard_layout)){ @@ -473,9 +473,11 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int switch(ch) { case 0x0000: break; // _S2 ToDo - case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout , dk_Table); break; + case 0xFFFF: + mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout , dk_Table); break; // _S2 ToDo non-dk OK, but all others not - default: mac_KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); + default: + mac_KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); } } } @@ -485,6 +487,18 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int // _S2 has to go later /*KMX_DWORD out = X_find_Shiftstates(0, keyboard_layout,12) ;*/ //KMX_DWORD out2= X_find_Shiftstates(0, keyboard_layout,0) ; + //KMX_DWORD out4= X_compare_Shiftstates(0, keyboard_layout,0) ; + //KMX_DWORD out3 = printout_dk(keyboard_layout); + //KMX_DWORD out5= X_playWithDK(0, keyboard_layout,0) ; + KMX_DWORD out6; + for ( int i= 0; i<50;i++) { + out6= X_playWithDK_one(i, keyboard_layout,8) ; + printf( " key-nr : %i gives char: %i(%c)\n", i, out6,out6); + } + for ( int i= 0; i<16;i++) { + out6= X_playWithDK_one(24, keyboard_layout,i) ; + printf( " key-nr : 24 ss %i gives char: %i(%c)\n",i, out6,out6); + } if(!mac_KMX_ImportRules(kbd, All_Vector, &keyboard_layout, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 return FALSE; From 0ebc1013af5af49cf5453b34871ccf2c0d113795 Mon Sep 17 00:00:00 2001 From: Sabine Date: Mon, 6 May 2024 21:22:58 +0200 Subject: [PATCH 17/71] feat(mac): mac_KMX_ConvertDeadkey mostly finished feat(mac): adapt mac_KMX_get_KeyVal_From_KeyCode to use for dk feat(mac): adapted mac_KMX_ConvertDeadkey feat(mac): tidy up --- mac/mcompile/deadkey.cpp | 4 +- mac/mcompile/deadkey.h | 2 +- mac/mcompile/keymap.cpp | 91 +++++++++++++++++++++++--------- mac/mcompile/keymap.h | 23 ++++---- mac/mcompile/mc_import_rules.cpp | 3 +- mac/mcompile/mcompile.cpp | 84 +++++++++++++++-------------- mac/mcompile/mcompile.h | 2 +- 7 files changed, 127 insertions(+), 82 deletions(-) diff --git a/mac/mcompile/deadkey.cpp b/mac/mcompile/deadkey.cpp index bf27bdb8a84..edb2e5b6535 100755 --- a/mac/mcompile/deadkey.cpp +++ b/mac/mcompile/deadkey.cpp @@ -78,7 +78,7 @@ void mac_refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector &dkVec, std::vector 0 is then propagated to ... mac_KMX_ToUnicodeEx (-> rc=0) .. ImportRules (rc=0-> do nothing ) ) @@ -209,6 +220,26 @@ int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, in return 0; } +int mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps, UInt32 &deadkeystate) { + + UniCharCount maxStringlength = 5; + UniCharCount actualStringlength = 0; + UniChar unicodeString[maxStringlength]; + int Keycode_Spacebar =49; + OSStatus status; + + // _S2 bette solution for 4*CAPS ???? + status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + + // If this was a deadkey, append a space + if(deadkeystate !=0) { + status = UCKeyTranslate(keyboard_layout, Keycode_Spacebar ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + } + + return (int) unicodeString[0]; +} + + // _S2 TODO dk/non-dk int mac_KMX_get_KeyVal_underlying_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { // _S2 not finished yet - needs deadkeys... @@ -234,6 +265,8 @@ int mac_KMX_get_KeyVal_underlying_From_KeyCode(const UCKeyboardLayout * keyboard return returnint; } + +// _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk? /*int mac_KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps) { GdkModifierType consumed; @@ -338,53 +371,64 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa return KVal; } - -// _S2 TODO dk +// _S2 TODO VKShiftstate KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey) { - // _S2 not finished yet - needs deadkeys... - int count; + PKMX_WCHAR dky=NULL; + UInt32 isdk=0; if (!keyboard_layout) return 0; -/* + +/*// _S2 needed? + int count; if (!(mac_map_VKShiftState_to_MacModifier(VKShiftState) <= count)) return 0; -*/ + if (!(KC_underlying <= keycode_max)) return 0; + */ - KMX_DWORD KeyV = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, KC_underlying, ShiftState(mac_map_VKShiftState_to_MacModifier(VKShiftState)), 0); + // _S2 VKShiftstate!!!! + KMX_DWORD KeyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, KC_underlying, ShiftState(mac_map_VKShiftState_to_MacModifier(VKShiftState)), 0, isdk); - // _S2 not finished - needs deadlkeys - /*if ((KeyV >= deadkey_min) && (KeyV <= deadkey_max) ){ // deadkey + // if there was a dk return 0xFFFF and copy dk into dky + if( isdk !=0) { dky = (PKMX_WCHAR) (mac_convert_DeadkeyValues_To_U16str((int) KeyV)).c_str(); *DeadKey = *dky; return 0xFFFF; } - else if((KeyV > deadkey_max) || ((KeyV < deadkey_min) && ( KeyV > 0xFF))) // out of range - return 0xFFFE; - else // usable char - return KeyV;*/ - - return KeyV; + return KeyV; } + // _S2 TODO dk -/*KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD VK_US) { - KMX_DWORD VK_underlying; +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD Keyval_US) { + KMX_DWORD VK_underlying; for( int i=0; i< (int)All_Vector[0].size()-1 ;i++) { for( int j=1; j< (int)All_Vector[0][0].size();j++) { - if ( ( All_Vector[0][i][j] == VK_US ) ) { + if ( All_Vector[0][i][j] == Keyval_US ) { VK_underlying = All_Vector[1][i][j]; return VK_underlying; } } } - return VK_US; -}*/ + return Keyval_US; +} + +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vector, KMX_DWORD KV_Underlying) { + for( int i=0; i< (int)All_Vector[1].size()-1 ;i++) { + for( int j=1; j< (int)All_Vector[1][0].size();j++) { + if ( All_Vector[1][i][j] == KV_Underlying ) { + return All_Vector[1][i][0]; + } + } + } + return KV_Underlying; +} KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_DWORD KC_US, ShiftState ss, int caps) { KMX_DWORD KC_underlying; + // _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk? std::u16string u16str = mac_convert_DeadkeyValues_To_U16str(mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, KC_US, ss, caps)); for( int i=0; i< (int)All_Vector[1].size()-1 ;i++) { @@ -399,7 +443,7 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * } UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS) { - uint ret= (mac_USVirtualKeyToScanCode[VirtualKeyUS]); + uint ret= (mac_USVirtualKeyToScanCode[VirtualKeyUS]); // _S2 can go later return (mac_USVirtualKeyToScanCode[VirtualKeyUS]); } @@ -455,6 +499,7 @@ std::u16string mac_get_character_From_Keycode(int dk, int ch , int shiftstate) { return character; } + std::u16string mac_get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { char16_t ch_array[3] = {L'\0'}; UInt32 deadkeystate = 0; @@ -476,7 +521,6 @@ std::u16string mac_get_character_From_Keycode(std::vector keyval, int shift return returnString; } - KMX_DWORD mac_get_keyval_From_Keycode_new(int charVal,const UCKeyboardLayout* keyboard_layout , KMX_DWORD shiftstate) { UInt32 deadkeystate = 0; @@ -495,8 +539,7 @@ KMX_DWORD mac_get_keyval_From_Keycode_new(int charVal,const UCKeyboardLayout* k return unicodeString[0]; } -/* -KMX_DWORD mac_get_keyval_From_Keycode(int keyval, int shiftstate, const UCKeyboardLayout* keyboard_layout ) { +/* KMX_DWORD mac_get_keyval_From_Keycode(int keyval, int shiftstate, const UCKeyboardLayout* keyboard_layout ) { UInt32 deadkeystate = 0; UniCharCount maxStringlength = 5; diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index fcc7a13200f..53d14b320aa 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -85,9 +85,9 @@ typedef std::vector > > v_dw_3D; static KMX_DWORD returnIfCharInvalid = 0; static KMX_DWORD max_shiftstate = 2; // _S2 only base+Shift -static KMX_DWORD keycode_max = 94; -static KMX_DWORD deadkey_min = 0xfe50; -static KMX_DWORD deadkey_max = 0xfe93; +static KMX_DWORD keycode_max = 94; // _S2 needed?? +static KMX_DWORD deadkey_min = 0xfe50; // _S2 needed?? +static KMX_DWORD deadkey_max = 0xfe93; // _S2 needed?? //static KMX_DWORD deadkey_max = 0xfe52; // _S2 TOP_6 TODO This has to go! my test: to only return 3 dk // map Shiftstate to modifier (e.g. 0->0; ) @@ -652,10 +652,6 @@ const UINT mac_ScanCodeToUSVirtualKey[128] = { 115 // L"K_?00", // &H73 }; - - - - // _S2 what instead x999? //( on character-.st index we find the keycode e.g. // for character A (65) we look at pos 65 and find keycode 0 @@ -928,7 +924,9 @@ bool mac_IsKeymanUsedChar(int KV); std::u16string mac_convert_DeadkeyValues_To_U16str(int in); // use gdk_keymap_translate_keyboard_state to get keyval - base function to get keyvals +// _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk only? int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int ss, int caps); +int mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps, UInt32 &deadkeystate_ret); // use mac_KMX_get_KeyVal_From_KeyCode and prevent use of certain keycodes KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int keycode, int shift_state_pos); @@ -939,6 +937,9 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa // use Vector to return the Keyval of underlying Keyboard KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D &All_Vector,KMX_DWORD VK_underlying); +// use Vector to return the Scancode of underlying Keyboard +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vector, KMX_DWORD KV_Underlying); + // use Vector to return the Keycode of the underlying Keyboard for given VK_US using GDK KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector,KMX_DWORD KC_US, ShiftState ss, int caps); @@ -951,16 +952,12 @@ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); // convert codePoint to u16string std::u16string mac_CodePointToU16String(unsigned int codepoint); - -void printoutKeyboards(v_dw_3D &All_Vector); - - - - //################################################################################################################################################ //################################################################################################################################################ // _S2 need to go + +void printoutKeyboards(v_dw_3D &All_Vector); KMX_DWORD X_playWithDK(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal) ; KMX_DWORD X_playWithDK_one(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal); KMX_DWORD X_compare_Shiftstates(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 19dd3e0ca60..c51deed9271 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -88,7 +88,7 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, i //rc>0: character //rc==0: no translation //rc<0: dk - +// _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk ? KMX_DWORD KeyVal= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode, mac_map_VKShiftState_to_MacModifier(ShiftState(shift_state_pos)), caps); // _S2 ToDo non-dk OK, but all others not @@ -386,6 +386,7 @@ class mac_KMX_VirtualKey { return n; }*/ +// _S2 need to go void print_All_Entries(std::vector rgKey); bool run_verify_S2(std::vector rgKey); diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index e46dcb8c185..9476484c36f 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -45,12 +45,12 @@ std::vector KMX_FDeadkeys; // I4353 #if defined(_WIN32) || defined(_WIN64) int wmain(int argc, wchar_t* argv[]) { std::vector str_argv_16 = convert_argvW_to_Vector_u16str( argc, argv); - mac_run(argc, str_argv_16); + run(argc, str_argv_16); #elif ((__linux__) || (__unix__ )) // LINUX, UNIX int main(int argc, char* argv[]) { std::vector str_argv_16 = convert_argv_to_Vector_u16str(argc, argv); - mac_run(argc, str_argv_16, argv); + run(argc, str_argv_16, argv); #elif (__APPLE__ && TARGET_OS_MAC) #include @@ -160,9 +160,9 @@ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NU // _S2 is this correct?? which SS ??? // Map of all shift states that we will work with -const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCTRLFLAG|RALTFLAG, 0xFFFF}; +//const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCTRLFLAG|RALTFLAG, 0xFFFF}; //const UINT VKShiftState[] = {0, 2, 4,6, 0xFFFF}; -//const UINT VKShiftState[] = {0, 2, 8,10, 0xFFFF}; +const UINT VKShiftState[] = {0, 2, 8,10, 0xFFFF}; // @@ -172,6 +172,7 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCT // correct shift state and key. Adjust the LCTRL+RALT -> RALT if necessary // void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { + //_S2 do we translate here or is this the reason for Shift + K_A <-> Shift 'a' ??? // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. @@ -233,7 +234,7 @@ void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { } } -/*void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { +void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { // _S2 TOP_2 INFO this produces a different output due to different layouts for Lin<-> win ( for the same language!!) if((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) { @@ -262,23 +263,23 @@ void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { key->dpContext = context; key->Key = vk; } -}*/ +} -/*void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group,KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { +void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group,KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { for(unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_TranslateDeadkeyKey(&group->dpKeyArray[i], deadkey, vk, shift, ch); } -}*/ +} -/*void mac_KMX_TranslateDeadkeyKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { +void mac_KMX_TranslateDeadkeyKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { if(kbd->dpGroupArray[i].fUsingKeys) { mac_KMX_TranslateDeadkeyGroup(&kbd->dpGroupArray[i], deadkey, vk, shift, ch); } } -}*/ +} -/*void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift) { +void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. @@ -306,7 +307,7 @@ void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { if(i == kbd->StartGroup[1]) break; // If this is the initial group, that's all we need to do. } } -}*/ +} KMX_WCHAR mac_KMX_ScanXStringForMaxDeadkeyID(PKMX_WCHAR str) { KMX_WCHAR dkid = 0; @@ -382,21 +383,23 @@ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_ // Lookup the deadkey table for the deadkey in the physical keyboard // Then for each character, go through and map it through KMX_WCHAR dkid = mac_KMX_GetUniqueDeadkeyID(kbd, deadkey); -/* + // Add the deadkey to the mapping table for use in the import rules phase KMX_DeadkeyMapping KMX_deadkeyMapping = { deadkey, dkid, shift, vk_US}; // I4353 KMX_FDeadkeys.push_back(KMX_deadkeyMapping); //dkid, vk, shift); // I4353 mac_KMX_AddDeadkeyRule(kbd, dkid, vk_US, shift); - mac_KMX_GetDeadkeys(dk_Table, deadkey, pdk = deadkeys, keymap); // returns array of [usvk, ch_out] pairs + // creates array [a,e,i,o,u][shiftstate][combined for a+dk e.g. â ] + KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying( All_Vector, (KMX_DWORD) deadkey); + mac_KMX_GetDeadkeys( sc_dk, pdk = deadkeys, keyboard_layout); // returns array of [usvk, ch_out] pairs while(*pdk) { // Look up the ch UINT KeyValUnderlying = mac_KMX_get_KeyValUnderlying_From_KeyValUS(All_Vector, *pdk); mac_KMX_TranslateDeadkeyKeyboard(kbd, dkid, KeyValUnderlying, *(pdk+1), *(pdk+2)); pdk+=3; - }*/ + } } KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { @@ -437,7 +440,6 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int wprintf(L"ERROR: can't Initialize GDK\n"); return FALSE; } - // _S2 deadkeys do not work yet - some result in 24(x18) ( this is key 10; key 24) // create vector that contains Keycode, base, shift for US-Keyboard and underlying keyboard v_dw_3D All_Vector; if(mac_createOneVectorFromBothKeyboards(All_Vector, keyboard_layout)){ @@ -457,10 +459,9 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int // Loop through each possible key on the keyboard for (int i = 0;KMX_VKMap[i]; i++) { // I4651 - // windows uses VK, Linux, mac use SC/Keycode + // windows uses VK, Linux and macOS use SC/Keycode // _S2 ToDo unused vk`s ?? UINT scUnderlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_VKMap[i]); - // _S2 ToDo non-dk OK, but all others not KMX_WCHAR ch = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, VKShiftState[j], scUnderlying, &DeadKey); //wprintf(L"--- VK_%d -> SC_ [%c] dk=%d ( ss %i) \n", KMX_VKMap[i], ch == 0 ? 32 : ch, DeadKey, VKShiftState[j]); @@ -473,19 +474,16 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int switch(ch) { case 0x0000: break; // _S2 ToDo - case 0xFFFF: - mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout , dk_Table); break; - // _S2 ToDo non-dk OK, but all others not - default: - mac_KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); + case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout , dk_Table); break; + default: mac_KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); } } } // _S2 ToDo non-dk OK, but all others are not mac_KMX_ReportUnconvertedKeyboardRules(kbd); - // _S2 has to go later - /*KMX_DWORD out = X_find_Shiftstates(0, keyboard_layout,12) ;*/ + /*// _S2 has to go later + KMX_DWORD out = X_find_Shiftstates(0, keyboard_layout,12) ; //KMX_DWORD out2= X_find_Shiftstates(0, keyboard_layout,0) ; //KMX_DWORD out4= X_compare_Shiftstates(0, keyboard_layout,0) ; //KMX_DWORD out3 = printout_dk(keyboard_layout); @@ -498,7 +496,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int for ( int i= 0; i<16;i++) { out6= X_playWithDK_one(24, keyboard_layout,i) ; printf( " key-nr : 24 ss %i gives char: %i(%c)\n",i, out6,out6); - } + }*/ if(!mac_KMX_ImportRules(kbd, All_Vector, &keyboard_layout, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 return FALSE; @@ -507,28 +505,32 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int return TRUE; } -/* int mac_KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap) { +int mac_KMX_GetDeadkeys( KMX_WORD DeadKey, KMX_WORD *OutputPairs, const UCKeyboardLayout * keyboard_layout) { + UniCharCount maxStringlength = 5; + UniCharCount actualStringlength = 0; + UniChar unicodeString[maxStringlength]; KMX_WORD *p = OutputPairs; - KMX_DWORD shift; - - v_dw_2D dk_SingleTable; - mac_query_dk_combinations_for_specific_dk(&dk_Table, dk_SingleTable, DeadKey); - for ( int i=0; i< (int) dk_SingleTable.size();i++) { - KMX_WORD vk = mac_KMX_changeKeynameToCapital(dk_SingleTable[i][1], shift, keymap); - if(vk != 0) { - *p++ = vk; - *p++ = shift; - *p++ = dk_SingleTable[i][2]; - } - else { - mac_KMX_LogError(L"Warning: complex deadkey not supported."); + UInt32 deadkeystate = 0; + OSStatus status; + KMX_DWORD shift=0; + + for ( int i=0; i< 50;i++) { + status = UCKeyTranslate(keyboard_layout, DeadKey ,kUCKeyActionDown, shift, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if(deadkeystate !=0) { + status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, shift, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if(deadkeystate !=0) { + KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, i, 1); + *p++ = vk; + *p++ = shift; + *p++ =unicodeString[0];; + } } } *p = 0; return (p-OutputPairs); } -*/ + void mac_KMX_LogError(const wchar_t* fmt, ...) { WCHAR fmtbuf[256]; diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 46eea28e6a0..c4018310917 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -45,7 +45,7 @@ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); -//int mac_KMX_GetDeadkeys(v_dw_2D & dk_Table, KMX_WORD DeadKey, KMX_WORD *OutputPairs, GdkKeymap* keymap); +int mac_KMX_GetDeadkeys( KMX_WORD DeadKey, KMX_WORD *OutputPairs, const UCKeyboardLayout * keyboard_layout); void mac_KMX_LogError(const wchar_t* fmt, ...); From 6d0bb71f6e3472c1b1219ffdcfedd0f64c864614 Mon Sep 17 00:00:00 2001 From: Sabine Date: Tue, 7 May 2024 16:55:16 +0200 Subject: [PATCH 18/71] Revert "feat(mac): adapt mac_KMX_get_KeyVal_From_KeyCode to use for dk" This reverts commit 4aa217266fc3812b182aa71077c39bec237165a9. # Conflicts: # mac/mcompile/keymap.cpp feat(mac): tidy up --- mac/mcompile/keymap.cpp | 2 -- mac/mcompile/mcompile.cpp | 8 +++----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index cf824feda82..5b4c71cbd34 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -239,7 +239,6 @@ int mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, return (int) unicodeString[0]; } - // _S2 TODO dk/non-dk int mac_KMX_get_KeyVal_underlying_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { // _S2 not finished yet - needs deadkeys... @@ -265,7 +264,6 @@ int mac_KMX_get_KeyVal_underlying_From_KeyCode(const UCKeyboardLayout * keyboard return returnint; } - // _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk? /*int mac_KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps) { diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 9476484c36f..3121c2a448a 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -197,13 +197,13 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) } } - void mac_KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { +void mac_KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { for(unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_TranslateKey(&group->dpKeyArray[i], vk, shift, ch); } } - void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { +void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { if(kbd->dpGroupArray[i].fUsingKeys) { mac_KMX_TranslateGroup(&kbd->dpGroupArray[i], vk, shift, ch); @@ -211,7 +211,6 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) } } - void mac_KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { if(key->ShiftFlags == 0) { // mac_KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); @@ -473,7 +472,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int } switch(ch) { case 0x0000: break; - // _S2 ToDo + // _S2 ToDo for all shiftstates... case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout , dk_Table); break; default: mac_KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); } @@ -531,7 +530,6 @@ int mac_KMX_GetDeadkeys( KMX_WORD DeadKey, KMX_WORD *OutputPairs, const UCKeyboa return (p-OutputPairs); } - void mac_KMX_LogError(const wchar_t* fmt, ...) { WCHAR fmtbuf[256]; const wchar_t* end = L"\0"; From 456b851366b5a1b02886cbd5387e3a4f32585d01 Mon Sep 17 00:00:00 2001 From: Sabine Date: Tue, 7 May 2024 17:04:49 +0200 Subject: [PATCH 19/71] feat(mac): set dk to 0 --- mac/mcompile/keymap.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 5b4c71cbd34..aa729dd3cac 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -396,6 +396,7 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa *DeadKey = *dky; return 0xFFFF; } + *DeadKey= 0; return KeyV; } From 08a51b992e5740d64599804496df1bc0dc14f29b Mon Sep 17 00:00:00 2001 From: SabineSIL <86713187+SabineSIL@users.noreply.github.com> Date: Tue, 7 May 2024 17:25:51 +0200 Subject: [PATCH 20/71] Delete mac/mcompile/x.bla --- mac/mcompile/x.bla | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 mac/mcompile/x.bla diff --git a/mac/mcompile/x.bla b/mac/mcompile/x.bla deleted file mode 100644 index e69de29bb2d..00000000000 From 7eca5cb128f43a843f8fb1db0d69cf506b446c41 Mon Sep 17 00:00:00 2001 From: SabineSIL <86713187+SabineSIL@users.noreply.github.com> Date: Tue, 7 May 2024 17:29:57 +0200 Subject: [PATCH 21/71] Delete mac/mcompile/X_helpers.h --- mac/mcompile/X_helpers.h | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 mac/mcompile/X_helpers.h diff --git a/mac/mcompile/X_helpers.h b/mac/mcompile/X_helpers.h deleted file mode 100644 index 0897afb8671..00000000000 --- a/mac/mcompile/X_helpers.h +++ /dev/null @@ -1,6 +0,0 @@ - -#pragma once -#ifndef X_HELPERS_H -#define X_HELPERS_H - -#endif //X_HELPERS_H \ No newline at end of file From b90abe67618cdbc93aef75d753490982cdf99ad7 Mon Sep 17 00:00:00 2001 From: Sabine Date: Mon, 13 May 2024 20:37:49 +0200 Subject: [PATCH 22/71] feat(mac): dk: mapping of shiftstates --- mac/mcompile/keymap.cpp | 36 ++++++++--------- mac/mcompile/keymap.h | 22 ++++++----- mac/mcompile/mc_import_rules.cpp | 21 +++++----- mac/mcompile/mcompile.cpp | 66 +++++++++++++++++++------------- mac/mcompile/mcompile.h | 4 +- 5 files changed, 81 insertions(+), 68 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index aa729dd3cac..6ab51d02cdf 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -1,24 +1,21 @@ #include "keymap.h" -// _S2 why not have 0,2,8,10 directly in VKShiftState ?? -// base, shift, OPT, shift+OPT, FF +// Base, Shift, OPT, Shift+OPT int mac_map_VKShiftState_to_MacModifier(int VKShiftState) { - if (VKShiftState == 0 ) return 0; // 0000 0000 - else if (VKShiftState == 1) return 2; // 0000 0010 - // else if (VKShiftState == 3) return 3; // 0000 0011 - // else if (VKShiftState == 4) return 4; // 0000 0100 - // else if (VKShiftState == 5) return 4; // 0000 0101 - else if (VKShiftState == 6 ) return 8; // 0000 0110 - else if (VKShiftState == 7) return 10; // 0000 0111 - // else if (VKShiftState == 8) return 4; // 0000 1000 - // else if (VKShiftState == 9) return 4; // 0000 1001 - - - else if (VKShiftState == 16) return 10; // 0000 0111 - else if (VKShiftState == 9) return 2; // 0000 0111 - else if (VKShiftState == 25) return 8; // 0000 0111 - - else return 99; // _S2 what to return if no match?? + if (VKShiftState == 0 ) return 0; // 0000 0000 + else if (VKShiftState == 16) return 2; // 0000 0111 + else if (VKShiftState == 9) return 8; // 0000 0111 + else if (VKShiftState == 25) return 10; // 0000 0111 + else return VKShiftState; // _S2 what to return if no match?? +} + +// Base, Shift, OPT, Shift+OPT +int mac_map_ShiftState_to_MacModifier(int ShiftState) { + if (ShiftState == 0 ) return 0; // 0000 0000 + else if (ShiftState == 1) return 2; // 0000 0010 + else if (ShiftState == 6 ) return 8; // 0000 0110 + else if (ShiftState == 7) return 10; // 0000 0111 + else return ShiftState; //;return 999; // _S2 what to return if no match?? } int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { @@ -387,8 +384,7 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa return 0; */ - // _S2 VKShiftstate!!!! - KMX_DWORD KeyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, KC_underlying, ShiftState(mac_map_VKShiftState_to_MacModifier(VKShiftState)), 0, isdk); + KMX_DWORD KeyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, KC_underlying, (mac_map_VKShiftState_to_MacModifier(VKShiftState)), 0, isdk); // if there was a dk return 0xFFFF and copy dk into dky if( isdk !=0) { diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 53d14b320aa..a2ad0151ab0 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -90,24 +90,17 @@ static KMX_DWORD deadkey_min = 0xfe50; // _S2 needed?? static KMX_DWORD deadkey_max = 0xfe93; // _S2 needed?? //static KMX_DWORD deadkey_max = 0xfe52; // _S2 TOP_6 TODO This has to go! my test: to only return 3 dk -// map Shiftstate to modifier (e.g. 0->0; ) +// map VKShiftstate to modifier (use 0,2,4,8,10 instead of 0,16,9,25 ) int mac_map_VKShiftState_to_MacModifier(int VKShiftState); -// take a std::string (=contents of line symbols-file ) and returns the (int) value of the character -KMX_DWORD mac_convertNamesTo_DWORD_Value(std::string tok_str); +// map ShiftState to modifier (use 0,2,4,8,10 instead of Base, Shft, Opt, Sh+Opt ) +int mac_map_ShiftState_to_MacModifier(int ShiftState); // create a Vector with all entries of both keymaps int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLayout * keykeyboard_layout); // read configuration file, split and write to 3D-Vector (Data for US on Vector[0][ ][ ] ) int mac_write_US_ToVector(v_dw_3D &vec); - -// 1. step: read complete Row of Configuration file US -bool mac_createCompleteRow_US(v_str_1D &complete_List, FILE *fpp, const char *text, std::string language); - -// replace Name of Key (e.g. ) wih Keycode ( e.g. 15 ) -int mac_replace_KeyName_with_Keycode(std::string in); - // create an empty 2D vector containing 0 in all fields v_dw_2D mac_create_empty_2D_Vector(int dim_rows, int dim_shifts); @@ -957,6 +950,15 @@ std::u16string mac_CodePointToU16String(unsigned int codepoint); // _S2 need to go +// replace Name of Key (e.g. ) wih Keycode ( e.g. 15 ) +int mac_replace_KeyName_with_Keycode(std::string in); + +// take a std::string (=contents of line symbols-file ) and returns the (int) value of the character +KMX_DWORD mac_convertNamesTo_DWORD_Value(std::string tok_str); + +// 1. step: read complete Row of Configuration file US +bool mac_createCompleteRow_US(v_str_1D &complete_List, FILE *fpp, const char *text, std::string language); + void printoutKeyboards(v_dw_3D &All_Vector); KMX_DWORD X_playWithDK(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal) ; KMX_DWORD X_playWithDK_one(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal); diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index c51deed9271..d112a531e05 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -88,8 +88,9 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, i //rc>0: character //rc==0: no translation //rc<0: dk -// _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk ? - KMX_DWORD KeyVal= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode, mac_map_VKShiftState_to_MacModifier(ShiftState(shift_state_pos)), caps); + + // _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk ? + KMX_DWORD KeyVal= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode, mac_map_ShiftState_to_MacModifier(ShiftState(shift_state_pos)), caps); // _S2 ToDo non-dk OK, but all others not std::u16string str = mac_convert_DeadkeyValues_To_U16str(KeyVal); @@ -387,10 +388,10 @@ class mac_KMX_VirtualKey { }*/ // _S2 need to go -void print_All_Entries(std::vector rgKey); +void print_All_Entries_S2(std::vector rgKey); bool run_verify_S2(std::vector rgKey); -bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout,std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 +bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout,std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 mac_KMX_Loader loader; std::vector rgKey; //= new VirtualKey[256]; @@ -449,8 +450,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar KMX_DWORD KC_US = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); for(int caps = 0; caps <= 1; caps++) { - // _S2 shiftstates - // _S2 what is rc for mac? + int rc = mac_KMX_ToUnicodeEx(KC_US, sbBuffer, ss, caps, *keyboard_layout); //rc>0: character //rc==0: no translation @@ -480,11 +480,11 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar //------------------------------------------------------------- // Now that we've collected the key data, we need to - // translate it to kmx and append to the existing keyboard + // translate it to kmx and append to the existing keyboar //------------------------------------------------------------- // _S2 needs to go - //print_All_Entries(rgKey); + //print_All_Entries_S2(rgKey); if ( ! run_verify_S2(rgKey)) printf(" \n::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG ENTRIES ::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); else @@ -649,7 +649,8 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar KMX_WCHAR *p = kkp->dpContext = new KMX_WCHAR[8]; *p++ = UC_SENTINEL; *p++ = CODE_DEADKEY; - // _S2 needs to be in *p++ = mac_KMX_DeadKeyMap(dk->KMX_DeadCharacter(), &alDead, nDeadkey, FDeadkeys); // I4353 + + *p++ = mac_KMX_DeadKeyMap(dk->KMX_DeadCharacter(), &alDead, nDeadkey, FDeadkeys); // I4353 // *p++ = nDeadkey+i; *p++ = UC_SENTINEL; *p++ = CODE_ANY; @@ -734,7 +735,7 @@ bool verify_entries_S2(int i, std::vector rgKey, int res1,i return all_OK; } -void print_All_Entries( std::vector rgKey) { +void print_All_Entries_S2( std::vector rgKey) { for ( int i=48; i<58; i++) print_entries_S2(i, rgKey," ","",""); diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 3121c2a448a..254d9c40bfe 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -155,15 +155,8 @@ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NU //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ - - - -// _S2 is this correct?? which SS ??? // Map of all shift states that we will work with -//const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCTRLFLAG|RALTFLAG, 0xFFFF}; -//const UINT VKShiftState[] = {0, 2, 4,6, 0xFFFF}; -const UINT VKShiftState[] = {0, 2, 8,10, 0xFFFF}; - +const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCTRLFLAG|RALTFLAG, 0xFFFF}; // // TranslateKey @@ -182,7 +175,7 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) if(key->ShiftFlags == 0 && key->Key == ch) { // Key is a mnemonic key with no shift state defined. // Remap the key according to the character on the key cap. - //LogError(L"Converted mnemonic rule on line %d, + '%c' TO + [%x K_%d]", key->Line, key->Key, shift, vk); + //mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO + [%x K_%d]", key->Line, key->Key, shift, vk); key->ShiftFlags = ISVIRTUALKEY | shift; key->Key = vk; } else if(key->ShiftFlags & VIRTUALCHARKEY && key->Key == ch) { @@ -191,7 +184,7 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) // This will not result in 100% wonderful mappings as there could // be overlap, depending on how keys are arranged on the target layout. // But that is up to the designer. - //LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, key->ShiftFlags & ~VIRTUALCHARKEY, vk); + //mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, key->ShiftFlags & ~VIRTUALCHARKEY, vk); key->ShiftFlags &= ~VIRTUALCHARKEY; key->Key = vk; } @@ -377,7 +370,8 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { } void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout,v_dw_2D dk_Table) { - KMX_WORD deadkeys[512], *pdk; + KMX_WORD deadkeys[512]={0}; + KMX_WORD *pdk; // Lookup the deadkey table for the deadkey in the physical keyboard // Then for each character, go through and map it through @@ -390,15 +384,18 @@ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_ mac_KMX_AddDeadkeyRule(kbd, dkid, vk_US, shift); // creates array [a,e,i,o,u][shiftstate][combined for a+dk e.g. â ] - KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying( All_Vector, (KMX_DWORD) deadkey); - mac_KMX_GetDeadkeys( sc_dk, pdk = deadkeys, keyboard_layout); // returns array of [usvk, ch_out] pairs + mac_KMX_GetDeadkeys( deadkey, shift, pdk = deadkeys, All_Vector, keyboard_layout); // returns array of [usvk, ch_out] pairs + + //KMX_WORD deadkeys1[512]={0}; + //KMX_WORD *pdk1; + //bool tt_S2= test_dk_S2(deadkeys, deadkeys1); while(*pdk) { // Look up the ch UINT KeyValUnderlying = mac_KMX_get_KeyValUnderlying_From_KeyValUS(All_Vector, *pdk); mac_KMX_TranslateDeadkeyKeyboard(kbd, dkid, KeyValUnderlying, *(pdk+1), *(pdk+2)); pdk+=3; - } + } } KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { @@ -472,13 +469,12 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int } switch(ch) { case 0x0000: break; - // _S2 ToDo for all shiftstates... case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout , dk_Table); break; default: mac_KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); } } } - // _S2 ToDo non-dk OK, but all others are not + // _S2 ToDo non-dk OK,shifted dk are not mac_KMX_ReportUnconvertedKeyboardRules(kbd); /*// _S2 has to go later @@ -504,7 +500,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int return TRUE; } -int mac_KMX_GetDeadkeys( KMX_WORD DeadKey, KMX_WORD *OutputPairs, const UCKeyboardLayout * keyboard_layout) { +int mac_KMX_GetDeadkeys( KMX_WCHAR DeadKey, UINT shift_dk, KMX_WORD *OutputPairs, v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; @@ -512,17 +508,22 @@ int mac_KMX_GetDeadkeys( KMX_WORD DeadKey, KMX_WORD *OutputPairs, const UCKeyboa KMX_WORD *p = OutputPairs; UInt32 deadkeystate = 0; OSStatus status; - KMX_DWORD shift=0; + KMX_WORD shift[4] ={0,2,8,10}; + int keycount =50; - for ( int i=0; i< 50;i++) { - status = UCKeyTranslate(keyboard_layout, DeadKey ,kUCKeyActionDown, shift, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, shift, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying( All_Vector, (KMX_DWORD) DeadKey); + + for ( int i=0; i < keycount;i++) { + for ( int j=0; j < sizeof(shift)/sizeof(shift[0]); j++) { + status = UCKeyTranslate(keyboard_layout, sc_dk ,kUCKeyActionDown, shift_dk, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { - KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, i, 1); - *p++ = vk; - *p++ = shift; - *p++ =unicodeString[0];; + status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if(deadkeystate !=0) { + KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, i, 1); + *p++ = vk; + *p++ = shift[j]; + *p++ =unicodeString[0]; + } } } } @@ -558,6 +559,19 @@ void mac_KMX_LogError(const wchar_t* fmt, ...) { //################################################################################################################################################ +bool test_dk_S2(KMX_WORD deadkeys[512], KMX_WORD deadkeys1[512]) { + bool tt= true; + KMX_DWORD val, val1; + for ( int i=0; i<512;i++) { + val = deadkeys[i]; + val1 = deadkeys1[i]; + tt= ( (deadkeys[i] == deadkeys1[i]) && tt); + if (!(tt)) + printf("wrong from %i \n",i); + } + return tt; +} + //-------------------------- /*void fun2() { std::cout << "Hier ist fun2 von mcompile.cpp ...\n";} diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index c4018310917..8242e660db5 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -45,15 +45,15 @@ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); -int mac_KMX_GetDeadkeys( KMX_WORD DeadKey, KMX_WORD *OutputPairs, const UCKeyboardLayout * keyboard_layout); +int mac_KMX_GetDeadkeys( KMX_WCHAR deadkey, UINT shift, KMX_WORD *OutputPairs, v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout); // returns array of [usvk, ch_out] pairs void mac_KMX_LogError(const wchar_t* fmt, ...); - //################################################################################################################################################ //################################################################################################################################################ +bool test_dk_S2(KMX_WORD deadkeys[512], KMX_WORD deadkeys1[512]); void fun2(); void testmyFunctions_S2(); #endif // MCOMPILE_H \ No newline at end of file From 86850d555828c39eab0be005683a779deebf4300 Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 15 May 2024 18:49:18 +0200 Subject: [PATCH 23/71] feat(mac): adapt order of keys for getDeadkeys to catch the most important key combinatin for a dk combination --- mac/mcompile/keymap.h | 8 ++--- mac/mcompile/mc_import_rules.cpp | 61 +++++++++++++++++++++++++++++--- mac/mcompile/mcompile.cpp | 43 ++++++++++++++++------ 3 files changed, 93 insertions(+), 19 deletions(-) diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index a2ad0151ab0..aac53669d85 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -110,7 +110,7 @@ int mac_append_underlying_ToVector(v_dw_3D &All_Vector, const UCKeyboardLayout * // initialize UCHR bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout); //------------------------------ - +/* const UINT USVirtualKeyToScanCode[256] = { 0x00, // L"K_?00", // &H0 0x00, // L"K_LBUTTON", // &H1 @@ -509,7 +509,7 @@ const UINT ScanCodeToUSVirtualKey[128] = { 0x6c, // 0x7e => K_SEPARATOR 0x00 // 0x7f => No match }; - +*/ // _S2 many keys still need to be defined !! //( on x. place there is key e.g. // on (US) position 24 we find key xBB ( = + ) @@ -746,7 +746,7 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, //0x5B, // L"K_?5B", // &H5B 0x999, //0x5C, // L"K_?5C", // &H5C 0x999, //0x5D, // L"K_?5D", // &H5D - 0x999, //0x00, // L"K_?5E", // &H5E + 10, //0x00, // L"K_?5E", // &H5E 0x999, //0x5F, // L"K_?5F", // &H5F 0x999, //0x52, // L"K_NP0", // &H60 0x999, //0x4F, // L"K_NP1", // &H61 @@ -875,7 +875,7 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0x2A, // L"K_BKSLASH", // &HDC 0x1E, // L"K_RBRKT", // &HDD 0x27, // L"K_QUOTE", // &HDE - 0x32, // L"K_oDF", // &HDF // MCD 01-11-02: Brazilian fix: 00 -> 73 + 27, // L"K_oDF", // &HDF // MCD 01-11-02: Brazilian fix: 00 -> 73 0x999, //0x00, // L"K_oE0", // &HE0 0x999, //0x00, // L"K_oE1", // &HE1 50, //0x56, // L"K_oE2", // &HE2 diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index d112a531e05..b003c510786 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -391,6 +391,8 @@ class mac_KMX_VirtualKey { void print_All_Entries_S2(std::vector rgKey); bool run_verify_S2(std::vector rgKey); +void print_All_Keys(const UCKeyboardLayout * keyboard_layout); +void print_certain_Keys(const UCKeyboardLayout * keyboard_layout, int keycode); bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout,std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 mac_KMX_Loader loader; @@ -442,10 +444,10 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar continue; } - // //_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! - // if(ss == MenuCtrl|| ss == ShftMenuCtrl) { - // continue; - // } + //_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! + if(ss == MenuCtrl|| ss == ShftMenuCtrl) { + continue; + } // _S2 ToDo what about not used keys?? KMX_DWORD KC_US = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); @@ -485,6 +487,9 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar // _S2 needs to go //print_All_Entries_S2(rgKey); + //print_All_Keys( * keyboard_layout); + //print_certain_Keys( * keyboard_layout, 10); + if ( ! run_verify_S2(rgKey)) printf(" \n::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG ENTRIES ::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); else @@ -757,6 +762,54 @@ void print_All_Entries_S2( std::vector rgKey) { print_entries_S2(226, rgKey, "<", ">", "< < > >"); } +void print_certain_Keys(const UCKeyboardLayout * keyboard_layout, int keycode) { + UniCharCount maxStringlength = 5; + UniCharCount actualStringlength = 0; + UniChar unicodeString[maxStringlength]; + UInt32 deadkeystate = 0; + OSStatus status; + int shiftarray[] ={0,2,8,10}; + + for(int k=0; k<2;k++) { + for(int j=0; j<4;j++) { + status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if(deadkeystate ==0) + printf(" key nr %i , ss %i has values %i(%c)\n", keycode, shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); + // If this was a deadkey, append a space + if(deadkeystate !=0) { + status = UCKeyTranslate(keyboard_layout, 49 ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + printf(" dk key nr %i , ss %i has values %i(%c)\n", keycode,shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); + } + } + } +} + + +void print_All_Keys(const UCKeyboardLayout * keyboard_layout){ + UniCharCount maxStringlength = 5; + UniCharCount actualStringlength = 0; + UniChar unicodeString[maxStringlength]; + UInt32 deadkeystate = 0; + OSStatus status; + int shiftarray[] ={0,2,8,10}; + + for(int k=0; k<2;k++) { + for(int j=0; j<4;j++) { + for(int i=0; i<50;i++) { + status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if(deadkeystate ==0) + printf(" key nr %i , ss %i has values %i(%c)\n", i, shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); + // If this was a deadkey, append a space + if(deadkeystate !=0) { + status = UCKeyTranslate(keyboard_layout, 49 ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + printf(" dk key nr %i , ss %i has values %i(%c)\n", i,shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); + } + } + } + } +} + + bool run_verify_S2(std::vector rgKey) { bool allOK= true; diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 254d9c40bfe..11ef2caa09e 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -175,7 +175,7 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) if(key->ShiftFlags == 0 && key->Key == ch) { // Key is a mnemonic key with no shift state defined. // Remap the key according to the character on the key cap. - //mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO + [%x K_%d]", key->Line, key->Key, shift, vk); + mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO + [%x K_%d]", key->Line, key->Key, shift, vk);// 1 key->ShiftFlags = ISVIRTUALKEY | shift; key->Key = vk; } else if(key->ShiftFlags & VIRTUALCHARKEY && key->Key == ch) { @@ -184,7 +184,7 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) // This will not result in 100% wonderful mappings as there could // be overlap, depending on how keys are arranged on the target layout. // But that is up to the designer. - //mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, key->ShiftFlags & ~VIRTUALCHARKEY, vk); + mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, key->ShiftFlags & ~VIRTUALCHARKEY, vk); key->ShiftFlags &= ~VIRTUALCHARKEY; key->Key = vk; } @@ -206,9 +206,9 @@ void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_ void mac_KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { if(key->ShiftFlags == 0) { - // mac_KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); + mac_KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); } else if(key->ShiftFlags & VIRTUALCHARKEY) { - // mac_KMX_LogError(L"Did not find a match for mnemonic virtual character key rule on line %d, + [%x '%c'] > ...", key->Line, key->ShiftFlags, key->Key); + mac_KMX_LogError(L"Did not find a match for mnemonic virtual character key rule on line %d, + [%x '%c'] > ...", key->Line, key->ShiftFlags, key->Key); } } @@ -237,10 +237,10 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, shift &= ~LCTRLFLAG; if(key->ShiftFlags == 0) { - //mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO dk(%d) + [%x K_%d]", key->Line, key->Key, deadkey, shift, vk); + mac_KMX_LogError(L"Converted ddkk mnemonic rule on line %d, + '%c' TO dk(%d) + [%x K_%d]", key->Line, key->Key, deadkey, shift, vk); key->ShiftFlags = ISVIRTUALKEY | shift; } else { - //mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO dk(%d) + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, deadkey, key->ShiftFlags & ~VIRTUALCHARKEY, vk); + mac_KMX_LogError(L"Converted ddkk mnemonic virtual char key rule on line %d, + [%x '%c'] TO dk(%d) + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, deadkey, key->ShiftFlags & ~VIRTUALCHARKEY, vk); key->ShiftFlags &= ~VIRTUALCHARKEY; } @@ -431,6 +431,10 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int // evident for the 102nd key on UK, for example, where \ can be generated with VK_OEM_102 or AltGr+VK_QUOTE. // For now, we get the least shifted version, which is hopefully adequate. + // _S2 : Sadly it`s not: on a german WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only. + // on a german MAC keyboard one will get '~' with either OPT + K_221(+) or OPT + K_84(T). + // K_84 will be caught first, so the least obvious version to get the '~' is found and processed. + const UCKeyboardLayout* keyboard_layout; if(mac_InitializeUCHR(&keyboard_layout)) { wprintf(L"ERROR: can't Initialize GDK\n"); @@ -513,13 +517,30 @@ int mac_KMX_GetDeadkeys( KMX_WCHAR DeadKey, UINT shift_dk, KMX_WORD *OutputPairs KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying( All_Vector, (KMX_DWORD) DeadKey); - for ( int i=0; i < keycount;i++) { - for ( int j=0; j < sizeof(shift)/sizeof(shift[0]); j++) { - status = UCKeyTranslate(keyboard_layout, sc_dk ,kUCKeyActionDown, shift_dk, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // _S2 + // we go in this order because we need to make sure that the most obvious keycombination is taken into account for deadkeys. + // This is important since it catches only the first key that matches a given rule, but multiple keys may match that rule. + // (see explanation in mcompile.cpp DoConvert() ) + // space is the most important one for deadkeys, so we start with Space (Keycode 49) + // then character keys in alphabetical order, then numbers, then punctuation keys + + // SPACE, A_Z, 0-9, VK_ACCENT,HYPHEN,EQUAL,LBRKT,RBRKT,BKSLASH,COLON,QUOTE,COMMA,PERIOD,SLASH,xDF,OEM_102 + int keyarray[] ={ + 49, + 0, 11, 8, 2, 14, 3, 5, 4, 34, 38, 40, 37, 46, 45, 31, 35, 12, 15, 1, 17, 32, 9, 13, 7, 16, 6, + 29, 18, 19, 20, 21, 23, 22, 26, 28, 25, + 42, 27, 24, 33, 30, 42, 41, 39, 43, 47, 44, 223, 226, 0xFFFF + }; + + for ( int j=0; j < sizeof(shift)/sizeof(shift[0]); j++) { + //for ( int i=0; i < keycount;i++) { + //for ( int i=keycount-1; i >=0; i--) { + for (int i = 0; keyarray[i] != 0xFFFF; i++) { + status = UCKeyTranslate(keyboard_layout, sc_dk ,kUCKeyActionDown, mac_map_VKShiftState_to_MacModifier(shift_dk), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + status = UCKeyTranslate(keyboard_layout, keyarray[i] ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { - KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, i, 1); + KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, keyarray[i], 1); *p++ = vk; *p++ = shift[j]; *p++ =unicodeString[0]; From d69600b9949bb5e8e3604e3454128dfd40be9ab3 Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 15 May 2024 19:34:17 +0200 Subject: [PATCH 24/71] feat(mac): tidy up --- mac/mcompile/mcompile.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 11ef2caa09e..d023713d9b2 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -237,10 +237,10 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, shift &= ~LCTRLFLAG; if(key->ShiftFlags == 0) { - mac_KMX_LogError(L"Converted ddkk mnemonic rule on line %d, + '%c' TO dk(%d) + [%x K_%d]", key->Line, key->Key, deadkey, shift, vk); + mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO dk(%d) + [%x K_%d]", key->Line, key->Key, deadkey, shift, vk); key->ShiftFlags = ISVIRTUALKEY | shift; } else { - mac_KMX_LogError(L"Converted ddkk mnemonic virtual char key rule on line %d, + [%x '%c'] TO dk(%d) + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, deadkey, key->ShiftFlags & ~VIRTUALCHARKEY, vk); + mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO dk(%d) + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, deadkey, key->ShiftFlags & ~VIRTUALCHARKEY, vk); key->ShiftFlags &= ~VIRTUALCHARKEY; } @@ -517,7 +517,7 @@ int mac_KMX_GetDeadkeys( KMX_WCHAR DeadKey, UINT shift_dk, KMX_WORD *OutputPairs KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying( All_Vector, (KMX_DWORD) DeadKey); - // _S2 + /*// _S2 // we go in this order because we need to make sure that the most obvious keycombination is taken into account for deadkeys. // This is important since it catches only the first key that matches a given rule, but multiple keys may match that rule. // (see explanation in mcompile.cpp DoConvert() ) @@ -530,17 +530,18 @@ int mac_KMX_GetDeadkeys( KMX_WCHAR DeadKey, UINT shift_dk, KMX_WORD *OutputPairs 0, 11, 8, 2, 14, 3, 5, 4, 34, 38, 40, 37, 46, 45, 31, 35, 12, 15, 1, 17, 32, 9, 13, 7, 16, 6, 29, 18, 19, 20, 21, 23, 22, 26, 28, 25, 42, 27, 24, 33, 30, 42, 41, 39, 43, 47, 44, 223, 226, 0xFFFF - }; + };*/ for ( int j=0; j < sizeof(shift)/sizeof(shift[0]); j++) { - //for ( int i=0; i < keycount;i++) { - //for ( int i=keycount-1; i >=0; i--) { - for (int i = 0; keyarray[i] != 0xFFFF; i++) { + // we start calculating SPACE(49) since most obvious deadkeys combinations use space. + for ( int i=keycount-1; i >=0; i--) { + //for ( int i=0; i< keycount-1; i++) { + //for (int i = 0; keyarray[i] != 0xFFFF; i++) { status = UCKeyTranslate(keyboard_layout, sc_dk ,kUCKeyActionDown, mac_map_VKShiftState_to_MacModifier(shift_dk), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, keyarray[i] ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { - KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, keyarray[i], 1); + KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, i, 1); *p++ = vk; *p++ = shift[j]; *p++ =unicodeString[0]; From 4a5e4579c88c72976fc4ea1baf609fef742d0ee1 Mon Sep 17 00:00:00 2001 From: Sabine Date: Thu, 16 May 2024 12:35:03 +0200 Subject: [PATCH 25/71] feat(mac): fill alDead OK --- mac/.gitignore | 3 +- mac/mcompile/keymap.cpp | 57 +++++++++- mac/mcompile/keymap.h | 13 ++- mac/mcompile/mc_import_rules.cpp | 176 +++++++++++++++++++++++++++++-- mac/mcompile/mc_import_rules.h | 1 + mac/mcompile/mcompile.cpp | 58 +++++++--- mac/mcompile/mcompile.h | 4 + 7 files changed, 280 insertions(+), 32 deletions(-) diff --git a/mac/.gitignore b/mac/.gitignore index 62da38b8ba0..c5ab971cfa0 100644 --- a/mac/.gitignore +++ b/mac/.gitignore @@ -20,4 +20,5 @@ setup/Install Keyman.app **/mcompile/executable/*.* **/mcompile/*.kmx **/mcompile/X*.cpp -**/mcompile/X_bak \ No newline at end of file +**/mcompile/X_bak +**/mcompile/X*.* \ No newline at end of file diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 6ab51d02cdf..d08397fea1b 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -212,8 +212,40 @@ int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, in return (int) unicodeString[0]; // even: combine char -> è } } + return 0; +} +// _S2 TODO dk/non-dk +// _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk? +int mac_KMX_get_KeyVal_From_KeyCode_S2(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { + // _S2 not finished yet - needs deadkeys... + KMX_DWORD in_array[2] = {0,0}; + UInt32 deadkeystate = 0; + UniCharCount maxStringlength = 5; + UniCharCount actualStringlength = 0; + UniChar unicodeString[maxStringlength]; + OSStatus status; + int Keycode_Spacebar =49; + // _S2 bette solution for 4*CAPS ???? + status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // If this was a deadkey, append a space + if(deadkeystate !=0) + status = UCKeyTranslate(keyboard_layout, Keycode_Spacebar ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // UCKeyTranslate writes 0x01 into unicodeString[0] if there is no character assigned to the Key+Shift+CAPS + // ( then returnes 0 -> 0 is then propagated to ... mac_KMX_ToUnicodeEx (-> rc=0) .. ImportRules (rc=0-> do nothing ) ) + + // _S2 no deadkeys yet or check last bit + if( shiftstate %2 == 1) + return 0; // _S2 what to return if deadkeys are used?? + + else { + if( (int) unicodeString[0] == 1 ) // impossible character + return 0; + else { + return (int) unicodeString[0]; // even: combine char -> è + } + } return 0; } @@ -233,6 +265,8 @@ int mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, status = UCKeyTranslate(keyboard_layout, Keycode_Spacebar ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); } + if( keycode==0x999) + return L'\0'; return (int) unicodeString[0]; } @@ -516,7 +550,7 @@ std::u16string mac_get_character_From_Keycode(std::vector keyval, int shift return returnString; } -KMX_DWORD mac_get_keyval_From_Keycode_new(int charVal,const UCKeyboardLayout* keyboard_layout , KMX_DWORD shiftstate) { +KMX_DWORD mac_get_keyval_From_Keycode_new(int VK_dk,const UCKeyboardLayout* keyboard_layout , KMX_DWORD shiftstate) { UInt32 deadkeystate = 0; UniCharCount maxStringlength = 5; @@ -524,7 +558,7 @@ KMX_DWORD mac_get_keyval_From_Keycode_new(int charVal,const UCKeyboardLayout* k UniChar unicodeString[maxStringlength]; OSStatus status; - status = UCKeyTranslate(keyboard_layout, charVal ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + status = UCKeyTranslate(keyboard_layout, VK_dk ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); // If this was a deadkey, append a space if(deadkeystate !=0) @@ -534,6 +568,25 @@ KMX_DWORD mac_get_keyval_From_Keycode_new(int charVal,const UCKeyboardLayout* k return unicodeString[0]; } +KMX_DWORD mac_get_CombinedChar_From_DK(int VK_dk,KMX_DWORD ss_dk,const UCKeyboardLayout* keyboard_layout, KMX_DWORD VK_US, KMX_DWORD shiftstate, int caps) { + + UInt32 deadkeystate = 0; + UniCharCount maxStringlength = 5; + UniCharCount actualStringlength = 0; + UniChar unicodeString[maxStringlength]; + OSStatus status; + + status = UCKeyTranslate(keyboard_layout, VK_dk ,kUCKeyActionDown, ss_dk, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + + // If this was a deadkey, append a space + if(deadkeystate !=0) { + status = UCKeyTranslate(keyboard_layout, (UInt16) VK_US ,kUCKeyActionDown, shiftstate+4*caps, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + return unicodeString[0]; + } + else + return 0; +} + /* KMX_DWORD mac_get_keyval_From_Keycode(int keyval, int shiftstate, const UCKeyboardLayout* keyboard_layout ) { UInt32 deadkeystate = 0; diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index aac53669d85..e5cfd3830b5 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -16,7 +16,7 @@ std::u16string mac_get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout); KMX_DWORD mac_get_keyval_From_Keycode_new(int charVal,const UCKeyboardLayout* keyboard_layout , KMX_DWORD shiftstate); - +KMX_DWORD mac_get_CombinedChar_From_DK(int charVal,KMX_DWORD ss_dk,const UCKeyboardLayout* keyboard_layout, KMX_DWORD VK_US, KMX_DWORD shiftstate, int caps); //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ @@ -88,6 +88,8 @@ static KMX_DWORD max_shiftstate = 2; // _S2 only base+Shift static KMX_DWORD keycode_max = 94; // _S2 needed?? static KMX_DWORD deadkey_min = 0xfe50; // _S2 needed?? static KMX_DWORD deadkey_max = 0xfe93; // _S2 needed?? + +static int maxKeyCodeMac =50; //static KMX_DWORD deadkey_max = 0xfe52; // _S2 TOP_6 TODO This has to go! my test: to only return 3 dk // map VKShiftstate to modifier (use 0,2,4,8,10 instead of 0,16,9,25 ) @@ -919,6 +921,7 @@ std::u16string mac_convert_DeadkeyValues_To_U16str(int in); // use gdk_keymap_translate_keyboard_state to get keyval - base function to get keyvals // _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk only? int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int ss, int caps); +int mac_KMX_get_KeyVal_From_KeyCode_S2(const UCKeyboardLayout * keyboard_layout, int keycode, int ss, int caps); int mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps, UInt32 &deadkeystate_ret); // use mac_KMX_get_KeyVal_From_KeyCode and prevent use of certain keycodes @@ -960,9 +963,9 @@ KMX_DWORD mac_convertNamesTo_DWORD_Value(std::string tok_str); bool mac_createCompleteRow_US(v_str_1D &complete_List, FILE *fpp, const char *text, std::string language); void printoutKeyboards(v_dw_3D &All_Vector); -KMX_DWORD X_playWithDK(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal) ; -KMX_DWORD X_playWithDK_one(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal); -KMX_DWORD X_compare_Shiftstates(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); -KMX_DWORD X_find_Shiftstates(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); +KMX_DWORD X_playWithDK_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal) ; +KMX_DWORD X_playWithDK_S2_one(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal); +KMX_DWORD X_compare_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); +KMX_DWORD X_find_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); KMX_DWORD printout_dk(const UCKeyboardLayout* keyboard_layout);/**/ #endif // KEYMAP_H \ No newline at end of file diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index b003c510786..c683738b9f8 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -68,6 +68,7 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { //################################################################################################################################################ +bool test_alDead_S2(std::vector ald); int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps,const UCKeyboardLayout * keyboard_layout) { @@ -90,7 +91,10 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, i //rc<0: dk // _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk ? - KMX_DWORD KeyVal= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode, mac_map_ShiftState_to_MacModifier(ShiftState(shift_state_pos)), caps); + KMX_DWORD KeyVal2= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode, mac_map_ShiftState_to_MacModifier(ShiftState(shift_state_pos)), caps); + + UInt32 isdk=0; + KMX_DWORD KeyVal= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_map_ShiftState_to_MacModifier(ShiftState(shift_state_pos)), caps, isdk); // _S2 ToDo non-dk OK, but all others not std::u16string str = mac_convert_DeadkeyValues_To_U16str(KeyVal); @@ -105,8 +109,8 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, i else if(gdk_keyval_to_unicode(KeyVal) == 0) // NO UNICODE return 0; else */ // usable char - - if ( 1!=1) // later for deadkeys +// _S2 dk >0 if dk found + if ((isdk) && (keycode!= 0x999)) // isdk !=0 return -1; else if (KeyVal ==0) // NO UNICODE return 0; @@ -374,6 +378,55 @@ class mac_KMX_VirtualKey { bool KMX_IsControlChar(char16_t ch) { return (ch < 0x0020) || (ch >= 0x007F && ch <= 0x009F); } + + DeadKey *ProcessDeadKey( + UINT iKeyDead, // The index into the VirtualKey of the dead key IKey US 187 for key nr 24 + ShiftState shiftStateDead, // The shiftstate that contains the dead key + std::vector rgKey, // Our array of dead keys + bool fCapsLock, // Was the caps lock key pressed? + const UCKeyboardLayout * keyboard_layout, v_dw_3D & All_Vector ) { // The keyboard layout + + DeadKey *deadKey = new DeadKey(rgKey[iKeyDead]->mac_KMX_GetShiftState(shiftStateDead, fCapsLock)[0]); + + int ss[]={0,2,8,10}; + int iindex=0; + // e.g. ^ keyval_underlying_dk + int ss_dead = mac_map_ShiftState_to_MacModifier(shiftStateDead); + int keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead],mac_map_ShiftState_to_MacModifier(shiftStateDead),0); + + for( int i=0; i< maxKeyCodeMac; i++) { + + for( int j=0; j< 2; j++) { + for( int caps = 0; caps < 1; caps++) { + // e.g. a basechar_ + int basechar_ = mac_KMX_get_KeyVal_From_KeyCode_S2(keyboard_layout, i,ss[j],caps); + + // e.g. â combchar_ + KMX_DWORD KC_u_dk = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKeyDead); + KMX_DWORD combchar_= mac_get_CombinedChar_From_DK(KC_u_dk, ss_dead, keyboard_layout , i, ss[j],caps); + + if(combchar_== 0) + continue; + + // write only for if combchar_ is not dk or combchar_ is dk with space  + if( (!(combchar_== keyval_underlying_dk)) || (basechar_ == mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, 49,ss[j],caps))) { + deadKey->KMX_AddDeadKeyRow(basechar_, combchar_); + iindex++; + printf( " [%i] processed basechar_ %i(%c) with dk %i(%c) ===> combchar_%i(%c) \t\t ss[%i](%i) caps%i \n",iindex-1, basechar_,basechar_ ,keyval_underlying_dk,keyval_underlying_dk, combchar_,combchar_ ,j,ss[j], caps ); + } + } + } + } + return deadKey; + } + + /*void ClearKeyboardBuffer(UINT vk, UINT sc, HKL hkl) { + WCHAR sb[16]; + int rc = 0; + do { + rc = ::ToUnicodeEx(vk, sc, lpKeyStateNull, sb, _countof(sb), 0, hkl); + } while(rc != 1 && rc != 0); + }*/ }; @@ -393,6 +446,7 @@ bool run_verify_S2(std::vector rgKey); void print_All_Keys(const UCKeyboardLayout * keyboard_layout); void print_certain_Keys(const UCKeyboardLayout * keyboard_layout, int keycode); + bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout,std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 mac_KMX_Loader loader; @@ -437,7 +491,6 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar if(rgKey[iKey] != NULL) { KMX_WCHAR sbBuffer[256]; // Scratchpad we use many places - for(ShiftState ss = Base; ss <= loader.KMX_MaxShiftState(); ss = (ShiftState)((int)ss + 1)) { if(ss == Menu || ss == ShftMenu) { // Alt and Shift+Alt don't work, so skip them (ss 4+5) @@ -445,9 +498,9 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar } //_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! - if(ss == MenuCtrl|| ss == ShftMenuCtrl) { + /*if(ss == MenuCtrl|| ss == ShftMenuCtrl) { continue; - } + }*/ // _S2 ToDo what about not used keys?? KMX_DWORD KC_US = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); @@ -473,7 +526,23 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on Linux is different // _S2 does not work - deadkeys - mac_refine_alDead(sbBuffer[0], alDead, &alDead_cpl); + if (!caps) + printf(" _S2 we have dk: %i(%i) %i %i(%c) \n", KC_US, iKey,ss, sbBuffer[0],sbBuffer[0] ); + + sbBuffer[2] = 0; + rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps == 0)); + DeadKey *dk = NULL; + for(UINT iDead = 0; iDead < alDead.size(); iDead++) { + dk = alDead[iDead]; + if(dk->KMX_DeadCharacter() == rgKey[iKey]->mac_KMX_GetShiftState(ss, caps == 0)[0]) { + break; + } + dk = NULL; + } + if(dk == NULL) { + alDead.push_back(loader.ProcessDeadKey(iKey, ss, rgKey, caps == 0, *keyboard_layout, All_Vector)); + printf(" WOULD DO alDead.push_back for caps: %i sbBuffer[0]%i\n", caps,sbBuffer[0]); + } } } } @@ -490,6 +559,8 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar //print_All_Keys( * keyboard_layout); //print_certain_Keys( * keyboard_layout, 10); + + bool allOK =test_alDead_S2(alDead); if ( ! run_verify_S2(rgKey)) printf(" \n::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG ENTRIES ::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); else @@ -795,7 +866,7 @@ void print_All_Keys(const UCKeyboardLayout * keyboard_layout){ for(int k=0; k<2;k++) { for(int j=0; j<4;j++) { - for(int i=0; i<50;i++) { + for(int i=0; i< maxKeyCodeMac ;i++) { status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate ==0) printf(" key nr %i , ss %i has values %i(%c)\n", i, shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); @@ -808,7 +879,94 @@ void print_All_Keys(const UCKeyboardLayout * keyboard_layout){ } } } - +bool checkBasechar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) { + return ( DK->KMX_GetBaseCharacter(index) == ch) ; +} +bool checkCombchar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) { + return ( DK->KMX_GetCombinedCharacter(index) == ch) ; +} +bool test_alDead_S2(std::vector ald) { + bool OK =true; + + OK = OK && checkBasechar_S2(ald[0],0, 0x61); + OK = OK && checkBasechar_S2(ald[0],1, 0x41); + OK = OK && checkBasechar_S2(ald[0],14, 0x65); + OK = OK && checkBasechar_S2(ald[0],15, 0x45); + OK = OK && checkBasechar_S2(ald[0],23 ,0x69 ); + OK = OK && checkBasechar_S2(ald[0],24 ,0x49 ); + OK = OK && checkBasechar_S2(ald[0],19 ,0x6f ); + OK = OK && checkBasechar_S2(ald[0],20 ,0x4f ); + OK = OK && checkBasechar_S2(ald[0],21 ,0x75 ); + OK = OK && checkBasechar_S2(ald[0],22 ,0x55 ); + OK = OK && checkBasechar_S2(ald[0],27 ,0x20 ); + OK = OK && checkBasechar_S2(ald[0],28 ,0x20 ); + + OK = OK && checkCombchar_S2(ald[0],0, 0xe2); + OK = OK && checkCombchar_S2(ald[0],1, 0xc2); + OK = OK && checkCombchar_S2(ald[0],14 ,0xea); + OK = OK && checkCombchar_S2(ald[0],15, 0xca); + OK = OK && checkCombchar_S2(ald[0],23 ,0xee ); + OK = OK && checkCombchar_S2(ald[0],24 ,0xce ); + OK = OK && checkCombchar_S2(ald[0],19 ,0xf4 ); + OK = OK && checkCombchar_S2(ald[0],20 ,0xd4 ); + OK = OK && checkCombchar_S2(ald[0],21 ,0xfb ); + OK = OK && checkCombchar_S2(ald[0],22 ,0xdb ); + OK = OK && checkCombchar_S2(ald[0],27 ,0x5e ); + OK = OK && checkCombchar_S2(ald[0],28 ,0x5e ); + + OK = OK && checkBasechar_S2(ald[1],0, 0x61); + OK = OK && checkBasechar_S2(ald[1],1, 0x41); + OK = OK && checkBasechar_S2(ald[1],12, 0x65); + OK = OK && checkBasechar_S2(ald[1],13, 0x45); + OK = OK && checkBasechar_S2(ald[1],24 ,0x69 ); + OK = OK && checkBasechar_S2(ald[1],25 ,0x49 ); + OK = OK && checkBasechar_S2(ald[1],18 ,0x6f ); + OK = OK && checkBasechar_S2(ald[1],19 ,0x4f ); + OK = OK && checkBasechar_S2(ald[1],20 ,0x75 ); + OK = OK && checkBasechar_S2(ald[1],21 ,0x55 ); + OK = OK && checkBasechar_S2(ald[1],36 ,0x20 ); + OK = OK && checkBasechar_S2(ald[1],37 ,0x20 ); + + OK = OK && checkCombchar_S2(ald[1],0, 0xe2-1); + OK = OK && checkCombchar_S2(ald[1],1, 0xc2-1); + OK = OK && checkCombchar_S2(ald[1],12 ,0xea-1); + OK = OK && checkCombchar_S2(ald[1],13, 0xca-1); + OK = OK && checkCombchar_S2(ald[1],24 ,0xee -1); + OK = OK && checkCombchar_S2(ald[1],25 ,0xce -1); + OK = OK && checkCombchar_S2(ald[1],18 ,0xf4 -1); + OK = OK && checkCombchar_S2(ald[1],19 ,0xd4 -1); + OK = OK && checkCombchar_S2(ald[1],20 ,0xfb -1); + OK = OK && checkCombchar_S2(ald[1],21 ,0xdb -1); + OK = OK && checkCombchar_S2(ald[1],36 ,0xb4 ); + OK = OK && checkCombchar_S2(ald[1],37 ,0xb4 ); + + OK = OK && checkBasechar_S2(ald[2],0, 0x61); + OK = OK && checkBasechar_S2(ald[2],1, 0x41); + OK = OK && checkBasechar_S2(ald[2],6, 0x65); + OK = OK && checkBasechar_S2(ald[2],7, 0x45); + OK = OK && checkBasechar_S2(ald[2],12 ,0x69 ); + OK = OK && checkBasechar_S2(ald[2],13 ,0x49 ); + OK = OK && checkBasechar_S2(ald[2],8 ,0x6f ); + OK = OK && checkBasechar_S2(ald[2],9 ,0x4f ); + OK = OK && checkBasechar_S2(ald[2],10 ,0x75 ); + OK = OK && checkBasechar_S2(ald[2],11 ,0x55 ); + OK = OK && checkBasechar_S2(ald[2],16 ,0x20 ); + OK = OK && checkBasechar_S2(ald[2],17 ,0x20 ); + + OK = OK && checkCombchar_S2(ald[2],0, 0xe2-2); + OK = OK && checkCombchar_S2(ald[2],1, 0xc2-2); + OK = OK && checkCombchar_S2(ald[2],6 ,0xea-2); + OK = OK && checkCombchar_S2(ald[2],7, 0xca-2); + OK = OK && checkCombchar_S2(ald[2],12 ,0xee -2); + OK = OK && checkCombchar_S2(ald[2],13 ,0xce -2); + OK = OK && checkCombchar_S2(ald[2],8 ,0xf4 -2); + OK = OK && checkCombchar_S2(ald[2],9 ,0xd4 -2); + OK = OK && checkCombchar_S2(ald[2],10 ,0xfb -2); + OK = OK && checkCombchar_S2(ald[2],11 ,0xdb -2); + OK = OK && checkCombchar_S2(ald[2],16 ,0x60 ); + OK = OK && checkCombchar_S2(ald[2],17 ,0x60 ); +return OK; +} bool run_verify_S2(std::vector rgKey) { diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h index e8ff532991a..c76585fab19 100755 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -5,6 +5,7 @@ //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ +int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps,const UCKeyboardLayout * keyboard_layout); class DeadKey { private: diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index d023713d9b2..9dea7fc291f 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -389,6 +389,11 @@ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_ //KMX_WORD deadkeys1[512]={0}; //KMX_WORD *pdk1; //bool tt_S2= test_dk_S2(deadkeys, deadkeys1); + /*bool uu_S2= test_dk_find_entries_S2(deadkeys, 75); + bool uu_S3= test_dk_find_entries_S2(deadkeys, 226); + bool uu_S4= test_dk_find_entries_S2(deadkeys, 8); + bool uu_S5= test_dk_find_entries_S2(deadkeys, 214);*/ + bool uu_S6= test_dk_write_entries_S2(deadkeys); while(*pdk) { // Look up the ch @@ -433,7 +438,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int // _S2 : Sadly it`s not: on a german WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only. // on a german MAC keyboard one will get '~' with either OPT + K_221(+) or OPT + K_84(T). - // K_84 will be caught first, so the least obvious version to get the '~' is found and processed. + // K_84 will be caught first, so the least obvious version for creating the '~' is found and processed. const UCKeyboardLayout* keyboard_layout; if(mac_InitializeUCHR(&keyboard_layout)) { @@ -482,18 +487,18 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int mac_KMX_ReportUnconvertedKeyboardRules(kbd); /*// _S2 has to go later - KMX_DWORD out = X_find_Shiftstates(0, keyboard_layout,12) ; - //KMX_DWORD out2= X_find_Shiftstates(0, keyboard_layout,0) ; - //KMX_DWORD out4= X_compare_Shiftstates(0, keyboard_layout,0) ; + KMX_DWORD out = X_find_Shiftstates_S2(0, keyboard_layout,12) ; + //KMX_DWORD out2= X_find_Shiftstates_S2(0, keyboard_layout,0) ; + //KMX_DWORD out4= X_compare_Shiftstates_S2(0, keyboard_layout,0) ; //KMX_DWORD out3 = printout_dk(keyboard_layout); - //KMX_DWORD out5= X_playWithDK(0, keyboard_layout,0) ; + //KMX_DWORD out5= X_playWithDK_S2(0, keyboard_layout,0) ; KMX_DWORD out6; - for ( int i= 0; i<50;i++) { - out6= X_playWithDK_one(i, keyboard_layout,8) ; + for ( int i= 0; i=0; i--) { - //for ( int i=0; i< keycount-1; i++) { - //for (int i = 0; keyarray[i] != 0xFFFF; i++) { + for ( int i=maxKeyCodeMac-1; i >=0; i--) { + // _S2 for (int i = 0; keyarray[i] != 0xFFFF; i++) { status = UCKeyTranslate(keyboard_layout, sc_dk ,kUCKeyActionDown, mac_map_VKShiftState_to_MacModifier(shift_dk), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // _S2 status = UCKeyTranslate(keyboard_layout, keyarray[i] ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, i, 1); - *p++ = vk; - *p++ = shift[j]; - *p++ =unicodeString[0]; + // _S2 KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, keyarray[i], 1); + // _S2 to not get combinations like ^a but only combined characters like â ( exception for ^+space) + if((unicodeString[0] != DeadKey) || (vk == 32)) { + *p++ = vk; + *p++ = shift[j]; + *p++ =unicodeString[0]; + } } } } @@ -594,6 +602,26 @@ bool test_dk_S2(KMX_WORD deadkeys[512], KMX_WORD deadkeys1[512]) { return tt; } +bool test_dk_find_entries_S2(KMX_WORD deadkeys[512], int search) { + for ( int i=0; i<512;i++) { + if (deadkeys[i] == search) { + printf("found value %i (first occurance) in deadkeys[%i] ",search, i); + if( i%3 ==0 ) printf("as character \n"); + if( i%3 ==1 ) printf("as shiftstate \n"); + if( i%3 ==2 ) printf("as combined character \n"); + return true; + } + } + return false; +} + +bool test_dk_write_entries_S2(KMX_WORD deadkeys[512]) { + for ( int i=0; i< 512/3;i++) { + if ( deadkeys[3*i] !=0) + printf(" %i set nr \t%i: %i\t-\t%i(%c)\t-\t%i(%c) \n",deadkeys[2] ,i,deadkeys[3*i+1], deadkeys[3*i],deadkeys[3*i],deadkeys[3*i+2],deadkeys[3*i+2]); + } + return true; +} //-------------------------- /*void fun2() { std::cout << "Hier ist fun2 von mcompile.cpp ...\n";} diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 8242e660db5..6c941facb9a 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -54,6 +54,10 @@ void mac_KMX_LogError(const wchar_t* fmt, ...); //################################################################################################################################################ bool test_dk_S2(KMX_WORD deadkeys[512], KMX_WORD deadkeys1[512]); +bool test_dk_find_entries_S2(KMX_WORD deadkeys[512], int search); +bool test_dk_write_entries_S2(KMX_WORD deadkeys[512]); + + void fun2(); void testmyFunctions_S2(); #endif // MCOMPILE_H \ No newline at end of file From 69a60c9075e42c8777b7294fa4f86d783e48839a Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 17 May 2024 17:45:58 +0200 Subject: [PATCH 26/71] feat(mac): massive tidy up --- mac/mcompile/deadkey.cpp | 23 ++++----- mac/mcompile/deadkey.h | 16 +++--- mac/mcompile/keymap.cpp | 14 +----- mac/mcompile/keymap.h | 19 ++++--- mac/mcompile/mc_import_rules.cpp | 86 +++++++++++++------------------- mac/mcompile/mcompile.cpp | 66 +++++++----------------- 6 files changed, 81 insertions(+), 143 deletions(-) diff --git a/mac/mcompile/deadkey.cpp b/mac/mcompile/deadkey.cpp index edb2e5b6535..09f6ca0f9b2 100755 --- a/mac/mcompile/deadkey.cpp +++ b/mac/mcompile/deadkey.cpp @@ -15,9 +15,9 @@ return line; }*/ -std::vector mac_create_alDead() { +/*std::vector mac_create_alDead() { std::vector alDead; - /*v_dw_2D dk_ComposeTable; + v_dw_2D dk_ComposeTable; mac_create_DKTable(dk_ComposeTable); @@ -28,12 +28,12 @@ std::vector mac_create_alDead() { dk2->KMX_AddDeadKeyRow(dk_ComposeTable[j][1],dk_ComposeTable[j][2]); } alDead.push_back(dk2); - }*/ + } return alDead; -} +}*/ -void mac_refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector *p_All_Vec) { - /*if( dk == 0) +/*void mac_refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector *p_All_Vec) { + if( dk == 0) return; for (int j=0; j < (int) (*p_All_Vec).size()-1;j++) { @@ -44,8 +44,8 @@ void mac_refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector &dkVec) { int i=0; @@ -98,8 +98,8 @@ void mac_refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector à ) -v_dw_1D mac_createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult); +//v_dw_1D mac_createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult); // create a 2D-vector of all dk combinations ( ` + a -> à ; ^ + a -> â ; `+ e -> è; ...) -void mac_create_DKTable(v_dw_2D & dk_ComposeTable); +//void mac_create_DKTable(v_dw_2D & dk_ComposeTable); -// find all possible dk combinations that exist -std::vector mac_create_alDead(); +// find all possible dk combinations that exist// +//std::vector mac_create_alDead(); // refine dk to those used in the underlying keyboard -void mac_refine_alDead(KMX_WCHAR dk, std::vector &myVec, std::vector *p_All_Vec); +//void mac_refine_alDead(KMX_WCHAR dk, std::vector &myVec, std::vector *p_All_Vec); // check if entry is already there -bool found_dk_inVector(KMX_WCHAR dk, std::vector &myVec); +//bool found_dk_inVector(KMX_WCHAR dk, std::vector &myVec); // get all combination for a specific deadkey(dk) from the dk_vector mac_query_dk_combinations_for_specific_dk which holds all possible dk: ^-> â,ê,î,ô,û,... -bool mac_query_dk_combinations_for_specific_dk(v_dw_2D * dk_ComposeTable, v_dw_2D & dk_SingleTable, KMX_DWORD dk); +//bool mac_query_dk_combinations_for_specific_dk(v_dw_2D * dk_ComposeTable, v_dw_2D & dk_SingleTable, KMX_DWORD dk); //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ // get the shifted character of a key and write shiftstate of KVal to shift -KMX_DWORD mac_KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, const UCKeyboardLayout * keyboard_layout); +//KMX_DWORD mac_KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, const UCKeyboardLayout * keyboard_layout); # endif//DEADKEY_H \ No newline at end of file diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index d08397fea1b..836e9880a34 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -129,15 +129,6 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { return 2; } - /*// _S2 can go later - char layout[128]; - memset(layout, '\0', sizeof(layout)); - // get input source id - kTISPropertyInputSourceID - // get layout name - kTISPropertyLocalizedName - CFStringRef layoutID =static_cast( TISGetInputSourceProperty(source, kTISPropertyInputSourceID)); - CFStringGetCString(layoutID, layout, sizeof(layout), kCFStringEncodingUTF8); - printf("++++++++++++++++++ we use keyboardLayout *** %s *** as underlying keyboard ++++++++++++++++++\n", layout);*/ - return 0; } @@ -190,7 +181,6 @@ int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, in UniCharCount actualStringlength = 0; UniChar unicodeString[maxStringlength]; OSStatus status; - int Keycode_Spacebar =49; // _S2 bette solution for 4*CAPS ???? status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); @@ -224,7 +214,7 @@ int mac_KMX_get_KeyVal_From_KeyCode_S2(const UCKeyboardLayout * keyboard_layout, UniCharCount actualStringlength = 0; UniChar unicodeString[maxStringlength]; OSStatus status; - int Keycode_Spacebar =49; + //int Keycode_Spacebar =49; // _S2 bette solution for 4*CAPS ???? status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); @@ -254,7 +244,7 @@ int mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; UniChar unicodeString[maxStringlength]; - int Keycode_Spacebar =49; + //int Keycode_Spacebar =49; OSStatus status; // _S2 bette solution for 4*CAPS ???? diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index e5cfd3830b5..6295d4ec29e 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -86,10 +86,9 @@ typedef std::vector > > v_dw_3D; static KMX_DWORD returnIfCharInvalid = 0; static KMX_DWORD max_shiftstate = 2; // _S2 only base+Shift static KMX_DWORD keycode_max = 94; // _S2 needed?? -static KMX_DWORD deadkey_min = 0xfe50; // _S2 needed?? -static KMX_DWORD deadkey_max = 0xfe93; // _S2 needed?? - -static int maxKeyCodeMac =50; +//static KMX_DWORD deadkey_min = 0xfe50; // _S2 needed?? +//static KMX_DWORD deadkey_max = 0xfe93; // _S2 needed?? +static int Keycode_Spacebar =49; //static KMX_DWORD deadkey_max = 0xfe52; // _S2 TOP_6 TODO This has to go! my test: to only return 3 dk // map VKShiftstate to modifier (use 0,2,4,8,10 instead of 0,16,9,25 ) @@ -652,7 +651,6 @@ const UINT mac_ScanCodeToUSVirtualKey[128] = { // for character A (65) we look at pos 65 and find keycode 0 // for character X (87) we look at pos 87 and find keycode 7 // for character + (187) we look at pos 187 and find keycode 24 - const UINT mac_USVirtualKeyToScanCode[256] = { 0x999, // L"K_?00", // &H0 ................................................... 0 ........................................... 0x999, // L"K_LBUTTON", // &H1 @@ -946,7 +944,7 @@ UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS); KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); // convert codePoint to u16string -std::u16string mac_CodePointToU16String(unsigned int codepoint); +//std::u16string mac_CodePointToU16String(unsigned int codepoint); //################################################################################################################################################ //################################################################################################################################################ @@ -954,18 +952,19 @@ std::u16string mac_CodePointToU16String(unsigned int codepoint); // _S2 need to go // replace Name of Key (e.g. ) wih Keycode ( e.g. 15 ) -int mac_replace_KeyName_with_Keycode(std::string in); +//int mac_replace_KeyName_with_Keycode(std::string in); // take a std::string (=contents of line symbols-file ) and returns the (int) value of the character -KMX_DWORD mac_convertNamesTo_DWORD_Value(std::string tok_str); +//KMX_DWORD mac_convertNamesTo_DWORD_Value(std::string tok_str); // 1. step: read complete Row of Configuration file US -bool mac_createCompleteRow_US(v_str_1D &complete_List, FILE *fpp, const char *text, std::string language); +//bool mac_createCompleteRow_US(v_str_1D &complete_List, FILE *fpp, const char *text, std::string language); void printoutKeyboards(v_dw_3D &All_Vector); KMX_DWORD X_playWithDK_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal) ; KMX_DWORD X_playWithDK_S2_one(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal); KMX_DWORD X_compare_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); KMX_DWORD X_find_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); -KMX_DWORD printout_dk(const UCKeyboardLayout* keyboard_layout);/**/ +KMX_DWORD printout_dk(const UCKeyboardLayout* keyboard_layout); + #endif // KEYMAP_H \ No newline at end of file diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index c683738b9f8..34d5bd33c69 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -71,14 +71,8 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { bool test_alDead_S2(std::vector ald); int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps,const UCKeyboardLayout * keyboard_layout) { - - /*GdkKeymapKey *maps; - guint *keyvals; - gint count; - - if (!gdk_keymap_get_entries_for_keycode(keymap, keycode, &maps, &keyvals, &count)) - return 0; - +// _S2 ToDo cleanup!! + /* if (!(shift_state_pos <= count)) return 0; @@ -101,8 +95,6 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, i pwszBuff[0]= * (PKMX_WCHAR) str.c_str(); /* - g_free(keyvals); - g_free(maps); if((KeyVal >= deadkey_min) && (KeyVal <= deadkey_max)) // deadkeys return -1; @@ -352,7 +344,7 @@ class mac_KMX_VirtualKey { }; - class mac_KMX_Loader { +class mac_KMX_Loader { private: KMX_BYTE lpKeyStateNull[256]; UINT m_XxxxVk; @@ -380,39 +372,39 @@ class mac_KMX_VirtualKey { } DeadKey *ProcessDeadKey( - UINT iKeyDead, // The index into the VirtualKey of the dead key IKey US 187 for key nr 24 + UINT iKeyDead, // The index into the VirtualKey of the dead key ShiftState shiftStateDead, // The shiftstate that contains the dead key std::vector rgKey, // Our array of dead keys - bool fCapsLock, // Was the caps lock key pressed? - const UCKeyboardLayout * keyboard_layout, v_dw_3D & All_Vector ) { // The keyboard layout + bool fCapsLock, // Was the caps lock key pressed? + const UCKeyboardLayout * keyboard_layout) { // The keyboard layout + int ss[]={0,2,8,10}; + int maxshiftstate=2; DeadKey *deadKey = new DeadKey(rgKey[iKeyDead]->mac_KMX_GetShiftState(shiftStateDead, fCapsLock)[0]); - int ss[]={0,2,8,10}; - int iindex=0; - // e.g. ^ keyval_underlying_dk + // e.g. ^ keyval int ss_dead = mac_map_ShiftState_to_MacModifier(shiftStateDead); - int keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead],mac_map_ShiftState_to_MacModifier(shiftStateDead),0); + int keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead],ss_dead,0); - for( int i=0; i< maxKeyCodeMac; i++) { + for( int i=0; i< Keycode_Spacebar+1; i++) { + for( int j=0; j< maxshiftstate ; j++) { + // _S2 do we need caps?? + for( int caps = 0; caps < 1; caps++) { - for( int j=0; j< 2; j++) { - for( int caps = 0; caps < 1; caps++) { - // e.g. a basechar_ - int basechar_ = mac_KMX_get_KeyVal_From_KeyCode_S2(keyboard_layout, i,ss[j],caps); + // e.g. a basechar + int basechar = mac_KMX_get_KeyVal_From_KeyCode_S2(keyboard_layout, i,ss[j],caps); - // e.g. â combchar_ - KMX_DWORD KC_u_dk = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKeyDead); - KMX_DWORD combchar_= mac_get_CombinedChar_From_DK(KC_u_dk, ss_dead, keyboard_layout , i, ss[j],caps); + // e.g. â combchar + KMX_DWORD KC_Underlying_dk = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKeyDead); + KMX_DWORD combchar= mac_get_CombinedChar_From_DK(KC_Underlying_dk, ss_dead, keyboard_layout , i, ss[j],caps); - if(combchar_== 0) + if(combchar== 0) continue; - // write only for if combchar_ is not dk or combchar_ is dk with space  - if( (!(combchar_== keyval_underlying_dk)) || (basechar_ == mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, 49,ss[j],caps))) { - deadKey->KMX_AddDeadKeyRow(basechar_, combchar_); - iindex++; - printf( " [%i] processed basechar_ %i(%c) with dk %i(%c) ===> combchar_%i(%c) \t\t ss[%i](%i) caps%i \n",iindex-1, basechar_,basechar_ ,keyval_underlying_dk,keyval_underlying_dk, combchar_,combchar_ ,j,ss[j], caps ); + // push only for if combchar is not dk or combchar is dk with space + if( (!(combchar== keyval_underlying_dk)) || (basechar == mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, Keycode_Spacebar,ss[j],caps))) { + deadKey->KMX_AddDeadKeyRow(basechar, combchar); + printf( " processed basechar %i(%c) with dk %i(%c) ===> combchar%i(%c) \t\t ss[%i](%i) caps%i \n", basechar,basechar ,keyval_underlying_dk,keyval_underlying_dk, combchar,combchar ,j,ss[j], caps ); } } } @@ -443,7 +435,6 @@ class mac_KMX_VirtualKey { // _S2 need to go void print_All_Entries_S2(std::vector rgKey); bool run_verify_S2(std::vector rgKey); - void print_All_Keys(const UCKeyboardLayout * keyboard_layout); void print_certain_Keys(const UCKeyboardLayout * keyboard_layout, int keycode); @@ -452,7 +443,6 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar std::vector rgKey; //= new VirtualKey[256]; std::vector alDead; - std::vector alDead_cpl = mac_create_alDead(); rgKey.resize(256); @@ -460,7 +450,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar // values in it. Then, store the SC in each valid VK so it can act as both a // flag that the VK is valid, and it can store the SC value. - //for(UINT sc = 0x01; sc <= 0x7f; sc++) { _S2 winL lin keycode start with 1; mac with 0 + //for(UINT sc = 0x01; sc <= 0x7f; sc++) { _S2 win lin keycode start with 1; mac with 0 for(UINT sc = 0x00; sc <= 0x7f; sc++) { // HERE IS A BIG DIFFERENCE COMPARED TO MCOMPILE FOR WINDOWS: @@ -507,7 +497,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar for(int caps = 0; caps <= 1; caps++) { int rc = mac_KMX_ToUnicodeEx(KC_US, sbBuffer, ss, caps, *keyboard_layout); - //rc>0: character + //rc>0: character //_S2 //rc==0: no translation //rc<0: dk if(rc > 0) { @@ -526,8 +516,8 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on Linux is different // _S2 does not work - deadkeys - if (!caps) - printf(" _S2 we have dk: %i(%i) %i %i(%c) \n", KC_US, iKey,ss, sbBuffer[0],sbBuffer[0] ); + if (!caps) // _S2 can go later + printf(" _S2 we use dk: %i(%i) %i %i(%c) \n", KC_US, iKey,ss, sbBuffer[0],sbBuffer[0] ); sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps == 0)); @@ -540,8 +530,8 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar dk = NULL; } if(dk == NULL) { - alDead.push_back(loader.ProcessDeadKey(iKey, ss, rgKey, caps == 0, *keyboard_layout, All_Vector)); - printf(" WOULD DO alDead.push_back for caps: %i sbBuffer[0]%i\n", caps,sbBuffer[0]); + alDead.push_back(loader.ProcessDeadKey(iKey, ss, rgKey, caps == 0, *keyboard_layout)); + printf(" WOULD DO alDead.push_back for caps: %i sbBuffer[0] %i\n", caps,sbBuffer[0]); } } } @@ -554,18 +544,17 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar // translate it to kmx and append to the existing keyboar //------------------------------------------------------------- - // _S2 needs to go + // _S2 need to go //print_All_Entries_S2(rgKey); //print_All_Keys( * keyboard_layout); //print_certain_Keys( * keyboard_layout, 10); - - - bool allOK =test_alDead_S2(alDead); + bool allOK =test_alDead_S2(alDead); if ( ! run_verify_S2(rgKey)) printf(" \n::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG ENTRIES ::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); else printf("\n ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :) :) :) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); + int nDeadkey = 0; LPKMX_GROUP gp = new KMX_GROUP[kp->cxGroupArray+4]; // leave space for old memcpy(gp, kp->dpGroupArray, sizeof(KMX_GROUP) * kp->cxGroupArray); @@ -775,7 +764,6 @@ const int CODE__SIZE[] = { // _S2 need to go - void print_entries_S2(int i, std::vector rgKey , std::string comp1,std::string comp2,std::string erg) { std::string b0 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 0 )); std::string b1 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 1 )); @@ -783,7 +771,6 @@ void print_entries_S2(int i, std::vector rgKey , std::strin std::string s1 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Shft, 1 )); printf("\n entry nr %i has characters %-30s:(%s|%s|%s|%s)",i, erg.c_str(), (const char * ) b0.c_str(),(const char * ) b1.c_str(),(const char * ) s0.c_str(),(const char * ) s1.c_str()); } - bool verify_entries_S2(int i, std::vector rgKey, int res1,int res2,int res3,int res4 ,int res5=0, int res6=0, int res7=0, int res8=0 ) { std::vector st_vec; std::vector r_vec; @@ -810,7 +797,6 @@ bool verify_entries_S2(int i, std::vector rgKey, int res1,i printf(" ERROR FOR i= Nr:%i, %i(%c) - %i (%c) - %i (%c) - %i (%c) \n",i, *st_vec[0].c_str(),*st_vec[1].c_str(),*st_vec[2].c_str(),*st_vec[3].c_str(),*st_vec[4].c_str(),*st_vec[5].c_str(),*st_vec[6].c_str(),*st_vec[7].c_str()); return all_OK; } - void print_All_Entries_S2( std::vector rgKey) { for ( int i=48; i<58; i++) print_entries_S2(i, rgKey," ","",""); @@ -832,7 +818,6 @@ void print_All_Entries_S2( std::vector rgKey) { print_entries_S2(222, rgKey, "ä", "Ä", "ä Ä Ä Ä"); print_entries_S2(226, rgKey, "<", ">", "< < > >"); } - void print_certain_Keys(const UCKeyboardLayout * keyboard_layout, int keycode) { UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; @@ -854,8 +839,6 @@ void print_certain_Keys(const UCKeyboardLayout * keyboard_layout, int keycode) { } } } - - void print_All_Keys(const UCKeyboardLayout * keyboard_layout){ UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; @@ -866,7 +849,7 @@ void print_All_Keys(const UCKeyboardLayout * keyboard_layout){ for(int k=0; k<2;k++) { for(int j=0; j<4;j++) { - for(int i=0; i< maxKeyCodeMac ;i++) { + for(int i=0; i< Keycode_Spacebar+1 ;i++) { status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate ==0) printf(" key nr %i , ss %i has values %i(%c)\n", i, shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); @@ -967,7 +950,6 @@ bool test_alDead_S2(std::vector ald) { OK = OK && checkCombchar_S2(ald[2],17 ,0x60 ); return OK; } - bool run_verify_S2(std::vector rgKey) { bool allOK= true; diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 9dea7fc291f..aa6f6e2aa07 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -60,7 +60,7 @@ std::vector KMX_FDeadkeys; // I4353 mac_run(argc, str_argv_16, argv); - printf("\n................................ END ..............................\n"); + printf("\n................................ END .............................. _S2 \n"); #endif @@ -175,7 +175,7 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) if(key->ShiftFlags == 0 && key->Key == ch) { // Key is a mnemonic key with no shift state defined. // Remap the key according to the character on the key cap. - mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO + [%x K_%d]", key->Line, key->Key, shift, vk);// 1 + //mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO + [%x K_%d]", key->Line, key->Key, shift, vk);// 1 key->ShiftFlags = ISVIRTUALKEY | shift; key->Key = vk; } else if(key->ShiftFlags & VIRTUALCHARKEY && key->Key == ch) { @@ -184,7 +184,7 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) // This will not result in 100% wonderful mappings as there could // be overlap, depending on how keys are arranged on the target layout. // But that is up to the designer. - mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, key->ShiftFlags & ~VIRTUALCHARKEY, vk); + //mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, key->ShiftFlags & ~VIRTUALCHARKEY, vk); key->ShiftFlags &= ~VIRTUALCHARKEY; key->Key = vk; } @@ -206,9 +206,9 @@ void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_ void mac_KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { if(key->ShiftFlags == 0) { - mac_KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); + //mac_KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); } else if(key->ShiftFlags & VIRTUALCHARKEY) { - mac_KMX_LogError(L"Did not find a match for mnemonic virtual character key rule on line %d, + [%x '%c'] > ...", key->Line, key->ShiftFlags, key->Key); + //mac_KMX_LogError(L"Did not find a match for mnemonic virtual character key rule on line %d, + [%x '%c'] > ...", key->Line, key->ShiftFlags, key->Key); } } @@ -237,10 +237,10 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, shift &= ~LCTRLFLAG; if(key->ShiftFlags == 0) { - mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO dk(%d) + [%x K_%d]", key->Line, key->Key, deadkey, shift, vk); + //mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO dk(%d) + [%x K_%d]", key->Line, key->Key, deadkey, shift, vk); key->ShiftFlags = ISVIRTUALKEY | shift; } else { - mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO dk(%d) + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, deadkey, key->ShiftFlags & ~VIRTUALCHARKEY, vk); + //mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO dk(%d) + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, deadkey, key->ShiftFlags & ~VIRTUALCHARKEY, vk); key->ShiftFlags &= ~VIRTUALCHARKEY; } @@ -369,7 +369,7 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { return s_dkids[s_ndkids++].dst_deadkey = s_next_dkid = ++dkid; } -void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout,v_dw_2D dk_Table) { +void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { KMX_WORD deadkeys[512]={0}; KMX_WORD *pdk; @@ -386,15 +386,6 @@ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_ // creates array [a,e,i,o,u][shiftstate][combined for a+dk e.g. â ] mac_KMX_GetDeadkeys( deadkey, shift, pdk = deadkeys, All_Vector, keyboard_layout); // returns array of [usvk, ch_out] pairs - //KMX_WORD deadkeys1[512]={0}; - //KMX_WORD *pdk1; - //bool tt_S2= test_dk_S2(deadkeys, deadkeys1); - /*bool uu_S2= test_dk_find_entries_S2(deadkeys, 75); - bool uu_S3= test_dk_find_entries_S2(deadkeys, 226); - bool uu_S4= test_dk_find_entries_S2(deadkeys, 8); - bool uu_S5= test_dk_find_entries_S2(deadkeys, 214);*/ - bool uu_S6= test_dk_write_entries_S2(deadkeys); - while(*pdk) { // Look up the ch UINT KeyValUnderlying = mac_KMX_get_KeyValUnderlying_From_KeyValUS(All_Vector, *pdk); @@ -452,12 +443,6 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int return FALSE; } - // _S2 printoutKeyboards(All_Vector); - - // _S2 ToDo - v_dw_2D dk_Table; - mac_create_DKTable(dk_Table); - // _S2 which shiftstates?? for (int j = 0; VKShiftState[j] != 0xFFFF; j++) { // I4651 @@ -478,30 +463,14 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int } switch(ch) { case 0x0000: break; - case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout , dk_Table); break; + case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout); break; default: mac_KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); } } } - // _S2 ToDo non-dk OK,shifted dk are not + // _S2 ToDo non-dk OK,shifted dk are not?? mac_KMX_ReportUnconvertedKeyboardRules(kbd); - /*// _S2 has to go later - KMX_DWORD out = X_find_Shiftstates_S2(0, keyboard_layout,12) ; - //KMX_DWORD out2= X_find_Shiftstates_S2(0, keyboard_layout,0) ; - //KMX_DWORD out4= X_compare_Shiftstates_S2(0, keyboard_layout,0) ; - //KMX_DWORD out3 = printout_dk(keyboard_layout); - //KMX_DWORD out5= X_playWithDK_S2(0, keyboard_layout,0) ; - KMX_DWORD out6; - for ( int i= 0; i=0; i--) { // _S2 for (int i = 0; keyarray[i] != 0xFFFF; i++) { + for ( int i=Keycode_Spacebar; i >=0; i--) { + status = UCKeyTranslate(keyboard_layout, sc_dk ,kUCKeyActionDown, mac_map_VKShiftState_to_MacModifier(shift_dk), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); // _S2 status = UCKeyTranslate(keyboard_layout, keyarray[i] ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if(deadkeystate !=0) { - KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, i, 1); // _S2 KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, keyarray[i], 1); + KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, i, 1); // _S2 to not get combinations like ^a but only combined characters like â ( exception for ^+space) if((unicodeString[0] != DeadKey) || (vk == 32)) { *p++ = vk; @@ -582,9 +555,6 @@ void mac_KMX_LogError(const wchar_t* fmt, ...) { } - - - //################################################################################################################################################ //################################################################################################################################################ @@ -601,7 +571,6 @@ bool test_dk_S2(KMX_WORD deadkeys[512], KMX_WORD deadkeys1[512]) { } return tt; } - bool test_dk_find_entries_S2(KMX_WORD deadkeys[512], int search) { for ( int i=0; i<512;i++) { if (deadkeys[i] == search) { @@ -614,7 +583,6 @@ bool test_dk_find_entries_S2(KMX_WORD deadkeys[512], int search) { } return false; } - bool test_dk_write_entries_S2(KMX_WORD deadkeys[512]) { for ( int i=0; i< 512/3;i++) { if ( deadkeys[3*i] !=0) From 362097da93c327bea15ac0b2096603b7bf3c7dcd Mon Sep 17 00:00:00 2001 From: Sabine Date: Tue, 21 May 2024 14:45:14 +0200 Subject: [PATCH 27/71] feat(mac): work on K_84 <-> K_221 for ~ --- mac/mcompile/keymap.cpp | 23 ++++++++++++++--------- mac/mcompile/mc_import_rules.cpp | 19 +++++++++---------- mac/mcompile/mcompile.cpp | 13 +++++++++---- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 836e9880a34..6239b325aa5 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -1,21 +1,26 @@ #include "keymap.h" +// _S2 _84 Shiftstates // Base, Shift, OPT, Shift+OPT + +// mapping for VKShiftState -> UcKeyTranslate uses 0,2,8,10 ( 4,6,12,14 with caps) int mac_map_VKShiftState_to_MacModifier(int VKShiftState) { - if (VKShiftState == 0 ) return 0; // 0000 0000 - else if (VKShiftState == 16) return 2; // 0000 0111 - else if (VKShiftState == 9) return 8; // 0000 0111 - else if (VKShiftState == 25) return 10; // 0000 0111 + if (VKShiftState == 0 ) return 0; + else if (VKShiftState == 16) return 2; + else if (VKShiftState == 9) return 8; + else if (VKShiftState == 25) return 10; else return VKShiftState; // _S2 what to return if no match?? } // Base, Shift, OPT, Shift+OPT +// mapping for rgkey -> UcKeyTranslate uses 0,2,8,10 ( 4,6,12,14 with caps) int mac_map_ShiftState_to_MacModifier(int ShiftState) { - if (ShiftState == 0 ) return 0; // 0000 0000 - else if (ShiftState == 1) return 2; // 0000 0010 - else if (ShiftState == 6 ) return 8; // 0000 0110 - else if (ShiftState == 7) return 10; // 0000 0111 - else return ShiftState; //;return 999; // _S2 what to return if no match?? + if (ShiftState == 0 ) return 0; + else if (ShiftState == 1) return 2; + else if (ShiftState == 6 ) return 8; + else if (ShiftState == 7) return 10; + // more?? + else return ShiftState; // _S2 what to return if no match?? } int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 34d5bd33c69..8c4543beda1 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -267,7 +267,7 @@ class mac_KMX_VirtualKey { (this->mac_KMX_IsSGCAPS() ? 2 : 0) | (this->mac_KMX_IsAltGrCapsEqualToAltGrShift() ? 4 : 0) | (this->mac_KMX_IsXxxxGrCapsEqualToXxxxShift() ? 8 : 0); - +capslock = 1; //_S2 for (int ss = 0; ss <= MaxShiftState; ss++) { if (ss == Menu || ss == ShftMenu) { // Alt and Shift+Alt don't work, so skip them @@ -488,9 +488,9 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar } //_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! - /*if(ss == MenuCtrl|| ss == ShftMenuCtrl) { + if(ss == MenuCtrl|| ss == ShftMenuCtrl) { continue; - }*/ + } // _S2 ToDo what about not used keys?? KMX_DWORD KC_US = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); @@ -516,8 +516,8 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on Linux is different // _S2 does not work - deadkeys - if (!caps) // _S2 can go later - printf(" _S2 we use dk: %i(%i) %i %i(%c) \n", KC_US, iKey,ss, sbBuffer[0],sbBuffer[0] ); + //if (!caps) // _S2 can go later + printf(" _S2 we use dk: %i(%i) %i caps:%i %i(%c) \n", KC_US, iKey,ss,caps, sbBuffer[0],sbBuffer[0] ); sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps == 0)); @@ -548,13 +548,12 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar //print_All_Entries_S2(rgKey); //print_All_Keys( * keyboard_layout); //print_certain_Keys( * keyboard_layout, 10); - bool allOK =test_alDead_S2(alDead); + // bool allOK =test_alDead_S2(alDead); if ( ! run_verify_S2(rgKey)) printf(" \n::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG ENTRIES ::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); else printf("\n ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :) :) :) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); - int nDeadkey = 0; LPKMX_GROUP gp = new KMX_GROUP[kp->cxGroupArray+4]; // leave space for old memcpy(gp, kp->dpGroupArray, sizeof(KMX_GROUP) * kp->cxGroupArray); @@ -617,7 +616,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar gp->cxKeyArray = nkeys; // - // Add nomatch control to each terminating 'using keys' group // I4550 + // Add nomatch control to each terminating 'using keys' group // I4550 ggggǵggg hhhhh´ggggggg ggggḣhh gggggggggg`gggggggǵg ǵǵggggg hhhh´gggggg ggggáaaa – Ñ // LPKMX_GROUP gp2 = kp->dpGroupArray; for(UINT i = 0; i < kp->cxGroupArray - 1; i++, gp2++) { @@ -985,7 +984,7 @@ bool run_verify_S2(std::vector rgKey) { allOK = verify_entries_S2(222, rgKey, 228,196,196,196) && allOK; allOK = verify_entries_S2(226, rgKey, 60,60,62,62) && allOK; // < > // ------------------------------------------- - allOK = verify_entries_S2(48, rgKey, 48,48,61,61,L'}',0,0,0) && allOK; + /*allOK = verify_entries_S2(48, rgKey, 48,48,61,61,L'}',0,0,0) && allOK; allOK = verify_entries_S2(49, rgKey, 49,49,33,33,L'’',0,0,0) && allOK; allOK = verify_entries_S2(50, rgKey, 50,50,34,34,L'²',0,0,0) && allOK; allOK = verify_entries_S2(51, rgKey, 51,51,167,167,L'³',0,0,0) && allOK; @@ -994,7 +993,7 @@ bool run_verify_S2(std::vector rgKey) { allOK = verify_entries_S2(54, rgKey, 54,54,38,38,L'¿',0,0,0) && allOK; allOK = verify_entries_S2(55, rgKey, 55,55,47,47,L'{',0,0,0) && allOK; allOK = verify_entries_S2(56, rgKey, 56,56,40,40,L'[',0,0,0) && allOK; - allOK = verify_entries_S2(57, rgKey, 57,57,41,41,L']',0,0,0) && allOK; + allOK = verify_entries_S2(57, rgKey, 57,57,41,41,L']',0,0,0) && allOK;*/ return allOK; } diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index aa6f6e2aa07..dfbe49983b0 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -154,7 +154,7 @@ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NU //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ - +// _S2 _84 // Map of all shift states that we will work with const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCTRLFLAG|RALTFLAG, 0xFFFF}; @@ -427,9 +427,11 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int // evident for the 102nd key on UK, for example, where \ can be generated with VK_OEM_102 or AltGr+VK_QUOTE. // For now, we get the least shifted version, which is hopefully adequate. - // _S2 : Sadly it`s not: on a german WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only. - // on a german MAC keyboard one will get '~' with either OPT + K_221(+) or OPT + K_84(T). - // K_84 will be caught first, so the least obvious version for creating the '~' is found and processed. + // _S2 : Sadly it`s not: on a German WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only. + // on a German MAC keyboard one will get '~' with either OPT + K_221(+) or OPT + K_84(T) or CAPS + OPT + K_78(N) + // K_84 will be caught first, so one of the the least obvious version for creating the '~' is found and processed. + + // -> meeting with Marc May 21 2024: We leave it as it is for now; it is OK if different combinations are found. const UCKeyboardLayout* keyboard_layout; if(mac_InitializeUCHR(&keyboard_layout)) { @@ -461,6 +463,8 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int ch = DeadKey; } } + + // _S2 ?5E OK till here switch(ch) { case 0x0000: break; case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout); break; @@ -507,6 +511,7 @@ int mac_KMX_GetDeadkeys( KMX_WCHAR DeadKey, UINT shift_dk, KMX_WORD *OutputPairs for ( int j=0; j < sizeof(shift)/sizeof(shift[0]); j++) { +// _S2 _84 // we start calculating SPACE(49) since most obvious deadkeys combinations use space. // _S2 for (int i = 0; keyarray[i] != 0xFFFF; i++) { for ( int i=Keycode_Spacebar; i >=0; i--) { From cc8cb5de5974b09c0a0f6269901b83412c673b42 Mon Sep 17 00:00:00 2001 From: Sabine Date: Tue, 21 May 2024 18:23:20 +0200 Subject: [PATCH 28/71] feat(mac): tidy up code: use shiftstates consistently; map shiftstates to mac shiftstates(mac, rgkey, win); remove unneccessary functions; rename functions to have more systematic consolidate order of parameters in functions; rename variables (casing), and also to clarify shiftstates; handle unused positions in USVirtualKeyToScanCode+ScanCodeToUSVirtualKey; use util_filesystem.cpp/h from Keyman instead of my own filesystem.cpp/h; remove deadkey.cpp/h; --- mac/mcompile/deadkey.cpp | 476 ------ mac/mcompile/deadkey.h | 32 - mac/mcompile/filesystem.h | 16 - mac/mcompile/keymap.cpp | 623 +++----- mac/mcompile/keymap.h | 1295 ++++++----------- mac/mcompile/km_types.h | 5 - mac/mcompile/kmx_file.h | 4 - mac/mcompile/mc_import_rules.cpp | 348 +++-- mac/mcompile/mc_import_rules.h | 7 +- mac/mcompile/mc_kmxfile.cpp | 2 +- mac/mcompile/mc_kmxfile.h | 5 +- mac/mcompile/mcompile.cpp | 216 ++- mac/mcompile/mcompile.h | 23 +- mac/mcompile/mcompiletest.kmx | Bin 526 -> 0 bytes mac/mcompile/u16.h | 1 + .../{filesystem.cpp => util_filesystem.cpp} | 43 +- mac/mcompile/util_filesystem.h | 16 + 17 files changed, 994 insertions(+), 2118 deletions(-) delete mode 100755 mac/mcompile/deadkey.cpp delete mode 100755 mac/mcompile/deadkey.h delete mode 100755 mac/mcompile/filesystem.h delete mode 100755 mac/mcompile/mcompiletest.kmx rename mac/mcompile/{filesystem.cpp => util_filesystem.cpp} (84%) create mode 100755 mac/mcompile/util_filesystem.h diff --git a/mac/mcompile/deadkey.cpp b/mac/mcompile/deadkey.cpp deleted file mode 100755 index 09f6ca0f9b2..00000000000 --- a/mac/mcompile/deadkey.cpp +++ /dev/null @@ -1,476 +0,0 @@ -#include "keymap.h" -#include "deadkey.h" -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - -// _S2 TODO dk - -/* v_dw_1D mac_createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult) { - v_dw_1D line; - line.push_back(mac_convertNamesTo_DWORD_Value(first)); - line.push_back(mac_convertNamesTo_DWORD_Value(second)); - //line.push_back(mac_convertNamesTo_DWORD_Value(nameresult)); - line.push_back(number); - return line; -}*/ - -/*std::vector mac_create_alDead() { - std::vector alDead; - v_dw_2D dk_ComposeTable; - - mac_create_DKTable(dk_ComposeTable); - - for( int i=0; i < (int) dk_ComposeTable.size()-1; i++) { - DeadKey *dk2 = new DeadKey(dk_ComposeTable[i][0]); - for ( int j=0; j< (int) dk_ComposeTable.size();j++) { - if(( dk_ComposeTable[i][0] == dk_ComposeTable[j][0]) && (mac_IsKeymanUsedChar(dk_ComposeTable[j][1]))) - dk2->KMX_AddDeadKeyRow(dk_ComposeTable[j][1],dk_ComposeTable[j][2]); - } - alDead.push_back(dk2); - } - return alDead; -}*/ - -/*void mac_refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector *p_All_Vec) { - if( dk == 0) - return; - - for (int j=0; j < (int) (*p_All_Vec).size()-1;j++) { - if( dk == (*p_All_Vec)[j]->KMX_GetDeadCharacter()) { - if(! found_dk_inVector(dk, dkVec)) { - dkVec.push_back((*p_All_Vec)[j]); - return; - } - else return; - } - } -}*/ - -/* bool found_dk_inVector(KMX_WCHAR dk, std::vector &dkVec) { - int i=0; - if( dkVec.size() > 0) { - do { - if( dk == dkVec[i]->KMX_GetDeadCharacter()) - return true; - i++; - } while (i < (int) dkVec.size()); - } - return false; -}*/ - -/*bool mac_query_dk_combinations_for_specific_dk(v_dw_2D * p_dk_ComposeTable, v_dw_2D &dk_SingleTable, KMX_DWORD dk) { - v_dw_1D line; - - for ( int i =0; i< (int) (*p_dk_ComposeTable).size(); i++) { - if (((*p_dk_ComposeTable)[i][0] == dk) && (mac_IsKeymanUsedChar((*p_dk_ComposeTable)[i][1]))) { - line.push_back((*p_dk_ComposeTable)[i][0]); - line.push_back((*p_dk_ComposeTable)[i][1]); - line.push_back((*p_dk_ComposeTable)[i][2]); - dk_SingleTable.push_back(line); - line.clear(); - } - } - - if( dk_SingleTable.size()>0) - return true; - else - return false; -}*/ - -/*KMX_DWORD mac_KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, const UCKeyboardLayout * keyboard_layout) { - guint Keyval = (guint) KVal; - GdkKeymapKey* keys; - gint n_keys; - - KMX_DWORD Cap = (KMX_DWORD) gdk_keyval_to_upper (KVal); - if( Keyval !=0) { - gdk_keymap_get_entries_for_keyval(keymap, Keyval, &keys, &n_keys); - for (int i = 0; i < n_keys; i++) { - if (keys[i].group == 0) { - shift = keys[i].level; - return Cap; - } - } - } - return Cap; - KMX_DWORD out_S2 =0; - return out_S2; -}*/ - -/* void mac_create_DKTable(v_dw_2D & dk_ComposeTable) { -//create a 2D-Vector which contains data for ALL existing deadkey combinations on a Linux Keyboard: - //dk_ComposeTable[i][0] : First (e.g. dead_circumflex) - //dk_ComposeTable[i][1] : Second (e.g. a) - //dk_ComposeTable[i][3] : Unicode-Value (e.g. 0x00E2) - - //values taken from: https://help.ubuntu.com/community/GtkDeadKeyTable#Accents - // _S2 Do we want to use GTK instead of this function? - - v_dw_1D line; - - line = mac_createLine("dead_circumflex", "a", 0x00E2, "small A with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "A", 0x00C2, "capital A with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "e", 0x00EA, "small E with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "E", 0x00CA, "capital E with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "i", 0x00EE, "small I with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "I", 0x00CE, "capital I with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "o", 0x00F4, "small O with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "O", 0x00D4, "capital O with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "u", 0x00FB, "small U with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "U", 0x00DB, "capital U with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_acute", "a", 0x00E1, "small A with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "A", 0x00C1, "capital A with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "c", 0x0107, "small C with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "C", 0x0106, "capital C with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "e", 0x00E9, "small E with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "E", 0x00C9, "capital E with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "i", 0x00ED, "small I with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "I", 0x00CD, "capital I with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "l", 0x013A, "small L with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "L", 0x0139, "capital L with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "n", 0x0144, "small N with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "N", 0x0143, "capital N with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "o", 0x00F3, "small O with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "O", 0x00D3, "capital O with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "r", 0x0155, "small R with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "R", 0x0154, "capital R with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "s", 0x015B, "small S with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "S", 0x015A, "capital S with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "u", 0x00FA, "small U with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "U", 0x00DA, "capital U with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "y", 0x00FD, "small Y with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "Y", 0x00DD, "capital Y with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "z", 0x017A, "small Z with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "Z", 0x0179, "capital Z with acute"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_grave", "a", 0x00E0, "small A with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "A", 0x00C0, "capital A with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "e", 0x00E8, "small E with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "E", 0x00C8, "capital E with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "i", 0x00EC, "small I with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "I", 0x00CC, "capital I with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "o", 0x00F2, "small O with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "O", 0x00D2, "capital O with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "u", 0x00F9, "small U with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "U", 0x00D9, "capital U with grave"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_tilde", "a", 0x00E3, "small A with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "A", 0x00C3, "capital A with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "i", 0x0129, "small I with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "I", 0x0128, "capital I with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "n", 0x00F1, "small N with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "N", 0x00D1, "capital N with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "o", 0x00F5, "small O with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "O", 0x00D5, "capital O with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "u", 0x0169, "small U with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "U", 0x0168, "capital U with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_macron", "a", 0x0101, "small A with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "A", 0x0100, "capital A with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "e", 0x0113, "small E with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "E", 0x0112, "capital E with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "i", 0x012B, "small I with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "I", 0x012A, "capital I with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "o", 0x014D, "small O with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "O", 0x014C, "capital O with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "u", 0x016B, "small U with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "U", 0x016A, "capital U with macron"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_breve", "a", 0x0103, "small A with breve"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_breve", "A", 0x0102, "capital A with breve"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_breve", "g", 0x011F, "small G with breve"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_breve", "G", 0x011E, "capital G with breve"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_abovedot", "e", 0x0117, "small E with dot above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "E", 0x0116, "capital E with dot above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "i", 0x0131, "small DOTLESS_I"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "I", 0x0130, "capital I with dot above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "z", 0x017C, "small Z with dot above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "Z", 0x017B, "capital Z with dot above"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_diaeresis", "a", 0x00E4, "small A with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "A", 0x00C4, "capital A with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "e", 0x00EB, "small E with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "E", 0x00CB, "capital E with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "i", 0x00EF, "small I with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "I", 0x00CF, "capital I with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "o", 0x00F6, "small O with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "O", 0x00D6, "capital O with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "u", 0x00FC, "small U with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "U", 0x00DC, "capital U with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "y", 0x00FF, "small Y with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "Y", 0x0178, "capital Y with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_abovering", "a", 0x00E5, "small A with ring above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovering", "A", 0x00C5, "capital A with ring above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovering", "u", 0x016F, "small U with ring above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovering", "U", 0x016E, "capital U with ring above"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_doubleacute", "o", 0x0151, "small O with double acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_doubleacute", "O", 0x0150, "capital O with double acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_doubleacute", "u", 0x0171, "small U with double acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_doubleacute", "U", 0x0170, "capital U with double acute"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_caron", "c", 0x010D, "small C with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "C", 0x010C, "capital C with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "d", 0x010F, "small D with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "D", 0x010E, "capital D with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "e", 0x011B, "small E with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "E", 0x011A, "capital E with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "l", 0x013E, "small L with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "L", 0x013D, "capital L with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "n", 0x0148, "small N with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "N", 0x0147, "capital N with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "r", 0x0159, "small R with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "R", 0x0158, "capital R with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "s", 0x0161, "small S with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "S", 0x0160, "capital S with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "t", 0x0165, "small T with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "T", 0x0164, "capital T with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "z", 0x017E, "small Z with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "Z", 0x017D, "capital Z with caron"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_cedilla", "c", 0x00E7, "small C with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "C", 0x00C7, "capital C with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "g", 0x0123, "small G with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "G", 0x0122, "capital G with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "k", 0x0137, "small K with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "K", 0x0136, "capital K with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "l", 0x013C, "small L with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "L", 0x013B, "capital L with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "n", 0x0146, "small N with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "N", 0x0145, "capital N with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "r", 0x0157, "small R with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "R", 0x0156, "capital R with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "s", 0x015F, "small S with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "S", 0x015E, "capital S with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_ogonek", "a", 0x0105, "small A with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "A", 0x0104, "capital A with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "e", 0x0119, "small E with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "E", 0x0118, "capital E with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "i", 0x012F, "small I with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "I", 0x012E, "capital I with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "u", 0x0173, "small U with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "U", 0x0172, "capital U with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_circumflex", "space", 0x005E, "CIRCUMFLEX_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_acute", "space", 0x0027, "APOSTROPHE"); - dk_ComposeTable.push_back(line); line.clear(); - //line = mac_createLine("dead_acute", "space", 0x00B4, "ACUTE_ACCENT"); // _S2 TOP_3 ToDo remove - this is not right: just for testing - // dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_grave", "space", 0x0060, "GRAVE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_breve", "space", 0x02D8, "BREVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "space", 0x02D9, "DOT_ABOVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovering", "space", 0x02DA, "RING_ABOVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_doubleacute", "space", 0x02DD, "DOUBLE_ACUTE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "space", 0x02C7, "CARON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "space", 0x00B8, "CEDILLA"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "space", 0x02DB, "OGONEK"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "space", 0x007E, "TILDE"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_breve", "dead_breve", 0x02D8, "BREVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "abovedot", 0x02D9, "DOT_ABOVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "dead_abovedot", 0x02D9, "DOT_ABOVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovering", "dead_abovering", 0x02DA, "RING_ABOVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "apostrophe", 0x00B4, "ACUTE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "acute", 0x00B4, "ACUTE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "dead_acute", 0x00B4, "ACUTE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_doubleacute", "dead_doubleacute", 0x02DD, "DOUBLE_ACUTE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "caron", 0x02C7, "CARON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "dead_caron", 0x02C7, "CARON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "comma", 0x00B8, "CEDILLA"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "cedilla", 0x00B8, "CEDILLA"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "dead_cedilla", 0x00B8, "CEDILLA"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "minus", 0x00AF, "MACRON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "asciicircum", 0x005E, "CIRCUMFLEX_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "underscore", 0x00AF, "MACRON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "dead_circumflex", 0x005E, "CIRCUMFLEX_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "quotedbl", 0x00A8, "DIAERESIS"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "diaeresis", 0x00A8, "DIAERESIS"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "dead_diaeresis", 0x00A8, "DIAERESIS"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "grave", 0x0060, "GRAVE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "dead_grave", 0x0060, "GRAVE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "macron", 0x00AF, "MACRON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "dead_macron", 0x00AF, "MACRON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "ogonek", 0x02DB, "OGONEK"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "dead_ogonek", 0x02DB, "OGONEK"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "asciitilde", 0x007E, "TILDE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "dead_tilde", 0x007E, "TILDE"); - dk_ComposeTable.push_back(line); line.clear(); -}*/ diff --git a/mac/mcompile/deadkey.h b/mac/mcompile/deadkey.h deleted file mode 100755 index d76c1386b1b..00000000000 --- a/mac/mcompile/deadkey.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#ifndef DEADKEY_H -#define DEADKEY_H - -#include -#include "mc_import_rules.h" -// _S2 TODO dk -// create a vector for a dk combination ( ` + a -> à ) -//v_dw_1D mac_createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult); - -// create a 2D-vector of all dk combinations ( ` + a -> à ; ^ + a -> â ; `+ e -> è; ...) -//void mac_create_DKTable(v_dw_2D & dk_ComposeTable); - -// find all possible dk combinations that exist// -//std::vector mac_create_alDead(); - -// refine dk to those used in the underlying keyboard -//void mac_refine_alDead(KMX_WCHAR dk, std::vector &myVec, std::vector *p_All_Vec); -// check if entry is already there -//bool found_dk_inVector(KMX_WCHAR dk, std::vector &myVec); - -// get all combination for a specific deadkey(dk) from the dk_vector mac_query_dk_combinations_for_specific_dk which holds all possible dk: ^-> â,ê,î,ô,û,... -//bool mac_query_dk_combinations_for_specific_dk(v_dw_2D * dk_ComposeTable, v_dw_2D & dk_SingleTable, KMX_DWORD dk); - -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - -// get the shifted character of a key and write shiftstate of KVal to shift -//KMX_DWORD mac_KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, const UCKeyboardLayout * keyboard_layout); - -# endif//DEADKEY_H \ No newline at end of file diff --git a/mac/mcompile/filesystem.h b/mac/mcompile/filesystem.h deleted file mode 100755 index 7e30f73b052..00000000000 --- a/mac/mcompile/filesystem.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -#include "u16.h" - -// Open files on windows and non-windows platforms. Datatypes for Filename and mode must be the same. -// return FILE* if file could be opened; FILE must to be closed in calling function -FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); -FILE* Open_File(const KMX_WCHART* Filename, const KMX_WCHART* mode); -FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode); -KMX_BOOL kmcmp_FileExists(const KMX_CHAR *filename); -KMX_BOOL kmcmp_FileExists(const KMX_WCHAR *filename); - -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 6239b325aa5..8e0f43c4c3c 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -1,31 +1,38 @@ #include "keymap.h" -// _S2 _84 Shiftstates -// Base, Shift, OPT, Shift+OPT - -// mapping for VKShiftState -> UcKeyTranslate uses 0,2,8,10 ( 4,6,12,14 with caps) -int mac_map_VKShiftState_to_MacModifier(int VKShiftState) { - if (VKShiftState == 0 ) return 0; - else if (VKShiftState == 16) return 2; - else if (VKShiftState == 9) return 8; - else if (VKShiftState == 25) return 10; - else return VKShiftState; // _S2 what to return if no match?? +// mapping for Base,Shift,OPT,Shift+OPT from vk_ShiftState -> shiftstates UcKeyTranslate uses (0,2,8,10 - 4,6,12,14 with caps) +int mac_map_VKShiftState_to_MacModifier(int vk_ShiftState) { + if (vk_ShiftState == 0 ) return 0; + else if (vk_ShiftState == 16) return 2; + else if (vk_ShiftState == 9) return 8; + else if (vk_ShiftState == 25) return 10; + else return vk_ShiftState; } -// Base, Shift, OPT, Shift+OPT -// mapping for rgkey -> UcKeyTranslate uses 0,2,8,10 ( 4,6,12,14 with caps) -int mac_map_ShiftState_to_MacModifier(int ShiftState) { - if (ShiftState == 0 ) return 0; - else if (ShiftState == 1) return 2; - else if (ShiftState == 6 ) return 8; - else if (ShiftState == 7) return 10; - // more?? - else return ShiftState; // _S2 what to return if no match?? +// mapping for Base,Shift,OPT,Shift+OPT from rgkey -> shiftstates UcKeyTranslate uses (0,2,8,10 - 4,6,12,14 with caps) +int mac_map_Win_ShiftState_to_MacModifier(int win_ShiftState) { + if (win_ShiftState == 0 ) return 0; + else if (win_ShiftState == 1) return 2; + else if (win_ShiftState == 6 ) return 8; + else if (win_ShiftState == 7) return 10; + else return win_ShiftState; + } + +/*bool is_correct_mac_shiftstate(int comp_ss) { + return ( (comp_ss ==0) || (comp_ss ==2) || (comp_ss ==8) || (comp_ss ==10) ); +}*/ + +/*bool is_correct_rgkey_shiftstate(int comp_ss) { + return ( (comp_ss ==0) || (comp_ss ==1) || (comp_ss ==6) || (comp_ss ==7) ); +}*/ + +bool is_correct_win_shiftstate(int comp_ss) { + return ( (comp_ss ==0) || (comp_ss ==16) || (comp_ss ==9) || (comp_ss ==25) || (comp_ss ==0xFFFF) ); } int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { // create a 3D-Vector which contains data of the US keyboard and the underlying Keyboard: - // All_Vector[ US_Keyboard ] + // All_Vector[ US_Keyboard ] // [KeyCode_US ] // [Keyval unshifted ] // [Keyval shifted ] @@ -40,7 +47,7 @@ int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLa } // add contents of underlying keyboard to All_Vector - if( mac_append_underlying_ToVector(All_Vector,keyboard_layout)) { + if( mac_append_underlying_ToVector(All_Vector, keyboard_layout)) { wprintf(L"ERROR: can't append underlying ToVector \n"); return 2; } @@ -49,25 +56,23 @@ int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLa int mac_write_US_ToVector( v_dw_3D &vec) { - v_dw_1D Values; - v_dw_2D Key; - - // _S2 unlike mcompile-linux we do not run a function to get the characters of the US keyboard but fix them like that: - // A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P, CR, L, J, ', K, ;, \, ,, /, N, M, . - std::vector US_Base = {97, 115, 100, 102, 104, 103, 122, 120, 99, 118, 167, 98, 113, 119, 101, 114, 121, 116, 49, 50, 51, 52, 54, 53, 61, 57, 55, 45, 56, 48, 93, 111, 117, 91, 105, 112, 13, 108, 106, 39, 107, 59, 92, 44, 47, 110, 109, 46}; - std::vector US_Shift = {65, 83, 68, 70, 72, 71, 90, 88, 67, 86, 177, 66, 81, 87, 69, 82, 89, 84, 33, 64, 35, 36, 94, 37, 43, 40, 38, 95, 42, 41, 125, 79, 85, 123, 73, 80, 13, 76, 74, 34, 75, 58, 124, 60, 63, 78, 77, 62}; - //std::vector US_Caps= {65, 83, 68, 70, 72, 71, 90, 88, 67, 86, 66, 81, 87, 69, 82, 89, 84, 49, 50, 51, 52, 54, 53, 61, 57, 55, 45, 56, 48, 93, 79, 85, 91, 73, 80, 76, 74, 39, 75, 59, 92, 44, 47, 78, 77, 46}; - - for ( int i=0; i< US_Base.size(); i++) { - Values.push_back( i ); - Values.push_back( US_Base[i]); - Values.push_back( US_Shift[i]); - Key.push_back(Values); - Values.clear(); + // Values for All_Vector: A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P,CR, L, J, ', K, ;, \, ,, /, N, M, . + std::vector us_Base = {97,115,100,102,104,103,122,120,99,118,167,98,113,119,101,114,121,116,49,50,51,52,54,53,61,57,55,45,56,48, 93,111,117, 91,105,112,13,108,106,39,107,59, 92,44,47,110,109,46}; + std::vector us_Shift = {65, 83, 68, 70, 72, 71, 90, 88,67, 86,177,66, 81, 87, 69, 82, 89, 84,33,64,35,36,94,37,43,40,38,95,42,41,125, 79, 85,123, 73, 80,13, 76, 74,34, 75,58,124,60,63, 78, 77,62}; + + v_dw_1D values; + v_dw_2D key; + + for ( int i=0; i< us_Base.size(); i++) { + values.push_back(i); + values.push_back(us_Base[i]); + values.push_back(us_Shift[i]); + key.push_back(values); + values.clear(); } - vec.push_back(Key); + vec.push_back(key); - if ( Key.size() == 0) { + if ( key.size() == 0) { wprintf(L"ERROR: can't Create Vector for US keyboard\n"); return 1; } @@ -75,25 +80,25 @@ int mac_write_US_ToVector( v_dw_3D &vec) { return 0; } -v_dw_2D mac_create_empty_2D_Vector( int dim_rows,int dim_ss) { +v_dw_2D mac_create_empty_2D_Vector( int dim_rows, int dim_ss) { - v_dw_1D shifts; - v_dw_2D Vector_2D; + v_dw_1D shift; + v_dw_2D vector_2D; for ( int i=0; i< dim_rows;i++) { for ( int j=0; j< dim_ss;j++) { - shifts.push_back(returnIfCharInvalid); + shift.push_back(returnIfCharInvalid); } - Vector_2D.push_back(shifts); - shifts.clear(); + vector_2D.push_back(shift); + shift.clear(); } - return Vector_2D; + return vector_2D; } int mac_append_underlying_ToVector(v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { // create a 2D vector all filled with " " and push to 3D-Vector - v_dw_2D underlying_Vector2D = mac_create_empty_2D_Vector(All_Vector[0].size(),All_Vector[0][0].size()); + v_dw_2D underlying_Vector2D = mac_create_empty_2D_Vector(All_Vector[0].size(), All_Vector[0][0].size()); if (underlying_Vector2D.size() == 0) { wprintf(L"ERROR: can't create empty 2D-Vector\n"); @@ -106,14 +111,13 @@ int mac_append_underlying_ToVector(v_dw_3D &All_Vector, const UCKeyboardLayout * return 1; } - for(int i =0; i< (int) All_Vector[1].size();i++) { + for(int i =0; i< All_Vector[1].size();i++) { // get key name US stored in [0][i][0] and copy to name in "underlying"-block[1][i][0] All_Vector[1][i][0] = All_Vector[0][i][0]; - // get Keyvals of this key and copy to unshifted/shifted in "underlying"-block[1][i][1] / block[1][i][2] - All_Vector[1][i][0+1] = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout,All_Vector[0][i][0],0); //shift state: unshifted:0 - All_Vector[1][i][1+1] = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout,All_Vector[0][i][0],1); //shift state: shifted:1 + All_Vector[1][i][0+1] = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, All_Vector[0][i][0], mac_map_Win_ShiftState_to_MacModifier(0)); //shift state: unshifted:0 + All_Vector[1][i][1+1] = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, All_Vector[0][i][0], mac_map_Win_ShiftState_to_MacModifier(1)); //shift state: shifted:1 } return 0; @@ -140,498 +144,209 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ -// _S2 TODO all -/*bool mac_IsKeymanUsedChar(int KV) { - // 32 A-Z a-z - if ((KV == 0x20 ) || (KV >= 65 && KV <= 90) || (KV >= 97 && KV <= 122) ) - return true; - else - return false; -}*/ - -// _S2 TODO all -std::u16string mac_convert_DeadkeyValues_To_U16str(int in) { -// _S2 not finished yet - needs deadkeys... -/* - if (in == 0 ) - return u"\0"; +// _S2 checked OK +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps) { - std::string long_name((const char*) gdk_keyval_name (in)); // e.g. "dead_circumflex" , "U+017F" , "t" - - if ( long_name.substr (0,2) == "U+" ) // U+... Unicode value - return mac_CodePointToU16String(in-0x1000000); - - if (in < (int) deadkey_min) { // no deadkey; no Unicode - return std::u16string(1, in); - } - - KMX_DWORD lname = mac_convertNamesTo_DWORD_Value(long_name); // 65106 => "dead_circumflex" => 94 => "^" - - if (lname != returnIfCharInvalid) { - return std::u16string(1, lname ); - } - else - return u"\0";*/ - - return std::u16string(1, in ); -} - -// _S2 TODO dk/non-dk -// _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk? -int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { - // _S2 not finished yet - needs deadkeys... - KMX_DWORD in_array[2] = {0,0}; - UInt32 deadkeystate = 0; + UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; + OptionBits keyTranslateOptions = 0; UniChar unicodeString[maxStringlength]; - OSStatus status; + OSStatus status ; + unicodeString[0] = 0; - // _S2 bette solution for 4*CAPS ???? - status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - // If this was a deadkey, append a space - if(deadkeystate !=0) - status = UCKeyTranslate(keyboard_layout, Keycode_Spacebar ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if (!keyboard_layout) + return 0; - // UCKeyTranslate writes 0x01 into unicodeString[0] if there is no character assigned to the Key+Shift+CAPS - // ( then returnes 0 -> 0 is then propagated to ... mac_KMX_ToUnicodeEx (-> rc=0) .. ImportRules (rc=0-> do nothing ) ) + if (!(keycode <= keycode_max)) + return 0; - // _S2 no deadkeys yet or check last bit - if( shiftstate %2 == 1) - return 0; // _S2 what to return if deadkeys are used?? + if (!(shiftstate_mac <= max_shiftstate)) + return 0; - else { - if( (int) unicodeString[0] == 1 ) // impossible character - return 0; - else { - return (int) unicodeString[0]; // even: combine char -> è - } - } - return 0; -} -// _S2 TODO dk/non-dk -// _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk? -int mac_KMX_get_KeyVal_From_KeyCode_S2(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { - // _S2 not finished yet - needs deadkeys... - KMX_DWORD in_array[2] = {0,0}; - UInt32 deadkeystate = 0; - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - OSStatus status; - //int Keycode_Spacebar =49; + if (!(caps <= 1)) + return 0; - // _S2 bette solution for 4*CAPS ???? - status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - // If this was a deadkey, append a space + status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // If this was a deadkey,append a space if(deadkeystate !=0) - status = UCKeyTranslate(keyboard_layout, Keycode_Spacebar ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - - // UCKeyTranslate writes 0x01 into unicodeString[0] if there is no character assigned to the Key+Shift+CAPS - // ( then returnes 0 -> 0 is then propagated to ... mac_KMX_ToUnicodeEx (-> rc=0) .. ImportRules (rc=0-> do nothing ) ) - - // _S2 no deadkeys yet or check last bit - if( shiftstate %2 == 1) - return 0; // _S2 what to return if deadkeys are used?? + status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown, (shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // if there is no character assigned to the Key+Shift+CAPS UCKeyTranslate writes 0x01 into unicodeString[0] + if( unicodeString[0] == 1 ) // impossible character + return 0; else { - if( (int) unicodeString[0] == 1 ) // impossible character - return 0; - else { - return (int) unicodeString[0]; // even: combine char -> è - } + return unicodeString[0]; // combined char e.g. â } + return 0; } - -int mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps, UInt32 &deadkeystate) { +//--------------------------------------------------- +// _S2 checked OK +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32 &deadkeystate) { UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; + OptionBits keyTranslateOptions = 0; UniChar unicodeString[maxStringlength]; - //int Keycode_Spacebar =49; + unicodeString[0] = 0; OSStatus status; - // _S2 bette solution for 4*CAPS ???? - status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if (!keyboard_layout) + return 0; - // If this was a deadkey, append a space - if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, Keycode_Spacebar ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - } + if (!(keycode <= keycode_max)) + return 0; - if( keycode==0x999) - return L'\0'; - return (int) unicodeString[0]; -} + if (!(shiftstate_mac <= max_shiftstate)) + return 0; -// _S2 TODO dk/non-dk -int mac_KMX_get_KeyVal_underlying_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { - // _S2 not finished yet - needs deadkeys... - KMX_DWORD in_array[2] = {0,0}; - UInt32 deadkeystate = 0; - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - OSStatus status; - int returnint=0; + if (!(caps <= 1)) + return 0; - status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 + status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown,(shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - // no deadkey yet - if( shiftstate %2 == 1) - return 0; // _S2 what to return if deadkeys are used?? - else { - in_array[0] = (int) unicodeString[0]; // even: combine char -> è - returnint = in_array[0]; - return returnint; - } + // If this was a deadkey,append a space + if(deadkeystate !=0) + status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown,(shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - return returnint; + // if there is no character assigned to the Key+Shift+CAPS UCKeyTranslate writes 0x01 into unicodeString[0] + if(unicodeString[0] == 1 ) // impossible character + return 0; + else + return unicodeString[0]; // combined char e.g. â } -// _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk? -/*int mac_KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps) { - - GdkModifierType consumed; - GdkKeymapKey *maps; - guint *keyvals; - gint count; +//--------------------------------------------------- +// _S2 checked OK +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int kc_underlying, int shiftstate_mac) { + KMX_DWORD kVal; + int caps=0; - if (!gdk_keymap_get_entries_for_keycode(keymap, keycode, &maps, &keyvals, &count)) + if (!keyboard_layout) return 0; - //BASE (shiftstate: 0) - if (( ss == Base ) && ( caps == 0 )) { - GdkModifierType MOD_base = (GdkModifierType) ( ~GDK_MODIFIER_MASK ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_base , 0, keyvals, NULL, NULL, & consumed); - } - - //BASE + CAPS (shiftstate: 0) - else if (( ss == Base ) && ( caps == 1 )) { - GdkModifierType MOD_Caps = (GdkModifierType) ( GDK_LOCK_MASK ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_Caps, 0, keyvals, NULL, NULL, & consumed); - } - - //SHIFT (shiftstate: 1) - else if (( ss == Shft ) && ( caps == 0 )) { - GdkModifierType MOD_Shift = (GdkModifierType) ( GDK_SHIFT_MASK ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_Shift , 0, keyvals, NULL, NULL, & consumed); - } - - //SHIFT + CAPS (shiftstate: 1) - else if ( ( ss == Shft ) && ( caps ==1 )) { - GdkModifierType MOD_ShiftCaps= (GdkModifierType) ((GDK_SHIFT_MASK | GDK_LOCK_MASK)); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_ShiftCaps , 0, keyvals, NULL, NULL, & consumed); - } - - // Ctrl (shiftstate: 2) - else if (( ss == Ctrl ) && ( caps == 0 )){ - GdkModifierType MOD_Ctrl = (GdkModifierType) ( GDK_MOD5_MASK ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_Ctrl , 0, keyvals, NULL, NULL, & consumed); - } - - // Ctrl + CAPS (shiftstate: 2) - else if (( ss == Ctrl ) && ( caps == 1 )){ - GdkModifierType MOD_CtrlCaps = (GdkModifierType) (GDK_MOD5_MASK | GDK_LOCK_MASK); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_CtrlCaps , 0, keyvals, NULL, NULL, & consumed); - } - - // SHIFT+Ctrl (shiftstate: 3) - else if (( ss == ShftCtrl ) && ( caps == 0 )){ - GdkModifierType MOD_Ctrl = (GdkModifierType) (GDK_SHIFT_MASK | GDK_MOD5_MASK ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_Ctrl , 0, keyvals, NULL, NULL, & consumed); - } - - // SHIFT+Ctrl + CAPS (shiftstate: 3) - else if (( ss == ShftCtrl ) && ( caps == 1 )){ - GdkModifierType MOD_CtrlCaps = (GdkModifierType) ( GDK_SHIFT_MASK | GDK_MOD5_MASK | GDK_LOCK_MASK); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_CtrlCaps , 0, keyvals, NULL, NULL, & consumed); - } - - //ALT-GR (shiftstate: 6) - else if (( ss == MenuCtrl ) && ( caps == 0 )){ - GdkModifierType MOD_AltGr = (GdkModifierType) (GDK_MOD2_MASK | GDK_MOD5_MASK); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_AltGr , 0, keyvals, NULL, NULL, & consumed); - } - - //ALT-GR + CAPS (shiftstate: 6) - else if (( ss == MenuCtrl ) && ( caps == 1 )){ - GdkModifierType MOD_AltGr = (GdkModifierType) (GDK_MOD2_MASK | GDK_MOD5_MASK | GDK_LOCK_MASK); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_AltGr , 0, keyvals, NULL, NULL, & consumed); - } - - //ALT-GR (shiftstate: 7) - else if (( ss == ShftMenuCtrl ) && ( caps == 0 )){ - GdkModifierType MOD_AltGr = (GdkModifierType) ( (GDK_SHIFT_MASK | GDK_MOD2_MASK | GDK_MOD5_MASK) ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_AltGr , 0, keyvals, NULL, NULL, & consumed); - } - - //ALT-GR +CAPS (shiftstate: 7) - else if (( ss == ShftMenuCtrl ) && ( caps == 1 )){ - GdkModifierType MOD_AltGr = (GdkModifierType) ( (GDK_SHIFT_MASK | GDK_MOD2_MASK | GDK_MOD5_MASK | GDK_LOCK_MASK) ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_AltGr , 0, keyvals, NULL, NULL, & consumed); - } - else + if (!(kc_underlying <= keycode_max)) return 0; - return (int) *keyvals; -}*/ - -// _S2 TODO dk -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int keycode, int shift_state_pos) { - - //KMX_DWORD KVal = mac_get_keyval_From_Keycode(keycode, shift_state_pos*2 , keyboard_layout ); - - KMX_DWORD KVal= mac_get_keyval_From_Keycode_new(keycode,keyboard_layout , shift_state_pos*2); - - int count = max_shiftstate; - if (!(shift_state_pos <= count*2)) + if (!(shiftstate_mac <= max_shiftstate)) return 0; - if (!(keycode <= keycode_max)) - return 0; + kVal = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_underlying, mac_map_Win_ShiftState_to_MacModifier(shiftstate_mac), caps); - return KVal; + return kVal; } +//--------------------------------------------------- +// _S2 checked OK +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey) { -// _S2 TODO VKShiftstate -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey) { - - PKMX_WCHAR dky=NULL; - UInt32 isdk=0; + PKMX_WCHAR dky = NULL; + UInt32 isdk = 0; + KMX_DWORD keyV; + int caps = 0; if (!keyboard_layout) return 0; -/*// _S2 needed? - int count; - if (!(mac_map_VKShiftState_to_MacModifier(VKShiftState) <= count)) - return 0; + if(!(is_correct_win_shiftstate(vk_ShiftState))) + return 0; - if (!(KC_underlying <= keycode_max)) + if (!(kc_underlying <= keycode_max)) return 0; - */ - KMX_DWORD KeyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, KC_underlying, (mac_map_VKShiftState_to_MacModifier(VKShiftState)), 0, isdk); + keyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, kc_underlying,(mac_map_VKShiftState_to_MacModifier(vk_ShiftState)), caps, isdk); - // if there was a dk return 0xFFFF and copy dk into dky + // if there was a deadkey return 0xFFFF and copy deadkey into dky if( isdk !=0) { - dky = (PKMX_WCHAR) (mac_convert_DeadkeyValues_To_U16str((int) KeyV)).c_str(); - *DeadKey = *dky; + dky = (PKMX_WCHAR) (std::u16string(1, keyV)).c_str(); + *deadKey = *dky; return 0xFFFF; } - *DeadKey= 0; - return KeyV; + *deadKey = 0; + return keyV; } - -// _S2 TODO dk -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD Keyval_US) { - KMX_DWORD VK_underlying; - for( int i=0; i< (int)All_Vector[0].size()-1 ;i++) { - for( int j=1; j< (int)All_Vector[0][0].size();j++) { - if ( All_Vector[0][i][j] == Keyval_US ) { - VK_underlying = All_Vector[1][i][j]; - return VK_underlying; - } +//--------------------------------------------------- +// _S2 checked OK +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD kv_us) { + + for( int i=0; i< All_Vector[0].size()-1 ;i++) { + for( int j=1; j< All_Vector[0][0].size();j++) { + if ( All_Vector[0][i][j] == kv_us ) + return All_Vector[1][i][j]; } } - return Keyval_US; + return kv_us; } +// _S2 checked OK +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vector, KMX_DWORD kv_underlying) { -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vector, KMX_DWORD KV_Underlying) { - for( int i=0; i< (int)All_Vector[1].size()-1 ;i++) { - for( int j=1; j< (int)All_Vector[1][0].size();j++) { - if ( All_Vector[1][i][j] == KV_Underlying ) { + for( int i=0; i< All_Vector[1].size()-1 ;i++) { + for( int j=1; j< All_Vector[1][0].size();j++) { + if ( All_Vector[1][i][j] == kv_underlying ) { return All_Vector[1][i][0]; } } } - return KV_Underlying; + return kv_underlying; } +// _S2 checked OK +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_DWORD kc_us, ShiftState ss, int caps) { -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_DWORD KC_US, ShiftState ss, int caps) { - KMX_DWORD KC_underlying; - // _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk? - std::u16string u16str = mac_convert_DeadkeyValues_To_U16str(mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, KC_US, ss, caps)); + std::u16string u16str_map= std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_map_Win_ShiftState_to_MacModifier(ss), caps) ); - for( int i=0; i< (int)All_Vector[1].size()-1 ;i++) { - for( int j=1; j< (int)All_Vector[1][0].size();j++) { - if ( ((KMX_DWORD) All_Vector[1][i][j] == (KMX_DWORD) *u16str.c_str() ) ) { - KC_underlying = All_Vector[1][i][0]; - return KC_underlying; - } + for( int i=0; i< All_Vector[1].size()-1 ;i++) { + for( int j=1; j< All_Vector[1][0].size();j++) { + if ( ((KMX_DWORD) All_Vector[1][i][j] == (KMX_DWORD) *u16str_map.c_str() ) ) + return All_Vector[1][i][0]; } } - return KC_US; + return kc_us; } - -UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS) { - uint ret= (mac_USVirtualKeyToScanCode[VirtualKeyUS]); // _S2 can go later - return (mac_USVirtualKeyToScanCode[VirtualKeyUS]); +// _S2 checked OK +UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us) { + return (mac_USVirtualKeyToScanCode[vk_us]); } - -// _S2 OK?? +// _S2 checked OK KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { - /*if ( keycode >7) - return (KMX_DWORD) ScanCodeToUSVirtualKey[keycode-8]; - - return 0;*/ - - return (KMX_DWORD) mac_ScanCodeToUSVirtualKey[keycode]; - return 0; + return mac_ScanCodeToUSVirtualKey[keycode]; } -/*std::u16string mac_CodePointToU16String(unsigned int codepoint) { - std::u16string str; - - if constexpr (sizeof(wchar_t) > 2) { - str = static_cast(codepoint); - } - else if (codepoint <= 0xFFFF) { - str = static_cast(codepoint); - } - else { - codepoint -= 0x10000; - str.resize(2); - str[0] = static_cast(0xD800 + ((codepoint >> 10) & 0x3FF)); - str[1] = static_cast(0xDC00 + (codepoint & 0x3FF)); - } - - return str; -}*/ - - //################################################################################################################################################ //################################################################################################################################################ +// _S2 checked_OK +KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps) { - -std::u16string mac_get_character_From_Keycode(int dk, int ch , int shiftstate) { - - std::u16string character; - std::vector keyvals; - keyvals.push_back(dk); - keyvals.push_back(ch); - - TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); - CFDataRef layout_data = static_cast((TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData))); - const UCKeyboardLayout* keyboard_layout = reinterpret_cast(CFDataGetBytePtr(layout_data)); - - if (layout_data) - character = mac_get_character_From_Keycode(keyvals, shiftstate, keyboard_layout); - - return character; -} - -std::u16string mac_get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { - char16_t ch_array[3] = {L'\0'}; - UInt32 deadkeystate = 0; - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - OSStatus status; - - for ( int i =0; i < keyval.size(); i++) { - - status = UCKeyTranslate(keyboard_layout, keyval[i] ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - if( shiftstate %2 == 1 ) // uneven: seperate char -> `e - ch_array[i] = (char16_t) unicodeString[0]; - else - ch_array[0] = (char16_t) unicodeString[0]; // even: combine char -> è - } - - std::u16string returnString(ch_array); - return returnString; -} - -KMX_DWORD mac_get_keyval_From_Keycode_new(int VK_dk,const UCKeyboardLayout* keyboard_layout , KMX_DWORD shiftstate) { - - UInt32 deadkeystate = 0; - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - OSStatus status; - - status = UCKeyTranslate(keyboard_layout, VK_dk ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - - // If this was a deadkey, append a space - if(deadkeystate !=0) - - status = UCKeyTranslate(keyboard_layout, 49 ,kUCKeyActionDown, 0, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - - return unicodeString[0]; -} - -KMX_DWORD mac_get_CombinedChar_From_DK(int VK_dk,KMX_DWORD ss_dk,const UCKeyboardLayout* keyboard_layout, KMX_DWORD VK_US, KMX_DWORD shiftstate, int caps) { - - UInt32 deadkeystate = 0; + UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; + OptionBits keyTranslateOptions = 0; UniChar unicodeString[maxStringlength]; + unicodeString[0] = 0; OSStatus status; - status = UCKeyTranslate(keyboard_layout, VK_dk ,kUCKeyActionDown, ss_dk, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + status = UCKeyTranslate(keyboard_layout, vk_dk, kUCKeyActionDown, ss_dk, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - // If this was a deadkey, append a space + // If this was a deadkey,append a character if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, (UInt16) VK_US ,kUCKeyActionDown, shiftstate+4*caps, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - return unicodeString[0]; + status = UCKeyTranslate(keyboard_layout,(UInt16) vk_us, kUCKeyActionDown, shiftstate_mac+4*caps, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + + if(unicodeString[0] == 1 ) // impossible character + return 0; + else + return unicodeString[0]; // combined char e.g. â } else - return 0; -} - -/* KMX_DWORD mac_get_keyval_From_Keycode(int keyval, int shiftstate, const UCKeyboardLayout* keyboard_layout ) { - - UInt32 deadkeystate = 0; - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - OSStatus status; - int treat_dk_as_Character = 1; // e.g. ^ = 94 - - //status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - - status = UCKeyTranslate(keyboard_layout, keyval ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - //status = UCKeyTranslate(keyboard_layout, keyval ,kUCKeyActionDown, shiftstate , LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - return unicodeString[0]; -} -*/ - -/*KMX_DWORD mac_get_keyval_From_Keycode_old(int keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { - - KMX_DWORD in_array[2] = {0,0}; - UInt32 deadkeystate = 0; - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - OSStatus status; - int treat_dk_as_Character = 1; // e.g. ^ = 94 - int returnint=0; - - status = UCKeyTranslate(keyboard_layout, keyval ,kUCKeyActionDown, shiftstate + treat_dk_as_Character, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - // no deadkey yet - if( shiftstate %2 == 1) - return 0; // _S2 what to return if deadkeys are used?? - else { - in_array[0] = (int) unicodeString[0]; // even: combine char -> è - returnint = in_array[0]; - return returnint; - } - -return returnint; + return 0; } -*/ -void printoutKeyboards(v_dw_3D &All_Vector) { +void test_printoutKeyboards_S2(v_dw_3D &All_Vector) { printf(" values of US - Values of underlying"); for ( int i=0; i< All_Vector[0].size(); i++) { printf("-----------------------------\n"); for ( int j=0; j< All_Vector[0][0].size(); j++) { - printf("i:%i\tUS: %i(%c)\t Underlying: %i(%c)\t \t\t\t%c \n" , i, All_Vector[0][i][j] , All_Vector[0][i][j] , All_Vector[1][i][j], All_Vector[1][i][j], (All_Vector[0][i][j] == All_Vector[1][i][j]) ? '.' : '*'); + printf("i:%i\tUS: %i(%c)\t Underlying: %i(%c)\t \t\t\t%c \n", i,All_Vector[0][i][j] , All_Vector[0][i][j] , All_Vector[1][i][j],All_Vector[1][i][j],(All_Vector[0][i][j] == All_Vector[1][i][j]) ? '.' : '*'); } } } - - diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 6295d4ec29e..e9ca11ca0d7 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -3,40 +3,15 @@ #ifndef KEYMAP_H #define KEYMAP_H -// compile with. gcc -framework Carbon -o Bla.exe HW.cpp +// compile with. gcc -framework Carbon -o xxx.exe yy.cpp // #import #include #include #include #include - #include "u16.h" -std::u16string mac_get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout); - -KMX_DWORD mac_get_keyval_From_Keycode_new(int charVal,const UCKeyboardLayout* keyboard_layout , KMX_DWORD shiftstate); -KMX_DWORD mac_get_CombinedChar_From_DK(int charVal,KMX_DWORD ss_dk,const UCKeyboardLayout* keyboard_layout, KMX_DWORD VK_US, KMX_DWORD shiftstate, int caps); -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - -// In ths program we use a 3D-Vector Vector[language][Keys][Shiftstates] -/* - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -*/ - enum ShiftState { Base = 0, // 0 Shft = 1, // 1 @@ -50,6 +25,9 @@ enum ShiftState { ShftXxxx = Shft | Xxxx, // 9 }; +// the shiftstates we can use for mac: Base;Shift, OPTION, Shift+OPTION +static int ss_mac[]={0,2,8,10}; + // Map of all US English virtual key codes that we can translate const KMX_DWORD KMX_VKMap[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', @@ -57,7 +35,7 @@ const KMX_DWORD KMX_VKMap[] = { VK_SPACE, // 32 // - VK_ACCENT, // 192 VK_OEM_3 K_BKQUOTE // + VK_ACCENT, // 192 VK_OEM_3 K_BKQUOTE // VK_HYPHEN, // - 189 VK_OEM_MINUS // VK_EQUAL, // = 187 VK_OEM_PLUS // @@ -78,30 +56,31 @@ const KMX_DWORD KMX_VKMap[] = { }; typedef std::vector v_str_1D; - typedef std::vector v_dw_1D; typedef std::vector > v_dw_2D; typedef std::vector > > v_dw_3D; - static KMX_DWORD returnIfCharInvalid = 0; -static KMX_DWORD max_shiftstate = 2; // _S2 only base+Shift -static KMX_DWORD keycode_max = 94; // _S2 needed?? -//static KMX_DWORD deadkey_min = 0xfe50; // _S2 needed?? -//static KMX_DWORD deadkey_max = 0xfe93; // _S2 needed?? -static int Keycode_Spacebar =49; -//static KMX_DWORD deadkey_max = 0xfe52; // _S2 TOP_6 TODO This has to go! my test: to only return 3 dk +static KMX_DWORD max_shiftstate = 10; +static KMX_DWORD keycode_max = 50; +static int keycode_spacebar = 49; -// map VKShiftstate to modifier (use 0,2,4,8,10 instead of 0,16,9,25 ) -int mac_map_VKShiftState_to_MacModifier(int VKShiftState); +// map vk_ShiftState to modifier (use 0,2,4,8,10 instead of 0,16,9,25 ) +int mac_map_VKShiftState_to_MacModifier(int vk_ShiftState); -// map ShiftState to modifier (use 0,2,4,8,10 instead of Base, Shft, Opt, Sh+Opt ) -int mac_map_ShiftState_to_MacModifier(int ShiftState); +// map win_ShiftState to modifier (use 0,2,4,8,10 instead of Base, Shft, Opt, Sh+Opt ) +int mac_map_Win_ShiftState_to_MacModifier(int win_ShiftState); + +// make sure a correct shiftstate was passed +//bool is_correct_mac_shiftstate(int comp_ss); +//bool is_correct_rgkey_shiftstate(int comp_ss); +bool is_correct_win_shiftstate(int comp_ss); // create a Vector with all entries of both keymaps int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLayout * keykeyboard_layout); // read configuration file, split and write to 3D-Vector (Data for US on Vector[0][ ][ ] ) int mac_write_US_ToVector(v_dw_3D &vec); + // create an empty 2D vector containing 0 in all fields v_dw_2D mac_create_empty_2D_Vector(int dim_rows, int dim_shifts); @@ -111,846 +90,450 @@ int mac_append_underlying_ToVector(v_dw_3D &All_Vector, const UCKeyboardLayout * // initialize UCHR bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout); //------------------------------ -/* -const UINT USVirtualKeyToScanCode[256] = { - 0x00, // L"K_?00", // &H0 - 0x00, // L"K_LBUTTON", // &H1 - 0x00, // L"K_RBUTTON", // &H2 - 0x46, // L"K_CANCEL", // &H3 - 0x00, // L"K_MBUTTON", // &H4 - 0x00, // L"K_?05", // &H5 - 0x00, // L"K_?06", // &H6 - 0x00, // L"K_?07", // &H7 - 0x0E, // L"K_BKSP", // &H8 - 0x0F, // L"K_TAB", // &H9 - 0x00, // L"K_?0A", // &HA - 0x00, // L"K_?0B", // &HB - 0x4C, // L"K_KP5", // &HC - 0x1C, // L"K_ENTER", // &HD - 0x00, // L"K_?0E", // &HE - 0x00, // L"K_?0F", // &HF - 0x2A, // L"K_SHIFT", // &H10 - 0x1D, // L"K_CONTRO0x00, // L", // &H11 - 0x38, // L"K_ALT", // &H12 - 0x00, // L"K_PAUSE", // &H13 - 0x3A, // L"K_CAPS", // &H14 - 0x00, // L"K_KANJI?15", // &H15 - 0x00, // L"K_KANJI?16", // &H16 - 0x00, // L"K_KANJI?17", // &H17 - 0x00, // L"K_KANJI?18", // &H18 - 0x00, // L"K_KANJI?19", // &H19 - 0x00, // L"K_?1A", // &H1A - 0x01, // L"K_ESC", // &H1B - 0x00, // L"K_KANJI?1C", // &H1C - 0x00, // L"K_KANJI?1D", // &H1D - 0x00, // L"K_KANJI?1E", // &H1E - 0x00, // L"K_KANJI?1F", // &H1F - 0x39, // L"K_SPACE", // &H20 - 0x49, // L"K_PGUP", // &H21 - 0x51, // L"K_PGDN", // &H22 - 0x4F, // L"K_END", // &H23 - 0x47, // L"K_HOME", // &H24 - 0x4B, // L"K_LEFT", // &H25 - 0x48, // L"K_UP", // &H26 - 0x4D, // L"K_RIGHT", // &H27 - 0x50, // L"K_DOWN", // &H28 - 0x00, // L"K_SEL", // &H29 - 0x00, // L"K_PRINT", // &H2A - 0x00, // L"K_EXEC", // &H2B - 0x54, // L"K_PRTSCN", // &H2C - 0x52, // L"K_INS", // &H2D - 0x53, // L"K_DEL", // &H2E - 0x63, // L"K_HELP", // &H2F - 0x0B, // L"K_0", // &H30 - 0x02, // L"K_1", // &H31 - 0x03, // L"K_2", // &H32 - 0x04, // L"K_3", // &H33 - 0x05, // L"K_4", // &H34 - 0x06, // L"K_5", // &H35 - 0x07, // L"K_6", // &H36 - 0x08, // L"K_7", // &H37 - 0x09, // L"K_8", // &H38 - 0x0A, // L"K_9", // &H39 - 0x00, // L"K_?3A", // &H3A - 0x00, // L"K_?3B", // &H3B - 0x00, // L"K_?3C", // &H3C - 0x00, // L"K_?3D", // &H3D - 0x00, // L"K_?3E", // &H3E - 0x00, // L"K_?3F", // &H3F - 0x00, // L"K_?40", // &H40 - 0x1E, // L"K_A", // &H41 - 0x30, // L"K_B", // &H42 - 0x2E, // L"K_C", // &H43 - 0x20, // L"K_D", // &H44 - 0x12, // L"K_E", // &H45 - 0x21, // L"K_F", // &H46 - 0x22, // L"K_G", // &H47 - 0x23, // L"K_H", // &H48 - 0x17, // L"K_I", // &H49 - 0x24, // L"K_J", // &H4A - 0x25, // L"K_K", // &H4B - 0x26, // L"K_L", // &H4C - 0x32, // L"K_M", // &H4D - 0x31, // L"K_N", // &H4E - 0x18, // L"K_O", // &H4F - 0x19, // L"K_P", // &H50 - 0x10, // L"K_Q", // &H51 - 0x13, // L"K_R", // &H52 - 0x1F, // L"K_S", // &H53 - 0x14, // L"K_T", // &H54 - 0x16, // L"K_U", // &H55 - 0x2F, // L"K_V", // &H56 - 0x11, // L"K_W", // &H57 - 0x2D, // L"K_X", // &H58 - 0x15, // L"K_Y", // &H59 - 0x2C, // L"K_Z", // &H5A - 0x5B, // L"K_?5B", // &H5B - 0x5C, // L"K_?5C", // &H5C - 0x5D, // L"K_?5D", // &H5D - 0x00, // L"K_?5E", // &H5E - 0x5F, // L"K_?5F", // &H5F - 0x52, // L"K_NP0", // &H60 - 0x4F, // L"K_NP1", // &H61 - 0x50, // L"K_NP2", // &H62 - 0x51, // L"K_NP3", // &H63 - 0x4B, // L"K_NP4", // &H64 - 0x4C, // L"K_NP5", // &H65 - 0x4D, // L"K_NP6", // &H66 - 0x47, // L"K_NP7", // &H67 - 0x48, // L"K_NP8", // &H68 - 0x49, // L"K_NP9", // &H69 - 0x37, // L"K_NPSTAR", // &H6A - 0x4E, // L"K_NPPLUS", // &H6B - 0x7E, // L"K_SEPARATOR", // &H6C // MCD 01-11-02: Brazilian Fix, 00 -> 7E - 0x4A, // L"K_NPMINUS", // &H6D - 0x53, // L"K_NPDOT", // &H6E - 0x135, // L"K_NPSLASH", // &H6F - 0x3B, // L"K_F1", // &H70 - 0x3C, // L"K_F2", // &H71 - 0x3D, // L"K_F3", // &H72 - 0x3E, // L"K_F4", // &H73 - 0x3F, // L"K_F5", // &H74 - 0x40, // L"K_F6", // &H75 - 0x41, // L"K_F7", // &H76 - 0x42, // L"K_F8", // &H77 - 0x43, // L"K_F9", // &H78 - 0x44, // L"K_F10", // &H79 - 0x57, // L"K_F11", // &H7A - 0x58, // L"K_F12", // &H7B - 0x64, // L"K_F13", // &H7C - 0x65, // L"K_F14", // &H7D - 0x66, // L"K_F15", // &H7E - 0x67, // L"K_F16", // &H7F - 0x68, // L"K_F17", // &H80 - 0x69, // L"K_F18", // &H81 - 0x6A, // L"K_F19", // &H82 - 0x6B, // L"K_F20", // &H83 - 0x6C, // L"K_F21", // &H84 - 0x6D, // L"K_F22", // &H85 - 0x6E, // L"K_F23", // &H86 - 0x76, // L"K_F24", // &H87 - - 0x00, // L"K_?88", // &H88 - 0x00, // L"K_?89", // &H89 - 0x00, // L"K_?8A", // &H8A - 0x00, // L"K_?8B", // &H8B - 0x00, // L"K_?8C", // &H8C - 0x00, // L"K_?8D", // &H8D - 0x00, // L"K_?8E", // &H8E - 0x00, // L"K_?8F", // &H8F - - 0x45, // L"K_NUMLOCK", // &H90 - 0x46, // L"K_SCROL0x00, // &H91 - - 0x00, // L"K_?92", // &H92 - 0x00, // L"K_?93", // &H93 - 0x00, // L"K_?94", // &H94 - 0x00, // L"K_?95", // &H95 - 0x00, // L"K_?96", // &H96 - 0x00, // L"K_?97", // &H97 - 0x00, // L"K_?98", // &H98 - 0x00, // L"K_?99", // &H99 - 0x00, // L"K_?9A", // &H9A - 0x00, // L"K_?9B", // &H9B - 0x00, // L"K_?9C", // &H9C - 0x00, // L"K_?9D", // &H9D - 0x00, // L"K_?9E", // &H9E - 0x00, // L"K_?9F", // &H9F - 0x2A, // L"K_?A0", // &HA0 - 0x36, // L"K_?A1", // &HA1 - 0x1D, // L"K_?A2", // &HA2 - 0x1D, // L"K_?A3", // &HA3 - 0x38, // L"K_?A4", // &HA4 - 0x38, // L"K_?A5", // &HA5 - 0x6A, // L"K_?A6", // &HA6 - 0x69, // L"K_?A7", // &HA7 - 0x67, // L"K_?A8", // &HA8 - 0x68, // L"K_?A9", // &HA9 - 0x65, // L"K_?AA", // &HAA - 0x66, // L"K_?AB", // &HAB - 0x32, // L"K_?AC", // &HAC - 0x20, // L"K_?AD", // &HAD - 0x2E, // L"K_?AE", // &HAE - 0x30, // L"K_?AF", // &HAF - 0x19, // L"K_?B0", // &HB0 - 0x10, // L"K_?B1", // &HB1 - 0x24, // L"K_?B2", // &HB2 - 0x22, // L"K_?B3", // &HB3 - 0x6C, // L"K_?B4", // &HB4 - 0x6D, // L"K_?B5", // &HB5 - 0x6B, // L"K_?B6", // &HB6 - 0x21, // L"K_?B7", // &HB7 - 0x00, // L"K_?B8", // &HB8 - 0x00, // L"K_?B9", // &HB9 - 0x27, // L"K_COLON", // &HBA - 0x0D, // L"K_EQUA0x00, // L", // &HBB - 0x33, // L"K_COMMA", // &HBC - 0x0C, // L"K_HYPHEN", // &HBD - 0x34, // L"K_PERIOD", // &HBE - 0x35, // L"K_SLASH", // &HBF - 0x29, // L"K_BKQUOTE", // &HC0 - - 0x73, // L"K_?C1", // &HC1 - 0x7E, // L"K_?C2", // &HC2 - 0x00, // L"K_?C3", // &HC3 - 0x00, // L"K_?C4", // &HC4 - 0x00, // L"K_?C5", // &HC5 - 0x00, // L"K_?C6", // &HC6 - 0x00, // L"K_?C7", // &HC7 - 0x00, // L"K_?C8", // &HC8 - 0x00, // L"K_?C9", // &HC9 - 0x00, // L"K_?CA", // &HCA - 0x00, // L"K_?CB", // &HCB - 0x00, // L"K_?CC", // &HCC - 0x00, // L"K_?CD", // &HCD - 0x00, // L"K_?CE", // &HCE - 0x00, // L"K_?CF", // &HCF - 0x00, // L"K_?D0", // &HD0 - 0x00, // L"K_?D1", // &HD1 - 0x00, // L"K_?D2", // &HD2 - 0x00, // L"K_?D3", // &HD3 - 0x00, // L"K_?D4", // &HD4 - 0x00, // L"K_?D5", // &HD5 - 0x00, // L"K_?D6", // &HD6 - 0x00, // L"K_?D7", // &HD7 - 0x00, // L"K_?D8", // &HD8 - 0x00, // L"K_?D9", // &HD9 - 0x00, // L"K_?DA", // &HDA - 0x1A, // L"K_LBRKT", // &HDB - 0x2B, // L"K_BKSLASH", // &HDC - 0x1B, // L"K_RBRKT", // &HDD - 0x28, // L"K_QUOTE", // &HDE - 0x73, // L"K_oDF", // &HDF // MCD 01-11-02: Brazilian fix: 00 -> 73 - 0x00, // L"K_oE0", // &HE0 - 0x00, // L"K_oE1", // &HE1 - 0x56, // L"K_oE2", // &HE2 - 0x00, // L"K_oE3", // &HE3 - 0x00, // L"K_oE4", // &HE4 - - 0x00, // L"K_?E5", // &HE5 - - 0x00, // L"K_oE6", // &HE6 - - 0x00, // L"K_?E7", // &HE7 - 0x00, // L"K_?E8", // &HE8 - - 0x71, // L"K_oE9", // &HE9 - 0x5C, // L"K_oEA", // &HEA - 0x7B, // L"K_oEB", // &HEB - 0x00, // L"K_oEC", // &HEC - 0x6F, // L"K_oED", // &HED - 0x5A, // L"K_oEE", // &HEE - 0x00, // L"K_oEF", // &HEF - 0x00, // L"K_oF0", // &HF0 - 0x5B, // L"K_oF1", // &HF1 - 0x00, // L"K_oF2", // &HF2 - 0x5F, // L"K_oF3", // &HF3 - 0x00, // L"K_oF4", // &HF4 - 0x5E, // L"K_oF5", // &HF5 - - 0x00, // L"K_?F6", // &HF6 - 0x00, // L"K_?F7", // &HF7 - 0x00, // L"K_?F8", // &HF8 - 0x5D, // L"K_?F9", // &HF9 - 0x00, // L"K_?FA", // &HFA - 0x62, // L"K_?FB", // &HFB - 0x00, // L"K_?FC", // &HFC - 0x00, // L"K_?FD", // &HFD - 0x00, // L"K_?FE", // &HFE - 0x00 // L"K_?FF" // &HFF -}; -const UINT ScanCodeToUSVirtualKey[128] = { - 0x01, // 0x00 => K_LBUTTON - 0x1b, // 0x01 => K_ESC - 0x31, // 0x02 => K_1 - 0x32, // 0x03 => K_2 - 0x33, // 0x04 => K_3 - 0x34, // 0x05 => K_4 - 0x35, // 0x06 => K_5 - 0x36, // 0x07 => K_6 - 0x37, // 0x08 => K_7 - 0x38, // 0x09 => K_8 - 0x39, // 0x0a => K_9 - 0x30, // 0x0b => K_0 - 0xbd, // 0x0c => K_HYPHEN - 0xbb, // 0x0d => K_EQUAL - 0x08, // 0x0e => K_BKSP - 0x09, // 0x0f => K_TAB - 0x51, // 0x10 => K_Q - 0x57, // 0x11 => K_W - 0x45, // 0x12 => K_E - 0x52, // 0x13 => K_R - 0x54, // 0x14 => K_T 20 - 0x59, // 0x15 => K_Y - 0x55, // 0x16 => K_U - 0x49, // 0x17 => K_I - 0x4f, // 0x18 => K_O - 0x50, // 0x19 => K_P - 0xdb, // 0x1a => K_LBRKT - 0xdd, // 0x1b => K_RBRKT - 0x0d, // 0x1c => K_ENTER - 0x11, // 0x1d => K_CONTROL - 0x41, // 0x1e => K_A - 0x53, // 0x1f => K_S - 0x44, // 0x20 => K_D - 0x46, // 0x21 => K_F - 0x47, // 0x22 => K_G - 0x48, // 0x23 => K_H - 0x4a, // 0x24 => K_J - 0x4b, // 0x25 => K_K - 0x4c, // 0x26 => K_L - 0xba, // 0x27 => K_COLON 39 - 0xde, // 0x28 => K_QUOTE - 0xc0, // 0x29 => K_BKQUOTE - 0x10, // 0x2a => K_SHIFT - 0xdc, // 0x2b => K_BKSLASH - 0x5a, // 0x2c => K_Z - 0x58, // 0x2d => K_X - 0x43, // 0x2e => K_C - 0x56, // 0x2f => K_V - 0x42, // 0x30 => K_B - 0x4e, // 0x31 => K_N - 0x4d, // 0x32 => K_M - 0xbc, // 0x33 => K_COMMA - 0xbe, // 0x34 => K_PERIOD - 0xbf, // 0x35 => K_SLASH - 0xa1, // 0x36 => K_?A1 - 0x6a, // 0x37 => K_NPSTAR - 0x12, // 0x38 => K_ALT - 0x20, // 0x39 => K_SPACE - 0x14, // 0x3a => K_CAPS - 0x70, // 0x3b => K_F1 59 - 0x71, // 0x3c => K_F2 - 0x72, // 0x3d => K_F3 - 0x73, // 0x3e => K_F4 - 0x74, // 0x3f => K_F5 - 0x75, // 0x40 => K_F6 - 0x76, // 0x41 => K_F7 - 0x77, // 0x42 => K_F8 - 0x78, // 0x43 => K_F9 - 0x79, // 0x44 => K_F10 - 0x90, // 0x45 => K_NUMLOCK - 0x03, // 0x46 => K_CANCEL - 0x24, // 0x47 => K_HOME - 0x26, // 0x48 => K_UP - 0x21, // 0x49 => K_PGUP - 0x6d, // 0x4a => K_NPMINUS - 0x25, // 0x4b => K_LEFT - 0x0c, // 0x4c => K_KP5 - 0x27, // 0x4d => K_RIGHT - 0x6b, // 0x4e => K_NPPLUS - 0x23, // 0x4f => K_END - 0x28, // 0x50 => K_DOWN - 0x22, // 0x51 => K_PGDN - 0x2d, // 0x52 => K_INS - 0x2e, // 0x53 => K_DEL - 0x2c, // 0x54 => K_PRTSCN - 0x00, // 0x55 => No match - 0xe2, // 0x56 => K_oE2 - 0x7a, // 0x57 => K_F11 - 0x7b, // 0x58 => K_F12 - 0x00, // 0x59 => No match - 0xee, // 0x5a => K_oEE - 0x5b, // 0x5b => K_?5B - 0x5c, // 0x5c => K_?5C - 0x5d, // 0x5d => K_?5D - 0xf5, // 0x5e => K_oF5 - 0x5f, // 0x5f => K_?5F - 0x00, // 0x60 => No match - 0x00, // 0x61 => No match - 0xfb, // 0x62 => K_?FB - 0x2f, // 0x63 => K_HELP - 0x7c, // 0x64 => K_F13 - 0x7d, // 0x65 => K_F14 - 0x7e, // 0x66 => K_F15 - 0x7f, // 0x67 => K_F16 - 0x80, // 0x68 => K_F17 - 0x81, // 0x69 => K_F18 - 0x82, // 0x6a => K_F19 - 0x83, // 0x6b => K_F20 - 0x84, // 0x6c => K_F21 - 0x85, // 0x6d => K_F22 - 0x86, // 0x6e => K_F23 - 0xed, // 0x6f => K_oED - 0x00, // 0x70 => No match - 0xe9, // 0x71 => K_oE9 - 0x00, // 0x72 => No match - 0xc1, // 0x73 => K_?C1 - 0x00, // 0x74 => No match - 0x00, // 0x75 => No match - 0x87, // 0x76 => K_F24 - 0x00, // 0x77 => No match - 0x00, // 0x78 => No match - 0x00, // 0x79 => No match - 0x00, // 0x7a => No match - 0xeb, // 0x7b => K_oEB - 0x00, // 0x7c => No match - 0x00, // 0x7d => No match - 0x6c, // 0x7e => K_SEPARATOR - 0x00 // 0x7f => No match -}; -*/ -// _S2 many keys still need to be defined !! -//( on x. place there is key e.g. -// on (US) position 24 we find key xBB ( = + ) -// on (US) position 0 we find key x41 ( A a ) +// we use the same type of array as throughout Keyman even though we have lots of unused fields const UINT mac_ScanCodeToUSVirtualKey[128] = { - 0x41 ,// L"K_A", // &H41 - 0x53 ,// L"K_S", // &H53 - 0x44 ,// L"K_D", // &H44 - 0x46 ,// L"K_F", // &H46 - 0x48 ,// L"K_H", // &H48 - 0x47 ,// L"K_G", // &H47 - 0x5A ,// L"K_Z", // &H5A - 0x58 ,// L"K_X", // &H58 - 0x43 ,// L"K_C", // &H43 - 0x56 ,// L"K_V", // &H56 -0xC0, // ^° // 10 - 0x42 ,// L"K_B", // &H42 - 0x51 ,// L"K_Q", // &H51 - 0x57 ,// L"K_W", // &H57 - 0x45 ,// L"K_E", // &H45 - 0x52 ,// L"K_R", // &H52 - 0x59 ,// L"K_Y", // &H59 - 0x54 ,// L"K_T", // &H54 - 0x31 ,// L"K_1", // &H31 - 0x32 ,// L"K_2", // &H32 -0x33 ,// L"K_3", // &H33 // 20 - 0x34 ,// L"K_4", // &H34 - 0x36 ,// L"K_6", // &H36 - 0x35 ,// L"K_5", // &H35 - 0xBB ,// L"K_?00",// &HB8 - 0x39 ,// L"K_9", // &H39 - 0x37 ,// L"K_7", // &H37 - 0xBD ,// L"K_?00",// &HBA - 0x38 ,// L"K_8", // &H38 - 0x30 ,// L"K_0", // &H30 -0xDD ,// 0 // &HD9 // 30 - 0x4F ,// L"K_O", // &H4F - 0x55 ,// L"K_U", // &H55 - 0xDB , // 0 // &HD7 - 0x49 ,// L"K_I", // &H49 - 0x50 ,// L"K_P", // &H50 - 0x00, - 0x4C ,// L"K_L", // &H4C - 0x4A ,// L"K_J", // &H4A - 0xDE, //222 ,// 0 // &HDA -0x4B ,// L"K_K", // &H4B // 40 - 186 ,// L"K_?00", // &HB7 - 220 ,// 0 // &HD8 - 188 ,// L"K_?00", // &HB9 - 191 ,// L"K_?00", // &HBC - 0x4E ,// L"K_N", // &H4E - 0x4D ,// L"K_M", // &H4D - 190 ,// L"K_?00", // L", - 0 ,// L"K_?00", // &H0 // 0x77 => No match - 32 ,// L"K_?00", // &H1 -0xE2 ,// L"K_?00", // &H2 // 50 // NEU xxx - 3 ,// L"K_?00", // &H3 - 4 ,// L"K_?00", // &H4 - 5 ,// L"K_?00", // &H5 - 6 ,// L"K_?00", // &H6 - 7 ,// L"K_?00", // &H7 - 8 ,// L"K_?00", // &H8 - 9 ,// L"K_?00", // &H9 - 10 ,// L"K_?00", // &HA - 11 ,// L"K_?00", // &HB -12 ,// L"K_?00", // &HC // 60 - 13 ,// L"K_?00", // &HD - 14 ,// L"K_?00", // &HE - 15 ,// L"K_?00", // &HF - 16 ,// L"K_?00", // &H10 - 17 ,// L"K_?00", // L", - 18 ,// L"K_?00", // &H12 - 19 ,// L"K_?00", // &H13 - 20 ,// L"K_?00", // &H14 - 21 ,// L"K_?00", // &H15 - 22 ,// L"K_?00", // &H16 - 23 ,// L"K_?00", // &H17 - 24 ,// L"K_?00", // &H18 - 25 ,// L"K_?00", // &H19 - 26 ,// L"K_?00", // &H1A - 27 ,// L"K_?00", // &H1B - 28 ,// L"K_?00", // &H1C - 29 ,// L"K_?00", // &H1D - 30 ,// L"K_?00", // &H1E - 31 ,// L"K_?00", // &H1F - 32 ,// L"K_?00", // &H20 - 33 ,// L"K_?00", // &H21 - 34 ,// L"K_?00", // &H22 - 35 ,// L"K_?00", // &H23 - 36 ,// L"K_?00", // &H24 - 37 ,// L"K_?00", // &H25 - 38 ,// L"K_?00", // &H26 - 39 ,// L"K_?00", // &H27 - 40 ,// L"K_?00", // &H28 - 41 ,// L"K_?00", // &H29 - 42 ,// L"K_?00", // &H2A - 43 ,// L"K_?00", // &H2B - 44 ,// L"K_?00", // &H2C - 45 ,// L"K_?00", // &H2D - 46 ,// L"K_?00", // &H2E - 47 ,// L"K_?00", // &H2F - 58 ,// L"K_?00", // &H3A - 59 ,// L"K_?00", // &H3B - 60 ,// L"K_?00", // &H3C - 61 ,// L"K_?00", // &H3D - 62 ,// L"K_?00", // &H3E - 63 ,// L"K_?00", // &H3F - 64 ,// L"K_?00", // &H40 - 91 ,// L"K_?00", // &H5B - 92 ,// L"K_?00", // &H5C - 93 ,// L"K_?00", // &H5D - 94 ,// L"K_?00", // &H5E - 95 ,// L"K_?00", // &H5F - 96 ,// L"K_?00", // &H60 - 97 ,// L"K_?00", // &H61 - 98 ,// L"K_?00", // &H62 - 99 ,// L"K_?00", // &H63 - 100 ,// L"K_?00", // &H64 - 101 ,// L"K_?00", // &H65 - 102 ,// L"K_?00", // &H66 - 103 ,// L"K_?00", // &H67 - 104 ,// L"K_?00", // &H68 - 105 ,// L"K_?00", // &H69 - 106 ,// L"K_?00", // &H6A - 107 ,// L"K_?00", // &H6B - 108 ,// L"K_?00", // &H6C - 109 ,// L"K_?00", // &H6D - 110 ,// L"K_?00", // &H6E - 111 ,// L"K_?00", // &H6F - 112 ,// L"K_?00", // &H70 - 113 ,// L"K_?00", // &H71 - 114 ,// L"K_?00", // &H72 - 115 // L"K_?00", // &H73 + 0x41, // L"K_A", // &H41 + 0x53, // L"K_S", // &H53 + 0x44, // L"K_D", // &H44 + 0x46, // L"K_F", // &H46 + 0x48, // L"K_H", // &H48 + 0x47, // L"K_G", // &H47 + 0x5A, // L"K_Z", // &H5A + 0x58, // L"K_X", // &H58 + 0x43, // L"K_C", // &H43 + 0x56, // L"K_V", // &H56 + 0xC0, // L"K_BKQUOTE", // &HC0 (192) + 0x42, // L"K_B", // &H42 + 0x51, // L"K_Q", // &H51 + 0x57, // L"K_W", // &H57 + 0x45, // L"K_E", // &H45 + 0x52, // L"K_R", // &H52 + 0x59, // L"K_Y", // &H59 + 0x54, // L"K_T", // &H54 + 0x31, // L"K_1", // &H31 + 0x32, // L"K_2", // &H32 + 0x33, // L"K_3", // &H33 + 0x34, // L"K_4", // &H34 + 0x36, // L"K_6", // &H36 + 0x35, // L"K_5", // &H35 + 0xBB, // L"K_EQUAL", // &HBB (187) + 0x39, // L"K_9", // &H39 + 0x37, // L"K_7", // &H37 + 0xBD, // L"K_H YPHEN", // &HBD (189) + 0x38, // L"K_8", // &H38 + 0x30, // L"K_0", // &H30 + 0xDD, // L"K_RBRKT", // &HDD (221) + 0x4F, // L"K_O", // &H4F + 0x55, // L"K_U", // &H55 + 0xDB, // L"K_LBRKT", // &HDB (219) + 0x49, // L"K_I", // &H49 + 0x50, // L"K_P", // &H50 + 0x00, // not used // ---- + 0x4C, // L"K_L", // &H4C + 0x4A, // L"K_J", // &H4A + 0xDE, // L"K_QUOTE", // &HDE (222) + 0x4B, // L"K_K", // &H4B + 0xBA, // L"K_COLON", // &HBA (186) + 0xDC, // L"K_BKSLASH", // &HDC (220) + 0xBC, // L"K_COMMA", // &HBC (188) + 0xBF, // L"K_SLASH", // &HBF (191) + 0x4E, // L"K_N", // &H4E + 0x4D, // L"K_M", // &H4D + 0xBE, // L"K_PERIOD", // &HBE (190) + 0x00, // not used // ---- + 0x20, // L"K_SPACE", // &H1 + 0xE2, // L"K_oE2", // &HE2 (226) + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used }; -// _S2 what instead x999? -//( on character-.st index we find the keycode e.g. -// for character A (65) we look at pos 65 and find keycode 0 -// for character X (87) we look at pos 87 and find keycode 7 -// for character + (187) we look at pos 187 and find keycode 24 +// we use the same type of array as throughout Keyman even though we have lots of unused fields const UINT mac_USVirtualKeyToScanCode[256] = { - 0x999, // L"K_?00", // &H0 ................................................... 0 ........................................... - 0x999, // L"K_LBUTTON", // &H1 - 0x999, // L"K_RBUTTON", // &H2 - 0x999, // 0x46, // L"K_CANCEL", // &H3 - 0x999, // L"K_MBUTTON", // &H4 - 0x999, // L"K_?05", // &H5 - 0x999, // L"K_?06", // &H6 - 0x999, // L"K_?07", // &H7 - 0x999, // 0x0E, // L"K_BKSP", // &H8 - 0x999, // 0x0F, // L"K_TAB", // &H9 - 0x999, // L"K_?0A", // &HA - 0x999, // L"K_?0B", // &HB................................................... 11 ........................................... - 0x999, // 0x4C, // L"K_KP5", // &HC - 0x999, // 0x1C, // L"K_ENTER", // &HD - 0x999, // L"K_?0E", // &HE - 0x999, // L"K_?0F", // &HF - 0x999, // 0x2A, // L"K_SHIFT", // &H10 - 0x999, // 0x1D, // L"K_CONTRO 0x999, // L", // &H11 - 0x999, // 0x38, // L"K_ALT", // &H12 - 0x999, // L"K_PAUSE", // &H13 - 0x999, // 0x3A, // L"K_CAPS", // &H14 - 0x999, // L"K_KANJI?15", // &H15 - 0x999, // L"K_KANJI?16", // &H16 - 0x999, // L"K_KANJI?17", // &H17 - 0x999, // L"K_KANJI?18", // &H18 - 0x999, // L"K_KANJI?19", // &H19 - 0x999, // L"K_?1A", // &H1A - 0x999, // L"K_ESC", // &H1B - 0x999, // L"K_KANJI?1C", // &H1C - 0x999, // L"K_KANJI?1D", // &H1D -0x999, // L"K_KANJI?1E", // &H1E - 0x999, // L"K_KANJI?1F", // &H1F................................................... 31 ........................................... - 0x31, // L"K_SPACE", // &H20 - 0x999, // 0x49, // L"K_PGUP", // &H21 - 0x999, // 0x51, // L"K_PGDN", // &H22 - 0x999, // 0x4F, // L"K_END", // &H23 - 0x999, // 0x47, // L"K_HOME", // &H24 - 0x999, // 0x4B, // L"K_LEFT", // &H25 - 0x999, // 0x48, // L"K_UP", // &H26 - 0x999, // 0x4D, // L"K_RIGHT", // &H27 -0x999, // 0x50, // L"K_DOWN", // &H28 - 0x999, // L"K_SEL", // &H29 - 0x999, // L"K_PRINT", // &H2A - 0x999, // L"K_EXEC", // &H2B - 0x999, // 0x54, // L"K_PRTSCN", // &H2C - 0x999, // 0x52, // L"K_INS", // &H2D - 0x999, // 0x53, // L"K_DEL", // &H2E - 0x999, // 0x63, // L"K_HELP", // &H2F - 0x1D, // L"K_0", // &H30 - 0x12, // L"K_1", // &H31 -0x13, // L"K_2", // &H32 - 0x14, // L"K_3", // &H33................................................... 51 ........................................... - 0x15, // L"K_4", // &H34 - 0x17, // L"K_5", // &H35 - 0x16, // L"K_6", // &H36 - 0x1A, // L"K_7", // &H37 - 0x1C, // L"K_8", // &H38 - 0x19, // L"K_9", // &H39 - 0x999, // L"K_?3A", // &H3A - 0x999, // L"K_?3B", // &H3B -0x999, // L"K_?3C", // &H3C - 0x999, // L"K_?3D", // &H3D - 0x999, // L"K_?3E", // &H3E - 0x999, // L"K_?3F", // &H3F - 0x999, // L"K_?40", // &H40 - 0x00, // L"K_A", // &H41 - 0x0B, // L"K_B", // &H42 - 0x08, // L"K_C", // &H43 - 0x02, // L"K_D", // &H44 - 0x0E, // L"K_E", // &H45 -0x03, // L"K_F", // &H46 - 0x05, // L"K_G", // &H47................................................... 71 ........................................... - 0x04, // L"K_H", // &H48 - 0x22, // L"K_I", // &H49 - 0x26, // L"K_J", // &H4A - 0x28, // L"K_K", // &H4B - 0x25, // L"K_L", // &H4C - 0x2E, // L"K_M", // &H4D - 0x2D, // L"K_N", // &H4E - 0x1F, // L"K_O", // &H4F -0x23, // L"K_P", // &H50 - 0x0C, // L"K_Q", // &H51 - 0x0F, // L"K_R", // &H52 - 0x01, // L"K_S", // &H53 - 0x11, // L"K_T", // &H54 - 0x20, // L"K_U", // &H55 - 0x09, // L"K_V", // &H56 - 0x0D, // L"K_W", // &H57 - 0x07, // L"K_X", // &H58 - 0x10, // L"K_Y", // &H59................................................... 89 ........................................... -0x06, // L"K_Z", // &H5A - 0x999, //0x5B, // L"K_?5B", // &H5B - 0x999, //0x5C, // L"K_?5C", // &H5C - 0x999, //0x5D, // L"K_?5D", // &H5D - 10, //0x00, // L"K_?5E", // &H5E - 0x999, //0x5F, // L"K_?5F", // &H5F - 0x999, //0x52, // L"K_NP0", // &H60 - 0x999, //0x4F, // L"K_NP1", // &H61 - 0x999, //0x50, // L"K_NP2", // &H62 - 0x999, //0x51, // L"K_NP3", // &H63 - 0x999, //0x4B, // L"K_NP4", // &H64 - 0x999, //0x4C, // L"K_NP5", // &H65 - 0x999, //0x4D, // L"K_NP6", // &H66 - 0x999, //0x47, // L"K_NP7", // &H67 - 0x999, //0x48, // L"K_NP8", // &H68 - 0x999, //0x49, // L"K_NP9", // &H69 - 0x999, //0x37, // L"K_NPSTAR", // &H6A - 0x999, //0x4E, // L"K_NPPLUS", // &H6B - 0x999, //0x7E, // L"K_SEPARATOR", // &H6C // MCD 01-11-02: Brazilian Fix, 00 -> 7E - 0x999, //0x4A, // L"K_NPMINUS", // &H6D - 0x999, //0x53, // L"K_NPDOT", // &H6E // ................................................. 110 ........... - 0x999, //0x135, // L"K_NPSLASH", // &H6F - 0x999, //0x3B, // L"K_F1", // &H70 - 0x999, //0x3C, // L"K_F2", // &H71 - 0x999, //0x3D, // L"K_F3", // &H72 - 0x999, //0x3E, // L"K_F4", // &H73 - 0x999, //0x3F, // L"K_F5", // &H74 - 0x999, //0x40, // L"K_F6", // &H75 - 0x999, //0x41, // L"K_F7", // &H76 - 0x999, //0x42, // L"K_F8", // &H77 - 0x999, //0x43, // L"K_F9", // &H78 - 0x999, //0x44, // L"K_F10", // &H79 - 0x999, //0x57, // L"K_F11", // &H7A - 0x999, //0x58, // L"K_F12", // &H7B - 0x999, //0x64, // L"K_F13", // &H7C - 0x999, //0x65, // L"K_F14", // &H7D - 0x999, //0x66, // L"K_F15", // &H7E - 0x999, //0x67, // L"K_F16", // &H7F - 0x999, //0x68, // L"K_F17", // &H80..... - 0x999, //0x69, // L"K_F18", // &H81 - 0x999, //0x6A, // L"K_F19", // &H82.................................................. 130 ....................................... - 0x999, //0x6B, // L"K_F20", // &H83 - 0x999, //0x6C, // L"K_F21", // &H84 - 0x999, //0x6D, // L"K_F22", // &H85 - 0x999, //0x6E, // L"K_F23", // &H86 - 0x999, //0x76, // L"K_F24", // &H87 ----- - 0x999, //0x00, // L"K_?88", // &H88 - 0x999, //0x00, // L"K_?89", // &H89 - 0x999, //0x00, // L"K_?8A", // &H8A - 0x999, //0x00, // L"K_?8B", // &H8B - 0x999, //0x00, // L"K_?8C", // &H8C - 0x999, //0x00, // L"K_?8D", // &H8D - 0x999, //0x00, // L"K_?8E", // &H8E - 0x999, //0x00, // L"K_?8F", // &H8F ----- - 0x999, //0x45, // L"K_NUMLOCK", // &H90 - 0x999, //0x46, // L"K_SCROL 0x999, //0x00, // L", // &H91 ----- - 0x999, //0x00, // L"K_?92", // &H92 - 0x999, //0x00, // L"K_?93", // &H93 - 0x999, //0x00, // L"K_?94", // &H94................. - 0x999, //0x00, // L"K_?95", // &H95 - 0x999, //0x00, // L"K_?96", // &H96............................................. 150 ................................ - 0x999, //0x00, // L"K_?97", // &H97 - 0x999, //0x00, // L"K_?98", // &H98 - 0x999, //0x00, // L"K_?99", // &H99 - 0x999, //0x00, // L"K_?9A", // &H9A - 0x999, //0x00, // L"K_?9B", // &H9B - 0x999, //0x00, // L"K_?9C", // &H9C - 0x999, //0x00, // L"K_?9D", // &H9D - 0x999, //0x00, // L"K_?9E", // &H9E - 0x999, //0x00, // L"K_?9F", // &H9F - 0x999, //0x2A, // L"K_?A0", // &HA0 - 0x999, //0x36, // L"K_?A1", // &HA1 - 0x999, //0x1D, // L"K_?A2", // &HA2 - 0x999, //0x1D, // L"K_?A3", // &HA3 - 0x999, //0x38, // L"K_?A4", // &HA4 - 0x999, //0x38, // L"K_?A5", // &HA5 - 0x999, //0x6A, // L"K_?A6", // &HA6 - 0x999, //0x69, // L"K_?A7", // &HA7 - 0x999, //0x67, // L"K_?A8", // &HA8...................... - 0x999, //0x68, // L"K_?A9", // &HA9 - 0x999, //0x65, // L"K_?AA", // &HAA....................................... 170 ................................. - 0x999, //0x66, // L"K_?AB", // &HAB - 0x999, //0x32, // L"K_?AC", // &HAC - 0x999, //0x20, // L"K_?AD", // &HAD - 0x999, //0x2E, // L"K_?AE", // &HAE - 0x999, //0x30, // L"K_?AF", // &HAF - 0x999, //0x19, // L"K_?B0", // &HB0 - 0x999, //0x10, // L"K_?B1", // &HB1 - 0x999, //0x24, // L"K_?B2", // &HB2 - 0x999, //0x22, // L"K_?B3", // &HB3 - 0x999, //0x6C, // L"K_?B4", // &HB4 - 0x999, //0x6D, // L"K_?B5", // &HB5 - 0x999, //0x6B, // L"K_?B6", // &HB6 - 0x999, //0x21, // L"K_?B7", // &HB7 - 0x999, //0x00, // L"K_?B8", // &HB8 - 0x999, //0x00, // L"K_?B9", // &HB9 ----- - 0x29, // L"K_COLON", // &HBA - 24, // 0x0D, // L"K_EQUA0x00, // L", // &HBB 187 - 0x2B, // L"K_COMMA", // &HBC ........ - 0x1B, // L"K_HYPHEN", // &HBD -0x2F, // L"K_PERIOD", // &HBE................................................ 190 ...................................... - 0x2C, // L"K_SLASH", // &HBF - 0x0A, //0x77, // L"K_BKQUOTE", // &HC0 ----- - 0x999, //0x73, // L"K_?C1", // &HC1 - 0x999, //0x7E, // L"K_?C2", // &HC2 - 0x999, //0x00, // L"K_?C3", // &HC3 - 0x999, //0x00, // L"K_?C4", // &HC4 196 - 0x999, //0x00, // L"K_?C5", // &HC5 - 0x999, //0x00, // L"K_?C6", // &HC6 - 0x999, //0x00, // L"K_?C7", // &HC7 - 0x999, //0x00, // L"K_?C8", // &HC8 - 0x999, //0x00, // L"K_?C9", // &HC9 - 0x999, //0x00, // L"K_?CA", // &HCA - 0x999, //0x00, // L"K_?CB", // &HCB - 0x999, //0x00, // L"K_?CC", // &HCC - 0x999, //0x00, // L"K_?CD", // &HCD - 0x999, //0x00, // L"K_?CE", // &HCE - 0x999, //0x00, // L"K_?CF", // &HCF - 0x999, //0x00, // L"K_?D0", // &HD0............... - 0x999, //0x00, // L"K_?D1", // &HD1 - 0x999, //0x00, // L"K_?D2", // &HD2............................................... 210 ................................ - 0x999, //0x00, // L"K_?D3", // &HD3 - 0x999, //0x00, // L"K_?D4", // &HD4 - 0x999, //0x00, // L"K_?D5", // &HD5 - 0x999, //0x00, // L"K_?D6", // &HD6 - 0x999, //0x00, // L"K_?D7", // &HD7 - 0x999, //0x00, // L"K_?D8", // &HD8 - 0x999, //0x00, // L"K_?D9", // &HD9 - 0x999, //0x00, // L"K_?DA", // &HDA - 0x21, // L"K_LBRKT", // &HDB - 0x2A, // L"K_BKSLASH", // &HDC - 0x1E, // L"K_RBRKT", // &HDD - 0x27, // L"K_QUOTE", // &HDE - 27, // L"K_oDF", // &HDF // MCD 01-11-02: Brazilian fix: 00 -> 73 - 0x999, //0x00, // L"K_oE0", // &HE0 - 0x999, //0x00, // L"K_oE1", // &HE1 - 50, //0x56, // L"K_oE2", // &HE2 - 0x999, //0x00, // L"K_oE3", // &HE3 - 0x999, //0x00, // L"K_oE4", // &HE4..... - 0x999, //0x00, // L"K_?E5", // &HE5 -0x999, //0x00, // L"K_oE6", // &HE6.................................................. 230 ....................................... - 0x999, //0x00, // L"K_?E7", // &HE7 - 0x999, //0x00, // L"K_?E8", // &HE8 222 - 0x999, //0x71, // L"K_oE9", // &HE9 - 0x999, //0x5C, // L"K_oEA", // &HEA - 0x999, //0x7B, // L"K_oEB", // &HEB - 0x999, //0x00, // L"K_oEC", // &HEC 226 - 0x999, //0x6F, // L"K_oED", // &HED - 0x999, //0x5A, // L"K_oEE", // &HEE - 0x999, //0x00, // L"K_oEF", // &HEF - 0x999, //0x00, // L"K_oF0", // &HF0 - 0x999, //0x5B, // L"K_oF1", // &HF1 - 0x999, //0x00, // L"K_oF2", // &HF2 - 0x999, //0x5F, // L"K_oF3", // &HF3 - 0x999, //0x00, // L"K_oF4", // &HF4 - 0x999, //0x5E, // L"K_oF5", // &HF5 - 0x999, //0x00, // L"K_?F6", // &HF6 - 0x999, //0x00, // L"K_?F7", // &HF7 - 0x999, //0x00, // L"K_?F8", // &HF8 - 0x999, //0x5D, // L"K_?F9", // &HF9 - 0x999, //0x00, // L"K_?FA", // &HFA - 0x999, //0x62, // L"K_?FB", // &HFB - 0x999, //0x00, // L"K_?FC", // &HFC - 0x999, //0x00, // L"K_?FD", // &HFD - 0x999, //0x00, // L"K_?FE", // &HFE - 0x999, //0x00 // L"K_?FF" // &HFF + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x31, // L"K_SPACE", // &H20 + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x1D, // L"K_0", // &H30 + 0x12, // L"K_1", // &H31 + 0x13, // L"K_2", // &H32 + 0x14, // L"K_3", // &H33 + 0x15, // L"K_4", // &H34 + 0x17, // L"K_5", // &H35 + 0x16, // L"K_6", // &H36 + 0x1A, // L"K_7", // &H37 + 0x1C, // L"K_8", // &H38 + 0x19, // L"K_9", // &H39 + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x00, // L"K_A", // &H41 + 0x0B, // L"K_B", // &H42 + 0x08, // L"K_C", // &H43 + 0x02, // L"K_D", // &H44 + 0x0E, // L"K_E", // &H45 + 0x03, // L"K_F", // &H46 + 0x05, // L"K_G", // &H47 + 0x04, // L"K_H", // &H48 + 0x22, // L"K_I", // &H49 + 0x26, // L"K_J", // &H4A + 0x28, // L"K_K", // &H4B + 0x25, // L"K_L", // &H4C + 0x2E, // L"K_M", // &H4D + 0x2D, // L"K_N", // &H4E + 0x1F, // L"K_O", // &H4F + 0x23, // L"K_P", // &H50 + 0x0C, // L"K_Q", // &H51 + 0x0F, // L"K_R", // &H52 + 0x01, // L"K_S", // &H53 + 0x11, // L"K_T", // &H54 + 0x20, // L"K_U", // &H55 + 0x09, // L"K_V", // &H56 + 0x0D, // L"K_W", // &H57 + 0x07, // L"K_X", // &H58 + 0x10, // L"K_Y", // &H59 + 0x06, // L"K_Z", // &H5A + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x29, // L"K_COLON", // &HBA (186) + 0x18, // L"K_EQUAL", // &HBB (187) + 0x2B, // L"K_COMMA", // &HBC (188) + 0x1B, // L"K_HYPHEN", // &HBD (189) + 0x2F, // L"K_PERIOD", // &HBE (190) + 0x2C, // L"K_SLASH", // &HBF (191) + 0x0A, // L"K_BKQUOTE", // &HC0 (192) + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x21, // L"K_LBRKT", // &HDB (219) + 0x2A, // L"K_BKSLASH", // &HDC (220) + 0x1E, // L"K_RBRKT", // &HDD (221) + 0x27, // L"K_QUOTE", // &HDE (222) + 0x1B, // L"K_oDF", // &HDF (223) + 0xFFFF, // not used + 0xFFFF, // not used + 0x32, // L"K_oE2", // &HE2 (226) + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used }; -bool mac_IsKeymanUsedChar(int KV); +//bool mac_IsKeymanUsedChar(int KV); //------------------------------ +// _S2 CHECKED OK +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int kc_underlying, int shiftstate_mac); -// take deadkey-value (e.g.65106) and return u16string (e.g. '^' ) -std::u16string mac_convert_DeadkeyValues_To_U16str(int in); +// _S2 CHECKED OK fill Deadkey with dk and return CATEGORY +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT kc_underlying, UINT VKShiftState, PKMX_WCHAR deadKey); -// use gdk_keymap_translate_keyboard_state to get keyval - base function to get keyvals -// _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk only? -int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int ss, int caps); -int mac_KMX_get_KeyVal_From_KeyCode_S2(const UCKeyboardLayout * keyboard_layout, int keycode, int ss, int caps); -int mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps, UInt32 &deadkeystate_ret); +// _S2 CHECKED OK use Vector to return the Keyval of underlying Keyboard +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D &All_Vector, KMX_DWORD kv_us); -// use mac_KMX_get_KeyVal_From_KeyCode and prevent use of certain keycodes -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int keycode, int shift_state_pos); +// _S2 CHECKED OK use Vector to return the Scancode of underlying Keyboard +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vector, KMX_DWORD kv_underlying); -// fill Deadkey with dk and return CATEGORY -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey); +// _S2 CHECKED OK use Vector to return the Keycode of the underlying Keyboard for given VK_US using GDK +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_DWORD kc_us, ShiftState ss, int caps); -// use Vector to return the Keyval of underlying Keyboard -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D &All_Vector,KMX_DWORD VK_underlying); +// _S2 CHECKED OK return the Keycode of the underlying Keyboard for given VK_US +UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us); -// use Vector to return the Scancode of underlying Keyboard -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vector, KMX_DWORD KV_Underlying); +// _S2 CHECKED OK return the VirtualKey of the US Keyboard for a given Keyode using GDK +KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); -// use Vector to return the Keycode of the underlying Keyboard for given VK_US using GDK -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector,KMX_DWORD KC_US, ShiftState ss, int caps); +// _S2 CHECKED OK +KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps); -// return the Keycode of the underlying Keyboard for given VK_US -UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS); +// use gdk_keymap_translate_keyboard_state to get keyval - base function to get keyvals -// return the VirtualKey of the US Keyboard for a given Keyode using GDK -KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); +// _S2 CHECKED OK +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps); +// _S2 CHECKED OK +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32 &deadkeystate); -// convert codePoint to u16string -//std::u16string mac_CodePointToU16String(unsigned int codepoint); //################################################################################################################################################ //################################################################################################################################################ +//KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_new(int charVal,const UCKeyboardLayout* keyboard_layout , KMX_DWORD shiftstate); +//static KMX_DWORD deadkey_min = 0xfe50; // _S2 needed?? +//static KMX_DWORD deadkey_max = 0xfe93; // _S2 needed?? +//static KMX_DWORD deadkey_max = 0xfe52; // _S2 TOP_6 TODO This has to go! my test: to only return 3 dk // _S2 need to go +// _S2 CHECKED OK +// take deadkey-value (e.g.65106) and return u16string (e.g. '^' ) +//std::u16string mac_convert_DeadkeyValues_To_U16str(int in); + + +// convert codePoint to u16string +//std::u16string mac_CodePointToU16String(unsigned int codepoint); + // replace Name of Key (e.g. ) wih Keycode ( e.g. 15 ) //int mac_replace_KeyName_with_Keycode(std::string in); @@ -960,7 +543,7 @@ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); // 1. step: read complete Row of Configuration file US //bool mac_createCompleteRow_US(v_str_1D &complete_List, FILE *fpp, const char *text, std::string language); -void printoutKeyboards(v_dw_3D &All_Vector); +void test_printoutKeyboards_S2(v_dw_3D &All_Vector); KMX_DWORD X_playWithDK_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal) ; KMX_DWORD X_playWithDK_S2_one(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal); KMX_DWORD X_compare_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); diff --git a/mac/mcompile/km_types.h b/mac/mcompile/km_types.h index 531bb2ccc06..8251cf7d481 100755 --- a/mac/mcompile/km_types.h +++ b/mac/mcompile/km_types.h @@ -113,8 +113,3 @@ typedef KMX_UCHAR* KMX_PUCHAR; #define VK_CAPITAL 0x14 #endif /*KM_TYPES*/ - - -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ diff --git a/mac/mcompile/kmx_file.h b/mac/mcompile/kmx_file.h index 1e7d76da8f5..d7fa0d51d5f 100755 --- a/mac/mcompile/kmx_file.h +++ b/mac/mcompile/kmx_file.h @@ -27,7 +27,6 @@ namespace kmx { #define KEYMANID_INVALID 0xFFFFFFFD // Shift flags for hotkeys (version 1.0) // -//_S2 here values for mac #define SHIFTFLAG 0x2000 #define CTRLFLAG 0x4000 #define ALTFLAG 0x8000 @@ -389,6 +388,3 @@ static_assert(sizeof(KMX_COMP_KEYBOARD) == KEYBOARDFILEHEADER_SIZE, "COMP_KEYBOA #endif #endif //KMX_FILE_H -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 8c4543beda1..85c90869587 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -70,44 +70,32 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { bool test_alDead_S2(std::vector ald); -int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps,const UCKeyboardLayout * keyboard_layout) { -// _S2 ToDo cleanup!! - /* - if (!(shift_state_pos <= count)) - return 0; +int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_win, int caps, const UCKeyboardLayout * keyboard_layout) { + KMX_DWORD keyval; + UInt32 isdk=0; - if (!(keycode <= keycode_max)) + if (!keyboard_layout) return 0; - */ - //rc>0: character - //rc==0: no translation - //rc<0: dk + if (!(keycode <= keycode_max)) + return 0; - // _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk ? - KMX_DWORD KeyVal2= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode, mac_map_ShiftState_to_MacModifier(ShiftState(shift_state_pos)), caps); + if (!(ss_win <= max_shiftstate)) + return 0; - UInt32 isdk=0; - KMX_DWORD KeyVal= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_map_ShiftState_to_MacModifier(ShiftState(shift_state_pos)), caps, isdk); + if (!(caps <= 1)) + return 0; - // _S2 ToDo non-dk OK, but all others not - std::u16string str = mac_convert_DeadkeyValues_To_U16str(KeyVal); + keyval= mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_map_Win_ShiftState_to_MacModifier(ShiftState(ss_win)), caps, isdk); + std::u16string str =std::u16string(1, keyval ); pwszBuff[0]= * (PKMX_WCHAR) str.c_str(); - /* - - if((KeyVal >= deadkey_min) && (KeyVal <= deadkey_max)) // deadkeys - return -1; - else if(gdk_keyval_to_unicode(KeyVal) == 0) // NO UNICODE - return 0; - else */ // usable char -// _S2 dk >0 if dk found - if ((isdk) && (keycode!= 0x999)) // isdk !=0 + if ((isdk) && (keycode!= 0x999)) // deadkeys return -1; - else if (KeyVal ==0) // NO UNICODE + if (keyval == 0) // no character return 0; - else - return 1; // usable char + else // usable char + return 1; } int mac_KMX_DeadKeyMap(int index, std::vector *deadkeys, int deadkeyBase, std::vector *deadkeyMappings) { // I4327 // I4353 @@ -235,7 +223,7 @@ class mac_KMX_VirtualKey { for (int caps = 0; caps <= 1; caps++) { std::u16string st = this->mac_KMX_GetShiftState((ShiftState) ss, (caps == 1)); - + // ctrl and sh+ctrl will be skipped since rgkey has no entries in m_rgss[2] m_rgss[3] if (st.size() == 0) { // No character assigned here } else if (this->m_rgfDeadKey[(int)ss][caps]) { @@ -246,9 +234,7 @@ class mac_KMX_VirtualKey { for (size_t ich = 0; ich < st.size(); ich++) { if(st[ich] < 0x20 || st[ich] == 0x7F) { isvalid=false; - - // _S2 must be included later - // wprintf(L"invalid for: %i\n", st[ich]); + wprintf(L"invalid for: %i\n", st[ich]); break; } } if(isvalid) { @@ -260,14 +246,15 @@ class mac_KMX_VirtualKey { return nkeys; } - bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector *deadkeys, int deadkeyBase, BOOL bDeadkeyConversion,v_dw_3D &All_Vector, const UCKeyboardLayout *keyboard_layout ) { // I4552 + bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector *deadkeys, int deadkeyBase, BOOL bDeadkeyConversion, v_dw_3D &All_Vector, const UCKeyboardLayout *keyboard_layout ) { // I4552 // Get the CAPSLOCK value int capslock = (this->mac_KMX_IsCapsEqualToShift() ? 1 : 0) | (this->mac_KMX_IsSGCAPS() ? 2 : 0) | (this->mac_KMX_IsAltGrCapsEqualToAltGrShift() ? 4 : 0) | (this->mac_KMX_IsXxxxGrCapsEqualToXxxxShift() ? 8 : 0); -capslock = 1; //_S2 +capslock = 1; //_S2 TODO + for (int ss = 0; ss <= MaxShiftState; ss++) { if (ss == Menu || ss == ShftMenu) { // Alt and Shift+Alt don't work, so skip them @@ -310,8 +297,7 @@ capslock = 1; //_S2 for (size_t ich = 0; ich < st.size(); ich++) { if(st[ich] < 0x20 || st[ich] == 0x7F) { isvalid=false; - // _S2 must be included later - //wprintf(L"invalid 16 for: %i\n", st[ich]); + wprintf(L"invalid 16 for: %i\n", st[ich]); break; } } if(isvalid) { @@ -320,8 +306,8 @@ capslock = 1; //_S2 // this->m_vk stores VK-US ( not underlying !!) // key->Key stores VK-US ( not underlying !!) // key->dpOutput stores character Underlying - KMX_DWORD SC_Underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keyboard_layout, All_Vector, this->SC(), (ShiftState) ss, caps); + key->Key = mac_KMX_get_VKUS_From_KeyCodeUnderlying( SC_Underlying); key->Line = 0; @@ -343,7 +329,6 @@ capslock = 1; //_S2 } }; - class mac_KMX_Loader { private: KMX_BYTE lpKeyStateNull[256]; @@ -378,33 +363,30 @@ class mac_KMX_Loader { bool fCapsLock, // Was the caps lock key pressed? const UCKeyboardLayout * keyboard_layout) { // The keyboard layout - int ss[]={0,2,8,10}; int maxshiftstate=2; DeadKey *deadKey = new DeadKey(rgKey[iKeyDead]->mac_KMX_GetShiftState(shiftStateDead, fCapsLock)[0]); - // e.g. ^ keyval - int ss_dead = mac_map_ShiftState_to_MacModifier(shiftStateDead); - int keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead],ss_dead,0); + int ss_dead = mac_map_Win_ShiftState_to_MacModifier(shiftStateDead); + KMX_DWORD keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead], ss_dead,0); - for( int i=0; i< Keycode_Spacebar+1; i++) { + for( int i=0; i< keycode_spacebar+1; i++) { for( int j=0; j< maxshiftstate ; j++) { - // _S2 do we need caps?? for( int caps = 0; caps < 1; caps++) { // e.g. a basechar - int basechar = mac_KMX_get_KeyVal_From_KeyCode_S2(keyboard_layout, i,ss[j],caps); + KMX_DWORD basechar = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[j], caps); // e.g. â combchar - KMX_DWORD KC_Underlying_dk = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKeyDead); - KMX_DWORD combchar= mac_get_CombinedChar_From_DK(KC_Underlying_dk, ss_dead, keyboard_layout , i, ss[j],caps); + KMX_DWORD KC_Underlying_dk = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKeyDead); + KMX_DWORD combchar= mac_get_CombinedChar_From_DK(KC_Underlying_dk, ss_dead, keyboard_layout, i, ss_mac[j], caps); if(combchar== 0) continue; // push only for if combchar is not dk or combchar is dk with space - if( (!(combchar== keyval_underlying_dk)) || (basechar == mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, Keycode_Spacebar,ss[j],caps))) { + if( (!(combchar== keyval_underlying_dk)) || (basechar == mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode_spacebar, ss_mac[j], caps))) { deadKey->KMX_AddDeadKeyRow(basechar, combchar); - printf( " processed basechar %i(%c) with dk %i(%c) ===> combchar%i(%c) \t\t ss[%i](%i) caps%i \n", basechar,basechar ,keyval_underlying_dk,keyval_underlying_dk, combchar,combchar ,j,ss[j], caps ); + //printf( " processed basechar %i(%c) with dk %i(%c) ===> combchar%i(%c) \t\t ss[%i](%i) caps%i \n", basechar,basechar ,keyval_underlying_dk,keyval_underlying_dk, combchar,combchar, j, ss[j], caps ); } } } @@ -421,8 +403,7 @@ class mac_KMX_Loader { }*/ }; - -/* int KMX_GetMaxDeadkeyIndex(KMX_WCHAR *p) { +int mac_KMX_GetMaxDeadkeyIndex(KMX_WCHAR *p) { int n = 0; while(p && *p) { if(*p == UC_SENTINEL && *(p+1) == CODE_DEADKEY) @@ -430,15 +411,15 @@ class mac_KMX_Loader { p = KMX_incxstr(p); } return n; -}*/ +} // _S2 need to go -void print_All_Entries_S2(std::vector rgKey); -bool run_verify_S2(std::vector rgKey); -void print_All_Keys(const UCKeyboardLayout * keyboard_layout); -void print_certain_Keys(const UCKeyboardLayout * keyboard_layout, int keycode); +void test_print_All_Entries_S2(std::vector rgKey); +bool test_run_verify_S2(std::vector rgKey); +void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout); +void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode); -bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout,std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 +bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout, std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 mac_KMX_Loader loader; std::vector rgKey; //= new VirtualKey[256]; @@ -450,7 +431,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar // values in it. Then, store the SC in each valid VK so it can act as both a // flag that the VK is valid, and it can store the SC value. - //for(UINT sc = 0x01; sc <= 0x7f; sc++) { _S2 win lin keycode start with 1; mac with 0 + //Windows and Linux Keycodes start with 1; Mac keycodes start with 0 for(UINT sc = 0x00; sc <= 0x7f; sc++) { // HERE IS A BIG DIFFERENCE COMPARED TO MCOMPILE FOR WINDOWS: @@ -471,7 +452,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar } } -// // _S2 TODO I assume we do not need those... +// // _S2 I assume we do not need those... // rgKey[VK_DIVIDE] = new mac_KMX_VirtualKey(hkl, VK_DIVIDE); // rgKey[VK_CANCEL] = new mac_KMX_VirtualKey(hkl, VK_CANCEL); // rgKey[VK_DECIMAL] = new mac_KMX_VirtualKey(hkl, VK_DECIMAL); @@ -488,36 +469,31 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar } //_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! - if(ss == MenuCtrl|| ss == ShftMenuCtrl) { + if(ss == MenuCtrl|| ss == ShftMenuCtrl) { continue; } - // _S2 ToDo what about not used keys?? - KMX_DWORD KC_US = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); - for(int caps = 0; caps <= 1; caps++) { + KMX_DWORD KC_US = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); + for(int caps = 0; caps <= 1; caps++) { int rc = mac_KMX_ToUnicodeEx(KC_US, sbBuffer, ss, caps, *keyboard_layout); - //rc>0: character //_S2 - //rc==0: no translation - //rc<0: dk + if(rc > 0) { if(*sbBuffer == 0) { - rgKey[iKey]->mac_KMX_SetShiftState(ss, u"", false, (caps)); // different to windows since behavior on Linux is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, u"", false, (caps)); // different to windows since behavior on mac is different } else { if( (ss == Ctrl || ss == ShftCtrl) ) { continue; } sbBuffer[rc] = 0; - rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to windows since behavior on Linux is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to windows since behavior on mac is different } } else if(rc < 0) { sbBuffer[2] = 0; - rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on Linux is different - // _S2 does not work - deadkeys - //if (!caps) // _S2 can go later - printf(" _S2 we use dk: %i(%i) %i caps:%i %i(%c) \n", KC_US, iKey,ss,caps, sbBuffer[0],sbBuffer[0] ); + rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on mac is different + printf(" _S2 we use dk: %i(%i) %i caps:%i %i(%c) \n", KC_US, iKey,ss, caps, sbBuffer[0],sbBuffer[0] ); sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps == 0)); @@ -531,7 +507,6 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar } if(dk == NULL) { alDead.push_back(loader.ProcessDeadKey(iKey, ss, rgKey, caps == 0, *keyboard_layout)); - printf(" WOULD DO alDead.push_back for caps: %i sbBuffer[0] %i\n", caps,sbBuffer[0]); } } } @@ -541,17 +516,20 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar //------------------------------------------------------------- // Now that we've collected the key data, we need to - // translate it to kmx and append to the existing keyboar + // translate it to kmx and append to the existing keyboard //------------------------------------------------------------- - // _S2 need to go - //print_All_Entries_S2(rgKey); - //print_All_Keys( * keyboard_layout); - //print_certain_Keys( * keyboard_layout, 10); - // bool allOK =test_alDead_S2(alDead); - if ( ! run_verify_S2(rgKey)) + // _S2 all of my tests need to go ............ + //test_print_All_Entries_S2(rgKey); + //test_print_All_Keys_S2( * keyboard_layout); + //test_print_certain_Keys_S2( * keyboard_layout, 14); + //bool allOK =test_alDead_S2(alDead); + bool allOK=true; + if ( ! allOK ) + printf(" \n::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG DEADKEYS :::::::::::::::::::::::::::::::::::::::::::::::::: \n"); + if ( ! test_run_verify_S2(rgKey)) printf(" \n::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG ENTRIES ::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); - else + if ( test_run_verify_S2(rgKey) && allOK) printf("\n ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :) :) :) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); int nDeadkey = 0; @@ -573,11 +551,10 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar //} LPKMX_KEY kkp = gp->dpKeyArray; - //_S2 deadkeys - /*for(UINT j = 0; j < gp->cxKeyArray; j++, kkp++) { - nDeadkey = std::max(nDeadkey, KMX_GetMaxDeadkeyIndex(kkp->dpContext)); - nDeadkey = std::max(nDeadkey, KMX_GetMaxDeadkeyIndex(kkp->dpOutput)); - }*/ + for(UINT j = 0; j < gp->cxKeyArray; j++, kkp++) { + nDeadkey = std::max(nDeadkey, mac_KMX_GetMaxDeadkeyIndex(kkp->dpContext)); + nDeadkey = std::max(nDeadkey, mac_KMX_GetMaxDeadkeyIndex(kkp->dpOutput)); + } } @@ -616,7 +593,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar gp->cxKeyArray = nkeys; // - // Add nomatch control to each terminating 'using keys' group // I4550 ggggǵggg hhhhh´ggggggg ggggḣhh gggggggggg`gggggggǵg ǵǵggggg hhhh´gggggg ggggáaaa – Ñ + // Add nomatch control to each terminating 'using keys' group // I4550 // LPKMX_GROUP gp2 = kp->dpGroupArray; for(UINT i = 0; i < kp->cxGroupArray - 1; i++, gp2++) { @@ -659,8 +636,6 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar // We only do this if not in deadkey conversion mode // - int STOP=0; // _S2 up to here - if (alDead.size() > 0 && !bDeadkeyConversion) { // I4552 kp->cxGroupArray++; @@ -761,7 +736,6 @@ const int CODE__SIZE[] = { 2 // CODE_SETSYSTEMSTORE 0x18 }; - // _S2 need to go void print_entries_S2(int i, std::vector rgKey , std::string comp1,std::string comp2,std::string erg) { std::string b0 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 0 )); @@ -796,7 +770,7 @@ bool verify_entries_S2(int i, std::vector rgKey, int res1,i printf(" ERROR FOR i= Nr:%i, %i(%c) - %i (%c) - %i (%c) - %i (%c) \n",i, *st_vec[0].c_str(),*st_vec[1].c_str(),*st_vec[2].c_str(),*st_vec[3].c_str(),*st_vec[4].c_str(),*st_vec[5].c_str(),*st_vec[6].c_str(),*st_vec[7].c_str()); return all_OK; } -void print_All_Entries_S2( std::vector rgKey) { +void test_print_All_Entries_S2( std::vector rgKey) { for ( int i=48; i<58; i++) print_entries_S2(i, rgKey," ","",""); @@ -817,139 +791,141 @@ void print_All_Entries_S2( std::vector rgKey) { print_entries_S2(222, rgKey, "ä", "Ä", "ä Ä Ä Ä"); print_entries_S2(226, rgKey, "<", ">", "< < > >"); } -void print_certain_Keys(const UCKeyboardLayout * keyboard_layout, int keycode) { +void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode) { UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; UniChar unicodeString[maxStringlength]; UInt32 deadkeystate = 0; OSStatus status; - int shiftarray[] ={0,2,8,10}; - + unicodeString[0]=0; + //int shiftarray[] ={0,2,8,10}; + int shiftarray[] ={0,1,2,3,4,5,6,7,8,9,10}; for(int k=0; k<2;k++) { - for(int j=0; j<4;j++) { - status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + for(int j=0; j<(sizeof(shiftarray)/ sizeof(int));j++) { + status = UCKeyTranslate(keyboard_layout, keycode , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate ==0) - printf(" key nr %i , ss %i has values %i(%c)\n", keycode, shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); + printf(" key nr %i , ss %i has values %i(%c)\n", keycode, shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); // If this was a deadkey, append a space if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, 49 ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - printf(" dk key nr %i , ss %i has values %i(%c)\n", keycode,shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); + status = UCKeyTranslate(keyboard_layout, keycode_spacebar , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + printf(" dk with caps key nr %i , ss %i has values %i(%c)\n", keycode,shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); } } } } -void print_All_Keys(const UCKeyboardLayout * keyboard_layout){ +void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout){ UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; UniChar unicodeString[maxStringlength]; UInt32 deadkeystate = 0; OSStatus status; + unicodeString[0]=0; int shiftarray[] ={0,2,8,10}; for(int k=0; k<2;k++) { for(int j=0; j<4;j++) { - for(int i=0; i< Keycode_Spacebar+1 ;i++) { - status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + for(int i=0; i< keycode_spacebar+1 ;i++) { + status = UCKeyTranslate(keyboard_layout, i , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate ==0) - printf(" key nr %i , ss %i has values %i(%c)\n", i, shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); + printf(" key nr %i , ss %i has values %i(%c)\n", i, shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); // If this was a deadkey, append a space if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, 49 ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - printf(" dk key nr %i , ss %i has values %i(%c)\n", i,shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); + status = UCKeyTranslate(keyboard_layout, keycode_spacebar , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + printf(" dk key nr %i , ss %i has values %i(%c)\n", i,shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); } } } } } -bool checkBasechar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) { +bool test_checkBasechar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) { return ( DK->KMX_GetBaseCharacter(index) == ch) ; } -bool checkCombchar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) { +bool test_checkCombchar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) { return ( DK->KMX_GetCombinedCharacter(index) == ch) ; } -bool test_alDead_S2(std::vector ald) { +bool test_alDead_S2(std::vector ald) { bool OK =true; - OK = OK && checkBasechar_S2(ald[0],0, 0x61); - OK = OK && checkBasechar_S2(ald[0],1, 0x41); - OK = OK && checkBasechar_S2(ald[0],14, 0x65); - OK = OK && checkBasechar_S2(ald[0],15, 0x45); - OK = OK && checkBasechar_S2(ald[0],23 ,0x69 ); - OK = OK && checkBasechar_S2(ald[0],24 ,0x49 ); - OK = OK && checkBasechar_S2(ald[0],19 ,0x6f ); - OK = OK && checkBasechar_S2(ald[0],20 ,0x4f ); - OK = OK && checkBasechar_S2(ald[0],21 ,0x75 ); - OK = OK && checkBasechar_S2(ald[0],22 ,0x55 ); - OK = OK && checkBasechar_S2(ald[0],27 ,0x20 ); - OK = OK && checkBasechar_S2(ald[0],28 ,0x20 ); - - OK = OK && checkCombchar_S2(ald[0],0, 0xe2); - OK = OK && checkCombchar_S2(ald[0],1, 0xc2); - OK = OK && checkCombchar_S2(ald[0],14 ,0xea); - OK = OK && checkCombchar_S2(ald[0],15, 0xca); - OK = OK && checkCombchar_S2(ald[0],23 ,0xee ); - OK = OK && checkCombchar_S2(ald[0],24 ,0xce ); - OK = OK && checkCombchar_S2(ald[0],19 ,0xf4 ); - OK = OK && checkCombchar_S2(ald[0],20 ,0xd4 ); - OK = OK && checkCombchar_S2(ald[0],21 ,0xfb ); - OK = OK && checkCombchar_S2(ald[0],22 ,0xdb ); - OK = OK && checkCombchar_S2(ald[0],27 ,0x5e ); - OK = OK && checkCombchar_S2(ald[0],28 ,0x5e ); - - OK = OK && checkBasechar_S2(ald[1],0, 0x61); - OK = OK && checkBasechar_S2(ald[1],1, 0x41); - OK = OK && checkBasechar_S2(ald[1],12, 0x65); - OK = OK && checkBasechar_S2(ald[1],13, 0x45); - OK = OK && checkBasechar_S2(ald[1],24 ,0x69 ); - OK = OK && checkBasechar_S2(ald[1],25 ,0x49 ); - OK = OK && checkBasechar_S2(ald[1],18 ,0x6f ); - OK = OK && checkBasechar_S2(ald[1],19 ,0x4f ); - OK = OK && checkBasechar_S2(ald[1],20 ,0x75 ); - OK = OK && checkBasechar_S2(ald[1],21 ,0x55 ); - OK = OK && checkBasechar_S2(ald[1],36 ,0x20 ); - OK = OK && checkBasechar_S2(ald[1],37 ,0x20 ); - - OK = OK && checkCombchar_S2(ald[1],0, 0xe2-1); - OK = OK && checkCombchar_S2(ald[1],1, 0xc2-1); - OK = OK && checkCombchar_S2(ald[1],12 ,0xea-1); - OK = OK && checkCombchar_S2(ald[1],13, 0xca-1); - OK = OK && checkCombchar_S2(ald[1],24 ,0xee -1); - OK = OK && checkCombchar_S2(ald[1],25 ,0xce -1); - OK = OK && checkCombchar_S2(ald[1],18 ,0xf4 -1); - OK = OK && checkCombchar_S2(ald[1],19 ,0xd4 -1); - OK = OK && checkCombchar_S2(ald[1],20 ,0xfb -1); - OK = OK && checkCombchar_S2(ald[1],21 ,0xdb -1); - OK = OK && checkCombchar_S2(ald[1],36 ,0xb4 ); - OK = OK && checkCombchar_S2(ald[1],37 ,0xb4 ); - - OK = OK && checkBasechar_S2(ald[2],0, 0x61); - OK = OK && checkBasechar_S2(ald[2],1, 0x41); - OK = OK && checkBasechar_S2(ald[2],6, 0x65); - OK = OK && checkBasechar_S2(ald[2],7, 0x45); - OK = OK && checkBasechar_S2(ald[2],12 ,0x69 ); - OK = OK && checkBasechar_S2(ald[2],13 ,0x49 ); - OK = OK && checkBasechar_S2(ald[2],8 ,0x6f ); - OK = OK && checkBasechar_S2(ald[2],9 ,0x4f ); - OK = OK && checkBasechar_S2(ald[2],10 ,0x75 ); - OK = OK && checkBasechar_S2(ald[2],11 ,0x55 ); - OK = OK && checkBasechar_S2(ald[2],16 ,0x20 ); - OK = OK && checkBasechar_S2(ald[2],17 ,0x20 ); - - OK = OK && checkCombchar_S2(ald[2],0, 0xe2-2); - OK = OK && checkCombchar_S2(ald[2],1, 0xc2-2); - OK = OK && checkCombchar_S2(ald[2],6 ,0xea-2); - OK = OK && checkCombchar_S2(ald[2],7, 0xca-2); - OK = OK && checkCombchar_S2(ald[2],12 ,0xee -2); - OK = OK && checkCombchar_S2(ald[2],13 ,0xce -2); - OK = OK && checkCombchar_S2(ald[2],8 ,0xf4 -2); - OK = OK && checkCombchar_S2(ald[2],9 ,0xd4 -2); - OK = OK && checkCombchar_S2(ald[2],10 ,0xfb -2); - OK = OK && checkCombchar_S2(ald[2],11 ,0xdb -2); - OK = OK && checkCombchar_S2(ald[2],16 ,0x60 ); - OK = OK && checkCombchar_S2(ald[2],17 ,0x60 ); + OK = OK && test_checkBasechar_S2(ald[2],0, 0x61); + OK = OK && test_checkBasechar_S2(ald[2],1, 0x41); + OK = OK && test_checkBasechar_S2(ald[2],14, 0x65); + OK = OK && test_checkBasechar_S2(ald[2],15, 0x45); + OK = OK && test_checkBasechar_S2(ald[2],23 ,0x69 ); + OK = OK && test_checkBasechar_S2(ald[2],24 ,0x49 ); + OK = OK && test_checkBasechar_S2(ald[2],19 ,0x6f ); + OK = OK && test_checkBasechar_S2(ald[2],20 ,0x4f ); + OK = OK && test_checkBasechar_S2(ald[2],21 ,0x75 ); + OK = OK && test_checkBasechar_S2(ald[2],22 ,0x55 ); + OK = OK && test_checkBasechar_S2(ald[2],27 ,0x20 ); + OK = OK && test_checkBasechar_S2(ald[2],28 ,0x20 ); + + OK = OK && test_checkCombchar_S2(ald[2],0, 0xe2); + OK = OK && test_checkCombchar_S2(ald[2],1, 0xc2); + OK = OK && test_checkCombchar_S2(ald[2],14 ,0xea); + OK = OK && test_checkCombchar_S2(ald[2],15, 0xca); + OK = OK && test_checkCombchar_S2(ald[2],23 ,0xee ); + OK = OK && test_checkCombchar_S2(ald[2],24 ,0xce ); + OK = OK && test_checkCombchar_S2(ald[2],19 ,0xf4 ); + OK = OK && test_checkCombchar_S2(ald[2],20 ,0xd4 ); + OK = OK && test_checkCombchar_S2(ald[2],21 ,0xfb ); + OK = OK && test_checkCombchar_S2(ald[2],22 ,0xdb ); + OK = OK && test_checkCombchar_S2(ald[2],27 ,0x5e ); + OK = OK && test_checkCombchar_S2(ald[2],28 ,0x5e ); + + OK = OK && test_checkBasechar_S2(ald[0],0, 0x61); + OK = OK && test_checkBasechar_S2(ald[0],1, 0x41); + OK = OK && test_checkBasechar_S2(ald[0],12, 0x65); + OK = OK && test_checkBasechar_S2(ald[0],13, 0x45); + OK = OK && test_checkBasechar_S2(ald[0],24 ,0x69 ); + OK = OK && test_checkBasechar_S2(ald[0],25 ,0x49 ); + OK = OK && test_checkBasechar_S2(ald[0],18 ,0x6f ); + OK = OK && test_checkBasechar_S2(ald[0],19 ,0x4f ); + OK = OK && test_checkBasechar_S2(ald[0],20 ,0x75 ); + OK = OK && test_checkBasechar_S2(ald[0],21 ,0x55 ); + OK = OK && test_checkBasechar_S2(ald[0],36 ,0x20 ); + OK = OK && test_checkBasechar_S2(ald[0],37 ,0x20 ); + + OK = OK && test_checkCombchar_S2(ald[0],0, 0xe2-1); + OK = OK && test_checkCombchar_S2(ald[0],1, 0xc2-1); + OK = OK && test_checkCombchar_S2(ald[0],12 ,0xea-1); + OK = OK && test_checkCombchar_S2(ald[0],13, 0xca-1); + OK = OK && test_checkCombchar_S2(ald[0],24 ,0xee -1); + OK = OK && test_checkCombchar_S2(ald[0],25 ,0xce -1); + OK = OK && test_checkCombchar_S2(ald[0],18 ,0xf4 -1); + OK = OK && test_checkCombchar_S2(ald[0],19 ,0xd4 -1); + OK = OK && test_checkCombchar_S2(ald[0],20 ,0xfb -1); + OK = OK && test_checkCombchar_S2(ald[0],21 ,0xdb -1); + OK = OK && test_checkCombchar_S2(ald[0],36 ,0xb4 ); + OK = OK && test_checkCombchar_S2(ald[0],37 ,0xb4 ); + + OK = OK && test_checkBasechar_S2(ald[1],0, 0x61); + OK = OK && test_checkBasechar_S2(ald[1],1, 0x41); + OK = OK && test_checkBasechar_S2(ald[1],6, 0x65); + OK = OK && test_checkBasechar_S2(ald[1],7, 0x45); + OK = OK && test_checkBasechar_S2(ald[1],12 ,0x69 ); + OK = OK && test_checkBasechar_S2(ald[1],13 ,0x49 ); + OK = OK && test_checkBasechar_S2(ald[1],8 ,0x6f ); + OK = OK && test_checkBasechar_S2(ald[1],9 ,0x4f ); + OK = OK && test_checkBasechar_S2(ald[1],10 ,0x75 ); + OK = OK && test_checkBasechar_S2(ald[1],11 ,0x55 ); + OK = OK && test_checkBasechar_S2(ald[1],16 ,0x20 ); + OK = OK && test_checkBasechar_S2(ald[1],17 ,0x20 ); + + OK = OK && test_checkCombchar_S2(ald[1],0, 0xe2-2); + OK = OK && test_checkCombchar_S2(ald[1],1, 0xc2-2); + OK = OK && test_checkCombchar_S2(ald[1],6 ,0xea-2); + OK = OK && test_checkCombchar_S2(ald[1],7, 0xca-2); + OK = OK && test_checkCombchar_S2(ald[1],12 ,0xee -2); + OK = OK && test_checkCombchar_S2(ald[1],13 ,0xce -2); + OK = OK && test_checkCombchar_S2(ald[1],8 ,0xf4 -2); + OK = OK && test_checkCombchar_S2(ald[1],9 ,0xd4 -2); + OK = OK && test_checkCombchar_S2(ald[1],10 ,0xfb -2); + OK = OK && test_checkCombchar_S2(ald[1],11 ,0xdb -2); + OK = OK && test_checkCombchar_S2(ald[1],16 ,0x60 ); + OK = OK && test_checkCombchar_S2(ald[1],17 ,0x60 ); return OK; } -bool run_verify_S2(std::vector rgKey) { +bool test_run_verify_S2(std::vector rgKey) { bool allOK= true; allOK = verify_entries_S2(48, rgKey, 48,48,61,61) && allOK; diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h index c76585fab19..5e544545527 100755 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -2,11 +2,10 @@ #ifndef MC_IMPORT_RULES_H #define MC_IMPORT_RULES_H -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ -int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps,const UCKeyboardLayout * keyboard_layout); +// _S2 CHECKED OK +int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps, const UCKeyboardLayout * keyboard_layout); +// _S2 CHECKED OK class DeadKey { private: KMX_WCHAR m_deadchar; diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index 0c2d2cb70da..eae54edf4aa 100755 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -205,7 +205,7 @@ KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL return CERR_SomewhereIGotItWrong; } - fwrite(buf, size,1,hOutfile); + fwrite(buf, size,1, hOutfile); if(offset != size) { delete[] buf; diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index 57395b492c2..a284b88991d 100755 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -6,7 +6,7 @@ #include "km_types.h" #include "kmx_file.h" -#include "filesystem.h" +#include "util_filesystem.h" //_S2 TODO include from keyman; not from this folder #include "mcompile.h" @@ -82,6 +82,3 @@ KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL #endif //MC_KMXFILE_H -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index dfbe49983b0..53afeef9efb 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -31,7 +31,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc, char *argv[]); -bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout,std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 +bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout, std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 std::vector KMX_FDeadkeys; // I4353 @@ -128,7 +128,6 @@ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NU return 3; } - #if defined(_WIN32) || defined(_WIN64) //Windows if(DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); @@ -150,11 +149,6 @@ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NU return 0; } - -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ -// _S2 _84 // Map of all shift states that we will work with const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCTRLFLAG|RALTFLAG, 0xFFFF}; @@ -165,7 +159,6 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCT // correct shift state and key. Adjust the LCTRL+RALT -> RALT if necessary // void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { - //_S2 do we translate here or is this the reason for Shift + K_A <-> Shift 'a' ??? // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. @@ -175,7 +168,7 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) if(key->ShiftFlags == 0 && key->Key == ch) { // Key is a mnemonic key with no shift state defined. // Remap the key according to the character on the key cap. - //mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO + [%x K_%d]", key->Line, key->Key, shift, vk);// 1 + // mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO + [%x K_%d]", key->Line, key->Key, shift, vk);// 1 key->ShiftFlags = ISVIRTUALKEY | shift; key->Key = vk; } else if(key->ShiftFlags & VIRTUALCHARKEY && key->Key == ch) { @@ -184,7 +177,7 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) // This will not result in 100% wonderful mappings as there could // be overlap, depending on how keys are arranged on the target layout. // But that is up to the designer. - //mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, key->ShiftFlags & ~VIRTUALCHARKEY, vk); + // mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, key->ShiftFlags & ~VIRTUALCHARKEY, vk); key->ShiftFlags &= ~VIRTUALCHARKEY; key->Key = vk; } @@ -227,8 +220,6 @@ void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { } void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { -// _S2 TOP_2 INFO this produces a different output due to different layouts for Lin<-> win ( for the same language!!) - if((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" @@ -257,7 +248,7 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, } } -void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group,KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { +void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { for(unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_TranslateDeadkeyKey(&group->dpKeyArray[i], deadkey, vk, shift, ch); } @@ -376,15 +367,13 @@ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_ // Lookup the deadkey table for the deadkey in the physical keyboard // Then for each character, go through and map it through KMX_WCHAR dkid = mac_KMX_GetUniqueDeadkeyID(kbd, deadkey); - // Add the deadkey to the mapping table for use in the import rules phase KMX_DeadkeyMapping KMX_deadkeyMapping = { deadkey, dkid, shift, vk_US}; // I4353 KMX_FDeadkeys.push_back(KMX_deadkeyMapping); //dkid, vk, shift); // I4353 mac_KMX_AddDeadkeyRule(kbd, dkid, vk_US, shift); - // creates array [a,e,i,o,u][shiftstate][combined for a+dk e.g. â ] - mac_KMX_GetDeadkeys( deadkey, shift, pdk = deadkeys, All_Vector, keyboard_layout); // returns array of [usvk, ch_out] pairs + mac_KMX_GetDeadkeys(keyboard_layout, All_Vector, deadkey, shift, pdk = deadkeys ); // returns array of [usvk, ch_out] pairs while(*pdk) { // Look up the ch @@ -415,6 +404,13 @@ KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { return FALSE; } + + + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc, char *argv[]) { KMX_WCHAR DeadKey=0; @@ -427,34 +423,62 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int // evident for the 102nd key on UK, for example, where \ can be generated with VK_OEM_102 or AltGr+VK_QUOTE. // For now, we get the least shifted version, which is hopefully adequate. - // _S2 : Sadly it`s not: on a German WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only. - // on a German MAC keyboard one will get '~' with either OPT + K_221(+) or OPT + K_84(T) or CAPS + OPT + K_78(N) - // K_84 will be caught first, so one of the the least obvious version for creating the '~' is found and processed. - - // -> meeting with Marc May 21 2024: We leave it as it is for now; it is OK if different combinations are found. + // Sadly it`s not: on a German WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only which is the usual combination to get ~. + // on a German MAC keyboard one will get '~' with either OPT + K_221(+) or OPT + K_84(T) or CAPS + OPT + K_78(N) + // K_84(T) will be caught first, so one of the the least obvious version for creating the '~' is found and processed. + // -> meeting with Marc May 21 2024: We leave it as it is; it is OK if different combinations are found. const UCKeyboardLayout* keyboard_layout; if(mac_InitializeUCHR(&keyboard_layout)) { wprintf(L"ERROR: can't Initialize GDK\n"); return FALSE; } - // create vector that contains Keycode, base, shift for US-Keyboard and underlying keyboard + // create vector that contains Keycode, Base, Shift for US-Keyboard and underlying keyboard v_dw_3D All_Vector; if(mac_createOneVectorFromBothKeyboards(All_Vector, keyboard_layout)){ wprintf(L"ERROR: can't create one vector from both keyboards\n"); return FALSE; } - // _S2 which shiftstates?? + //printoutKeyboards(All_Vector); + +print_character_of_key_S2(keyboard_layout, 40); +print_character_of_key_S2(keyboard_layout, 43); +print_character_of_key_S2(keyboard_layout, 24); +print_character_of_key_S2(keyboard_layout, 42); +print_character_of_key_S2(keyboard_layout, 39); +print_character_of_key_S2(keyboard_layout, 44); + +//DE: comma +find_character_S2(keyboard_layout, 44); +//DE: equal +find_character_S2(keyboard_layout, 39); +find_character_S2(keyboard_layout, 45); + + +//FR: BKSLASH +print_character_of_key_S2(keyboard_layout, 10); +print_character_of_key_S2(keyboard_layout, 42); +find_character_S2(keyboard_layout, 35); +find_character_S2(keyboard_layout, 64); + + +//ES HYPHEN +print_character_of_key_S2(keyboard_layout, 43); +print_character_of_key_S2(keyboard_layout, 39); +print_character_of_key_S2(keyboard_layout, 27); +find_character_S2(keyboard_layout, 180); +printf("-------\n"); +print_dublicates_S2(keyboard_layout); +//find_double_keys(keyboard_layout,1); for (int j = 0; VKShiftState[j] != 0xFFFF; j++) { // I4651 // Loop through each possible key on the keyboard for (int i = 0;KMX_VKMap[i]; i++) { // I4651 // windows uses VK, Linux and macOS use SC/Keycode - // _S2 ToDo unused vk`s ?? UINT scUnderlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_VKMap[i]); - KMX_WCHAR ch = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, VKShiftState[j], scUnderlying, &DeadKey); + KMX_WCHAR ch = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, scUnderlying, VKShiftState[j], &DeadKey); //wprintf(L"--- VK_%d -> SC_ [%c] dk=%d ( ss %i) \n", KMX_VKMap[i], ch == 0 ? 32 : ch, DeadKey, VKShiftState[j]); @@ -464,7 +488,6 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int } } - // _S2 ?5E OK till here switch(ch) { case 0x0000: break; case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout); break; @@ -472,7 +495,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int } } } - // _S2 ToDo non-dk OK,shifted dk are not?? + mac_KMX_ReportUnconvertedKeyboardRules(kbd); if(!mac_KMX_ImportRules(kbd, All_Vector, &keyboard_layout, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 @@ -481,54 +504,36 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int return TRUE; } +int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ) { -int mac_KMX_GetDeadkeys( KMX_WCHAR DeadKey, UINT shift_dk, KMX_WORD *OutputPairs, v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { - + UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; + OptionBits keyTranslateOptions = 0; UniChar unicodeString[maxStringlength]; - KMX_WORD *p = OutputPairs; - UInt32 deadkeystate = 0; OSStatus status; - KMX_WORD shift[4] ={0,2,8,10}; - - KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying( All_Vector, (KMX_DWORD) DeadKey); - - /*// _S2 - // we go in this order because we need to make sure that the most obvious keycombination is taken into account for deadkeys. - // This is important since it catches only the first key that matches a given rule, but multiple keys may match that rule. - // (see explanation in mcompile.cpp DoConvert() ) - // space is the most important one for deadkeys, so we start with Space (Keycode 49) - // then character keys in alphabetical order, then numbers, then punctuation keys - - // SPACE, A_Z, 0-9, VK_ACCENT,HYPHEN,EQUAL,LBRKT,RBRKT,BKSLASH,COLON,QUOTE,COMMA,PERIOD,SLASH,xDF,OEM_102 - int keyarray[] ={ - 49, - 0, 11, 8, 2, 14, 3, 5, 4, 34, 38, 40, 37, 46, 45, 31, 35, 12, 15, 1, 17, 32, 9, 13, 7, 16, 6, - 29, 18, 19, 20, 21, 23, 22, 26, 28, 25, - 42, 27, 24, 33, 30, 42, 41, 39, 43, 47, 44, 223, 226, 0xFFFF - };*/ + unicodeString[0] = 0; - for ( int j=0; j < sizeof(shift)/sizeof(shift[0]); j++) { - -// _S2 _84 - // we start calculating SPACE(49) since most obvious deadkeys combinations use space. - // _S2 for (int i = 0; keyarray[i] != 0xFFFF; i++) { - for ( int i=Keycode_Spacebar; i >=0; i--) { + KMX_WORD *p = OutputPairs; + KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying( All_Vector, deadkey); - status = UCKeyTranslate(keyboard_layout, sc_dk ,kUCKeyActionDown, mac_map_VKShiftState_to_MacModifier(shift_dk), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + for ( int j=0; j < sizeof(ss_mac)/sizeof(ss_mac[0]); j++) { + // we start with SPACE (keycode_spacebar=49) since all deadkeys occur in combinations with space. + // Since mcompile finds only the first occurance of a dk combination, this makes sure that we always find the dk+SPACE combinations for a deadkey. + // If there are more combinations to create a specific character they will not be found. (See comment at the beginning of mac_KMX_DoConvert()) + for ( int i=keycode_spacebar; i >=0; i--) { + status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_map_VKShiftState_to_MacModifier(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { - // _S2 status = UCKeyTranslate(keyboard_layout, keyarray[i] ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + status = UCKeyTranslate(keyboard_layout, i, kUCKeyActionDown, ss_mac[j], LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { - // _S2 KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, keyarray[i], 1); - KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, i, 1); - // _S2 to not get combinations like ^a but only combined characters like â ( exception for ^+space) - if((unicodeString[0] != DeadKey) || (vk == 32)) { + KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, i, ss_mac[1]); + + // ensure to not get key combinations like ^a but only combined characters like â ( exception for ^+space) + if((unicodeString[0] != deadkey) || (vk == 32)) { *p++ = vk; - *p++ = shift[j]; + *p++ = ss_mac[j]; *p++ =unicodeString[0]; } } @@ -586,16 +591,97 @@ bool test_dk_find_entries_S2(KMX_WORD deadkeys[512], int search) { return true; } } - return false; + return false; } bool test_dk_write_entries_S2(KMX_WORD deadkeys[512]) { for ( int i=0; i< 512/3;i++) { if ( deadkeys[3*i] !=0) - printf(" %i set nr \t%i: %i\t-\t%i(%c)\t-\t%i(%c) \n",deadkeys[2] ,i,deadkeys[3*i+1], deadkeys[3*i],deadkeys[3*i],deadkeys[3*i+2],deadkeys[3*i+2]); + printf(" %i set nr \t%i: %i\t-\t%i(%c)\t-\t%i(%c) \n", deadkeys[2], i,deadkeys[3*i+1], deadkeys[3*i], deadkeys[3*i], deadkeys[3*i+2], deadkeys[3*i+2]); } return true; } +bool find_print_character_S2(const UCKeyboardLayout * keyboard_layout, int keyval, int k, int c, int s) { + int ss_rgkey; +int count =0; +bool moreval=false; + std::vector res_vec; + + for ( int key=0; key< 50;key++) { + for ( int caps=0; caps< 2;caps++) { + for ( int ss=0; ss< 10;ss++) { + + if( ss == 0 ) ss_rgkey= 0; + else if( ss == 2 ) ss_rgkey= 1; + else if( ss == 8 ) ss_rgkey= 6; + else if( ss == 10 ) ss_rgkey= 7; + else ss_rgkey= 999; +if( (ss==1) || (ss==3) || (ss==5) || (ss==7) || (ss==9) ) +continue; + + int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, ss, caps); + + count++; + if((ss_rgkey!= 999 )&& ( keyval!= 0)&& ( keyval== keyvalsearch)&& ( count>1)&& ( key!=k)) { + printf( " key: %i, ss_mac: %i ( ss_rgkey:%i), caps:%i \n",key, ss, ss_rgkey, caps); + moreval=true; + } + } + } + } + return moreval; +} +bool print_dublicates_S2(const UCKeyboardLayout * keyboard_layout){ + for ( int key=0; key< 50;key++) { + for ( int caps=0; caps< 2;caps++) { + for ( int ss=0; ss< 6;ss++) { + int keyval= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, 2*ss, caps); + if (find_print_character_S2(keyboard_layout, keyval, key,caps,ss) && (keyval>0)) { + printf( "Keyval %i(%c): can be found on : \tkey: %i, ss-mac: %i caps:%i\t:\n---------------------------------------------------------\n",keyval,keyval, key, 2*ss,caps); + } + } + } + } + + + return true; +} +bool print_character_of_key_S2(const UCKeyboardLayout * keyboard_layout, int key) { +int ss_rgkey; + for ( int ss=0; ss< 6;ss++) { + for ( int caps=0; caps< 2;caps++) { + + int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, 2*ss, caps); + printf( " key %i has values : %i (%c) ( ss:%i, caps:%i) \n", key, keyvalsearch,keyvalsearch, 2*ss, caps); + } + } + return true; +} +bool find_character_S2(const UCKeyboardLayout * keyboard_layout, int keyval) { +int ss_rgkey; + for ( int ss=0; ss< 10;ss++) { + +if( ss == 0 ) ss_rgkey= 0; +else if( ss == 2 ) ss_rgkey= 1; +else if( ss == 8 ) ss_rgkey= 6; +else if( ss == 10 ) ss_rgkey= 7; +else ss_rgkey= 999; + +if( (ss==1) || (ss==3) || (ss==5) || (ss==7) || (ss==9) ) +continue; + + for ( int caps=0; caps< 2;caps++) { + for ( int key=0; key< 50;key++) { + int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, mac_map_Win_ShiftState_to_MacModifier(ss), caps); + if((ss_rgkey!= 999 )&& ( keyval== keyvalsearch)) + printf( " found keyval: key: %i, ss_mac:%i ( ss_rgkey:%i), caps:%i -> character: %i (%c) \n", key, ss, ss_rgkey, caps, keyvalsearch,keyvalsearch); + } + } + } + return true; +} + + //-------------------------- /*void fun2() { std::cout << "Hier ist fun2 von mcompile.cpp ...\n";} diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 6c941facb9a..d384cc38364 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -3,7 +3,8 @@ #include "keymap.h" #include -#include "deadkey.h" +#include +#include "mc_import_rules.h" #include "mc_kmxfile.h" /* @@ -34,30 +35,30 @@ struct KMX_DeadkeyMapping { // I4353 extern std::vector KMX_FDeadkeys; // I4353 +// _S2 CHECKED OK int mac_run(int argc, std::vector str_argv, char* argv[]); PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); +// _S2 CHECKED OK +int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ); // returns array of [usvk, ch_out] pairs -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - - - -int mac_KMX_GetDeadkeys( KMX_WCHAR deadkey, UINT shift, KMX_WORD *OutputPairs, v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout); // returns array of [usvk, ch_out] pairs - +// _S2 CHECKED OK void mac_KMX_LogError(const wchar_t* fmt, ...); //################################################################################################################################################ //################################################################################################################################################ +bool find_print_character_S2(const UCKeyboardLayout * keyboard_layout, int keyval, int k, int c, int s); +bool print_dublicates_S2(const UCKeyboardLayout * keyboard_layout); +bool print_character_of_key_S2(const UCKeyboardLayout * keyboard_layout, int key) ; +bool find_character_S2(const UCKeyboardLayout * keyboard_layout, int keyval) ; + bool test_dk_S2(KMX_WORD deadkeys[512], KMX_WORD deadkeys1[512]); bool test_dk_find_entries_S2(KMX_WORD deadkeys[512], int search); bool test_dk_write_entries_S2(KMX_WORD deadkeys[512]); - - void fun2(); void testmyFunctions_S2(); + #endif // MCOMPILE_H \ No newline at end of file diff --git a/mac/mcompile/mcompiletest.kmx b/mac/mcompile/mcompiletest.kmx deleted file mode 100755 index 4f9224998a830a6671c848c8b6b192bdccff877e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 526 zcmaix%Su8~6o!AD7$Jgm(P5xC^WXuaX=pQ><)Eo}!AqwT$1d2jG-&GE_yi4lh^FWXLP4n59|ps^ApXfh|`=<7Yfus=L%C2p8j+aCzfIHNPQ|J`c3FNR2R*eE-lff wgUw&;$hI3>cAyzIneEB=eM_C1SWnCztIpgW-OabTVXFVHAgs*~8k=R%4*`ZgvH$=8 diff --git a/mac/mcompile/u16.h b/mac/mcompile/u16.h index 7f18e03ec15..310f4e22bc4 100755 --- a/mac/mcompile/u16.h +++ b/mac/mcompile/u16.h @@ -8,6 +8,7 @@ #include #include "km_types.h" +// _S2 CHECKED_ std::vector convert_argvW_to_Vector_u16str(int argc, wchar_t* argv[]); std::vector convert_argv_to_Vector_u16str(int argc, char* argv[]); diff --git a/mac/mcompile/filesystem.cpp b/mac/mcompile/util_filesystem.cpp similarity index 84% rename from mac/mcompile/filesystem.cpp rename to mac/mcompile/util_filesystem.cpp index 459312448e7..7f9edd6b367 100755 --- a/mac/mcompile/filesystem.cpp +++ b/mac/mcompile/util_filesystem.cpp @@ -7,7 +7,7 @@ #include #include #include -#include "filesystem.h" +#include "util_filesystem.h" #ifdef _MSC_VER #include @@ -187,6 +187,41 @@ KMX_BOOL kmcmp_FileExists(const KMX_WCHAR* filename) { return FALSE; }; -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ + +bool IsRelativePath(KMX_CHAR const * p) { + // Relative path (returns TRUE): + // ..\...\BITMAP.BMP + // PATH\BITMAP.BMP + // BITMAP.BMP + + // Semi-absolute path (returns FALSE): + // \...\BITMAP.BMP + + // Absolute path (returns FALSE): + // C:\...\BITMAP.BMP + // \\SERVER\SHARE\...\BITMAP.BMP + + if ((*p == '\\') || (*p == '/')) return FALSE; + if (*p && *(p + 1) == ':') return FALSE; + + return TRUE; +} + +bool IsRelativePath(KMX_WCHAR const * p) { + // Relative path (returns TRUE): + // ..\...\BITMAP.BMP + // PATH\BITMAP.BMP + // BITMAP.BMP + + // Semi-absolute path (returns FALSE): + // \...\BITMAP.BMP + + // Absolute path (returns FALSE): + // C:\...\BITMAP.BMP + // \\SERVER\SHARE\...\BITMAP.BMP + + if ((*p == u'\\') || (*p == u'/'))return FALSE; + if (*p && *(p + 1) == u':') return FALSE; + + return TRUE; +} \ No newline at end of file diff --git a/mac/mcompile/util_filesystem.h b/mac/mcompile/util_filesystem.h new file mode 100755 index 00000000000..38877bf9f26 --- /dev/null +++ b/mac/mcompile/util_filesystem.h @@ -0,0 +1,16 @@ +#pragma once + +#include +//#include _S2 "../src/kmx_u16.h" we want to include this... +#include "u16.h" + +// Opens files on windows and non-windows platforms. Datatypes for Filename and mode must be the same. +// returns FILE* if file could be opened; FILE needs to be closed in calling function +FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); +FILE* Open_File(const KMX_WCHART* Filename, const KMX_WCHART* mode); +FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode); +KMX_BOOL kmcmp_FileExists(const KMX_CHAR *filename); +KMX_BOOL kmcmp_FileExists(const KMX_WCHAR *filename); + +bool IsRelativePath(KMX_CHAR const * p); +bool IsRelativePath(KMX_WCHAR const * p); \ No newline at end of file From b2d9e96488062ac04f20c0749a002b10dc8703fc Mon Sep 17 00:00:00 2001 From: Sabine Date: Tue, 21 May 2024 18:23:20 +0200 Subject: [PATCH 29/71] feat(mac): tidy up code: fixes #11334 use shiftstates consistently; map shiftstates to mac shiftstates(mac, rgkey, win); remove unneccessary functions; rename functions to have more systematic consolidate order of parameters in functions; rename variables (casing), and also to clarify shiftstates; handle unused positions in USVirtualKeyToScanCode+ScanCodeToUSVirtualKey; use util_filesystem.cpp/h from Keyman instead of my own filesystem.cpp/h; remove deadkey.cpp/h; --- mac/mcompile/deadkey.cpp | 476 ------ mac/mcompile/deadkey.h | 32 - mac/mcompile/filesystem.h | 16 - mac/mcompile/keymap.cpp | 623 +++----- mac/mcompile/keymap.h | 1295 ++++++----------- mac/mcompile/km_types.h | 5 - mac/mcompile/kmx_file.h | 4 - mac/mcompile/mc_import_rules.cpp | 348 +++-- mac/mcompile/mc_import_rules.h | 7 +- mac/mcompile/mc_kmxfile.cpp | 2 +- mac/mcompile/mc_kmxfile.h | 5 +- mac/mcompile/mcompile.cpp | 216 ++- mac/mcompile/mcompile.h | 23 +- mac/mcompile/mcompiletest.kmx | Bin 526 -> 0 bytes mac/mcompile/u16.h | 1 + .../{filesystem.cpp => util_filesystem.cpp} | 43 +- mac/mcompile/util_filesystem.h | 16 + 17 files changed, 994 insertions(+), 2118 deletions(-) delete mode 100755 mac/mcompile/deadkey.cpp delete mode 100755 mac/mcompile/deadkey.h delete mode 100755 mac/mcompile/filesystem.h delete mode 100755 mac/mcompile/mcompiletest.kmx rename mac/mcompile/{filesystem.cpp => util_filesystem.cpp} (84%) create mode 100755 mac/mcompile/util_filesystem.h diff --git a/mac/mcompile/deadkey.cpp b/mac/mcompile/deadkey.cpp deleted file mode 100755 index 09f6ca0f9b2..00000000000 --- a/mac/mcompile/deadkey.cpp +++ /dev/null @@ -1,476 +0,0 @@ -#include "keymap.h" -#include "deadkey.h" -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - -// _S2 TODO dk - -/* v_dw_1D mac_createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult) { - v_dw_1D line; - line.push_back(mac_convertNamesTo_DWORD_Value(first)); - line.push_back(mac_convertNamesTo_DWORD_Value(second)); - //line.push_back(mac_convertNamesTo_DWORD_Value(nameresult)); - line.push_back(number); - return line; -}*/ - -/*std::vector mac_create_alDead() { - std::vector alDead; - v_dw_2D dk_ComposeTable; - - mac_create_DKTable(dk_ComposeTable); - - for( int i=0; i < (int) dk_ComposeTable.size()-1; i++) { - DeadKey *dk2 = new DeadKey(dk_ComposeTable[i][0]); - for ( int j=0; j< (int) dk_ComposeTable.size();j++) { - if(( dk_ComposeTable[i][0] == dk_ComposeTable[j][0]) && (mac_IsKeymanUsedChar(dk_ComposeTable[j][1]))) - dk2->KMX_AddDeadKeyRow(dk_ComposeTable[j][1],dk_ComposeTable[j][2]); - } - alDead.push_back(dk2); - } - return alDead; -}*/ - -/*void mac_refine_alDead(KMX_WCHAR dk, std::vector &dkVec, std::vector *p_All_Vec) { - if( dk == 0) - return; - - for (int j=0; j < (int) (*p_All_Vec).size()-1;j++) { - if( dk == (*p_All_Vec)[j]->KMX_GetDeadCharacter()) { - if(! found_dk_inVector(dk, dkVec)) { - dkVec.push_back((*p_All_Vec)[j]); - return; - } - else return; - } - } -}*/ - -/* bool found_dk_inVector(KMX_WCHAR dk, std::vector &dkVec) { - int i=0; - if( dkVec.size() > 0) { - do { - if( dk == dkVec[i]->KMX_GetDeadCharacter()) - return true; - i++; - } while (i < (int) dkVec.size()); - } - return false; -}*/ - -/*bool mac_query_dk_combinations_for_specific_dk(v_dw_2D * p_dk_ComposeTable, v_dw_2D &dk_SingleTable, KMX_DWORD dk) { - v_dw_1D line; - - for ( int i =0; i< (int) (*p_dk_ComposeTable).size(); i++) { - if (((*p_dk_ComposeTable)[i][0] == dk) && (mac_IsKeymanUsedChar((*p_dk_ComposeTable)[i][1]))) { - line.push_back((*p_dk_ComposeTable)[i][0]); - line.push_back((*p_dk_ComposeTable)[i][1]); - line.push_back((*p_dk_ComposeTable)[i][2]); - dk_SingleTable.push_back(line); - line.clear(); - } - } - - if( dk_SingleTable.size()>0) - return true; - else - return false; -}*/ - -/*KMX_DWORD mac_KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, const UCKeyboardLayout * keyboard_layout) { - guint Keyval = (guint) KVal; - GdkKeymapKey* keys; - gint n_keys; - - KMX_DWORD Cap = (KMX_DWORD) gdk_keyval_to_upper (KVal); - if( Keyval !=0) { - gdk_keymap_get_entries_for_keyval(keymap, Keyval, &keys, &n_keys); - for (int i = 0; i < n_keys; i++) { - if (keys[i].group == 0) { - shift = keys[i].level; - return Cap; - } - } - } - return Cap; - KMX_DWORD out_S2 =0; - return out_S2; -}*/ - -/* void mac_create_DKTable(v_dw_2D & dk_ComposeTable) { -//create a 2D-Vector which contains data for ALL existing deadkey combinations on a Linux Keyboard: - //dk_ComposeTable[i][0] : First (e.g. dead_circumflex) - //dk_ComposeTable[i][1] : Second (e.g. a) - //dk_ComposeTable[i][3] : Unicode-Value (e.g. 0x00E2) - - //values taken from: https://help.ubuntu.com/community/GtkDeadKeyTable#Accents - // _S2 Do we want to use GTK instead of this function? - - v_dw_1D line; - - line = mac_createLine("dead_circumflex", "a", 0x00E2, "small A with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "A", 0x00C2, "capital A with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "e", 0x00EA, "small E with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "E", 0x00CA, "capital E with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "i", 0x00EE, "small I with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "I", 0x00CE, "capital I with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "o", 0x00F4, "small O with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "O", 0x00D4, "capital O with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "u", 0x00FB, "small U with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "U", 0x00DB, "capital U with circumflex"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_acute", "a", 0x00E1, "small A with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "A", 0x00C1, "capital A with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "c", 0x0107, "small C with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "C", 0x0106, "capital C with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "e", 0x00E9, "small E with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "E", 0x00C9, "capital E with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "i", 0x00ED, "small I with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "I", 0x00CD, "capital I with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "l", 0x013A, "small L with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "L", 0x0139, "capital L with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "n", 0x0144, "small N with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "N", 0x0143, "capital N with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "o", 0x00F3, "small O with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "O", 0x00D3, "capital O with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "r", 0x0155, "small R with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "R", 0x0154, "capital R with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "s", 0x015B, "small S with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "S", 0x015A, "capital S with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "u", 0x00FA, "small U with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "U", 0x00DA, "capital U with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "y", 0x00FD, "small Y with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "Y", 0x00DD, "capital Y with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "z", 0x017A, "small Z with acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "Z", 0x0179, "capital Z with acute"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_grave", "a", 0x00E0, "small A with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "A", 0x00C0, "capital A with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "e", 0x00E8, "small E with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "E", 0x00C8, "capital E with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "i", 0x00EC, "small I with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "I", 0x00CC, "capital I with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "o", 0x00F2, "small O with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "O", 0x00D2, "capital O with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "u", 0x00F9, "small U with grave"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "U", 0x00D9, "capital U with grave"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_tilde", "a", 0x00E3, "small A with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "A", 0x00C3, "capital A with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "i", 0x0129, "small I with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "I", 0x0128, "capital I with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "n", 0x00F1, "small N with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "N", 0x00D1, "capital N with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "o", 0x00F5, "small O with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "O", 0x00D5, "capital O with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "u", 0x0169, "small U with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "U", 0x0168, "capital U with tilde"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_macron", "a", 0x0101, "small A with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "A", 0x0100, "capital A with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "e", 0x0113, "small E with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "E", 0x0112, "capital E with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "i", 0x012B, "small I with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "I", 0x012A, "capital I with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "o", 0x014D, "small O with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "O", 0x014C, "capital O with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "u", 0x016B, "small U with macron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "U", 0x016A, "capital U with macron"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_breve", "a", 0x0103, "small A with breve"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_breve", "A", 0x0102, "capital A with breve"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_breve", "g", 0x011F, "small G with breve"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_breve", "G", 0x011E, "capital G with breve"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_abovedot", "e", 0x0117, "small E with dot above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "E", 0x0116, "capital E with dot above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "i", 0x0131, "small DOTLESS_I"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "I", 0x0130, "capital I with dot above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "z", 0x017C, "small Z with dot above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "Z", 0x017B, "capital Z with dot above"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_diaeresis", "a", 0x00E4, "small A with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "A", 0x00C4, "capital A with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "e", 0x00EB, "small E with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "E", 0x00CB, "capital E with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "i", 0x00EF, "small I with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "I", 0x00CF, "capital I with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "o", 0x00F6, "small O with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "O", 0x00D6, "capital O with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "u", 0x00FC, "small U with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "U", 0x00DC, "capital U with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "y", 0x00FF, "small Y with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "Y", 0x0178, "capital Y with diaeresis"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_abovering", "a", 0x00E5, "small A with ring above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovering", "A", 0x00C5, "capital A with ring above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovering", "u", 0x016F, "small U with ring above"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovering", "U", 0x016E, "capital U with ring above"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_doubleacute", "o", 0x0151, "small O with double acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_doubleacute", "O", 0x0150, "capital O with double acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_doubleacute", "u", 0x0171, "small U with double acute"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_doubleacute", "U", 0x0170, "capital U with double acute"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_caron", "c", 0x010D, "small C with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "C", 0x010C, "capital C with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "d", 0x010F, "small D with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "D", 0x010E, "capital D with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "e", 0x011B, "small E with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "E", 0x011A, "capital E with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "l", 0x013E, "small L with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "L", 0x013D, "capital L with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "n", 0x0148, "small N with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "N", 0x0147, "capital N with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "r", 0x0159, "small R with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "R", 0x0158, "capital R with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "s", 0x0161, "small S with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "S", 0x0160, "capital S with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "t", 0x0165, "small T with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "T", 0x0164, "capital T with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "z", 0x017E, "small Z with caron"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "Z", 0x017D, "capital Z with caron"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_cedilla", "c", 0x00E7, "small C with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "C", 0x00C7, "capital C with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "g", 0x0123, "small G with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "G", 0x0122, "capital G with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "k", 0x0137, "small K with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "K", 0x0136, "capital K with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "l", 0x013C, "small L with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "L", 0x013B, "capital L with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "n", 0x0146, "small N with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "N", 0x0145, "capital N with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "r", 0x0157, "small R with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "R", 0x0156, "capital R with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "s", 0x015F, "small S with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "S", 0x015E, "capital S with cedilla"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_ogonek", "a", 0x0105, "small A with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "A", 0x0104, "capital A with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "e", 0x0119, "small E with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "E", 0x0118, "capital E with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "i", 0x012F, "small I with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "I", 0x012E, "capital I with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "u", 0x0173, "small U with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "U", 0x0172, "capital U with ogonek"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_circumflex", "space", 0x005E, "CIRCUMFLEX_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_acute", "space", 0x0027, "APOSTROPHE"); - dk_ComposeTable.push_back(line); line.clear(); - //line = mac_createLine("dead_acute", "space", 0x00B4, "ACUTE_ACCENT"); // _S2 TOP_3 ToDo remove - this is not right: just for testing - // dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_grave", "space", 0x0060, "GRAVE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_breve", "space", 0x02D8, "BREVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "space", 0x02D9, "DOT_ABOVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovering", "space", 0x02DA, "RING_ABOVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_doubleacute", "space", 0x02DD, "DOUBLE_ACUTE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "space", 0x02C7, "CARON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "space", 0x00B8, "CEDILLA"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "space", 0x02DB, "OGONEK"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "space", 0x007E, "TILDE"); - dk_ComposeTable.push_back(line); line.clear(); - - line = mac_createLine("dead_breve", "dead_breve", 0x02D8, "BREVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "abovedot", 0x02D9, "DOT_ABOVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovedot", "dead_abovedot", 0x02D9, "DOT_ABOVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_abovering", "dead_abovering", 0x02DA, "RING_ABOVE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "apostrophe", 0x00B4, "ACUTE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "acute", 0x00B4, "ACUTE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_acute", "dead_acute", 0x00B4, "ACUTE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_doubleacute", "dead_doubleacute", 0x02DD, "DOUBLE_ACUTE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "caron", 0x02C7, "CARON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_caron", "dead_caron", 0x02C7, "CARON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "comma", 0x00B8, "CEDILLA"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "cedilla", 0x00B8, "CEDILLA"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_cedilla", "dead_cedilla", 0x00B8, "CEDILLA"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "minus", 0x00AF, "MACRON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "asciicircum", 0x005E, "CIRCUMFLEX_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "underscore", 0x00AF, "MACRON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_circumflex", "dead_circumflex", 0x005E, "CIRCUMFLEX_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "quotedbl", 0x00A8, "DIAERESIS"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "diaeresis", 0x00A8, "DIAERESIS"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_diaeresis", "dead_diaeresis", 0x00A8, "DIAERESIS"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "grave", 0x0060, "GRAVE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_grave", "dead_grave", 0x0060, "GRAVE_ACCENT"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "macron", 0x00AF, "MACRON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_macron", "dead_macron", 0x00AF, "MACRON"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "ogonek", 0x02DB, "OGONEK"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_ogonek", "dead_ogonek", 0x02DB, "OGONEK"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "asciitilde", 0x007E, "TILDE"); - dk_ComposeTable.push_back(line); line.clear(); - line = mac_createLine("dead_tilde", "dead_tilde", 0x007E, "TILDE"); - dk_ComposeTable.push_back(line); line.clear(); -}*/ diff --git a/mac/mcompile/deadkey.h b/mac/mcompile/deadkey.h deleted file mode 100755 index d76c1386b1b..00000000000 --- a/mac/mcompile/deadkey.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#ifndef DEADKEY_H -#define DEADKEY_H - -#include -#include "mc_import_rules.h" -// _S2 TODO dk -// create a vector for a dk combination ( ` + a -> à ) -//v_dw_1D mac_createLine(std::string first, std::string second, KMX_DWORD number, std::string nameresult); - -// create a 2D-vector of all dk combinations ( ` + a -> à ; ^ + a -> â ; `+ e -> è; ...) -//void mac_create_DKTable(v_dw_2D & dk_ComposeTable); - -// find all possible dk combinations that exist// -//std::vector mac_create_alDead(); - -// refine dk to those used in the underlying keyboard -//void mac_refine_alDead(KMX_WCHAR dk, std::vector &myVec, std::vector *p_All_Vec); -// check if entry is already there -//bool found_dk_inVector(KMX_WCHAR dk, std::vector &myVec); - -// get all combination for a specific deadkey(dk) from the dk_vector mac_query_dk_combinations_for_specific_dk which holds all possible dk: ^-> â,ê,î,ô,û,... -//bool mac_query_dk_combinations_for_specific_dk(v_dw_2D * dk_ComposeTable, v_dw_2D & dk_SingleTable, KMX_DWORD dk); - -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - -// get the shifted character of a key and write shiftstate of KVal to shift -//KMX_DWORD mac_KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, const UCKeyboardLayout * keyboard_layout); - -# endif//DEADKEY_H \ No newline at end of file diff --git a/mac/mcompile/filesystem.h b/mac/mcompile/filesystem.h deleted file mode 100755 index 7e30f73b052..00000000000 --- a/mac/mcompile/filesystem.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -#include "u16.h" - -// Open files on windows and non-windows platforms. Datatypes for Filename and mode must be the same. -// return FILE* if file could be opened; FILE must to be closed in calling function -FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); -FILE* Open_File(const KMX_WCHART* Filename, const KMX_WCHART* mode); -FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode); -KMX_BOOL kmcmp_FileExists(const KMX_CHAR *filename); -KMX_BOOL kmcmp_FileExists(const KMX_WCHAR *filename); - -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 6239b325aa5..8e0f43c4c3c 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -1,31 +1,38 @@ #include "keymap.h" -// _S2 _84 Shiftstates -// Base, Shift, OPT, Shift+OPT - -// mapping for VKShiftState -> UcKeyTranslate uses 0,2,8,10 ( 4,6,12,14 with caps) -int mac_map_VKShiftState_to_MacModifier(int VKShiftState) { - if (VKShiftState == 0 ) return 0; - else if (VKShiftState == 16) return 2; - else if (VKShiftState == 9) return 8; - else if (VKShiftState == 25) return 10; - else return VKShiftState; // _S2 what to return if no match?? +// mapping for Base,Shift,OPT,Shift+OPT from vk_ShiftState -> shiftstates UcKeyTranslate uses (0,2,8,10 - 4,6,12,14 with caps) +int mac_map_VKShiftState_to_MacModifier(int vk_ShiftState) { + if (vk_ShiftState == 0 ) return 0; + else if (vk_ShiftState == 16) return 2; + else if (vk_ShiftState == 9) return 8; + else if (vk_ShiftState == 25) return 10; + else return vk_ShiftState; } -// Base, Shift, OPT, Shift+OPT -// mapping for rgkey -> UcKeyTranslate uses 0,2,8,10 ( 4,6,12,14 with caps) -int mac_map_ShiftState_to_MacModifier(int ShiftState) { - if (ShiftState == 0 ) return 0; - else if (ShiftState == 1) return 2; - else if (ShiftState == 6 ) return 8; - else if (ShiftState == 7) return 10; - // more?? - else return ShiftState; // _S2 what to return if no match?? +// mapping for Base,Shift,OPT,Shift+OPT from rgkey -> shiftstates UcKeyTranslate uses (0,2,8,10 - 4,6,12,14 with caps) +int mac_map_Win_ShiftState_to_MacModifier(int win_ShiftState) { + if (win_ShiftState == 0 ) return 0; + else if (win_ShiftState == 1) return 2; + else if (win_ShiftState == 6 ) return 8; + else if (win_ShiftState == 7) return 10; + else return win_ShiftState; + } + +/*bool is_correct_mac_shiftstate(int comp_ss) { + return ( (comp_ss ==0) || (comp_ss ==2) || (comp_ss ==8) || (comp_ss ==10) ); +}*/ + +/*bool is_correct_rgkey_shiftstate(int comp_ss) { + return ( (comp_ss ==0) || (comp_ss ==1) || (comp_ss ==6) || (comp_ss ==7) ); +}*/ + +bool is_correct_win_shiftstate(int comp_ss) { + return ( (comp_ss ==0) || (comp_ss ==16) || (comp_ss ==9) || (comp_ss ==25) || (comp_ss ==0xFFFF) ); } int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { // create a 3D-Vector which contains data of the US keyboard and the underlying Keyboard: - // All_Vector[ US_Keyboard ] + // All_Vector[ US_Keyboard ] // [KeyCode_US ] // [Keyval unshifted ] // [Keyval shifted ] @@ -40,7 +47,7 @@ int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLa } // add contents of underlying keyboard to All_Vector - if( mac_append_underlying_ToVector(All_Vector,keyboard_layout)) { + if( mac_append_underlying_ToVector(All_Vector, keyboard_layout)) { wprintf(L"ERROR: can't append underlying ToVector \n"); return 2; } @@ -49,25 +56,23 @@ int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLa int mac_write_US_ToVector( v_dw_3D &vec) { - v_dw_1D Values; - v_dw_2D Key; - - // _S2 unlike mcompile-linux we do not run a function to get the characters of the US keyboard but fix them like that: - // A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P, CR, L, J, ', K, ;, \, ,, /, N, M, . - std::vector US_Base = {97, 115, 100, 102, 104, 103, 122, 120, 99, 118, 167, 98, 113, 119, 101, 114, 121, 116, 49, 50, 51, 52, 54, 53, 61, 57, 55, 45, 56, 48, 93, 111, 117, 91, 105, 112, 13, 108, 106, 39, 107, 59, 92, 44, 47, 110, 109, 46}; - std::vector US_Shift = {65, 83, 68, 70, 72, 71, 90, 88, 67, 86, 177, 66, 81, 87, 69, 82, 89, 84, 33, 64, 35, 36, 94, 37, 43, 40, 38, 95, 42, 41, 125, 79, 85, 123, 73, 80, 13, 76, 74, 34, 75, 58, 124, 60, 63, 78, 77, 62}; - //std::vector US_Caps= {65, 83, 68, 70, 72, 71, 90, 88, 67, 86, 66, 81, 87, 69, 82, 89, 84, 49, 50, 51, 52, 54, 53, 61, 57, 55, 45, 56, 48, 93, 79, 85, 91, 73, 80, 76, 74, 39, 75, 59, 92, 44, 47, 78, 77, 46}; - - for ( int i=0; i< US_Base.size(); i++) { - Values.push_back( i ); - Values.push_back( US_Base[i]); - Values.push_back( US_Shift[i]); - Key.push_back(Values); - Values.clear(); + // Values for All_Vector: A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P,CR, L, J, ', K, ;, \, ,, /, N, M, . + std::vector us_Base = {97,115,100,102,104,103,122,120,99,118,167,98,113,119,101,114,121,116,49,50,51,52,54,53,61,57,55,45,56,48, 93,111,117, 91,105,112,13,108,106,39,107,59, 92,44,47,110,109,46}; + std::vector us_Shift = {65, 83, 68, 70, 72, 71, 90, 88,67, 86,177,66, 81, 87, 69, 82, 89, 84,33,64,35,36,94,37,43,40,38,95,42,41,125, 79, 85,123, 73, 80,13, 76, 74,34, 75,58,124,60,63, 78, 77,62}; + + v_dw_1D values; + v_dw_2D key; + + for ( int i=0; i< us_Base.size(); i++) { + values.push_back(i); + values.push_back(us_Base[i]); + values.push_back(us_Shift[i]); + key.push_back(values); + values.clear(); } - vec.push_back(Key); + vec.push_back(key); - if ( Key.size() == 0) { + if ( key.size() == 0) { wprintf(L"ERROR: can't Create Vector for US keyboard\n"); return 1; } @@ -75,25 +80,25 @@ int mac_write_US_ToVector( v_dw_3D &vec) { return 0; } -v_dw_2D mac_create_empty_2D_Vector( int dim_rows,int dim_ss) { +v_dw_2D mac_create_empty_2D_Vector( int dim_rows, int dim_ss) { - v_dw_1D shifts; - v_dw_2D Vector_2D; + v_dw_1D shift; + v_dw_2D vector_2D; for ( int i=0; i< dim_rows;i++) { for ( int j=0; j< dim_ss;j++) { - shifts.push_back(returnIfCharInvalid); + shift.push_back(returnIfCharInvalid); } - Vector_2D.push_back(shifts); - shifts.clear(); + vector_2D.push_back(shift); + shift.clear(); } - return Vector_2D; + return vector_2D; } int mac_append_underlying_ToVector(v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { // create a 2D vector all filled with " " and push to 3D-Vector - v_dw_2D underlying_Vector2D = mac_create_empty_2D_Vector(All_Vector[0].size(),All_Vector[0][0].size()); + v_dw_2D underlying_Vector2D = mac_create_empty_2D_Vector(All_Vector[0].size(), All_Vector[0][0].size()); if (underlying_Vector2D.size() == 0) { wprintf(L"ERROR: can't create empty 2D-Vector\n"); @@ -106,14 +111,13 @@ int mac_append_underlying_ToVector(v_dw_3D &All_Vector, const UCKeyboardLayout * return 1; } - for(int i =0; i< (int) All_Vector[1].size();i++) { + for(int i =0; i< All_Vector[1].size();i++) { // get key name US stored in [0][i][0] and copy to name in "underlying"-block[1][i][0] All_Vector[1][i][0] = All_Vector[0][i][0]; - // get Keyvals of this key and copy to unshifted/shifted in "underlying"-block[1][i][1] / block[1][i][2] - All_Vector[1][i][0+1] = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout,All_Vector[0][i][0],0); //shift state: unshifted:0 - All_Vector[1][i][1+1] = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout,All_Vector[0][i][0],1); //shift state: shifted:1 + All_Vector[1][i][0+1] = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, All_Vector[0][i][0], mac_map_Win_ShiftState_to_MacModifier(0)); //shift state: unshifted:0 + All_Vector[1][i][1+1] = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, All_Vector[0][i][0], mac_map_Win_ShiftState_to_MacModifier(1)); //shift state: shifted:1 } return 0; @@ -140,498 +144,209 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ -// _S2 TODO all -/*bool mac_IsKeymanUsedChar(int KV) { - // 32 A-Z a-z - if ((KV == 0x20 ) || (KV >= 65 && KV <= 90) || (KV >= 97 && KV <= 122) ) - return true; - else - return false; -}*/ - -// _S2 TODO all -std::u16string mac_convert_DeadkeyValues_To_U16str(int in) { -// _S2 not finished yet - needs deadkeys... -/* - if (in == 0 ) - return u"\0"; +// _S2 checked OK +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps) { - std::string long_name((const char*) gdk_keyval_name (in)); // e.g. "dead_circumflex" , "U+017F" , "t" - - if ( long_name.substr (0,2) == "U+" ) // U+... Unicode value - return mac_CodePointToU16String(in-0x1000000); - - if (in < (int) deadkey_min) { // no deadkey; no Unicode - return std::u16string(1, in); - } - - KMX_DWORD lname = mac_convertNamesTo_DWORD_Value(long_name); // 65106 => "dead_circumflex" => 94 => "^" - - if (lname != returnIfCharInvalid) { - return std::u16string(1, lname ); - } - else - return u"\0";*/ - - return std::u16string(1, in ); -} - -// _S2 TODO dk/non-dk -// _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk? -int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { - // _S2 not finished yet - needs deadkeys... - KMX_DWORD in_array[2] = {0,0}; - UInt32 deadkeystate = 0; + UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; + OptionBits keyTranslateOptions = 0; UniChar unicodeString[maxStringlength]; - OSStatus status; + OSStatus status ; + unicodeString[0] = 0; - // _S2 bette solution for 4*CAPS ???? - status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - // If this was a deadkey, append a space - if(deadkeystate !=0) - status = UCKeyTranslate(keyboard_layout, Keycode_Spacebar ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if (!keyboard_layout) + return 0; - // UCKeyTranslate writes 0x01 into unicodeString[0] if there is no character assigned to the Key+Shift+CAPS - // ( then returnes 0 -> 0 is then propagated to ... mac_KMX_ToUnicodeEx (-> rc=0) .. ImportRules (rc=0-> do nothing ) ) + if (!(keycode <= keycode_max)) + return 0; - // _S2 no deadkeys yet or check last bit - if( shiftstate %2 == 1) - return 0; // _S2 what to return if deadkeys are used?? + if (!(shiftstate_mac <= max_shiftstate)) + return 0; - else { - if( (int) unicodeString[0] == 1 ) // impossible character - return 0; - else { - return (int) unicodeString[0]; // even: combine char -> è - } - } - return 0; -} -// _S2 TODO dk/non-dk -// _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk? -int mac_KMX_get_KeyVal_From_KeyCode_S2(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { - // _S2 not finished yet - needs deadkeys... - KMX_DWORD in_array[2] = {0,0}; - UInt32 deadkeystate = 0; - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - OSStatus status; - //int Keycode_Spacebar =49; + if (!(caps <= 1)) + return 0; - // _S2 bette solution for 4*CAPS ???? - status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - // If this was a deadkey, append a space + status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // If this was a deadkey,append a space if(deadkeystate !=0) - status = UCKeyTranslate(keyboard_layout, Keycode_Spacebar ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - - // UCKeyTranslate writes 0x01 into unicodeString[0] if there is no character assigned to the Key+Shift+CAPS - // ( then returnes 0 -> 0 is then propagated to ... mac_KMX_ToUnicodeEx (-> rc=0) .. ImportRules (rc=0-> do nothing ) ) - - // _S2 no deadkeys yet or check last bit - if( shiftstate %2 == 1) - return 0; // _S2 what to return if deadkeys are used?? + status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown, (shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // if there is no character assigned to the Key+Shift+CAPS UCKeyTranslate writes 0x01 into unicodeString[0] + if( unicodeString[0] == 1 ) // impossible character + return 0; else { - if( (int) unicodeString[0] == 1 ) // impossible character - return 0; - else { - return (int) unicodeString[0]; // even: combine char -> è - } + return unicodeString[0]; // combined char e.g. â } + return 0; } - -int mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps, UInt32 &deadkeystate) { +//--------------------------------------------------- +// _S2 checked OK +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32 &deadkeystate) { UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; + OptionBits keyTranslateOptions = 0; UniChar unicodeString[maxStringlength]; - //int Keycode_Spacebar =49; + unicodeString[0] = 0; OSStatus status; - // _S2 bette solution for 4*CAPS ???? - status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if (!keyboard_layout) + return 0; - // If this was a deadkey, append a space - if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, Keycode_Spacebar ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - } + if (!(keycode <= keycode_max)) + return 0; - if( keycode==0x999) - return L'\0'; - return (int) unicodeString[0]; -} + if (!(shiftstate_mac <= max_shiftstate)) + return 0; -// _S2 TODO dk/non-dk -int mac_KMX_get_KeyVal_underlying_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps) { - // _S2 not finished yet - needs deadkeys... - KMX_DWORD in_array[2] = {0,0}; - UInt32 deadkeystate = 0; - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - OSStatus status; - int returnint=0; + if (!(caps <= 1)) + return 0; - status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + // if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 + status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown,(shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - // no deadkey yet - if( shiftstate %2 == 1) - return 0; // _S2 what to return if deadkeys are used?? - else { - in_array[0] = (int) unicodeString[0]; // even: combine char -> è - returnint = in_array[0]; - return returnint; - } + // If this was a deadkey,append a space + if(deadkeystate !=0) + status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown,(shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - return returnint; + // if there is no character assigned to the Key+Shift+CAPS UCKeyTranslate writes 0x01 into unicodeString[0] + if(unicodeString[0] == 1 ) // impossible character + return 0; + else + return unicodeString[0]; // combined char e.g. â } -// _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk? -/*int mac_KMX_get_KeyVal_From_KeyCode(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps) { - - GdkModifierType consumed; - GdkKeymapKey *maps; - guint *keyvals; - gint count; +//--------------------------------------------------- +// _S2 checked OK +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int kc_underlying, int shiftstate_mac) { + KMX_DWORD kVal; + int caps=0; - if (!gdk_keymap_get_entries_for_keycode(keymap, keycode, &maps, &keyvals, &count)) + if (!keyboard_layout) return 0; - //BASE (shiftstate: 0) - if (( ss == Base ) && ( caps == 0 )) { - GdkModifierType MOD_base = (GdkModifierType) ( ~GDK_MODIFIER_MASK ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_base , 0, keyvals, NULL, NULL, & consumed); - } - - //BASE + CAPS (shiftstate: 0) - else if (( ss == Base ) && ( caps == 1 )) { - GdkModifierType MOD_Caps = (GdkModifierType) ( GDK_LOCK_MASK ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_Caps, 0, keyvals, NULL, NULL, & consumed); - } - - //SHIFT (shiftstate: 1) - else if (( ss == Shft ) && ( caps == 0 )) { - GdkModifierType MOD_Shift = (GdkModifierType) ( GDK_SHIFT_MASK ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_Shift , 0, keyvals, NULL, NULL, & consumed); - } - - //SHIFT + CAPS (shiftstate: 1) - else if ( ( ss == Shft ) && ( caps ==1 )) { - GdkModifierType MOD_ShiftCaps= (GdkModifierType) ((GDK_SHIFT_MASK | GDK_LOCK_MASK)); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_ShiftCaps , 0, keyvals, NULL, NULL, & consumed); - } - - // Ctrl (shiftstate: 2) - else if (( ss == Ctrl ) && ( caps == 0 )){ - GdkModifierType MOD_Ctrl = (GdkModifierType) ( GDK_MOD5_MASK ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_Ctrl , 0, keyvals, NULL, NULL, & consumed); - } - - // Ctrl + CAPS (shiftstate: 2) - else if (( ss == Ctrl ) && ( caps == 1 )){ - GdkModifierType MOD_CtrlCaps = (GdkModifierType) (GDK_MOD5_MASK | GDK_LOCK_MASK); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_CtrlCaps , 0, keyvals, NULL, NULL, & consumed); - } - - // SHIFT+Ctrl (shiftstate: 3) - else if (( ss == ShftCtrl ) && ( caps == 0 )){ - GdkModifierType MOD_Ctrl = (GdkModifierType) (GDK_SHIFT_MASK | GDK_MOD5_MASK ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_Ctrl , 0, keyvals, NULL, NULL, & consumed); - } - - // SHIFT+Ctrl + CAPS (shiftstate: 3) - else if (( ss == ShftCtrl ) && ( caps == 1 )){ - GdkModifierType MOD_CtrlCaps = (GdkModifierType) ( GDK_SHIFT_MASK | GDK_MOD5_MASK | GDK_LOCK_MASK); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_CtrlCaps , 0, keyvals, NULL, NULL, & consumed); - } - - //ALT-GR (shiftstate: 6) - else if (( ss == MenuCtrl ) && ( caps == 0 )){ - GdkModifierType MOD_AltGr = (GdkModifierType) (GDK_MOD2_MASK | GDK_MOD5_MASK); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_AltGr , 0, keyvals, NULL, NULL, & consumed); - } - - //ALT-GR + CAPS (shiftstate: 6) - else if (( ss == MenuCtrl ) && ( caps == 1 )){ - GdkModifierType MOD_AltGr = (GdkModifierType) (GDK_MOD2_MASK | GDK_MOD5_MASK | GDK_LOCK_MASK); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_AltGr , 0, keyvals, NULL, NULL, & consumed); - } - - //ALT-GR (shiftstate: 7) - else if (( ss == ShftMenuCtrl ) && ( caps == 0 )){ - GdkModifierType MOD_AltGr = (GdkModifierType) ( (GDK_SHIFT_MASK | GDK_MOD2_MASK | GDK_MOD5_MASK) ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_AltGr , 0, keyvals, NULL, NULL, & consumed); - } - - //ALT-GR +CAPS (shiftstate: 7) - else if (( ss == ShftMenuCtrl ) && ( caps == 1 )){ - GdkModifierType MOD_AltGr = (GdkModifierType) ( (GDK_SHIFT_MASK | GDK_MOD2_MASK | GDK_MOD5_MASK | GDK_LOCK_MASK) ); - gdk_keymap_translate_keyboard_state (keymap, keycode, MOD_AltGr , 0, keyvals, NULL, NULL, & consumed); - } - else + if (!(kc_underlying <= keycode_max)) return 0; - return (int) *keyvals; -}*/ - -// _S2 TODO dk -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int keycode, int shift_state_pos) { - - //KMX_DWORD KVal = mac_get_keyval_From_Keycode(keycode, shift_state_pos*2 , keyboard_layout ); - - KMX_DWORD KVal= mac_get_keyval_From_Keycode_new(keycode,keyboard_layout , shift_state_pos*2); - - int count = max_shiftstate; - if (!(shift_state_pos <= count*2)) + if (!(shiftstate_mac <= max_shiftstate)) return 0; - if (!(keycode <= keycode_max)) - return 0; + kVal = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_underlying, mac_map_Win_ShiftState_to_MacModifier(shiftstate_mac), caps); - return KVal; + return kVal; } +//--------------------------------------------------- +// _S2 checked OK +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey) { -// _S2 TODO VKShiftstate -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey) { - - PKMX_WCHAR dky=NULL; - UInt32 isdk=0; + PKMX_WCHAR dky = NULL; + UInt32 isdk = 0; + KMX_DWORD keyV; + int caps = 0; if (!keyboard_layout) return 0; -/*// _S2 needed? - int count; - if (!(mac_map_VKShiftState_to_MacModifier(VKShiftState) <= count)) - return 0; + if(!(is_correct_win_shiftstate(vk_ShiftState))) + return 0; - if (!(KC_underlying <= keycode_max)) + if (!(kc_underlying <= keycode_max)) return 0; - */ - KMX_DWORD KeyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, KC_underlying, (mac_map_VKShiftState_to_MacModifier(VKShiftState)), 0, isdk); + keyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, kc_underlying,(mac_map_VKShiftState_to_MacModifier(vk_ShiftState)), caps, isdk); - // if there was a dk return 0xFFFF and copy dk into dky + // if there was a deadkey return 0xFFFF and copy deadkey into dky if( isdk !=0) { - dky = (PKMX_WCHAR) (mac_convert_DeadkeyValues_To_U16str((int) KeyV)).c_str(); - *DeadKey = *dky; + dky = (PKMX_WCHAR) (std::u16string(1, keyV)).c_str(); + *deadKey = *dky; return 0xFFFF; } - *DeadKey= 0; - return KeyV; + *deadKey = 0; + return keyV; } - -// _S2 TODO dk -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD Keyval_US) { - KMX_DWORD VK_underlying; - for( int i=0; i< (int)All_Vector[0].size()-1 ;i++) { - for( int j=1; j< (int)All_Vector[0][0].size();j++) { - if ( All_Vector[0][i][j] == Keyval_US ) { - VK_underlying = All_Vector[1][i][j]; - return VK_underlying; - } +//--------------------------------------------------- +// _S2 checked OK +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD kv_us) { + + for( int i=0; i< All_Vector[0].size()-1 ;i++) { + for( int j=1; j< All_Vector[0][0].size();j++) { + if ( All_Vector[0][i][j] == kv_us ) + return All_Vector[1][i][j]; } } - return Keyval_US; + return kv_us; } +// _S2 checked OK +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vector, KMX_DWORD kv_underlying) { -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vector, KMX_DWORD KV_Underlying) { - for( int i=0; i< (int)All_Vector[1].size()-1 ;i++) { - for( int j=1; j< (int)All_Vector[1][0].size();j++) { - if ( All_Vector[1][i][j] == KV_Underlying ) { + for( int i=0; i< All_Vector[1].size()-1 ;i++) { + for( int j=1; j< All_Vector[1][0].size();j++) { + if ( All_Vector[1][i][j] == kv_underlying ) { return All_Vector[1][i][0]; } } } - return KV_Underlying; + return kv_underlying; } +// _S2 checked OK +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_DWORD kc_us, ShiftState ss, int caps) { -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_DWORD KC_US, ShiftState ss, int caps) { - KMX_DWORD KC_underlying; - // _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk? - std::u16string u16str = mac_convert_DeadkeyValues_To_U16str(mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, KC_US, ss, caps)); + std::u16string u16str_map= std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_map_Win_ShiftState_to_MacModifier(ss), caps) ); - for( int i=0; i< (int)All_Vector[1].size()-1 ;i++) { - for( int j=1; j< (int)All_Vector[1][0].size();j++) { - if ( ((KMX_DWORD) All_Vector[1][i][j] == (KMX_DWORD) *u16str.c_str() ) ) { - KC_underlying = All_Vector[1][i][0]; - return KC_underlying; - } + for( int i=0; i< All_Vector[1].size()-1 ;i++) { + for( int j=1; j< All_Vector[1][0].size();j++) { + if ( ((KMX_DWORD) All_Vector[1][i][j] == (KMX_DWORD) *u16str_map.c_str() ) ) + return All_Vector[1][i][0]; } } - return KC_US; + return kc_us; } - -UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS) { - uint ret= (mac_USVirtualKeyToScanCode[VirtualKeyUS]); // _S2 can go later - return (mac_USVirtualKeyToScanCode[VirtualKeyUS]); +// _S2 checked OK +UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us) { + return (mac_USVirtualKeyToScanCode[vk_us]); } - -// _S2 OK?? +// _S2 checked OK KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { - /*if ( keycode >7) - return (KMX_DWORD) ScanCodeToUSVirtualKey[keycode-8]; - - return 0;*/ - - return (KMX_DWORD) mac_ScanCodeToUSVirtualKey[keycode]; - return 0; + return mac_ScanCodeToUSVirtualKey[keycode]; } -/*std::u16string mac_CodePointToU16String(unsigned int codepoint) { - std::u16string str; - - if constexpr (sizeof(wchar_t) > 2) { - str = static_cast(codepoint); - } - else if (codepoint <= 0xFFFF) { - str = static_cast(codepoint); - } - else { - codepoint -= 0x10000; - str.resize(2); - str[0] = static_cast(0xD800 + ((codepoint >> 10) & 0x3FF)); - str[1] = static_cast(0xDC00 + (codepoint & 0x3FF)); - } - - return str; -}*/ - - //################################################################################################################################################ //################################################################################################################################################ +// _S2 checked_OK +KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps) { - -std::u16string mac_get_character_From_Keycode(int dk, int ch , int shiftstate) { - - std::u16string character; - std::vector keyvals; - keyvals.push_back(dk); - keyvals.push_back(ch); - - TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); - CFDataRef layout_data = static_cast((TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData))); - const UCKeyboardLayout* keyboard_layout = reinterpret_cast(CFDataGetBytePtr(layout_data)); - - if (layout_data) - character = mac_get_character_From_Keycode(keyvals, shiftstate, keyboard_layout); - - return character; -} - -std::u16string mac_get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { - char16_t ch_array[3] = {L'\0'}; - UInt32 deadkeystate = 0; - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - OSStatus status; - - for ( int i =0; i < keyval.size(); i++) { - - status = UCKeyTranslate(keyboard_layout, keyval[i] ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - if( shiftstate %2 == 1 ) // uneven: seperate char -> `e - ch_array[i] = (char16_t) unicodeString[0]; - else - ch_array[0] = (char16_t) unicodeString[0]; // even: combine char -> è - } - - std::u16string returnString(ch_array); - return returnString; -} - -KMX_DWORD mac_get_keyval_From_Keycode_new(int VK_dk,const UCKeyboardLayout* keyboard_layout , KMX_DWORD shiftstate) { - - UInt32 deadkeystate = 0; - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - OSStatus status; - - status = UCKeyTranslate(keyboard_layout, VK_dk ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - - // If this was a deadkey, append a space - if(deadkeystate !=0) - - status = UCKeyTranslate(keyboard_layout, 49 ,kUCKeyActionDown, 0, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - - return unicodeString[0]; -} - -KMX_DWORD mac_get_CombinedChar_From_DK(int VK_dk,KMX_DWORD ss_dk,const UCKeyboardLayout* keyboard_layout, KMX_DWORD VK_US, KMX_DWORD shiftstate, int caps) { - - UInt32 deadkeystate = 0; + UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; + OptionBits keyTranslateOptions = 0; UniChar unicodeString[maxStringlength]; + unicodeString[0] = 0; OSStatus status; - status = UCKeyTranslate(keyboard_layout, VK_dk ,kUCKeyActionDown, ss_dk, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + status = UCKeyTranslate(keyboard_layout, vk_dk, kUCKeyActionDown, ss_dk, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - // If this was a deadkey, append a space + // If this was a deadkey,append a character if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, (UInt16) VK_US ,kUCKeyActionDown, shiftstate+4*caps, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - return unicodeString[0]; + status = UCKeyTranslate(keyboard_layout,(UInt16) vk_us, kUCKeyActionDown, shiftstate_mac+4*caps, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + + if(unicodeString[0] == 1 ) // impossible character + return 0; + else + return unicodeString[0]; // combined char e.g. â } else - return 0; -} - -/* KMX_DWORD mac_get_keyval_From_Keycode(int keyval, int shiftstate, const UCKeyboardLayout* keyboard_layout ) { - - UInt32 deadkeystate = 0; - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - OSStatus status; - int treat_dk_as_Character = 1; // e.g. ^ = 94 - - //status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftstate+ 4*caps), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - - status = UCKeyTranslate(keyboard_layout, keyval ,kUCKeyActionDown, shiftstate, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - //status = UCKeyTranslate(keyboard_layout, keyval ,kUCKeyActionDown, shiftstate , LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - return unicodeString[0]; -} -*/ - -/*KMX_DWORD mac_get_keyval_From_Keycode_old(int keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout ) { - - KMX_DWORD in_array[2] = {0,0}; - UInt32 deadkeystate = 0; - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - OSStatus status; - int treat_dk_as_Character = 1; // e.g. ^ = 94 - int returnint=0; - - status = UCKeyTranslate(keyboard_layout, keyval ,kUCKeyActionDown, shiftstate + treat_dk_as_Character, LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - // no deadkey yet - if( shiftstate %2 == 1) - return 0; // _S2 what to return if deadkeys are used?? - else { - in_array[0] = (int) unicodeString[0]; // even: combine char -> è - returnint = in_array[0]; - return returnint; - } - -return returnint; + return 0; } -*/ -void printoutKeyboards(v_dw_3D &All_Vector) { +void test_printoutKeyboards_S2(v_dw_3D &All_Vector) { printf(" values of US - Values of underlying"); for ( int i=0; i< All_Vector[0].size(); i++) { printf("-----------------------------\n"); for ( int j=0; j< All_Vector[0][0].size(); j++) { - printf("i:%i\tUS: %i(%c)\t Underlying: %i(%c)\t \t\t\t%c \n" , i, All_Vector[0][i][j] , All_Vector[0][i][j] , All_Vector[1][i][j], All_Vector[1][i][j], (All_Vector[0][i][j] == All_Vector[1][i][j]) ? '.' : '*'); + printf("i:%i\tUS: %i(%c)\t Underlying: %i(%c)\t \t\t\t%c \n", i,All_Vector[0][i][j] , All_Vector[0][i][j] , All_Vector[1][i][j],All_Vector[1][i][j],(All_Vector[0][i][j] == All_Vector[1][i][j]) ? '.' : '*'); } } } - - diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 6295d4ec29e..e9ca11ca0d7 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -3,40 +3,15 @@ #ifndef KEYMAP_H #define KEYMAP_H -// compile with. gcc -framework Carbon -o Bla.exe HW.cpp +// compile with. gcc -framework Carbon -o xxx.exe yy.cpp // #import #include #include #include #include - #include "u16.h" -std::u16string mac_get_character_From_Keycode(std::vector keyval, int shiftstate,const UCKeyboardLayout* keyboard_layout); - -KMX_DWORD mac_get_keyval_From_Keycode_new(int charVal,const UCKeyboardLayout* keyboard_layout , KMX_DWORD shiftstate); -KMX_DWORD mac_get_CombinedChar_From_DK(int charVal,KMX_DWORD ss_dk,const UCKeyboardLayout* keyboard_layout, KMX_DWORD VK_US, KMX_DWORD shiftstate, int caps); -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - -// In ths program we use a 3D-Vector Vector[language][Keys][Shiftstates] -/* - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -*/ - enum ShiftState { Base = 0, // 0 Shft = 1, // 1 @@ -50,6 +25,9 @@ enum ShiftState { ShftXxxx = Shft | Xxxx, // 9 }; +// the shiftstates we can use for mac: Base;Shift, OPTION, Shift+OPTION +static int ss_mac[]={0,2,8,10}; + // Map of all US English virtual key codes that we can translate const KMX_DWORD KMX_VKMap[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', @@ -57,7 +35,7 @@ const KMX_DWORD KMX_VKMap[] = { VK_SPACE, // 32 // - VK_ACCENT, // 192 VK_OEM_3 K_BKQUOTE // + VK_ACCENT, // 192 VK_OEM_3 K_BKQUOTE // VK_HYPHEN, // - 189 VK_OEM_MINUS // VK_EQUAL, // = 187 VK_OEM_PLUS // @@ -78,30 +56,31 @@ const KMX_DWORD KMX_VKMap[] = { }; typedef std::vector v_str_1D; - typedef std::vector v_dw_1D; typedef std::vector > v_dw_2D; typedef std::vector > > v_dw_3D; - static KMX_DWORD returnIfCharInvalid = 0; -static KMX_DWORD max_shiftstate = 2; // _S2 only base+Shift -static KMX_DWORD keycode_max = 94; // _S2 needed?? -//static KMX_DWORD deadkey_min = 0xfe50; // _S2 needed?? -//static KMX_DWORD deadkey_max = 0xfe93; // _S2 needed?? -static int Keycode_Spacebar =49; -//static KMX_DWORD deadkey_max = 0xfe52; // _S2 TOP_6 TODO This has to go! my test: to only return 3 dk +static KMX_DWORD max_shiftstate = 10; +static KMX_DWORD keycode_max = 50; +static int keycode_spacebar = 49; -// map VKShiftstate to modifier (use 0,2,4,8,10 instead of 0,16,9,25 ) -int mac_map_VKShiftState_to_MacModifier(int VKShiftState); +// map vk_ShiftState to modifier (use 0,2,4,8,10 instead of 0,16,9,25 ) +int mac_map_VKShiftState_to_MacModifier(int vk_ShiftState); -// map ShiftState to modifier (use 0,2,4,8,10 instead of Base, Shft, Opt, Sh+Opt ) -int mac_map_ShiftState_to_MacModifier(int ShiftState); +// map win_ShiftState to modifier (use 0,2,4,8,10 instead of Base, Shft, Opt, Sh+Opt ) +int mac_map_Win_ShiftState_to_MacModifier(int win_ShiftState); + +// make sure a correct shiftstate was passed +//bool is_correct_mac_shiftstate(int comp_ss); +//bool is_correct_rgkey_shiftstate(int comp_ss); +bool is_correct_win_shiftstate(int comp_ss); // create a Vector with all entries of both keymaps int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLayout * keykeyboard_layout); // read configuration file, split and write to 3D-Vector (Data for US on Vector[0][ ][ ] ) int mac_write_US_ToVector(v_dw_3D &vec); + // create an empty 2D vector containing 0 in all fields v_dw_2D mac_create_empty_2D_Vector(int dim_rows, int dim_shifts); @@ -111,846 +90,450 @@ int mac_append_underlying_ToVector(v_dw_3D &All_Vector, const UCKeyboardLayout * // initialize UCHR bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout); //------------------------------ -/* -const UINT USVirtualKeyToScanCode[256] = { - 0x00, // L"K_?00", // &H0 - 0x00, // L"K_LBUTTON", // &H1 - 0x00, // L"K_RBUTTON", // &H2 - 0x46, // L"K_CANCEL", // &H3 - 0x00, // L"K_MBUTTON", // &H4 - 0x00, // L"K_?05", // &H5 - 0x00, // L"K_?06", // &H6 - 0x00, // L"K_?07", // &H7 - 0x0E, // L"K_BKSP", // &H8 - 0x0F, // L"K_TAB", // &H9 - 0x00, // L"K_?0A", // &HA - 0x00, // L"K_?0B", // &HB - 0x4C, // L"K_KP5", // &HC - 0x1C, // L"K_ENTER", // &HD - 0x00, // L"K_?0E", // &HE - 0x00, // L"K_?0F", // &HF - 0x2A, // L"K_SHIFT", // &H10 - 0x1D, // L"K_CONTRO0x00, // L", // &H11 - 0x38, // L"K_ALT", // &H12 - 0x00, // L"K_PAUSE", // &H13 - 0x3A, // L"K_CAPS", // &H14 - 0x00, // L"K_KANJI?15", // &H15 - 0x00, // L"K_KANJI?16", // &H16 - 0x00, // L"K_KANJI?17", // &H17 - 0x00, // L"K_KANJI?18", // &H18 - 0x00, // L"K_KANJI?19", // &H19 - 0x00, // L"K_?1A", // &H1A - 0x01, // L"K_ESC", // &H1B - 0x00, // L"K_KANJI?1C", // &H1C - 0x00, // L"K_KANJI?1D", // &H1D - 0x00, // L"K_KANJI?1E", // &H1E - 0x00, // L"K_KANJI?1F", // &H1F - 0x39, // L"K_SPACE", // &H20 - 0x49, // L"K_PGUP", // &H21 - 0x51, // L"K_PGDN", // &H22 - 0x4F, // L"K_END", // &H23 - 0x47, // L"K_HOME", // &H24 - 0x4B, // L"K_LEFT", // &H25 - 0x48, // L"K_UP", // &H26 - 0x4D, // L"K_RIGHT", // &H27 - 0x50, // L"K_DOWN", // &H28 - 0x00, // L"K_SEL", // &H29 - 0x00, // L"K_PRINT", // &H2A - 0x00, // L"K_EXEC", // &H2B - 0x54, // L"K_PRTSCN", // &H2C - 0x52, // L"K_INS", // &H2D - 0x53, // L"K_DEL", // &H2E - 0x63, // L"K_HELP", // &H2F - 0x0B, // L"K_0", // &H30 - 0x02, // L"K_1", // &H31 - 0x03, // L"K_2", // &H32 - 0x04, // L"K_3", // &H33 - 0x05, // L"K_4", // &H34 - 0x06, // L"K_5", // &H35 - 0x07, // L"K_6", // &H36 - 0x08, // L"K_7", // &H37 - 0x09, // L"K_8", // &H38 - 0x0A, // L"K_9", // &H39 - 0x00, // L"K_?3A", // &H3A - 0x00, // L"K_?3B", // &H3B - 0x00, // L"K_?3C", // &H3C - 0x00, // L"K_?3D", // &H3D - 0x00, // L"K_?3E", // &H3E - 0x00, // L"K_?3F", // &H3F - 0x00, // L"K_?40", // &H40 - 0x1E, // L"K_A", // &H41 - 0x30, // L"K_B", // &H42 - 0x2E, // L"K_C", // &H43 - 0x20, // L"K_D", // &H44 - 0x12, // L"K_E", // &H45 - 0x21, // L"K_F", // &H46 - 0x22, // L"K_G", // &H47 - 0x23, // L"K_H", // &H48 - 0x17, // L"K_I", // &H49 - 0x24, // L"K_J", // &H4A - 0x25, // L"K_K", // &H4B - 0x26, // L"K_L", // &H4C - 0x32, // L"K_M", // &H4D - 0x31, // L"K_N", // &H4E - 0x18, // L"K_O", // &H4F - 0x19, // L"K_P", // &H50 - 0x10, // L"K_Q", // &H51 - 0x13, // L"K_R", // &H52 - 0x1F, // L"K_S", // &H53 - 0x14, // L"K_T", // &H54 - 0x16, // L"K_U", // &H55 - 0x2F, // L"K_V", // &H56 - 0x11, // L"K_W", // &H57 - 0x2D, // L"K_X", // &H58 - 0x15, // L"K_Y", // &H59 - 0x2C, // L"K_Z", // &H5A - 0x5B, // L"K_?5B", // &H5B - 0x5C, // L"K_?5C", // &H5C - 0x5D, // L"K_?5D", // &H5D - 0x00, // L"K_?5E", // &H5E - 0x5F, // L"K_?5F", // &H5F - 0x52, // L"K_NP0", // &H60 - 0x4F, // L"K_NP1", // &H61 - 0x50, // L"K_NP2", // &H62 - 0x51, // L"K_NP3", // &H63 - 0x4B, // L"K_NP4", // &H64 - 0x4C, // L"K_NP5", // &H65 - 0x4D, // L"K_NP6", // &H66 - 0x47, // L"K_NP7", // &H67 - 0x48, // L"K_NP8", // &H68 - 0x49, // L"K_NP9", // &H69 - 0x37, // L"K_NPSTAR", // &H6A - 0x4E, // L"K_NPPLUS", // &H6B - 0x7E, // L"K_SEPARATOR", // &H6C // MCD 01-11-02: Brazilian Fix, 00 -> 7E - 0x4A, // L"K_NPMINUS", // &H6D - 0x53, // L"K_NPDOT", // &H6E - 0x135, // L"K_NPSLASH", // &H6F - 0x3B, // L"K_F1", // &H70 - 0x3C, // L"K_F2", // &H71 - 0x3D, // L"K_F3", // &H72 - 0x3E, // L"K_F4", // &H73 - 0x3F, // L"K_F5", // &H74 - 0x40, // L"K_F6", // &H75 - 0x41, // L"K_F7", // &H76 - 0x42, // L"K_F8", // &H77 - 0x43, // L"K_F9", // &H78 - 0x44, // L"K_F10", // &H79 - 0x57, // L"K_F11", // &H7A - 0x58, // L"K_F12", // &H7B - 0x64, // L"K_F13", // &H7C - 0x65, // L"K_F14", // &H7D - 0x66, // L"K_F15", // &H7E - 0x67, // L"K_F16", // &H7F - 0x68, // L"K_F17", // &H80 - 0x69, // L"K_F18", // &H81 - 0x6A, // L"K_F19", // &H82 - 0x6B, // L"K_F20", // &H83 - 0x6C, // L"K_F21", // &H84 - 0x6D, // L"K_F22", // &H85 - 0x6E, // L"K_F23", // &H86 - 0x76, // L"K_F24", // &H87 - - 0x00, // L"K_?88", // &H88 - 0x00, // L"K_?89", // &H89 - 0x00, // L"K_?8A", // &H8A - 0x00, // L"K_?8B", // &H8B - 0x00, // L"K_?8C", // &H8C - 0x00, // L"K_?8D", // &H8D - 0x00, // L"K_?8E", // &H8E - 0x00, // L"K_?8F", // &H8F - - 0x45, // L"K_NUMLOCK", // &H90 - 0x46, // L"K_SCROL0x00, // &H91 - - 0x00, // L"K_?92", // &H92 - 0x00, // L"K_?93", // &H93 - 0x00, // L"K_?94", // &H94 - 0x00, // L"K_?95", // &H95 - 0x00, // L"K_?96", // &H96 - 0x00, // L"K_?97", // &H97 - 0x00, // L"K_?98", // &H98 - 0x00, // L"K_?99", // &H99 - 0x00, // L"K_?9A", // &H9A - 0x00, // L"K_?9B", // &H9B - 0x00, // L"K_?9C", // &H9C - 0x00, // L"K_?9D", // &H9D - 0x00, // L"K_?9E", // &H9E - 0x00, // L"K_?9F", // &H9F - 0x2A, // L"K_?A0", // &HA0 - 0x36, // L"K_?A1", // &HA1 - 0x1D, // L"K_?A2", // &HA2 - 0x1D, // L"K_?A3", // &HA3 - 0x38, // L"K_?A4", // &HA4 - 0x38, // L"K_?A5", // &HA5 - 0x6A, // L"K_?A6", // &HA6 - 0x69, // L"K_?A7", // &HA7 - 0x67, // L"K_?A8", // &HA8 - 0x68, // L"K_?A9", // &HA9 - 0x65, // L"K_?AA", // &HAA - 0x66, // L"K_?AB", // &HAB - 0x32, // L"K_?AC", // &HAC - 0x20, // L"K_?AD", // &HAD - 0x2E, // L"K_?AE", // &HAE - 0x30, // L"K_?AF", // &HAF - 0x19, // L"K_?B0", // &HB0 - 0x10, // L"K_?B1", // &HB1 - 0x24, // L"K_?B2", // &HB2 - 0x22, // L"K_?B3", // &HB3 - 0x6C, // L"K_?B4", // &HB4 - 0x6D, // L"K_?B5", // &HB5 - 0x6B, // L"K_?B6", // &HB6 - 0x21, // L"K_?B7", // &HB7 - 0x00, // L"K_?B8", // &HB8 - 0x00, // L"K_?B9", // &HB9 - 0x27, // L"K_COLON", // &HBA - 0x0D, // L"K_EQUA0x00, // L", // &HBB - 0x33, // L"K_COMMA", // &HBC - 0x0C, // L"K_HYPHEN", // &HBD - 0x34, // L"K_PERIOD", // &HBE - 0x35, // L"K_SLASH", // &HBF - 0x29, // L"K_BKQUOTE", // &HC0 - - 0x73, // L"K_?C1", // &HC1 - 0x7E, // L"K_?C2", // &HC2 - 0x00, // L"K_?C3", // &HC3 - 0x00, // L"K_?C4", // &HC4 - 0x00, // L"K_?C5", // &HC5 - 0x00, // L"K_?C6", // &HC6 - 0x00, // L"K_?C7", // &HC7 - 0x00, // L"K_?C8", // &HC8 - 0x00, // L"K_?C9", // &HC9 - 0x00, // L"K_?CA", // &HCA - 0x00, // L"K_?CB", // &HCB - 0x00, // L"K_?CC", // &HCC - 0x00, // L"K_?CD", // &HCD - 0x00, // L"K_?CE", // &HCE - 0x00, // L"K_?CF", // &HCF - 0x00, // L"K_?D0", // &HD0 - 0x00, // L"K_?D1", // &HD1 - 0x00, // L"K_?D2", // &HD2 - 0x00, // L"K_?D3", // &HD3 - 0x00, // L"K_?D4", // &HD4 - 0x00, // L"K_?D5", // &HD5 - 0x00, // L"K_?D6", // &HD6 - 0x00, // L"K_?D7", // &HD7 - 0x00, // L"K_?D8", // &HD8 - 0x00, // L"K_?D9", // &HD9 - 0x00, // L"K_?DA", // &HDA - 0x1A, // L"K_LBRKT", // &HDB - 0x2B, // L"K_BKSLASH", // &HDC - 0x1B, // L"K_RBRKT", // &HDD - 0x28, // L"K_QUOTE", // &HDE - 0x73, // L"K_oDF", // &HDF // MCD 01-11-02: Brazilian fix: 00 -> 73 - 0x00, // L"K_oE0", // &HE0 - 0x00, // L"K_oE1", // &HE1 - 0x56, // L"K_oE2", // &HE2 - 0x00, // L"K_oE3", // &HE3 - 0x00, // L"K_oE4", // &HE4 - - 0x00, // L"K_?E5", // &HE5 - - 0x00, // L"K_oE6", // &HE6 - - 0x00, // L"K_?E7", // &HE7 - 0x00, // L"K_?E8", // &HE8 - - 0x71, // L"K_oE9", // &HE9 - 0x5C, // L"K_oEA", // &HEA - 0x7B, // L"K_oEB", // &HEB - 0x00, // L"K_oEC", // &HEC - 0x6F, // L"K_oED", // &HED - 0x5A, // L"K_oEE", // &HEE - 0x00, // L"K_oEF", // &HEF - 0x00, // L"K_oF0", // &HF0 - 0x5B, // L"K_oF1", // &HF1 - 0x00, // L"K_oF2", // &HF2 - 0x5F, // L"K_oF3", // &HF3 - 0x00, // L"K_oF4", // &HF4 - 0x5E, // L"K_oF5", // &HF5 - - 0x00, // L"K_?F6", // &HF6 - 0x00, // L"K_?F7", // &HF7 - 0x00, // L"K_?F8", // &HF8 - 0x5D, // L"K_?F9", // &HF9 - 0x00, // L"K_?FA", // &HFA - 0x62, // L"K_?FB", // &HFB - 0x00, // L"K_?FC", // &HFC - 0x00, // L"K_?FD", // &HFD - 0x00, // L"K_?FE", // &HFE - 0x00 // L"K_?FF" // &HFF -}; -const UINT ScanCodeToUSVirtualKey[128] = { - 0x01, // 0x00 => K_LBUTTON - 0x1b, // 0x01 => K_ESC - 0x31, // 0x02 => K_1 - 0x32, // 0x03 => K_2 - 0x33, // 0x04 => K_3 - 0x34, // 0x05 => K_4 - 0x35, // 0x06 => K_5 - 0x36, // 0x07 => K_6 - 0x37, // 0x08 => K_7 - 0x38, // 0x09 => K_8 - 0x39, // 0x0a => K_9 - 0x30, // 0x0b => K_0 - 0xbd, // 0x0c => K_HYPHEN - 0xbb, // 0x0d => K_EQUAL - 0x08, // 0x0e => K_BKSP - 0x09, // 0x0f => K_TAB - 0x51, // 0x10 => K_Q - 0x57, // 0x11 => K_W - 0x45, // 0x12 => K_E - 0x52, // 0x13 => K_R - 0x54, // 0x14 => K_T 20 - 0x59, // 0x15 => K_Y - 0x55, // 0x16 => K_U - 0x49, // 0x17 => K_I - 0x4f, // 0x18 => K_O - 0x50, // 0x19 => K_P - 0xdb, // 0x1a => K_LBRKT - 0xdd, // 0x1b => K_RBRKT - 0x0d, // 0x1c => K_ENTER - 0x11, // 0x1d => K_CONTROL - 0x41, // 0x1e => K_A - 0x53, // 0x1f => K_S - 0x44, // 0x20 => K_D - 0x46, // 0x21 => K_F - 0x47, // 0x22 => K_G - 0x48, // 0x23 => K_H - 0x4a, // 0x24 => K_J - 0x4b, // 0x25 => K_K - 0x4c, // 0x26 => K_L - 0xba, // 0x27 => K_COLON 39 - 0xde, // 0x28 => K_QUOTE - 0xc0, // 0x29 => K_BKQUOTE - 0x10, // 0x2a => K_SHIFT - 0xdc, // 0x2b => K_BKSLASH - 0x5a, // 0x2c => K_Z - 0x58, // 0x2d => K_X - 0x43, // 0x2e => K_C - 0x56, // 0x2f => K_V - 0x42, // 0x30 => K_B - 0x4e, // 0x31 => K_N - 0x4d, // 0x32 => K_M - 0xbc, // 0x33 => K_COMMA - 0xbe, // 0x34 => K_PERIOD - 0xbf, // 0x35 => K_SLASH - 0xa1, // 0x36 => K_?A1 - 0x6a, // 0x37 => K_NPSTAR - 0x12, // 0x38 => K_ALT - 0x20, // 0x39 => K_SPACE - 0x14, // 0x3a => K_CAPS - 0x70, // 0x3b => K_F1 59 - 0x71, // 0x3c => K_F2 - 0x72, // 0x3d => K_F3 - 0x73, // 0x3e => K_F4 - 0x74, // 0x3f => K_F5 - 0x75, // 0x40 => K_F6 - 0x76, // 0x41 => K_F7 - 0x77, // 0x42 => K_F8 - 0x78, // 0x43 => K_F9 - 0x79, // 0x44 => K_F10 - 0x90, // 0x45 => K_NUMLOCK - 0x03, // 0x46 => K_CANCEL - 0x24, // 0x47 => K_HOME - 0x26, // 0x48 => K_UP - 0x21, // 0x49 => K_PGUP - 0x6d, // 0x4a => K_NPMINUS - 0x25, // 0x4b => K_LEFT - 0x0c, // 0x4c => K_KP5 - 0x27, // 0x4d => K_RIGHT - 0x6b, // 0x4e => K_NPPLUS - 0x23, // 0x4f => K_END - 0x28, // 0x50 => K_DOWN - 0x22, // 0x51 => K_PGDN - 0x2d, // 0x52 => K_INS - 0x2e, // 0x53 => K_DEL - 0x2c, // 0x54 => K_PRTSCN - 0x00, // 0x55 => No match - 0xe2, // 0x56 => K_oE2 - 0x7a, // 0x57 => K_F11 - 0x7b, // 0x58 => K_F12 - 0x00, // 0x59 => No match - 0xee, // 0x5a => K_oEE - 0x5b, // 0x5b => K_?5B - 0x5c, // 0x5c => K_?5C - 0x5d, // 0x5d => K_?5D - 0xf5, // 0x5e => K_oF5 - 0x5f, // 0x5f => K_?5F - 0x00, // 0x60 => No match - 0x00, // 0x61 => No match - 0xfb, // 0x62 => K_?FB - 0x2f, // 0x63 => K_HELP - 0x7c, // 0x64 => K_F13 - 0x7d, // 0x65 => K_F14 - 0x7e, // 0x66 => K_F15 - 0x7f, // 0x67 => K_F16 - 0x80, // 0x68 => K_F17 - 0x81, // 0x69 => K_F18 - 0x82, // 0x6a => K_F19 - 0x83, // 0x6b => K_F20 - 0x84, // 0x6c => K_F21 - 0x85, // 0x6d => K_F22 - 0x86, // 0x6e => K_F23 - 0xed, // 0x6f => K_oED - 0x00, // 0x70 => No match - 0xe9, // 0x71 => K_oE9 - 0x00, // 0x72 => No match - 0xc1, // 0x73 => K_?C1 - 0x00, // 0x74 => No match - 0x00, // 0x75 => No match - 0x87, // 0x76 => K_F24 - 0x00, // 0x77 => No match - 0x00, // 0x78 => No match - 0x00, // 0x79 => No match - 0x00, // 0x7a => No match - 0xeb, // 0x7b => K_oEB - 0x00, // 0x7c => No match - 0x00, // 0x7d => No match - 0x6c, // 0x7e => K_SEPARATOR - 0x00 // 0x7f => No match -}; -*/ -// _S2 many keys still need to be defined !! -//( on x. place there is key e.g. -// on (US) position 24 we find key xBB ( = + ) -// on (US) position 0 we find key x41 ( A a ) +// we use the same type of array as throughout Keyman even though we have lots of unused fields const UINT mac_ScanCodeToUSVirtualKey[128] = { - 0x41 ,// L"K_A", // &H41 - 0x53 ,// L"K_S", // &H53 - 0x44 ,// L"K_D", // &H44 - 0x46 ,// L"K_F", // &H46 - 0x48 ,// L"K_H", // &H48 - 0x47 ,// L"K_G", // &H47 - 0x5A ,// L"K_Z", // &H5A - 0x58 ,// L"K_X", // &H58 - 0x43 ,// L"K_C", // &H43 - 0x56 ,// L"K_V", // &H56 -0xC0, // ^° // 10 - 0x42 ,// L"K_B", // &H42 - 0x51 ,// L"K_Q", // &H51 - 0x57 ,// L"K_W", // &H57 - 0x45 ,// L"K_E", // &H45 - 0x52 ,// L"K_R", // &H52 - 0x59 ,// L"K_Y", // &H59 - 0x54 ,// L"K_T", // &H54 - 0x31 ,// L"K_1", // &H31 - 0x32 ,// L"K_2", // &H32 -0x33 ,// L"K_3", // &H33 // 20 - 0x34 ,// L"K_4", // &H34 - 0x36 ,// L"K_6", // &H36 - 0x35 ,// L"K_5", // &H35 - 0xBB ,// L"K_?00",// &HB8 - 0x39 ,// L"K_9", // &H39 - 0x37 ,// L"K_7", // &H37 - 0xBD ,// L"K_?00",// &HBA - 0x38 ,// L"K_8", // &H38 - 0x30 ,// L"K_0", // &H30 -0xDD ,// 0 // &HD9 // 30 - 0x4F ,// L"K_O", // &H4F - 0x55 ,// L"K_U", // &H55 - 0xDB , // 0 // &HD7 - 0x49 ,// L"K_I", // &H49 - 0x50 ,// L"K_P", // &H50 - 0x00, - 0x4C ,// L"K_L", // &H4C - 0x4A ,// L"K_J", // &H4A - 0xDE, //222 ,// 0 // &HDA -0x4B ,// L"K_K", // &H4B // 40 - 186 ,// L"K_?00", // &HB7 - 220 ,// 0 // &HD8 - 188 ,// L"K_?00", // &HB9 - 191 ,// L"K_?00", // &HBC - 0x4E ,// L"K_N", // &H4E - 0x4D ,// L"K_M", // &H4D - 190 ,// L"K_?00", // L", - 0 ,// L"K_?00", // &H0 // 0x77 => No match - 32 ,// L"K_?00", // &H1 -0xE2 ,// L"K_?00", // &H2 // 50 // NEU xxx - 3 ,// L"K_?00", // &H3 - 4 ,// L"K_?00", // &H4 - 5 ,// L"K_?00", // &H5 - 6 ,// L"K_?00", // &H6 - 7 ,// L"K_?00", // &H7 - 8 ,// L"K_?00", // &H8 - 9 ,// L"K_?00", // &H9 - 10 ,// L"K_?00", // &HA - 11 ,// L"K_?00", // &HB -12 ,// L"K_?00", // &HC // 60 - 13 ,// L"K_?00", // &HD - 14 ,// L"K_?00", // &HE - 15 ,// L"K_?00", // &HF - 16 ,// L"K_?00", // &H10 - 17 ,// L"K_?00", // L", - 18 ,// L"K_?00", // &H12 - 19 ,// L"K_?00", // &H13 - 20 ,// L"K_?00", // &H14 - 21 ,// L"K_?00", // &H15 - 22 ,// L"K_?00", // &H16 - 23 ,// L"K_?00", // &H17 - 24 ,// L"K_?00", // &H18 - 25 ,// L"K_?00", // &H19 - 26 ,// L"K_?00", // &H1A - 27 ,// L"K_?00", // &H1B - 28 ,// L"K_?00", // &H1C - 29 ,// L"K_?00", // &H1D - 30 ,// L"K_?00", // &H1E - 31 ,// L"K_?00", // &H1F - 32 ,// L"K_?00", // &H20 - 33 ,// L"K_?00", // &H21 - 34 ,// L"K_?00", // &H22 - 35 ,// L"K_?00", // &H23 - 36 ,// L"K_?00", // &H24 - 37 ,// L"K_?00", // &H25 - 38 ,// L"K_?00", // &H26 - 39 ,// L"K_?00", // &H27 - 40 ,// L"K_?00", // &H28 - 41 ,// L"K_?00", // &H29 - 42 ,// L"K_?00", // &H2A - 43 ,// L"K_?00", // &H2B - 44 ,// L"K_?00", // &H2C - 45 ,// L"K_?00", // &H2D - 46 ,// L"K_?00", // &H2E - 47 ,// L"K_?00", // &H2F - 58 ,// L"K_?00", // &H3A - 59 ,// L"K_?00", // &H3B - 60 ,// L"K_?00", // &H3C - 61 ,// L"K_?00", // &H3D - 62 ,// L"K_?00", // &H3E - 63 ,// L"K_?00", // &H3F - 64 ,// L"K_?00", // &H40 - 91 ,// L"K_?00", // &H5B - 92 ,// L"K_?00", // &H5C - 93 ,// L"K_?00", // &H5D - 94 ,// L"K_?00", // &H5E - 95 ,// L"K_?00", // &H5F - 96 ,// L"K_?00", // &H60 - 97 ,// L"K_?00", // &H61 - 98 ,// L"K_?00", // &H62 - 99 ,// L"K_?00", // &H63 - 100 ,// L"K_?00", // &H64 - 101 ,// L"K_?00", // &H65 - 102 ,// L"K_?00", // &H66 - 103 ,// L"K_?00", // &H67 - 104 ,// L"K_?00", // &H68 - 105 ,// L"K_?00", // &H69 - 106 ,// L"K_?00", // &H6A - 107 ,// L"K_?00", // &H6B - 108 ,// L"K_?00", // &H6C - 109 ,// L"K_?00", // &H6D - 110 ,// L"K_?00", // &H6E - 111 ,// L"K_?00", // &H6F - 112 ,// L"K_?00", // &H70 - 113 ,// L"K_?00", // &H71 - 114 ,// L"K_?00", // &H72 - 115 // L"K_?00", // &H73 + 0x41, // L"K_A", // &H41 + 0x53, // L"K_S", // &H53 + 0x44, // L"K_D", // &H44 + 0x46, // L"K_F", // &H46 + 0x48, // L"K_H", // &H48 + 0x47, // L"K_G", // &H47 + 0x5A, // L"K_Z", // &H5A + 0x58, // L"K_X", // &H58 + 0x43, // L"K_C", // &H43 + 0x56, // L"K_V", // &H56 + 0xC0, // L"K_BKQUOTE", // &HC0 (192) + 0x42, // L"K_B", // &H42 + 0x51, // L"K_Q", // &H51 + 0x57, // L"K_W", // &H57 + 0x45, // L"K_E", // &H45 + 0x52, // L"K_R", // &H52 + 0x59, // L"K_Y", // &H59 + 0x54, // L"K_T", // &H54 + 0x31, // L"K_1", // &H31 + 0x32, // L"K_2", // &H32 + 0x33, // L"K_3", // &H33 + 0x34, // L"K_4", // &H34 + 0x36, // L"K_6", // &H36 + 0x35, // L"K_5", // &H35 + 0xBB, // L"K_EQUAL", // &HBB (187) + 0x39, // L"K_9", // &H39 + 0x37, // L"K_7", // &H37 + 0xBD, // L"K_H YPHEN", // &HBD (189) + 0x38, // L"K_8", // &H38 + 0x30, // L"K_0", // &H30 + 0xDD, // L"K_RBRKT", // &HDD (221) + 0x4F, // L"K_O", // &H4F + 0x55, // L"K_U", // &H55 + 0xDB, // L"K_LBRKT", // &HDB (219) + 0x49, // L"K_I", // &H49 + 0x50, // L"K_P", // &H50 + 0x00, // not used // ---- + 0x4C, // L"K_L", // &H4C + 0x4A, // L"K_J", // &H4A + 0xDE, // L"K_QUOTE", // &HDE (222) + 0x4B, // L"K_K", // &H4B + 0xBA, // L"K_COLON", // &HBA (186) + 0xDC, // L"K_BKSLASH", // &HDC (220) + 0xBC, // L"K_COMMA", // &HBC (188) + 0xBF, // L"K_SLASH", // &HBF (191) + 0x4E, // L"K_N", // &H4E + 0x4D, // L"K_M", // &H4D + 0xBE, // L"K_PERIOD", // &HBE (190) + 0x00, // not used // ---- + 0x20, // L"K_SPACE", // &H1 + 0xE2, // L"K_oE2", // &HE2 (226) + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used }; -// _S2 what instead x999? -//( on character-.st index we find the keycode e.g. -// for character A (65) we look at pos 65 and find keycode 0 -// for character X (87) we look at pos 87 and find keycode 7 -// for character + (187) we look at pos 187 and find keycode 24 +// we use the same type of array as throughout Keyman even though we have lots of unused fields const UINT mac_USVirtualKeyToScanCode[256] = { - 0x999, // L"K_?00", // &H0 ................................................... 0 ........................................... - 0x999, // L"K_LBUTTON", // &H1 - 0x999, // L"K_RBUTTON", // &H2 - 0x999, // 0x46, // L"K_CANCEL", // &H3 - 0x999, // L"K_MBUTTON", // &H4 - 0x999, // L"K_?05", // &H5 - 0x999, // L"K_?06", // &H6 - 0x999, // L"K_?07", // &H7 - 0x999, // 0x0E, // L"K_BKSP", // &H8 - 0x999, // 0x0F, // L"K_TAB", // &H9 - 0x999, // L"K_?0A", // &HA - 0x999, // L"K_?0B", // &HB................................................... 11 ........................................... - 0x999, // 0x4C, // L"K_KP5", // &HC - 0x999, // 0x1C, // L"K_ENTER", // &HD - 0x999, // L"K_?0E", // &HE - 0x999, // L"K_?0F", // &HF - 0x999, // 0x2A, // L"K_SHIFT", // &H10 - 0x999, // 0x1D, // L"K_CONTRO 0x999, // L", // &H11 - 0x999, // 0x38, // L"K_ALT", // &H12 - 0x999, // L"K_PAUSE", // &H13 - 0x999, // 0x3A, // L"K_CAPS", // &H14 - 0x999, // L"K_KANJI?15", // &H15 - 0x999, // L"K_KANJI?16", // &H16 - 0x999, // L"K_KANJI?17", // &H17 - 0x999, // L"K_KANJI?18", // &H18 - 0x999, // L"K_KANJI?19", // &H19 - 0x999, // L"K_?1A", // &H1A - 0x999, // L"K_ESC", // &H1B - 0x999, // L"K_KANJI?1C", // &H1C - 0x999, // L"K_KANJI?1D", // &H1D -0x999, // L"K_KANJI?1E", // &H1E - 0x999, // L"K_KANJI?1F", // &H1F................................................... 31 ........................................... - 0x31, // L"K_SPACE", // &H20 - 0x999, // 0x49, // L"K_PGUP", // &H21 - 0x999, // 0x51, // L"K_PGDN", // &H22 - 0x999, // 0x4F, // L"K_END", // &H23 - 0x999, // 0x47, // L"K_HOME", // &H24 - 0x999, // 0x4B, // L"K_LEFT", // &H25 - 0x999, // 0x48, // L"K_UP", // &H26 - 0x999, // 0x4D, // L"K_RIGHT", // &H27 -0x999, // 0x50, // L"K_DOWN", // &H28 - 0x999, // L"K_SEL", // &H29 - 0x999, // L"K_PRINT", // &H2A - 0x999, // L"K_EXEC", // &H2B - 0x999, // 0x54, // L"K_PRTSCN", // &H2C - 0x999, // 0x52, // L"K_INS", // &H2D - 0x999, // 0x53, // L"K_DEL", // &H2E - 0x999, // 0x63, // L"K_HELP", // &H2F - 0x1D, // L"K_0", // &H30 - 0x12, // L"K_1", // &H31 -0x13, // L"K_2", // &H32 - 0x14, // L"K_3", // &H33................................................... 51 ........................................... - 0x15, // L"K_4", // &H34 - 0x17, // L"K_5", // &H35 - 0x16, // L"K_6", // &H36 - 0x1A, // L"K_7", // &H37 - 0x1C, // L"K_8", // &H38 - 0x19, // L"K_9", // &H39 - 0x999, // L"K_?3A", // &H3A - 0x999, // L"K_?3B", // &H3B -0x999, // L"K_?3C", // &H3C - 0x999, // L"K_?3D", // &H3D - 0x999, // L"K_?3E", // &H3E - 0x999, // L"K_?3F", // &H3F - 0x999, // L"K_?40", // &H40 - 0x00, // L"K_A", // &H41 - 0x0B, // L"K_B", // &H42 - 0x08, // L"K_C", // &H43 - 0x02, // L"K_D", // &H44 - 0x0E, // L"K_E", // &H45 -0x03, // L"K_F", // &H46 - 0x05, // L"K_G", // &H47................................................... 71 ........................................... - 0x04, // L"K_H", // &H48 - 0x22, // L"K_I", // &H49 - 0x26, // L"K_J", // &H4A - 0x28, // L"K_K", // &H4B - 0x25, // L"K_L", // &H4C - 0x2E, // L"K_M", // &H4D - 0x2D, // L"K_N", // &H4E - 0x1F, // L"K_O", // &H4F -0x23, // L"K_P", // &H50 - 0x0C, // L"K_Q", // &H51 - 0x0F, // L"K_R", // &H52 - 0x01, // L"K_S", // &H53 - 0x11, // L"K_T", // &H54 - 0x20, // L"K_U", // &H55 - 0x09, // L"K_V", // &H56 - 0x0D, // L"K_W", // &H57 - 0x07, // L"K_X", // &H58 - 0x10, // L"K_Y", // &H59................................................... 89 ........................................... -0x06, // L"K_Z", // &H5A - 0x999, //0x5B, // L"K_?5B", // &H5B - 0x999, //0x5C, // L"K_?5C", // &H5C - 0x999, //0x5D, // L"K_?5D", // &H5D - 10, //0x00, // L"K_?5E", // &H5E - 0x999, //0x5F, // L"K_?5F", // &H5F - 0x999, //0x52, // L"K_NP0", // &H60 - 0x999, //0x4F, // L"K_NP1", // &H61 - 0x999, //0x50, // L"K_NP2", // &H62 - 0x999, //0x51, // L"K_NP3", // &H63 - 0x999, //0x4B, // L"K_NP4", // &H64 - 0x999, //0x4C, // L"K_NP5", // &H65 - 0x999, //0x4D, // L"K_NP6", // &H66 - 0x999, //0x47, // L"K_NP7", // &H67 - 0x999, //0x48, // L"K_NP8", // &H68 - 0x999, //0x49, // L"K_NP9", // &H69 - 0x999, //0x37, // L"K_NPSTAR", // &H6A - 0x999, //0x4E, // L"K_NPPLUS", // &H6B - 0x999, //0x7E, // L"K_SEPARATOR", // &H6C // MCD 01-11-02: Brazilian Fix, 00 -> 7E - 0x999, //0x4A, // L"K_NPMINUS", // &H6D - 0x999, //0x53, // L"K_NPDOT", // &H6E // ................................................. 110 ........... - 0x999, //0x135, // L"K_NPSLASH", // &H6F - 0x999, //0x3B, // L"K_F1", // &H70 - 0x999, //0x3C, // L"K_F2", // &H71 - 0x999, //0x3D, // L"K_F3", // &H72 - 0x999, //0x3E, // L"K_F4", // &H73 - 0x999, //0x3F, // L"K_F5", // &H74 - 0x999, //0x40, // L"K_F6", // &H75 - 0x999, //0x41, // L"K_F7", // &H76 - 0x999, //0x42, // L"K_F8", // &H77 - 0x999, //0x43, // L"K_F9", // &H78 - 0x999, //0x44, // L"K_F10", // &H79 - 0x999, //0x57, // L"K_F11", // &H7A - 0x999, //0x58, // L"K_F12", // &H7B - 0x999, //0x64, // L"K_F13", // &H7C - 0x999, //0x65, // L"K_F14", // &H7D - 0x999, //0x66, // L"K_F15", // &H7E - 0x999, //0x67, // L"K_F16", // &H7F - 0x999, //0x68, // L"K_F17", // &H80..... - 0x999, //0x69, // L"K_F18", // &H81 - 0x999, //0x6A, // L"K_F19", // &H82.................................................. 130 ....................................... - 0x999, //0x6B, // L"K_F20", // &H83 - 0x999, //0x6C, // L"K_F21", // &H84 - 0x999, //0x6D, // L"K_F22", // &H85 - 0x999, //0x6E, // L"K_F23", // &H86 - 0x999, //0x76, // L"K_F24", // &H87 ----- - 0x999, //0x00, // L"K_?88", // &H88 - 0x999, //0x00, // L"K_?89", // &H89 - 0x999, //0x00, // L"K_?8A", // &H8A - 0x999, //0x00, // L"K_?8B", // &H8B - 0x999, //0x00, // L"K_?8C", // &H8C - 0x999, //0x00, // L"K_?8D", // &H8D - 0x999, //0x00, // L"K_?8E", // &H8E - 0x999, //0x00, // L"K_?8F", // &H8F ----- - 0x999, //0x45, // L"K_NUMLOCK", // &H90 - 0x999, //0x46, // L"K_SCROL 0x999, //0x00, // L", // &H91 ----- - 0x999, //0x00, // L"K_?92", // &H92 - 0x999, //0x00, // L"K_?93", // &H93 - 0x999, //0x00, // L"K_?94", // &H94................. - 0x999, //0x00, // L"K_?95", // &H95 - 0x999, //0x00, // L"K_?96", // &H96............................................. 150 ................................ - 0x999, //0x00, // L"K_?97", // &H97 - 0x999, //0x00, // L"K_?98", // &H98 - 0x999, //0x00, // L"K_?99", // &H99 - 0x999, //0x00, // L"K_?9A", // &H9A - 0x999, //0x00, // L"K_?9B", // &H9B - 0x999, //0x00, // L"K_?9C", // &H9C - 0x999, //0x00, // L"K_?9D", // &H9D - 0x999, //0x00, // L"K_?9E", // &H9E - 0x999, //0x00, // L"K_?9F", // &H9F - 0x999, //0x2A, // L"K_?A0", // &HA0 - 0x999, //0x36, // L"K_?A1", // &HA1 - 0x999, //0x1D, // L"K_?A2", // &HA2 - 0x999, //0x1D, // L"K_?A3", // &HA3 - 0x999, //0x38, // L"K_?A4", // &HA4 - 0x999, //0x38, // L"K_?A5", // &HA5 - 0x999, //0x6A, // L"K_?A6", // &HA6 - 0x999, //0x69, // L"K_?A7", // &HA7 - 0x999, //0x67, // L"K_?A8", // &HA8...................... - 0x999, //0x68, // L"K_?A9", // &HA9 - 0x999, //0x65, // L"K_?AA", // &HAA....................................... 170 ................................. - 0x999, //0x66, // L"K_?AB", // &HAB - 0x999, //0x32, // L"K_?AC", // &HAC - 0x999, //0x20, // L"K_?AD", // &HAD - 0x999, //0x2E, // L"K_?AE", // &HAE - 0x999, //0x30, // L"K_?AF", // &HAF - 0x999, //0x19, // L"K_?B0", // &HB0 - 0x999, //0x10, // L"K_?B1", // &HB1 - 0x999, //0x24, // L"K_?B2", // &HB2 - 0x999, //0x22, // L"K_?B3", // &HB3 - 0x999, //0x6C, // L"K_?B4", // &HB4 - 0x999, //0x6D, // L"K_?B5", // &HB5 - 0x999, //0x6B, // L"K_?B6", // &HB6 - 0x999, //0x21, // L"K_?B7", // &HB7 - 0x999, //0x00, // L"K_?B8", // &HB8 - 0x999, //0x00, // L"K_?B9", // &HB9 ----- - 0x29, // L"K_COLON", // &HBA - 24, // 0x0D, // L"K_EQUA0x00, // L", // &HBB 187 - 0x2B, // L"K_COMMA", // &HBC ........ - 0x1B, // L"K_HYPHEN", // &HBD -0x2F, // L"K_PERIOD", // &HBE................................................ 190 ...................................... - 0x2C, // L"K_SLASH", // &HBF - 0x0A, //0x77, // L"K_BKQUOTE", // &HC0 ----- - 0x999, //0x73, // L"K_?C1", // &HC1 - 0x999, //0x7E, // L"K_?C2", // &HC2 - 0x999, //0x00, // L"K_?C3", // &HC3 - 0x999, //0x00, // L"K_?C4", // &HC4 196 - 0x999, //0x00, // L"K_?C5", // &HC5 - 0x999, //0x00, // L"K_?C6", // &HC6 - 0x999, //0x00, // L"K_?C7", // &HC7 - 0x999, //0x00, // L"K_?C8", // &HC8 - 0x999, //0x00, // L"K_?C9", // &HC9 - 0x999, //0x00, // L"K_?CA", // &HCA - 0x999, //0x00, // L"K_?CB", // &HCB - 0x999, //0x00, // L"K_?CC", // &HCC - 0x999, //0x00, // L"K_?CD", // &HCD - 0x999, //0x00, // L"K_?CE", // &HCE - 0x999, //0x00, // L"K_?CF", // &HCF - 0x999, //0x00, // L"K_?D0", // &HD0............... - 0x999, //0x00, // L"K_?D1", // &HD1 - 0x999, //0x00, // L"K_?D2", // &HD2............................................... 210 ................................ - 0x999, //0x00, // L"K_?D3", // &HD3 - 0x999, //0x00, // L"K_?D4", // &HD4 - 0x999, //0x00, // L"K_?D5", // &HD5 - 0x999, //0x00, // L"K_?D6", // &HD6 - 0x999, //0x00, // L"K_?D7", // &HD7 - 0x999, //0x00, // L"K_?D8", // &HD8 - 0x999, //0x00, // L"K_?D9", // &HD9 - 0x999, //0x00, // L"K_?DA", // &HDA - 0x21, // L"K_LBRKT", // &HDB - 0x2A, // L"K_BKSLASH", // &HDC - 0x1E, // L"K_RBRKT", // &HDD - 0x27, // L"K_QUOTE", // &HDE - 27, // L"K_oDF", // &HDF // MCD 01-11-02: Brazilian fix: 00 -> 73 - 0x999, //0x00, // L"K_oE0", // &HE0 - 0x999, //0x00, // L"K_oE1", // &HE1 - 50, //0x56, // L"K_oE2", // &HE2 - 0x999, //0x00, // L"K_oE3", // &HE3 - 0x999, //0x00, // L"K_oE4", // &HE4..... - 0x999, //0x00, // L"K_?E5", // &HE5 -0x999, //0x00, // L"K_oE6", // &HE6.................................................. 230 ....................................... - 0x999, //0x00, // L"K_?E7", // &HE7 - 0x999, //0x00, // L"K_?E8", // &HE8 222 - 0x999, //0x71, // L"K_oE9", // &HE9 - 0x999, //0x5C, // L"K_oEA", // &HEA - 0x999, //0x7B, // L"K_oEB", // &HEB - 0x999, //0x00, // L"K_oEC", // &HEC 226 - 0x999, //0x6F, // L"K_oED", // &HED - 0x999, //0x5A, // L"K_oEE", // &HEE - 0x999, //0x00, // L"K_oEF", // &HEF - 0x999, //0x00, // L"K_oF0", // &HF0 - 0x999, //0x5B, // L"K_oF1", // &HF1 - 0x999, //0x00, // L"K_oF2", // &HF2 - 0x999, //0x5F, // L"K_oF3", // &HF3 - 0x999, //0x00, // L"K_oF4", // &HF4 - 0x999, //0x5E, // L"K_oF5", // &HF5 - 0x999, //0x00, // L"K_?F6", // &HF6 - 0x999, //0x00, // L"K_?F7", // &HF7 - 0x999, //0x00, // L"K_?F8", // &HF8 - 0x999, //0x5D, // L"K_?F9", // &HF9 - 0x999, //0x00, // L"K_?FA", // &HFA - 0x999, //0x62, // L"K_?FB", // &HFB - 0x999, //0x00, // L"K_?FC", // &HFC - 0x999, //0x00, // L"K_?FD", // &HFD - 0x999, //0x00, // L"K_?FE", // &HFE - 0x999, //0x00 // L"K_?FF" // &HFF + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x31, // L"K_SPACE", // &H20 + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x1D, // L"K_0", // &H30 + 0x12, // L"K_1", // &H31 + 0x13, // L"K_2", // &H32 + 0x14, // L"K_3", // &H33 + 0x15, // L"K_4", // &H34 + 0x17, // L"K_5", // &H35 + 0x16, // L"K_6", // &H36 + 0x1A, // L"K_7", // &H37 + 0x1C, // L"K_8", // &H38 + 0x19, // L"K_9", // &H39 + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x00, // L"K_A", // &H41 + 0x0B, // L"K_B", // &H42 + 0x08, // L"K_C", // &H43 + 0x02, // L"K_D", // &H44 + 0x0E, // L"K_E", // &H45 + 0x03, // L"K_F", // &H46 + 0x05, // L"K_G", // &H47 + 0x04, // L"K_H", // &H48 + 0x22, // L"K_I", // &H49 + 0x26, // L"K_J", // &H4A + 0x28, // L"K_K", // &H4B + 0x25, // L"K_L", // &H4C + 0x2E, // L"K_M", // &H4D + 0x2D, // L"K_N", // &H4E + 0x1F, // L"K_O", // &H4F + 0x23, // L"K_P", // &H50 + 0x0C, // L"K_Q", // &H51 + 0x0F, // L"K_R", // &H52 + 0x01, // L"K_S", // &H53 + 0x11, // L"K_T", // &H54 + 0x20, // L"K_U", // &H55 + 0x09, // L"K_V", // &H56 + 0x0D, // L"K_W", // &H57 + 0x07, // L"K_X", // &H58 + 0x10, // L"K_Y", // &H59 + 0x06, // L"K_Z", // &H5A + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x29, // L"K_COLON", // &HBA (186) + 0x18, // L"K_EQUAL", // &HBB (187) + 0x2B, // L"K_COMMA", // &HBC (188) + 0x1B, // L"K_HYPHEN", // &HBD (189) + 0x2F, // L"K_PERIOD", // &HBE (190) + 0x2C, // L"K_SLASH", // &HBF (191) + 0x0A, // L"K_BKQUOTE", // &HC0 (192) + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x21, // L"K_LBRKT", // &HDB (219) + 0x2A, // L"K_BKSLASH", // &HDC (220) + 0x1E, // L"K_RBRKT", // &HDD (221) + 0x27, // L"K_QUOTE", // &HDE (222) + 0x1B, // L"K_oDF", // &HDF (223) + 0xFFFF, // not used + 0xFFFF, // not used + 0x32, // L"K_oE2", // &HE2 (226) + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used }; -bool mac_IsKeymanUsedChar(int KV); +//bool mac_IsKeymanUsedChar(int KV); //------------------------------ +// _S2 CHECKED OK +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int kc_underlying, int shiftstate_mac); -// take deadkey-value (e.g.65106) and return u16string (e.g. '^' ) -std::u16string mac_convert_DeadkeyValues_To_U16str(int in); +// _S2 CHECKED OK fill Deadkey with dk and return CATEGORY +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT kc_underlying, UINT VKShiftState, PKMX_WCHAR deadKey); -// use gdk_keymap_translate_keyboard_state to get keyval - base function to get keyvals -// _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk only? -int mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int ss, int caps); -int mac_KMX_get_KeyVal_From_KeyCode_S2(const UCKeyboardLayout * keyboard_layout, int keycode, int ss, int caps); -int mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate, int caps, UInt32 &deadkeystate_ret); +// _S2 CHECKED OK use Vector to return the Keyval of underlying Keyboard +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D &All_Vector, KMX_DWORD kv_us); -// use mac_KMX_get_KeyVal_From_KeyCode and prevent use of certain keycodes -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int keycode, int shift_state_pos); +// _S2 CHECKED OK use Vector to return the Scancode of underlying Keyboard +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vector, KMX_DWORD kv_underlying); -// fill Deadkey with dk and return CATEGORY -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT VKShiftState, UINT KC_underlying, PKMX_WCHAR DeadKey); +// _S2 CHECKED OK use Vector to return the Keycode of the underlying Keyboard for given VK_US using GDK +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_DWORD kc_us, ShiftState ss, int caps); -// use Vector to return the Keyval of underlying Keyboard -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D &All_Vector,KMX_DWORD VK_underlying); +// _S2 CHECKED OK return the Keycode of the underlying Keyboard for given VK_US +UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us); -// use Vector to return the Scancode of underlying Keyboard -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vector, KMX_DWORD KV_Underlying); +// _S2 CHECKED OK return the VirtualKey of the US Keyboard for a given Keyode using GDK +KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); -// use Vector to return the Keycode of the underlying Keyboard for given VK_US using GDK -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector,KMX_DWORD KC_US, ShiftState ss, int caps); +// _S2 CHECKED OK +KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps); -// return the Keycode of the underlying Keyboard for given VK_US -UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD VirtualKeyUS); +// use gdk_keymap_translate_keyboard_state to get keyval - base function to get keyvals -// return the VirtualKey of the US Keyboard for a given Keyode using GDK -KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); +// _S2 CHECKED OK +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps); +// _S2 CHECKED OK +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32 &deadkeystate); -// convert codePoint to u16string -//std::u16string mac_CodePointToU16String(unsigned int codepoint); //################################################################################################################################################ //################################################################################################################################################ +//KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_new(int charVal,const UCKeyboardLayout* keyboard_layout , KMX_DWORD shiftstate); +//static KMX_DWORD deadkey_min = 0xfe50; // _S2 needed?? +//static KMX_DWORD deadkey_max = 0xfe93; // _S2 needed?? +//static KMX_DWORD deadkey_max = 0xfe52; // _S2 TOP_6 TODO This has to go! my test: to only return 3 dk // _S2 need to go +// _S2 CHECKED OK +// take deadkey-value (e.g.65106) and return u16string (e.g. '^' ) +//std::u16string mac_convert_DeadkeyValues_To_U16str(int in); + + +// convert codePoint to u16string +//std::u16string mac_CodePointToU16String(unsigned int codepoint); + // replace Name of Key (e.g. ) wih Keycode ( e.g. 15 ) //int mac_replace_KeyName_with_Keycode(std::string in); @@ -960,7 +543,7 @@ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); // 1. step: read complete Row of Configuration file US //bool mac_createCompleteRow_US(v_str_1D &complete_List, FILE *fpp, const char *text, std::string language); -void printoutKeyboards(v_dw_3D &All_Vector); +void test_printoutKeyboards_S2(v_dw_3D &All_Vector); KMX_DWORD X_playWithDK_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal) ; KMX_DWORD X_playWithDK_S2_one(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal); KMX_DWORD X_compare_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); diff --git a/mac/mcompile/km_types.h b/mac/mcompile/km_types.h index 531bb2ccc06..8251cf7d481 100755 --- a/mac/mcompile/km_types.h +++ b/mac/mcompile/km_types.h @@ -113,8 +113,3 @@ typedef KMX_UCHAR* KMX_PUCHAR; #define VK_CAPITAL 0x14 #endif /*KM_TYPES*/ - - -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ diff --git a/mac/mcompile/kmx_file.h b/mac/mcompile/kmx_file.h index 1e7d76da8f5..d7fa0d51d5f 100755 --- a/mac/mcompile/kmx_file.h +++ b/mac/mcompile/kmx_file.h @@ -27,7 +27,6 @@ namespace kmx { #define KEYMANID_INVALID 0xFFFFFFFD // Shift flags for hotkeys (version 1.0) // -//_S2 here values for mac #define SHIFTFLAG 0x2000 #define CTRLFLAG 0x4000 #define ALTFLAG 0x8000 @@ -389,6 +388,3 @@ static_assert(sizeof(KMX_COMP_KEYBOARD) == KEYBOARDFILEHEADER_SIZE, "COMP_KEYBOA #endif #endif //KMX_FILE_H -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 8c4543beda1..85c90869587 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -70,44 +70,32 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { bool test_alDead_S2(std::vector ald); -int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps,const UCKeyboardLayout * keyboard_layout) { -// _S2 ToDo cleanup!! - /* - if (!(shift_state_pos <= count)) - return 0; +int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_win, int caps, const UCKeyboardLayout * keyboard_layout) { + KMX_DWORD keyval; + UInt32 isdk=0; - if (!(keycode <= keycode_max)) + if (!keyboard_layout) return 0; - */ - //rc>0: character - //rc==0: no translation - //rc<0: dk + if (!(keycode <= keycode_max)) + return 0; - // _S2 can I use mac_KMX_get_KeyVal_From_KeyCode_dk ? - KMX_DWORD KeyVal2= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode, mac_map_ShiftState_to_MacModifier(ShiftState(shift_state_pos)), caps); + if (!(ss_win <= max_shiftstate)) + return 0; - UInt32 isdk=0; - KMX_DWORD KeyVal= (KMX_DWORD) mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_map_ShiftState_to_MacModifier(ShiftState(shift_state_pos)), caps, isdk); + if (!(caps <= 1)) + return 0; - // _S2 ToDo non-dk OK, but all others not - std::u16string str = mac_convert_DeadkeyValues_To_U16str(KeyVal); + keyval= mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_map_Win_ShiftState_to_MacModifier(ShiftState(ss_win)), caps, isdk); + std::u16string str =std::u16string(1, keyval ); pwszBuff[0]= * (PKMX_WCHAR) str.c_str(); - /* - - if((KeyVal >= deadkey_min) && (KeyVal <= deadkey_max)) // deadkeys - return -1; - else if(gdk_keyval_to_unicode(KeyVal) == 0) // NO UNICODE - return 0; - else */ // usable char -// _S2 dk >0 if dk found - if ((isdk) && (keycode!= 0x999)) // isdk !=0 + if ((isdk) && (keycode!= 0x999)) // deadkeys return -1; - else if (KeyVal ==0) // NO UNICODE + if (keyval == 0) // no character return 0; - else - return 1; // usable char + else // usable char + return 1; } int mac_KMX_DeadKeyMap(int index, std::vector *deadkeys, int deadkeyBase, std::vector *deadkeyMappings) { // I4327 // I4353 @@ -235,7 +223,7 @@ class mac_KMX_VirtualKey { for (int caps = 0; caps <= 1; caps++) { std::u16string st = this->mac_KMX_GetShiftState((ShiftState) ss, (caps == 1)); - + // ctrl and sh+ctrl will be skipped since rgkey has no entries in m_rgss[2] m_rgss[3] if (st.size() == 0) { // No character assigned here } else if (this->m_rgfDeadKey[(int)ss][caps]) { @@ -246,9 +234,7 @@ class mac_KMX_VirtualKey { for (size_t ich = 0; ich < st.size(); ich++) { if(st[ich] < 0x20 || st[ich] == 0x7F) { isvalid=false; - - // _S2 must be included later - // wprintf(L"invalid for: %i\n", st[ich]); + wprintf(L"invalid for: %i\n", st[ich]); break; } } if(isvalid) { @@ -260,14 +246,15 @@ class mac_KMX_VirtualKey { return nkeys; } - bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector *deadkeys, int deadkeyBase, BOOL bDeadkeyConversion,v_dw_3D &All_Vector, const UCKeyboardLayout *keyboard_layout ) { // I4552 + bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector *deadkeys, int deadkeyBase, BOOL bDeadkeyConversion, v_dw_3D &All_Vector, const UCKeyboardLayout *keyboard_layout ) { // I4552 // Get the CAPSLOCK value int capslock = (this->mac_KMX_IsCapsEqualToShift() ? 1 : 0) | (this->mac_KMX_IsSGCAPS() ? 2 : 0) | (this->mac_KMX_IsAltGrCapsEqualToAltGrShift() ? 4 : 0) | (this->mac_KMX_IsXxxxGrCapsEqualToXxxxShift() ? 8 : 0); -capslock = 1; //_S2 +capslock = 1; //_S2 TODO + for (int ss = 0; ss <= MaxShiftState; ss++) { if (ss == Menu || ss == ShftMenu) { // Alt and Shift+Alt don't work, so skip them @@ -310,8 +297,7 @@ capslock = 1; //_S2 for (size_t ich = 0; ich < st.size(); ich++) { if(st[ich] < 0x20 || st[ich] == 0x7F) { isvalid=false; - // _S2 must be included later - //wprintf(L"invalid 16 for: %i\n", st[ich]); + wprintf(L"invalid 16 for: %i\n", st[ich]); break; } } if(isvalid) { @@ -320,8 +306,8 @@ capslock = 1; //_S2 // this->m_vk stores VK-US ( not underlying !!) // key->Key stores VK-US ( not underlying !!) // key->dpOutput stores character Underlying - KMX_DWORD SC_Underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keyboard_layout, All_Vector, this->SC(), (ShiftState) ss, caps); + key->Key = mac_KMX_get_VKUS_From_KeyCodeUnderlying( SC_Underlying); key->Line = 0; @@ -343,7 +329,6 @@ capslock = 1; //_S2 } }; - class mac_KMX_Loader { private: KMX_BYTE lpKeyStateNull[256]; @@ -378,33 +363,30 @@ class mac_KMX_Loader { bool fCapsLock, // Was the caps lock key pressed? const UCKeyboardLayout * keyboard_layout) { // The keyboard layout - int ss[]={0,2,8,10}; int maxshiftstate=2; DeadKey *deadKey = new DeadKey(rgKey[iKeyDead]->mac_KMX_GetShiftState(shiftStateDead, fCapsLock)[0]); - // e.g. ^ keyval - int ss_dead = mac_map_ShiftState_to_MacModifier(shiftStateDead); - int keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead],ss_dead,0); + int ss_dead = mac_map_Win_ShiftState_to_MacModifier(shiftStateDead); + KMX_DWORD keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead], ss_dead,0); - for( int i=0; i< Keycode_Spacebar+1; i++) { + for( int i=0; i< keycode_spacebar+1; i++) { for( int j=0; j< maxshiftstate ; j++) { - // _S2 do we need caps?? for( int caps = 0; caps < 1; caps++) { // e.g. a basechar - int basechar = mac_KMX_get_KeyVal_From_KeyCode_S2(keyboard_layout, i,ss[j],caps); + KMX_DWORD basechar = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[j], caps); // e.g. â combchar - KMX_DWORD KC_Underlying_dk = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKeyDead); - KMX_DWORD combchar= mac_get_CombinedChar_From_DK(KC_Underlying_dk, ss_dead, keyboard_layout , i, ss[j],caps); + KMX_DWORD KC_Underlying_dk = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKeyDead); + KMX_DWORD combchar= mac_get_CombinedChar_From_DK(KC_Underlying_dk, ss_dead, keyboard_layout, i, ss_mac[j], caps); if(combchar== 0) continue; // push only for if combchar is not dk or combchar is dk with space - if( (!(combchar== keyval_underlying_dk)) || (basechar == mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, Keycode_Spacebar,ss[j],caps))) { + if( (!(combchar== keyval_underlying_dk)) || (basechar == mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode_spacebar, ss_mac[j], caps))) { deadKey->KMX_AddDeadKeyRow(basechar, combchar); - printf( " processed basechar %i(%c) with dk %i(%c) ===> combchar%i(%c) \t\t ss[%i](%i) caps%i \n", basechar,basechar ,keyval_underlying_dk,keyval_underlying_dk, combchar,combchar ,j,ss[j], caps ); + //printf( " processed basechar %i(%c) with dk %i(%c) ===> combchar%i(%c) \t\t ss[%i](%i) caps%i \n", basechar,basechar ,keyval_underlying_dk,keyval_underlying_dk, combchar,combchar, j, ss[j], caps ); } } } @@ -421,8 +403,7 @@ class mac_KMX_Loader { }*/ }; - -/* int KMX_GetMaxDeadkeyIndex(KMX_WCHAR *p) { +int mac_KMX_GetMaxDeadkeyIndex(KMX_WCHAR *p) { int n = 0; while(p && *p) { if(*p == UC_SENTINEL && *(p+1) == CODE_DEADKEY) @@ -430,15 +411,15 @@ class mac_KMX_Loader { p = KMX_incxstr(p); } return n; -}*/ +} // _S2 need to go -void print_All_Entries_S2(std::vector rgKey); -bool run_verify_S2(std::vector rgKey); -void print_All_Keys(const UCKeyboardLayout * keyboard_layout); -void print_certain_Keys(const UCKeyboardLayout * keyboard_layout, int keycode); +void test_print_All_Entries_S2(std::vector rgKey); +bool test_run_verify_S2(std::vector rgKey); +void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout); +void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode); -bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout,std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 +bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout, std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 mac_KMX_Loader loader; std::vector rgKey; //= new VirtualKey[256]; @@ -450,7 +431,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar // values in it. Then, store the SC in each valid VK so it can act as both a // flag that the VK is valid, and it can store the SC value. - //for(UINT sc = 0x01; sc <= 0x7f; sc++) { _S2 win lin keycode start with 1; mac with 0 + //Windows and Linux Keycodes start with 1; Mac keycodes start with 0 for(UINT sc = 0x00; sc <= 0x7f; sc++) { // HERE IS A BIG DIFFERENCE COMPARED TO MCOMPILE FOR WINDOWS: @@ -471,7 +452,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar } } -// // _S2 TODO I assume we do not need those... +// // _S2 I assume we do not need those... // rgKey[VK_DIVIDE] = new mac_KMX_VirtualKey(hkl, VK_DIVIDE); // rgKey[VK_CANCEL] = new mac_KMX_VirtualKey(hkl, VK_CANCEL); // rgKey[VK_DECIMAL] = new mac_KMX_VirtualKey(hkl, VK_DECIMAL); @@ -488,36 +469,31 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar } //_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! - if(ss == MenuCtrl|| ss == ShftMenuCtrl) { + if(ss == MenuCtrl|| ss == ShftMenuCtrl) { continue; } - // _S2 ToDo what about not used keys?? - KMX_DWORD KC_US = (KMX_DWORD) mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); - for(int caps = 0; caps <= 1; caps++) { + KMX_DWORD KC_US = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); + for(int caps = 0; caps <= 1; caps++) { int rc = mac_KMX_ToUnicodeEx(KC_US, sbBuffer, ss, caps, *keyboard_layout); - //rc>0: character //_S2 - //rc==0: no translation - //rc<0: dk + if(rc > 0) { if(*sbBuffer == 0) { - rgKey[iKey]->mac_KMX_SetShiftState(ss, u"", false, (caps)); // different to windows since behavior on Linux is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, u"", false, (caps)); // different to windows since behavior on mac is different } else { if( (ss == Ctrl || ss == ShftCtrl) ) { continue; } sbBuffer[rc] = 0; - rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to windows since behavior on Linux is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to windows since behavior on mac is different } } else if(rc < 0) { sbBuffer[2] = 0; - rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on Linux is different - // _S2 does not work - deadkeys - //if (!caps) // _S2 can go later - printf(" _S2 we use dk: %i(%i) %i caps:%i %i(%c) \n", KC_US, iKey,ss,caps, sbBuffer[0],sbBuffer[0] ); + rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on mac is different + printf(" _S2 we use dk: %i(%i) %i caps:%i %i(%c) \n", KC_US, iKey,ss, caps, sbBuffer[0],sbBuffer[0] ); sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps == 0)); @@ -531,7 +507,6 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar } if(dk == NULL) { alDead.push_back(loader.ProcessDeadKey(iKey, ss, rgKey, caps == 0, *keyboard_layout)); - printf(" WOULD DO alDead.push_back for caps: %i sbBuffer[0] %i\n", caps,sbBuffer[0]); } } } @@ -541,17 +516,20 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar //------------------------------------------------------------- // Now that we've collected the key data, we need to - // translate it to kmx and append to the existing keyboar + // translate it to kmx and append to the existing keyboard //------------------------------------------------------------- - // _S2 need to go - //print_All_Entries_S2(rgKey); - //print_All_Keys( * keyboard_layout); - //print_certain_Keys( * keyboard_layout, 10); - // bool allOK =test_alDead_S2(alDead); - if ( ! run_verify_S2(rgKey)) + // _S2 all of my tests need to go ............ + //test_print_All_Entries_S2(rgKey); + //test_print_All_Keys_S2( * keyboard_layout); + //test_print_certain_Keys_S2( * keyboard_layout, 14); + //bool allOK =test_alDead_S2(alDead); + bool allOK=true; + if ( ! allOK ) + printf(" \n::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG DEADKEYS :::::::::::::::::::::::::::::::::::::::::::::::::: \n"); + if ( ! test_run_verify_S2(rgKey)) printf(" \n::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG ENTRIES ::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); - else + if ( test_run_verify_S2(rgKey) && allOK) printf("\n ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :) :) :) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); int nDeadkey = 0; @@ -573,11 +551,10 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar //} LPKMX_KEY kkp = gp->dpKeyArray; - //_S2 deadkeys - /*for(UINT j = 0; j < gp->cxKeyArray; j++, kkp++) { - nDeadkey = std::max(nDeadkey, KMX_GetMaxDeadkeyIndex(kkp->dpContext)); - nDeadkey = std::max(nDeadkey, KMX_GetMaxDeadkeyIndex(kkp->dpOutput)); - }*/ + for(UINT j = 0; j < gp->cxKeyArray; j++, kkp++) { + nDeadkey = std::max(nDeadkey, mac_KMX_GetMaxDeadkeyIndex(kkp->dpContext)); + nDeadkey = std::max(nDeadkey, mac_KMX_GetMaxDeadkeyIndex(kkp->dpOutput)); + } } @@ -616,7 +593,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar gp->cxKeyArray = nkeys; // - // Add nomatch control to each terminating 'using keys' group // I4550 ggggǵggg hhhhh´ggggggg ggggḣhh gggggggggg`gggggggǵg ǵǵggggg hhhh´gggggg ggggáaaa – Ñ + // Add nomatch control to each terminating 'using keys' group // I4550 // LPKMX_GROUP gp2 = kp->dpGroupArray; for(UINT i = 0; i < kp->cxGroupArray - 1; i++, gp2++) { @@ -659,8 +636,6 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboar // We only do this if not in deadkey conversion mode // - int STOP=0; // _S2 up to here - if (alDead.size() > 0 && !bDeadkeyConversion) { // I4552 kp->cxGroupArray++; @@ -761,7 +736,6 @@ const int CODE__SIZE[] = { 2 // CODE_SETSYSTEMSTORE 0x18 }; - // _S2 need to go void print_entries_S2(int i, std::vector rgKey , std::string comp1,std::string comp2,std::string erg) { std::string b0 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 0 )); @@ -796,7 +770,7 @@ bool verify_entries_S2(int i, std::vector rgKey, int res1,i printf(" ERROR FOR i= Nr:%i, %i(%c) - %i (%c) - %i (%c) - %i (%c) \n",i, *st_vec[0].c_str(),*st_vec[1].c_str(),*st_vec[2].c_str(),*st_vec[3].c_str(),*st_vec[4].c_str(),*st_vec[5].c_str(),*st_vec[6].c_str(),*st_vec[7].c_str()); return all_OK; } -void print_All_Entries_S2( std::vector rgKey) { +void test_print_All_Entries_S2( std::vector rgKey) { for ( int i=48; i<58; i++) print_entries_S2(i, rgKey," ","",""); @@ -817,139 +791,141 @@ void print_All_Entries_S2( std::vector rgKey) { print_entries_S2(222, rgKey, "ä", "Ä", "ä Ä Ä Ä"); print_entries_S2(226, rgKey, "<", ">", "< < > >"); } -void print_certain_Keys(const UCKeyboardLayout * keyboard_layout, int keycode) { +void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode) { UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; UniChar unicodeString[maxStringlength]; UInt32 deadkeystate = 0; OSStatus status; - int shiftarray[] ={0,2,8,10}; - + unicodeString[0]=0; + //int shiftarray[] ={0,2,8,10}; + int shiftarray[] ={0,1,2,3,4,5,6,7,8,9,10}; for(int k=0; k<2;k++) { - for(int j=0; j<4;j++) { - status = UCKeyTranslate(keyboard_layout, keycode ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + for(int j=0; j<(sizeof(shiftarray)/ sizeof(int));j++) { + status = UCKeyTranslate(keyboard_layout, keycode , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate ==0) - printf(" key nr %i , ss %i has values %i(%c)\n", keycode, shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); + printf(" key nr %i , ss %i has values %i(%c)\n", keycode, shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); // If this was a deadkey, append a space if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, 49 ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - printf(" dk key nr %i , ss %i has values %i(%c)\n", keycode,shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); + status = UCKeyTranslate(keyboard_layout, keycode_spacebar , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + printf(" dk with caps key nr %i , ss %i has values %i(%c)\n", keycode,shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); } } } } -void print_All_Keys(const UCKeyboardLayout * keyboard_layout){ +void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout){ UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; UniChar unicodeString[maxStringlength]; UInt32 deadkeystate = 0; OSStatus status; + unicodeString[0]=0; int shiftarray[] ={0,2,8,10}; for(int k=0; k<2;k++) { for(int j=0; j<4;j++) { - for(int i=0; i< Keycode_Spacebar+1 ;i++) { - status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + for(int i=0; i< keycode_spacebar+1 ;i++) { + status = UCKeyTranslate(keyboard_layout, i , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate ==0) - printf(" key nr %i , ss %i has values %i(%c)\n", i, shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); + printf(" key nr %i , ss %i has values %i(%c)\n", i, shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); // If this was a deadkey, append a space if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, 49 ,kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - printf(" dk key nr %i , ss %i has values %i(%c)\n", i,shiftarray[j]+ 4*k, unicodeString[0],unicodeString[0] ); + status = UCKeyTranslate(keyboard_layout, keycode_spacebar , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + printf(" dk key nr %i , ss %i has values %i(%c)\n", i,shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); } } } } } -bool checkBasechar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) { +bool test_checkBasechar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) { return ( DK->KMX_GetBaseCharacter(index) == ch) ; } -bool checkCombchar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) { +bool test_checkCombchar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) { return ( DK->KMX_GetCombinedCharacter(index) == ch) ; } -bool test_alDead_S2(std::vector ald) { +bool test_alDead_S2(std::vector ald) { bool OK =true; - OK = OK && checkBasechar_S2(ald[0],0, 0x61); - OK = OK && checkBasechar_S2(ald[0],1, 0x41); - OK = OK && checkBasechar_S2(ald[0],14, 0x65); - OK = OK && checkBasechar_S2(ald[0],15, 0x45); - OK = OK && checkBasechar_S2(ald[0],23 ,0x69 ); - OK = OK && checkBasechar_S2(ald[0],24 ,0x49 ); - OK = OK && checkBasechar_S2(ald[0],19 ,0x6f ); - OK = OK && checkBasechar_S2(ald[0],20 ,0x4f ); - OK = OK && checkBasechar_S2(ald[0],21 ,0x75 ); - OK = OK && checkBasechar_S2(ald[0],22 ,0x55 ); - OK = OK && checkBasechar_S2(ald[0],27 ,0x20 ); - OK = OK && checkBasechar_S2(ald[0],28 ,0x20 ); - - OK = OK && checkCombchar_S2(ald[0],0, 0xe2); - OK = OK && checkCombchar_S2(ald[0],1, 0xc2); - OK = OK && checkCombchar_S2(ald[0],14 ,0xea); - OK = OK && checkCombchar_S2(ald[0],15, 0xca); - OK = OK && checkCombchar_S2(ald[0],23 ,0xee ); - OK = OK && checkCombchar_S2(ald[0],24 ,0xce ); - OK = OK && checkCombchar_S2(ald[0],19 ,0xf4 ); - OK = OK && checkCombchar_S2(ald[0],20 ,0xd4 ); - OK = OK && checkCombchar_S2(ald[0],21 ,0xfb ); - OK = OK && checkCombchar_S2(ald[0],22 ,0xdb ); - OK = OK && checkCombchar_S2(ald[0],27 ,0x5e ); - OK = OK && checkCombchar_S2(ald[0],28 ,0x5e ); - - OK = OK && checkBasechar_S2(ald[1],0, 0x61); - OK = OK && checkBasechar_S2(ald[1],1, 0x41); - OK = OK && checkBasechar_S2(ald[1],12, 0x65); - OK = OK && checkBasechar_S2(ald[1],13, 0x45); - OK = OK && checkBasechar_S2(ald[1],24 ,0x69 ); - OK = OK && checkBasechar_S2(ald[1],25 ,0x49 ); - OK = OK && checkBasechar_S2(ald[1],18 ,0x6f ); - OK = OK && checkBasechar_S2(ald[1],19 ,0x4f ); - OK = OK && checkBasechar_S2(ald[1],20 ,0x75 ); - OK = OK && checkBasechar_S2(ald[1],21 ,0x55 ); - OK = OK && checkBasechar_S2(ald[1],36 ,0x20 ); - OK = OK && checkBasechar_S2(ald[1],37 ,0x20 ); - - OK = OK && checkCombchar_S2(ald[1],0, 0xe2-1); - OK = OK && checkCombchar_S2(ald[1],1, 0xc2-1); - OK = OK && checkCombchar_S2(ald[1],12 ,0xea-1); - OK = OK && checkCombchar_S2(ald[1],13, 0xca-1); - OK = OK && checkCombchar_S2(ald[1],24 ,0xee -1); - OK = OK && checkCombchar_S2(ald[1],25 ,0xce -1); - OK = OK && checkCombchar_S2(ald[1],18 ,0xf4 -1); - OK = OK && checkCombchar_S2(ald[1],19 ,0xd4 -1); - OK = OK && checkCombchar_S2(ald[1],20 ,0xfb -1); - OK = OK && checkCombchar_S2(ald[1],21 ,0xdb -1); - OK = OK && checkCombchar_S2(ald[1],36 ,0xb4 ); - OK = OK && checkCombchar_S2(ald[1],37 ,0xb4 ); - - OK = OK && checkBasechar_S2(ald[2],0, 0x61); - OK = OK && checkBasechar_S2(ald[2],1, 0x41); - OK = OK && checkBasechar_S2(ald[2],6, 0x65); - OK = OK && checkBasechar_S2(ald[2],7, 0x45); - OK = OK && checkBasechar_S2(ald[2],12 ,0x69 ); - OK = OK && checkBasechar_S2(ald[2],13 ,0x49 ); - OK = OK && checkBasechar_S2(ald[2],8 ,0x6f ); - OK = OK && checkBasechar_S2(ald[2],9 ,0x4f ); - OK = OK && checkBasechar_S2(ald[2],10 ,0x75 ); - OK = OK && checkBasechar_S2(ald[2],11 ,0x55 ); - OK = OK && checkBasechar_S2(ald[2],16 ,0x20 ); - OK = OK && checkBasechar_S2(ald[2],17 ,0x20 ); - - OK = OK && checkCombchar_S2(ald[2],0, 0xe2-2); - OK = OK && checkCombchar_S2(ald[2],1, 0xc2-2); - OK = OK && checkCombchar_S2(ald[2],6 ,0xea-2); - OK = OK && checkCombchar_S2(ald[2],7, 0xca-2); - OK = OK && checkCombchar_S2(ald[2],12 ,0xee -2); - OK = OK && checkCombchar_S2(ald[2],13 ,0xce -2); - OK = OK && checkCombchar_S2(ald[2],8 ,0xf4 -2); - OK = OK && checkCombchar_S2(ald[2],9 ,0xd4 -2); - OK = OK && checkCombchar_S2(ald[2],10 ,0xfb -2); - OK = OK && checkCombchar_S2(ald[2],11 ,0xdb -2); - OK = OK && checkCombchar_S2(ald[2],16 ,0x60 ); - OK = OK && checkCombchar_S2(ald[2],17 ,0x60 ); + OK = OK && test_checkBasechar_S2(ald[2],0, 0x61); + OK = OK && test_checkBasechar_S2(ald[2],1, 0x41); + OK = OK && test_checkBasechar_S2(ald[2],14, 0x65); + OK = OK && test_checkBasechar_S2(ald[2],15, 0x45); + OK = OK && test_checkBasechar_S2(ald[2],23 ,0x69 ); + OK = OK && test_checkBasechar_S2(ald[2],24 ,0x49 ); + OK = OK && test_checkBasechar_S2(ald[2],19 ,0x6f ); + OK = OK && test_checkBasechar_S2(ald[2],20 ,0x4f ); + OK = OK && test_checkBasechar_S2(ald[2],21 ,0x75 ); + OK = OK && test_checkBasechar_S2(ald[2],22 ,0x55 ); + OK = OK && test_checkBasechar_S2(ald[2],27 ,0x20 ); + OK = OK && test_checkBasechar_S2(ald[2],28 ,0x20 ); + + OK = OK && test_checkCombchar_S2(ald[2],0, 0xe2); + OK = OK && test_checkCombchar_S2(ald[2],1, 0xc2); + OK = OK && test_checkCombchar_S2(ald[2],14 ,0xea); + OK = OK && test_checkCombchar_S2(ald[2],15, 0xca); + OK = OK && test_checkCombchar_S2(ald[2],23 ,0xee ); + OK = OK && test_checkCombchar_S2(ald[2],24 ,0xce ); + OK = OK && test_checkCombchar_S2(ald[2],19 ,0xf4 ); + OK = OK && test_checkCombchar_S2(ald[2],20 ,0xd4 ); + OK = OK && test_checkCombchar_S2(ald[2],21 ,0xfb ); + OK = OK && test_checkCombchar_S2(ald[2],22 ,0xdb ); + OK = OK && test_checkCombchar_S2(ald[2],27 ,0x5e ); + OK = OK && test_checkCombchar_S2(ald[2],28 ,0x5e ); + + OK = OK && test_checkBasechar_S2(ald[0],0, 0x61); + OK = OK && test_checkBasechar_S2(ald[0],1, 0x41); + OK = OK && test_checkBasechar_S2(ald[0],12, 0x65); + OK = OK && test_checkBasechar_S2(ald[0],13, 0x45); + OK = OK && test_checkBasechar_S2(ald[0],24 ,0x69 ); + OK = OK && test_checkBasechar_S2(ald[0],25 ,0x49 ); + OK = OK && test_checkBasechar_S2(ald[0],18 ,0x6f ); + OK = OK && test_checkBasechar_S2(ald[0],19 ,0x4f ); + OK = OK && test_checkBasechar_S2(ald[0],20 ,0x75 ); + OK = OK && test_checkBasechar_S2(ald[0],21 ,0x55 ); + OK = OK && test_checkBasechar_S2(ald[0],36 ,0x20 ); + OK = OK && test_checkBasechar_S2(ald[0],37 ,0x20 ); + + OK = OK && test_checkCombchar_S2(ald[0],0, 0xe2-1); + OK = OK && test_checkCombchar_S2(ald[0],1, 0xc2-1); + OK = OK && test_checkCombchar_S2(ald[0],12 ,0xea-1); + OK = OK && test_checkCombchar_S2(ald[0],13, 0xca-1); + OK = OK && test_checkCombchar_S2(ald[0],24 ,0xee -1); + OK = OK && test_checkCombchar_S2(ald[0],25 ,0xce -1); + OK = OK && test_checkCombchar_S2(ald[0],18 ,0xf4 -1); + OK = OK && test_checkCombchar_S2(ald[0],19 ,0xd4 -1); + OK = OK && test_checkCombchar_S2(ald[0],20 ,0xfb -1); + OK = OK && test_checkCombchar_S2(ald[0],21 ,0xdb -1); + OK = OK && test_checkCombchar_S2(ald[0],36 ,0xb4 ); + OK = OK && test_checkCombchar_S2(ald[0],37 ,0xb4 ); + + OK = OK && test_checkBasechar_S2(ald[1],0, 0x61); + OK = OK && test_checkBasechar_S2(ald[1],1, 0x41); + OK = OK && test_checkBasechar_S2(ald[1],6, 0x65); + OK = OK && test_checkBasechar_S2(ald[1],7, 0x45); + OK = OK && test_checkBasechar_S2(ald[1],12 ,0x69 ); + OK = OK && test_checkBasechar_S2(ald[1],13 ,0x49 ); + OK = OK && test_checkBasechar_S2(ald[1],8 ,0x6f ); + OK = OK && test_checkBasechar_S2(ald[1],9 ,0x4f ); + OK = OK && test_checkBasechar_S2(ald[1],10 ,0x75 ); + OK = OK && test_checkBasechar_S2(ald[1],11 ,0x55 ); + OK = OK && test_checkBasechar_S2(ald[1],16 ,0x20 ); + OK = OK && test_checkBasechar_S2(ald[1],17 ,0x20 ); + + OK = OK && test_checkCombchar_S2(ald[1],0, 0xe2-2); + OK = OK && test_checkCombchar_S2(ald[1],1, 0xc2-2); + OK = OK && test_checkCombchar_S2(ald[1],6 ,0xea-2); + OK = OK && test_checkCombchar_S2(ald[1],7, 0xca-2); + OK = OK && test_checkCombchar_S2(ald[1],12 ,0xee -2); + OK = OK && test_checkCombchar_S2(ald[1],13 ,0xce -2); + OK = OK && test_checkCombchar_S2(ald[1],8 ,0xf4 -2); + OK = OK && test_checkCombchar_S2(ald[1],9 ,0xd4 -2); + OK = OK && test_checkCombchar_S2(ald[1],10 ,0xfb -2); + OK = OK && test_checkCombchar_S2(ald[1],11 ,0xdb -2); + OK = OK && test_checkCombchar_S2(ald[1],16 ,0x60 ); + OK = OK && test_checkCombchar_S2(ald[1],17 ,0x60 ); return OK; } -bool run_verify_S2(std::vector rgKey) { +bool test_run_verify_S2(std::vector rgKey) { bool allOK= true; allOK = verify_entries_S2(48, rgKey, 48,48,61,61) && allOK; diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h index c76585fab19..5e544545527 100755 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -2,11 +2,10 @@ #ifndef MC_IMPORT_RULES_H #define MC_IMPORT_RULES_H -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ -int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps,const UCKeyboardLayout * keyboard_layout); +// _S2 CHECKED OK +int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps, const UCKeyboardLayout * keyboard_layout); +// _S2 CHECKED OK class DeadKey { private: KMX_WCHAR m_deadchar; diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index 0c2d2cb70da..eae54edf4aa 100755 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -205,7 +205,7 @@ KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL return CERR_SomewhereIGotItWrong; } - fwrite(buf, size,1,hOutfile); + fwrite(buf, size,1, hOutfile); if(offset != size) { delete[] buf; diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index 57395b492c2..a284b88991d 100755 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -6,7 +6,7 @@ #include "km_types.h" #include "kmx_file.h" -#include "filesystem.h" +#include "util_filesystem.h" //_S2 TODO include from keyman; not from this folder #include "mcompile.h" @@ -82,6 +82,3 @@ KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL #endif //MC_KMXFILE_H -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index dfbe49983b0..53afeef9efb 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -31,7 +31,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc, char *argv[]); -bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout,std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 +bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout, std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 std::vector KMX_FDeadkeys; // I4353 @@ -128,7 +128,6 @@ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NU return 3; } - #if defined(_WIN32) || defined(_WIN64) //Windows if(DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); @@ -150,11 +149,6 @@ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NU return 0; } - -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ -// _S2 _84 // Map of all shift states that we will work with const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCTRLFLAG|RALTFLAG, 0xFFFF}; @@ -165,7 +159,6 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCT // correct shift state and key. Adjust the LCTRL+RALT -> RALT if necessary // void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { - //_S2 do we translate here or is this the reason for Shift + K_A <-> Shift 'a' ??? // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. @@ -175,7 +168,7 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) if(key->ShiftFlags == 0 && key->Key == ch) { // Key is a mnemonic key with no shift state defined. // Remap the key according to the character on the key cap. - //mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO + [%x K_%d]", key->Line, key->Key, shift, vk);// 1 + // mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO + [%x K_%d]", key->Line, key->Key, shift, vk);// 1 key->ShiftFlags = ISVIRTUALKEY | shift; key->Key = vk; } else if(key->ShiftFlags & VIRTUALCHARKEY && key->Key == ch) { @@ -184,7 +177,7 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) // This will not result in 100% wonderful mappings as there could // be overlap, depending on how keys are arranged on the target layout. // But that is up to the designer. - //mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, key->ShiftFlags & ~VIRTUALCHARKEY, vk); + // mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, key->ShiftFlags & ~VIRTUALCHARKEY, vk); key->ShiftFlags &= ~VIRTUALCHARKEY; key->Key = vk; } @@ -227,8 +220,6 @@ void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { } void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { -// _S2 TOP_2 INFO this produces a different output due to different layouts for Lin<-> win ( for the same language!!) - if((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" @@ -257,7 +248,7 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, } } -void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group,KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { +void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { for(unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_TranslateDeadkeyKey(&group->dpKeyArray[i], deadkey, vk, shift, ch); } @@ -376,15 +367,13 @@ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_ // Lookup the deadkey table for the deadkey in the physical keyboard // Then for each character, go through and map it through KMX_WCHAR dkid = mac_KMX_GetUniqueDeadkeyID(kbd, deadkey); - // Add the deadkey to the mapping table for use in the import rules phase KMX_DeadkeyMapping KMX_deadkeyMapping = { deadkey, dkid, shift, vk_US}; // I4353 KMX_FDeadkeys.push_back(KMX_deadkeyMapping); //dkid, vk, shift); // I4353 mac_KMX_AddDeadkeyRule(kbd, dkid, vk_US, shift); - // creates array [a,e,i,o,u][shiftstate][combined for a+dk e.g. â ] - mac_KMX_GetDeadkeys( deadkey, shift, pdk = deadkeys, All_Vector, keyboard_layout); // returns array of [usvk, ch_out] pairs + mac_KMX_GetDeadkeys(keyboard_layout, All_Vector, deadkey, shift, pdk = deadkeys ); // returns array of [usvk, ch_out] pairs while(*pdk) { // Look up the ch @@ -415,6 +404,13 @@ KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { return FALSE; } + + + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc, char *argv[]) { KMX_WCHAR DeadKey=0; @@ -427,34 +423,62 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int // evident for the 102nd key on UK, for example, where \ can be generated with VK_OEM_102 or AltGr+VK_QUOTE. // For now, we get the least shifted version, which is hopefully adequate. - // _S2 : Sadly it`s not: on a German WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only. - // on a German MAC keyboard one will get '~' with either OPT + K_221(+) or OPT + K_84(T) or CAPS + OPT + K_78(N) - // K_84 will be caught first, so one of the the least obvious version for creating the '~' is found and processed. - - // -> meeting with Marc May 21 2024: We leave it as it is for now; it is OK if different combinations are found. + // Sadly it`s not: on a German WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only which is the usual combination to get ~. + // on a German MAC keyboard one will get '~' with either OPT + K_221(+) or OPT + K_84(T) or CAPS + OPT + K_78(N) + // K_84(T) will be caught first, so one of the the least obvious version for creating the '~' is found and processed. + // -> meeting with Marc May 21 2024: We leave it as it is; it is OK if different combinations are found. const UCKeyboardLayout* keyboard_layout; if(mac_InitializeUCHR(&keyboard_layout)) { wprintf(L"ERROR: can't Initialize GDK\n"); return FALSE; } - // create vector that contains Keycode, base, shift for US-Keyboard and underlying keyboard + // create vector that contains Keycode, Base, Shift for US-Keyboard and underlying keyboard v_dw_3D All_Vector; if(mac_createOneVectorFromBothKeyboards(All_Vector, keyboard_layout)){ wprintf(L"ERROR: can't create one vector from both keyboards\n"); return FALSE; } - // _S2 which shiftstates?? + //printoutKeyboards(All_Vector); + +print_character_of_key_S2(keyboard_layout, 40); +print_character_of_key_S2(keyboard_layout, 43); +print_character_of_key_S2(keyboard_layout, 24); +print_character_of_key_S2(keyboard_layout, 42); +print_character_of_key_S2(keyboard_layout, 39); +print_character_of_key_S2(keyboard_layout, 44); + +//DE: comma +find_character_S2(keyboard_layout, 44); +//DE: equal +find_character_S2(keyboard_layout, 39); +find_character_S2(keyboard_layout, 45); + + +//FR: BKSLASH +print_character_of_key_S2(keyboard_layout, 10); +print_character_of_key_S2(keyboard_layout, 42); +find_character_S2(keyboard_layout, 35); +find_character_S2(keyboard_layout, 64); + + +//ES HYPHEN +print_character_of_key_S2(keyboard_layout, 43); +print_character_of_key_S2(keyboard_layout, 39); +print_character_of_key_S2(keyboard_layout, 27); +find_character_S2(keyboard_layout, 180); +printf("-------\n"); +print_dublicates_S2(keyboard_layout); +//find_double_keys(keyboard_layout,1); for (int j = 0; VKShiftState[j] != 0xFFFF; j++) { // I4651 // Loop through each possible key on the keyboard for (int i = 0;KMX_VKMap[i]; i++) { // I4651 // windows uses VK, Linux and macOS use SC/Keycode - // _S2 ToDo unused vk`s ?? UINT scUnderlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_VKMap[i]); - KMX_WCHAR ch = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, VKShiftState[j], scUnderlying, &DeadKey); + KMX_WCHAR ch = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, scUnderlying, VKShiftState[j], &DeadKey); //wprintf(L"--- VK_%d -> SC_ [%c] dk=%d ( ss %i) \n", KMX_VKMap[i], ch == 0 ? 32 : ch, DeadKey, VKShiftState[j]); @@ -464,7 +488,6 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int } } - // _S2 ?5E OK till here switch(ch) { case 0x0000: break; case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout); break; @@ -472,7 +495,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int } } } - // _S2 ToDo non-dk OK,shifted dk are not?? + mac_KMX_ReportUnconvertedKeyboardRules(kbd); if(!mac_KMX_ImportRules(kbd, All_Vector, &keyboard_layout, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 @@ -481,54 +504,36 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int return TRUE; } +int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ) { -int mac_KMX_GetDeadkeys( KMX_WCHAR DeadKey, UINT shift_dk, KMX_WORD *OutputPairs, v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { - + UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; + OptionBits keyTranslateOptions = 0; UniChar unicodeString[maxStringlength]; - KMX_WORD *p = OutputPairs; - UInt32 deadkeystate = 0; OSStatus status; - KMX_WORD shift[4] ={0,2,8,10}; - - KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying( All_Vector, (KMX_DWORD) DeadKey); - - /*// _S2 - // we go in this order because we need to make sure that the most obvious keycombination is taken into account for deadkeys. - // This is important since it catches only the first key that matches a given rule, but multiple keys may match that rule. - // (see explanation in mcompile.cpp DoConvert() ) - // space is the most important one for deadkeys, so we start with Space (Keycode 49) - // then character keys in alphabetical order, then numbers, then punctuation keys - - // SPACE, A_Z, 0-9, VK_ACCENT,HYPHEN,EQUAL,LBRKT,RBRKT,BKSLASH,COLON,QUOTE,COMMA,PERIOD,SLASH,xDF,OEM_102 - int keyarray[] ={ - 49, - 0, 11, 8, 2, 14, 3, 5, 4, 34, 38, 40, 37, 46, 45, 31, 35, 12, 15, 1, 17, 32, 9, 13, 7, 16, 6, - 29, 18, 19, 20, 21, 23, 22, 26, 28, 25, - 42, 27, 24, 33, 30, 42, 41, 39, 43, 47, 44, 223, 226, 0xFFFF - };*/ + unicodeString[0] = 0; - for ( int j=0; j < sizeof(shift)/sizeof(shift[0]); j++) { - -// _S2 _84 - // we start calculating SPACE(49) since most obvious deadkeys combinations use space. - // _S2 for (int i = 0; keyarray[i] != 0xFFFF; i++) { - for ( int i=Keycode_Spacebar; i >=0; i--) { + KMX_WORD *p = OutputPairs; + KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying( All_Vector, deadkey); - status = UCKeyTranslate(keyboard_layout, sc_dk ,kUCKeyActionDown, mac_map_VKShiftState_to_MacModifier(shift_dk), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + for ( int j=0; j < sizeof(ss_mac)/sizeof(ss_mac[0]); j++) { + // we start with SPACE (keycode_spacebar=49) since all deadkeys occur in combinations with space. + // Since mcompile finds only the first occurance of a dk combination, this makes sure that we always find the dk+SPACE combinations for a deadkey. + // If there are more combinations to create a specific character they will not be found. (See comment at the beginning of mac_KMX_DoConvert()) + for ( int i=keycode_spacebar; i >=0; i--) { + status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_map_VKShiftState_to_MacModifier(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { - // _S2 status = UCKeyTranslate(keyboard_layout, keyarray[i] ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - status = UCKeyTranslate(keyboard_layout, i ,kUCKeyActionDown, shift[j], LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + status = UCKeyTranslate(keyboard_layout, i, kUCKeyActionDown, ss_mac[j], LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { - // _S2 KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, keyarray[i], 1); - KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, i, 1); - // _S2 to not get combinations like ^a but only combined characters like â ( exception for ^+space) - if((unicodeString[0] != DeadKey) || (vk == 32)) { + KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, i, ss_mac[1]); + + // ensure to not get key combinations like ^a but only combined characters like â ( exception for ^+space) + if((unicodeString[0] != deadkey) || (vk == 32)) { *p++ = vk; - *p++ = shift[j]; + *p++ = ss_mac[j]; *p++ =unicodeString[0]; } } @@ -586,16 +591,97 @@ bool test_dk_find_entries_S2(KMX_WORD deadkeys[512], int search) { return true; } } - return false; + return false; } bool test_dk_write_entries_S2(KMX_WORD deadkeys[512]) { for ( int i=0; i< 512/3;i++) { if ( deadkeys[3*i] !=0) - printf(" %i set nr \t%i: %i\t-\t%i(%c)\t-\t%i(%c) \n",deadkeys[2] ,i,deadkeys[3*i+1], deadkeys[3*i],deadkeys[3*i],deadkeys[3*i+2],deadkeys[3*i+2]); + printf(" %i set nr \t%i: %i\t-\t%i(%c)\t-\t%i(%c) \n", deadkeys[2], i,deadkeys[3*i+1], deadkeys[3*i], deadkeys[3*i], deadkeys[3*i+2], deadkeys[3*i+2]); } return true; } +bool find_print_character_S2(const UCKeyboardLayout * keyboard_layout, int keyval, int k, int c, int s) { + int ss_rgkey; +int count =0; +bool moreval=false; + std::vector res_vec; + + for ( int key=0; key< 50;key++) { + for ( int caps=0; caps< 2;caps++) { + for ( int ss=0; ss< 10;ss++) { + + if( ss == 0 ) ss_rgkey= 0; + else if( ss == 2 ) ss_rgkey= 1; + else if( ss == 8 ) ss_rgkey= 6; + else if( ss == 10 ) ss_rgkey= 7; + else ss_rgkey= 999; +if( (ss==1) || (ss==3) || (ss==5) || (ss==7) || (ss==9) ) +continue; + + int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, ss, caps); + + count++; + if((ss_rgkey!= 999 )&& ( keyval!= 0)&& ( keyval== keyvalsearch)&& ( count>1)&& ( key!=k)) { + printf( " key: %i, ss_mac: %i ( ss_rgkey:%i), caps:%i \n",key, ss, ss_rgkey, caps); + moreval=true; + } + } + } + } + return moreval; +} +bool print_dublicates_S2(const UCKeyboardLayout * keyboard_layout){ + for ( int key=0; key< 50;key++) { + for ( int caps=0; caps< 2;caps++) { + for ( int ss=0; ss< 6;ss++) { + int keyval= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, 2*ss, caps); + if (find_print_character_S2(keyboard_layout, keyval, key,caps,ss) && (keyval>0)) { + printf( "Keyval %i(%c): can be found on : \tkey: %i, ss-mac: %i caps:%i\t:\n---------------------------------------------------------\n",keyval,keyval, key, 2*ss,caps); + } + } + } + } + + + return true; +} +bool print_character_of_key_S2(const UCKeyboardLayout * keyboard_layout, int key) { +int ss_rgkey; + for ( int ss=0; ss< 6;ss++) { + for ( int caps=0; caps< 2;caps++) { + + int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, 2*ss, caps); + printf( " key %i has values : %i (%c) ( ss:%i, caps:%i) \n", key, keyvalsearch,keyvalsearch, 2*ss, caps); + } + } + return true; +} +bool find_character_S2(const UCKeyboardLayout * keyboard_layout, int keyval) { +int ss_rgkey; + for ( int ss=0; ss< 10;ss++) { + +if( ss == 0 ) ss_rgkey= 0; +else if( ss == 2 ) ss_rgkey= 1; +else if( ss == 8 ) ss_rgkey= 6; +else if( ss == 10 ) ss_rgkey= 7; +else ss_rgkey= 999; + +if( (ss==1) || (ss==3) || (ss==5) || (ss==7) || (ss==9) ) +continue; + + for ( int caps=0; caps< 2;caps++) { + for ( int key=0; key< 50;key++) { + int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, mac_map_Win_ShiftState_to_MacModifier(ss), caps); + if((ss_rgkey!= 999 )&& ( keyval== keyvalsearch)) + printf( " found keyval: key: %i, ss_mac:%i ( ss_rgkey:%i), caps:%i -> character: %i (%c) \n", key, ss, ss_rgkey, caps, keyvalsearch,keyvalsearch); + } + } + } + return true; +} + + //-------------------------- /*void fun2() { std::cout << "Hier ist fun2 von mcompile.cpp ...\n";} diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 6c941facb9a..d384cc38364 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -3,7 +3,8 @@ #include "keymap.h" #include -#include "deadkey.h" +#include +#include "mc_import_rules.h" #include "mc_kmxfile.h" /* @@ -34,30 +35,30 @@ struct KMX_DeadkeyMapping { // I4353 extern std::vector KMX_FDeadkeys; // I4353 +// _S2 CHECKED OK int mac_run(int argc, std::vector str_argv, char* argv[]); PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); +// _S2 CHECKED OK +int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ); // returns array of [usvk, ch_out] pairs -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - - - -int mac_KMX_GetDeadkeys( KMX_WCHAR deadkey, UINT shift, KMX_WORD *OutputPairs, v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout); // returns array of [usvk, ch_out] pairs - +// _S2 CHECKED OK void mac_KMX_LogError(const wchar_t* fmt, ...); //################################################################################################################################################ //################################################################################################################################################ +bool find_print_character_S2(const UCKeyboardLayout * keyboard_layout, int keyval, int k, int c, int s); +bool print_dublicates_S2(const UCKeyboardLayout * keyboard_layout); +bool print_character_of_key_S2(const UCKeyboardLayout * keyboard_layout, int key) ; +bool find_character_S2(const UCKeyboardLayout * keyboard_layout, int keyval) ; + bool test_dk_S2(KMX_WORD deadkeys[512], KMX_WORD deadkeys1[512]); bool test_dk_find_entries_S2(KMX_WORD deadkeys[512], int search); bool test_dk_write_entries_S2(KMX_WORD deadkeys[512]); - - void fun2(); void testmyFunctions_S2(); + #endif // MCOMPILE_H \ No newline at end of file diff --git a/mac/mcompile/mcompiletest.kmx b/mac/mcompile/mcompiletest.kmx deleted file mode 100755 index 4f9224998a830a6671c848c8b6b192bdccff877e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 526 zcmaix%Su8~6o!AD7$Jgm(P5xC^WXuaX=pQ><)Eo}!AqwT$1d2jG-&GE_yi4lh^FWXLP4n59|ps^ApXfh|`=<7Yfus=L%C2p8j+aCzfIHNPQ|J`c3FNR2R*eE-lff wgUw&;$hI3>cAyzIneEB=eM_C1SWnCztIpgW-OabTVXFVHAgs*~8k=R%4*`ZgvH$=8 diff --git a/mac/mcompile/u16.h b/mac/mcompile/u16.h index 7f18e03ec15..310f4e22bc4 100755 --- a/mac/mcompile/u16.h +++ b/mac/mcompile/u16.h @@ -8,6 +8,7 @@ #include #include "km_types.h" +// _S2 CHECKED_ std::vector convert_argvW_to_Vector_u16str(int argc, wchar_t* argv[]); std::vector convert_argv_to_Vector_u16str(int argc, char* argv[]); diff --git a/mac/mcompile/filesystem.cpp b/mac/mcompile/util_filesystem.cpp similarity index 84% rename from mac/mcompile/filesystem.cpp rename to mac/mcompile/util_filesystem.cpp index 459312448e7..7f9edd6b367 100755 --- a/mac/mcompile/filesystem.cpp +++ b/mac/mcompile/util_filesystem.cpp @@ -7,7 +7,7 @@ #include #include #include -#include "filesystem.h" +#include "util_filesystem.h" #ifdef _MSC_VER #include @@ -187,6 +187,41 @@ KMX_BOOL kmcmp_FileExists(const KMX_WCHAR* filename) { return FALSE; }; -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ + +bool IsRelativePath(KMX_CHAR const * p) { + // Relative path (returns TRUE): + // ..\...\BITMAP.BMP + // PATH\BITMAP.BMP + // BITMAP.BMP + + // Semi-absolute path (returns FALSE): + // \...\BITMAP.BMP + + // Absolute path (returns FALSE): + // C:\...\BITMAP.BMP + // \\SERVER\SHARE\...\BITMAP.BMP + + if ((*p == '\\') || (*p == '/')) return FALSE; + if (*p && *(p + 1) == ':') return FALSE; + + return TRUE; +} + +bool IsRelativePath(KMX_WCHAR const * p) { + // Relative path (returns TRUE): + // ..\...\BITMAP.BMP + // PATH\BITMAP.BMP + // BITMAP.BMP + + // Semi-absolute path (returns FALSE): + // \...\BITMAP.BMP + + // Absolute path (returns FALSE): + // C:\...\BITMAP.BMP + // \\SERVER\SHARE\...\BITMAP.BMP + + if ((*p == u'\\') || (*p == u'/'))return FALSE; + if (*p && *(p + 1) == u':') return FALSE; + + return TRUE; +} \ No newline at end of file diff --git a/mac/mcompile/util_filesystem.h b/mac/mcompile/util_filesystem.h new file mode 100755 index 00000000000..38877bf9f26 --- /dev/null +++ b/mac/mcompile/util_filesystem.h @@ -0,0 +1,16 @@ +#pragma once + +#include +//#include _S2 "../src/kmx_u16.h" we want to include this... +#include "u16.h" + +// Opens files on windows and non-windows platforms. Datatypes for Filename and mode must be the same. +// returns FILE* if file could be opened; FILE needs to be closed in calling function +FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); +FILE* Open_File(const KMX_WCHART* Filename, const KMX_WCHART* mode); +FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode); +KMX_BOOL kmcmp_FileExists(const KMX_CHAR *filename); +KMX_BOOL kmcmp_FileExists(const KMX_WCHAR *filename); + +bool IsRelativePath(KMX_CHAR const * p); +bool IsRelativePath(KMX_WCHAR const * p); \ No newline at end of file From 71a5226291d9ef4be338b067f4efeb7ea6a0eafd Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 7 Jun 2024 16:22:44 +0200 Subject: [PATCH 30/71] feat(mac): function header comments mcompile.cpp, mc_import_rules.cpp, keymap.cpp --- mac/mcompile/keymap.cpp | 355 +++++++++++++++++++++++-------- mac/mcompile/keymap.h | 113 +++------- mac/mcompile/mc_import_rules.cpp | 58 +++-- mac/mcompile/mc_import_rules.h | 2 - mac/mcompile/mcompile.cpp | 237 +++++++++++++++------ mac/mcompile/mcompile.h | 5 +- 6 files changed, 516 insertions(+), 254 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 8e0f43c4c3c..d75fe18d789 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -1,7 +1,19 @@ +/* + * Keyman is copyright (C) SIL International. MIT License. + * + * Keyboard reading and mapping for mac + */ + #include "keymap.h" -// mapping for Base,Shift,OPT,Shift+OPT from vk_ShiftState -> shiftstates UcKeyTranslate uses (0,2,8,10 - 4,6,12,14 with caps) -int mac_map_VKShiftState_to_MacModifier(int vk_ShiftState) { + /** + * @brief map shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on mac + * Windows: (Base: 00000000 (0); Shift 00010000 (16); AltGr 00001001 (9); Shift+AltGr 00011001 (25)) + * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10 ) + * @param vk_ShiftState shiftstate used on windows + * @return a shiftstate usable for UCKeyTranslate() on mac if available + */ +int mac_map_VKShiftState_to_Shiftstate(int vk_ShiftState) { if (vk_ShiftState == 0 ) return 0; else if (vk_ShiftState == 16) return 2; else if (vk_ShiftState == 9) return 8; @@ -9,37 +21,78 @@ int mac_map_VKShiftState_to_MacModifier(int vk_ShiftState) { else return vk_ShiftState; } -// mapping for Base,Shift,OPT,Shift+OPT from rgkey -> shiftstates UcKeyTranslate uses (0,2,8,10 - 4,6,12,14 with caps) -int mac_map_Win_ShiftState_to_MacModifier(int win_ShiftState) { - if (win_ShiftState == 0 ) return 0; - else if (win_ShiftState == 1) return 2; - else if (win_ShiftState == 6 ) return 8; - else if (win_ShiftState == 7) return 10; - else return win_ShiftState; + + /** + * @brief map shiftstate used for rgkey to shiftstate suitable for UCKeyTranslate() on mac + * rgkey: (Base: 0; Shift 1; OPT 6; Shift+OPT 7 ) + * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10) + * @param rgkey_ShiftState shiftstate used for rgkey + * @return int shiftstate usable for UCKeyTranslate() on mac if available + */ + int mac_map_rgkey_ShiftState_to_Shiftstate(int rgkey_ShiftState) { + if (rgkey_ShiftState == 0 ) return 0; + else if (rgkey_ShiftState == 1) return 2; + else if (rgkey_ShiftState == 6 ) return 8; + else if (rgkey_ShiftState == 7) return 10; + else return rgkey_ShiftState; } -/*bool is_correct_mac_shiftstate(int comp_ss) { - return ( (comp_ss ==0) || (comp_ss ==2) || (comp_ss ==8) || (comp_ss ==10) ); -}*/ -/*bool is_correct_rgkey_shiftstate(int comp_ss) { - return ( (comp_ss ==0) || (comp_ss ==1) || (comp_ss ==6) || (comp_ss ==7) ); -}*/ + /** + * @brief check if the shiftstate value can be used + * @param win_ss shiftstate used on windows + * @return true on success; false on failure + */ +bool is_correct_win_shiftstate(int win_ss) { + return ( (win_ss ==0) || (win_ss ==16) || (win_ss ==9) || (win_ss ==25) || (win_ss ==0xFFFF) ); +} + + + /** + * @brief check for correct input parameter + * What character will be produced for a keypress of a key and modifiers? + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @param keycode a key of the currently used keyboard Layout + * @param shiftstate a shiftstate of the currently used keyboard Layout + * @param caps state of the caps key of the currently used keyboard Layout + * @return true if all parameters are OK; false if not + */ +bool is_correct_Input_For_KeyboardTranslation(const UCKeyboardLayout * keyboard_layout,int keycode, int shiftstate, int caps=0){ + + if (!keyboard_layout) + return false; + + if (!(keycode <= keycode_max)) + return false; + + if (!(shiftstate <= max_shiftstate)) + return false; -bool is_correct_win_shiftstate(int comp_ss) { - return ( (comp_ss ==0) || (comp_ss ==16) || (comp_ss ==9) || (comp_ss ==25) || (comp_ss ==0xFFFF) ); + if (!(caps <= 1)) + return false; + +return true; } -int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { - // create a 3D-Vector which contains data of the US keyboard and the underlying Keyboard: - // All_Vector[ US_Keyboard ] - // [KeyCode_US ] - // [Keyval unshifted ] - // [Keyval shifted ] - // [Underlying Kbd] - // [KeyCode_underlying] - // [Keyval unshifted ] - // [Keyval shifted ] + + + + + /** + * @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard : + * All_Vector [ US_Keyboard ] + * [KeyCode_US ] + * [Keyval unshifted ] + * [Keyval shifted ] + * [Underlying Kbd] + * [KeyCode_underlying] + * [Keyval unshifted ] + * [Keyval shifted ] + * @param[out] All_Vector Vector that holds the data of the US keyboard as well as the currently used (underlying) keyboard + * @param keyboard_layout ptr to currently used (underlying) keyboard Layout + * @return 0 on success; 1 if data of US keyboard was not written; 2 if data of underlying keyboard was not written + */ +int mac_createOneVectorFromBothKeyboards(vector_dword_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { if(mac_write_US_ToVector(All_Vector)) { wprintf(L"ERROR: can't write US to Vector \n"); @@ -54,14 +107,20 @@ int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLa return 0; } -int mac_write_US_ToVector( v_dw_3D &vec) { - // Values for All_Vector: A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P,CR, L, J, ', K, ;, \, ,, /, N, M, . + /** + * @brief write data of the US keyboard into a 3D-Vector which later will contain data of the US keyboard and the currently used (underlying) keyboard + * @param[out] vec_us Vector that holds the date + * @return 0 on success; 1 if data of US keyboard was not written; + */ +int mac_write_US_ToVector( vector_dword_3D &vec_us) { + + // Values for US : A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P,CR, L, J, ', K, ;, \, ,, /, N, M, . std::vector us_Base = {97,115,100,102,104,103,122,120,99,118,167,98,113,119,101,114,121,116,49,50,51,52,54,53,61,57,55,45,56,48, 93,111,117, 91,105,112,13,108,106,39,107,59, 92,44,47,110,109,46}; std::vector us_Shift = {65, 83, 68, 70, 72, 71, 90, 88,67, 86,177,66, 81, 87, 69, 82, 89, 84,33,64,35,36,94,37,43,40,38,95,42,41,125, 79, 85,123, 73, 80,13, 76, 74,34, 75,58,124,60,63, 78, 77,62}; - v_dw_1D values; - v_dw_2D key; + vector_dword_1D values; + vector_dword_2D key; for ( int i=0; i< us_Base.size(); i++) { values.push_back(i); @@ -70,7 +129,7 @@ int mac_write_US_ToVector( v_dw_3D &vec) { key.push_back(values); values.clear(); } - vec.push_back(key); + vec_us.push_back(key); if ( key.size() == 0) { wprintf(L"ERROR: can't Create Vector for US keyboard\n"); @@ -80,25 +139,42 @@ int mac_write_US_ToVector( v_dw_3D &vec) { return 0; } -v_dw_2D mac_create_empty_2D_Vector( int dim_rows, int dim_ss) { - v_dw_1D shift; - v_dw_2D vector_2D; + /** + * @brief create an 2D-Vector with all fields containing returnIfCharInvalid + * @param dim_rows number of rows in vector + * @param dim_cols number of columns in vector + * @return the 2D-Vector + */ + +vector_dword_2D mac_create_empty_2D_Vector( int dim_rows, int dim_cols) { + + vector_dword_1D shift; + vector_dword_2D vector_2D; + + for ( int j=0; j< dim_cols;j++) { + shift.push_back(INVALID_NAME); + } for ( int i=0; i< dim_rows;i++) { - for ( int j=0; j< dim_ss;j++) { - shift.push_back(returnIfCharInvalid); - } vector_2D.push_back(shift); - shift.clear(); } + shift.clear(); // _S2 needed?? return vector_2D; } -int mac_append_underlying_ToVector(v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { + /** + * + * @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector + * @param[out] All_Vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param keyboard_layout ptr to currently used (underlying) keyboard Layout + * @return 0 on success; 1 if the initialization of the underlying vector failes; 2 if data of less than 2 keyboards is contained in All_Vector + */ +int mac_append_underlying_ToVector(vector_dword_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { + int caps=0; // create a 2D vector all filled with " " and push to 3D-Vector - v_dw_2D underlying_Vector2D = mac_create_empty_2D_Vector(All_Vector[0].size(), All_Vector[0][0].size()); + vector_dword_2D underlying_Vector2D = mac_create_empty_2D_Vector(All_Vector[0].size(), All_Vector[0][0].size()); if (underlying_Vector2D.size() == 0) { wprintf(L"ERROR: can't create empty 2D-Vector\n"); @@ -116,13 +192,21 @@ int mac_append_underlying_ToVector(v_dw_3D &All_Vector, const UCKeyboardLayout * // get key name US stored in [0][i][0] and copy to name in "underlying"-block[1][i][0] All_Vector[1][i][0] = All_Vector[0][i][0]; - All_Vector[1][i][0+1] = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, All_Vector[0][i][0], mac_map_Win_ShiftState_to_MacModifier(0)); //shift state: unshifted:0 - All_Vector[1][i][1+1] = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, All_Vector[0][i][0], mac_map_Win_ShiftState_to_MacModifier(1)); //shift state: shifted:1 + for( int k=0; k<2;k++) { + All_Vector[1][i][k+1] = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, All_Vector[0][i][0], mac_map_rgkey_ShiftState_to_Shiftstate(k),0); + } } return 0; } + + /** + * + * @brief create a pointer to the current keyboard layout + * @param[out] keyboard_layout* ptr to currently used (underlying) keyboard Layout + * @return 0 on success; 1 if the source is not found; 2 if the keyboard layout is not found + */ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); @@ -141,10 +225,16 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { return 0; } -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ -// _S2 checked OK + + /** + * @brief return the keyvalue for a given Keycode, shiftstate and caps of the currently used (underlying) keyboard Layout + * What character will be produced for a keypress of a key and modifiers? + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @param keycode a key of the currently used keyboard Layout + * @param shiftstate_mac a shiftstate of the currently used keyboard Layout + * @param caps state of the caps key of the currently used keyboard Layout + * @return the keyval obtained from Keycode, shiftstate and caps + */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps) { UInt32 deadkeystate; @@ -155,7 +245,7 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layo OSStatus status ; unicodeString[0] = 0; - if (!keyboard_layout) + /*if (!keyboard_layout) return 0; if (!(keycode <= keycode_max)) @@ -165,8 +255,12 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layo return 0; if (!(caps <= 1)) + return 0;*/ + + if(! is_correct_Input_For_KeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) return 0; + status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); // If this was a deadkey,append a space if(deadkeystate !=0) @@ -181,8 +275,19 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layo return 0; } -//--------------------------------------------------- -// _S2 checked OK + + + /** + * + * @brief return the keyvalue for a given Keycode, shiftstate and caps of the currently used (underlying) keyboard Layout taking the deadkeystate into account + * What character or deadkey will be produced for a keypress of a key and modifiers? + * @param keyboard_layout* ptr to currently used keyboard Layout + * @param keycode a key of the currently used keyboard + * @param shiftstate_mac a shiftstate of the currently used keyboard Layout + * @param caps state of the caps key of the currently used keyboard Layout + * @param[out] deadkeystate !=0 if a deadkey was found in translation; 0 if no deadkey was found + * @return the keyval obtained from Keycode, shiftstate and caps + */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32 &deadkeystate) { UniCharCount maxStringlength = 5; @@ -192,7 +297,7 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_l unicodeString[0] = 0; OSStatus status; - if (!keyboard_layout) + /*if (!keyboard_layout) return 0; if (!(keycode <= keycode_max)) @@ -202,8 +307,10 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_l return 0; if (!(caps <= 1)) - return 0; + return 0;*/ + if(! is_correct_Input_For_KeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) + return 0; // if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown,(shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); @@ -218,27 +325,17 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_l return unicodeString[0]; // combined char e.g. â } -//--------------------------------------------------- -// _S2 checked OK -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int kc_underlying, int shiftstate_mac) { - KMX_DWORD kVal; - int caps=0; - if (!keyboard_layout) - return 0; - - if (!(kc_underlying <= keycode_max)) - return 0; - - if (!(shiftstate_mac <= max_shiftstate)) - return 0; - - kVal = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_underlying, mac_map_Win_ShiftState_to_MacModifier(shiftstate_mac), caps); - - return kVal; -} -//--------------------------------------------------- -// _S2 checked OK + /** + * + * @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard Layout. If a deadkey was found return 0xFFFF and copy deadkey into deadKey + * What character will be produced for a keypress of a key and modifiers on the underlying keyboard? 0XFFFF in case of a deadkey? + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @param kc_underlying a key of the currently used keyboard + * @param vk_ShiftState a shiftstate of the currently used keyboard Layout + * @param deadKey* ptr to keyvalue if a deadkey was found; if not NULL + * @return the keyval obtained from Keycode and shiftstate and caps or 0xFFFF in case a deadkey was found + */ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey) { PKMX_WCHAR dky = NULL; @@ -246,16 +343,20 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa KMX_DWORD keyV; int caps = 0; - if (!keyboard_layout) + /*if (!keyboard_layout) return 0; if(!(is_correct_win_shiftstate(vk_ShiftState))) return 0; if (!(kc_underlying <= keycode_max)) - return 0; + return 0;*/ + + if(! is_correct_Input_For_KeyboardTranslation(keyboard_layout, kc_underlying, is_correct_win_shiftstate(vk_ShiftState))) + return 0; - keyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, kc_underlying,(mac_map_VKShiftState_to_MacModifier(vk_ShiftState)), caps, isdk); + + keyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, kc_underlying,(mac_map_VKShiftState_to_Shiftstate(vk_ShiftState)), caps, isdk); // if there was a deadkey return 0xFFFF and copy deadkey into dky if( isdk !=0) { @@ -266,10 +367,19 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa *deadKey = 0; return keyV; } -//--------------------------------------------------- -// _S2 checked OK -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD kv_us) { + + /** + * + * @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard + * What character is on the same position/shiftstats/caps on the currently used (underlying) keyboard? + * @param All_Vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param kv_us a keyvalue on the US keyboard + * @return keyval of the underlying keyboard if available; else the keyval of the US keyboard + */ +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vector_dword_3D & All_Vector, KMX_DWORD kv_us) { + + // look for kv_us for any shiftstate of US keyboard for( int i=0; i< All_Vector[0].size()-1 ;i++) { for( int j=1; j< All_Vector[0][0].size();j++) { if ( All_Vector[0][i][j] == kv_us ) @@ -278,9 +388,19 @@ KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_D } return kv_us; } -// _S2 checked OK -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vector, KMX_DWORD kv_underlying) { + +/** + * + * @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard + * On what key of the underlying keyboard do we find a certain character? + * @param All_Vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param kv_underlying a keyvalue on the currently used (underlying) keyboard + * @return keycode of the underlying keyboardif foundf; else the keyval of the underlying keyboard + */ +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vector_dword_3D & All_Vector, KMX_DWORD kv_underlying) { + + // look for kv_us for any shiftstate of US keyboard for( int i=0; i< All_Vector[1].size()-1 ;i++) { for( int j=1; j< All_Vector[1][0].size();j++) { if ( All_Vector[1][i][j] == kv_underlying ) { @@ -290,32 +410,73 @@ KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vect } return kv_underlying; } -// _S2 checked OK -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_DWORD kc_us, ShiftState ss, int caps) { - std::u16string u16str_map= std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_map_Win_ShiftState_to_MacModifier(ss), caps) ); + /** + * + * @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard + * Where on a underlying keyboard do we find a character that is on a certain key on a US keyboard? + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @param All_Vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param kc_us a key of the US keyboard + * @param ss_win a windows-type shiftstate + * @param caps state of the caps key + * @return the keycode of the underlying keyboardif found; else the keycode of the US keyboard + */ +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, vector_dword_3D &All_Vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) { + + // first get the keyvalue of the key on the US keyboard (kc_us) + std::u16string keyval_us= std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_map_rgkey_ShiftState_to_Shiftstate(ss_win), caps) ); + + // then find the same keyvalue on the underlying keyboard and return the keycode of that key on the underlying keyboard for( int i=0; i< All_Vector[1].size()-1 ;i++) { for( int j=1; j< All_Vector[1][0].size();j++) { - if ( ((KMX_DWORD) All_Vector[1][i][j] == (KMX_DWORD) *u16str_map.c_str() ) ) + if ( ((KMX_DWORD) All_Vector[1][i][j] == (KMX_DWORD) *keyval_us.c_str() ) ) return All_Vector[1][i][0]; } } return kc_us; } -// _S2 checked OK + + + /** + * + * @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard + * Which keycode of a underlying keyboard will be mapped to a virtuaĺ key of a US keyboard + * @param vk_us a virtual key of the US keyboard + * @return the keycode of the currently used (underlying) keyboard + */ UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us) { + // On mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an 'artificial' us virtual key return (mac_USVirtualKeyToScanCode[vk_us]); } -// _S2 checked OK + + + /** + * + * @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard + * Which key of a underlying keyboard will be mapped to a virtual key of a US keyboard + * @param keycode a keycode of the currently used (underlying) keyboard + * @return the virtual key of the US keyboard + */ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { + // On mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an keycode from an 'artificial' us virtual key return mac_ScanCodeToUSVirtualKey[keycode]; } -//################################################################################################################################################ -//################################################################################################################################################ -// _S2 checked_OK + /** + * + * @brief return the keyvalue of a combination of deadkey + character if there is a combination available + * What character will be produced for a deadkey + a character? + * @param vk_dk a keycode of a deadkey on the currently used (underlying) keyboard + * @param ss a shiftstate of a deadkey on the currently used (underlying) keyboard + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @param vk_us a keycode of a character key on the currently used (underlying) keyboard + * @param shiftstate_mac a shiftstate of a character key on the currently used (underlying) keyboard + * @param caps state of the caps key of a character key on the currently used (underlying) keyboard + * @return the combination of deadkey + character if it is available; if not return 0 + */ KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps) { UInt32 deadkeystate; @@ -341,7 +502,12 @@ KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyb return 0; } -void test_printoutKeyboards_S2(v_dw_3D &All_Vector) { + +//################################################################################################################################################ +//################################################################################################################################################ + + +void test_printoutKeyboards_S2(vector_dword_3D &All_Vector) { printf(" values of US - Values of underlying"); for ( int i=0; i< All_Vector[0].size(); i++) { printf("-----------------------------\n"); @@ -350,3 +516,12 @@ void test_printoutKeyboards_S2(v_dw_3D &All_Vector) { } } } + +/*bool is_correct_mac_shiftstate(int win_ss) { + return ( (win_ss ==0) || (win_ss ==2) || (win_ss ==8) || (win_ss ==10) ); +}*/ + +/*bool is_correct_rgkey_shiftstate(int win_ss) { + return ( (win_ss ==0) || (win_ss ==1) || (win_ss ==6) || (win_ss ==7) ); +}*/ + diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index e9ca11ca0d7..a73005092a3 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -55,41 +55,52 @@ const KMX_DWORD KMX_VKMap[] = { 0 }; -typedef std::vector v_str_1D; -typedef std::vector v_dw_1D; -typedef std::vector > v_dw_2D; -typedef std::vector > > v_dw_3D; -static KMX_DWORD returnIfCharInvalid = 0; +typedef std::vector vector_str_1D; +typedef std::vector vector_dword_1D; +typedef std::vector > vector_dword_2D; +typedef std::vector > > vector_dword_3D; +static KMX_DWORD INVALID_NAME = 0; static KMX_DWORD max_shiftstate = 10; static KMX_DWORD keycode_max = 50; static int keycode_spacebar = 49; -// map vk_ShiftState to modifier (use 0,2,4,8,10 instead of 0,16,9,25 ) -int mac_map_VKShiftState_to_MacModifier(int vk_ShiftState); +int mac_map_VKShiftState_to_Shiftstate(int vk_ShiftState); -// map win_ShiftState to modifier (use 0,2,4,8,10 instead of Base, Shft, Opt, Sh+Opt ) -int mac_map_Win_ShiftState_to_MacModifier(int win_ShiftState); +int mac_map_rgkey_ShiftState_to_Shiftstate(int win_ShiftState); -// make sure a correct shiftstate was passed -//bool is_correct_mac_shiftstate(int comp_ss); -//bool is_correct_rgkey_shiftstate(int comp_ss); bool is_correct_win_shiftstate(int comp_ss); -// create a Vector with all entries of both keymaps -int mac_createOneVectorFromBothKeyboards(v_dw_3D &All_Vector, const UCKeyboardLayout * keykeyboard_layout); +bool is_correct_Input_For_KeyboardTranslation(const UCKeyboardLayout * keyboard_layout,int keycode, int shiftstate, int cap); -// read configuration file, split and write to 3D-Vector (Data for US on Vector[0][ ][ ] ) -int mac_write_US_ToVector(v_dw_3D &vec); +int mac_createOneVectorFromBothKeyboards(vector_dword_3D &All_Vector, const UCKeyboardLayout * keykeyboard_layout); -// create an empty 2D vector containing 0 in all fields -v_dw_2D mac_create_empty_2D_Vector(int dim_rows, int dim_shifts); +int mac_write_US_ToVector(vector_dword_3D &vec); -// append characters to 3D-Vector using GDK (Data for underlying Language on Vector[1][ ][ ] ) -int mac_append_underlying_ToVector(v_dw_3D &All_Vector, const UCKeyboardLayout * keykeyboard_layout); +vector_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_shifts); + +int mac_append_underlying_ToVector(vector_dword_3D &All_Vector, const UCKeyboardLayout * keykeyboard_layout); -// initialize UCHR bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout); -//------------------------------ + +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps); + +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32 &deadkeystate); + +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int kc_underlying, int shiftstate_mac); + +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT kc_underlying, UINT VKShiftState, PKMX_WCHAR deadKey); + +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vector_dword_3D &All_Vector, KMX_DWORD kv_us); + +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vector_dword_3D & All_Vector, KMX_DWORD kv_underlying); + +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, vector_dword_3D &All_Vector, KMX_DWORD kc_us, ShiftState ss, int caps); + +UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us); + +KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); + +KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps); // we use the same type of array as throughout Keyman even though we have lots of unused fields const UINT mac_ScanCodeToUSVirtualKey[128] = { @@ -483,67 +494,11 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0xFFFF, // not used }; -//bool mac_IsKeymanUsedChar(int KV); -//------------------------------ -// _S2 CHECKED OK -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int kc_underlying, int shiftstate_mac); - -// _S2 CHECKED OK fill Deadkey with dk and return CATEGORY -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT kc_underlying, UINT VKShiftState, PKMX_WCHAR deadKey); - -// _S2 CHECKED OK use Vector to return the Keyval of underlying Keyboard -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D &All_Vector, KMX_DWORD kv_us); - -// _S2 CHECKED OK use Vector to return the Scancode of underlying Keyboard -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vector, KMX_DWORD kv_underlying); - -// _S2 CHECKED OK use Vector to return the Keycode of the underlying Keyboard for given VK_US using GDK -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_DWORD kc_us, ShiftState ss, int caps); - -// _S2 CHECKED OK return the Keycode of the underlying Keyboard for given VK_US -UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us); - -// _S2 CHECKED OK return the VirtualKey of the US Keyboard for a given Keyode using GDK -KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); - -// _S2 CHECKED OK -KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps); - -// use gdk_keymap_translate_keyboard_state to get keyval - base function to get keyvals - -// _S2 CHECKED OK -KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps); -// _S2 CHECKED OK -KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32 &deadkeystate); - //################################################################################################################################################ //################################################################################################################################################ -//KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_new(int charVal,const UCKeyboardLayout* keyboard_layout , KMX_DWORD shiftstate); - -//static KMX_DWORD deadkey_min = 0xfe50; // _S2 needed?? -//static KMX_DWORD deadkey_max = 0xfe93; // _S2 needed?? -//static KMX_DWORD deadkey_max = 0xfe52; // _S2 TOP_6 TODO This has to go! my test: to only return 3 dk -// _S2 need to go - -// _S2 CHECKED OK -// take deadkey-value (e.g.65106) and return u16string (e.g. '^' ) -//std::u16string mac_convert_DeadkeyValues_To_U16str(int in); - - -// convert codePoint to u16string -//std::u16string mac_CodePointToU16String(unsigned int codepoint); - -// replace Name of Key (e.g. ) wih Keycode ( e.g. 15 ) -//int mac_replace_KeyName_with_Keycode(std::string in); - -// take a std::string (=contents of line symbols-file ) and returns the (int) value of the character -//KMX_DWORD mac_convertNamesTo_DWORD_Value(std::string tok_str); - -// 1. step: read complete Row of Configuration file US -//bool mac_createCompleteRow_US(v_str_1D &complete_List, FILE *fpp, const char *text, std::string language); -void test_printoutKeyboards_S2(v_dw_3D &All_Vector); +void test_printoutKeyboards_S2(vector_dword_3D &All_Vector); KMX_DWORD X_playWithDK_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal) ; KMX_DWORD X_playWithDK_S2_one(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal); KMX_DWORD X_compare_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 85c90869587..b66fd417c82 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -23,7 +23,6 @@ #include #include #include -//#include "km_types.h" #include "mc_kmxfile.h" #include "keymap.h" @@ -63,18 +62,22 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { return false; } -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - - bool test_alDead_S2(std::vector ald); +/** + * @brief a function similar to Window`s ToUnicodeEx() function. Find a keyvalue for given keycode, shiftstate and caps + * @param keycode a key of the currently used keyboard Layout + * @param pwszBuff Buffer to store resulting character + * @param ss_win a windows-style shiftstate of the currently used keyboard Layout + * @param caps state of the caps key of the currently used keyboard Layout + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @return -1 if a deadkey was found; 0 if no translation is available; +1 if character was found and written to pwszBuff + */ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_win, int caps, const UCKeyboardLayout * keyboard_layout) { KMX_DWORD keyval; UInt32 isdk=0; - if (!keyboard_layout) + /*if (!keyboard_layout) return 0; if (!(keycode <= keycode_max)) @@ -84,13 +87,16 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_win, int caps, return 0; if (!(caps <= 1)) + return 0;*/ + + if(! is_correct_Input_For_KeyboardTranslation(keyboard_layout, keycode, ss_win, caps)) return 0; - keyval= mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_map_Win_ShiftState_to_MacModifier(ShiftState(ss_win)), caps, isdk); + keyval= mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_map_rgkey_ShiftState_to_Shiftstate(ShiftState(ss_win)), caps, isdk); std::u16string str =std::u16string(1, keyval ); pwszBuff[0]= * (PKMX_WCHAR) str.c_str(); - if ((isdk) && (keycode!= 0x999)) // deadkeys + if ((isdk) && (keycode!= 0xFFFF)) // deadkeys return -1; if (keyval == 0) // no character return 0; @@ -246,14 +252,15 @@ class mac_KMX_VirtualKey { return nkeys; } - bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector *deadkeys, int deadkeyBase, BOOL bDeadkeyConversion, v_dw_3D &All_Vector, const UCKeyboardLayout *keyboard_layout ) { // I4552 + bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector *deadkeys, int deadkeyBase, BOOL bDeadkeyConversion, vector_dword_3D &All_Vector, const UCKeyboardLayout *keyboard_layout ) { // I4552 // Get the CAPSLOCK value - int capslock = - (this->mac_KMX_IsCapsEqualToShift() ? 1 : 0) | - (this->mac_KMX_IsSGCAPS() ? 2 : 0) | - (this->mac_KMX_IsAltGrCapsEqualToAltGrShift() ? 4 : 0) | - (this->mac_KMX_IsXxxxGrCapsEqualToXxxxShift() ? 8 : 0); -capslock = 1; //_S2 TODO + /*int capslock = + (this->mac_KMX_IsCapsEqualToShift() ? 1 : 0) | + (this->mac_KMX_IsSGCAPS() ? 2 : 0) | + (this->mac_KMX_IsAltGrCapsEqualToAltGrShift() ? 4 : 0) | + (this->mac_KMX_IsXxxxGrCapsEqualToXxxxShift() ? 8 : 0);*/ + + int capslock = 1; //we do not use the equation to obtain capslock. On Mac we set capslock=1 for (int ss = 0; ss <= MaxShiftState; ss++) { if (ss == Menu || ss == ShftMenu) { @@ -366,7 +373,7 @@ class mac_KMX_Loader { int maxshiftstate=2; DeadKey *deadKey = new DeadKey(rgKey[iKeyDead]->mac_KMX_GetShiftState(shiftStateDead, fCapsLock)[0]); - int ss_dead = mac_map_Win_ShiftState_to_MacModifier(shiftStateDead); + int ss_dead = mac_map_rgkey_ShiftState_to_Shiftstate(shiftStateDead); KMX_DWORD keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead], ss_dead,0); for( int i=0; i< keycode_spacebar+1; i++) { @@ -413,13 +420,27 @@ int mac_KMX_GetMaxDeadkeyIndex(KMX_WCHAR *p) { return n; } +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + + // _S2 need to go void test_print_All_Entries_S2(std::vector rgKey); bool test_run_verify_S2(std::vector rgKey); void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout); void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode); -bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout, std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 + /** + * @brief Collect the key data, translate it to kmx and append to the existing keyboard + * @param kp keyboard + * @param All_Vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @param FDeadkeys vector of all deadkeys for the currently used (underlying)keyboard Layout + * @param bDeadkeyConversion 1 to convert a deadkey to a character; 0 no conversion + * @return true in case of success + */ +bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &All_Vector, const UCKeyboardLayout **keyboard_layout, std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 mac_KMX_Loader loader; std::vector rgKey; //= new VirtualKey[256]; @@ -493,7 +514,6 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, v_dw_3D &All_Vector, const UCKeyboa else if(rc < 0) { sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on mac is different - printf(" _S2 we use dk: %i(%i) %i caps:%i %i(%c) \n", KC_US, iKey,ss, caps, sbBuffer[0],sbBuffer[0] ); sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps == 0)); diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h index 5e544545527..773eaa39470 100755 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -2,10 +2,8 @@ #ifndef MC_IMPORT_RULES_H #define MC_IMPORT_RULES_H -// _S2 CHECKED OK int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps, const UCKeyboardLayout * keyboard_layout); -// _S2 CHECKED OK class DeadKey { private: KMX_WCHAR m_deadchar; diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 53afeef9efb..3a0fda673f6 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -29,9 +29,9 @@ #include "u16.h" -KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc, char *argv[]); +KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc); -bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, v_dw_3D &All_Vector, const UCKeyboardLayout **keyboard_layout, std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 +bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &All_Vector, const UCKeyboardLayout **keyboard_layout, std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 std::vector KMX_FDeadkeys; // I4353 @@ -42,6 +42,14 @@ std::vector KMX_FDeadkeys; // I4353 #define _countof(a) (sizeof(a)/sizeof(*(a))) + + /** + * @brief main function for mcompile for Windows, Linux, Mac + * @param argc number of commandline arguments + * @param argv commandline arguments + * @return 0 on success, 1 for wrong usage of calling parameters, 3 if unable ro load keyboard + */ + #if defined(_WIN32) || defined(_WIN64) int wmain(int argc, wchar_t* argv[]) { std::vector str_argv_16 = convert_argvW_to_Vector_u16str( argc, argv); @@ -58,14 +66,20 @@ std::vector KMX_FDeadkeys; // I4353 int main(int argc, char* argv[]) { std::vector str_argv_16 = convert_argv_to_Vector_u16str(argc, argv); - mac_run(argc, str_argv_16, argv); printf("\n................................ END .............................. _S2 \n"); - #endif } + + /** + * @brief start of mcompile; load, convert and save keyboard + * @param argc number of commandline arguments + * @param str_argv vector of string of commandline arguments: executable, inputfile, outputfile + * @param argv_ch pointer to pointer to char/wchar_t (commandline arguments) + * @return 0 on success, 1 for wrong usage of calling parameters, 3 if unable ro load keyboard + */ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ std::vector argv; @@ -134,12 +148,12 @@ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NU } #elif ((__linux__) || (__unix__ )) // LINUX, UNIX - if(mac_KMX_DoConvert( kmxfile, bDeadkeyConversion, argc, (gchar**) argv_ch)) { // I4552F + if(mac_KMX_DoConvert( kmxfile, bDeadkeyConversion, argc)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); } #elif (__APPLE__ && TARGET_OS_MAC ) //macOS - if(mac_KMX_DoConvert( kmxfile, bDeadkeyConversion, argc, (char**) argv_ch)) { // I4552F + if(mac_KMX_DoConvert( kmxfile, bDeadkeyConversion, argc)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); } #endif @@ -158,6 +172,14 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCT // For each key rule on the keyboard, remap its key to the // correct shift state and key. Adjust the LCTRL+RALT -> RALT if necessary // +/** + * @brief translate each key of a group: remap the content of a key (key->Key) of the US keyboard to a character (ch) + * @param key a key + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @param ch character of the underlying keyboard to be remapped + * @return void + */ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" @@ -182,13 +204,27 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) key->Key = vk; } } - +/** + * @brief translate a group of a keyboard + * @param group a keyboard group + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @param ch character of the underlying keyboard to be remapped + * @return void + */ void mac_KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { for(unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_TranslateKey(&group->dpKeyArray[i], vk, shift, ch); } } - +/** + * @brief translate a keyboard + * @param kbd the US keyboard + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @param ch character of the underlying keyboard to be remapped + * @return void + */ void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { if(kbd->dpGroupArray[i].fUsingKeys) { @@ -197,20 +233,34 @@ void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_ } } + + /** + * @brief check key for unconverted key rules + * @param key a key + * @return void + */ void mac_KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { if(key->ShiftFlags == 0) { - //mac_KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); + mac_KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); } else if(key->ShiftFlags & VIRTUALCHARKEY) { - //mac_KMX_LogError(L"Did not find a match for mnemonic virtual character key rule on line %d, + [%x '%c'] > ...", key->Line, key->ShiftFlags, key->Key); + mac_KMX_LogError(L"Did not find a match for mnemonic virtual character key rule on line %d, + [%x '%c'] > ...", key->Line, key->ShiftFlags, key->Key); } } - + /** + * @brief check a group for unconverted rules + * @param group a keyboard group + * @return void + */ void mac_KMX_ReportUnconvertedGroupRules(LPKMX_GROUP group) { for(unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_ReportUnconvertedKeyRule(&group->dpKeyArray[i]); } } - + /** + * @brief check a keyboard for unconverted rules + * @param kbd the US keyboard + * @return void + */ void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { if(kbd->dpGroupArray[i].fUsingKeys) { @@ -219,6 +269,16 @@ void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { } } + + /** + * @brief remap the content of a key (key->dpContext) of the US keyboard to a deadkey sequence + * @param key a key + * @param deadkey a deadkey to be remapped + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @param ch character of the underlying keyboard + * @return void + */ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { if((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. @@ -247,13 +307,29 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, key->Key = vk; } } - + /** + * @brief translate a group + * @param group a keyboard group + * @param a deadkey to be remapped + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @param character of the underlying keyboard + * @return void + */ void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { for(unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_TranslateDeadkeyKey(&group->dpKeyArray[i], deadkey, vk, shift, ch); } } - + /** + * @brief translate a keyboard + * @param kbd the US keyboard + * @param a deadkey to be remapped + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @param character of the underlying keyboard + * @return void + */ void mac_KMX_TranslateDeadkeyKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { if(kbd->dpGroupArray[i].fUsingKeys) { @@ -262,6 +338,15 @@ void mac_KMX_TranslateDeadkeyKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX } } + + /** + * @brief add a deadkey rule + * @param kbd the US keyboard + * @param deadkey a deadkey to be added + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @return void + */ void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" @@ -292,6 +377,11 @@ void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, } } +/** + * @brief find the maximum deadkey id + * @param str the deadkey + * @return the maximum deadkey id + */ KMX_WCHAR mac_KMX_ScanXStringForMaxDeadkeyID(PKMX_WCHAR str) { KMX_WCHAR dkid = 0; while(str && *str) { @@ -306,10 +396,18 @@ KMX_WCHAR mac_KMX_ScanXStringForMaxDeadkeyID(PKMX_WCHAR str) { return dkid; } + struct KMX_dkidmap { KMX_WCHAR src_deadkey, dst_deadkey; }; + + /** + * @brief find a deadkey id for a given deadkey + * @param kbd the keyboard + * @param deadkey + * @return 0 if failed; otherwise a deadkey-id + */ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { LPKMX_GROUP gp; LPKMX_KEY kp; @@ -360,7 +458,19 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { return s_dkids[s_ndkids++].dst_deadkey = s_next_dkid = ++dkid; } -void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, v_dw_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { + + /** + * @brief Lookup the deadkey table for the deadkey in the physical keyboard. Then for each character, go through and map it through + * @param kbd the keyboard + * @param vk_US virtual key of the us keyboard + * @param shift shiftstate + * @param deadkey character produced by a deadkey + * @param All_Vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param keyboard_layout the currently used (underlying) keyboard Layout + * + * @return void + */ +void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, vector_dword_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { KMX_WORD deadkeys[512]={0}; KMX_WORD *pdk; @@ -383,6 +493,13 @@ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_ } } + + /** + * @brief convert a mnemonic keyboard to a positional keyboard + * (i.e. setting *sp->dpString = '0' / TSS_MNEMONIC=0) + * @param kbd keyboard + * @return TRUE if conversion was successful; FALSE otherwise + */ KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { LPKMX_STORE sp; UINT i; @@ -405,13 +522,15 @@ KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { } - - -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - -KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc, char *argv[]) { + /** + * @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard + * @param kbd US keyboard + * @param bDeadkeyConversion 1 for converting a deadkey to a character; + * 0 for not converting a deadkey to a character + * @param argc number of commandline arguments + * @return TRUE if conversion was succsessful; FALSE if not + */ +KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc) { KMX_WCHAR DeadKey=0; @@ -423,8 +542,8 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int // evident for the 102nd key on UK, for example, where \ can be generated with VK_OEM_102 or AltGr+VK_QUOTE. // For now, we get the least shifted version, which is hopefully adequate. - // Sadly it`s not: on a German WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only which is the usual combination to get ~. - // on a German MAC keyboard one will get '~' with either OPT + K_221(+) or OPT + K_84(T) or CAPS + OPT + K_78(N) + // Sadly it`s not e.g.: : on a German WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only which is the usual combination to get ~. + // on a German MAC keyboard one will get '~' with either OPT + K_221(+) or OPT + K_84(T) or CAPS + OPT + K_78(N) // K_84(T) will be caught first, so one of the the least obvious version for creating the '~' is found and processed. // -> meeting with Marc May 21 2024: We leave it as it is; it is OK if different combinations are found. @@ -434,49 +553,24 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int return FALSE; } // create vector that contains Keycode, Base, Shift for US-Keyboard and underlying keyboard - v_dw_3D All_Vector; + vector_dword_3D All_Vector; if(mac_createOneVectorFromBothKeyboards(All_Vector, keyboard_layout)){ wprintf(L"ERROR: can't create one vector from both keyboards\n"); return FALSE; } //printoutKeyboards(All_Vector); - -print_character_of_key_S2(keyboard_layout, 40); -print_character_of_key_S2(keyboard_layout, 43); -print_character_of_key_S2(keyboard_layout, 24); -print_character_of_key_S2(keyboard_layout, 42); -print_character_of_key_S2(keyboard_layout, 39); -print_character_of_key_S2(keyboard_layout, 44); - -//DE: comma -find_character_S2(keyboard_layout, 44); -//DE: equal -find_character_S2(keyboard_layout, 39); -find_character_S2(keyboard_layout, 45); - - -//FR: BKSLASH -print_character_of_key_S2(keyboard_layout, 10); -print_character_of_key_S2(keyboard_layout, 42); -find_character_S2(keyboard_layout, 35); -find_character_S2(keyboard_layout, 64); - - -//ES HYPHEN -print_character_of_key_S2(keyboard_layout, 43); -print_character_of_key_S2(keyboard_layout, 39); -print_character_of_key_S2(keyboard_layout, 27); find_character_S2(keyboard_layout, 180); printf("-------\n"); -print_dublicates_S2(keyboard_layout); +//print_dublicates_S2(keyboard_layout); //find_double_keys(keyboard_layout,1); + for (int j = 0; VKShiftState[j] != 0xFFFF; j++) { // I4651 // Loop through each possible key on the keyboard for (int i = 0;KMX_VKMap[i]; i++) { // I4651 - // windows uses VK, Linux and macOS use SC/Keycode + // windows uses VK as sorting order in rgkey[], Linux and macOS use SC/Keycode as sorting order UINT scUnderlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_VKMap[i]); KMX_WCHAR ch = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, scUnderlying, VKShiftState[j], &DeadKey); @@ -504,7 +598,18 @@ print_dublicates_S2(keyboard_layout); return TRUE; } -int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ) { + + + /** + * @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard + * @param keyboard_layout the currently used (underlying) keyboard Layout + * @param All_Vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param deadkey deadkey character + * @param shift_dk shiftstate of the deadkey + * @param OutputPairs ptr to array of deadkeys + * @return size of array of deadkeys + */ +int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, vector_dword_3D &All_Vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ) { UInt32 deadkeystate; UniCharCount maxStringlength = 5; @@ -522,13 +627,13 @@ int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, v_dw_3D &All // Since mcompile finds only the first occurance of a dk combination, this makes sure that we always find the dk+SPACE combinations for a deadkey. // If there are more combinations to create a specific character they will not be found. (See comment at the beginning of mac_KMX_DoConvert()) for ( int i=keycode_spacebar; i >=0; i--) { - status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_map_VKShiftState_to_MacModifier(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_map_VKShiftState_to_Shiftstate(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { status = UCKeyTranslate(keyboard_layout, i, kUCKeyActionDown, ss_mac[j], LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { - KMX_WORD vk = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, i, ss_mac[1]); + KMX_WORD vk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[1],0); // ensure to not get key combinations like ^a but only combined characters like â ( exception for ^+space) if((unicodeString[0] != deadkey) || (vk == 32)) { @@ -544,7 +649,13 @@ int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, v_dw_3D &All return (p-OutputPairs); } -void mac_KMX_LogError(const wchar_t* fmt, ...) { + + /** + * @brief print (error) messages + * @param fmt text to print + * @return void + */ + void mac_KMX_LogError(const wchar_t* fmt, ...) { WCHAR fmtbuf[256]; const wchar_t* end = L"\0"; const wchar_t* nl = L"\n"; @@ -565,6 +676,12 @@ void mac_KMX_LogError(const wchar_t* fmt, ...) { } + + +//################################################################################################################################################ +//################################# Code beyond these lines needs to be included in mcompile ##################################################### +//################################################################################################################################################ + //################################################################################################################################################ //################################################################################################################################################ @@ -618,7 +735,7 @@ bool moreval=false; else ss_rgkey= 999; if( (ss==1) || (ss==3) || (ss==5) || (ss==7) || (ss==9) ) continue; - + int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, ss, caps); count++; @@ -650,7 +767,7 @@ bool print_character_of_key_S2(const UCKeyboardLayout * keyboard_layout, int key int ss_rgkey; for ( int ss=0; ss< 6;ss++) { for ( int caps=0; caps< 2;caps++) { - + int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, 2*ss, caps); printf( " key %i has values : %i (%c) ( ss:%i, caps:%i) \n", key, keyvalsearch,keyvalsearch, 2*ss, caps); } @@ -672,7 +789,7 @@ continue; for ( int caps=0; caps< 2;caps++) { for ( int key=0; key< 50;key++) { - int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, mac_map_Win_ShiftState_to_MacModifier(ss), caps); + int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, mac_map_rgkey_ShiftState_to_Shiftstate(ss), caps); if((ss_rgkey!= 999 )&& ( keyval== keyvalsearch)) printf( " found keyval: key: %i, ss_mac:%i ( ss_rgkey:%i), caps:%i -> character: %i (%c) \n", key, ss, ss_rgkey, caps, keyvalsearch,keyvalsearch); } diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index d384cc38364..0e4848f6389 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -35,15 +35,12 @@ struct KMX_DeadkeyMapping { // I4353 extern std::vector KMX_FDeadkeys; // I4353 -// _S2 CHECKED OK int mac_run(int argc, std::vector str_argv, char* argv[]); PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); -// _S2 CHECKED OK -int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ); // returns array of [usvk, ch_out] pairs +int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, vector_dword_3D &All_Vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ); // returns array of [usvk, ch_out] pairs -// _S2 CHECKED OK void mac_KMX_LogError(const wchar_t* fmt, ...); From f47a037a59a6d5fba15b944479417650e1a916f5 Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 5 Jul 2024 15:54:45 +0200 Subject: [PATCH 31/71] feat(mac): implement comments of PR9384 --- mac/.gitignore | 7 - mac/mcompile/keymap.cpp | 12 +- mac/mcompile/keymap.h | 8 +- mac/mcompile/mc_kmxfile.cpp | 91 ++++++++----- mac/mcompile/mc_kmxfile.h | 8 +- mac/mcompile/util_filesystem.cpp | 227 ------------------------------- mac/mcompile/util_filesystem.h | 16 --- 7 files changed, 76 insertions(+), 293 deletions(-) delete mode 100755 mac/mcompile/util_filesystem.cpp delete mode 100755 mac/mcompile/util_filesystem.h diff --git a/mac/.gitignore b/mac/.gitignore index c5ab971cfa0..590a6ee1aad 100644 --- a/mac/.gitignore +++ b/mac/.gitignore @@ -15,10 +15,3 @@ setup/textinputsource/textinputsource setup/textinputsource/textinputsource.arm64 setup/textinputsource/textinputsource.x86_64 setup/Install Keyman.app - -//Sabine -**/mcompile/executable/*.* -**/mcompile/*.kmx -**/mcompile/X*.cpp -**/mcompile/X_bak -**/mcompile/X*.* \ No newline at end of file diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index d75fe18d789..3cb89e568b3 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -119,8 +119,8 @@ int mac_write_US_ToVector( vector_dword_3D &vec_us) { std::vector us_Base = {97,115,100,102,104,103,122,120,99,118,167,98,113,119,101,114,121,116,49,50,51,52,54,53,61,57,55,45,56,48, 93,111,117, 91,105,112,13,108,106,39,107,59, 92,44,47,110,109,46}; std::vector us_Shift = {65, 83, 68, 70, 72, 71, 90, 88,67, 86,177,66, 81, 87, 69, 82, 89, 84,33,64,35,36,94,37,43,40,38,95,42,41,125, 79, 85,123, 73, 80,13, 76, 74,34, 75,58,124,60,63, 78, 77,62}; - vector_dword_1D values; - vector_dword_2D key; + vec_dword_1D values; + vec_dword_2D key; for ( int i=0; i< us_Base.size(); i++) { values.push_back(i); @@ -147,10 +147,10 @@ int mac_write_US_ToVector( vector_dword_3D &vec_us) { * @return the 2D-Vector */ -vector_dword_2D mac_create_empty_2D_Vector( int dim_rows, int dim_cols) { +vec_dword_2D mac_create_empty_2D_Vector( int dim_rows, int dim_cols) { - vector_dword_1D shift; - vector_dword_2D vector_2D; + vec_dword_1D shift; + vec_dword_2D vector_2D; for ( int j=0; j< dim_cols;j++) { shift.push_back(INVALID_NAME); @@ -174,7 +174,7 @@ vector_dword_2D mac_create_empty_2D_Vector( int dim_rows, int dim_cols) { int mac_append_underlying_ToVector(vector_dword_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { int caps=0; // create a 2D vector all filled with " " and push to 3D-Vector - vector_dword_2D underlying_Vector2D = mac_create_empty_2D_Vector(All_Vector[0].size(), All_Vector[0][0].size()); + vec_dword_2D underlying_Vector2D = mac_create_empty_2D_Vector(All_Vector[0].size(), All_Vector[0][0].size()); if (underlying_Vector2D.size() == 0) { wprintf(L"ERROR: can't create empty 2D-Vector\n"); diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index a73005092a3..2572b944412 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -55,9 +55,9 @@ const KMX_DWORD KMX_VKMap[] = { 0 }; -typedef std::vector vector_str_1D; -typedef std::vector vector_dword_1D; -typedef std::vector > vector_dword_2D; +typedef std::vector vec_string_1D; +typedef std::vector vec_dword_1D; +typedef std::vector > vec_dword_2D; typedef std::vector > > vector_dword_3D; static KMX_DWORD INVALID_NAME = 0; static KMX_DWORD max_shiftstate = 10; @@ -76,7 +76,7 @@ int mac_createOneVectorFromBothKeyboards(vector_dword_3D &All_Vector, const UCKe int mac_write_US_ToVector(vector_dword_3D &vec); -vector_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_shifts); +vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_shifts); int mac_append_underlying_ToVector(vector_dword_3D &All_Vector, const UCKeyboardLayout * keykeyboard_layout); diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index eae54edf4aa..0b9ba7025a1 100755 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -7,37 +7,6 @@ #define CERR_UnableToWriteFully 0x00008007 #define CERR_SomewhereIGotItWrong 0x00008009 -KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz); - -LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize); - -KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename) { - - FILE *fp; - fp = Open_File(filename, u"wb"); - - if(fp == NULL) - { - mac_KMX_LogError(L"Failed to create output file (%d)", errno); - return FALSE; - } - - KMX_DWORD err = KMX_WriteCompiledKeyboard(kbd, fp, FALSE); - fclose(fp); - - if(err != CERR_None) { - mac_KMX_LogError(L"Failed to write compiled keyboard with error %d", err); - - std::u16string u16_filname(filename); - std::string s = string_from_u16string(u16_filname); - - remove(s.c_str()); - return FALSE; - } - - return TRUE; -} - KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug) { LPKMX_GROUP fgp; @@ -217,6 +186,37 @@ KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL return CERR_None; } + +KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz); + +LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize); + +KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename) { + + FILE *fp; + fp = Open_File(filename, u"wb"); + + if(fp == NULL) + { + mac_KMX_LogError(L"Failed to create output file (%d)", errno); + return FALSE; + } + + KMX_DWORD err = KMX_WriteCompiledKeyboard(kbd, fp, FALSE); + fclose(fp); + + if(err != CERR_None) { + mac_KMX_LogError(L"Failed to write compiled keyboard with error %d", err); + + std::u16string u16_filname(filename); + std::string s = string_from_u16string(u16_filname); + + remove(s.c_str()); + return FALSE; + } + + return TRUE; +} PKMX_WCHAR KMX_StringOffset(PKMX_BYTE base, KMX_DWORD offset) { if(offset == 0) return NULL; return (PKMX_WCHAR)(base + offset); @@ -516,3 +516,32 @@ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) { //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ + +FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode) { +#ifdef _MSC_VER + std::string cpath = Filename; //, cmode = mode; + std::replace(cpath.begin(), cpath.end(), '/', '\\'); + return fopen(cpath.c_str(), (const KMX_CHAR*) mode); +#else + return fopen(Filename, mode); + std::string cpath, cmode; + cpath = (const KMX_CHAR*) Filename; + cmode = (const KMX_CHAR*) mode; + return fopen(cpath.c_str(), cmode.c_str()); +#endif +}; + + +FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode) { +#ifdef _MSC_VER + std::wstring cpath = convert_pchar16T_To_wstr((KMX_WCHAR*) Filename); + std::wstring cmode = convert_pchar16T_To_wstr((KMX_WCHAR*) mode); + std::replace(cpath.begin(), cpath.end(), '/', '\\'); + return _wfsopen(cpath.c_str(), cmode.c_str(), _SH_DENYWR); +#else + std::string cpath, cmode; + cpath = string_from_u16string(Filename); + cmode = string_from_u16string(mode); + return fopen(cpath.c_str(), cmode.c_str()); +#endif +}; diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index a284b88991d..b3070184225 100755 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -6,7 +6,7 @@ #include "km_types.h" #include "kmx_file.h" -#include "util_filesystem.h" //_S2 TODO include from keyman; not from this folder +//#include "util_filesystem.h" //_S2 TODO include from keyman; not from this folder #include "mcompile.h" @@ -76,7 +76,11 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD *lpKeyboard); KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename); -KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug); +// _S2 Open files on windows and non-windows platforms. Datatypes for Filename and mode must be the same. +// return FILE* if file could be opened; FILE must to be closed in calling function +FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); +FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode); + #endif // _KMXFILE_H diff --git a/mac/mcompile/util_filesystem.cpp b/mac/mcompile/util_filesystem.cpp deleted file mode 100755 index 7f9edd6b367..00000000000 --- a/mac/mcompile/util_filesystem.cpp +++ /dev/null @@ -1,227 +0,0 @@ - -#ifdef __EMSCRIPTEN__ -#include -#include -#endif - -#include -#include -#include -#include "util_filesystem.h" - -#ifdef _MSC_VER -#include -#else -#include -#endif - -//#define _DEBUG_FOPEN 1 - -#ifdef __EMSCRIPTEN__ - -const std::string get_wasm_file_path(const std::string& filename) { - // Verify that we are passing a fully-qualified path - // TODO: we need to support relative paths based on CWD -#if _DEBUG_FOPEN - std::cout << "get_wasm_file_path ENTER (" << filename << ")" << std::endl; -#endif - - assert( - (filename.length() > 0 && filename.at(0) == '/') || - (filename.length() > 1 && filename.at(1) == ':') - ); - -#if _DEBUG_FOPEN - std::cout << "get_wasm_file_path assert passed " << std::endl; -#endif - - EM_ASM_({ - //console.log('EM_ASM enter'); - let path = Module.UTF8ToString($0); - const isWin32Path = path.match(/^[a-zA-Z]:/); - - //console.log('EM_ASM path = '+path); - let root = '/nodefs-mount'; - if(!FS.analyzePath(root).exists) { - //console.log('EM_ASM mkdir '+root); - FS.mkdir(root); - if(!isWin32Path) { - //console.log('EM_ASM mount '+root); - FS.mount(NODEFS, {root : '/'}, root); - } - } - - if(isWin32Path) { - // Win32 path, one mount per drive - root += "/" + path.charAt(0); - if(!FS.analyzePath(root).exists) { - //console.log('EM_ASM mkdir '+root); - FS.mkdir(root); - //console.log('EM_ASM mount '+root); - FS.mount(NODEFS, {root : path.substr(0,3) }, root); - } - } - }, filename.c_str()); - -#if _DEBUG_FOPEN - std::cout << "get_wasm_file_path EM_ASM_ passed " << std::endl; -#endif - - std::string f = std::string("/nodefs-mount"); - - if(filename.length() > 2 && filename.at(1) == ':') { - f += std::string("/") + filename.at(0) + filename.substr(2); - } else { - f += filename; - } - -#if _DEBUG_FOPEN - std::cout << "get_wasm_file_path opening virtual path: " << f << std::endl; -#endif - - return f; -} - -FILE* fopen_wasm(const std::string& filename, const std::string& mode) { - std::string f = get_wasm_file_path(filename); - FILE* fp = fopen(f.c_str(), mode.c_str()); - -#if _DEBUG_FOPEN - std::cout << "get_wasm_file_path fopen called, returned " << fp << std::endl; -#endif - - return fp; -} - -#endif - -#ifndef _MSC_VER -#ifdef __EMSCRIPTEN__ -#define fopen_wrapper fopen_wasm -#else -#define fopen_wrapper fopen -#endif -#endif - -FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode) { -#ifdef _MSC_VER - std::string cpath = Filename; //, cmode = mode; - std::replace(cpath.begin(), cpath.end(), '/', '\\'); - return fopen(cpath.c_str(), (const KMX_CHAR*) mode); -#else - return fopen_wrapper(Filename, mode); - std::string cpath, cmode; - cpath = (const KMX_CHAR*) Filename; - cmode = (const KMX_CHAR*) mode; - return fopen_wrapper(cpath.c_str(), cmode.c_str()); -#endif -}; - -FILE* Open_File(const KMX_WCHART* Filename, const KMX_WCHART* mode) { -#ifdef _MSC_VER - std::wstring cpath = Filename; //, cmode = mode; - std::replace(cpath.begin(), cpath.end(), '/', '\\'); - return _wfsopen(cpath.c_str(), mode, _SH_DENYWR); -#else - std::string cpath, cmode; - cpath = string_from_wstring(Filename); - cmode = string_from_wstring(mode); - return fopen_wrapper(cpath.c_str(), cmode.c_str()); -#endif -}; - -FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode) { -#ifdef _MSC_VER - std::wstring cpath = convert_pchar16T_To_wstr((KMX_WCHAR*) Filename); - std::wstring cmode = convert_pchar16T_To_wstr((KMX_WCHAR*) mode); - std::replace(cpath.begin(), cpath.end(), '/', '\\'); - return _wfsopen(cpath.c_str(), cmode.c_str(), _SH_DENYWR); -#else - std::string cpath, cmode; - cpath = string_from_u16string(Filename); - cmode = string_from_u16string(mode); - return fopen_wrapper(cpath.c_str(), cmode.c_str()); -#endif -}; - -KMX_BOOL kmcmp_FileExists(const KMX_CHAR *filename) { - -#ifdef _MSC_VER - intptr_t n; - _finddata_t fi; - if((n = _findfirst(filename, &fi)) != -1) { - _findclose(n); - return TRUE; - } -#else //!_MSC_VER - -#ifdef __EMSCRIPTEN__ - std::string f = get_wasm_file_path(filename); -#else //!__EMSCRIPTEN__ - std::string f = filename; -#endif // !__EMSCRIPTEN__ - - if(access(f.c_str(), F_OK) != -1) { - return TRUE; - } - -#endif // !_MSC_VER - - return FALSE; -} - -KMX_BOOL kmcmp_FileExists(const KMX_WCHAR* filename) { -#ifdef _MSC_VER - intptr_t n; - _wfinddata_t fi; - if((n = _wfindfirst((wchar_t*) filename, &fi)) != -1) { - _findclose(n); - return TRUE; - } -#else - std::string cpath; - cpath = string_from_u16string(filename); - return kmcmp_FileExists(cpath.c_str()); -#endif - - return FALSE; -}; - - -bool IsRelativePath(KMX_CHAR const * p) { - // Relative path (returns TRUE): - // ..\...\BITMAP.BMP - // PATH\BITMAP.BMP - // BITMAP.BMP - - // Semi-absolute path (returns FALSE): - // \...\BITMAP.BMP - - // Absolute path (returns FALSE): - // C:\...\BITMAP.BMP - // \\SERVER\SHARE\...\BITMAP.BMP - - if ((*p == '\\') || (*p == '/')) return FALSE; - if (*p && *(p + 1) == ':') return FALSE; - - return TRUE; -} - -bool IsRelativePath(KMX_WCHAR const * p) { - // Relative path (returns TRUE): - // ..\...\BITMAP.BMP - // PATH\BITMAP.BMP - // BITMAP.BMP - - // Semi-absolute path (returns FALSE): - // \...\BITMAP.BMP - - // Absolute path (returns FALSE): - // C:\...\BITMAP.BMP - // \\SERVER\SHARE\...\BITMAP.BMP - - if ((*p == u'\\') || (*p == u'/'))return FALSE; - if (*p && *(p + 1) == u':') return FALSE; - - return TRUE; -} \ No newline at end of file diff --git a/mac/mcompile/util_filesystem.h b/mac/mcompile/util_filesystem.h deleted file mode 100755 index 38877bf9f26..00000000000 --- a/mac/mcompile/util_filesystem.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -//#include _S2 "../src/kmx_u16.h" we want to include this... -#include "u16.h" - -// Opens files on windows and non-windows platforms. Datatypes for Filename and mode must be the same. -// returns FILE* if file could be opened; FILE needs to be closed in calling function -FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); -FILE* Open_File(const KMX_WCHART* Filename, const KMX_WCHART* mode); -FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode); -KMX_BOOL kmcmp_FileExists(const KMX_CHAR *filename); -KMX_BOOL kmcmp_FileExists(const KMX_WCHAR *filename); - -bool IsRelativePath(KMX_CHAR const * p); -bool IsRelativePath(KMX_WCHAR const * p); \ No newline at end of file From 4040e95e0c5c8ce4687a26ace9a5a4ca9d2b246d Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 5 Jul 2024 17:14:42 +0200 Subject: [PATCH 32/71] feat(mac): implement comments of PR9384 on keymap --- mac/mcompile/keymap.cpp | 133 ++++++++++++++++--------------- mac/mcompile/keymap.h | 38 ++++----- mac/mcompile/mc_import_rules.cpp | 14 ++-- mac/mcompile/mcompile.cpp | 28 +++---- mac/mcompile/mcompile.h | 2 +- 5 files changed, 108 insertions(+), 107 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 3cb89e568b3..2bc6ec64b0d 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -5,20 +5,21 @@ */ #include "keymap.h" +#include "kmx_file.h" /** * @brief map shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on mac * Windows: (Base: 00000000 (0); Shift 00010000 (16); AltGr 00001001 (9); Shift+AltGr 00011001 (25)) * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10 ) - * @param vk_ShiftState shiftstate used on windows + * @param shiftState shiftstate used on windows * @return a shiftstate usable for UCKeyTranslate() on mac if available */ -int mac_map_VKShiftState_to_Shiftstate(int vk_ShiftState) { - if (vk_ShiftState == 0 ) return 0; - else if (vk_ShiftState == 16) return 2; - else if (vk_ShiftState == 9) return 8; - else if (vk_ShiftState == 25) return 10; - else return vk_ShiftState; +int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) { + if (shiftState == 0 ) return 0; // Win ss 0 -> mac ss 0 + else if (shiftState == K_SHIFTFLAG) return 2; // Win ss 0 -> mac ss 2 + else if (shiftState == (LCTRLFLAG | RALTFLAG)) return 8; // Win ss 0 -> mac ss 8 + else if (shiftState == (K_SHIFTFLAG | LCTRLFLAG | RALTFLAG)) return 10; // Win ss 0 -> mac ss 10 + else return shiftState; // Win x 0 -> mac ss x } @@ -57,18 +58,18 @@ bool is_correct_win_shiftstate(int win_ss) { * @param caps state of the caps key of the currently used keyboard Layout * @return true if all parameters are OK; false if not */ -bool is_correct_Input_For_KeyboardTranslation(const UCKeyboardLayout * keyboard_layout,int keycode, int shiftstate, int caps=0){ +bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout * keyboard_layout,int keycode, int shiftstate, int caps=0){ if (!keyboard_layout) return false; - if (!(keycode <= keycode_max)) + if ((int) keycode > (int)keycode_max) return false; - if (!(shiftstate <= max_shiftstate)) + if ((shiftstate > max_shiftstate)) return false; - if (!(caps <= 1)) + if ((caps> 1)) return false; return true; @@ -80,7 +81,7 @@ return true; /** * @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard : - * All_Vector [ US_Keyboard ] + * all_vector [ US_Keyboard ] * [KeyCode_US ] * [Keyval unshifted ] * [Keyval shifted ] @@ -88,19 +89,19 @@ return true; * [KeyCode_underlying] * [Keyval unshifted ] * [Keyval shifted ] - * @param[out] All_Vector Vector that holds the data of the US keyboard as well as the currently used (underlying) keyboard + * @param[out] all_vector Vector that holds the data of the US keyboard as well as the currently used (underlying) keyboard * @param keyboard_layout ptr to currently used (underlying) keyboard Layout * @return 0 on success; 1 if data of US keyboard was not written; 2 if data of underlying keyboard was not written */ -int mac_createOneVectorFromBothKeyboards(vector_dword_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { +int mac_createOneVectorFromBothKeyboards(vector_dword_3D& all_vector, const UCKeyboardLayout * keyboard_layout) { - if(mac_write_US_ToVector(All_Vector)) { + if(mac_write_US_ToVector(all_vector)) { wprintf(L"ERROR: can't write US to Vector \n"); return 1; } - // add contents of underlying keyboard to All_Vector - if( mac_append_underlying_ToVector(All_Vector, keyboard_layout)) { + // add contents of underlying keyboard to all_vector + if ( mac_append_underlying_ToVector(all_vector, keyboard_layout)) { wprintf(L"ERROR: can't append underlying ToVector \n"); return 2; } @@ -113,7 +114,7 @@ int mac_createOneVectorFromBothKeyboards(vector_dword_3D &All_Vector, const UCKe * @param[out] vec_us Vector that holds the date * @return 0 on success; 1 if data of US keyboard was not written; */ -int mac_write_US_ToVector( vector_dword_3D &vec_us) { +int mac_write_US_ToVector( vector_dword_3D& vec_us) { // Values for US : A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P,CR, L, J, ', K, ;, \, ,, /, N, M, . std::vector us_Base = {97,115,100,102,104,103,122,120,99,118,167,98,113,119,101,114,121,116,49,50,51,52,54,53,61,57,55,45,56,48, 93,111,117, 91,105,112,13,108,106,39,107,59, 92,44,47,110,109,46}; @@ -143,57 +144,57 @@ int mac_write_US_ToVector( vector_dword_3D &vec_us) { /** * @brief create an 2D-Vector with all fields containing returnIfCharInvalid * @param dim_rows number of rows in vector - * @param dim_cols number of columns in vector + * @param dim_ss number of columns in vector * @return the 2D-Vector */ - -vec_dword_2D mac_create_empty_2D_Vector( int dim_rows, int dim_cols) { - - vec_dword_1D shift; +vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss) { + vec_dword_1D shifts; vec_dword_2D vector_2D; - for ( int j=0; j< dim_cols;j++) { - shift.push_back(INVALID_NAME); + for (int j = 0; j < dim_ss; j++) { + shifts.push_back(INVALID_NAME); } - for ( int i=0; i< dim_rows;i++) { - vector_2D.push_back(shift); + for (int i = 0; i < dim_rows; i++) { + vector_2D.push_back(shifts); } - shift.clear(); // _S2 needed?? return vector_2D; } /** - * * @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector - * @param[out] All_Vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param[out] all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param keyboard_layout ptr to currently used (underlying) keyboard Layout - * @return 0 on success; 1 if the initialization of the underlying vector failes; 2 if data of less than 2 keyboards is contained in All_Vector + * @return 0 on success; 1 if the initialization of the underlying vector failes; 2 if data of less than 2 keyboards is contained in all_vector */ -int mac_append_underlying_ToVector(vector_dword_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { +int mac_append_underlying_ToVector(vector_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { int caps=0; + if (all_vector.size() != 1) { + printf("ERROR: data for US keyboard not correct\n"); + return 1; + } // create a 2D vector all filled with " " and push to 3D-Vector - vec_dword_2D underlying_Vector2D = mac_create_empty_2D_Vector(All_Vector[0].size(), All_Vector[0][0].size()); + vec_dword_2D underlying_Vector2D = mac_create_empty_2D_Vector(all_vector[0].size(), all_vector[0][0].size()); if (underlying_Vector2D.size() == 0) { wprintf(L"ERROR: can't create empty 2D-Vector\n"); return 1; } - All_Vector.push_back(underlying_Vector2D); - if (All_Vector.size() < 2) { + all_vector.push_back(underlying_Vector2D); + if (all_vector.size() < 2) { wprintf(L"ERROR: creation of 3D-Vector failed\n"); - return 1; + return 2; } - for(int i =0; i< All_Vector[1].size();i++) { + for(int i = 0; i < (int)all_vector[1].size(); i++) { // get key name US stored in [0][i][0] and copy to name in "underlying"-block[1][i][0] - All_Vector[1][i][0] = All_Vector[0][i][0]; + all_vector[1][i][0] = all_vector[0][i][0]; for( int k=0; k<2;k++) { - All_Vector[1][i][k+1] = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, All_Vector[0][i][0], mac_map_rgkey_ShiftState_to_Shiftstate(k),0); + all_vector[1][i][k+1] = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, all_vector[0][i][0], mac_map_rgkey_ShiftState_to_Shiftstate(k),0); } } @@ -221,7 +222,7 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { wprintf(L"ERROR: Can't get keyboard_layout\n"); return 2; } - +// intentionally leaking `display` in order to still be able to access `keymap` return 0; } @@ -257,7 +258,7 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layo if (!(caps <= 1)) return 0;*/ - if(! is_correct_Input_For_KeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) + if(! ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) return 0; @@ -309,7 +310,7 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_l if (!(caps <= 1)) return 0;*/ - if(! is_correct_Input_For_KeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) + if(! ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) return 0; // if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown,(shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); @@ -352,11 +353,11 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa if (!(kc_underlying <= keycode_max)) return 0;*/ - if(! is_correct_Input_For_KeyboardTranslation(keyboard_layout, kc_underlying, is_correct_win_shiftstate(vk_ShiftState))) + if(! ensureValidInputForKeyboardTranslation(keyboard_layout, kc_underlying, is_correct_win_shiftstate(vk_ShiftState))) return 0; - keyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, kc_underlying,(mac_map_VKShiftState_to_Shiftstate(vk_ShiftState)), caps, isdk); + keyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, kc_underlying,(mac_convert_Shiftstate_to_MacShiftstate(vk_ShiftState)), caps, isdk); // if there was a deadkey return 0xFFFF and copy deadkey into dky if( isdk !=0) { @@ -373,17 +374,17 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa * * @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard * What character is on the same position/shiftstats/caps on the currently used (underlying) keyboard? - * @param All_Vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param kv_us a keyvalue on the US keyboard * @return keyval of the underlying keyboard if available; else the keyval of the US keyboard */ -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vector_dword_3D & All_Vector, KMX_DWORD kv_us) { +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vector_dword_3D& all_vector, KMX_DWORD kv_us) { // look for kv_us for any shiftstate of US keyboard - for( int i=0; i< All_Vector[0].size()-1 ;i++) { - for( int j=1; j< All_Vector[0][0].size();j++) { - if ( All_Vector[0][i][j] == kv_us ) - return All_Vector[1][i][j]; + for (int i = 0; i < all_vector[0].size() - 1; i++) { + for (int j = 1; j < all_vector[0][0].size(); j++) { + if (all_vector[0][i][j] == kv_us) + return all_vector[1][i][j]; } } return kv_us; @@ -394,17 +395,17 @@ KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vector_dword_3D & All_Vecto * * @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard * On what key of the underlying keyboard do we find a certain character? - * @param All_Vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param kv_underlying a keyvalue on the currently used (underlying) keyboard * @return keycode of the underlying keyboardif foundf; else the keyval of the underlying keyboard */ -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vector_dword_3D & All_Vector, KMX_DWORD kv_underlying) { +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vector_dword_3D& all_vector, KMX_DWORD kv_underlying) { // look for kv_us for any shiftstate of US keyboard - for( int i=0; i< All_Vector[1].size()-1 ;i++) { - for( int j=1; j< All_Vector[1][0].size();j++) { - if ( All_Vector[1][i][j] == kv_underlying ) { - return All_Vector[1][i][0]; + for( int i=0; i< all_vector[1].size()-1 ;i++) { + for( int j=1; j< all_vector[1][0].size();j++) { + if ( all_vector[1][i][j] == kv_underlying ) { + return all_vector[1][i][0]; } } } @@ -417,22 +418,22 @@ KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vector_dword_3D & * @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard * Where on a underlying keyboard do we find a character that is on a certain key on a US keyboard? * @param keyboard_layout the currently used (underlying)keyboard Layout - * @param All_Vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param kc_us a key of the US keyboard * @param ss_win a windows-type shiftstate * @param caps state of the caps key * @return the keycode of the underlying keyboardif found; else the keycode of the US keyboard */ -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, vector_dword_3D &All_Vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) { +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, vector_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) { // first get the keyvalue of the key on the US keyboard (kc_us) std::u16string keyval_us= std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_map_rgkey_ShiftState_to_Shiftstate(ss_win), caps) ); // then find the same keyvalue on the underlying keyboard and return the keycode of that key on the underlying keyboard - for( int i=0; i< All_Vector[1].size()-1 ;i++) { - for( int j=1; j< All_Vector[1][0].size();j++) { - if ( ((KMX_DWORD) All_Vector[1][i][j] == (KMX_DWORD) *keyval_us.c_str() ) ) - return All_Vector[1][i][0]; + for (int i = 0; i < all_vector[1].size() - 1; i++) { + for (int j = 1; j < all_vector[1][0].size(); j++) { + if (((KMX_DWORD) all_vector[1][i][j] == (KMX_DWORD)*keyval_us.c_str() ) ) + return all_vector[1][i][0]; } } return kc_us; @@ -507,12 +508,12 @@ KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyb //################################################################################################################################################ -void test_printoutKeyboards_S2(vector_dword_3D &All_Vector) { +void test_printoutKeyboards_S2(vector_dword_3D& all_vector) { printf(" values of US - Values of underlying"); - for ( int i=0; i< All_Vector[0].size(); i++) { + for ( int i=0; i< all_vector[0].size(); i++) { printf("-----------------------------\n"); - for ( int j=0; j< All_Vector[0][0].size(); j++) { - printf("i:%i\tUS: %i(%c)\t Underlying: %i(%c)\t \t\t\t%c \n", i,All_Vector[0][i][j] , All_Vector[0][i][j] , All_Vector[1][i][j],All_Vector[1][i][j],(All_Vector[0][i][j] == All_Vector[1][i][j]) ? '.' : '*'); + for ( int j=0; j< all_vector[0][0].size(); j++) { + printf("i:%i\tUS: %i(%c)\t Underlying: %i(%c)\t \t\t\t%c \n", i,all_vector[0][i][j] , all_vector[0][i][j] , all_vector[1][i][j],all_vector[1][i][j],(all_vector[0][i][j] == all_vector[1][i][j]) ? '.' : '*'); } } } diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 2572b944412..4682826bef5 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -13,16 +13,16 @@ #include "u16.h" enum ShiftState { - Base = 0, // 0 - Shft = 1, // 1 - Ctrl = 2, // 2 - ShftCtrl = Shft | Ctrl, // 3 - Menu = 4, // 4 -- NOT USED - ShftMenu = Shft | Menu, // 5 -- NOT USED - MenuCtrl = Menu | Ctrl, // 6 - ShftMenuCtrl = Shft | Menu | Ctrl, // 7 - Xxxx = 8, // 8 - ShftXxxx = Shft | Xxxx, // 9 + Base = 0, // 0 + Shft = 1, // 1 + Ctrl = 2, // 2 + ShftCtrl = Shft | Ctrl, // 3 + Menu = 4, // 4 -- NOT USED + ShftMenu = Shft | Menu, // 5 -- NOT USED + MenuCtrl = Menu | Ctrl, // 6 + ShftMenuCtrl = Shft | Menu | Ctrl, // 7 + Xxxx = 8, // 8 + ShftXxxx = Shft | Xxxx, // 9 }; // the shiftstates we can use for mac: Base;Shift, OPTION, Shift+OPTION @@ -60,25 +60,25 @@ typedef std::vector vec_dword_1D; typedef std::vector > vec_dword_2D; typedef std::vector > > vector_dword_3D; static KMX_DWORD INVALID_NAME = 0; -static KMX_DWORD max_shiftstate = 10; static KMX_DWORD keycode_max = 50; static int keycode_spacebar = 49; +static KMX_DWORD max_shiftstate = 10; -int mac_map_VKShiftState_to_Shiftstate(int vk_ShiftState); +int mac_convert_Shiftstate_to_MacShiftstate(int vk_ShiftState); int mac_map_rgkey_ShiftState_to_Shiftstate(int win_ShiftState); bool is_correct_win_shiftstate(int comp_ss); -bool is_correct_Input_For_KeyboardTranslation(const UCKeyboardLayout * keyboard_layout,int keycode, int shiftstate, int cap); +bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout * keyboard_layout,int keycode, int shiftstate, int cap); -int mac_createOneVectorFromBothKeyboards(vector_dword_3D &All_Vector, const UCKeyboardLayout * keykeyboard_layout); +int mac_createOneVectorFromBothKeyboards(vector_dword_3D &all_vector, const UCKeyboardLayout * keykeyboard_layout); int mac_write_US_ToVector(vector_dword_3D &vec); vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_shifts); -int mac_append_underlying_ToVector(vector_dword_3D &All_Vector, const UCKeyboardLayout * keykeyboard_layout); +int mac_append_underlying_ToVector(vector_dword_3D &all_vector, const UCKeyboardLayout * keykeyboard_layout); bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout); @@ -90,11 +90,11 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT kc_underlying, UINT VKShiftState, PKMX_WCHAR deadKey); -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vector_dword_3D &All_Vector, KMX_DWORD kv_us); +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vector_dword_3D &all_vector, KMX_DWORD kv_us); -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vector_dword_3D & All_Vector, KMX_DWORD kv_underlying); +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vector_dword_3D & all_vector, KMX_DWORD kv_underlying); -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, vector_dword_3D &All_Vector, KMX_DWORD kc_us, ShiftState ss, int caps); +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, vector_dword_3D &all_vector, KMX_DWORD kc_us, ShiftState ss, int caps); UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us); @@ -498,7 +498,7 @@ const UINT mac_USVirtualKeyToScanCode[256] = { //################################################################################################################################################ //################################################################################################################################################ -void test_printoutKeyboards_S2(vector_dword_3D &All_Vector); +void test_printoutKeyboards_S2(vector_dword_3D &all_vector); KMX_DWORD X_playWithDK_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal) ; KMX_DWORD X_playWithDK_S2_one(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal); KMX_DWORD X_compare_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index b66fd417c82..a9ffe2177eb 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -89,7 +89,7 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_win, int caps, if (!(caps <= 1)) return 0;*/ - if(! is_correct_Input_For_KeyboardTranslation(keyboard_layout, keycode, ss_win, caps)) + if(! ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, ss_win, caps)) return 0; keyval= mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_map_rgkey_ShiftState_to_Shiftstate(ShiftState(ss_win)), caps, isdk); @@ -252,7 +252,7 @@ class mac_KMX_VirtualKey { return nkeys; } - bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector *deadkeys, int deadkeyBase, BOOL bDeadkeyConversion, vector_dword_3D &All_Vector, const UCKeyboardLayout *keyboard_layout ) { // I4552 + bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector *deadkeys, int deadkeyBase, BOOL bDeadkeyConversion, vector_dword_3D &all_vector, const UCKeyboardLayout *keyboard_layout ) { // I4552 // Get the CAPSLOCK value /*int capslock = (this->mac_KMX_IsCapsEqualToShift() ? 1 : 0) | @@ -313,7 +313,7 @@ class mac_KMX_VirtualKey { // this->m_vk stores VK-US ( not underlying !!) // key->Key stores VK-US ( not underlying !!) // key->dpOutput stores character Underlying - KMX_DWORD SC_Underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keyboard_layout, All_Vector, this->SC(), (ShiftState) ss, caps); + KMX_DWORD SC_Underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keyboard_layout, all_vector, this->SC(), (ShiftState) ss, caps); key->Key = mac_KMX_get_VKUS_From_KeyCodeUnderlying( SC_Underlying); @@ -434,13 +434,13 @@ void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int ke /** * @brief Collect the key data, translate it to kmx and append to the existing keyboard * @param kp keyboard - * @param All_Vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param all_vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param keyboard_layout the currently used (underlying)keyboard Layout * @param FDeadkeys vector of all deadkeys for the currently used (underlying)keyboard Layout * @param bDeadkeyConversion 1 to convert a deadkey to a character; 0 no conversion * @return true in case of success */ -bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &All_Vector, const UCKeyboardLayout **keyboard_layout, std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 +bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const UCKeyboardLayout **keyboard_layout, std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 mac_KMX_Loader loader; std::vector rgKey; //= new VirtualKey[256]; @@ -462,7 +462,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &All_Vector, const // macOS cannot get a VK for the underling Keyboard since this does not exist // macOS can only get a VK for the US Keyboard (by using USVirtualKeyToScanCode/ScanCodeToUSVirtualKey) - // therefore in rgkey[ ] we use VK_US which we get from All_Vector + // therefore in rgkey[ ] we use VK_US which we get from all_vector mac_KMX_VirtualKey *key = new mac_KMX_VirtualKey(sc); @@ -603,7 +603,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &All_Vector, const // for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { if ((rgKey[iKey] != NULL) && rgKey[iKey]->mac_KMX_IsKeymanUsedKey() && (!rgKey[iKey]->mac_KMX_IsEmpty())) { - if(rgKey[iKey]->mac_KMX_LayoutRow(loader.KMX_MaxShiftState(), &gp->dpKeyArray[nkeys], &alDead, nDeadkey, bDeadkeyConversion, All_Vector,*keyboard_layout)) { // I4552 + if(rgKey[iKey]->mac_KMX_LayoutRow(loader.KMX_MaxShiftState(), &gp->dpKeyArray[nkeys], &alDead, nDeadkey, bDeadkeyConversion, all_vector,*keyboard_layout)) { // I4552 nkeys+=rgKey[iKey]->mac_KMX_GetKeyCount(loader.KMX_MaxShiftState()); } } diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 3a0fda673f6..2cfef115368 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -31,7 +31,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc); -bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &All_Vector, const UCKeyboardLayout **keyboard_layout, std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 +bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const UCKeyboardLayout **keyboard_layout, std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 std::vector KMX_FDeadkeys; // I4353 @@ -465,12 +465,12 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { * @param vk_US virtual key of the us keyboard * @param shift shiftstate * @param deadkey character produced by a deadkey - * @param All_Vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param all_vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param keyboard_layout the currently used (underlying) keyboard Layout * * @return void */ -void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, vector_dword_3D &All_Vector, const UCKeyboardLayout * keyboard_layout) { +void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, vector_dword_3D &all_vector, const UCKeyboardLayout * keyboard_layout) { KMX_WORD deadkeys[512]={0}; KMX_WORD *pdk; @@ -483,11 +483,11 @@ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_ KMX_FDeadkeys.push_back(KMX_deadkeyMapping); //dkid, vk, shift); // I4353 mac_KMX_AddDeadkeyRule(kbd, dkid, vk_US, shift); - mac_KMX_GetDeadkeys(keyboard_layout, All_Vector, deadkey, shift, pdk = deadkeys ); // returns array of [usvk, ch_out] pairs + mac_KMX_GetDeadkeys(keyboard_layout, all_vector, deadkey, shift, pdk = deadkeys ); // returns array of [usvk, ch_out] pairs while(*pdk) { // Look up the ch - UINT KeyValUnderlying = mac_KMX_get_KeyValUnderlying_From_KeyValUS(All_Vector, *pdk); + UINT KeyValUnderlying = mac_KMX_get_KeyValUnderlying_From_KeyValUS(all_vector, *pdk); mac_KMX_TranslateDeadkeyKeyboard(kbd, dkid, KeyValUnderlying, *(pdk+1), *(pdk+2)); pdk+=3; } @@ -553,13 +553,13 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int return FALSE; } // create vector that contains Keycode, Base, Shift for US-Keyboard and underlying keyboard - vector_dword_3D All_Vector; - if(mac_createOneVectorFromBothKeyboards(All_Vector, keyboard_layout)){ + vector_dword_3D all_vector; + if(mac_createOneVectorFromBothKeyboards(all_vector, keyboard_layout)){ wprintf(L"ERROR: can't create one vector from both keyboards\n"); return FALSE; } - //printoutKeyboards(All_Vector); + //printoutKeyboards(all_vector); find_character_S2(keyboard_layout, 180); printf("-------\n"); //print_dublicates_S2(keyboard_layout); @@ -584,7 +584,7 @@ printf("-------\n"); switch(ch) { case 0x0000: break; - case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keyboard_layout); break; + case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, all_vector, keyboard_layout); break; default: mac_KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); } } @@ -592,7 +592,7 @@ printf("-------\n"); mac_KMX_ReportUnconvertedKeyboardRules(kbd); - if(!mac_KMX_ImportRules(kbd, All_Vector, &keyboard_layout, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 + if(!mac_KMX_ImportRules(kbd, all_vector, &keyboard_layout, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 return FALSE; } @@ -603,13 +603,13 @@ printf("-------\n"); /** * @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard * @param keyboard_layout the currently used (underlying) keyboard Layout - * @param All_Vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param all_vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param deadkey deadkey character * @param shift_dk shiftstate of the deadkey * @param OutputPairs ptr to array of deadkeys * @return size of array of deadkeys */ -int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, vector_dword_3D &All_Vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ) { +int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, vector_dword_3D &all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ) { UInt32 deadkeystate; UniCharCount maxStringlength = 5; @@ -620,14 +620,14 @@ int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, vector_dword unicodeString[0] = 0; KMX_WORD *p = OutputPairs; - KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying( All_Vector, deadkey); + KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying( all_vector, deadkey); for ( int j=0; j < sizeof(ss_mac)/sizeof(ss_mac[0]); j++) { // we start with SPACE (keycode_spacebar=49) since all deadkeys occur in combinations with space. // Since mcompile finds only the first occurance of a dk combination, this makes sure that we always find the dk+SPACE combinations for a deadkey. // If there are more combinations to create a specific character they will not be found. (See comment at the beginning of mac_KMX_DoConvert()) for ( int i=keycode_spacebar; i >=0; i--) { - status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_map_VKShiftState_to_Shiftstate(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_convert_Shiftstate_to_MacShiftstate(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); if(deadkeystate !=0) { status = UCKeyTranslate(keyboard_layout, i, kUCKeyActionDown, ss_mac[j], LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 0e4848f6389..ab4bfa52d3c 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -39,7 +39,7 @@ int mac_run(int argc, std::vector str_argv, char* argv[]); PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); -int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, vector_dword_3D &All_Vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ); // returns array of [usvk, ch_out] pairs +int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, vector_dword_3D &all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ); // returns array of [usvk, ch_out] pairs void mac_KMX_LogError(const wchar_t* fmt, ...); From 1c0a44f2b0a8c12cba03ca08c0de248737f73c5d Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 10 Jul 2024 12:31:26 +0200 Subject: [PATCH 33/71] feat(mac): add module, fun-comments --- .clang-format | 4 +- mac/mcompile/keymap.cpp | 208 +++--------- mac/mcompile/keymap.h | 488 +++++++++++++++++----------- mac/mcompile/mc_import_rules.cpp | 333 ++++++++++--------- mac/mcompile/mc_import_rules.h | 25 +- mac/mcompile/mc_kmxfile.h | 43 ++- mac/mcompile/mcompile.cpp | 533 +++++++++++++++---------------- mac/mcompile/mcompile.h | 32 +- mac/mcompile/u16.cpp | 178 +++++------ mac/mcompile/u16.h | 51 ++- 10 files changed, 935 insertions(+), 960 deletions(-) diff --git a/.clang-format b/.clang-format index 76e36e1d44d..81ca2c82a37 100644 --- a/.clang-format +++ b/.clang-format @@ -19,7 +19,7 @@ AllowShortLambdasOnASingleLine: All AllowShortIfStatementsOnASingleLine: Never AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: AllDefinitions +AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: true AlwaysBreakTemplateDeclarations: MultiLine BinPackArguments: true @@ -58,7 +58,7 @@ ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DeriveLineEnding: true -DerivePointerAlignment: true +DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 2bc6ec64b0d..06f3b67e3ec 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -7,29 +7,17 @@ #include "keymap.h" #include "kmx_file.h" - /** - * @brief map shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on mac - * Windows: (Base: 00000000 (0); Shift 00010000 (16); AltGr 00001001 (9); Shift+AltGr 00011001 (25)) - * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10 ) - * @param shiftState shiftstate used on windows - * @return a shiftstate usable for UCKeyTranslate() on mac if available - */ + /** @brief map shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on mac */ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) { - if (shiftState == 0 ) return 0; // Win ss 0 -> mac ss 0 - else if (shiftState == K_SHIFTFLAG) return 2; // Win ss 0 -> mac ss 2 - else if (shiftState == (LCTRLFLAG | RALTFLAG)) return 8; // Win ss 0 -> mac ss 8 - else if (shiftState == (K_SHIFTFLAG | LCTRLFLAG | RALTFLAG)) return 10; // Win ss 0 -> mac ss 10 - else return shiftState; // Win x 0 -> mac ss x + if (shiftState == 0) return 0; // Win ss 0 -> mac ss 0 + else if (shiftState == K_SHIFTFLAG) return 2; // Win ss 16 -> mac ss 2 + else if (shiftState == (LCTRLFLAG | RALTFLAG)) return 8; // Win ss 9 -> mac ss 8 + else if (shiftState == (K_SHIFTFLAG | LCTRLFLAG | RALTFLAG)) return 10; // Win ss 25 -> mac ss 10 + else return shiftState; // Win ss x -> mac ss x } - /** - * @brief map shiftstate used for rgkey to shiftstate suitable for UCKeyTranslate() on mac - * rgkey: (Base: 0; Shift 1; OPT 6; Shift+OPT 7 ) - * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10) - * @param rgkey_ShiftState shiftstate used for rgkey - * @return int shiftstate usable for UCKeyTranslate() on mac if available - */ +// _S2 Todo int mac_map_rgkey_ShiftState_to_Shiftstate(int rgkey_ShiftState) { if (rgkey_ShiftState == 0 ) return 0; else if (rgkey_ShiftState == 1) return 2; @@ -39,25 +27,13 @@ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) { } - /** - * @brief check if the shiftstate value can be used - * @param win_ss shiftstate used on windows - * @return true on success; false on failure - */ +// _S2 Todo bool is_correct_win_shiftstate(int win_ss) { return ( (win_ss ==0) || (win_ss ==16) || (win_ss ==9) || (win_ss ==25) || (win_ss ==0xFFFF) ); } - - /** - * @brief check for correct input parameter - * What character will be produced for a keypress of a key and modifiers? - * @param keyboard_layout the currently used (underlying)keyboard Layout - * @param keycode a key of the currently used keyboard Layout - * @param shiftstate a shiftstate of the currently used keyboard Layout - * @param caps state of the caps key of the currently used keyboard Layout - * @return true if all parameters are OK; false if not - */ +// _S2 todo missing code +/** @brief check for correct input parameter that will later be used in UCKeyTranslate() */ bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout * keyboard_layout,int keycode, int shiftstate, int caps=0){ if (!keyboard_layout) @@ -75,26 +51,9 @@ bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout * keyboard_la return true; } - - - - - /** - * @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard : - * all_vector [ US_Keyboard ] - * [KeyCode_US ] - * [Keyval unshifted ] - * [Keyval shifted ] - * [Underlying Kbd] - * [KeyCode_underlying] - * [Keyval unshifted ] - * [Keyval shifted ] - * @param[out] all_vector Vector that holds the data of the US keyboard as well as the currently used (underlying) keyboard - * @param keyboard_layout ptr to currently used (underlying) keyboard Layout - * @return 0 on success; 1 if data of US keyboard was not written; 2 if data of underlying keyboard was not written - */ -int mac_createOneVectorFromBothKeyboards(vector_dword_3D& all_vector, const UCKeyboardLayout * keyboard_layout) { - + /** @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard */ +int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeyboardLayout * keyboard_layout) { + // store contents of the English (US) keyboard in all_vector if(mac_write_US_ToVector(all_vector)) { wprintf(L"ERROR: can't write US to Vector \n"); return 1; @@ -108,14 +67,9 @@ int mac_createOneVectorFromBothKeyboards(vector_dword_3D& all_vector, const UCKe return 0; } - - /** - * @brief write data of the US keyboard into a 3D-Vector which later will contain data of the US keyboard and the currently used (underlying) keyboard - * @param[out] vec_us Vector that holds the date - * @return 0 on success; 1 if data of US keyboard was not written; - */ -int mac_write_US_ToVector( vector_dword_3D& vec_us) { - + /** @brief write data of the US keyboard into a 3D-Vector */ +int mac_write_US_ToVector( vec_dword_3D& vec_us) { +//_S2 TODO // Values for US : A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P,CR, L, J, ', K, ;, \, ,, /, N, M, . std::vector us_Base = {97,115,100,102,104,103,122,120,99,118,167,98,113,119,101,114,121,116,49,50,51,52,54,53,61,57,55,45,56,48, 93,111,117, 91,105,112,13,108,106,39,107,59, 92,44,47,110,109,46}; std::vector us_Shift = {65, 83, 68, 70, 72, 71, 90, 88,67, 86,177,66, 81, 87, 69, 82, 89, 84,33,64,35,36,94,37,43,40,38,95,42,41,125, 79, 85,123, 73, 80,13, 76, 74,34, 75,58,124,60,63, 78, 77,62}; @@ -141,12 +95,7 @@ int mac_write_US_ToVector( vector_dword_3D& vec_us) { } - /** - * @brief create an 2D-Vector with all fields containing returnIfCharInvalid - * @param dim_rows number of rows in vector - * @param dim_ss number of columns in vector - * @return the 2D-Vector - */ + /** @brief create an 2D-Vector with all fields containing INVALID_NAME */ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss) { vec_dword_1D shifts; vec_dword_2D vector_2D; @@ -162,18 +111,14 @@ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss) { } - /** - * @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector - * @param[out] all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param keyboard_layout ptr to currently used (underlying) keyboard Layout - * @return 0 on success; 1 if the initialization of the underlying vector failes; 2 if data of less than 2 keyboards is contained in all_vector - */ -int mac_append_underlying_ToVector(vector_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { + /** @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector */ +int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { int caps=0; if (all_vector.size() != 1) { printf("ERROR: data for US keyboard not correct\n"); return 1; } + // create a 2D vector all filled with " " and push to 3D-Vector vec_dword_2D underlying_Vector2D = mac_create_empty_2D_Vector(all_vector[0].size(), all_vector[0][0].size()); @@ -188,12 +133,11 @@ int mac_append_underlying_ToVector(vector_dword_3D& all_vector, const UCKeyboard return 2; } - for(int i = 0; i < (int)all_vector[1].size(); i++) { - + for (int i = 0; i < (int)all_vector[1].size(); i++) { // get key name US stored in [0][i][0] and copy to name in "underlying"-block[1][i][0] all_vector[1][i][0] = all_vector[0][i][0]; - for( int k=0; k<2;k++) { + for ( int k=0; k < 2; k++) { all_vector[1][i][k+1] = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, all_vector[0][i][0], mac_map_rgkey_ShiftState_to_Shiftstate(k),0); } } @@ -202,12 +146,7 @@ int mac_append_underlying_ToVector(vector_dword_3D& all_vector, const UCKeyboard } - /** - * - * @brief create a pointer to the current keyboard layout - * @param[out] keyboard_layout* ptr to currently used (underlying) keyboard Layout - * @return 0 on success; 1 if the source is not found; 2 if the keyboard layout is not found - */ +/** @brief create a pointer to pointer of the current keymap for later use */ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); @@ -222,12 +161,12 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { wprintf(L"ERROR: Can't get keyboard_layout\n"); return 2; } -// intentionally leaking `display` in order to still be able to access `keymap` + // intentionally leaking `display` in order to still be able to access `keymap` return 0; } - /** + /** old * @brief return the keyvalue for a given Keycode, shiftstate and caps of the currently used (underlying) keyboard Layout * What character will be produced for a keypress of a key and modifiers? * @param keyboard_layout the currently used (underlying)keyboard Layout @@ -236,8 +175,8 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { * @param caps state of the caps key of the currently used keyboard Layout * @return the keyval obtained from Keycode, shiftstate and caps */ + /** @brief return the keyvalue for a given Keycode, shiftstate and caps */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps) { - UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; @@ -278,17 +217,7 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layo } - /** - * - * @brief return the keyvalue for a given Keycode, shiftstate and caps of the currently used (underlying) keyboard Layout taking the deadkeystate into account - * What character or deadkey will be produced for a keypress of a key and modifiers? - * @param keyboard_layout* ptr to currently used keyboard Layout - * @param keycode a key of the currently used keyboard - * @param shiftstate_mac a shiftstate of the currently used keyboard Layout - * @param caps state of the caps key of the currently used keyboard Layout - * @param[out] deadkeystate !=0 if a deadkey was found in translation; 0 if no deadkey was found - * @return the keyval obtained from Keycode, shiftstate and caps - */ + //_S2 ToDO KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32 &deadkeystate) { UniCharCount maxStringlength = 5; @@ -327,18 +256,9 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_l } - /** - * - * @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard Layout. If a deadkey was found return 0xFFFF and copy deadkey into deadKey - * What character will be produced for a keypress of a key and modifiers on the underlying keyboard? 0XFFFF in case of a deadkey? - * @param keyboard_layout the currently used (underlying)keyboard Layout - * @param kc_underlying a key of the currently used keyboard - * @param vk_ShiftState a shiftstate of the currently used keyboard Layout - * @param deadKey* ptr to keyvalue if a deadkey was found; if not NULL - * @return the keyval obtained from Keycode and shiftstate and caps or 0xFFFF in case a deadkey was found - */ -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey) { +/** @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout and copy deadkey into deadKey */ +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey) { PKMX_WCHAR dky = NULL; UInt32 isdk = 0; KMX_DWORD keyV; @@ -370,19 +290,11 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa } - /** - * - * @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard - * What character is on the same position/shiftstats/caps on the currently used (underlying) keyboard? - * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param kv_us a keyvalue on the US keyboard - * @return keyval of the underlying keyboard if available; else the keyval of the US keyboard - */ -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vector_dword_3D& all_vector, KMX_DWORD kv_us) { - +/** @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard */ +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us) { // look for kv_us for any shiftstate of US keyboard - for (int i = 0; i < all_vector[0].size() - 1; i++) { - for (int j = 1; j < all_vector[0][0].size(); j++) { + for (int i = 0; i < (int)all_vector[0].size() - 1; i++) { + for (int j = 1; j < (int)all_vector[0][0].size(); j++) { if (all_vector[0][i][j] == kv_us) return all_vector[1][i][j]; } @@ -390,8 +302,8 @@ KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vector_dword_3D& all_vecto return kv_us; } - -/** +// _S2 ToDo +/** old * * @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard * On what key of the underlying keyboard do we find a certain character? @@ -399,11 +311,11 @@ KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vector_dword_3D& all_vecto * @param kv_underlying a keyvalue on the currently used (underlying) keyboard * @return keycode of the underlying keyboardif foundf; else the keyval of the underlying keyboard */ -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vector_dword_3D& all_vector, KMX_DWORD kv_underlying) { +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying) { // look for kv_us for any shiftstate of US keyboard - for( int i=0; i< all_vector[1].size()-1 ;i++) { - for( int j=1; j< all_vector[1][0].size();j++) { + for ( int i=0; i< all_vector[1].size()-1 ;i++) { + for ( int j=1; j< all_vector[1][0].size();j++) { if ( all_vector[1][i][j] == kv_underlying ) { return all_vector[1][i][0]; } @@ -411,28 +323,16 @@ KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vector_dword_3D& } return kv_underlying; } - - - /** - * - * @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard - * Where on a underlying keyboard do we find a character that is on a certain key on a US keyboard? - * @param keyboard_layout the currently used (underlying)keyboard Layout - * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param kc_us a key of the US keyboard - * @param ss_win a windows-type shiftstate - * @param caps state of the caps key - * @return the keycode of the underlying keyboardif found; else the keycode of the US keyboard - */ -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, vector_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) { + /** @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard */ +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) { // first get the keyvalue of the key on the US keyboard (kc_us) - std::u16string keyval_us= std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_map_rgkey_ShiftState_to_Shiftstate(ss_win), caps) ); + std::u16string u16str = std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_map_rgkey_ShiftState_to_Shiftstate(ss_win), caps) ); // then find the same keyvalue on the underlying keyboard and return the keycode of that key on the underlying keyboard for (int i = 0; i < all_vector[1].size() - 1; i++) { for (int j = 1; j < all_vector[1][0].size(); j++) { - if (((KMX_DWORD) all_vector[1][i][j] == (KMX_DWORD)*keyval_us.c_str() ) ) + if (((KMX_DWORD) all_vector[1][i][j] == (KMX_DWORD)*u16str.c_str() ) ) return all_vector[1][i][0]; } } @@ -440,33 +340,21 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * } - /** - * - * @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard - * Which keycode of a underlying keyboard will be mapped to a virtuaĺ key of a US keyboard - * @param vk_us a virtual key of the US keyboard - * @return the keycode of the currently used (underlying) keyboard - */ + +/** @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard */ UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us) { // On mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an 'artificial' us virtual key return (mac_USVirtualKeyToScanCode[vk_us]); } - - /** - * - * @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard - * Which key of a underlying keyboard will be mapped to a virtual key of a US keyboard - * @param keycode a keycode of the currently used (underlying) keyboard - * @return the virtual key of the US keyboard - */ + /** @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard */ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { // On mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an keycode from an 'artificial' us virtual key return mac_ScanCodeToUSVirtualKey[keycode]; } - - /** +//_S2 TODO + /** old * * @brief return the keyvalue of a combination of deadkey + character if there is a combination available * What character will be produced for a deadkey + a character? @@ -508,7 +396,7 @@ KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyb //################################################################################################################################################ -void test_printoutKeyboards_S2(vector_dword_3D& all_vector) { +void test_printoutKeyboards_S2(vec_dword_3D& all_vector) { printf(" values of US - Values of underlying"); for ( int i=0; i< all_vector[0].size(); i++) { printf("-----------------------------\n"); diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 4682826bef5..7867fd045ca 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -1,10 +1,7 @@ - #pragma once #ifndef KEYMAP_H #define KEYMAP_H -// compile with. gcc -framework Carbon -o xxx.exe yy.cpp -// #import #include #include @@ -25,7 +22,7 @@ enum ShiftState { ShftXxxx = Shft | Xxxx, // 9 }; -// the shiftstates we can use for mac: Base;Shift, OPTION, Shift+OPTION +// shiftstates we can use for mac: Base;Shift, OPTION, Shift+OPTION static int ss_mac[]={0,2,8,10}; // Map of all US English virtual key codes that we can translate @@ -33,207 +30,113 @@ const KMX_DWORD KMX_VKMap[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - VK_SPACE, // 32 // + VK_SPACE, /* 32 */ - VK_ACCENT, // 192 VK_OEM_3 K_BKQUOTE // - VK_HYPHEN, // - 189 VK_OEM_MINUS // - VK_EQUAL, // = 187 VK_OEM_PLUS // + VK_ACCENT, /* 192 VK_OEM_3 K_BKQUOTE */ + VK_HYPHEN, /* - 189 VK_OEM_MINUS */ + VK_EQUAL, /* = 187 VK_OEM_PLUS */ - VK_LBRKT, // [ 219 VK_OEM_4 // - VK_RBRKT, // ] 221 VK_OEM_6 // - VK_BKSLASH, // \ 220 VK_OEM_5 // + VK_LBRKT, /* [ 219 VK_OEM_4 */ + VK_RBRKT, /* ] 221 VK_OEM_6 */ + VK_BKSLASH, /* \ 220 VK_OEM_5 */ - VK_COLON, // ; 186 VK_OEM_1 // - VK_QUOTE, // ' 222 VK_OEM_7 // + VK_COLON, /* ; 186 VK_OEM_1 */ + VK_QUOTE, /* ' 222 VK_OEM_7 */ - VK_COMMA, // , 188 VK_OEM_COMMA // - VK_PERIOD, // . 190 VK_OEM_PERIOD // - VK_SLASH, // / 191 VK_OEM_2 //ˍ + VK_COMMA, /* , 188 VK_OEM_COMMA */ + VK_PERIOD, /* . 190 VK_OEM_PERIOD */ + VK_SLASH, /* / 191 VK_OEM_2 */ - VK_xDF, // ß (?) 223// - VK_OEM_102, // < > | 226 // - 0 -}; + VK_xDF, /* ß (?) 223*/ + VK_OEM_102, /* < > | 226 */ + 0}; typedef std::vector vec_string_1D; typedef std::vector vec_dword_1D; typedef std::vector > vec_dword_2D; -typedef std::vector > > vector_dword_3D; +typedef std::vector > > vec_dword_3D; + static KMX_DWORD INVALID_NAME = 0; -static KMX_DWORD keycode_max = 50; -static int keycode_spacebar = 49; +static KMX_DWORD keycode_max = 50; +static int keycode_spacebar = 49; static KMX_DWORD max_shiftstate = 10; -int mac_convert_Shiftstate_to_MacShiftstate(int vk_ShiftState); - +/** + * @brief map shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on mac + * Windows: (Base: 00000000 (0); Shift 00010000 (16); AltGr 00001001 (9); Shift+AltGr 00011001 (25)) + * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10 ) + * @param shiftState shiftstate used on windows + * @return a shiftstate usable for UCKeyTranslate() on mac if available + * if shiftState is a windows ShiftState: convert the windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) + * if shiftState is NOT a windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate + */ +int mac_convert_Shiftstate_to_MacShiftstate(int shiftState); +// _S2 TODO int mac_map_rgkey_ShiftState_to_Shiftstate(int win_ShiftState); - +// _S2 TODO bool is_correct_win_shiftstate(int comp_ss); +/** + * @brief check for correct input parameter that will later be used in gdk_keymap_translate_keyboard_state() + * @param keyboard_layout ptr to the the currently used keyboard layout + * @param keycode the code of the key in question + * @param shiftstate the currently used shiftstate + * @param cap the code of the key in question + * @return true if all parameters are OK; false if not + */ bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout * keyboard_layout,int keycode, int shiftstate, int cap); -int mac_createOneVectorFromBothKeyboards(vector_dword_3D &all_vector, const UCKeyboardLayout * keykeyboard_layout); -int mac_write_US_ToVector(vector_dword_3D &vec); -vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_shifts); - -int mac_append_underlying_ToVector(vector_dword_3D &all_vector, const UCKeyboardLayout * keykeyboard_layout); +// _S2 TODO + + + +/** + * @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard : + * all_vector [ US_Keyboard ] + * [KeyCode_US ] + * [Keyval unshifted ] + * [Keyval shifted ] + * [Underlying Kbd] + * [KeyCode_underlying] + * [Keyval unshifted ] + * [Keyval shifted ] + * @param[in,out] all_vector Vector that holds the data of the US keyboard as well as the currently used (underlying) keyboard + * @param keyboard_layout ptr to currently used (underlying) keyboard layout + * @return 0 on success; 1 if data of US keyboard was not written; 2 if data of underlying keyboard was not written + */ +int mac_createOneVectorFromBothKeyboards(vec_dword_3D &all_vector, const UCKeyboardLayout * keyboard_layout); +/** + * @brief write data of the US keyboard into a 3D-Vector which later will contain + * data of the US keyboard and the currently used (underlying) keyboard + * @param[in,out] vec Vector that holds the data of the US keyboard + * @return 0 on success; 1 if data of US keyboard was not written; + */ +int mac_write_US_ToVector(vec_dword_3D &vec); +/** + * @brief create an 2D-Vector with all fields containing INVALID_NAME + * @param dim_rows number of rows in vector + * @param dim_ss number of columns in vector + * @return the 2D-Vector + */ +vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss); + + /** + * @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector + * @param[in,out] all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param keyboard_layout ptr to currently used (underlying) keybord layout + * @return 0 on success; 1 if the initialization of the underlying vector failes; 2 if data of less than 2 keyboards is contained in all_vector + */ +int mac_append_underlying_ToVector(vec_dword_3D &all_vector, const UCKeyboardLayout * keyboard_layout); +/** + * @brief create a pointer to pointer of the current keyboard_layout for later use + * @param keyboard_layout ptr to ptr to currently used (underlying) keyborad layout + * @return 0 on success; 1 if the display is not found; 2 if the keymap is not found + */ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout); -KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps); - -KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32 &deadkeystate); - -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int kc_underlying, int shiftstate_mac); - -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT kc_underlying, UINT VKShiftState, PKMX_WCHAR deadKey); - -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vector_dword_3D &all_vector, KMX_DWORD kv_us); - -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vector_dword_3D & all_vector, KMX_DWORD kv_underlying); - -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, vector_dword_3D &all_vector, KMX_DWORD kc_us, ShiftState ss, int caps); - -UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us); - -KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); - -KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps); - -// we use the same type of array as throughout Keyman even though we have lots of unused fields -const UINT mac_ScanCodeToUSVirtualKey[128] = { - 0x41, // L"K_A", // &H41 - 0x53, // L"K_S", // &H53 - 0x44, // L"K_D", // &H44 - 0x46, // L"K_F", // &H46 - 0x48, // L"K_H", // &H48 - 0x47, // L"K_G", // &H47 - 0x5A, // L"K_Z", // &H5A - 0x58, // L"K_X", // &H58 - 0x43, // L"K_C", // &H43 - 0x56, // L"K_V", // &H56 - 0xC0, // L"K_BKQUOTE", // &HC0 (192) - 0x42, // L"K_B", // &H42 - 0x51, // L"K_Q", // &H51 - 0x57, // L"K_W", // &H57 - 0x45, // L"K_E", // &H45 - 0x52, // L"K_R", // &H52 - 0x59, // L"K_Y", // &H59 - 0x54, // L"K_T", // &H54 - 0x31, // L"K_1", // &H31 - 0x32, // L"K_2", // &H32 - 0x33, // L"K_3", // &H33 - 0x34, // L"K_4", // &H34 - 0x36, // L"K_6", // &H36 - 0x35, // L"K_5", // &H35 - 0xBB, // L"K_EQUAL", // &HBB (187) - 0x39, // L"K_9", // &H39 - 0x37, // L"K_7", // &H37 - 0xBD, // L"K_H YPHEN", // &HBD (189) - 0x38, // L"K_8", // &H38 - 0x30, // L"K_0", // &H30 - 0xDD, // L"K_RBRKT", // &HDD (221) - 0x4F, // L"K_O", // &H4F - 0x55, // L"K_U", // &H55 - 0xDB, // L"K_LBRKT", // &HDB (219) - 0x49, // L"K_I", // &H49 - 0x50, // L"K_P", // &H50 - 0x00, // not used // ---- - 0x4C, // L"K_L", // &H4C - 0x4A, // L"K_J", // &H4A - 0xDE, // L"K_QUOTE", // &HDE (222) - 0x4B, // L"K_K", // &H4B - 0xBA, // L"K_COLON", // &HBA (186) - 0xDC, // L"K_BKSLASH", // &HDC (220) - 0xBC, // L"K_COMMA", // &HBC (188) - 0xBF, // L"K_SLASH", // &HBF (191) - 0x4E, // L"K_N", // &H4E - 0x4D, // L"K_M", // &H4D - 0xBE, // L"K_PERIOD", // &HBE (190) - 0x00, // not used // ---- - 0x20, // L"K_SPACE", // &H1 - 0xE2, // L"K_oE2", // &HE2 (226) - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used -}; - // we use the same type of array as throughout Keyman even though we have lots of unused fields const UINT mac_USVirtualKeyToScanCode[256] = { 0xFFFF, // not used @@ -495,10 +398,227 @@ const UINT mac_USVirtualKeyToScanCode[256] = { }; +// we use the same type of array as throughout Keyman even though we have lots of unused fields +const UINT mac_ScanCodeToUSVirtualKey[128] = { + 0x41, // L"K_A", // &H41 + 0x53, // L"K_S", // &H53 + 0x44, // L"K_D", // &H44 + 0x46, // L"K_F", // &H46 + 0x48, // L"K_H", // &H48 + 0x47, // L"K_G", // &H47 + 0x5A, // L"K_Z", // &H5A + 0x58, // L"K_X", // &H58 + 0x43, // L"K_C", // &H43 + 0x56, // L"K_V", // &H56 + 0xC0, // L"K_BKQUOTE", // &HC0 (192) + 0x42, // L"K_B", // &H42 + 0x51, // L"K_Q", // &H51 + 0x57, // L"K_W", // &H57 + 0x45, // L"K_E", // &H45 + 0x52, // L"K_R", // &H52 + 0x59, // L"K_Y", // &H59 + 0x54, // L"K_T", // &H54 + 0x31, // L"K_1", // &H31 + 0x32, // L"K_2", // &H32 + 0x33, // L"K_3", // &H33 + 0x34, // L"K_4", // &H34 + 0x36, // L"K_6", // &H36 + 0x35, // L"K_5", // &H35 + 0xBB, // L"K_EQUAL", // &HBB (187) + 0x39, // L"K_9", // &H39 + 0x37, // L"K_7", // &H37 + 0xBD, // L"K_H YPHEN", // &HBD (189) + 0x38, // L"K_8", // &H38 + 0x30, // L"K_0", // &H30 + 0xDD, // L"K_RBRKT", // &HDD (221) + 0x4F, // L"K_O", // &H4F + 0x55, // L"K_U", // &H55 + 0xDB, // L"K_LBRKT", // &HDB (219) + 0x49, // L"K_I", // &H49 + 0x50, // L"K_P", // &H50 + 0x00, // not used // ---- + 0x4C, // L"K_L", // &H4C + 0x4A, // L"K_J", // &H4A + 0xDE, // L"K_QUOTE", // &HDE (222) + 0x4B, // L"K_K", // &H4B + 0xBA, // L"K_COLON", // &HBA (186) + 0xDC, // L"K_BKSLASH", // &HDC (220) + 0xBC, // L"K_COMMA", // &HBC (188) + 0xBF, // L"K_SLASH", // &HBF (191) + 0x4E, // L"K_N", // &H4E + 0x4D, // L"K_M", // &H4D + 0xBE, // L"K_PERIOD", // &HBE (190) + 0x00, // not used // ---- + 0x20, // L"K_SPACE", // &H1 + 0xE2, // L"K_oE2", // &HE2 (226) + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used +}; +// _S2 TODO IsKeymanUsedChar()?? +// _S2 TODO convert_DeadkeyValues_To_U16str?? + +/** + * @brief return the keyvalue for a given Keycode, shiftstate and caps of the + * currently used (underlying) keyboard layout + * "What character will be produced for a keypress of a key and modifiers?" + * @param keyboard_layout pointer to the currently used (underlying) keyboard layout + * @param keycode a key of the currently used keyboard layout + * @param ss a (windows-)shiftstate of the currently used keyboard layout _S2 + * @param caps state of the caps key of the currently used keyboard layout + * @return the keyval obtained from keycode, shiftstate and caps + */ +// _S2 ShiftState ss vs int shiftstate_mac +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps); + +//_S2 TODO +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32 &deadkeystate); + +/** // _S2 shift_state_pos vs int shiftstate_mac + * @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. + * "What character will be produced for a keypress of a key and modifiers on the underlying keyboard?" + * @param keyboard_layout a pointer to the currently used (underlying) keyboard layout + * @param keycode a key of the currently used keyboard + * @param shift_state_pos a shiftstate of the currently used keyboard layout + * @return the keyval obtained from Keycode and shiftstate; + */ +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac); + +/** + * @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. + * "What character will be produced for a keypress of a key and modifiers on the underlying keyboard? + * If a deadkey was found return 0xFFFF and copy the deadkey into deadKey + * This function is similar to KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap* keymap, guint keycode, int shiftState) + * but processes deadkeys + * @param keyboard_layout a pointer to the currently used (underlying) keyboard layout + * @param keycode a key of the currently used keyboard + * @param shiftState a shiftstate of the currently used keyboard layout + * @param deadKey* ptr to keyvalue if a deadkey was found; if not NULL + * @return 0xFFFF in case a deadkey was found, then the deadkey is stored in deadKey + * the keyval obtained from Keycode and shiftstate and caps; + */ +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT keycode, UINT shiftState, PKMX_WCHAR deadKey); + +/** + * @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard + * "What character is on the same position/shiftstats/caps on the currently used (underlying) keyboard?" + * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param kv_us a keyvalue on the US keyboard + * @return keyval of the underlying keyboard if available; else the keyval of the US keyboard + */ +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D &all_vector, KMX_DWORD kv_us); + +/** + * @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard + * "Where on an underlying keyboard do we find a character that is on a certain key on a US keyboard?" + * @param keyboard_layout the currently used (underlying) keyboard layout + * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param kc_us a key of the US keyboard + * @param ss a windows-type shiftstate + * @param caps state of the caps key + * @return the keycode of the underlying keyboard if found; else the keycode of the US keyboard + */ +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, vec_dword_3D &all_vector, KMX_DWORD kc_us, ShiftState ss, int caps); + +/** + * @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard + * "Which keycode of an underlying keyboard will be mapped to a virtuaĺ key of a US keyboard?" + * @param virtualKeyUS a virtual key of the US keyboard + * @return the keycode of the currently used (underlying) keyboard + */ +UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD virtualKeyUS); + + /** + * @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard + * "Which key of a underlying keyboard will be mapped to a virtual key of a US keyboard?" + * @param keycode a keycode of the currently used (underlying) keyboard + * @return the virtual key of the US keyboard or 0 + */ +KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); + +//_S2 TODO +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D & all_vector, KMX_DWORD kv_underlying); +//_S2 TODO +KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps); +//_S2 TODO CodePointToU16String?? //################################################################################################################################################ //################################################################################################################################################ -void test_printoutKeyboards_S2(vector_dword_3D &all_vector); +void test_printoutKeyboards_S2(vec_dword_3D &all_vector); KMX_DWORD X_playWithDK_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal) ; KMX_DWORD X_playWithDK_S2_one(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal); KMX_DWORD X_compare_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index a9ffe2177eb..607a564c009 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -1,24 +1,8 @@ - /* - Name: mc_import_rules - Copyright: Copyright (C) SIL International. - Documentation: - Description: - Create Date: 3 Aug 2014 - - Modified Date: 6 Feb 2015 - Authors: mcdurdin - Related Files: - Dependencies: - - Bugs: - Todo: - Notes: - History: 03 Aug 2014 - mcdurdin - I4327 - V9.0 - Mnemonic layout compiler follow-up - 03 Aug 2014 - mcdurdin - I4353 - V9.0 - mnemonic layout recompiler mixes up deadkey rules - 31 Dec 2014 - mcdurdin - I4550 - V9.0 - logical flaw in mnemonic layout recompiler means that AltGr base keys are never processed - 06 Feb 2015 - mcdurdin - I4552 - V9.0 - Add mnemonic recompile option to ignore deadkeys -*/ + * Keyman is copyright (C) 2004 SIL International. MIT License. + * + * Mnemonic layout support for Linux + */ #include #include @@ -36,46 +20,49 @@ const int KMX_ShiftStateMap[] = { ISVIRTUALKEY | RALTFLAG, ISVIRTUALKEY | RALTFLAG | K_SHIFTFLAG, 0, - 0 -}; + 0}; +/** @brief Constructor */ DeadKey::DeadKey(KMX_WCHAR deadCharacter) { this->m_deadchar = deadCharacter; } +/** @brief return character */ KMX_WCHAR DeadKey::KMX_DeadCharacter() { return this->m_deadchar; } +/** @brief set Deadkey with values */ void DeadKey::KMX_AddDeadKeyRow(KMX_WCHAR baseCharacter, KMX_WCHAR combinedCharacter) { this->m_rgbasechar.push_back(baseCharacter); this->m_rgcombchar.push_back(combinedCharacter); } +/** @brief check if character exists in DeadKey */ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { std::vector::iterator it; - for(it=this->m_rgbasechar.begin(); itm_rgbasechar.begin(); it < m_rgbasechar.end(); it++) { + if (*it == baseCharacter) { return true; } } return false; } - -bool test_alDead_S2(std::vector ald); - -/** - * @brief a function similar to Window`s ToUnicodeEx() function. Find a keyvalue for given keycode, shiftstate and caps - * @param keycode a key of the currently used keyboard Layout - * @param pwszBuff Buffer to store resulting character - * @param ss_win a windows-style shiftstate of the currently used keyboard Layout - * @param caps state of the caps key of the currently used keyboard Layout - * @param keyboard_layout the currently used (underlying)keyboard Layout - * @return -1 if a deadkey was found; 0 if no translation is available; +1 if character was found and written to pwszBuff - */ -int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_win, int caps, const UCKeyboardLayout * keyboard_layout) { +//_S2 remove! +bool test_alDead_S2(std::vector ald); + +/** // _S2 at merge: better description in other branch: + * @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. + * @param keycode a key of the currently used keyboard Layout + * @param pwszBuff Buffer to store resulting character + * @param ss_win a windows-style shiftstate of the currently used keyboard Layout + * @param caps state of the caps key of the currently used keyboard Layout + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @return -1 if a deadkey was found; 0 if no translation is available; +1 if character was found and written to pwszBuff + */ +int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_win, int caps, const UCKeyboardLayout* keyboard_layout) { KMX_DWORD keyval; - UInt32 isdk=0; + UInt32 isdk = 0; /*if (!keyboard_layout) return 0; @@ -89,14 +76,14 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_win, int caps, if (!(caps <= 1)) return 0;*/ - if(! ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, ss_win, caps)) + if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, ss_win, caps)) return 0; keyval= mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_map_rgkey_ShiftState_to_Shiftstate(ShiftState(ss_win)), caps, isdk); std::u16string str =std::u16string(1, keyval ); - pwszBuff[0]= * (PKMX_WCHAR) str.c_str(); + pwszBuff[0] = *(PKMX_WCHAR)str.c_str(); - if ((isdk) && (keycode!= 0xFFFF)) // deadkeys + if ((isdk) && (keycode != 0xFFFF)) // deadkeys return -1; if (keyval == 0) // no character return 0; @@ -104,21 +91,22 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_win, int caps, return 1; } -int mac_KMX_DeadKeyMap(int index, std::vector *deadkeys, int deadkeyBase, std::vector *deadkeyMappings) { // I4327 // I4353 - for(size_t i = 0; i < deadkeyMappings->size(); i++) { - if((*deadkeyMappings)[i].deadkey == index) { +int mac_KMX_DeadKeyMap(int index, std::vector*deadkeys, int deadkeyBase, std::vector*deadkeyMappings) { // I4327 // I4353 + for (size_t i = 0; i < deadkeyMappings->size(); i++) { + if ((*deadkeyMappings)[i].deadkey == index) { return (*deadkeyMappings)[i].dkid; } } - for(size_t i = 0; i < deadkeys->size(); i++) { - if((*deadkeys)[i]->KMX_DeadCharacter() == index) { + for (size_t i = 0; i < deadkeys->size(); i++) { + if ((*deadkeys)[i]->KMX_DeadCharacter() == index) { return deadkeyBase + i; } } return 0xFFFF; } +/** @brief Base class for dealing with rgkey*/ class mac_KMX_VirtualKey { private: UINT m_vk; @@ -127,11 +115,10 @@ class mac_KMX_VirtualKey { std::u16string m_rgss[10][2]; public: - mac_KMX_VirtualKey(UINT scanCode) { this->m_vk = mac_KMX_get_VKUS_From_KeyCodeUnderlying(scanCode); this->m_sc = scanCode; - memset(this->m_rgfDeadKey,0,sizeof(this->m_rgfDeadKey)); + memset(this->m_rgfDeadKey, 0, sizeof(this->m_rgfDeadKey)); } UINT VK() { @@ -227,8 +214,7 @@ class mac_KMX_VirtualKey { continue; } for (int caps = 0; caps <= 1; caps++) { - - std::u16string st = this->mac_KMX_GetShiftState((ShiftState) ss, (caps == 1)); + std::u16string st = this->mac_KMX_GetShiftState((ShiftState)ss, (caps == 1)); // ctrl and sh+ctrl will be skipped since rgkey has no entries in m_rgss[2] m_rgss[3] if (st.size() == 0) { // No character assigned here @@ -238,12 +224,13 @@ class mac_KMX_VirtualKey { } else { bool isvalid = true; for (size_t ich = 0; ich < st.size(); ich++) { - if(st[ich] < 0x20 || st[ich] == 0x7F) { - isvalid=false; + if (st[ich] < 0x20 || st[ich] == 0x7F) { + isvalid = false; wprintf(L"invalid for: %i\n", st[ich]); - break; } + break; + } } - if(isvalid) { + if (isvalid) { nkeys++; } } @@ -252,7 +239,7 @@ class mac_KMX_VirtualKey { return nkeys; } - bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector *deadkeys, int deadkeyBase, BOOL bDeadkeyConversion, vector_dword_3D &all_vector, const UCKeyboardLayout *keyboard_layout ) { // I4552 + bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector*deadkeys, int deadkeyBase, BOOL bDeadkeyConversion, vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { // I4552 // Get the CAPSLOCK value /*int capslock = (this->mac_KMX_IsCapsEqualToShift() ? 1 : 0) | @@ -260,7 +247,7 @@ class mac_KMX_VirtualKey { (this->mac_KMX_IsAltGrCapsEqualToAltGrShift() ? 4 : 0) | (this->mac_KMX_IsXxxxGrCapsEqualToXxxxShift() ? 8 : 0);*/ - int capslock = 1; //we do not use the equation to obtain capslock. On Mac we set capslock=1 + int capslock = 1; // we do not use the equation to obtain capslock. On Mac we set capslock=1 for (int ss = 0; ss <= MaxShiftState; ss++) { if (ss == Menu || ss == ShftMenu) { @@ -268,62 +255,60 @@ class mac_KMX_VirtualKey { continue; } for (int caps = 0; caps <= 1; caps++) { - std::u16string st = this->mac_KMX_GetShiftState((ShiftState) ss, (caps == 1)); + std::u16string st = this->mac_KMX_GetShiftState((ShiftState)ss, (caps == 1)); PKMX_WCHAR p; if (st.size() == 0) { // No character assigned here - } - else if (this->m_rgfDeadKey[(int)ss][caps]) { + } else if (this->m_rgfDeadKey[(int)ss][caps]) { // It's a dead key, append an @ sign. key->dpContext = new KMX_WCHAR[1]; *key->dpContext = 0; - key->ShiftFlags = this->KMX_GetShiftStateValue(capslock, caps, (ShiftState) ss); + key->ShiftFlags = this->KMX_GetShiftStateValue(capslock, caps, (ShiftState)ss); // we already use VK_US so no need to convert it as we do on windows key->Key = this->VK(); key->Line = 0; - if(bDeadkeyConversion) { // I4552 + if (bDeadkeyConversion) { // I4552 p = key->dpOutput = new KMX_WCHAR[2]; *p++ = st[0]; *p = 0; } else { - p = key->dpOutput = new KMX_WCHAR[4]; *p++ = UC_SENTINEL; *p++ = CODE_DEADKEY; - *p++ = mac_KMX_DeadKeyMap(st[0], deadkeys, deadkeyBase, &KMX_FDeadkeys); // I4353 + *p++ = mac_KMX_DeadKeyMap(st[0], deadkeys, deadkeyBase, &KMX_FDeadkeys); // I4353 *p = 0; } key++; - } - else { + } else { bool isvalid = true; for (size_t ich = 0; ich < st.size(); ich++) { - if(st[ich] < 0x20 || st[ich] == 0x7F) { - isvalid=false; + if (st[ich] < 0x20 || st[ich] == 0x7F) { + isvalid = false; wprintf(L"invalid 16 for: %i\n", st[ich]); - break; } + break; + } } - if(isvalid) { + if (isvalid) { // this is different to mcompile windows !!!! // this->m_sc stores SC-US = SCUnderlying // this->m_vk stores VK-US ( not underlying !!) // key->Key stores VK-US ( not underlying !!) // key->dpOutput stores character Underlying - KMX_DWORD SC_Underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keyboard_layout, all_vector, this->SC(), (ShiftState) ss, caps); + KMX_DWORD SC_Underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keyboard_layout, all_vector, this->SC(), (ShiftState)ss, caps); - key->Key = mac_KMX_get_VKUS_From_KeyCodeUnderlying( SC_Underlying); + key->Key = mac_KMX_get_VKUS_From_KeyCodeUnderlying(SC_Underlying); key->Line = 0; - key->ShiftFlags = this->KMX_GetShiftStateValue(capslock, caps, (ShiftState) ss); + key->ShiftFlags = this->KMX_GetShiftStateValue(capslock, caps, (ShiftState)ss); key->dpContext = new KMX_WCHAR; *key->dpContext = 0; p = key->dpOutput = new KMX_WCHAR[st.size() + 1]; - for(size_t ich = 0; ich < st.size(); ich++) { + for (size_t ich = 0; ich < st.size(); ich++) { *p++ = st[ich]; } *p = 0; @@ -336,6 +321,7 @@ class mac_KMX_VirtualKey { } }; +/** @brief Base class for KMX_loader*/ class mac_KMX_Loader { private: KMX_BYTE lpKeyStateNull[256]; @@ -363,35 +349,34 @@ class mac_KMX_Loader { return (ch < 0x0020) || (ch >= 0x007F && ch <= 0x009F); } - DeadKey *ProcessDeadKey( - UINT iKeyDead, // The index into the VirtualKey of the dead key - ShiftState shiftStateDead, // The shiftstate that contains the dead key - std::vector rgKey, // Our array of dead keys - bool fCapsLock, // Was the caps lock key pressed? - const UCKeyboardLayout * keyboard_layout) { // The keyboard layout + DeadKey* ProcessDeadKey( + UINT iKeyDead, // The index into the VirtualKey of the dead key + ShiftState shiftStateDead, // The shiftstate that contains the dead key + std::vector rgKey, // Our array of dead keys + bool fCapsLock, // Was the caps lock key pressed? + const UCKeyboardLayout* keyboard_layout) { // The keyboard layout - int maxshiftstate=2; - DeadKey *deadKey = new DeadKey(rgKey[iKeyDead]->mac_KMX_GetShiftState(shiftStateDead, fCapsLock)[0]); + int maxshiftstate = 2; + DeadKey* deadKey = new DeadKey(rgKey[iKeyDead]->mac_KMX_GetShiftState(shiftStateDead, fCapsLock)[0]); int ss_dead = mac_map_rgkey_ShiftState_to_Shiftstate(shiftStateDead); - KMX_DWORD keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead], ss_dead,0); - - for( int i=0; i< keycode_spacebar+1; i++) { - for( int j=0; j< maxshiftstate ; j++) { - for( int caps = 0; caps < 1; caps++) { + KMX_DWORD keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead], ss_dead, 0); + for (int i = 0; i < keycode_spacebar + 1; i++) { + for (int j = 0; j < maxshiftstate; j++) { + for (int caps = 0; caps < 1; caps++) { // e.g. a basechar - KMX_DWORD basechar = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[j], caps); + KMX_DWORD basechar = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[j], caps); // e.g. â combchar KMX_DWORD KC_Underlying_dk = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKeyDead); - KMX_DWORD combchar= mac_get_CombinedChar_From_DK(KC_Underlying_dk, ss_dead, keyboard_layout, i, ss_mac[j], caps); + KMX_DWORD combchar = mac_get_CombinedChar_From_DK(KC_Underlying_dk, ss_dead, keyboard_layout, i, ss_mac[j], caps); - if(combchar== 0) + if (combchar == 0) continue; // push only for if combchar is not dk or combchar is dk with space - if( (!(combchar== keyval_underlying_dk)) || (basechar == mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode_spacebar, ss_mac[j], caps))) { + if ((!(combchar== keyval_underlying_dk)) || (basechar == mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode_spacebar, ss_mac[j], caps))) { deadKey->KMX_AddDeadKeyRow(basechar, combchar); //printf( " processed basechar %i(%c) with dk %i(%c) ===> combchar%i(%c) \t\t ss[%i](%i) caps%i \n", basechar,basechar ,keyval_underlying_dk,keyval_underlying_dk, combchar,combchar, j, ss[j], caps ); } @@ -406,15 +391,20 @@ class mac_KMX_Loader { int rc = 0; do { rc = ::ToUnicodeEx(vk, sc, lpKeyStateNull, sb, _countof(sb), 0, hkl); - } while(rc != 1 && rc != 0); + } while (rc != 1 && rc != 0); }*/ }; -int mac_KMX_GetMaxDeadkeyIndex(KMX_WCHAR *p) { +/** + * @brief find the maximum index of a deadkey + * @param p pointer to deadkey + * @return index of deadkey + */ +int mac_KMX_GetMaxDeadkeyIndex(KMX_WCHAR* p) { int n = 0; - while(p && *p) { - if(*p == UC_SENTINEL && *(p+1) == CODE_DEADKEY) - n = std::max(n, (int) *(p+2)); + while (p && *p) { + if (*p == UC_SENTINEL && *(p + 1) == CODE_DEADKEY) + n = std::max(n, (int)*(p + 2)); p = KMX_incxstr(p); } return n; @@ -432,15 +422,20 @@ void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout); void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode); /** - * @brief Collect the key data, translate it to kmx and append to the existing keyboard - * @param kp keyboard - * @param all_vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param keyboard_layout the currently used (underlying)keyboard Layout - * @param FDeadkeys vector of all deadkeys for the currently used (underlying)keyboard Layout - * @param bDeadkeyConversion 1 to convert a deadkey to a character; 0 no conversion - * @return true in case of success - */ -bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const UCKeyboardLayout **keyboard_layout, std::vector *FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 + * @brief Collect the key data, translate it to kmx and append to the existing keyboard + * It is important to understand that this function has different sorting order in rgkey compared to mcompile-windows! + * On windows the values of rgkey are sorted according to the VK of the underlying keyboard + * On Linux the values of rgkey are sorted according to the VK of the the US keyboard + * Since Linux Keyboards do not use a VK mcompile uses the VK of the the US keyboard because + * these are available in mcompile through USVirtualKeyToScanCode/ScanCodeToUSVirtualKey and an offset of 8 + * @param kp pointer to keyboard + * @param all_vector vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @param FDeadkeys vector of all deadkeys for the currently used (underlying)keyboard Layout + * @param bDeadkeyConversion 1 to convert a deadkey to a character; 0 no conversion + * @return true in case of success + */ +bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKeyboardLayout** keyboard_layout, std::vector* FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 mac_KMX_Loader loader; std::vector rgKey; //= new VirtualKey[256]; @@ -453,8 +448,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const // flag that the VK is valid, and it can store the SC value. //Windows and Linux Keycodes start with 1; Mac keycodes start with 0 - for(UINT sc = 0x00; sc <= 0x7f; sc++) { - + for (UINT sc = 0x00; sc <= 0x7f; sc++) { // HERE IS A BIG DIFFERENCE COMPARED TO MCOMPILE FOR WINDOWS: // mcompile on Windows fills rgkey.m_vk with the VK of the Underlying keyboard // mcompile for macOS fills rgkey.m_vk with the VK of the US keyboard @@ -464,9 +458,9 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const // macOS can only get a VK for the US Keyboard (by using USVirtualKeyToScanCode/ScanCodeToUSVirtualKey) // therefore in rgkey[ ] we use VK_US which we get from all_vector - mac_KMX_VirtualKey *key = new mac_KMX_VirtualKey(sc); + mac_KMX_VirtualKey* key = new mac_KMX_VirtualKey(sc); - if((key->VK() != 0) ) { + if ((key->VK() != 0)) { rgKey[key->VK()] = key; } else { delete key; @@ -479,53 +473,50 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const // rgKey[VK_DECIMAL] = new mac_KMX_VirtualKey(hkl, VK_DECIMAL); // in this part we skip shiftstates 4, 5, 8, 9 - for(UINT iKey = 0; iKey < rgKey.size(); iKey++) { - - if(rgKey[iKey] != NULL) { - KMX_WCHAR sbBuffer[256]; // Scratchpad we use many places - for(ShiftState ss = Base; ss <= loader.KMX_MaxShiftState(); ss = (ShiftState)((int)ss + 1)) { - if(ss == Menu || ss == ShftMenu) { + for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { + if (rgKey[iKey] != NULL) { + KMX_WCHAR sbBuffer[256]; // Scratchpad we use many places + for (ShiftState ss = Base; ss <= loader.KMX_MaxShiftState(); ss = (ShiftState)((int)ss + 1)) { + if (ss == Menu || ss == ShftMenu) { // Alt and Shift+Alt don't work, so skip them (ss 4+5) continue; } //_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! - if(ss == MenuCtrl|| ss == ShftMenuCtrl) { + if (ss == MenuCtrl || ss == ShftMenuCtrl) { continue; } - KMX_DWORD KC_US = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); + KMX_DWORD KC_US = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); - for(int caps = 0; caps <= 1; caps++) { + for (int caps = 0; caps <= 1; caps++) { int rc = mac_KMX_ToUnicodeEx(KC_US, sbBuffer, ss, caps, *keyboard_layout); - if(rc > 0) { - if(*sbBuffer == 0) { - rgKey[iKey]->mac_KMX_SetShiftState(ss, u"", false, (caps)); // different to windows since behavior on mac is different - } - else { - if( (ss == Ctrl || ss == ShftCtrl) ) { + if (rc > 0) { + if (*sbBuffer == 0) { + rgKey[iKey]->mac_KMX_SetShiftState(ss, u"", false, (caps)); // different to windows since behavior on mac is different + } else { + if ((ss == Ctrl || ss == ShftCtrl)) { continue; } sbBuffer[rc] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to windows since behavior on mac is different } - } - else if(rc < 0) { + } else if (rc < 0) { sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on mac is different sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps == 0)); - DeadKey *dk = NULL; - for(UINT iDead = 0; iDead < alDead.size(); iDead++) { + DeadKey* dk = NULL; + for (UINT iDead = 0; iDead < alDead.size(); iDead++) { dk = alDead[iDead]; - if(dk->KMX_DeadCharacter() == rgKey[iKey]->mac_KMX_GetShiftState(ss, caps == 0)[0]) { + if (dk->KMX_DeadCharacter() == rgKey[iKey]->mac_KMX_GetShiftState(ss, caps == 0)[0]) { break; } dk = NULL; } - if(dk == NULL) { + if (dk == NULL) { alDead.push_back(loader.ProcessDeadKey(iKey, ss, rgKey, caps == 0, *keyboard_layout)); } } @@ -561,8 +552,8 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const // kp->dpGroupArray = gp; - for(UINT i = 0; i < kp->cxGroupArray; i++, gp++) { - //if(gp->fUsingKeys && gp->dpNoMatch == NULL) { // I4550 + for (UINT i = 0; i < kp->cxGroupArray; i++, gp++) { + //if (gp->fUsingKeys && gp->dpNoMatch == NULL) { // I4550 // WCHAR *p = gp->dpNoMatch = new WCHAR[4]; // *p++ = UC_SENTINEL; // *p++ = CODE_USE; @@ -571,54 +562,54 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const //} LPKMX_KEY kkp = gp->dpKeyArray; - for(UINT j = 0; j < gp->cxKeyArray; j++, kkp++) { + for (UINT j = 0; j < gp->cxKeyArray; j++, kkp++) { nDeadkey = std::max(nDeadkey, mac_KMX_GetMaxDeadkeyIndex(kkp->dpContext)); nDeadkey = std::max(nDeadkey, mac_KMX_GetMaxDeadkeyIndex(kkp->dpOutput)); } } - kp->cxGroupArray++; - gp = &kp->dpGroupArray[kp->cxGroupArray-1]; + gp = &kp->dpGroupArray[kp->cxGroupArray - 1]; + + // calculate the required size of `gp->dpKeyArray` UINT nkeys = 0; for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { if ((rgKey[iKey] != NULL) && rgKey[iKey]->mac_KMX_IsKeymanUsedKey() && (!rgKey[iKey]->mac_KMX_IsEmpty())) { - nkeys+= rgKey[iKey]->mac_KMX_GetKeyCount(loader.KMX_MaxShiftState()); + nkeys += rgKey[iKey]->mac_KMX_GetKeyCount(loader.KMX_MaxShiftState()); } } - nDeadkey++; // ensure a 1-based index above the max deadkey value already in the keyboard - gp->fUsingKeys = TRUE; gp->dpMatch = NULL; gp->dpName = NULL; gp->dpNoMatch = NULL; gp->cxKeyArray = nkeys; gp->dpKeyArray = new KMX_KEY[gp->cxKeyArray]; - nkeys = 0; + + nDeadkey++; // ensure a 1-based index above the max deadkey value already in the keyboard // // Fill in the new rules // + nkeys = 0; for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { if ((rgKey[iKey] != NULL) && rgKey[iKey]->mac_KMX_IsKeymanUsedKey() && (!rgKey[iKey]->mac_KMX_IsEmpty())) { - if(rgKey[iKey]->mac_KMX_LayoutRow(loader.KMX_MaxShiftState(), &gp->dpKeyArray[nkeys], &alDead, nDeadkey, bDeadkeyConversion, all_vector,*keyboard_layout)) { // I4552 - nkeys+=rgKey[iKey]->mac_KMX_GetKeyCount(loader.KMX_MaxShiftState()); + if (rgKey[iKey]->mac_KMX_LayoutRow(loader.KMX_MaxShiftState(), &gp->dpKeyArray[nkeys], &alDead, nDeadkey, bDeadkeyConversion, all_vector, *keyboard_layout)) { // I4552 + nkeys += rgKey[iKey]->mac_KMX_GetKeyCount(loader.KMX_MaxShiftState()); } } } - gp->cxKeyArray = nkeys; // // Add nomatch control to each terminating 'using keys' group // I4550 // LPKMX_GROUP gp2 = kp->dpGroupArray; - for(UINT i = 0; i < kp->cxGroupArray - 1; i++, gp2++) { - if(gp2->fUsingKeys && gp2->dpNoMatch == NULL) { - KMX_WCHAR *p = gp2->dpNoMatch = new KMX_WCHAR[4]; + for (UINT i = 0; i < kp->cxGroupArray - 1; i++, gp2++) { + if (gp2->fUsingKeys && gp2->dpNoMatch == NULL) { + KMX_WCHAR* p = gp2->dpNoMatch = new KMX_WCHAR[4]; *p++ = UC_SENTINEL; *p++ = CODE_USE; *p++ = (KMX_WCHAR)(kp->cxGroupArray); @@ -630,19 +621,19 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const // UINT j; LPKMX_KEY kkp; - for(j = 0, kkp = gp->dpKeyArray; j < gp->cxKeyArray; j++, kkp++) { - if((kkp->ShiftFlags & (K_CTRLFLAG|K_ALTFLAG|LCTRLFLAG|LALTFLAG|RCTRLFLAG|RALTFLAG)) != 0) { - gp2->cxKeyArray++; + for (j = 0, kkp = gp->dpKeyArray; j < gp->cxKeyArray; j++, kkp++) { + if ((kkp->ShiftFlags & (K_CTRLFLAG | K_ALTFLAG | LCTRLFLAG | LALTFLAG | RCTRLFLAG | RALTFLAG)) != 0) { + gp2->cxKeyArray++; LPKMX_KEY kkp2 = new KMX_KEY[gp2->cxKeyArray]; - memcpy(kkp2, gp2->dpKeyArray, sizeof(KMX_KEY)*(gp2->cxKeyArray-1)); + memcpy(kkp2, gp2->dpKeyArray, sizeof(KMX_KEY) * (gp2->cxKeyArray - 1)); gp2->dpKeyArray = kkp2; - kkp2 = &kkp2[gp2->cxKeyArray-1]; + kkp2 = &kkp2[gp2->cxKeyArray - 1]; kkp2->dpContext = new KMX_WCHAR; *kkp2->dpContext = 0; kkp2->Key = kkp->Key; kkp2->ShiftFlags = kkp->ShiftFlags; kkp2->Line = 0; - KMX_WCHAR *p = kkp2->dpOutput = new KMX_WCHAR[4]; + KMX_WCHAR* p = kkp2->dpOutput = new KMX_WCHAR[4]; *p++ = UC_SENTINEL; *p++ = CODE_USE; *p++ = (KMX_WCHAR)(kp->cxGroupArray); @@ -656,13 +647,13 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const // We only do this if not in deadkey conversion mode // - if (alDead.size() > 0 && !bDeadkeyConversion) { // I4552 + if (alDead.size() > 0 && !bDeadkeyConversion) { // I4552 kp->cxGroupArray++; - KMX_WCHAR *p = gp->dpMatch = new KMX_WCHAR[4]; + KMX_WCHAR* p = gp->dpMatch = new KMX_WCHAR[4]; *p++ = UC_SENTINEL; *p++ = CODE_USE; - *p++ = (KMX_WCHAR) kp->cxGroupArray; + *p++ = (KMX_WCHAR)kp->cxGroupArray; *p = 0; gp++; @@ -683,13 +674,13 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const int nStoreBase = kp->cxStoreArray; kp->cxStoreArray += alDead.size() * 2; - for(UINT i = 0; i < alDead.size(); i++) { - DeadKey *dk = alDead[i]; + for (UINT i = 0; i < alDead.size(); i++) { + DeadKey* dk = alDead[i]; sp->dpName = NULL; sp->dwSystemID = 0; sp->dpString = new KMX_WCHAR[dk->KMX_Count() + 1]; - for(int j = 0; j < dk->KMX_Count(); j++) + for (int j = 0; j < dk->KMX_Count(); j++) sp->dpString[j] = dk->KMX_GetBaseCharacter(j); sp->dpString[dk->KMX_Count()] = 0; sp++; @@ -697,7 +688,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const sp->dpName = NULL; sp->dwSystemID = 0; sp->dpString = new KMX_WCHAR[dk->KMX_Count() + 1]; - for(int j = 0; j < dk->KMX_Count(); j++) + for (int j = 0; j < dk->KMX_Count(); j++) sp->dpString[j] = dk->KMX_GetCombinedCharacter(j); sp->dpString[dk->KMX_Count()] = 0; sp++; @@ -705,7 +696,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const kkp->Line = 0; kkp->ShiftFlags = 0; kkp->Key = 0; - KMX_WCHAR *p = kkp->dpContext = new KMX_WCHAR[8]; + KMX_WCHAR* p = kkp->dpContext = new KMX_WCHAR[8]; *p++ = UC_SENTINEL; *p++ = CODE_DEADKEY; @@ -713,13 +704,13 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const // *p++ = nDeadkey+i; *p++ = UC_SENTINEL; *p++ = CODE_ANY; - *p++ = nStoreBase + i*2 + 1; + *p++ = nStoreBase + i * 2 + 1; *p = 0; p = kkp->dpOutput = new KMX_WCHAR[5]; *p++ = UC_SENTINEL; *p++ = CODE_INDEX; - *p++ = nStoreBase + i*2 + 2; + *p++ = nStoreBase + i * 2 + 2; *p++ = 2; *p = 0; kkp++; @@ -786,7 +777,7 @@ bool verify_entries_S2(int i, std::vector rgKey, int res1,i for ( int k=0; k< st_vec.size();k++) if (r_vec[k] !=0 ) all_OK = ( *st_vec[k].c_str() == r_vec[k] ) && all_OK; - if( !all_OK) + if ( !all_OK) printf(" ERROR FOR i= Nr:%i, %i(%c) - %i (%c) - %i (%c) - %i (%c) \n",i, *st_vec[0].c_str(),*st_vec[1].c_str(),*st_vec[2].c_str(),*st_vec[3].c_str(),*st_vec[4].c_str(),*st_vec[5].c_str(),*st_vec[6].c_str(),*st_vec[7].c_str()); return all_OK; } @@ -820,13 +811,13 @@ void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int ke unicodeString[0]=0; //int shiftarray[] ={0,2,8,10}; int shiftarray[] ={0,1,2,3,4,5,6,7,8,9,10}; - for(int k=0; k<2;k++) { - for(int j=0; j<(sizeof(shiftarray)/ sizeof(int));j++) { + for (int k=0; k<2;k++) { + for (int j=0; j<(sizeof(shiftarray)/ sizeof(int));j++) { status = UCKeyTranslate(keyboard_layout, keycode , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - if(deadkeystate ==0) + if (deadkeystate ==0) printf(" key nr %i , ss %i has values %i(%c)\n", keycode, shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); // If this was a deadkey, append a space - if(deadkeystate !=0) { + if (deadkeystate !=0) { status = UCKeyTranslate(keyboard_layout, keycode_spacebar , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); printf(" dk with caps key nr %i , ss %i has values %i(%c)\n", keycode,shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); } @@ -842,14 +833,14 @@ void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout){ unicodeString[0]=0; int shiftarray[] ={0,2,8,10}; - for(int k=0; k<2;k++) { - for(int j=0; j<4;j++) { - for(int i=0; i< keycode_spacebar+1 ;i++) { + for (int k=0; k<2;k++) { + for (int j=0; j<4;j++) { + for (int i=0; i< keycode_spacebar+1 ;i++) { status = UCKeyTranslate(keyboard_layout, i , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - if(deadkeystate ==0) + if (deadkeystate ==0) printf(" key nr %i , ss %i has values %i(%c)\n", i, shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); // If this was a deadkey, append a space - if(deadkeystate !=0) { + if (deadkeystate !=0) { status = UCKeyTranslate(keyboard_layout, keycode_spacebar , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); printf(" dk key nr %i , ss %i has values %i(%c)\n", i,shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); } @@ -960,7 +951,7 @@ bool test_run_verify_S2(std::vector rgKey) { allOK = verify_entries_S2(56, rgKey, 56,56,40,40) && allOK; allOK = verify_entries_S2(57, rgKey, 57,57,41,41) && allOK; - for( int i=65; i<89;i++) + for ( int i=65; i<89;i++) allOK = verify_entries_S2(i, rgKey,i+32,i,i,i) && allOK; allOK = verify_entries_S2(89, rgKey, 90+32,90,90,90) && allOK; diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h index 773eaa39470..d8f0c70b8b4 100755 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -1,9 +1,11 @@ + #pragma once #ifndef MC_IMPORT_RULES_H #define MC_IMPORT_RULES_H -int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps, const UCKeyboardLayout * keyboard_layout); +int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps, const UCKeyboardLayout* keyboard_layout); +/** @brief Base class for Deadkey*/ class DeadKey { private: KMX_WCHAR m_deadchar; @@ -11,10 +13,24 @@ class DeadKey { std::vector m_rgcombchar; public: +/** + * @brief Constructor + * @param deadCharacter a deadkey + */ DeadKey(KMX_WCHAR deadCharacter); +/** + * @brief return dead character + * @return deadkey character + */ KMX_WCHAR KMX_DeadCharacter(); +/** + * @brief set Deadkey with values + * @param baseCharacter the base character + * @param combinedCharacter the combined character + * @return void + */ void KMX_AddDeadKeyRow(KMX_WCHAR baseCharacter, KMX_WCHAR combinedCharacter); int KMX_Count() { @@ -33,7 +49,12 @@ class DeadKey { return this->m_rgcombchar[index]; } +/** + * @brief check if character exists in DeadKey + * @param baseCharacter + * @return true if found; false if not found + */ bool KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter); }; -# endif //MC_IMPORT_RULES_H +#endif // MC_IMPORT_RULES_H diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index b3070184225..8ef29dc67c0 100755 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -1,15 +1,11 @@ - #pragma once #ifndef MC_KMXFILE_H #define MC_KMXFILE_H - #include "km_types.h" #include "kmx_file.h" -//#include "util_filesystem.h" //_S2 TODO include from keyman; not from this folder #include "mcompile.h" - #ifndef _KMXFILE_H #define _KMXFILE_H @@ -72,17 +68,38 @@ typedef struct KMX_tagKEYBOARD { //HBITMAP hBitmap; // handle to the bitmap in the file; } KMX_KEYBOARD, *LPKMX_KEYBOARD; -KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD *lpKeyboard); - -KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename); - -// _S2 Open files on windows and non-windows platforms. Datatypes for Filename and mode must be the same. -// return FILE* if file could be opened; FILE must to be closed in calling function +/** + * @brief load a keyboard kmx-file + * @param fileName ptr to filename of kmx-file + * @param [in,out] lpKeyboard ptr to ptr to keyboard + * @return TRUE on success; else FALSE + */ +KMX_BOOL KMX_LoadKeyboard(KMX_WCHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) ; + +/** + * @brief save keyboard to file + * @param kbd ptr to the keyboard + * @param filename ptr to filename of a kmx-file + * @return TRUE on success; else FALSE + */ +KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR* filename); + +/** + * @brief increment in a string + * @param p ptr to a character + * @return ptr to the incremented character + */ +PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); + +/** + * @brief open a file + * @param Filename name of the file + * @param mode same as mode in fopen + * @return ptr to file. On error, returns a null pointer + */ FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode); - #endif // _KMXFILE_H -#endif //MC_KMXFILE_H - +#endif /*MC_KMXFILE_H*/ diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 2cfef115368..dbed5cede2c 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -1,37 +1,31 @@ /* - Name: mcompile - Copyright: Copyright (C) SIL International. - Documentation: - Description: - Create Date: 24 Apr 2014 - - Modified Date: 8 Apr 2015 - Authors: mcdurdin - Related Files: - Dependencies: - - Bugs: - Todo: - Notes: - History: 24 Apr 2014 - mcdurdin - I4174 - V9 - mcompile logs should be stored in diag folder - 16 Jun 2014 - mcdurdin - I4273 - V9.0 - Convert keyboards to Unicode before installing - 23 Jun 2014 - mcdurdin - I4279 - V9.0 - mcompile fails to start when converting keyboard to Unicode - 03 Aug 2014 - mcdurdin - I4353 - V9.0 - mnemonic layout recompiler mixes up deadkey rules - 03 Aug 2014 - mcdurdin - I4327 - V9.0 - Mnemonic layout compiler follow-up - 31 Dec 2014 - mcdurdin - I4549 - V9.0 - Mnemonic layout recompiler does not translate Lctrl Ralt for deadkeys correctly - 06 Feb 2015 - mcdurdin - I4552 - V9.0 - Add mnemonic recompile option to ignore deadkeys - 08 Apr 2015 - mcdurdin - I4651 - V9.0 - Mnemonic layout recompiler maps AltGr+VK_BKSLASH rather than VK_OEM_102 -*/ + * Keyman is copyright (C) 2004 SIL International. MIT License. + * + * Mnemonic layout support for Linux + */ + +// +// Defines the entry point for the console application. +// +// Note: this program deliberately leaks memory as it has a very short life cycle and managing the memory allocations +// for the subcomponents of the compiled keyboard is an unnecessary optimisation. Just so you know. +// #include #include #include "mcompile.h" #include "u16.h" - - +/** + * @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard + * @param kbd pointer to US keyboard + * @param bDeadkeyConversion option for converting a deadkey to a character: 1=conversion; 0= no conversion + * @param argc number of commandline arguments + * @return TRUE if conversion was successful; FALSE if not + */ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc); -bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vector_dword_3D &all_vector, const UCKeyboardLayout **keyboard_layout, std::vector *KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 +/** @brief Collect the key data, translate it to kmx and append to the existing keyboard */ +bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D &all_vector, const UCKeyboardLayout** keyboard_layout, std::vector* KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 std::vector KMX_FDeadkeys; // I4353 @@ -40,22 +34,21 @@ std::vector KMX_FDeadkeys; // I4353 #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif -#define _countof(a) (sizeof(a)/sizeof(*(a))) - - - /** - * @brief main function for mcompile for Windows, Linux, Mac - * @param argc number of commandline arguments - * @param argv commandline arguments - * @return 0 on success, 1 for wrong usage of calling parameters, 3 if unable ro load keyboard - */ +// _S2 run and getdeadkeys to here +#define _countof(a) (sizeof(a) / sizeof(*(a))) + /** + * @brief main function for mcompile for Windows, Linux, Mac + * @param argc number of commandline arguments + * @param argv commandline arguments + * @return 0 on success + */ #if defined(_WIN32) || defined(_WIN64) int wmain(int argc, wchar_t* argv[]) { - std::vector str_argv_16 = convert_argvW_to_Vector_u16str( argc, argv); + std::vector str_argv_16 = convert_argvW_to_Vector_u16str(argc, argv); run(argc, str_argv_16); -#elif ((__linux__) || (__unix__ )) // LINUX, UNIX +#elif ((__linux__) || (__unix__)) // LINUX, UNIX int main(int argc, char* argv[]) { std::vector str_argv_16 = convert_argv_to_Vector_u16str(argc, argv); run(argc, str_argv_16, argv); @@ -71,43 +64,35 @@ std::vector KMX_FDeadkeys; // I4353 #endif } - - - /** - * @brief start of mcompile; load, convert and save keyboard - * @param argc number of commandline arguments - * @param str_argv vector of string of commandline arguments: executable, inputfile, outputfile - * @param argv_ch pointer to pointer to char/wchar_t (commandline arguments) - * @return 0 on success, 1 for wrong usage of calling parameters, 3 if unable ro load keyboard - */ -int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ - + +/** @brief start of mcompile; load, convert and save keyboard */ +int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NULL) { std::vector argv; for (int i = 0; i < argc; i++) { const char16_t* cmdl_par = str_argv[i].c_str(); argv.push_back(cmdl_par); } - if(argc < 3 || (argc > 4)) { // I4273// I4273 + if (argc < 3 || (argc > 4)) { // I4273// I4273 wprintf( L"Usage: mcompile [-d] infile.kmx outfile.kmx\n" L" mmcompile -u ... (not available for mac)\n " L" mcompile converts a Keyman mnemonic layout to a\n" L" positional one based on the mac keyboard\n" L" layout on top position\n" - L" (-d convert deadkeys to plain keys) not available yet \n\n" - ); // I4552 + L" (-d convert deadkeys to plain keys) not available yet \n\n"); // I4552 return 1; } // -u option is not available for Linux and macOS - int bDeadkeyConversion = u16cmp(argv[1], u"-d") == 0; // I4552 + int bDeadkeyConversion = u16cmp(argv[1], u"-d") == 0; // I4552 int n = (bDeadkeyConversion ? 2 : 1); - char16_t* infile = (char16_t*) argv[n], *outfile = (char16_t*) argv[n+1]; + char16_t *infile = (char16_t*)argv[n], *outfile = (char16_t*)argv[n + 1]; - wprintf(L"mcompile%ls \"%ls\" \"%ls\"\n", bDeadkeyConversion ? L" -d" : L"", u16fmt((const char16_t*) infile).c_str(), u16fmt((const char16_t*) outfile).c_str() ); // I4174 + // _S2 TODO open again!! + //wprintf(L"mcompile%ls \"%ls\" \"%ls\"\n", bDeadkeyConversion ? L" -d" : L"", u16fmt((const char16_t*) infile).c_str(), u16fmt((const char16_t*) outfile).c_str() ); // I4174 // 1. Load the keyman keyboard file @@ -134,37 +119,36 @@ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NU // // 3. Write the new keyman keyboard file - LPKMX_KEYBOARD kmxfile; - if(!KMX_LoadKeyboard(infile, &kmxfile)) { - mac_KMX_LogError(L"Failed to load keyboard (%d)\n", errno ); + if (!KMX_LoadKeyboard(infile, &kmxfile)) { + mac_KMX_LogError(L"Failed to load keyboard (%d)\n", errno); return 3; } - #if defined(_WIN32) || defined(_WIN64) //Windows - if(DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F + #if defined(_WIN32) || defined(_WIN64) // Windows + if (DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); } - #elif ((__linux__) || (__unix__ )) // LINUX, UNIX - if(mac_KMX_DoConvert( kmxfile, bDeadkeyConversion, argc)) { // I4552F + #elif ((__linux__) || (__unix__)) // LINUX, UNIX + if (mac_KMX_DoConvert(kmxfile, bDeadkeyConversion, argc)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); } - #elif (__APPLE__ && TARGET_OS_MAC ) //macOS - if(mac_KMX_DoConvert( kmxfile, bDeadkeyConversion, argc)) { // I4552F + #elif (__APPLE__ && TARGET_OS_MAC) // macOS + if (mac_KMX_DoConvert(kmxfile, bDeadkeyConversion, argc)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); } #endif - //DeleteReallocatedPointers(kmxfile); :TODO // _S2 not my ToDo :-) + // DeleteReallocatedPointers(kmxfile); :TODO // _S2 not my ToDo :-) delete kmxfile; return 0; } // Map of all shift states that we will work with -const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCTRLFLAG|RALTFLAG, 0xFFFF}; +const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG | RALTFLAG, K_SHIFTFLAG | LCTRLFLAG | RALTFLAG, 0xFFFF}; // // TranslateKey @@ -172,28 +156,29 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCT // For each key rule on the keyboard, remap its key to the // correct shift state and key. Adjust the LCTRL+RALT -> RALT if necessary // + /** - * @brief translate each key of a group: remap the content of a key (key->Key) of the US keyboard to a character (ch) - * @param key a key - * @param vk a keyvalue of the US keyboard - * @param shift shiftstate - * @param ch character of the underlying keyboard to be remapped - * @return void - */ + * @brief translate each key of a group: remap the content of a key (key->Key) of the US keyboard to a character (ch) + * @param key pointer to a key + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @param ch character of the underlying keyboard to be remapped + * @return void + */ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. - if((shift & (LCTRLFLAG|RALTFLAG)) == (LCTRLFLAG|RALTFLAG)) + if ((shift & (LCTRLFLAG | RALTFLAG)) == (LCTRLFLAG | RALTFLAG)) shift &= ~LCTRLFLAG; - if(key->ShiftFlags == 0 && key->Key == ch) { + if (key->ShiftFlags == 0 && key->Key == ch) { // Key is a mnemonic key with no shift state defined. // Remap the key according to the character on the key cap. // mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO + [%x K_%d]", key->Line, key->Key, shift, vk);// 1 key->ShiftFlags = ISVIRTUALKEY | shift; key->Key = vk; - } else if(key->ShiftFlags & VIRTUALCHARKEY && key->Key == ch) { + } else if (key->ShiftFlags & VIRTUALCHARKEY && key->Key == ch) { // Key is a virtual character key with a hard-coded shift state. // Do not remap the shift state, just move the key. // This will not result in 100% wonderful mappings as there could @@ -204,90 +189,92 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) key->Key = vk; } } + /** - * @brief translate a group of a keyboard - * @param group a keyboard group - * @param vk a keyvalue of the US keyboard - * @param shift shiftstate - * @param ch character of the underlying keyboard to be remapped - * @return void - */ + * @brief translate a group of a keyboard + * @param group pointer to a keyboard group + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @param ch character of the underlying keyboard to be remapped + * @return void + */ void mac_KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { - for(unsigned int i = 0; i < group->cxKeyArray; i++) { + for (unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_TranslateKey(&group->dpKeyArray[i], vk, shift, ch); } } + /** - * @brief translate a keyboard - * @param kbd the US keyboard - * @param vk a keyvalue of the US keyboard - * @param shift shiftstate - * @param ch character of the underlying keyboard to be remapped - * @return void - */ + * @brief translate a keyboard + * @param kbd pointer to the US keyboard + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @param ch character of the underlying keyboard to be remapped + * @return void + */ void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { - for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { - if(kbd->dpGroupArray[i].fUsingKeys) { + for (unsigned int i = 0; i < kbd->cxGroupArray; i++) { + if (kbd->dpGroupArray[i].fUsingKeys) { mac_KMX_TranslateGroup(&kbd->dpGroupArray[i], vk, shift, ch); } } } - - /** - * @brief check key for unconverted key rules - * @param key a key - * @return void - */ + /** + * @brief check key for unconverted key rules + * @param key pointer to a key + * @return void + */ void mac_KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { - if(key->ShiftFlags == 0) { + if (key->ShiftFlags == 0) { mac_KMX_LogError(L"Did not find a match for mnemonic rule on line %d, + '%c' > ...", key->Line, key->Key); - } else if(key->ShiftFlags & VIRTUALCHARKEY) { + } else if (key->ShiftFlags & VIRTUALCHARKEY) { mac_KMX_LogError(L"Did not find a match for mnemonic virtual character key rule on line %d, + [%x '%c'] > ...", key->Line, key->ShiftFlags, key->Key); } } - /** - * @brief check a group for unconverted rules - * @param group a keyboard group - * @return void - */ + +/** + * @brief check a group for unconverted rules + * @param group pointer to a keyboard group + * @return void + */ void mac_KMX_ReportUnconvertedGroupRules(LPKMX_GROUP group) { - for(unsigned int i = 0; i < group->cxKeyArray; i++) { + for (unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_ReportUnconvertedKeyRule(&group->dpKeyArray[i]); } } - /** - * @brief check a keyboard for unconverted rules - * @param kbd the US keyboard - * @return void - */ + +/** + * @brief check a keyboard for unconverted rules + * @param kbd pointer to the US keyboard + * @return void + */ void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { - for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { - if(kbd->dpGroupArray[i].fUsingKeys) { + for (unsigned int i = 0; i < kbd->cxGroupArray; i++) { + if (kbd->dpGroupArray[i].fUsingKeys) { mac_KMX_ReportUnconvertedGroupRules(&kbd->dpGroupArray[i]); } } } - - /** - * @brief remap the content of a key (key->dpContext) of the US keyboard to a deadkey sequence - * @param key a key - * @param deadkey a deadkey to be remapped - * @param vk a keyvalue of the US keyboard - * @param shift shiftstate - * @param ch character of the underlying keyboard - * @return void - */ +/** + * @brief remap the content of a key (key->dpContext) of the US keyboard to a deadkey sequence + * @param key pointer to a key + * @param deadkey a deadkey to be remapped + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @param ch character of the underlying keyboard + * @return void + */ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { - if((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) { + if ((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. - if((shift & (LCTRLFLAG|RALTFLAG)) == (LCTRLFLAG|RALTFLAG)) // I4327 + if ((shift & (LCTRLFLAG|RALTFLAG)) == (LCTRLFLAG|RALTFLAG)) // I4327 shift &= ~LCTRLFLAG; - if(key->ShiftFlags == 0) { + if (key->ShiftFlags == 0) { //mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO dk(%d) + [%x K_%d]", key->Line, key->Key, deadkey, shift, vk); key->ShiftFlags = ISVIRTUALKEY | shift; } else { @@ -307,56 +294,57 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, key->Key = vk; } } - /** - * @brief translate a group - * @param group a keyboard group - * @param a deadkey to be remapped - * @param vk a keyvalue of the US keyboard - * @param shift shiftstate - * @param character of the underlying keyboard - * @return void - */ + +/** + * @brief translate a group + * @param group pointer to a keyboard group + * @param a deadkey to be remapped + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @param character of the underlying keyboard + * @return void + */ void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { - for(unsigned int i = 0; i < group->cxKeyArray; i++) { + for (unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_TranslateDeadkeyKey(&group->dpKeyArray[i], deadkey, vk, shift, ch); } } - /** - * @brief translate a keyboard - * @param kbd the US keyboard - * @param a deadkey to be remapped - * @param vk a keyvalue of the US keyboard - * @param shift shiftstate - * @param character of the underlying keyboard - * @return void - */ + +/** + * @brief translate a keyboard + * @param kbd pointer to the US keyboard + * @param a deadkey to be remapped + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @param character of the underlying keyboard + * @return void + */ void mac_KMX_TranslateDeadkeyKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { - for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { - if(kbd->dpGroupArray[i].fUsingKeys) { + for (unsigned int i = 0; i < kbd->cxGroupArray; i++) { + if (kbd->dpGroupArray[i].fUsingKeys) { mac_KMX_TranslateDeadkeyGroup(&kbd->dpGroupArray[i], deadkey, vk, shift, ch); } } } - - /** - * @brief add a deadkey rule - * @param kbd the US keyboard - * @param deadkey a deadkey to be added - * @param vk a keyvalue of the US keyboard - * @param shift shiftstate - * @return void - */ +/** + * @brief add a deadkey rule + * @param kbd pointer to the US keyboard + * @param deadkey a deadkey to be added + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @return void + */ void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. - if((shift & (LCTRLFLAG|RALTFLAG)) == (LCTRLFLAG|RALTFLAG)) // I4549 + if ((shift & (LCTRLFLAG | RALTFLAG)) == (LCTRLFLAG | RALTFLAG)) // I4549 shift &= ~LCTRLFLAG; // If the first group is not a matching-keys group, then we need to add into // each subgroup, otherwise just the match group - for(unsigned int i = 0; i < kbd->cxGroupArray; i++) { - if(kbd->dpGroupArray[i].fUsingKeys) { + for (unsigned int i = 0; i < kbd->cxGroupArray; i++) { + if (kbd->dpGroupArray[i].fUsingKeys) { LPKMX_KEY keys = new KMX_KEY[kbd->dpGroupArray[i].cxKeyArray + 1]; memcpy(keys+1, kbd->dpGroupArray[i].dpKeyArray, kbd->dpGroupArray[i].cxKeyArray * sizeof(KMX_KEY)); keys[0].dpContext = new KMX_WCHAR[1]; @@ -372,20 +360,21 @@ void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, kbd->dpGroupArray[i].dpKeyArray = keys; kbd->dpGroupArray[i].cxKeyArray++; mac_KMX_LogError(L"Add deadkey rule: + [%d K_%d] > dk(%d)", shift, vk, deadkey); - if(i == kbd->StartGroup[1]) break; // If this is the initial group, that's all we need to do. + if (i == kbd->StartGroup[1]) + break; // If this is the initial group, that's all we need to do. } } } /** - * @brief find the maximum deadkey id - * @param str the deadkey - * @return the maximum deadkey id - */ + * @brief find the maximal deadkey id + * @param str the deadkey + * @return the maximum deadkey id + */ KMX_WCHAR mac_KMX_ScanXStringForMaxDeadkeyID(PKMX_WCHAR str) { KMX_WCHAR dkid = 0; while(str && *str) { - if(*str == UC_SENTINEL) { + if (*str == UC_SENTINEL) { switch(*(str+1)) { case CODE_DEADKEY: dkid = max(dkid, *(str+2)); @@ -396,18 +385,16 @@ KMX_WCHAR mac_KMX_ScanXStringForMaxDeadkeyID(PKMX_WCHAR str) { return dkid; } - struct KMX_dkidmap { KMX_WCHAR src_deadkey, dst_deadkey; }; - - /** - * @brief find a deadkey id for a given deadkey - * @param kbd the keyboard - * @param deadkey - * @return 0 if failed; otherwise a deadkey-id - */ +/** + * @brief find the deadkey id for a given deadkey + * @param kbd pointer to the keyboard + * @param deadkey for which an id is to be found + * @return 0 if failed; otherwise a deadkey-id + */ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { LPKMX_GROUP gp; LPKMX_KEY kp; @@ -415,11 +402,11 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { UINT i, j; KMX_WCHAR dkid = 0; static KMX_WCHAR s_next_dkid = 0; - static KMX_dkidmap *s_dkids = NULL; + static KMX_dkidmap* s_dkids = NULL; static int s_ndkids = 0; - if(!kbd) { - if(s_dkids) { + if (!kbd) { + if (s_dkids) { delete s_dkids; } s_dkids = NULL; @@ -428,20 +415,20 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { return 0; } - for(int i = 0; i < s_ndkids; i++) { - if(s_dkids[i].src_deadkey == deadkey) { + for (int i = 0; i < s_ndkids; i++) { + if (s_dkids[i].src_deadkey == deadkey) { return s_dkids[i].dst_deadkey; } } - if(s_next_dkid != 0) { - s_dkids = (KMX_dkidmap*) realloc(s_dkids, sizeof(KMX_dkidmap) * (s_ndkids+1)); + if (s_next_dkid != 0) { + s_dkids = (KMX_dkidmap*)realloc(s_dkids, sizeof(KMX_dkidmap) * (s_ndkids + 1)); s_dkids[s_ndkids].src_deadkey = deadkey; return s_dkids[s_ndkids++].dst_deadkey = ++s_next_dkid; } - for(i = 0, gp = kbd->dpGroupArray; i < kbd->cxGroupArray; i++, gp++) { - for(j = 0, kp = gp->dpKeyArray; j < gp->cxKeyArray; j++, kp++) { + for (i = 0, gp = kbd->dpGroupArray; i < kbd->cxGroupArray; i++, gp++) { + for (j = 0, kp = gp->dpKeyArray; j < gp->cxKeyArray; j++, kp++) { dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(kp->dpContext)); dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(kp->dpOutput)); } @@ -449,67 +436,65 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(gp->dpNoMatch)); } - for(i = 0, sp = kbd->dpStoreArray; i < kbd->cxStoreArray; i++, sp++) { + for (i = 0, sp = kbd->dpStoreArray; i < kbd->cxStoreArray; i++, sp++) { dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(sp->dpString)); } - s_dkids = (KMX_dkidmap*) realloc(s_dkids, sizeof(KMX_dkidmap) * (s_ndkids+1)); + s_dkids = (KMX_dkidmap*)realloc(s_dkids, sizeof(KMX_dkidmap) * (s_ndkids + 1)); s_dkids[s_ndkids].src_deadkey = deadkey; return s_dkids[s_ndkids++].dst_deadkey = s_next_dkid = ++dkid; } - - /** - * @brief Lookup the deadkey table for the deadkey in the physical keyboard. Then for each character, go through and map it through - * @param kbd the keyboard - * @param vk_US virtual key of the us keyboard - * @param shift shiftstate - * @param deadkey character produced by a deadkey - * @param all_vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param keyboard_layout the currently used (underlying) keyboard Layout - * - * @return void - */ -void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, vector_dword_3D &all_vector, const UCKeyboardLayout * keyboard_layout) { - KMX_WORD deadkeys[512]={0}; - KMX_WORD *pdk; +/** + * @brief Lookup the deadkey table for the deadkey in the physical keyboard. Then for each character, go through and map it through + * @param kbd pointer to the keyboard + * @param vk_US virtual key of the us keyboard + * @param shift shiftstate + * @param deadkey character produced by a deadkey + * @param all_vector vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param keymap pointer to the currently used (underlying) keyboard Layout + * @param dk_Table a vector of all possible deadkey combinations for all Linux keyboards + * @return void + */ +void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { + KMX_WORD deadkeys[512] = {0}; + KMX_WORD* pdk; // Lookup the deadkey table for the deadkey in the physical keyboard // Then for each character, go through and map it through KMX_WCHAR dkid = mac_KMX_GetUniqueDeadkeyID(kbd, deadkey); // Add the deadkey to the mapping table for use in the import rules phase - KMX_DeadkeyMapping KMX_deadkeyMapping = { deadkey, dkid, shift, vk_US}; // I4353 + KMX_DeadkeyMapping KMX_deadkeyMapping = {deadkey, dkid, shift, vk_US}; // I4353 - KMX_FDeadkeys.push_back(KMX_deadkeyMapping); //dkid, vk, shift); // I4353 + KMX_FDeadkeys.push_back(KMX_deadkeyMapping); // dkid, vk, shift); // I4353 mac_KMX_AddDeadkeyRule(kbd, dkid, vk_US, shift); - mac_KMX_GetDeadkeys(keyboard_layout, all_vector, deadkey, shift, pdk = deadkeys ); // returns array of [usvk, ch_out] pairs + mac_KMX_GetDeadkeys(keyboard_layout, all_vector, deadkey, shift, pdk = deadkeys); // returns array of [usvk, ch_out] pairs - while(*pdk) { + while (*pdk) { // Look up the ch UINT KeyValUnderlying = mac_KMX_get_KeyValUnderlying_From_KeyValUS(all_vector, *pdk); - mac_KMX_TranslateDeadkeyKeyboard(kbd, dkid, KeyValUnderlying, *(pdk+1), *(pdk+2)); - pdk+=3; + mac_KMX_TranslateDeadkeyKeyboard(kbd, dkid, KeyValUnderlying, *(pdk + 1), *(pdk + 2)); + pdk += 3; } } - - /** - * @brief convert a mnemonic keyboard to a positional keyboard - * (i.e. setting *sp->dpString = '0' / TSS_MNEMONIC=0) - * @param kbd keyboard - * @return TRUE if conversion was successful; FALSE otherwise - */ + /** + * @brief convert a mnemonic keyboard to a positional keyboard + * (i.e. setting *sp->dpString = '0' / TSS_MNEMONIC=0) + * @param kbd pointer to keyboard + * @return TRUE if conversion was successful; FALSE otherwise + */ KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { LPKMX_STORE sp; UINT i; - for(i = 0, sp = kbd->dpStoreArray; i < kbd->cxStoreArray; i++, sp++) { - if(sp->dwSystemID == TSS_MNEMONIC) { - if(!sp->dpString) { + for (i = 0, sp = kbd->dpStoreArray; i < kbd->cxStoreArray; i++, sp++) { + if (sp->dwSystemID == TSS_MNEMONIC) { + if (!sp->dpString) { mac_KMX_LogError(L"Invalid &mnemoniclayout system store"); return FALSE; } - if(u16cmp((const KMX_WCHAR*)sp->dpString, u"1") != 0) { + if (u16cmp((const KMX_WCHAR*)sp->dpString, u"1") != 0) { mac_KMX_LogError(L"Keyboard is not a mnemonic layout keyboard"); return FALSE; } @@ -521,20 +506,12 @@ KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { return FALSE; } - - /** - * @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard - * @param kbd US keyboard - * @param bDeadkeyConversion 1 for converting a deadkey to a character; - * 0 for not converting a deadkey to a character - * @param argc number of commandline arguments - * @return TRUE if conversion was succsessful; FALSE if not - */ +/** @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard */ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc) { KMX_WCHAR DeadKey=0; - - if(!mac_KMX_SetKeyboardToPositional(kbd)) return FALSE; + if (!mac_KMX_SetKeyboardToPositional(kbd)) + return FALSE; // Go through each of the shift states - base, shift, ctrl+alt, ctrl+alt+shift, [caps vs ncaps?] // Currently, we go in this order so the 102nd key works. But this is not ideal for keyboards without 102nd key: // I4651 @@ -542,19 +519,19 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int // evident for the 102nd key on UK, for example, where \ can be generated with VK_OEM_102 or AltGr+VK_QUOTE. // For now, we get the least shifted version, which is hopefully adequate. - // Sadly it`s not e.g.: : on a German WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only which is the usual combination to get ~. + // Sadly it`s not e.g.: on a German WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only which is the usual combination to get ~. // on a German MAC keyboard one will get '~' with either OPT + K_221(+) or OPT + K_84(T) or CAPS + OPT + K_78(N) // K_84(T) will be caught first, so one of the the least obvious version for creating the '~' is found and processed. // -> meeting with Marc May 21 2024: We leave it as it is; it is OK if different combinations are found. const UCKeyboardLayout* keyboard_layout; - if(mac_InitializeUCHR(&keyboard_layout)) { + if (mac_InitializeUCHR(&keyboard_layout)) { wprintf(L"ERROR: can't Initialize GDK\n"); return FALSE; } // create vector that contains Keycode, Base, Shift for US-Keyboard and underlying keyboard - vector_dword_3D all_vector; - if(mac_createOneVectorFromBothKeyboards(all_vector, keyboard_layout)){ + vec_dword_3D all_vector; + if (mac_createOneVectorFromBothKeyboards(all_vector, keyboard_layout)) { wprintf(L"ERROR: can't create one vector from both keyboards\n"); return FALSE; } @@ -565,19 +542,19 @@ printf("-------\n"); //print_dublicates_S2(keyboard_layout); //find_double_keys(keyboard_layout,1); - for (int j = 0; VKShiftState[j] != 0xFFFF; j++) { // I4651 + for (int j = 0; VKShiftState[j] != 0xFFFF; j++) { // I4651 // Loop through each possible key on the keyboard - for (int i = 0;KMX_VKMap[i]; i++) { // I4651 + for (int i = 0; KMX_VKMap[i]; i++) { // I4651 // windows uses VK as sorting order in rgkey[], Linux and macOS use SC/Keycode as sorting order - UINT scUnderlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_VKMap[i]); + UINT scUnderlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_VKMap[i]); KMX_WCHAR ch = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, scUnderlying, VKShiftState[j], &DeadKey); - //wprintf(L"--- VK_%d -> SC_ [%c] dk=%d ( ss %i) \n", KMX_VKMap[i], ch == 0 ? 32 : ch, DeadKey, VKShiftState[j]); + // wprintf(L"--- VK_%d -> SC_ [%c] dk=%d ( ss %i) \n", KMX_VKMap[i], ch == 0 ? 32 : ch, DeadKey, VKShiftState[j]); - if(bDeadkeyConversion) { // I4552 - if(ch == 0xFFFF) { + if (bDeadkeyConversion) { // I4552 + if (ch == 0xFFFF) { ch = DeadKey; } } @@ -592,7 +569,7 @@ printf("-------\n"); mac_KMX_ReportUnconvertedKeyboardRules(kbd); - if(!mac_KMX_ImportRules(kbd, all_vector, &keyboard_layout, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 + if (!mac_KMX_ImportRules(kbd, all_vector, &keyboard_layout, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 return FALSE; } @@ -609,8 +586,15 @@ printf("-------\n"); * @param OutputPairs ptr to array of deadkeys * @return size of array of deadkeys */ -int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, vector_dword_3D &all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ) { - + /** _S2 TODO thids is from linux: + * @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard + * @param deadkey deadkey character + * @param [out] OutputPairs pointer to array of [usvk, ch_out] pairs + * @param keymap pointer to the currently used (underlying) keyboard Layout + * @param dk_Table shiftstate of the deadkey + * @return size of array of [usvk, ch_out] pairs + */ +int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* OutputPairs) { UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; @@ -619,60 +603,53 @@ int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, vector_dword OSStatus status; unicodeString[0] = 0; - KMX_WORD *p = OutputPairs; - KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying( all_vector, deadkey); + KMX_WORD* p = OutputPairs; + KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(all_vector, deadkey); - for ( int j=0; j < sizeof(ss_mac)/sizeof(ss_mac[0]); j++) { + for (int j = 0; j < sizeof(ss_mac) / sizeof(ss_mac[0]); j++) { // we start with SPACE (keycode_spacebar=49) since all deadkeys occur in combinations with space. // Since mcompile finds only the first occurance of a dk combination, this makes sure that we always find the dk+SPACE combinations for a deadkey. // If there are more combinations to create a specific character they will not be found. (See comment at the beginning of mac_KMX_DoConvert()) - for ( int i=keycode_spacebar; i >=0; i--) { - status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_convert_Shiftstate_to_MacShiftstate(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + for (int i = keycode_spacebar; i >= 0; i--) { + status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_convert_Shiftstate_to_MacShiftstate(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, i, kUCKeyActionDown, ss_mac[j], LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if (deadkeystate != 0) { + status = UCKeyTranslate(keyboard_layout, i, kUCKeyActionDown, ss_mac[j], LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - if(deadkeystate !=0) { - KMX_WORD vk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[1],0); + if (deadkeystate != 0) { + KMX_WORD vk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[1], 0); // ensure to not get key combinations like ^a but only combined characters like â ( exception for ^+space) - if((unicodeString[0] != deadkey) || (vk == 32)) { + if ((unicodeString[0] != deadkey) || (vk == 32)) { *p++ = vk; *p++ = ss_mac[j]; - *p++ =unicodeString[0]; + *p++ = unicodeString[0]; } } } } } *p = 0; - return (p-OutputPairs); + return (p - OutputPairs); } - - /** - * @brief print (error) messages - * @param fmt text to print - * @return void - */ + /** @brief print (error) messages */ void mac_KMX_LogError(const wchar_t* fmt, ...) { WCHAR fmtbuf[256]; const wchar_t* end = L"\0"; const wchar_t* nl = L"\n"; va_list vars; - int j=0; + int j = 0; va_start(vars, fmt); - vswprintf (fmtbuf,_countof(fmtbuf), fmt, vars ); + vswprintf (fmtbuf, _countof(fmtbuf), fmt, vars); fmtbuf[255] = 0; do { putwchar(fmtbuf[j]); j++; - } - while(fmtbuf[j] != *end); + } while (fmtbuf[j] != *end); putwchar(*nl); - } @@ -702,9 +679,9 @@ bool test_dk_find_entries_S2(KMX_WORD deadkeys[512], int search) { for ( int i=0; i<512;i++) { if (deadkeys[i] == search) { printf("found value %i (first occurance) in deadkeys[%i] ",search, i); - if( i%3 ==0 ) printf("as character \n"); - if( i%3 ==1 ) printf("as shiftstate \n"); - if( i%3 ==2 ) printf("as combined character \n"); + if ( i%3 ==0 ) printf("as character \n"); + if ( i%3 ==1 ) printf("as shiftstate \n"); + if ( i%3 ==2 ) printf("as combined character \n"); return true; } } @@ -728,18 +705,18 @@ bool moreval=false; for ( int caps=0; caps< 2;caps++) { for ( int ss=0; ss< 10;ss++) { - if( ss == 0 ) ss_rgkey= 0; - else if( ss == 2 ) ss_rgkey= 1; - else if( ss == 8 ) ss_rgkey= 6; - else if( ss == 10 ) ss_rgkey= 7; + if ( ss == 0 ) ss_rgkey= 0; + else if ( ss == 2 ) ss_rgkey= 1; + else if ( ss == 8 ) ss_rgkey= 6; + else if ( ss == 10 ) ss_rgkey= 7; else ss_rgkey= 999; -if( (ss==1) || (ss==3) || (ss==5) || (ss==7) || (ss==9) ) +if ( (ss==1) || (ss==3) || (ss==5) || (ss==7) || (ss==9) ) continue; int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, ss, caps); count++; - if((ss_rgkey!= 999 )&& ( keyval!= 0)&& ( keyval== keyvalsearch)&& ( count>1)&& ( key!=k)) { + if ((ss_rgkey!= 999 )&& ( keyval!= 0)&& ( keyval== keyvalsearch)&& ( count>1)&& ( key!=k)) { printf( " key: %i, ss_mac: %i ( ss_rgkey:%i), caps:%i \n",key, ss, ss_rgkey, caps); moreval=true; } @@ -778,19 +755,19 @@ bool find_character_S2(const UCKeyboardLayout * keyboard_layout, int keyval) { int ss_rgkey; for ( int ss=0; ss< 10;ss++) { -if( ss == 0 ) ss_rgkey= 0; -else if( ss == 2 ) ss_rgkey= 1; -else if( ss == 8 ) ss_rgkey= 6; -else if( ss == 10 ) ss_rgkey= 7; +if ( ss == 0 ) ss_rgkey= 0; +else if ( ss == 2 ) ss_rgkey= 1; +else if ( ss == 8 ) ss_rgkey= 6; +else if ( ss == 10 ) ss_rgkey= 7; else ss_rgkey= 999; -if( (ss==1) || (ss==3) || (ss==5) || (ss==7) || (ss==9) ) +if ( (ss==1) || (ss==3) || (ss==5) || (ss==7) || (ss==9) ) continue; for ( int caps=0; caps< 2;caps++) { for ( int key=0; key< 50;key++) { int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, mac_map_rgkey_ShiftState_to_Shiftstate(ss), caps); - if((ss_rgkey!= 999 )&& ( keyval== keyvalsearch)) + if ((ss_rgkey!= 999 )&& ( keyval== keyvalsearch)) printf( " found keyval: key: %i, ss_mac:%i ( ss_rgkey:%i), caps:%i -> character: %i (%c) \n", key, ss, ss_rgkey, caps, keyvalsearch,keyvalsearch); } } diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index ab4bfa52d3c..1603ec6e23c 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -1,12 +1,3 @@ -#ifndef MCOMPILE_H -#define MCOMPILE_H - -#include "keymap.h" -#include -#include -#include "mc_import_rules.h" -#include "mc_kmxfile.h" - /* Name: mcompile Copyright: Copyright (C) 2003-2017 SIL International. @@ -26,24 +17,35 @@ */ +#ifndef MCOMPILE_H +#define MCOMPILE_H +#include +#include "keymap.h" +#include "mc_kmxfile.h" +#include +#include "mc_import_rules.h" -struct KMX_DeadkeyMapping { // I4353 +struct KMX_DeadkeyMapping { // I4353 KMX_WCHAR deadkey, dkid; UINT shift; KMX_WORD vk; }; -extern std::vector KMX_FDeadkeys; // I4353 +extern std::vector KMX_FDeadkeys; // I4353 -int mac_run(int argc, std::vector str_argv, char* argv[]); +int mac_run(int argc, std::vector str_argv, char* argv[]); PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); -int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, vector_dword_3D &all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ); // returns array of [usvk, ch_out] pairs +int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* OutputPairs); // returns array of [usvk, ch_out] pairs +/** + * @brief print (error) messages + * @param fmt text to print + * @return void + */ void mac_KMX_LogError(const wchar_t* fmt, ...); - //################################################################################################################################################ //################################################################################################################################################ @@ -58,4 +60,4 @@ bool test_dk_write_entries_S2(KMX_WORD deadkeys[512]); void fun2(); void testmyFunctions_S2(); -#endif // MCOMPILE_H \ No newline at end of file +#endif /*MCOMPILE_H*/ \ No newline at end of file diff --git a/mac/mcompile/u16.cpp b/mac/mcompile/u16.cpp index df604cf8c69..6f5d297f8be 100755 --- a/mac/mcompile/u16.cpp +++ b/mac/mcompile/u16.cpp @@ -1,17 +1,13 @@ #include "u16.h" - -//#include -//#include #include #include #include - std::vector convert_argv_to_Vector_u16str(int argc, char* argv[]) { std::vector vector_u16; // for each arg convert to u16string and push to vector - for (char** arg = argv, i=0; *arg; ++arg,i++) { + for (char **arg = argv, i = 0; *arg; ++arg, i++) { std::string S(*arg); vector_u16.push_back(u16string_from_string(S)); } @@ -22,20 +18,22 @@ std::vector convert_argvW_to_Vector_u16str(int argc, wchar_t* ar std::vector vector_u16; // for each arg convert to u16string and push to vector - for (wchar_t** arg = argv, i=0; *arg; ++arg,i++) { + for (wchar_t **arg = argv, i = 0; *arg; ++arg, i++) { std::wstring S(*arg); vector_u16.push_back(u16string_from_wstring(S)); } return vector_u16; } -//String <- wstring +// ToDo codecvt needs to be replaced !! + +// String <- wstring std::string string_from_wstring(std::wstring const str) { std::wstring_convert, wchar_t> converter; return converter.to_bytes(str); } -//wstring <- string +// wstring <- string std::wstring wstring_from_string(std::string const str) { std::wstring_convert, wchar_t> converter; return converter.from_bytes(str); @@ -43,42 +41,30 @@ std::wstring wstring_from_string(std::string const str) { // u16String <- wstring std::u16string u16string_from_wstring(std::wstring const wstr) { - std::string str= string_from_wstring(wstr); + std::string str = string_from_wstring(wstr); std::u16string str16 = u16string_from_string(str); return str16; } -//u16String <- string +// u16String <- string std::u16string u16string_from_string(std::string const str) { std::wstring_convert, char16_t> converter; return converter.from_bytes(str); } -//string <- u16string +// string <- u16string std::string string_from_u16string(std::u16string const str) { std::wstring_convert, char16_t> converter; return converter.to_bytes(str); } -//wstring <- u16string +// wstring <- u16string std::wstring wstring_from_u16string(std::u16string const str16) { std::string str = string_from_u16string(str16); - std::wstring wstr = wstring_from_string( str); + std::wstring wstr = wstring_from_string(str); return wstr; } -// often used with c_str() e.g. u16fmt( DEBUGSTORE_MATCH).c_str() -// UTF16 (= const char16_t*) -> UTF8 (= std::string) -> UTF16 ( = std::wstring 16 bit) -std::wstring u16fmt(const KMX_WCHAR * str) { - std::wstring_convert, wchar_t> convert_wstring; - std::wstring_convert, char16_t> convert; - - // UTF16 (= const char16_t*) -> UTF8 (= std::string) -> UTF16 ( = std::wstring 16 bit) - std::string utf8str = convert.to_bytes(str); // UTF16 (= const char16_t*) -> UTF8 (= std::string) - std::wstring wstr = convert_wstring.from_bytes(utf8str); // UTF8 (= std::string) -> UTF16 ( = std::wstring 16 bit) - return wstr; -} - -void u16sprintf(KMX_WCHAR * dst, const size_t sz, const wchar_t* fmt, ...) { +void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...) { // UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) wchar_t* wbuf = new wchar_t[sz]; va_list args; @@ -90,64 +76,46 @@ void u16sprintf(KMX_WCHAR * dst, const size_t sz, const wchar_t* fmt, ...) { std::wstring_convert, char16_t> convert; // UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) - std::string utf8str = convert_wstring.to_bytes(wbuf); // UTF16 ( = const wchar_t*) -> std::string - std::u16string u16str = convert.from_bytes(utf8str); // std::string -> std::u16string - u16ncpy(dst, u16str.c_str(), sz); // std::u16string.c_str() -> char16_t* + std::string utf8str = convert_wstring.to_bytes(wbuf); // UTF16 ( = const wchar_t*) -> std::string + std::u16string u16str = convert.from_bytes(utf8str); // std::string -> std::u16string + u16ncpy(dst, u16str.c_str(), sz); // std::u16string.c_str() -> char16_t* delete[] wbuf; } - std::wstring convert_pchar16T_To_wstr(KMX_WCHAR *Name){ +std::wstring convert_pchar16T_To_wstr(KMX_WCHAR* Name) { // convert char16_t* -> std::u16string -> std::string -> std::wstring // char16_t* -> std::u16string std::u16string u16str(Name); // std::u16string -> std::string std::string stri = string_from_u16string(u16str); // std::string -> std::wstring - std::wstring wstr = wstring_from_string(stri); + std::wstring wstr = wstring_from_string(stri); return wstr; } -long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) -{ +long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) { auto s = string_from_u16string(str); char* t; long int result = strtol(s.c_str(), &t, base); - if (endptr != nullptr) *endptr = (KMX_WCHAR*)str + (t - s.c_str()); + if (endptr != nullptr) + *endptr = (KMX_WCHAR*)str + (t - s.c_str()); return result; } -/* -std::string toHex(int num1) { - if (num1 == 0) - return "0"; - int num = num1; - std::string s = ""; - while (num) { - int temp = num % 16; - if (temp <= 9) - s += (48 + temp); - else - s += (87 + temp); - num = num / 16; - } - reverse(s.begin(), s.end()); - return s; -}*/ -const KMX_WCHAR * u16ncat(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max) { +const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { KMX_WCHAR* o = dst; - dst = (KMX_WCHAR*) u16chr(dst, 0); - //max -= (dst-o); + dst = (KMX_WCHAR*)u16chr(dst, 0); + // max -= (dst-o); while (*src && max > 0) { *dst++ = *src++; max--; } - if(max > 0) + if (max > 0) *dst = 0; return o; } -const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name) -{ +const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name) { const KMX_WCHAR* cp = NULL; cp = u16rchr(Name, '\\'); if (cp == NULL) @@ -164,28 +132,31 @@ KMX_CHAR* strrchr_slash(KMX_CHAR* Name) return cp; } */ -// u16rchr returns last occurence of ch in p; It returns NULL if ch = '\0' and NULL if ch is not found +// u16rchr returns last occurence of ch in p; It returns '\0' if ch == '\0' and NULL if ch is not found const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch) { const KMX_WCHAR* p_end = p + u16len(p) - 1; - if (ch == '\0') return p_end + 1; + if (ch == '\0') + return p_end + 1; while (p_end >= p) { - if (*p_end == ch) return p_end; + if (*p_end == ch) + return p_end; p_end--; } return NULL; } -const KMX_WCHAR * u16chr(const KMX_WCHAR *p, KMX_WCHAR ch) { +const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch) { while (*p) { - if (*p == ch) return p; + if (*p == ch) + return p; p++; } return ch == 0 ? p : NULL; } -const KMX_WCHAR * u16cpy(KMX_WCHAR *dst, const KMX_WCHAR *src) { - KMX_WCHAR *o = dst; +const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src) { + KMX_WCHAR* o = dst; while (*src) { *dst++ = *src++; } @@ -193,20 +164,20 @@ const KMX_WCHAR * u16cpy(KMX_WCHAR *dst, const KMX_WCHAR *src) { return o; } -const KMX_WCHAR * u16ncpy(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max) { - KMX_WCHAR *o = dst; +const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { + KMX_WCHAR* o = dst; while (*src && max > 0) { *dst++ = *src++; max--; } - while(max > 0) { + while (max > 0) { *dst++ = 0; max--; } return o; } -size_t u16len(const KMX_WCHAR *p) { +size_t u16len(const KMX_WCHAR* p) { int i = 0; while (*p) { p++; @@ -215,18 +186,20 @@ size_t u16len(const KMX_WCHAR *p) { return i; } -int u16cmp(const KMX_WCHAR *p, const KMX_WCHAR *q) { +int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q) { while (*p && *q) { - if (*p != *q) return *p - *q; + if (*p != *q) + return *p - *q; p++; q++; } return *p - *q; } -int u16nicmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count) { +int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { while (*p && *q && count) { - if (toupper(*p) != toupper(*q)) return *p - *q; + if (toupper(*p) != toupper(*q)) + return *p - *q; p++; q++; count--; @@ -236,18 +209,20 @@ int u16nicmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count) { return 0; } -int u16icmp(const KMX_WCHAR *p, const KMX_WCHAR *q) { +int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q) { while (*p && *q) { - if (toupper(*p) != toupper(*q)) return *p - *q; + if (toupper(*p) != toupper(*q)) + return *p - *q; p++; q++; } return *p - *q; } -int u16ncmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count) { +int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { while (*p && *q && count) { - if (*p != *q) return *p - *q; + if (*p != *q) + return *p - *q; p++; q++; count--; @@ -257,78 +232,73 @@ int u16ncmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count) { return 0; } -KMX_WCHAR * u16tok(KMX_WCHAR *p, KMX_WCHAR ch, KMX_WCHAR **ctx) { +KMX_WCHAR* u16tok(KMX_WCHAR* p, KMX_WCHAR ch, KMX_WCHAR** ctx) { if (!p) { p = *ctx; - if (!p) return NULL; + if (!p) + return NULL; } - - KMX_WCHAR *q = p; + KMX_WCHAR* q = p; while (*q && *q != ch) { q++; } if (*q) { *q = 0; q++; - while (*q == ch) q++; + while (*q == ch) + q++; *ctx = q; - } - else { + } else { *ctx = NULL; } - return p; + return *p ? p : NULL; } -KMX_WCHAR * u16tok(KMX_WCHAR* p, KMX_WCHAR* delim, KMX_WCHAR** ctx) { +// _S2 delimiters is array of char ( of size 2) +KMX_WCHAR* u16tok(KMX_WCHAR* p, KMX_WCHAR* delimiters, KMX_WCHAR** ctx) { if (!p) { p = *ctx; - if (!p) return NULL; + if (!p) + return NULL; } - KMX_WCHAR * q = p; - while (*q && !u16chr(delim, *q)) { + KMX_WCHAR* q = p; + while (*q && !u16chr(delimiters, *q)) { q++; } if (*q) { *q = 0; q++; - while (u16chr(delim, *q)) q++; + while (*q && u16chr(delimiters, *q)) + q++; *ctx = q; - } - else { + } else { *ctx = NULL; } - return p; + return *p ? p : NULL; } -double u16tof( KMX_WCHAR* str) -{ +double u16tof(KMX_WCHAR* str) { double val = 0; - int offsetdot=0; + int offsetdot = 0; char digit; PKMX_WCHAR q = (PKMX_WCHAR)u16chr(str, '.'); - size_t pos_dot = q-str ; + size_t pos_dot = q - str; if (pos_dot < 0) pos_dot = u16len(str); - for (size_t i = 0; i < u16len(str); i++) - { + for (size_t i = 0; i < u16len(str); i++) { digit = static_cast(towupper(*str)); if (i > pos_dot - 1) offsetdot = 1; if (digit != '.') - val =val+ ((int(digit)) - 48) * pow(10, (pos_dot - 1- i + offsetdot)); + val = val + ((int(digit)) - 48) * pow(10, (pos_dot - 1 - i + offsetdot)); str++; } return val; } - - -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ diff --git a/mac/mcompile/u16.h b/mac/mcompile/u16.h index 310f4e22bc4..0e61ade4e2b 100755 --- a/mac/mcompile/u16.h +++ b/mac/mcompile/u16.h @@ -1,14 +1,13 @@ #ifndef U16_H #define U16_H -#include +#include "km_types.h" #include -#include #include +#include #include -#include "km_types.h" +#include -// _S2 CHECKED_ std::vector convert_argvW_to_Vector_u16str(int argc, wchar_t* argv[]); std::vector convert_argv_to_Vector_u16str(int argc, char* argv[]); @@ -19,36 +18,26 @@ std::u16string u16string_from_string(std::string const str); std::u16string u16string_from_wstring(std::wstring const wstr); std::string string_from_u16string(std::u16string const str); -std::wstring u16fmt(const KMX_WCHAR * str); -void u16sprintf(KMX_WCHAR * dst, const size_t sz, const wchar_t* fmt, ...); - -std::wstring convert_pchar16T_To_wstr(KMX_WCHAR *Name); - -size_t u16len(const KMX_WCHAR *p); -int u16cmp(const KMX_WCHAR *p, const KMX_WCHAR *q); -int u16icmp(const KMX_WCHAR *p, const KMX_WCHAR *q); -int u16ncmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count); -int u16nicmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count); -const KMX_WCHAR * u16ncpy(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max); -const KMX_WCHAR * u16cpy(KMX_WCHAR *dst, const KMX_WCHAR *src); -const KMX_WCHAR * u16rchr(const KMX_WCHAR *p, KMX_WCHAR ch); -const KMX_WCHAR * u16chr(const KMX_WCHAR *p, KMX_WCHAR ch); -const KMX_WCHAR * u16ncat(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max); -KMX_WCHAR * u16tok(KMX_WCHAR *p, KMX_WCHAR ch, KMX_WCHAR **ctx); -KMX_WCHAR * u16tok(KMX_WCHAR* p, KMX_WCHAR* ch, KMX_WCHAR** ctx); +void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...); + +std::wstring convert_pchar16T_To_wstr(KMX_WCHAR* Name); + +size_t u16len(const KMX_WCHAR* p); +int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q); +int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q); +int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count); +int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count); +const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max); +const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src); +const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch); +const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch); +const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max); +KMX_WCHAR* u16tok(KMX_WCHAR* p, KMX_WCHAR ch, KMX_WCHAR** ctx); +KMX_WCHAR* u16tok(KMX_WCHAR* p, KMX_WCHAR* ch, KMX_WCHAR** ctx); long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base); -double u16tof( KMX_WCHAR* str); +double u16tof(KMX_WCHAR* str); KMX_CHAR* strrchr_slash(KMX_CHAR* Name); const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name); -std::string toHex(int num1); - - #endif /* U16_H */ - - -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - From 48f98cdce9b4cbe749d368fabac18f7786583d13 Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 10 Jul 2024 12:54:38 +0200 Subject: [PATCH 34/71] feat(mac): format documents --- mac/mcompile/keymap.cpp | 128 +++++++++++++++++----------------------- mac/mcompile/keymap.h | 31 +++++----- mac/mcompile/km_types.h | 4 -- 3 files changed, 69 insertions(+), 94 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 06f3b67e3ec..55957c4b20f 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -29,38 +29,37 @@ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) { // _S2 Todo bool is_correct_win_shiftstate(int win_ss) { - return ( (win_ss ==0) || (win_ss ==16) || (win_ss ==9) || (win_ss ==25) || (win_ss ==0xFFFF) ); + return ((win_ss == 0) || (win_ss == 16) || (win_ss == 9) || (win_ss == 25) || (win_ss == 0xFFFF)); } // _S2 todo missing code /** @brief check for correct input parameter that will later be used in UCKeyTranslate() */ -bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout * keyboard_layout,int keycode, int shiftstate, int caps=0){ - +bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate, int caps = 0) { if (!keyboard_layout) return false; - if ((int) keycode > (int)keycode_max) + if ((int)keycode > (int)keycode_max) return false; if ((shiftstate > max_shiftstate)) return false; - if ((caps> 1)) + if ((caps > 1)) return false; return true; } /** @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard */ -int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeyboardLayout * keyboard_layout) { +int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { // store contents of the English (US) keyboard in all_vector - if(mac_write_US_ToVector(all_vector)) { + if (mac_write_US_ToVector(all_vector)) { wprintf(L"ERROR: can't write US to Vector \n"); return 1; } // add contents of underlying keyboard to all_vector - if ( mac_append_underlying_ToVector(all_vector, keyboard_layout)) { + if (mac_append_underlying_ToVector(all_vector, keyboard_layout)) { wprintf(L"ERROR: can't append underlying ToVector \n"); return 2; } @@ -68,7 +67,7 @@ int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeybo } /** @brief write data of the US keyboard into a 3D-Vector */ -int mac_write_US_ToVector( vec_dword_3D& vec_us) { +int mac_write_US_ToVector(vec_dword_3D& vec_us) { //_S2 TODO // Values for US : A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P,CR, L, J, ', K, ;, \, ,, /, N, M, . std::vector us_Base = {97,115,100,102,104,103,122,120,99,118,167,98,113,119,101,114,121,116,49,50,51,52,54,53,61,57,55,45,56,48, 93,111,117, 91,105,112,13,108,106,39,107,59, 92,44,47,110,109,46}; @@ -77,7 +76,7 @@ int mac_write_US_ToVector( vec_dword_3D& vec_us) { vec_dword_1D values; vec_dword_2D key; - for ( int i=0; i< us_Base.size(); i++) { + for (int i = 0; i < us_Base.size(); i++) { values.push_back(i); values.push_back(us_Base[i]); values.push_back(us_Shift[i]); @@ -86,16 +85,14 @@ int mac_write_US_ToVector( vec_dword_3D& vec_us) { } vec_us.push_back(key); - if ( key.size() == 0) { + if (key.size() == 0) { wprintf(L"ERROR: can't Create Vector for US keyboard\n"); return 1; - } - else + } else return 0; } - - /** @brief create an 2D-Vector with all fields containing INVALID_NAME */ +/** @brief create an 2D-Vector with all fields containing INVALID_NAME */ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss) { vec_dword_1D shifts; vec_dword_2D vector_2D; @@ -110,10 +107,9 @@ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss) { return vector_2D; } - /** @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector */ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { - int caps=0; + int caps = 0; if (all_vector.size() != 1) { printf("ERROR: data for US keyboard not correct\n"); return 1; @@ -137,18 +133,16 @@ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLay // get key name US stored in [0][i][0] and copy to name in "underlying"-block[1][i][0] all_vector[1][i][0] = all_vector[0][i][0]; - for ( int k=0; k < 2; k++) { - all_vector[1][i][k+1] = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, all_vector[0][i][0], mac_map_rgkey_ShiftState_to_Shiftstate(k),0); + for (int k = 0; k < 2; k++) { + all_vector[1][i][k + 1] = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, all_vector[0][i][0], mac_map_rgkey_ShiftState_to_Shiftstate(k), 0); } } return 0; } - /** @brief create a pointer to pointer of the current keymap for later use */ -bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { - +bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout) { TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); if (!source) { wprintf(L"ERROR: can't get source\n"); @@ -156,7 +150,7 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { } CFDataRef layout_data = static_cast((TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData))); - * keyboard_layout = reinterpret_cast(CFDataGetBytePtr(layout_data)); + *keyboard_layout = reinterpret_cast(CFDataGetBytePtr(layout_data)); if (!keyboard_layout) { wprintf(L"ERROR: Can't get keyboard_layout\n"); return 2; @@ -165,7 +159,6 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { return 0; } - /** old * @brief return the keyvalue for a given Keycode, shiftstate and caps of the currently used (underlying) keyboard Layout * What character will be produced for a keypress of a key and modifiers? @@ -176,13 +169,13 @@ bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout) { * @return the keyval obtained from Keycode, shiftstate and caps */ /** @brief return the keyvalue for a given Keycode, shiftstate and caps */ -KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps) { +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps) { UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; OptionBits keyTranslateOptions = 0; UniChar unicodeString[maxStringlength]; - OSStatus status ; + OSStatus status; unicodeString[0] = 0; /*if (!keyboard_layout) @@ -197,29 +190,27 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layo if (!(caps <= 1)) return 0;*/ - if(! ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) + if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) return 0; - status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); // If this was a deadkey,append a space - if(deadkeystate !=0) - status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown, (shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if (deadkeystate != 0) + status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); // if there is no character assigned to the Key+Shift+CAPS UCKeyTranslate writes 0x01 into unicodeString[0] - if( unicodeString[0] == 1 ) // impossible character + if (unicodeString[0] == 1) // impossible character return 0; else { - return unicodeString[0]; // combined char e.g. â + return unicodeString[0]; // combined char e.g. â } return 0; } - //_S2 ToDO -KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32 &deadkeystate) { - +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32& deadkeystate) { UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; OptionBits keyTranslateOptions = 0; @@ -239,26 +230,24 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_l if (!(caps <= 1)) return 0;*/ - if(! ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) + if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) return 0; // if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 - status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown,(shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); // If this was a deadkey,append a space - if(deadkeystate !=0) - status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown,(shiftstate_mac+ 4*caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if (deadkeystate != 0) + status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown,(shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); // if there is no character assigned to the Key+Shift+CAPS UCKeyTranslate writes 0x01 into unicodeString[0] - if(unicodeString[0] == 1 ) // impossible character + if (unicodeString[0] == 1) // impossible character return 0; else - return unicodeString[0]; // combined char e.g. â + return unicodeString[0]; // combined char e.g. â } - - /** @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout and copy deadkey into deadKey */ -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey) { +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey) { PKMX_WCHAR dky = NULL; UInt32 isdk = 0; KMX_DWORD keyV; @@ -267,21 +256,21 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa /*if (!keyboard_layout) return 0; - if(!(is_correct_win_shiftstate(vk_ShiftState))) + if (!(is_correct_win_shiftstate(vk_ShiftState))) return 0; if (!(kc_underlying <= keycode_max)) return 0;*/ - if(! ensureValidInputForKeyboardTranslation(keyboard_layout, kc_underlying, is_correct_win_shiftstate(vk_ShiftState))) + if (!ensureValidInputForKeyboardTranslation(keyboard_layout, kc_underlying, is_correct_win_shiftstate(vk_ShiftState))) return 0; - keyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, kc_underlying,(mac_convert_Shiftstate_to_MacShiftstate(vk_ShiftState)), caps, isdk); + keyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, kc_underlying, (mac_convert_Shiftstate_to_MacShiftstate(vk_ShiftState)), caps, isdk); // if there was a deadkey return 0xFFFF and copy deadkey into dky - if( isdk !=0) { - dky = (PKMX_WCHAR) (std::u16string(1, keyV)).c_str(); + if (isdk != 0) { + dky = (PKMX_WCHAR)(std::u16string(1, keyV)).c_str(); *deadKey = *dky; return 0xFFFF; } @@ -289,12 +278,11 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa return keyV; } - /** @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard */ -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us) { +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us) { // look for kv_us for any shiftstate of US keyboard for (int i = 0; i < (int)all_vector[0].size() - 1; i++) { - for (int j = 1; j < (int)all_vector[0][0].size(); j++) { + for (int j = 1; j < (int)all_vector[0][0].size(); j++) { if (all_vector[0][i][j] == kv_us) return all_vector[1][i][j]; } @@ -311,12 +299,11 @@ KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, * @param kv_underlying a keyvalue on the currently used (underlying) keyboard * @return keycode of the underlying keyboardif foundf; else the keyval of the underlying keyboard */ -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying) { - +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying) { // look for kv_us for any shiftstate of US keyboard - for ( int i=0; i< all_vector[1].size()-1 ;i++) { - for ( int j=1; j< all_vector[1][0].size();j++) { - if ( all_vector[1][i][j] == kv_underlying ) { + for (int i = 0; i < all_vector[1].size() - 1; i++) { + for (int j = 1; j < all_vector[1][0].size(); j++) { + if (all_vector[1][i][j] == kv_underlying) { return all_vector[1][i][0]; } } @@ -324,25 +311,22 @@ KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all return kv_underlying; } /** @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard */ -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) { - +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) { // first get the keyvalue of the key on the US keyboard (kc_us) - std::u16string u16str = std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_map_rgkey_ShiftState_to_Shiftstate(ss_win), caps) ); + std::u16string u16str = std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_map_rgkey_ShiftState_to_Shiftstate(ss_win), caps)); // then find the same keyvalue on the underlying keyboard and return the keycode of that key on the underlying keyboard for (int i = 0; i < all_vector[1].size() - 1; i++) { for (int j = 1; j < all_vector[1][0].size(); j++) { - if (((KMX_DWORD) all_vector[1][i][j] == (KMX_DWORD)*u16str.c_str() ) ) + if (((KMX_DWORD)all_vector[1][i][j] == (KMX_DWORD)*u16str.c_str())) return all_vector[1][i][0]; } } return kc_us; } - - /** @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard */ -UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us) { +UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us) { // On mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an 'artificial' us virtual key return (mac_USVirtualKeyToScanCode[vk_us]); } @@ -366,8 +350,7 @@ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { * @param caps state of the caps key of a character key on the currently used (underlying) keyboard * @return the combination of deadkey + character if it is available; if not return 0 */ -KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps) { - +KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps) { UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; @@ -376,18 +359,17 @@ KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyb unicodeString[0] = 0; OSStatus status; - status = UCKeyTranslate(keyboard_layout, vk_dk, kUCKeyActionDown, ss_dk, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + status = UCKeyTranslate(keyboard_layout, vk_dk, kUCKeyActionDown, ss_dk, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); // If this was a deadkey,append a character - if(deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout,(UInt16) vk_us, kUCKeyActionDown, shiftstate_mac+4*caps, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); + if (deadkeystate != 0) { + status = UCKeyTranslate(keyboard_layout,(UInt16) vk_us, kUCKeyActionDown, shiftstate_mac+4*caps, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - if(unicodeString[0] == 1 ) // impossible character + if (unicodeString[0] == 1) // impossible character return 0; else - return unicodeString[0]; // combined char e.g. â - } - else + return unicodeString[0]; // combined char e.g. â + } else return 0; } diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 7867fd045ca..7ee49ef521e 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -23,7 +23,7 @@ enum ShiftState { }; // shiftstates we can use for mac: Base;Shift, OPTION, Shift+OPTION -static int ss_mac[]={0,2,8,10}; +static int ss_mac[] = {0, 2, 8, 10}; // Map of all US English virtual key codes that we can translate const KMX_DWORD KMX_VKMap[] = { @@ -84,15 +84,10 @@ bool is_correct_win_shiftstate(int comp_ss); * @param cap the code of the key in question * @return true if all parameters are OK; false if not */ -bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout * keyboard_layout,int keycode, int shiftstate, int cap); - - - +bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate, int cap); // _S2 TODO - - /** * @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard : * all_vector [ US_Keyboard ] @@ -127,15 +122,17 @@ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss); * @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector * @param[in,out] all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param keyboard_layout ptr to currently used (underlying) keybord layout - * @return 0 on success; 1 if the initialization of the underlying vector failes; 2 if data of less than 2 keyboards is contained in all_vector + * @return 0 on success; + * 1 if the initialization of the underlying vector failes; + * 2 if data of less than 2 keyboards is contained in all_vector; */ -int mac_append_underlying_ToVector(vec_dword_3D &all_vector, const UCKeyboardLayout * keyboard_layout); +int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout); /** * @brief create a pointer to pointer of the current keyboard_layout for later use * @param keyboard_layout ptr to ptr to currently used (underlying) keyborad layout * @return 0 on success; 1 if the display is not found; 2 if the keymap is not found */ -bool mac_InitializeUCHR(const UCKeyboardLayout **keyboard_layout); +bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout); // we use the same type of array as throughout Keyman even though we have lots of unused fields const UINT mac_USVirtualKeyToScanCode[256] = { @@ -543,10 +540,10 @@ const UINT mac_ScanCodeToUSVirtualKey[128] = { * @return the keyval obtained from keycode, shiftstate and caps */ // _S2 ShiftState ss vs int shiftstate_mac -KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps); +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps); //_S2 TODO -KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32 &deadkeystate); +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32& deadkeystate); /** // _S2 shift_state_pos vs int shiftstate_mac * @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. @@ -556,7 +553,7 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout * keyboard_l * @param shift_state_pos a shiftstate of the currently used keyboard layout * @return the keyval obtained from Keycode and shiftstate; */ -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, int keycode, int shiftstate_mac); +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac); /** * @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. @@ -571,7 +568,7 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa * @return 0xFFFF in case a deadkey was found, then the deadkey is stored in deadKey * the keyval obtained from Keycode and shiftstate and caps; */ -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout * keyboard_layout, UINT keycode, UINT shiftState, PKMX_WCHAR deadKey); +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, UINT keycode, UINT shiftState, PKMX_WCHAR deadKey); /** * @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard @@ -580,7 +577,7 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa * @param kv_us a keyvalue on the US keyboard * @return keyval of the underlying keyboard if available; else the keyval of the US keyboard */ -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D &all_vector, KMX_DWORD kv_us); +KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us); /** * @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard @@ -592,7 +589,7 @@ KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D &all_vector, K * @param caps state of the caps key * @return the keycode of the underlying keyboard if found; else the keycode of the US keyboard */ -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, vec_dword_3D &all_vector, KMX_DWORD kc_us, ShiftState ss, int caps); +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss, int caps); /** * @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard @@ -611,7 +608,7 @@ UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD virtualKeyUS); KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); //_S2 TODO -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D & all_vector, KMX_DWORD kv_underlying); +KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying); //_S2 TODO KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps); //_S2 TODO CodePointToU16String?? diff --git a/mac/mcompile/km_types.h b/mac/mcompile/km_types.h index 8251cf7d481..5381ff1e6a4 100755 --- a/mac/mcompile/km_types.h +++ b/mac/mcompile/km_types.h @@ -1,11 +1,7 @@ - - #pragma once #ifndef KM_TYPES #define KM_TYPES - #include - /* #if defined(_WIN32) || defined(_WIN64) #define snprintf _snprintf From 70b232a95b50384ce184491f081d5b0785fc5db8 Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 10 Jul 2024 15:59:57 +0200 Subject: [PATCH 35/71] feat(mac): comments from #9384 --- mac/mcompile/keymap.cpp | 16 +++---- mac/mcompile/mc_import_rules.cpp | 15 +++---- mac/mcompile/mc_kmxfile.cpp | 71 ++++++++++++-------------------- mac/mcompile/mc_kmxfile.h | 1 + mac/mcompile/mcompile.cpp | 43 ++++++++++--------- mac/mcompile/mcompile.h | 4 -- mac/mcompile/u16.cpp | 18 ++++---- 7 files changed, 71 insertions(+), 97 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 55957c4b20f..2f3df338035 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -54,13 +54,13 @@ return true; int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { // store contents of the English (US) keyboard in all_vector if (mac_write_US_ToVector(all_vector)) { - wprintf(L"ERROR: can't write US to Vector \n"); + printf("ERROR: can't write US to Vector \n"); return 1; } // add contents of underlying keyboard to all_vector if (mac_append_underlying_ToVector(all_vector, keyboard_layout)) { - wprintf(L"ERROR: can't append underlying ToVector \n"); + printf("ERROR: can't append underlying ToVector \n"); return 2; } return 0; @@ -86,7 +86,7 @@ int mac_write_US_ToVector(vec_dword_3D& vec_us) { vec_us.push_back(key); if (key.size() == 0) { - wprintf(L"ERROR: can't Create Vector for US keyboard\n"); + printf("ERROR: can't Create Vector for US keyboard\n"); return 1; } else return 0; @@ -119,13 +119,13 @@ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLay vec_dword_2D underlying_Vector2D = mac_create_empty_2D_Vector(all_vector[0].size(), all_vector[0][0].size()); if (underlying_Vector2D.size() == 0) { - wprintf(L"ERROR: can't create empty 2D-Vector\n"); + printf("ERROR: can't create empty 2D-Vector\n"); return 1; } all_vector.push_back(underlying_Vector2D); if (all_vector.size() < 2) { - wprintf(L"ERROR: creation of 3D-Vector failed\n"); + printf("ERROR: creation of 3D-Vector failed\n"); return 2; } @@ -145,17 +145,17 @@ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLay bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout) { TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); if (!source) { - wprintf(L"ERROR: can't get source\n"); + printf("ERROR: can't get source\n"); return 1; } CFDataRef layout_data = static_cast((TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData))); *keyboard_layout = reinterpret_cast(CFDataGetBytePtr(layout_data)); if (!keyboard_layout) { - wprintf(L"ERROR: Can't get keyboard_layout\n"); + printf("ERROR: Can't get keyboard_layout\n"); return 2; } - // intentionally leaking `display` in order to still be able to access `keymap` + // intentionally leaking `source` in order to still be able to access `keymap` return 0; } diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 607a564c009..45948052e6a 100755 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -79,7 +79,7 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_win, int caps, if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, ss_win, caps)) return 0; - keyval= mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_map_rgkey_ShiftState_to_Shiftstate(ShiftState(ss_win)), caps, isdk); + keyval = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_map_rgkey_ShiftState_to_Shiftstate(ShiftState(ss_win)), caps, isdk); std::u16string str =std::u16string(1, keyval ); pwszBuff[0] = *(PKMX_WCHAR)str.c_str(); @@ -226,7 +226,7 @@ class mac_KMX_VirtualKey { for (size_t ich = 0; ich < st.size(); ich++) { if (st[ich] < 0x20 || st[ich] == 0x7F) { isvalid = false; - wprintf(L"invalid for: %i\n", st[ich]); + wprintf(L"invalid for: %i\n", st[ich]); break; } } @@ -467,11 +467,6 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK } } -// // _S2 I assume we do not need those... -// rgKey[VK_DIVIDE] = new mac_KMX_VirtualKey(hkl, VK_DIVIDE); -// rgKey[VK_CANCEL] = new mac_KMX_VirtualKey(hkl, VK_CANCEL); -// rgKey[VK_DECIMAL] = new mac_KMX_VirtualKey(hkl, VK_DECIMAL); - // in this part we skip shiftstates 4, 5, 8, 9 for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { if (rgKey[iKey] != NULL) { @@ -483,11 +478,11 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK } //_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! - if (ss == MenuCtrl || ss == ShftMenuCtrl) { + /*if (ss == MenuCtrl || ss == ShftMenuCtrl) { continue; - } + }*/ - KMX_DWORD KC_US = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); + KMX_DWORD KC_US = (KMX_DWORD)mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); for (int caps = 0; caps <= 1; caps++) { int rc = mac_KMX_ToUnicodeEx(KC_US, sbBuffer, ss, caps, *keyboard_layout); diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index 0b9ba7025a1..0cfef9ef6a6 100755 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -7,7 +7,7 @@ #define CERR_UnableToWriteFully 0x00008007 #define CERR_SomewhereIGotItWrong 0x00008009 -KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug) { +KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug) { LPKMX_GROUP fgp; LPKMX_STORE fsp; @@ -33,22 +33,22 @@ KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL for(i = 0, fgp = fk->dpGroupArray; i < fk->cxGroupArray; i++, fgp++) { if(fgp->dpName) - size += u16len(fgp->dpName)*2 + 2; + size += (u16len(fgp->dpName) + 1) * sizeof(KMX_WCHAR); size += fgp->cxKeyArray * sizeof(KMX_COMP_KEY); for(j = 0, fkp = fgp->dpKeyArray; j < fgp->cxKeyArray; j++, fkp++) { - size += u16len(fkp->dpOutput)*2 + 2; - size += u16len(fkp->dpContext)*2 + 2; + size += (u16len(fkp->dpOutput) + 1) * sizeof(KMX_WCHAR); + size += (u16len(fkp->dpContext) + 1) * sizeof(KMX_WCHAR); } - if( fgp->dpMatch ) size += u16len(fgp->dpMatch)*2 + 2; - if( fgp->dpNoMatch ) size += u16len(fgp->dpNoMatch)*2 + 2; + if( fgp->dpMatch ) size += (u16len(fgp->dpMatch) + 1) * sizeof(KMX_WCHAR); + if( fgp->dpNoMatch ) size += (u16len(fgp->dpNoMatch) + 1) * sizeof(KMX_WCHAR); } for(i = 0; i < fk->cxStoreArray; i++) { - size += u16len(fk->dpStoreArray[i].dpString)*2 + 2; + size += (u16len(fk->dpStoreArray[i].dpString) + 1) * sizeof(KMX_WCHAR); if(fk->dpStoreArray[i].dpName) - size += u16len(fk->dpStoreArray[i].dpName)*2 + 2; + size += (u16len(fk->dpStoreArray[i].dpName) + 1) * sizeof(KMX_WCHAR); } buf = new KMX_BYTE[size]; @@ -73,22 +73,6 @@ KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL offset = sizeof(KMX_COMP_KEYBOARD); - // ck->dpLanguageName = offset; - //wcscpy((PWSTR)(buf + offset), fk->szLanguageName); - //offset += wcslen(fk->szLanguageName)*2 + 2; - - //ck->dpName = offset; - //wcscpy((PWSTR)(buf + offset), fk->szName); - //offset += wcslen(fk->szName)*2 + 2; - - //ck->dpCopyright = offset; - //wcscpy((PWSTR)(buf + offset), fk->szCopyright); - //offset += wcslen(fk->szCopyright)*2 + 2; - - //ck->dpMessage = offset; - //wcscpy((PWSTR)(buf + offset), fk->szMessage); - //offset += wcslen(fk->szMessage)*2 + 2; - ck->dpStoreArray = offset; sp = (PKMX_COMP_STORE)(buf+offset); fsp = fk->dpStoreArray; @@ -97,14 +81,14 @@ KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL sp->dwSystemID = fsp->dwSystemID; sp->dpString = offset; u16ncpy((PKMX_WCHAR)(buf+offset), fsp->dpString, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 - offset += u16len(fsp->dpString)*2 + 2; + offset += (u16len(fsp->dpString) + 1) * sizeof(KMX_WCHAR); if(!fsp->dpName) { sp->dpName = 0; } else { sp->dpName = offset; u16ncpy((PKMX_WCHAR)(buf+offset), fsp->dpName, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 - offset += u16len(fsp->dpName)*2 + 2; + offset += (u16len(fsp->dpName) + 1) * sizeof(KMX_WCHAR); } } @@ -123,38 +107,37 @@ KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL if(fgp->dpMatch) { gp->dpMatch = offset; u16ncpy((PKMX_WCHAR)(buf+offset), fgp->dpMatch, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 - offset += u16len(fgp->dpMatch)*2 + 2; + offset += (u16len(fgp->dpMatch) + 1) * sizeof(KMX_WCHAR); } if(fgp->dpNoMatch) { gp->dpNoMatch = offset; u16ncpy((PKMX_WCHAR)(buf+offset), fgp->dpNoMatch, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 - offset += u16len(fgp->dpNoMatch)*2 + 2; + offset += (u16len(fgp->dpNoMatch) + 1) * sizeof(KMX_WCHAR); } if(fgp->dpName) { gp->dpName = offset; u16ncpy((PKMX_WCHAR)(buf+offset), fgp->dpName, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 - offset += u16len(fgp->dpName)*2 + 2; + offset += (u16len(fgp->dpName) + 1) * sizeof(KMX_WCHAR); } else { gp->dpName = 0; } gp->dpKeyArray = offset; kp = (PKMX_COMP_KEY) (buf + offset); - fkp = fgp->dpKeyArray; offset += gp->cxKeyArray * sizeof(KMX_COMP_KEY); - for(j = 0; j < gp->cxKeyArray; j++, kp++, fkp++) { + for(j = 0, fkp = fgp->dpKeyArray; j < gp->cxKeyArray; j++, kp++, fkp++) { kp->Key = fkp->Key; kp->Line = fkp->Line; kp->ShiftFlags = fkp->ShiftFlags; kp->dpOutput = offset; u16ncpy((PKMX_WCHAR)(buf+offset), fkp->dpOutput, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 - offset += u16len(fkp->dpOutput)*2 + 2; + offset += (u16len(fkp->dpOutput) + 1) * sizeof(KMX_WCHAR); kp->dpContext = offset; u16ncpy((PKMX_WCHAR)(buf+offset), fkp->dpContext, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 - offset += u16len(fkp->dpContext)*2 + 2; + offset += (u16len(fkp->dpContext) + 1) * sizeof(KMX_WCHAR); } } @@ -168,12 +151,6 @@ KMX_DWORD KMX_WriteCompiledKeyboard(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL ck->dpBitmapOffset = 0; } - if(offset != size) - { - delete[] buf; - return CERR_SomewhereIGotItWrong; - } - fwrite(buf, size,1, hOutfile); if(offset != size) { @@ -202,7 +179,7 @@ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename) { return FALSE; } - KMX_DWORD err = KMX_WriteCompiledKeyboard(kbd, fp, FALSE); + KMX_DWORD err = KMX_WriteCompiledKeyboardToFile(kbd, fp, FALSE); fclose(fp); if(err != CERR_None) { @@ -351,7 +328,7 @@ LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFil #endif KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { - + *lpKeyboard = NULL; PKMX_BYTE buf; FILE* fp; LPKMX_KEYBOARD kbp; @@ -376,7 +353,7 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { } auto sz = ftell(fp); - if (sz < 0) { + if (sz <= 0) { fclose(fp); return FALSE; } @@ -400,6 +377,7 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { #endif if (!buf) { + delete[] buf; fclose(fp); mac_KMX_LogError(L"Not allocmem\n" ); return FALSE; @@ -413,13 +391,14 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { if (fread(filebase, 1, sz, fp) < (size_t)sz) { mac_KMX_LogError(L"Could not read file\n" ); + delete[] buf; fclose(fp); return FALSE; } - +// delete??? fclose(fp); - if(*PKMX_DWORD(filebase) != KMX_DWORD(FILEID_COMPILED)) + if (*((PKMX_DWORD)filebase) != (KMX_DWORD)FILEID_COMPILED) { delete [] buf; mac_KMX_LogError(L"Invalid file - signature is invalid\n"); @@ -428,6 +407,7 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { if (!KMX_VerifyKeyboard(filebase, sz)) { mac_KMX_LogError(L"errVerifyKeyboard\n" ); + delete[] buf; return FALSE; } @@ -440,6 +420,7 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { if (!kbp) { mac_KMX_LogError(L"errFixupKeyboard\n" ); + delete[] buf; return FALSE; } @@ -480,7 +461,7 @@ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz){ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) { - if (*p == 0) + if (p == NULL || *p == 0) return p; if (*p != UC_SENTINEL) { if (*p >= 0xD800 && *p <= 0xDBFF && *(p + 1) >= 0xDC00 && *(p + 1) <= 0xDFFF) diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index 8ef29dc67c0..b932f4d1371 100755 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -4,6 +4,7 @@ #include "km_types.h" #include "kmx_file.h" + #include "mcompile.h" #ifndef _KMXFILE_H diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index dbed5cede2c..db374177d79 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -4,17 +4,23 @@ * Mnemonic layout support for Linux */ -// -// Defines the entry point for the console application. -// -// Note: this program deliberately leaks memory as it has a very short life cycle and managing the memory allocations -// for the subcomponents of the compiled keyboard is an unnecessary optimisation. Just so you know. -// +/* + Defines the entry point for the console application. + + Note: this program deliberately leaks memory as it has a very short life cycle and managing the memory allocations + for the subcomponents of the compiled keyboard is an unnecessary optimisation. Just so you know. +*/ #include #include #include "mcompile.h" #include "u16.h" + + +int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* OutputPairs); // returns array of [usvk, ch_out] pairs + +int mac_run(int argc, std::vector str_argv, char* argv[]); + /** * @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard * @param kbd pointer to US keyboard @@ -74,13 +80,13 @@ int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NU } if (argc < 3 || (argc > 4)) { // I4273// I4273 - wprintf( - L"Usage: mcompile [-d] infile.kmx outfile.kmx\n" - L" mmcompile -u ... (not available for mac)\n " - L" mcompile converts a Keyman mnemonic layout to a\n" - L" positional one based on the mac keyboard\n" - L" layout on top position\n" - L" (-d convert deadkeys to plain keys) not available yet \n\n"); // I4552 + printf( + "Usage: mcompile [-d] infile.kmx outfile.kmx\n" + " mmcompile -u ... (not available for mac)\n " + " mcompile converts a Keyman mnemonic layout to a\n" + " positional one based on the mac keyboard\n" + " layout on top position\n" + " (-d convert deadkeys to plain keys) not available yet \n\n"); // I4552 return 1; } @@ -374,11 +380,8 @@ void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, KMX_WCHAR mac_KMX_ScanXStringForMaxDeadkeyID(PKMX_WCHAR str) { KMX_WCHAR dkid = 0; while(str && *str) { - if (*str == UC_SENTINEL) { - switch(*(str+1)) { - case CODE_DEADKEY: - dkid = max(dkid, *(str+2)); - } + if(*str == UC_SENTINEL && *(str+1) == CODE_DEADKEY) { + dkid = max(dkid, *(str+2)); } str = KMX_incxstr(str); } @@ -526,13 +529,13 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int const UCKeyboardLayout* keyboard_layout; if (mac_InitializeUCHR(&keyboard_layout)) { - wprintf(L"ERROR: can't Initialize GDK\n"); + printf("ERROR: can't Initialize GDK\n"); return FALSE; } // create vector that contains Keycode, Base, Shift for US-Keyboard and underlying keyboard vec_dword_3D all_vector; if (mac_createOneVectorFromBothKeyboards(all_vector, keyboard_layout)) { - wprintf(L"ERROR: can't create one vector from both keyboards\n"); + printf("ERROR: can't create one vector from both keyboards\n"); return FALSE; } diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 1603ec6e23c..2406b98136e 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -33,12 +33,8 @@ struct KMX_DeadkeyMapping { // I4353 extern std::vector KMX_FDeadkeys; // I4353 -int mac_run(int argc, std::vector str_argv, char* argv[]); - PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); -int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* OutputPairs); // returns array of [usvk, ch_out] pairs - /** * @brief print (error) messages * @param fmt text to print diff --git a/mac/mcompile/u16.cpp b/mac/mcompile/u16.cpp index 6f5d297f8be..32fd6fa4812 100755 --- a/mac/mcompile/u16.cpp +++ b/mac/mcompile/u16.cpp @@ -64,12 +64,12 @@ std::wstring wstring_from_u16string(std::u16string const str16) { return wstr; } -void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...) { +void u16sprintf(KMX_WCHAR* dst, const size_t max_len, const wchar_t* fmt, ...) { // UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) - wchar_t* wbuf = new wchar_t[sz]; + wchar_t* wbuf = new wchar_t[max_len]; va_list args; va_start(args, fmt); - vswprintf(wbuf, sz, fmt, args); + vswprintf(wbuf, max_len, fmt, args); va_end(args); std::wstring_convert, wchar_t> convert_wstring; @@ -78,7 +78,7 @@ void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...) { // UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) std::string utf8str = convert_wstring.to_bytes(wbuf); // UTF16 ( = const wchar_t*) -> std::string std::u16string u16str = convert.from_bytes(utf8str); // std::string -> std::u16string - u16ncpy(dst, u16str.c_str(), sz); // std::u16string.c_str() -> char16_t* + u16ncpy(dst, u16str.c_str(), max_len); // std::u16string.c_str() -> char16_t* delete[] wbuf; } @@ -96,7 +96,8 @@ std::wstring convert_pchar16T_To_wstr(KMX_WCHAR* Name) { long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) { auto s = string_from_u16string(str); char* t; - long int result = strtol(s.c_str(), &t, base); + size_t idx; + long int result = stol(s, &idx, base); if (endptr != nullptr) *endptr = (KMX_WCHAR*)str + (t - s.c_str()); return result; @@ -134,13 +135,10 @@ KMX_CHAR* strrchr_slash(KMX_CHAR* Name) */ // u16rchr returns last occurence of ch in p; It returns '\0' if ch == '\0' and NULL if ch is not found const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch) { - const KMX_WCHAR* p_end = p + u16len(p) - 1; - - if (ch == '\0') - return p_end + 1; + const KMX_WCHAR* p_end = p + u16len(p); while (p_end >= p) { if (*p_end == ch) - return p_end; + return p_end; p_end--; } return NULL; From 96870c49267ebf9091ed952a360951157e323b6a Mon Sep 17 00:00:00 2001 From: Sabine Date: Thu, 11 Jul 2024 09:52:07 +0200 Subject: [PATCH 36/71] feat(mac): comments from all other PR --- mac/mcompile/keymap.cpp | 85 +++++++------- mac/mcompile/keymap.h | 26 +++-- mac/mcompile/km_types.h | 1 + mac/mcompile/kmx_file.h | 1 - mac/mcompile/mc_import_rules.cpp | 97 ++++++---------- mac/mcompile/mc_import_rules.h | 1 + mac/mcompile/mc_kmxfile.cpp | 185 ++++++++++++++++++++++++++++--- mac/mcompile/mc_kmxfile.h | 10 +- mac/mcompile/mcompile.cpp | 68 +++++------- mac/mcompile/u16.cpp | 1 + mac/mcompile/u16.h | 1 + 11 files changed, 296 insertions(+), 180 deletions(-) mode change 100755 => 100644 mac/mcompile/km_types.h mode change 100755 => 100644 mac/mcompile/kmx_file.h mode change 100755 => 100644 mac/mcompile/mc_import_rules.cpp mode change 100755 => 100644 mac/mcompile/mc_import_rules.h mode change 100755 => 100644 mac/mcompile/mc_kmxfile.cpp mode change 100755 => 100644 mac/mcompile/mc_kmxfile.h mode change 100755 => 100644 mac/mcompile/u16.cpp mode change 100755 => 100644 mac/mcompile/u16.h diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 2f3df338035..b9f95f06561 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -7,22 +7,22 @@ #include "keymap.h" #include "kmx_file.h" - /** @brief map shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on mac */ + /** @brief map a shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on the mac */ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) { - if (shiftState == 0) return 0; // Win ss 0 -> mac ss 0 - else if (shiftState == K_SHIFTFLAG) return 2; // Win ss 16 -> mac ss 2 - else if (shiftState == (LCTRLFLAG | RALTFLAG)) return 8; // Win ss 9 -> mac ss 8 - else if (shiftState == (K_SHIFTFLAG | LCTRLFLAG | RALTFLAG)) return 10; // Win ss 25 -> mac ss 10 - else return shiftState; // Win ss x -> mac ss x + if (shiftState == 0) return MAC_BASE; // Win ss 0 -> mac ss 0 + else if (shiftState == K_SHIFTFLAG) return MAC_SHIFT; // Win ss 16 -> mac ss 2 + else if (shiftState == (LCTRLFLAG | RALTFLAG)) return MAC_OPT; // Win ss 9 -> mac ss 8 + else if (shiftState == (K_SHIFTFLAG | LCTRLFLAG | RALTFLAG)) return MAC_SHIFT_OPT; // Win ss 25 -> mac ss 10 + else return shiftState; // Win ss x -> mac ss x } -// _S2 Todo - int mac_map_rgkey_ShiftState_to_Shiftstate(int rgkey_ShiftState) { - if (rgkey_ShiftState == 0 ) return 0; - else if (rgkey_ShiftState == 1) return 2; - else if (rgkey_ShiftState == 6 ) return 8; - else if (rgkey_ShiftState == 7) return 10; +/** @brief map a shiftstate used in rgkey (a vector of VirtualKey*) to a shiftstate suitable for UCKeyTranslate() on the mac */ +int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState) { + if (rgkey_ShiftState == 0) return MAC_BASE; + else if (rgkey_ShiftState == 1) return MAC_SHIFT; + else if (rgkey_ShiftState == 6) return MAC_OPT; + else if (rgkey_ShiftState == 7) return MAC_SHIFT_OPT; else return rgkey_ShiftState; } @@ -38,7 +38,7 @@ bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout* keyboard_lay if (!keyboard_layout) return false; - if ((int)keycode > (int)keycode_max) + if (keycode > keycode_max) return false; if ((shiftstate > max_shiftstate)) @@ -47,6 +47,17 @@ bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout* keyboard_lay if ((caps > 1)) return false; +return true; +} +// _S2 todo missing code +/** @brief check for correct input parameter that will later be used in UCKeyTranslate() */ +bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode) { + if ((shiftstate > max_shiftstate)) + return false; + + if (keycode > keycode_max) + return false; + return true; } @@ -133,8 +144,8 @@ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLay // get key name US stored in [0][i][0] and copy to name in "underlying"-block[1][i][0] all_vector[1][i][0] = all_vector[0][i][0]; - for (int k = 0; k < 2; k++) { - all_vector[1][i][k + 1] = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, all_vector[0][i][0], mac_map_rgkey_ShiftState_to_Shiftstate(k), 0); + for (int k = 0; k < 2; k++) { // use BASE and SHIFT only + all_vector[1][i][k + 1] = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, all_vector[0][i][0], mac_convert_rgkey_Shiftstate_to_MacShiftstate(k), 0); } } @@ -178,19 +189,8 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou OSStatus status; unicodeString[0] = 0; - /*if (!keyboard_layout) - return 0; - - if (!(keycode <= keycode_max)) - return 0; - - if (!(shiftstate_mac <= max_shiftstate)) - return 0; - - if (!(caps <= 1)) - return 0;*/ - - if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) + //if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) + if (!ensureValidInputForKeyboardTranslation(shiftstate_mac, keycode)) return 0; @@ -230,7 +230,8 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la if (!(caps <= 1)) return 0;*/ - if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) + //if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) + if (!ensureValidInputForKeyboardTranslation(shiftstate_mac, keycode)) return 0; // if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); @@ -253,19 +254,11 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa KMX_DWORD keyV; int caps = 0; - /*if (!keyboard_layout) - return 0; - - if (!(is_correct_win_shiftstate(vk_ShiftState))) - return 0; - - if (!(kc_underlying <= keycode_max)) - return 0;*/ - - if (!ensureValidInputForKeyboardTranslation(keyboard_layout, kc_underlying, is_correct_win_shiftstate(vk_ShiftState))) +// _S2 WOW NO! convert?? + //if (!ensureValidInputForKeyboardTranslation(keyboard_layout, kc_underlying, is_correct_win_shiftstate(vk_ShiftState))) + if (!ensureValidInputForKeyboardTranslation(mac_convert_Shiftstate_to_MacShiftstate(vk_ShiftState), kc_underlying)) return 0; - keyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, kc_underlying, (mac_convert_Shiftstate_to_MacShiftstate(vk_ShiftState)), caps, isdk); // if there was a deadkey return 0xFFFF and copy deadkey into dky @@ -313,12 +306,12 @@ KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_ /** @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) { // first get the keyvalue of the key on the US keyboard (kc_us) - std::u16string u16str = std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_map_rgkey_ShiftState_to_Shiftstate(ss_win), caps)); + std::u16string u16str = std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_win), caps)); // then find the same keyvalue on the underlying keyboard and return the keycode of that key on the underlying keyboard - for (int i = 0; i < all_vector[1].size() - 1; i++) { - for (int j = 1; j < all_vector[1][0].size(); j++) { - if (((KMX_DWORD)all_vector[1][i][j] == (KMX_DWORD)*u16str.c_str())) + for (int i = 0; i < (int)all_vector[1].size() - 1; i++) { + for (int j = 1; j < (int)all_vector[1][0].size(); j++) { + if (all_vector[1][i][j] == (KMX_DWORD)*u16str.c_str()) return all_vector[1][i][0]; } } @@ -327,13 +320,13 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* k /** @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard */ UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us) { - // On mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an 'artificial' us virtual key + // on the mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an 'artificial' us virtual key return (mac_USVirtualKeyToScanCode[vk_us]); } /** @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard */ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { - // On mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an keycode from an 'artificial' us virtual key + // on the mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an keycode from an 'artificial' us virtual key return mac_ScanCodeToUSVirtualKey[keycode]; } diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 7ee49ef521e..5e9967b841f 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -61,8 +61,12 @@ static KMX_DWORD keycode_max = 50; static int keycode_spacebar = 49; static KMX_DWORD max_shiftstate = 10; +static int MAC_BASE = 0; +static int MAC_SHIFT = 2; +static int MAC_OPT = 8; +static int MAC_SHIFT_OPT = 10; /** - * @brief map shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on mac + * @brief map a shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on the mac * Windows: (Base: 00000000 (0); Shift 00010000 (16); AltGr 00001001 (9); Shift+AltGr 00011001 (25)) * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10 ) * @param shiftState shiftstate used on windows @@ -71,21 +75,27 @@ static KMX_DWORD max_shiftstate = 10; * if shiftState is NOT a windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate */ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState); -// _S2 TODO -int mac_map_rgkey_ShiftState_to_Shiftstate(int win_ShiftState); +/** + * @brief map a shiftstate used in rgkey ( a vector of VirtualKey*) to a shiftstate suitable for UCKeyTranslate() on the mac + * rgkey: (Base: 0; Shift 1; OPT 6; Shift+OPT 7 ) + * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10) + * @param shiftState shiftstate used in rgkey + * @return a shiftstate usable for UCKeyTranslate() on mac if available + * if shiftState is a windows ShiftState: convert the windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) + * if shiftState is NOT a windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate + */ +int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int win_ShiftState); // _S2 TODO bool is_correct_win_shiftstate(int comp_ss); /** - * @brief check for correct input parameter that will later be used in gdk_keymap_translate_keyboard_state() - * @param keyboard_layout ptr to the the currently used keyboard layout - * @param keycode the code of the key in question + * @brief check for correct input parameter that will later be used in UCKeyTranslate() * @param shiftstate the currently used shiftstate - * @param cap the code of the key in question + * @param keycode the code of the key in question * @return true if all parameters are OK; false if not */ bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate, int cap); - +bool ensureValidInputForKeyboardTranslation(int shiftstate,int keycode); // _S2 TODO /** diff --git a/mac/mcompile/km_types.h b/mac/mcompile/km_types.h old mode 100755 new mode 100644 index 5381ff1e6a4..89a806adce6 --- a/mac/mcompile/km_types.h +++ b/mac/mcompile/km_types.h @@ -11,6 +11,7 @@ #endif */ + #if defined(__LP64__) || defined(_LP64) /* 64-bit, g++ */ #define KMX_64BIT diff --git a/mac/mcompile/kmx_file.h b/mac/mcompile/kmx_file.h old mode 100755 new mode 100644 index d7fa0d51d5f..3901d119e23 --- a/mac/mcompile/kmx_file.h +++ b/mac/mcompile/kmx_file.h @@ -8,7 +8,6 @@ Authors: mcdurdin */ - #define UNREFERENCED_PARAMETER(P) (P) #define TRUNCATE ((size_t)-1) #ifdef KMN_KBP diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp old mode 100755 new mode 100644 index 45948052e6a..ba4ab17478f --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -4,6 +4,7 @@ * Mnemonic layout support for Linux */ + #include #include #include @@ -51,38 +52,38 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { //_S2 remove! bool test_alDead_S2(std::vector ald); -/** // _S2 at merge: better description in other branch: - * @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. - * @param keycode a key of the currently used keyboard Layout - * @param pwszBuff Buffer to store resulting character - * @param ss_win a windows-style shiftstate of the currently used keyboard Layout - * @param caps state of the caps key of the currently used keyboard Layout - * @param keyboard_layout the currently used (underlying)keyboard Layout + + /** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. + * Contrary to what the function name might suggest, the function the mac_KMX_ToUnicodeEx does NOT process surrogate pairs. + * This is because it is used in mcompile only which only deals with latin scripts. + * In case this function is used for surrogate pairs, they will be ignored and a message will be printed out + * @param keycode a key of the currently used keyboard Layout + * @param pwszBuff Buffer to store resulting character + * @param ss_win a windows-style shiftstate of the currently used keyboard Layout + * @param caps state of the caps key of the currently used keyboard Layout + * @param keyboard_layout the currently used (underlying)keyboard Layout * @return -1 if a deadkey was found; 0 if no translation is available; +1 if character was found and written to pwszBuff */ -int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_win, int caps, const UCKeyboardLayout* keyboard_layout) { +int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, ShiftState ss_rgkey, int caps, const UCKeyboardLayout* keyboard_layout) { KMX_DWORD keyval; UInt32 isdk = 0; - /*if (!keyboard_layout) + if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_rgkey), caps)) return 0; - if (!(keycode <= keycode_max)) - return 0; + keyval = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_rgkey), caps, isdk); + std::u16string str =std::u16string(1, keyval ); + KMX_WCHAR firstchar = *(PKMX_WCHAR)str.c_str(); - if (!(ss_win <= max_shiftstate)) + if ((firstchar >= 0xD800) && (firstchar <= 0xDFFF)) { + wprintf(L"Surrogate pair found that is not processed in KMX_ToUnicodeEx\n"); return 0; + } - if (!(caps <= 1)) - return 0;*/ + pwszBuff[0] = firstchar; - if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, ss_win, caps)) + if (u16len(pwszBuff) < 1) return 0; - - keyval = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_map_rgkey_ShiftState_to_Shiftstate(ShiftState(ss_win)), caps, isdk); - std::u16string str =std::u16string(1, keyval ); - pwszBuff[0] = *(PKMX_WCHAR)str.c_str(); - if ((isdk) && (keycode != 0xFFFF)) // deadkeys return -1; if (keyval == 0) // no character @@ -91,7 +92,7 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_win, int caps, return 1; } -int mac_KMX_DeadKeyMap(int index, std::vector*deadkeys, int deadkeyBase, std::vector*deadkeyMappings) { // I4327 // I4353 +KMX_WCHAR mac_KMX_DeadKeyMap(int index, std::vector*deadkeys, int deadkeyBase, std::vector*deadkeyMappings) { // I4327 // I4353 for (size_t i = 0; i < deadkeyMappings->size(); i++) { if ((*deadkeyMappings)[i].deadkey == index) { return (*deadkeyMappings)[i].dkid; @@ -100,7 +101,7 @@ int mac_KMX_DeadKeyMap(int index, std::vector*deadkeys, int deadkeyBas for (size_t i = 0; i < deadkeys->size(); i++) { if ((*deadkeys)[i]->KMX_DeadCharacter() == index) { - return deadkeyBase + i; + return (KMX_WCHAR)deadkeyBase + i; } } return 0xFFFF; @@ -247,7 +248,7 @@ class mac_KMX_VirtualKey { (this->mac_KMX_IsAltGrCapsEqualToAltGrShift() ? 4 : 0) | (this->mac_KMX_IsXxxxGrCapsEqualToXxxxShift() ? 8 : 0);*/ - int capslock = 1; // we do not use the equation to obtain capslock. On Mac we set capslock=1 + int capslock = 1; // we do not use the equation to obtain capslock. on the mac we set capslock=1 for (int ss = 0; ss <= MaxShiftState; ss++) { if (ss == Menu || ss == ShftMenu) { @@ -356,10 +357,10 @@ class mac_KMX_Loader { bool fCapsLock, // Was the caps lock key pressed? const UCKeyboardLayout* keyboard_layout) { // The keyboard layout - int maxshiftstate = 2; + int maxshiftstate = 2; //_S2 MAC_SHIFT?? DeadKey* deadKey = new DeadKey(rgKey[iKeyDead]->mac_KMX_GetShiftState(shiftStateDead, fCapsLock)[0]); - int ss_dead = mac_map_rgkey_ShiftState_to_Shiftstate(shiftStateDead); + int ss_dead = mac_convert_rgkey_Shiftstate_to_MacShiftstate(shiftStateDead); KMX_DWORD keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead], ss_dead, 0); for (int i = 0; i < keycode_spacebar + 1; i++) { @@ -478,9 +479,9 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK } //_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! - /*if (ss == MenuCtrl || ss == ShftMenuCtrl) { + if (ss == MenuCtrl || ss == ShftMenuCtrl) { continue; - }*/ + } KMX_DWORD KC_US = (KMX_DWORD)mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); @@ -489,17 +490,17 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK if (rc > 0) { if (*sbBuffer == 0) { - rgKey[iKey]->mac_KMX_SetShiftState(ss, u"", false, (caps)); // different to windows since behavior on mac is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, u"", false, (caps)); // different to windows since behavior on the mac is different } else { if ((ss == Ctrl || ss == ShftCtrl)) { continue; } sbBuffer[rc] = 0; - rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to windows since behavior on mac is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to windows since behavior on the mac is different } } else if (rc < 0) { sbBuffer[2] = 0; - rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on mac is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on the mac is different sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps == 0)); @@ -548,13 +549,6 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK kp->dpGroupArray = gp; for (UINT i = 0; i < kp->cxGroupArray; i++, gp++) { - //if (gp->fUsingKeys && gp->dpNoMatch == NULL) { // I4550 - // WCHAR *p = gp->dpNoMatch = new WCHAR[4]; - // *p++ = UC_SENTINEL; - // *p++ = CODE_USE; - // *p++ = (WCHAR)(kp->cxGroupArray + 1); - // *p = 0; - //} LPKMX_KEY kkp = gp->dpKeyArray; for (UINT j = 0; j < gp->cxKeyArray; j++, kkp++) { @@ -713,35 +707,6 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK } return true; } - -const int CODE__SIZE[] = { - -1, // undefined 0x00 - 1, // CODE_ANY 0x01 - 2, // CODE_INDEX 0x02 - 0, // CODE_CONTEXT 0x03 - 0, // CODE_NUL 0x04 - 1, // CODE_USE 0x05 - 0, // CODE_RETURN 0x06 - 0, // CODE_BEEP 0x07 - 1, // CODE_DEADKEY 0x08 - -1, // unused 0x09 - 2, // CODE_EXTENDED 0x0A - -1, // CODE_EXTENDEDEND 0x0B (unused) - 1, // CODE_SWITCH 0x0C - -1, // CODE_KEY 0x0D (never used) - 0, // CODE_CLEARCONTEXT 0x0E - 1, // CODE_CALL 0x0F - -1, // UC_SENTINEL_EXTENDEDEND 0x10 (not valid with UC_SENTINEL) - 1, // CODE_CONTEXTEX 0x11 - 1, // CODE_NOTANY 0x12 - 2, // CODE_SETOPT 0x13 - 3, // CODE_IFOPT 0x14 - 1, // CODE_SAVEOPT 0x15 - 1, // CODE_RESETOPT 0x16 - 3, // CODE_IFSYSTEMSTORE 0x17 - 2 // CODE_SETSYSTEMSTORE 0x18 -}; - // _S2 need to go void print_entries_S2(int i, std::vector rgKey , std::string comp1,std::string comp2,std::string erg) { std::string b0 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 0 )); diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h old mode 100755 new mode 100644 index d8f0c70b8b4..3cb44268272 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -3,6 +3,7 @@ #ifndef MC_IMPORT_RULES_H #define MC_IMPORT_RULES_H + int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps, const UCKeyboardLayout* keyboard_layout); /** @brief Base class for Deadkey*/ diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp old mode 100755 new mode 100644 index 0cfef9ef6a6..e5f281c02da --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -7,6 +7,35 @@ #define CERR_UnableToWriteFully 0x00008007 #define CERR_SomewhereIGotItWrong 0x00008009 + +const int CODE__SIZE[] = { + -1, // undefined 0x00 + 1, // CODE_ANY 0x01 + 2, // CODE_INDEX 0x02 + 0, // CODE_CONTEXT 0x03 + 0, // CODE_NUL 0x04 + 1, // CODE_USE 0x05 + 0, // CODE_RETURN 0x06 + 0, // CODE_BEEP 0x07 + 1, // CODE_DEADKEY 0x08 + -1, // unused 0x09 + 2, // CODE_EXTENDED 0x0A + -1, // CODE_EXTENDEDEND 0x0B (unused) + 1, // CODE_SWITCH 0x0C + -1, // CODE_KEY 0x0D (never used) + 0, // CODE_CLEARCONTEXT 0x0E + 1, // CODE_CALL 0x0F + -1, // UC_SENTINEL_EXTENDEDEND 0x10 (not valid with UC_SENTINEL) + 1, // CODE_CONTEXTEX 0x11 + 1, // CODE_NOTANY 0x12 + 2, // CODE_SETOPT 0x13 + 3, // CODE_IFOPT 0x14 + 1, // CODE_SAVEOPT 0x15 + 1, // CODE_RESETOPT 0x16 + 3, // CODE_IFSYSTEMSTORE 0x17 + 2 // CODE_SETSYSTEMSTORE 0x18 +}; + KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug) { LPKMX_GROUP fgp; @@ -163,15 +192,14 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX return CERR_None; } - -KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz); +KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size); LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize); -KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename) { +KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR fileName) { FILE *fp; - fp = Open_File(filename, u"wb"); + fp = Open_File(fileName, u"wb"); if(fp == NULL) { @@ -185,7 +213,7 @@ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename) { if(err != CERR_None) { mac_KMX_LogError(L"Failed to write compiled keyboard with error %d", err); - std::u16string u16_filname(filename); + std::u16string u16_filname(fileName); std::string s = string_from_u16string(u16_filname); remove(s.c_str()); @@ -194,6 +222,30 @@ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR filename) { return TRUE; } +KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName) { + + FILE *fp; + fp = Open_File(fileName, "wb"); + + if(fp == NULL) + { + mac_KMX_LogError(L"Failed to create output file (%d)", errno); + return FALSE; + } + + KMX_DWORD err = KMX_WriteCompiledKeyboardToFile(kbd, fp, FALSE); + fclose(fp); + + if(err != CERR_None) { + mac_KMX_LogError(L"Failed to write compiled keyboard with error %d", err); + std::string s(fileName); + remove(s.c_str()); + return FALSE; + } + + return TRUE; +} + PKMX_WCHAR KMX_StringOffset(PKMX_BYTE base, KMX_DWORD offset) { if(offset == 0) return NULL; return (PKMX_WCHAR)(base + offset); @@ -352,8 +404,113 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { return FALSE; } - auto sz = ftell(fp); - if (sz <= 0) { + auto file_size = ftell(fp); + if (file_size <= 0) { + fclose(fp); + return FALSE; + } + + if (fseek(fp, 0, SEEK_SET) != 0) { + fclose(fp); + mac_KMX_LogError(L"Could not fseek(set) file\n" ); + return FALSE; + } + + #ifdef KMX_64BIT + // allocate enough memory for expanded data structure + original data. + // Expanded data structure is double the size of data on disk (8-byte + // pointers) - on disk the "pointers" are relative to the beginning of + // the file. + // We save the original data at the end of buf; we don't copy strings, so + // those will remain in the location at the end of the buffer. + buf = new KMX_BYTE[file_size * 3]; + #else + buf = new KMX_BYTE[file_size]; + #endif + + if (!buf) { + delete[] buf; + fclose(fp); + mac_KMX_LogError(L"Not allocmem\n" ); + return FALSE; + } + + #ifdef KMX_64BIT + filebase = buf + file_size*2; + #else + filebase = buf; + #endif + + if (fread(filebase, 1, file_size, fp) < (size_t)file_size) { + mac_KMX_LogError(L"Could not read file\n" ); + delete[] buf; + fclose(fp); + return FALSE; + } +// delete??? + fclose(fp); + + if (*((PKMX_DWORD)filebase) != (KMX_DWORD)FILEID_COMPILED) + { + delete [] buf; + mac_KMX_LogError(L"Invalid file - signature is invalid\n"); + return FALSE; + } + + if (!KMX_VerifyKeyboard(filebase, file_size)) { + mac_KMX_LogError(L"errVerifyKeyboard\n" ); + delete[] buf; + return FALSE; + } + +#ifdef KMX_64BIT + kbp = KMX_CopyKeyboard(buf, filebase); +#else + kbp = KMX_FixupKeyboard(buf, filebase, file_size); +#endif + + + if (!kbp) { + mac_KMX_LogError(L"errFixupKeyboard\n" ); + delete[] buf; + return FALSE; + } + + if (kbp->dwIdentifier != FILEID_COMPILED) { + delete[] buf; + mac_KMX_LogError(L"errNotFileID\n" ); + return FALSE; + } + *lpKeyboard = kbp; + return TRUE; +} +KMX_BOOL KMX_LoadKeyboard(char* fileName, LPKMX_KEYBOARD* lpKeyboard) { + *lpKeyboard = NULL; + PKMX_BYTE buf; + FILE* fp; + LPKMX_KEYBOARD kbp; + PKMX_BYTE filebase; + + if(!fileName || !lpKeyboard) { + mac_KMX_LogError(L"Bad Filename\n" ); + return FALSE; + } + + fp = Open_File((const KMX_CHAR*)fileName, "rb"); + + if(fp == NULL) { + mac_KMX_LogError(L"Could not open file\n" ); + return FALSE; + } + + if (fseek(fp, 0, SEEK_END) != 0) { + fclose(fp); + mac_KMX_LogError(L"Could not fseek file\n" ); + return FALSE; + } + + auto file_size = ftell(fp); + if (file_size <= 0) { fclose(fp); return FALSE; } @@ -371,9 +528,9 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { // the file. // We save the original data at the end of buf; we don't copy strings, so // those will remain in the location at the end of the buffer. - buf = new KMX_BYTE[sz * 3]; + buf = new KMX_BYTE[file_size * 3]; #else - buf = new KMX_BYTE[sz]; + buf = new KMX_BYTE[file_size]; #endif if (!buf) { @@ -384,12 +541,12 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { } #ifdef KMX_64BIT - filebase = buf + sz*2; + filebase = buf + file_size*2; #else filebase = buf; #endif - if (fread(filebase, 1, sz, fp) < (size_t)sz) { + if (fread(filebase, 1, file_size, fp) < (size_t)file_size) { mac_KMX_LogError(L"Could not read file\n" ); delete[] buf; fclose(fp); @@ -405,7 +562,7 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { return FALSE; } - if (!KMX_VerifyKeyboard(filebase, sz)) { + if (!KMX_VerifyKeyboard(filebase, file_size)) { mac_KMX_LogError(L"errVerifyKeyboard\n" ); delete[] buf; return FALSE; @@ -414,7 +571,7 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { #ifdef KMX_64BIT kbp = KMX_CopyKeyboard(buf, filebase); #else - kbp = KMX_FixupKeyboard(buf, filebase, sz); + kbp = KMX_FixupKeyboard(buf, filebase, file_size); #endif @@ -433,7 +590,7 @@ KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { return TRUE; } -KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz){ +KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size){ KMX_DWORD i; PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)filebase; diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h old mode 100755 new mode 100644 index b932f4d1371..3bac3ada917 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -4,7 +4,6 @@ #include "km_types.h" #include "kmx_file.h" - #include "mcompile.h" #ifndef _KMXFILE_H @@ -71,20 +70,21 @@ typedef struct KMX_tagKEYBOARD { /** * @brief load a keyboard kmx-file - * @param fileName ptr to filename of kmx-file + * @param fileName ptr to fileName of kmx-file * @param [in,out] lpKeyboard ptr to ptr to keyboard * @return TRUE on success; else FALSE */ KMX_BOOL KMX_LoadKeyboard(KMX_WCHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) ; +KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) ; /** * @brief save keyboard to file * @param kbd ptr to the keyboard - * @param filename ptr to filename of a kmx-file + * @param fileName ptr to fileName of a kmx-file * @return TRUE on success; else FALSE */ -KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR* filename); - +KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR* fileName); +KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName); /** * @brief increment in a string * @param p ptr to a character diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index db374177d79..308d04efcf1 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -19,7 +19,7 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* OutputPairs); // returns array of [usvk, ch_out] pairs -int mac_run(int argc, std::vector str_argv, char* argv[]); +int mac_run(int argc, char* argv[]); /** * @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard @@ -35,11 +35,6 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D &all_vector, const UCKe std::vector KMX_FDeadkeys; // I4353 -// Note: max is not a standard c api function or macro -#ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif - // _S2 run and getdeadkeys to here #define _countof(a) (sizeof(a) / sizeof(*(a))) @@ -51,52 +46,45 @@ std::vector KMX_FDeadkeys; // I4353 */ #if defined(_WIN32) || defined(_WIN64) int wmain(int argc, wchar_t* argv[]) { - std::vector str_argv_16 = convert_argvW_to_Vector_u16str(argc, argv); - run(argc, str_argv_16); #elif ((__linux__) || (__unix__)) // LINUX, UNIX int main(int argc, char* argv[]) { - std::vector str_argv_16 = convert_argv_to_Vector_u16str(argc, argv); - run(argc, str_argv_16, argv); #elif (__APPLE__ && TARGET_OS_MAC) #include - int main(int argc, char* argv[]) { - std::vector str_argv_16 = convert_argv_to_Vector_u16str(argc, argv); +#endif - mac_run(argc, str_argv_16, argv); + mac_run(argc, argv); printf("\n................................ END .............................. _S2 \n"); -#endif } /** @brief start of mcompile; load, convert and save keyboard */ -int mac_run(int argc, std::vector str_argv, char* argv_ch[] = NULL) { - std::vector argv; - for (int i = 0; i < argc; i++) { - const char16_t* cmdl_par = str_argv[i].c_str(); - argv.push_back(cmdl_par); - } +int mac_run(int argc, char* argv[] ) { - if (argc < 3 || (argc > 4)) { // I4273// I4273 - printf( - "Usage: mcompile [-d] infile.kmx outfile.kmx\n" - " mmcompile -u ... (not available for mac)\n " - " mcompile converts a Keyman mnemonic layout to a\n" - " positional one based on the mac keyboard\n" - " layout on top position\n" - " (-d convert deadkeys to plain keys) not available yet \n\n"); // I4552 + int bDeadkeyConversion = 0; - return 1; - } - // -u option is not available for Linux and macOS + if (argc > 1) + bDeadkeyConversion = (strcmp(argv[1], "-d") == 0); // I4552 - int bDeadkeyConversion = u16cmp(argv[1], u"-d") == 0; // I4552 int n = (bDeadkeyConversion ? 2 : 1); - char16_t *infile = (char16_t*)argv[n], *outfile = (char16_t*)argv[n + 1]; + if (argc < 3 || argc > 4 || (argc - n) != 2) { // I4273// I4273 + printf( + "Usage: \tmcompile [-d] infile.kmx outfile.kmx\n" + " \tmcompile -u ... (not available for mac)\n " + " \tmcompile converts a Keyman mnemonic layout to\n" + " \ta positional one based on the currently used \n" + " \tmac keyboard layout\n" + " \t(-d convert deadkeys to plain keys) \n \n"); // I4552 + } + // -u option is not available for Linux and macOS + + KMX_CHAR* infile = argv[n]; + KMX_CHAR* outfile = argv[n + 1]; + printf("mcompile%s \"%s\" \"%s\"\n", bDeadkeyConversion ? " -d" : "", infile, outfile); // I4174 // _S2 TODO open again!! //wprintf(L"mcompile%ls \"%ls\" \"%ls\"\n", bDeadkeyConversion ? L" -d" : L"", u16fmt((const char16_t*) infile).c_str(), u16fmt((const char16_t*) outfile).c_str() ); // I4174 @@ -381,7 +369,7 @@ KMX_WCHAR mac_KMX_ScanXStringForMaxDeadkeyID(PKMX_WCHAR str) { KMX_WCHAR dkid = 0; while(str && *str) { if(*str == UC_SENTINEL && *(str+1) == CODE_DEADKEY) { - dkid = max(dkid, *(str+2)); + dkid = std::max(dkid, *(str+2)); } str = KMX_incxstr(str); } @@ -432,15 +420,15 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { for (i = 0, gp = kbd->dpGroupArray; i < kbd->cxGroupArray; i++, gp++) { for (j = 0, kp = gp->dpKeyArray; j < gp->cxKeyArray; j++, kp++) { - dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(kp->dpContext)); - dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(kp->dpOutput)); + dkid = std::max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(kp->dpContext)); + dkid = std::max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(kp->dpOutput)); } - dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(gp->dpMatch)); - dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(gp->dpNoMatch)); + dkid = std::max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(gp->dpMatch)); + dkid = std::max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(gp->dpNoMatch)); } for (i = 0, sp = kbd->dpStoreArray; i < kbd->cxStoreArray; i++, sp++) { - dkid = max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(sp->dpString)); + dkid = std::max(dkid, mac_KMX_ScanXStringForMaxDeadkeyID(sp->dpString)); } s_dkids = (KMX_dkidmap*)realloc(s_dkids, sizeof(KMX_dkidmap) * (s_ndkids + 1)); @@ -769,7 +757,7 @@ continue; for ( int caps=0; caps< 2;caps++) { for ( int key=0; key< 50;key++) { - int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, mac_map_rgkey_ShiftState_to_Shiftstate(ss), caps); + int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss), caps); if ((ss_rgkey!= 999 )&& ( keyval== keyvalsearch)) printf( " found keyval: key: %i, ss_mac:%i ( ss_rgkey:%i), caps:%i -> character: %i (%c) \n", key, ss, ss_rgkey, caps, keyvalsearch,keyvalsearch); } diff --git a/mac/mcompile/u16.cpp b/mac/mcompile/u16.cpp old mode 100755 new mode 100644 index 32fd6fa4812..1c931097cac --- a/mac/mcompile/u16.cpp +++ b/mac/mcompile/u16.cpp @@ -3,6 +3,7 @@ #include #include + std::vector convert_argv_to_Vector_u16str(int argc, char* argv[]) { std::vector vector_u16; diff --git a/mac/mcompile/u16.h b/mac/mcompile/u16.h old mode 100755 new mode 100644 index 0e61ade4e2b..644974fb064 --- a/mac/mcompile/u16.h +++ b/mac/mcompile/u16.h @@ -8,6 +8,7 @@ #include #include + std::vector convert_argvW_to_Vector_u16str(int argc, wchar_t* argv[]); std::vector convert_argv_to_Vector_u16str(int argc, char* argv[]); From 927154cebb0061bd659782176238bf65fc2ffb8a Mon Sep 17 00:00:00 2001 From: Sabine Date: Thu, 11 Jul 2024 14:29:34 +0200 Subject: [PATCH 37/71] # This is a combination of 8 commits. # This is the 1st commit message: feat(mac): remove unused func # This is the commit message #2: feat(mac): edit, remove unused code # This is the commit message #3: feat(mac): more edit # This is the commit message #4: feat(mac): comments keymap # This is the commit message #5: feat(mac): comments importRules # This is the commit message #6: feat(mac): comments # This is the commit message #7: feat(mac): more comments # This is the commit message #8: feat(mac): adapt data types return para --- mac/mcompile/keymap.cpp | 165 +++++------- mac/mcompile/keymap.h | 147 ++++++----- mac/mcompile/mc_import_rules.cpp | 107 ++++---- mac/mcompile/mc_import_rules.h | 55 ++-- mac/mcompile/mc_kmxfile.cpp | 416 +++++++++++-------------------- mac/mcompile/mc_kmxfile.h | 18 +- mac/mcompile/mcompile.cpp | 143 +++++------ mac/mcompile/mcompile.h | 4 +- mac/mcompile/u16.cpp | 30 ++- mac/mcompile/u16.h | 6 +- 10 files changed, 474 insertions(+), 617 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index b9f95f06561..c439211eafe 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -1,13 +1,19 @@ /* * Keyman is copyright (C) SIL International. MIT License. * - * Keyboard reading and mapping for mac + * Mnemonic layout support for mac + * + * Throughout mcompile we use the following naming conventions: + * KEYCODE: The physical position of a key on a keyboard e.g. Keycode for 'Z' on US: 6 on Mac | 52 on Linux/x11 | 44 on Windows + * SCANCODE (naming on windows): The physical position of a key on a keyboard e.g. Keycode for 'Z' on US: 44 on Windows + * VIRTUAL KEY: The value of a character on a key e.g. 'A' = 65; 'a' = 97 - not neccessarily the same as ACSII- exists on a Windows keyboard only + * KEYVAL(UE): The value of a character on a key e.g. 'A' = 65; 'a' = 97 - not neccessarily the same as ACSII */ #include "keymap.h" #include "kmx_file.h" - /** @brief map a shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on the mac */ +/** @brief map a shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on the mac */ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) { if (shiftState == 0) return MAC_BASE; // Win ss 0 -> mac ss 0 else if (shiftState == K_SHIFTFLAG) return MAC_SHIFT; // Win ss 16 -> mac ss 2 @@ -16,39 +22,15 @@ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) { else return shiftState; // Win ss x -> mac ss x } - /** @brief map a shiftstate used in rgkey (a vector of VirtualKey*) to a shiftstate suitable for UCKeyTranslate() on the mac */ int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState) { - if (rgkey_ShiftState == 0) return MAC_BASE; - else if (rgkey_ShiftState == 1) return MAC_SHIFT; - else if (rgkey_ShiftState == 6) return MAC_OPT; - else if (rgkey_ShiftState == 7) return MAC_SHIFT_OPT; + if (rgkey_ShiftState == 0) return MAC_BASE; + else if (rgkey_ShiftState == 1) return MAC_SHIFT; + else if (rgkey_ShiftState == 6) return MAC_OPT; + else if (rgkey_ShiftState == 7) return MAC_SHIFT_OPT; else return rgkey_ShiftState; } - -// _S2 Todo -bool is_correct_win_shiftstate(int win_ss) { - return ((win_ss == 0) || (win_ss == 16) || (win_ss == 9) || (win_ss == 25) || (win_ss == 0xFFFF)); -} - -// _S2 todo missing code -/** @brief check for correct input parameter that will later be used in UCKeyTranslate() */ -bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate, int caps = 0) { - if (!keyboard_layout) - return false; - - if (keycode > keycode_max) - return false; - - if ((shiftstate > max_shiftstate)) - return false; - - if ((caps > 1)) - return false; - -return true; -} // _S2 todo missing code /** @brief check for correct input parameter that will later be used in UCKeyTranslate() */ bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode) { @@ -61,11 +43,11 @@ bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode) { return true; } - /** @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard */ +/** @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard */ int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { // store contents of the English (US) keyboard in all_vector if (mac_write_US_ToVector(all_vector)) { - printf("ERROR: can't write US to Vector \n"); + printf("ERROR: can't write full US to Vector \n"); return 1; } @@ -77,9 +59,8 @@ int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeybo return 0; } - /** @brief write data of the US keyboard into a 3D-Vector */ +/** @brief write data of the US keyboard into a 3D-Vector */ int mac_write_US_ToVector(vec_dword_3D& vec_us) { -//_S2 TODO // Values for US : A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P,CR, L, J, ', K, ;, \, ,, /, N, M, . std::vector us_Base = {97,115,100,102,104,103,122,120,99,118,167,98,113,119,101,114,121,116,49,50,51,52,54,53,61,57,55,45,56,48, 93,111,117, 91,105,112,13,108,106,39,107,59, 92,44,47,110,109,46}; std::vector us_Shift = {65, 83, 68, 70, 72, 71, 90, 88,67, 86,177,66, 81, 87, 69, 82, 89, 84,33,64,35,36,94,37,43,40,38,95,42,41,125, 79, 85,123, 73, 80,13, 76, 74,34, 75,58,124,60,63, 78, 77,62}; @@ -99,11 +80,14 @@ int mac_write_US_ToVector(vec_dword_3D& vec_us) { if (key.size() == 0) { printf("ERROR: can't Create Vector for US keyboard\n"); return 1; + } else if (key.size() < 48) { + printf("ERROR: keyboard not created completely\n"); + return 1; } else return 0; } -/** @brief create an 2D-Vector with all fields containing INVALID_NAME */ +/** @brief create an 2D-Vector with all fields initialized to INVALID_NAME */ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss) { vec_dword_1D shifts; vec_dword_2D vector_2D; @@ -118,9 +102,8 @@ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss) { return vector_2D; } - /** @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector */ +/** @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector */ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { - int caps = 0; if (all_vector.size() != 1) { printf("ERROR: data for US keyboard not correct\n"); return 1; @@ -170,16 +153,7 @@ bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout) { return 0; } - /** old - * @brief return the keyvalue for a given Keycode, shiftstate and caps of the currently used (underlying) keyboard Layout - * What character will be produced for a keypress of a key and modifiers? - * @param keyboard_layout the currently used (underlying)keyboard Layout - * @param keycode a key of the currently used keyboard Layout - * @param shiftstate_mac a shiftstate of the currently used keyboard Layout - * @param caps state of the caps key of the currently used keyboard Layout - * @return the keyval obtained from Keycode, shiftstate and caps - */ - /** @brief return the keyvalue for a given Keycode, shiftstate and caps */ +/** @brief return the keyvalue for a given Keycode, shiftstate and caps */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps) { UInt32 deadkeystate; UniCharCount maxStringlength = 5; @@ -189,13 +163,16 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou OSStatus status; unicodeString[0] = 0; - //if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) if (!ensureValidInputForKeyboardTranslation(shiftstate_mac, keycode)) return 0; + /* + UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^' + if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 + */ status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - // If this was a deadkey,append a space + // If this was a deadkey (deadkeystate != 0), append a space if (deadkeystate != 0) status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); @@ -209,7 +186,7 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou return 0; } - //_S2 ToDO +/** @brief return the keyvalue for a given Keycode, shiftstate and caps */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32& deadkeystate) { UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; @@ -218,22 +195,14 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la unicodeString[0] = 0; OSStatus status; - /*if (!keyboard_layout) - return 0; - - if (!(keycode <= keycode_max)) - return 0; - - if (!(shiftstate_mac <= max_shiftstate)) - return 0; - - if (!(caps <= 1)) - return 0;*/ - - //if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps)) if (!ensureValidInputForKeyboardTranslation(shiftstate_mac, keycode)) return 0; - // if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 + + /* + UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^' + if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 + */ + status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); // If this was a deadkey,append a space @@ -247,21 +216,19 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la return unicodeString[0]; // combined char e.g. â } -/** @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout and copy deadkey into deadKey */ +/** @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. */ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey) { PKMX_WCHAR dky = NULL; UInt32 isdk = 0; KMX_DWORD keyV; int caps = 0; -// _S2 WOW NO! convert?? - //if (!ensureValidInputForKeyboardTranslation(keyboard_layout, kc_underlying, is_correct_win_shiftstate(vk_ShiftState))) if (!ensureValidInputForKeyboardTranslation(mac_convert_Shiftstate_to_MacShiftstate(vk_ShiftState), kc_underlying)) return 0; keyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, kc_underlying, (mac_convert_Shiftstate_to_MacShiftstate(vk_ShiftState)), caps, isdk); - // if there was a deadkey return 0xFFFF and copy deadkey into dky + // if there was a deadkey return 0xFFFF and copy deadkey into dky; else return the keyvalue if (isdk != 0) { dky = (PKMX_WCHAR)(std::u16string(1, keyV)).c_str(); *deadKey = *dky; @@ -272,7 +239,7 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa } /** @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard */ -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us) { +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us) { // look for kv_us for any shiftstate of US keyboard for (int i = 0; i < (int)all_vector[0].size() - 1; i++) { for (int j = 1; j < (int)all_vector[0][0].size(); j++) { @@ -283,16 +250,8 @@ KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, K return kv_us; } -// _S2 ToDo -/** old - * - * @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard - * On what key of the underlying keyboard do we find a certain character? - * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param kv_underlying a keyvalue on the currently used (underlying) keyboard - * @return keycode of the underlying keyboardif foundf; else the keyval of the underlying keyboard - */ -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying) { +/** @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard */ +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying) { // look for kv_us for any shiftstate of US keyboard for (int i = 0; i < all_vector[1].size() - 1; i++) { for (int j = 1; j < all_vector[1][0].size(); j++) { @@ -303,47 +262,38 @@ KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_ } return kv_underlying; } - /** @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard */ + +/** @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) { // first get the keyvalue of the key on the US keyboard (kc_us) std::u16string u16str = std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_win), caps)); - + KMX_DWORD kv = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_win), caps); + //_S2 // then find the same keyvalue on the underlying keyboard and return the keycode of that key on the underlying keyboard for (int i = 0; i < (int)all_vector[1].size() - 1; i++) { for (int j = 1; j < (int)all_vector[1][0].size(); j++) { - if (all_vector[1][i][j] == (KMX_DWORD)*u16str.c_str()) + //if (all_vector[1][i][j] == (KMX_DWORD)*u16str.c_str()) + if (all_vector[1][i][j] == kv) return all_vector[1][i][0]; } } return kc_us; } - + /** @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard */ -UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us) { +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us) { // on the mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an 'artificial' us virtual key return (mac_USVirtualKeyToScanCode[vk_us]); } - /** @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard */ +/** @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard */ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { // on the mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an keycode from an 'artificial' us virtual key return mac_ScanCodeToUSVirtualKey[keycode]; } -//_S2 TODO - /** old - * - * @brief return the keyvalue of a combination of deadkey + character if there is a combination available - * What character will be produced for a deadkey + a character? - * @param vk_dk a keycode of a deadkey on the currently used (underlying) keyboard - * @param ss a shiftstate of a deadkey on the currently used (underlying) keyboard - * @param keyboard_layout the currently used (underlying)keyboard Layout - * @param vk_us a keycode of a character key on the currently used (underlying) keyboard - * @param shiftstate_mac a shiftstate of a character key on the currently used (underlying) keyboard - * @param caps state of the caps key of a character key on the currently used (underlying) keyboard - * @return the combination of deadkey + character if it is available; if not return 0 - */ -KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps) { +/** @brief return the keyvalue of a combination of deadkey + character if there is a combination available */ +KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, int vk_dk, KMX_DWORD ss_dk, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps) { UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; @@ -352,11 +302,16 @@ KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeybo unicodeString[0] = 0; OSStatus status; + /* + UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a base character (vk_us) to get the combined dk e.g.'Â' + if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 + */ + status = UCKeyTranslate(keyboard_layout, vk_dk, kUCKeyActionDown, ss_dk, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - // If this was a deadkey,append a character + // If this was a deadkey, append a character if (deadkeystate != 0) { - status = UCKeyTranslate(keyboard_layout,(UInt16) vk_us, kUCKeyActionDown, shiftstate_mac+4*caps, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); + status = UCKeyTranslate(keyboard_layout, vk_us, kUCKeyActionDown, shiftstate_mac + 4 * caps, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); if (unicodeString[0] == 1) // impossible character return 0; @@ -381,11 +336,3 @@ void test_printoutKeyboards_S2(vec_dword_3D& all_vector) { } } -/*bool is_correct_mac_shiftstate(int win_ss) { - return ( (win_ss ==0) || (win_ss ==2) || (win_ss ==8) || (win_ss ==10) ); -}*/ - -/*bool is_correct_rgkey_shiftstate(int win_ss) { - return ( (win_ss ==0) || (win_ss ==1) || (win_ss ==6) || (win_ss ==7) ); -}*/ - diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 5e9967b841f..a53f50b59a8 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -49,7 +49,8 @@ const KMX_DWORD KMX_VKMap[] = { VK_xDF, /* ß (?) 223*/ VK_OEM_102, /* < > | 226 */ - 0}; + + 0}; typedef std::vector vec_string_1D; typedef std::vector vec_dword_1D; @@ -65,41 +66,39 @@ static int MAC_BASE = 0; static int MAC_SHIFT = 2; static int MAC_OPT = 8; static int MAC_SHIFT_OPT = 10; + /** * @brief map a shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on the mac * Windows: (Base: 00000000 (0); Shift 00010000 (16); AltGr 00001001 (9); Shift+AltGr 00011001 (25)) - * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10 ) + * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10 ) * @param shiftState shiftstate used on windows * @return a shiftstate usable for UCKeyTranslate() on mac if available * if shiftState is a windows ShiftState: convert the windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) * if shiftState is NOT a windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate */ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState); + /** - * @brief map a shiftstate used in rgkey ( a vector of VirtualKey*) to a shiftstate suitable for UCKeyTranslate() on the mac + * @brief map a shiftstate used in rgkey (a vector of VirtualKey*) to a shiftstate suitable for UCKeyTranslate() on the mac * rgkey: (Base: 0; Shift 1; OPT 6; Shift+OPT 7 ) * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10) - * @param shiftState shiftstate used in rgkey + * @param rgkey_ShiftState shiftstate used in rgkey * @return a shiftstate usable for UCKeyTranslate() on mac if available * if shiftState is a windows ShiftState: convert the windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) * if shiftState is NOT a windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate */ -int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int win_ShiftState); -// _S2 TODO -bool is_correct_win_shiftstate(int comp_ss); +int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState); /** - * @brief check for correct input parameter that will later be used in UCKeyTranslate() + * @brief check for correct input parameters that will later be used in UCKeyTranslate() * @param shiftstate the currently used shiftstate * @param keycode the code of the key in question * @return true if all parameters are OK; false if not */ -bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate, int cap); -bool ensureValidInputForKeyboardTranslation(int shiftstate,int keycode); -// _S2 TODO +bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode); /** - * @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard : + * @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard * all_vector [ US_Keyboard ] * [KeyCode_US ] * [Keyval unshifted ] @@ -109,42 +108,48 @@ bool ensureValidInputForKeyboardTranslation(int shiftstate,int keycode); * [Keyval unshifted ] * [Keyval shifted ] * @param[in,out] all_vector Vector that holds the data of the US keyboard as well as the currently used (underlying) keyboard - * @param keyboard_layout ptr to currently used (underlying) keyboard layout + * @param keyboard_layout pointer to currently used (underlying) keyboard layout * @return 0 on success; 1 if data of US keyboard was not written; 2 if data of underlying keyboard was not written */ -int mac_createOneVectorFromBothKeyboards(vec_dword_3D &all_vector, const UCKeyboardLayout * keyboard_layout); +int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout); + /** * @brief write data of the US keyboard into a 3D-Vector which later will contain * data of the US keyboard and the currently used (underlying) keyboard - * @param[in,out] vec Vector that holds the data of the US keyboard + * @param[in,out] vec_us Vector that holds the data of the US keyboard * @return 0 on success; 1 if data of US keyboard was not written; */ -int mac_write_US_ToVector(vec_dword_3D &vec); +int mac_write_US_ToVector(vec_dword_3D& vec_us); + /** - * @brief create an 2D-Vector with all fields containing INVALID_NAME + * @brief create an 2D-Vector with all fields initialized to INVALID_NAME * @param dim_rows number of rows in vector * @param dim_ss number of columns in vector * @return the 2D-Vector */ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss); - /** - * @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector +/** + * @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector all_vector * @param[in,out] all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param keyboard_layout ptr to currently used (underlying) keybord layout + * @param keyboard_layout pointer to currently used (underlying) keybord layout * @return 0 on success; * 1 if the initialization of the underlying vector failes; * 2 if data of less than 2 keyboards is contained in all_vector; */ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout); + /** * @brief create a pointer to pointer of the current keyboard_layout for later use - * @param keyboard_layout ptr to ptr to currently used (underlying) keyborad layout + * @param keyboard_layout pointer to pointer to currently used (underlying) keyborad layout * @return 0 on success; 1 if the display is not found; 2 if the keymap is not found */ bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout); -// we use the same type of array as throughout Keyman even though we have lots of unused fields +/** + * @brief array of USVirtualKey-ScanCode-pairs + * we use the same type of array as throughout Keyman even though we have lots of unused fields + */ const UINT mac_USVirtualKeyToScanCode[256] = { 0xFFFF, // not used 0xFFFF, // not used @@ -404,8 +409,10 @@ const UINT mac_USVirtualKeyToScanCode[256] = { 0xFFFF, // not used }; - -// we use the same type of array as throughout Keyman even though we have lots of unused fields +/** + * @brief array of ScanCode-USVirtualKey-pairs + * we use the same type of array as throughout Keyman even though we have lots of unused fields + */ const UINT mac_ScanCodeToUSVirtualKey[128] = { 0x41, // L"K_A", // &H41 0x53, // L"K_S", // &H53 @@ -536,91 +543,105 @@ const UINT mac_ScanCodeToUSVirtualKey[128] = { 0x00, // not used 0x00, // not used }; -// _S2 TODO IsKeymanUsedChar()?? -// _S2 TODO convert_DeadkeyValues_To_U16str?? /** * @brief return the keyvalue for a given Keycode, shiftstate and caps of the * currently used (underlying) keyboard layout - * "What character will be produced for a keypress of a key and modifiers?" + * "What character will be produced for a keypress of a key and modifier?" * @param keyboard_layout pointer to the currently used (underlying) keyboard layout * @param keycode a key of the currently used keyboard layout - * @param ss a (windows-)shiftstate of the currently used keyboard layout _S2 + * @param shiftstate_mac a shiftstate of the currently used keyboard layout * @param caps state of the caps key of the currently used keyboard layout * @return the keyval obtained from keycode, shiftstate and caps */ -// _S2 ShiftState ss vs int shiftstate_mac KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps); -//_S2 TODO -KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32& deadkeystate); - -/** // _S2 shift_state_pos vs int shiftstate_mac - * @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. - * "What character will be produced for a keypress of a key and modifiers on the underlying keyboard?" - * @param keyboard_layout a pointer to the currently used (underlying) keyboard layout - * @param keycode a key of the currently used keyboard - * @param shift_state_pos a shiftstate of the currently used keyboard layout - * @return the keyval obtained from Keycode and shiftstate; +/** + * @brief return the keyvalue for a given Keycode, shiftstate and caps of the + * currently used (underlying) keyboard layout taking dk into account + * "What character will be produced for a keypress of a key and modifiers? + * @param keyboard_layout pointer to the currently used (underlying) keyboard layout + * @param keycode a key of the currently used keyboard layout + * @param shiftstate_mac a shiftstate of the currently used keyboard layout + * @param caps state of the caps key of the currently used keyboard layout + * @param[in,out] deadkeystate states wheter a deadkey was used or not + * @return the keyval obtained from keycode, shiftstate and caps */ -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac); +KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32& deadkeystate); /** * @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. * "What character will be produced for a keypress of a key and modifiers on the underlying keyboard? * If a deadkey was found return 0xFFFF and copy the deadkey into deadKey - * This function is similar to KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap* keymap, guint keycode, int shiftState) - * but processes deadkeys * @param keyboard_layout a pointer to the currently used (underlying) keyboard layout - * @param keycode a key of the currently used keyboard - * @param shiftState a shiftstate of the currently used keyboard layout - * @param deadKey* ptr to keyvalue if a deadkey was found; if not NULL - * @return 0xFFFF in case a deadkey was found, then the deadkey is stored in deadKey - * the keyval obtained from Keycode and shiftstate and caps; + * @param kc_underlying a key of the currently used keyboard + * @param vk_ShiftState a shiftstate of the currently used keyboard layout + * @param deadKey pointer to keyvalue if a deadkey was found; if not NULL + * @return 0xFFFF in case a deadkey was found, then the deadkey is stored in deadKey; + * or else the keyval obtained from Keycode and shiftstate and caps; */ -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, UINT keycode, UINT shiftState, PKMX_WCHAR deadKey); +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey); /** * @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard - * "What character is on the same position/shiftstats/caps on the currently used (underlying) keyboard?" + * "What character is on the same position/shiftstats/caps on the currently used (underlying) keyboard as on the US keyboard?" * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param kv_us a keyvalue on the US keyboard * @return keyval of the underlying keyboard if available; else the keyval of the US keyboard */ -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us); +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us); /** - * @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard + * @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard + * On what key of the underlying keyboard do we find a certain character? + * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param kv_underlying a keyvalue on the currently used (underlying) keyboard + * @return keycode of the underlying keyboard if foundf; else the keyval of the underlying keyboard + */ +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying); + +/** + * @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard -> it`s the same!! * "Where on an underlying keyboard do we find a character that is on a certain key on a US keyboard?" * @param keyboard_layout the currently used (underlying) keyboard layout * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param kc_us a key of the US keyboard - * @param ss a windows-type shiftstate + * @param ss_win a windows-type shiftstate * @param caps state of the caps key * @return the keycode of the underlying keyboard if found; else the keycode of the US keyboard */ -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss, int caps); +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps); + /** * @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard - * "Which keycode of an underlying keyboard will be mapped to a virtuaĺ key of a US keyboard?" - * @param virtualKeyUS a virtual key of the US keyboard + * "Where on an underlying keyboard do we find a character of a US keyboard?" + * @param vk_us a virtual key of the US keyboard * @return the keycode of the currently used (underlying) keyboard */ -UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD virtualKeyUS); +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us); - /** +/** * @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard - * "Which key of a underlying keyboard will be mapped to a virtual key of a US keyboard?" + * "Which character is found on a key of the US keyboard?" * @param keycode a keycode of the currently used (underlying) keyboard * @return the virtual key of the US keyboard or 0 */ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); -//_S2 TODO -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying); -//_S2 TODO -KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps); +/** + * @brief return the keyvalue of a combination of deadkey + character if there is a combination available + * "What character will be produced for a deadkey + a character?" e.g. '^' + 'a' -> 'â' + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @param vk_dk a keycode of a deadkey of the currently used (underlying) keyboard + * @param ss_dk a shiftstate of a deadkey of the currently used (underlying) keyboard + * @param vk_us a keycode of a character key on the currently used (underlying) keyboard to be combined to a dk + * @param shiftstate_mac a shiftstate of a character key on the currently used (underlying) keyboard + * @param caps state of the caps key of a character key on the currently used (underlying) keyboard + * @return the combination of deadkey + character if it is available; if not return 0 + */ +KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, int vk_dk, KMX_DWORD ss_dk, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps); + //_S2 TODO CodePointToU16String?? //################################################################################################################################################ //################################################################################################################################################ @@ -632,4 +653,4 @@ KMX_DWORD X_compare_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboa KMX_DWORD X_find_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); KMX_DWORD printout_dk(const UCKeyboardLayout* keyboard_layout); -#endif // KEYMAP_H \ No newline at end of file +#endif /*KEYMAP_H*/ \ No newline at end of file diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index ba4ab17478f..8b5c4f9d4c1 100644 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -1,7 +1,7 @@ /* * Keyman is copyright (C) 2004 SIL International. MIT License. * - * Mnemonic layout support for Linux + * Mnemonic layout support for mac */ @@ -28,7 +28,7 @@ DeadKey::DeadKey(KMX_WCHAR deadCharacter) { this->m_deadchar = deadCharacter; } -/** @brief return character */ +/** @brief return dead character */ KMX_WCHAR DeadKey::KMX_DeadCharacter() { return this->m_deadchar; } @@ -53,22 +53,12 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { bool test_alDead_S2(std::vector ald); - /** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. - * Contrary to what the function name might suggest, the function the mac_KMX_ToUnicodeEx does NOT process surrogate pairs. - * This is because it is used in mcompile only which only deals with latin scripts. - * In case this function is used for surrogate pairs, they will be ignored and a message will be printed out - * @param keycode a key of the currently used keyboard Layout - * @param pwszBuff Buffer to store resulting character - * @param ss_win a windows-style shiftstate of the currently used keyboard Layout - * @param caps state of the caps key of the currently used keyboard Layout - * @param keyboard_layout the currently used (underlying)keyboard Layout - * @return -1 if a deadkey was found; 0 if no translation is available; +1 if character was found and written to pwszBuff - */ +/** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. */ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, ShiftState ss_rgkey, int caps, const UCKeyboardLayout* keyboard_layout) { KMX_DWORD keyval; UInt32 isdk = 0; - if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_rgkey), caps)) + if (!ensureValidInputForKeyboardTranslation(mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_rgkey),keycode)) return 0; keyval = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_rgkey), caps, isdk); @@ -84,6 +74,7 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, ShiftState ss_rgkey, i if (u16len(pwszBuff) < 1) return 0; + if ((isdk) && (keycode != 0xFFFF)) // deadkeys return -1; if (keyval == 0) // no character @@ -101,7 +92,7 @@ KMX_WCHAR mac_KMX_DeadKeyMap(int index, std::vector*deadkeys, int dead for (size_t i = 0; i < deadkeys->size(); i++) { if ((*deadkeys)[i]->KMX_DeadCharacter() == index) { - return (KMX_WCHAR)deadkeyBase + i; + return (KMX_WCHAR)(deadkeyBase + i); } } return 0xFFFF; @@ -122,10 +113,12 @@ class mac_KMX_VirtualKey { memset(this->m_rgfDeadKey, 0, sizeof(this->m_rgfDeadKey)); } +/** @brief return member variable virtual key */ UINT VK() { return this->m_vk; } +/** @brief return member variable scancode */ UINT SC() { return this->m_sc; } @@ -197,6 +190,7 @@ class mac_KMX_VirtualKey { return true; } +/** @brief check if we use only keys used in mcompile */ bool mac_KMX_IsKeymanUsedKey() { return (this->m_vk >= 0x20 && this->m_vk <= 0x5F) || (this->m_vk >= 0x88); } @@ -205,6 +199,7 @@ class mac_KMX_VirtualKey { return KMX_ShiftStateMap[(int)ss] | (capslock ? (caps ? CAPITALFLAG : NOTCAPITALFLAG) : 0); } +/** @brief count the number of keys */ int mac_KMX_GetKeyCount(int MaxShiftState) { int nkeys = 0; @@ -216,7 +211,7 @@ class mac_KMX_VirtualKey { } for (int caps = 0; caps <= 1; caps++) { std::u16string st = this->mac_KMX_GetShiftState((ShiftState)ss, (caps == 1)); - // ctrl and sh+ctrl will be skipped since rgkey has no entries in m_rgss[2] m_rgss[3] + // ctrl and shift+ctrl will be skipped since rgkey has no entries in m_rgss[2] m_rgss[3] if (st.size() == 0) { // No character assigned here } else if (this->m_rgfDeadKey[(int)ss][caps]) { @@ -240,6 +235,7 @@ class mac_KMX_VirtualKey { return nkeys; } +/** @brief edit the row of kmx-file */ bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector*deadkeys, int deadkeyBase, BOOL bDeadkeyConversion, vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { // I4552 // Get the CAPSLOCK value /*int capslock = @@ -294,14 +290,16 @@ class mac_KMX_VirtualKey { } } if (isvalid) { - // this is different to mcompile windows !!!! - // this->m_sc stores SC-US = SCUnderlying - // this->m_vk stores VK-US ( not underlying !!) - // key->Key stores VK-US ( not underlying !!) - // key->dpOutput stores character Underlying - KMX_DWORD SC_Underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keyboard_layout, all_vector, this->SC(), (ShiftState)ss, caps); + /* + * this is different to mcompile windows !!!! + * this->m_sc stores SC-US = SCUnderlying + * this->m_vk stores VK-US ( not underlying !!) + * key->Key stores VK-US ( not underlying !!) + * key->dpOutput stores character Underlying + */ + KMX_DWORD sc_underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keyboard_layout, all_vector, this->SC(), (ShiftState)ss, caps); - key->Key = mac_KMX_get_VKUS_From_KeyCodeUnderlying(SC_Underlying); + key->Key = mac_KMX_get_VKUS_From_KeyCodeUnderlying(sc_underlying); key->Line = 0; key->ShiftFlags = this->KMX_GetShiftStateValue(capslock, caps, (ShiftState)ss); @@ -320,6 +318,7 @@ class mac_KMX_VirtualKey { } return true; } + }; /** @brief Base class for KMX_loader*/ @@ -357,21 +356,21 @@ class mac_KMX_Loader { bool fCapsLock, // Was the caps lock key pressed? const UCKeyboardLayout* keyboard_layout) { // The keyboard layout - int maxshiftstate = 2; //_S2 MAC_SHIFT?? + int max_shiftstate_pos = 1; // use BASE + SHIFT only DeadKey* deadKey = new DeadKey(rgKey[iKeyDead]->mac_KMX_GetShiftState(shiftStateDead, fCapsLock)[0]); int ss_dead = mac_convert_rgkey_Shiftstate_to_MacShiftstate(shiftStateDead); KMX_DWORD keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead], ss_dead, 0); for (int i = 0; i < keycode_spacebar + 1; i++) { - for (int j = 0; j < maxshiftstate; j++) { + for (int j = 0; j <= max_shiftstate_pos; j++) { for (int caps = 0; caps < 1; caps++) { // e.g. a basechar KMX_DWORD basechar = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[j], caps); // e.g. â combchar - KMX_DWORD KC_Underlying_dk = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKeyDead); - KMX_DWORD combchar = mac_get_CombinedChar_From_DK(KC_Underlying_dk, ss_dead, keyboard_layout, i, ss_mac[j], caps); + KMX_DWORD kc_Underlying_dk = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKeyDead); + KMX_DWORD combchar = mac_get_CombinedChar_From_DK(keyboard_layout, kc_Underlying_dk, ss_dead, i, ss_mac[j], caps); if (combchar == 0) continue; @@ -386,14 +385,6 @@ class mac_KMX_Loader { } return deadKey; } - - /*void ClearKeyboardBuffer(UINT vk, UINT sc, HKL hkl) { - WCHAR sb[16]; - int rc = 0; - do { - rc = ::ToUnicodeEx(vk, sc, lpKeyStateNull, sb, _countof(sb), 0, hkl); - } while (rc != 1 && rc != 0); - }*/ }; /** @@ -416,13 +407,13 @@ int mac_KMX_GetMaxDeadkeyIndex(KMX_WCHAR* p) { //################################################################################################################################################ +bool test_run_verify_S2(std::vector rgKey); // _S2 need to go void test_print_All_Entries_S2(std::vector rgKey); -bool test_run_verify_S2(std::vector rgKey); -void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout); -void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode); +//void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout); +//void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode); - /** +/** * @brief Collect the key data, translate it to kmx and append to the existing keyboard * It is important to understand that this function has different sorting order in rgkey compared to mcompile-windows! * On windows the values of rgkey are sorted according to the VK of the underlying keyboard @@ -450,15 +441,15 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK //Windows and Linux Keycodes start with 1; Mac keycodes start with 0 for (UINT sc = 0x00; sc <= 0x7f; sc++) { - // HERE IS A BIG DIFFERENCE COMPARED TO MCOMPILE FOR WINDOWS: - // mcompile on Windows fills rgkey.m_vk with the VK of the Underlying keyboard - // mcompile for macOS fills rgkey.m_vk with the VK of the US keyboard - // this results in a different sorting order in rgkey[] ! - - // macOS cannot get a VK for the underling Keyboard since this does not exist - // macOS can only get a VK for the US Keyboard (by using USVirtualKeyToScanCode/ScanCodeToUSVirtualKey) - // therefore in rgkey[ ] we use VK_US which we get from all_vector - + /* HERE IS A BIG DIFFERENCE COMPARED TO MCOMPILE FOR WINDOWS: + * mcompile on Windows fills rgkey.m_vk with the VK of the Underlying keyboard + * mcompile for macOS fills rgkey.m_vk with the VK of the US keyboard + * this results in a different sorting order in rgkey[] ! + + * macOS cannot get a VK for the underling Keyboard since this does not exist + * macOS can only get a VK for the US Keyboard (by using USVirtualKeyToScanCode/ScanCodeToUSVirtualKey) + * therefore in rgkey[ ] we use VK_US which we get from all_vector + */ mac_KMX_VirtualKey* key = new mac_KMX_VirtualKey(sc); if ((key->VK() != 0)) { @@ -478,15 +469,15 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK continue; } - //_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! - if (ss == MenuCtrl || ss == ShftMenuCtrl) { + //_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! + /*if (ss == MenuCtrl || ss == ShftMenuCtrl) { continue; - } + }*/ - KMX_DWORD KC_US = (KMX_DWORD)mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); + KMX_DWORD kc_underlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); for (int caps = 0; caps <= 1; caps++) { - int rc = mac_KMX_ToUnicodeEx(KC_US, sbBuffer, ss, caps, *keyboard_layout); + int rc = mac_KMX_ToUnicodeEx(kc_underlying, sbBuffer, ss, caps, *keyboard_layout); if (rc > 0) { if (*sbBuffer == 0) { @@ -688,8 +679,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK KMX_WCHAR* p = kkp->dpContext = new KMX_WCHAR[8]; *p++ = UC_SENTINEL; *p++ = CODE_DEADKEY; - - *p++ = mac_KMX_DeadKeyMap(dk->KMX_DeadCharacter(), &alDead, nDeadkey, FDeadkeys); // I4353 + *p++ = mac_KMX_DeadKeyMap(dk->KMX_DeadCharacter(), &alDead, nDeadkey, FDeadkeys); // I4353 // *p++ = nDeadkey+i; *p++ = UC_SENTINEL; *p++ = CODE_ANY; @@ -708,6 +698,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK return true; } // _S2 need to go + void print_entries_S2(int i, std::vector rgKey , std::string comp1,std::string comp2,std::string erg) { std::string b0 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 0 )); std::string b1 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 1 )); @@ -762,7 +753,7 @@ void test_print_All_Entries_S2( std::vector rgKey) { print_entries_S2(222, rgKey, "ä", "Ä", "ä Ä Ä Ä"); print_entries_S2(226, rgKey, "<", ">", "< < > >"); } -void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode) { +/*void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode) { UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; UniChar unicodeString[maxStringlength]; @@ -784,7 +775,8 @@ void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int ke } } } -void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout){ +*/ +/*void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout){ UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; UniChar unicodeString[maxStringlength]; @@ -808,6 +800,7 @@ void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout){ } } } +*/ bool test_checkBasechar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) { return ( DK->KMX_GetBaseCharacter(index) == ch) ; } diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h index 3cb44268272..a108acbc4ed 100644 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -3,8 +3,20 @@ #ifndef MC_IMPORT_RULES_H #define MC_IMPORT_RULES_H - -int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps, const UCKeyboardLayout* keyboard_layout); +/** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. + * Contrary to what the function name might suggest, the function the mac_KMX_ToUnicodeEx does NOT process surrogate pairs. + * This is because it is used in mcompile only which only deals with latin scripts. + * In case this function is used for surrogate pairs, they will be ignored and a message will be printed out + * @param keycode a key of the currently used keyboard Layout + * @param pwszBuff Buffer to store resulting character + * @param ss_rgkey a windows-style shiftstate of the currently used keyboard Layout + * @param caps state of the caps key of the currently used keyboard Layout + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @return -1 if a deadkey was found; + * 0 if no translation is available; + * +1 if character was found and written to pwszBuff + */ +int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_rgkey, int caps, const UCKeyboardLayout* keyboard_layout); /** @brief Base class for Deadkey*/ class DeadKey { @@ -14,48 +26,53 @@ class DeadKey { std::vector m_rgcombchar; public: -/** - * @brief Constructor - * @param deadCharacter a deadkey - */ + /** + * @brief Constructor + * @param deadCharacter a deadkey + */ DeadKey(KMX_WCHAR deadCharacter); -/** - * @brief return dead character - * @return deadkey character - */ - KMX_WCHAR KMX_DeadCharacter(); + /** + * @brief return dead character + * @return deadkey character + */ + KMX_WCHAR KMX_DeadCharacter(); -/** - * @brief set Deadkey with values - * @param baseCharacter the base character - * @param combinedCharacter the combined character - * @return void - */ + /** + * @brief set member variable with base and combined character + * @param baseCharacter the base character + * @param combinedCharacter the combined character + * @return void + */ void KMX_AddDeadKeyRow(KMX_WCHAR baseCharacter, KMX_WCHAR combinedCharacter); + + /** @brief return size of array of basecharacters */ int KMX_Count() { return this->m_rgbasechar.size(); } + /** @brief get member variable m_deadchar */ KMX_WCHAR KMX_GetDeadCharacter() { return this->m_deadchar; } + /** @brief return base character at index */ KMX_WCHAR KMX_GetBaseCharacter(int index) { return this->m_rgbasechar[index]; } + /** @brief return combined character at index */ KMX_WCHAR KMX_GetCombinedCharacter(int index) { return this->m_rgcombchar[index]; } /** * @brief check if character exists in DeadKey - * @param baseCharacter + * @param baseCharacter a character to be found * @return true if found; false if not found */ bool KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter); }; -#endif // MC_IMPORT_RULES_H +#endif /*MC_IMPORT_RULES_H*/ diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index e5f281c02da..0c5b6136801 100644 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -1,3 +1,8 @@ +/* + * Keyman is copyright (C) SIL International. MIT License. + * + * Mnemonic layout support for mac + */ #include "mc_kmxfile.h" #include @@ -36,8 +41,32 @@ const int CODE__SIZE[] = { 2 // CODE_SETSYSTEMSTORE 0x18 }; -KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug) { +/** + * @brief check if the file has correct version + * @param filebase containing data of the input file + * @param file_size a size + * @return true if successful; false if not + */ +KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size); +/** + * @brief Fixup the keyboard by expanding pointers. On disk the pointers are stored relative to the + * beginning of the file, but we need real pointers. This method is used on 32-bit architectures. + * @param bufp pointer to buffer where data will be copied into + * @param base pointer to starting point + * @param dwFileSize size of the file + * @return pointer to the keyboard + */ +LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize); + +/** + * @brief Save a Keyboard to a file + * @param fk pointer to the keyboard + * @param hOutfile pointer to the output file + * @param FSaveDebug + * @return an Error in case of failure + */ +KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug) { LPKMX_GROUP fgp; LPKMX_STORE fsp; LPKMX_KEY fkp; @@ -60,28 +89,27 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX //wcslen(fk->szMessage)*2 + 2 + fk->dwBitmapSize; - for(i = 0, fgp = fk->dpGroupArray; i < fk->cxGroupArray; i++, fgp++) { - if(fgp->dpName) + for (i = 0, fgp = fk->dpGroupArray; i < fk->cxGroupArray; i++, fgp++) { + if (fgp->dpName) size += (u16len(fgp->dpName) + 1) * sizeof(KMX_WCHAR); size += fgp->cxKeyArray * sizeof(KMX_COMP_KEY); - for(j = 0, fkp = fgp->dpKeyArray; j < fgp->cxKeyArray; j++, fkp++) { + for (j = 0, fkp = fgp->dpKeyArray; j < fgp->cxKeyArray; j++, fkp++) { size += (u16len(fkp->dpOutput) + 1) * sizeof(KMX_WCHAR); size += (u16len(fkp->dpContext) + 1) * sizeof(KMX_WCHAR); } - if( fgp->dpMatch ) size += (u16len(fgp->dpMatch) + 1) * sizeof(KMX_WCHAR); - if( fgp->dpNoMatch ) size += (u16len(fgp->dpNoMatch) + 1) * sizeof(KMX_WCHAR); + if (fgp->dpMatch) size += (u16len(fgp->dpMatch) + 1) * sizeof(KMX_WCHAR); + if (fgp->dpNoMatch) size += (u16len(fgp->dpNoMatch) + 1) * sizeof(KMX_WCHAR); } - for(i = 0; i < fk->cxStoreArray; i++) - { + for (i = 0; i < fk->cxStoreArray; i++) { size += (u16len(fk->dpStoreArray[i].dpString) + 1) * sizeof(KMX_WCHAR); - if(fk->dpStoreArray[i].dpName) + if (fk->dpStoreArray[i].dpName) size += (u16len(fk->dpStoreArray[i].dpName) + 1) * sizeof(KMX_WCHAR); } buf = new KMX_BYTE[size]; - if(!buf) return CERR_CannotAllocateMemory; + if (!buf) return CERR_CannotAllocateMemory; memset(buf, 0, size); ck = (PKMX_COMP_KEYBOARD) buf; @@ -103,74 +131,74 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX offset = sizeof(KMX_COMP_KEYBOARD); ck->dpStoreArray = offset; - sp = (PKMX_COMP_STORE)(buf+offset); + sp = (PKMX_COMP_STORE)(buf + offset); fsp = fk->dpStoreArray; offset += sizeof(KMX_COMP_STORE) * ck->cxStoreArray; - for(i = 0; i < ck->cxStoreArray; i++, sp++, fsp++) { + for (i = 0; i < ck->cxStoreArray; i++, sp++, fsp++) { sp->dwSystemID = fsp->dwSystemID; sp->dpString = offset; - u16ncpy((PKMX_WCHAR)(buf+offset), fsp->dpString, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 - offset += (u16len(fsp->dpString) + 1) * sizeof(KMX_WCHAR); + u16ncpy((PKMX_WCHAR)(buf + offset), fsp->dpString, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 - if(!fsp->dpName) { + offset += (u16len(fsp->dpString) + 1) * sizeof(KMX_WCHAR); + if (!fsp->dpName) { sp->dpName = 0; } else { sp->dpName = offset; - u16ncpy((PKMX_WCHAR)(buf+offset), fsp->dpName, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + u16ncpy((PKMX_WCHAR)(buf + offset), fsp->dpName, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 offset += (u16len(fsp->dpName) + 1) * sizeof(KMX_WCHAR); } } ck->dpGroupArray = offset; - gp = (PKMX_COMP_GROUP)(buf+offset); - fgp = fk->dpGroupArray; + gp = (PKMX_COMP_GROUP)(buf + offset); offset += sizeof(KMX_COMP_GROUP) * ck->cxGroupArray; - for(i = 0; i < ck->cxGroupArray; i++, gp++, fgp++) { + for (i = 0, fgp = fk->dpGroupArray; i < ck->cxGroupArray; i++, gp++, fgp++) { gp->cxKeyArray = fgp->cxKeyArray; gp->fUsingKeys = fgp->fUsingKeys; gp->dpMatch = gp->dpNoMatch = 0; - if(fgp->dpMatch) { + if (fgp->dpMatch) { gp->dpMatch = offset; - u16ncpy((PKMX_WCHAR)(buf+offset), fgp->dpMatch, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + u16ncpy((PKMX_WCHAR)(buf + offset), fgp->dpMatch, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 offset += (u16len(fgp->dpMatch) + 1) * sizeof(KMX_WCHAR); } - if(fgp->dpNoMatch) { + if (fgp->dpNoMatch) { gp->dpNoMatch = offset; - u16ncpy((PKMX_WCHAR)(buf+offset), fgp->dpNoMatch, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + u16ncpy((PKMX_WCHAR)(buf + offset), fgp->dpNoMatch, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 offset += (u16len(fgp->dpNoMatch) + 1) * sizeof(KMX_WCHAR); } - if(fgp->dpName) { + if (fgp->dpName) { gp->dpName = offset; - u16ncpy((PKMX_WCHAR)(buf+offset), fgp->dpName, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + u16ncpy((PKMX_WCHAR)(buf + offset), fgp->dpName, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 offset += (u16len(fgp->dpName) + 1) * sizeof(KMX_WCHAR); - } else { + } else { gp->dpName = 0; } gp->dpKeyArray = offset; - kp = (PKMX_COMP_KEY) (buf + offset); + kp = (PKMX_COMP_KEY)(buf + offset); offset += gp->cxKeyArray * sizeof(KMX_COMP_KEY); - for(j = 0, fkp = fgp->dpKeyArray; j < gp->cxKeyArray; j++, kp++, fkp++) { + + for (j = 0, fkp = fgp->dpKeyArray; j < gp->cxKeyArray; j++, kp++, fkp++) { kp->Key = fkp->Key; kp->Line = fkp->Line; kp->ShiftFlags = fkp->ShiftFlags; kp->dpOutput = offset; - u16ncpy((PKMX_WCHAR)(buf+offset), fkp->dpOutput, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + u16ncpy((PKMX_WCHAR)(buf + offset), fkp->dpOutput, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 offset += (u16len(fkp->dpOutput) + 1) * sizeof(KMX_WCHAR); kp->dpContext = offset; - u16ncpy((PKMX_WCHAR)(buf+offset), fkp->dpContext, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + u16ncpy((PKMX_WCHAR)(buf + offset), fkp->dpContext, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 offset += (u16len(fkp->dpContext) + 1) * sizeof(KMX_WCHAR); } } - if(fk->dwBitmapSize > 0) { + if (fk->dwBitmapSize > 0) { ck->dwBitmapSize = fk->dwBitmapSize; ck->dpBitmapOffset = offset; memcpy(buf + offset, ((PKMX_BYTE)fk) + fk->dpBitmapOffset, fk->dwBitmapSize); @@ -178,11 +206,16 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX } else { ck->dwBitmapSize = 0; ck->dpBitmapOffset = 0; + } + + size_t nr_elements = fwrite(buf, size, 1, hOutfile); + + if (nr_elements < 1) { + delete[] buf; + return CERR_SomewhereIGotItWrong; } - fwrite(buf, size,1, hOutfile); - if(offset != size) - { + if (offset != size) { delete[] buf; return CERR_UnableToWriteFully; } @@ -192,43 +225,13 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX return CERR_None; } -KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size); - -LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize); - -KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR fileName) { - - FILE *fp; - fp = Open_File(fileName, u"wb"); - - if(fp == NULL) - { - mac_KMX_LogError(L"Failed to create output file (%d)", errno); - return FALSE; - } - - KMX_DWORD err = KMX_WriteCompiledKeyboardToFile(kbd, fp, FALSE); - fclose(fp); - - if(err != CERR_None) { - mac_KMX_LogError(L"Failed to write compiled keyboard with error %d", err); - - std::u16string u16_filname(fileName); - std::string s = string_from_u16string(u16_filname); - - remove(s.c_str()); - return FALSE; - } - - return TRUE; -} +/** @brief save keyboard to file */ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName) { - FILE *fp; + FILE* fp; fp = Open_File(fileName, "wb"); - if(fp == NULL) - { + if (fp == NULL) { mac_KMX_LogError(L"Failed to create output file (%d)", errno); return FALSE; } @@ -236,7 +239,7 @@ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName) { KMX_DWORD err = KMX_WriteCompiledKeyboardToFile(kbd, fp, FALSE); fclose(fp); - if(err != CERR_None) { + if (err != CERR_None) { mac_KMX_LogError(L"Failed to write compiled keyboard with error %d", err); std::string s(fileName); remove(s.c_str()); @@ -246,25 +249,35 @@ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName) { return TRUE; } +/** + * @brief add an offset + * @param base pointer to starting point + * @param offset a given offset + * @return pointer to base + offset + */ PKMX_WCHAR KMX_StringOffset(PKMX_BYTE base, KMX_DWORD offset) { - if(offset == 0) return NULL; + if (offset == 0) + return NULL; return (PKMX_WCHAR)(base + offset); } #ifdef KMX_64BIT -/** CopyKeyboard will copy the data read into bufp from x86-sized structures into - x64-sized structures starting at `base` - * After this function finishes, we still need to keep the original data because - we don't copy the strings - This method is used on 64-bit architectures. -*/ +/** + * @brief CopyKeyboard will copy the data into bufp from x86-sized structures into + * x64-sized structures starting at `base`. After this function finishes, we still + * need to keep the original data because we don't copy the strings. The method is + * used on 64-bit architectures. + * @param bufp pointer to buffer where data is copied into + * @param base pointer to starting point + * @return pointer to the keyboard + */ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { - PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD) base; + PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)base; // Copy keyboard structure // - LPKMX_KEYBOARD kbp = (LPKMX_KEYBOARD) bufp; + LPKMX_KEYBOARD kbp = (LPKMX_KEYBOARD)bufp; bufp += sizeof(KMX_KEYBOARD); kbp->dwIdentifier = ckbp->dwIdentifier; @@ -280,21 +293,17 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { kbp->dwFlags = ckbp->dwFlags; kbp->dwHotKey = ckbp->dwHotKey; - kbp->dpStoreArray = (LPKMX_STORE) bufp; + kbp->dpStoreArray = (LPKMX_STORE)bufp; bufp += sizeof(KMX_STORE) * kbp->cxStoreArray; - kbp->dpGroupArray = (LPKMX_GROUP) bufp; + kbp->dpGroupArray = (LPKMX_GROUP)bufp; bufp += sizeof(KMX_GROUP) * kbp->cxGroupArray; PKMX_COMP_STORE csp; LPKMX_STORE sp; KMX_DWORD i; - for( - csp = (PKMX_COMP_STORE)(base + ckbp->dpStoreArray), sp = kbp->dpStoreArray, i = 0; - i < kbp->cxStoreArray; - i++, sp++, csp++) - { + for (csp = (PKMX_COMP_STORE)(base + ckbp->dpStoreArray), sp = kbp->dpStoreArray, i = 0; i < kbp->cxStoreArray; i++, sp++, csp++) { sp->dwSystemID = csp->dwSystemID; sp->dpName = KMX_StringOffset(base, csp->dpName); sp->dpString = KMX_StringOffset(base, csp->dpString); @@ -303,13 +312,9 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { PKMX_COMP_GROUP cgp; LPKMX_GROUP gp; - for( - cgp = (PKMX_COMP_GROUP)(base + ckbp->dpGroupArray), gp = kbp->dpGroupArray, i = 0; - i < kbp->cxGroupArray; - i++, gp++, cgp++) - { + for (cgp = (PKMX_COMP_GROUP)(base + ckbp->dpGroupArray), gp = kbp->dpGroupArray, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) { gp->dpName = KMX_StringOffset(base, cgp->dpName); - gp->dpKeyArray = cgp->cxKeyArray > 0 ? (LPKMX_KEY) bufp : NULL; + gp->dpKeyArray = cgp->cxKeyArray > 0 ? (LPKMX_KEY)bufp : NULL; gp->cxKeyArray = cgp->cxKeyArray; bufp += sizeof(KMX_KEY) * gp->cxKeyArray; gp->dpMatch = KMX_StringOffset(base, cgp->dpMatch); @@ -320,11 +325,7 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { LPKMX_KEY kp; KMX_DWORD j; - for( - ckp = (PKMX_COMP_KEY)(base + cgp->dpKeyArray), kp = gp->dpKeyArray, j = 0; - j < gp->cxKeyArray; - j++, kp++, ckp++) - { + for (ckp = (PKMX_COMP_KEY)(base + cgp->dpKeyArray), kp = gp->dpKeyArray, j = 0; j < gp->cxKeyArray; j++, kp++, ckp++) { kp->Key = ckp->Key; kp->Line = ckp->Line; kp->ShiftFlags = ckp->ShiftFlags; @@ -336,41 +337,38 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { } // else KMX_FixupKeyboard -#else /* Fixup the keyboard by expanding pointers. On disk the pointers are stored relative to the - beginning of the file, but we need real pointers. This method is used on 32-bit architectures. -*/ - +#else +/** @brief Fixup the keyboard by expanding pointers. */ LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize) { - UNREFERENCED_PARAMETER(dwFileSize); KMX_DWORD i, j; - PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD) base; + PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)base; PKMX_COMP_GROUP cgp; PKMX_COMP_STORE csp; PKMX_COMP_KEY ckp; - LPKMX_KEYBOARD kbp = (LPKMX_KEYBOARD) bufp; + LPKMX_KEYBOARD kbp = (LPKMX_KEYBOARD)bufp; LPKMX_STORE sp; LPKMX_GROUP gp; LPKMX_KEY kp; - kbp->dpStoreArray = (LPKMX_STORE) (base + ckbp->dpStoreArray); - kbp->dpGroupArray = (LPKMX_GROUP) (base + ckbp->dpGroupArray); + kbp->dpStoreArray = (LPKMX_STORE)(base + ckbp->dpStoreArray); + kbp->dpGroupArray = (LPKMX_GROUP)(base + ckbp->dpGroupArray); - for(sp = kbp->dpStoreArray, csp = (PKMX_COMP_STORE) sp, i = 0; i < kbp->cxStoreArray; i++, sp++, csp++) { + for (sp = kbp->dpStoreArray, csp = (PKMX_COMP_STORE)sp, i = 0; i < kbp->cxStoreArray; i++, sp++, csp++) { sp->dpName = KMX_StringOffset(base, csp->dpName); sp->dpString = KMX_StringOffset(base, csp->dpString); } - for(gp = kbp->dpGroupArray, cgp = (PKMX_COMP_GROUP) gp, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) { + for (gp = kbp->dpGroupArray, cgp = (PKMX_COMP_GROUP)gp, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) { gp->dpName = KMX_StringOffset(base, cgp->dpName); - gp->dpKeyArray = (LPKMX_KEY) (base + cgp->dpKeyArray); - if(cgp->dpMatch != NULL) gp->dpMatch = (PKMX_WCHAR) (base + cgp->dpMatch); - if(cgp->dpNoMatch != NULL) gp->dpNoMatch = (PKMX_WCHAR) (base + cgp->dpNoMatch); + gp->dpKeyArray = (LPKMX_KEY)(base + cgp->dpKeyArray); + if (cgp->dpMatch != NULL)gp->dpMatch = (PKMX_WCHAR)(base + cgp->dpMatch); + if (cgp->dpNoMatch != NULL)gp->dpNoMatch = (PKMX_WCHAR)(base + cgp->dpNoMatch); - for(kp = gp->dpKeyArray, ckp = (PKMX_COMP_KEY) kp, j = 0; j < gp->cxKeyArray; j++, kp++, ckp++) { - kp->dpOutput = (PKMX_WCHAR) (base + ckp->dpOutput); - kp->dpContext = (PKMX_WCHAR) (base + ckp->dpContext); + for (kp = gp->dpKeyArray, ckp = (PKMX_COMP_KEY)kp, j = 0; j < gp->cxKeyArray; j++, kp++, ckp++) { + kp->dpOutput = (PKMX_WCHAR)(base + ckp->dpOutput); + kp->dpContext = (PKMX_WCHAR)(base + ckp->dpContext); } } @@ -379,133 +377,29 @@ LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFil #endif -KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) { +/** @brief load a keyboard kmx-file */ +KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) { *lpKeyboard = NULL; PKMX_BYTE buf; FILE* fp; LPKMX_KEYBOARD kbp; PKMX_BYTE filebase; - if(!fileName || !lpKeyboard) { - mac_KMX_LogError(L"Bad Filename\n" ); - return FALSE; - } - - fp = Open_File((const KMX_WCHAR*)fileName, u"rb"); - - if(fp == NULL) { - mac_KMX_LogError(L"Could not open file\n" ); - return FALSE; - } - - if (fseek(fp, 0, SEEK_END) != 0) { - fclose(fp); - mac_KMX_LogError(L"Could not fseek file\n" ); - return FALSE; - } - - auto file_size = ftell(fp); - if (file_size <= 0) { - fclose(fp); - return FALSE; - } - - if (fseek(fp, 0, SEEK_SET) != 0) { - fclose(fp); - mac_KMX_LogError(L"Could not fseek(set) file\n" ); - return FALSE; - } - - #ifdef KMX_64BIT - // allocate enough memory for expanded data structure + original data. - // Expanded data structure is double the size of data on disk (8-byte - // pointers) - on disk the "pointers" are relative to the beginning of - // the file. - // We save the original data at the end of buf; we don't copy strings, so - // those will remain in the location at the end of the buffer. - buf = new KMX_BYTE[file_size * 3]; - #else - buf = new KMX_BYTE[file_size]; - #endif - - if (!buf) { - delete[] buf; - fclose(fp); - mac_KMX_LogError(L"Not allocmem\n" ); - return FALSE; - } - - #ifdef KMX_64BIT - filebase = buf + file_size*2; - #else - filebase = buf; - #endif - - if (fread(filebase, 1, file_size, fp) < (size_t)file_size) { - mac_KMX_LogError(L"Could not read file\n" ); - delete[] buf; - fclose(fp); - return FALSE; - } -// delete??? - fclose(fp); - - if (*((PKMX_DWORD)filebase) != (KMX_DWORD)FILEID_COMPILED) - { - delete [] buf; - mac_KMX_LogError(L"Invalid file - signature is invalid\n"); - return FALSE; - } - - if (!KMX_VerifyKeyboard(filebase, file_size)) { - mac_KMX_LogError(L"errVerifyKeyboard\n" ); - delete[] buf; - return FALSE; - } - -#ifdef KMX_64BIT - kbp = KMX_CopyKeyboard(buf, filebase); -#else - kbp = KMX_FixupKeyboard(buf, filebase, file_size); -#endif - - - if (!kbp) { - mac_KMX_LogError(L"errFixupKeyboard\n" ); - delete[] buf; - return FALSE; - } - - if (kbp->dwIdentifier != FILEID_COMPILED) { - delete[] buf; - mac_KMX_LogError(L"errNotFileID\n" ); - return FALSE; - } - *lpKeyboard = kbp; - return TRUE; -} -KMX_BOOL KMX_LoadKeyboard(char* fileName, LPKMX_KEYBOARD* lpKeyboard) { - *lpKeyboard = NULL; - PKMX_BYTE buf; - FILE* fp; - LPKMX_KEYBOARD kbp; - PKMX_BYTE filebase; - - if(!fileName || !lpKeyboard) { - mac_KMX_LogError(L"Bad Filename\n" ); + if (!fileName || !lpKeyboard) { + mac_KMX_LogError(L"Bad Filename\n"); return FALSE; } fp = Open_File((const KMX_CHAR*)fileName, "rb"); - if(fp == NULL) { - mac_KMX_LogError(L"Could not open file\n" ); + if (fp == NULL) { + mac_KMX_LogError(L"Could not open file\n"); return FALSE; } if (fseek(fp, 0, SEEK_END) != 0) { fclose(fp); - mac_KMX_LogError(L"Could not fseek file\n" ); + mac_KMX_LogError(L"Could not fseek file\n"); return FALSE; } @@ -517,17 +411,19 @@ KMX_BOOL KMX_LoadKeyboard(char* fileName, LPKMX_KEYBOARD* lpKeyboard) { if (fseek(fp, 0, SEEK_SET) != 0) { fclose(fp); - mac_KMX_LogError(L"Could not fseek(set) file\n" ); + mac_KMX_LogError(L"Could not fseek(set) file\n"); return FALSE; } #ifdef KMX_64BIT - // allocate enough memory for expanded data structure + original data. - // Expanded data structure is double the size of data on disk (8-byte - // pointers) - on disk the "pointers" are relative to the beginning of - // the file. - // We save the original data at the end of buf; we don't copy strings, so - // those will remain in the location at the end of the buffer. +/** + * allocate enough memory for expanded data structure + original data. + * Expanded data structure is double the size of data on disk (8-byte + * pointers) - on disk the "pointers" are relative to the beginning of + * the file. + * We save the original data at the end of buf; we don't copy strings, so + * those will remain in the location at the end of the buffer. + */ buf = new KMX_BYTE[file_size * 3]; #else buf = new KMX_BYTE[file_size]; @@ -536,35 +432,34 @@ KMX_BOOL KMX_LoadKeyboard(char* fileName, LPKMX_KEYBOARD* lpKeyboard) { if (!buf) { delete[] buf; fclose(fp); - mac_KMX_LogError(L"Not allocmem\n" ); + mac_KMX_LogError(L"Not allocmem\n"); return FALSE; } #ifdef KMX_64BIT - filebase = buf + file_size*2; + filebase = buf + file_size * 2; #else filebase = buf; #endif if (fread(filebase, 1, file_size, fp) < (size_t)file_size) { - mac_KMX_LogError(L"Could not read file\n" ); + mac_KMX_LogError(L"Could not read file\n"); delete[] buf; fclose(fp); return FALSE; } -// delete??? +// delete??? _S2 fclose(fp); - if (*((PKMX_DWORD)filebase) != (KMX_DWORD)FILEID_COMPILED) - { - delete [] buf; + if (*((PKMX_DWORD)filebase) != (KMX_DWORD)FILEID_COMPILED) { + delete[] buf; mac_KMX_LogError(L"Invalid file - signature is invalid\n"); return FALSE; } if (!KMX_VerifyKeyboard(filebase, file_size)) { - mac_KMX_LogError(L"errVerifyKeyboard\n" ); delete[] buf; + mac_KMX_LogError(L"errVerifyKeyboard\n"); return FALSE; } @@ -574,10 +469,9 @@ KMX_BOOL KMX_LoadKeyboard(char* fileName, LPKMX_KEYBOARD* lpKeyboard) { kbp = KMX_FixupKeyboard(buf, filebase, file_size); #endif - if (!kbp) { - mac_KMX_LogError(L"errFixupKeyboard\n" ); delete[] buf; + mac_KMX_LogError(L"errFixupKeyboard\n"); return FALSE; } @@ -590,8 +484,8 @@ KMX_BOOL KMX_LoadKeyboard(char* fileName, LPKMX_KEYBOARD* lpKeyboard) { return TRUE; } -KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size){ - +/** @brief check if the file has correct version */ +KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size) { KMX_DWORD i; PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)filebase; PKMX_COMP_STORE csp; @@ -605,7 +499,7 @@ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size){ if (csp->dpString == 0) { mac_KMX_LogError(L"errWrongFileVersion:NULL"); } else { - mac_KMX_LogError(L"errWrongFileVersion:%10.10ls",(const PKMX_WCHAR) KMX_StringOffset((PKMX_BYTE)filebase, csp->dpString)); + mac_KMX_LogError(L"errWrongFileVersion:%10.10ls", (const PKMX_WCHAR)KMX_StringOffset((PKMX_BYTE)filebase, csp->dpString)); } return FALSE; } @@ -616,8 +510,8 @@ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size){ return TRUE; } +/** @brief increment in a string */ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) { - if (p == NULL || *p == 0) return p; if (*p != UC_SENTINEL) { @@ -625,13 +519,14 @@ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) { return p + 2; return p + 1; } - // UC_SENTINEL(FFFF) with UC_SENTINEL_EXTENDEDEND(0x10) == variable length + // UC_SENTINEL(FFFF) with UC_SENTINEL_EXTENDEDEND(0x10) ==> variable length if (*(p + 1) == CODE_EXTENDED) { p += 2; while (*p && *p != UC_SENTINEL_EXTENDEDEND) p++; - if (*p == 0) return p; + if (*p == 0) + return p; return p + 1; } @@ -650,36 +545,17 @@ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) { return p; } -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - - +/** @brief open a file */ FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode) { #ifdef _MSC_VER - std::string cpath = Filename; //, cmode = mode; + std::string cpath = Filename; //, cmode = mode; std::replace(cpath.begin(), cpath.end(), '/', '\\'); - return fopen(cpath.c_str(), (const KMX_CHAR*) mode); + return fopen(cpath.c_str(), (const KMX_CHAR*)mode); #else return fopen(Filename, mode); std::string cpath, cmode; - cpath = (const KMX_CHAR*) Filename; - cmode = (const KMX_CHAR*) mode; - return fopen(cpath.c_str(), cmode.c_str()); -#endif -}; - - -FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode) { -#ifdef _MSC_VER - std::wstring cpath = convert_pchar16T_To_wstr((KMX_WCHAR*) Filename); - std::wstring cmode = convert_pchar16T_To_wstr((KMX_WCHAR*) mode); - std::replace(cpath.begin(), cpath.end(), '/', '\\'); - return _wfsopen(cpath.c_str(), cmode.c_str(), _SH_DENYWR); -#else - std::string cpath, cmode; - cpath = string_from_u16string(Filename); - cmode = string_from_u16string(mode); + cpath = (const KMX_CHAR*)Filename; + cmode = (const KMX_CHAR*)mode; return fopen(cpath.c_str(), cmode.c_str()); #endif }; diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index 3bac3ada917..b4ab675bbc4 100644 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -70,25 +70,24 @@ typedef struct KMX_tagKEYBOARD { /** * @brief load a keyboard kmx-file - * @param fileName ptr to fileName of kmx-file - * @param [in,out] lpKeyboard ptr to ptr to keyboard + * @param fileName pointer to fileName of kmx-file + * @param [in,out] lpKeyboard pointer to pointer to keyboard * @return TRUE on success; else FALSE */ -KMX_BOOL KMX_LoadKeyboard(KMX_WCHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) ; KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) ; /** * @brief save keyboard to file - * @param kbd ptr to the keyboard - * @param fileName ptr to fileName of a kmx-file + * @param kbd pointer to the keyboard + * @param fileName pointer to fileName of a kmx-file * @return TRUE on success; else FALSE */ -KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR* fileName); KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName); + /** * @brief increment in a string - * @param p ptr to a character - * @return ptr to the incremented character + * @param p pointer to a character + * @return pointer to the incremented character */ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); @@ -96,10 +95,9 @@ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); * @brief open a file * @param Filename name of the file * @param mode same as mode in fopen - * @return ptr to file. On error, returns a null pointer + * @return pointer to file. On error, returns a null pointer */ FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); -FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode); #endif // _KMXFILE_H diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 308d04efcf1..dcc96dde55b 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -1,14 +1,12 @@ /* * Keyman is copyright (C) 2004 SIL International. MIT License. * - * Mnemonic layout support for Linux - */ - -/* - Defines the entry point for the console application. - - Note: this program deliberately leaks memory as it has a very short life cycle and managing the memory allocations - for the subcomponents of the compiled keyboard is an unnecessary optimisation. Just so you know. + * Mnemonic layout support for mac + * + * Defines the entry point for the console application. + * + * Note: this program deliberately leaks memory as it has a very short life cycle and managing the memory allocations + * for the subcomponents of the compiled keyboard is an unnecessary optimisation. Just so you know. */ #include @@ -17,15 +15,11 @@ #include "u16.h" -int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* OutputPairs); // returns array of [usvk, ch_out] pairs - -int mac_run(int argc, char* argv[]); - /** * @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard * @param kbd pointer to US keyboard - * @param bDeadkeyConversion option for converting a deadkey to a character: 1=conversion; 0= no conversion - * @param argc number of commandline arguments + * @param bDeadkeyConversion option for converting a deadkey to a character: 1 = dk conversion; 0 = no dk conversion + * @param argc number of command line arguments * @return TRUE if conversion was successful; FALSE if not */ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc); @@ -33,12 +27,32 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int /** @brief Collect the key data, translate it to kmx and append to the existing keyboard */ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D &all_vector, const UCKeyboardLayout** keyboard_layout, std::vector* KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 +/** + * @brief start of mcompile; load, convert and save keyboard + * @param argc number of commandline arguments + * @param argv pointer to commandline arguments: executable, inputfile, outputfile + * @return 0 on success; + * 1 for wrong usage of calling parameters; + * 3 if unable to load keyboard + */ +int mac_run(int argc, char* argv[]); + +/** + * @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard + * @param keyboard_layout pointer to the currently used (underlying) keyboard Layout + * @param all_vector vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param deadkey deadkey character + * @param shift_dk shiftstate opf a deadkey character + * @param [out] outputPairs pointer to array of [usvk, ch_out] pairs + * @return size of array of [usvk, ch_out] pairs + */ +int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* outputPairs); // returns array of [usvk, ch_out] pairs + std::vector KMX_FDeadkeys; // I4353 -// _S2 run and getdeadkeys to here #define _countof(a) (sizeof(a) / sizeof(*(a))) - /** +/** * @brief main function for mcompile for Windows, Linux, Mac * @param argc number of commandline arguments * @param argv commandline arguments @@ -57,12 +71,10 @@ std::vector KMX_FDeadkeys; // I4353 mac_run(argc, argv); printf("\n................................ END .............................. _S2 \n"); - } -/** @brief start of mcompile; load, convert and save keyboard */ -int mac_run(int argc, char* argv[] ) { - +/** @brief start of mcompile; load, convert and save keyboard */ +int mac_run(int argc, char* argv[]) { int bDeadkeyConversion = 0; if (argc > 1) @@ -79,14 +91,13 @@ int mac_run(int argc, char* argv[] ) { " \tmac keyboard layout\n" " \t(-d convert deadkeys to plain keys) \n \n"); // I4552 } - // -u option is not available for Linux and macOS + + // -u option is not available for Linux and macOS KMX_CHAR* infile = argv[n]; KMX_CHAR* outfile = argv[n + 1]; printf("mcompile%s \"%s\" \"%s\"\n", bDeadkeyConversion ? " -d" : "", infile, outfile); // I4174 - // _S2 TODO open again!! - //wprintf(L"mcompile%ls \"%ls\" \"%ls\"\n", bDeadkeyConversion ? L" -d" : L"", u16fmt((const char16_t*) infile).c_str(), u16fmt((const char16_t*) outfile).c_str() ); // I4174 // 1. Load the keyman keyboard file @@ -121,16 +132,16 @@ int mac_run(int argc, char* argv[] ) { } #if defined(_WIN32) || defined(_WIN64) // Windows - if (DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F + if (DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); } - #elif ((__linux__) || (__unix__)) // LINUX, UNIX + #elif ((__linux__) || (__unix__)) // LINUX, UNIX if (mac_KMX_DoConvert(kmxfile, bDeadkeyConversion, argc)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); } - #elif (__APPLE__ && TARGET_OS_MAC) // macOS + #elif (__APPLE__ && TARGET_OS_MAC) // macOS if (mac_KMX_DoConvert(kmxfile, bDeadkeyConversion, argc)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); } @@ -265,7 +276,7 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. - if ((shift & (LCTRLFLAG|RALTFLAG)) == (LCTRLFLAG|RALTFLAG)) // I4327 + if ((shift & (LCTRLFLAG | RALTFLAG)) == (LCTRLFLAG | RALTFLAG)) // I4327 shift &= ~LCTRLFLAG; if (key->ShiftFlags == 0) { @@ -281,9 +292,9 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, PKMX_WCHAR context = new KMX_WCHAR[len + 4]; memcpy(context, key->dpContext, len * sizeof(KMX_WCHAR)); context[len] = UC_SENTINEL; - context[len+1] = CODE_DEADKEY; - context[len+2] = deadkey; - context[len+3] = 0; + context[len + 1] = CODE_DEADKEY; + context[len + 2] = deadkey; + context[len + 3] = 0; key->dpContext = context; key->Key = vk; } @@ -340,7 +351,7 @@ void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, for (unsigned int i = 0; i < kbd->cxGroupArray; i++) { if (kbd->dpGroupArray[i].fUsingKeys) { LPKMX_KEY keys = new KMX_KEY[kbd->dpGroupArray[i].cxKeyArray + 1]; - memcpy(keys+1, kbd->dpGroupArray[i].dpKeyArray, kbd->dpGroupArray[i].cxKeyArray * sizeof(KMX_KEY)); + memcpy(keys + 1, kbd->dpGroupArray[i].dpKeyArray, kbd->dpGroupArray[i].cxKeyArray * sizeof(KMX_KEY)); keys[0].dpContext = new KMX_WCHAR[1]; keys[0].dpContext[0] = 0; keys[0].dpOutput = new KMX_WCHAR[4]; @@ -367,9 +378,9 @@ void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, */ KMX_WCHAR mac_KMX_ScanXStringForMaxDeadkeyID(PKMX_WCHAR str) { KMX_WCHAR dkid = 0; - while(str && *str) { - if(*str == UC_SENTINEL && *(str+1) == CODE_DEADKEY) { - dkid = std::max(dkid, *(str+2)); + while (str && *str) { + if (*str == UC_SENTINEL && *(str + 1) == CODE_DEADKEY) { + dkid = std::max(dkid, *(str + 2)); } str = KMX_incxstr(str); } @@ -393,7 +404,7 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { UINT i, j; KMX_WCHAR dkid = 0; static KMX_WCHAR s_next_dkid = 0; - static KMX_dkidmap* s_dkids = NULL; + static KMX_dkidmap* s_dkids = NULL; static int s_ndkids = 0; if (!kbd) { @@ -510,10 +521,10 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int // evident for the 102nd key on UK, for example, where \ can be generated with VK_OEM_102 or AltGr+VK_QUOTE. // For now, we get the least shifted version, which is hopefully adequate. - // Sadly it`s not e.g.: on a German WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only which is the usual combination to get ~. + // Sadly it`s not e.g.: on a German WINDOWS keyboard one will get '~' with ALTGR + K_221(+) which is the usual combination to get ~. // on a German MAC keyboard one will get '~' with either OPT + K_221(+) or OPT + K_84(T) or CAPS + OPT + K_78(N) // K_84(T) will be caught first, so one of the the least obvious version for creating the '~' is found and processed. - // -> meeting with Marc May 21 2024: We leave it as it is; it is OK if different combinations are found. + // -> meeting with @MD May 21 2024: We leave it as it is; it is OK if different combinations are found. const UCKeyboardLayout* keyboard_layout; if (mac_InitializeUCHR(&keyboard_layout)) { @@ -527,12 +538,6 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int return FALSE; } - //printoutKeyboards(all_vector); -find_character_S2(keyboard_layout, 180); -printf("-------\n"); -//print_dublicates_S2(keyboard_layout); -//find_double_keys(keyboard_layout,1); - for (int j = 0; VKShiftState[j] != 0xFFFF; j++) { // I4651 // Loop through each possible key on the keyboard @@ -563,29 +568,19 @@ printf("-------\n"); if (!mac_KMX_ImportRules(kbd, all_vector, &keyboard_layout, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 return FALSE; } - return TRUE; } - - /** - * @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard - * @param keyboard_layout the currently used (underlying) keyboard Layout - * @param all_vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param deadkey deadkey character - * @param shift_dk shiftstate of the deadkey - * @param OutputPairs ptr to array of deadkeys - * @return size of array of deadkeys - */ - /** _S2 TODO thids is from linux: +/** * @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard - * @param deadkey deadkey character - * @param [out] OutputPairs pointer to array of [usvk, ch_out] pairs - * @param keymap pointer to the currently used (underlying) keyboard Layout - * @param dk_Table shiftstate of the deadkey - * @return size of array of [usvk, ch_out] pairs + * @param keyboard_layout the currently used (underlying) keyboard Layout + * @param all_vector Vector that holds the data of the US keyboard and the currently used (under lying) keyboard + * @param deadkey deadkey character + * @param shift_dk shiftstate of the deadkey + * @param [out] outputPairs pointer to array of [usvk, ch_out] pairs + * @return size of array of [usvk, ch_out] pairs */ -int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* OutputPairs) { +int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* outputPairs) { UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; @@ -594,23 +589,31 @@ int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D& OSStatus status; unicodeString[0] = 0; - KMX_WORD* p = OutputPairs; + KMX_WORD* p = outputPairs; KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(all_vector, deadkey); for (int j = 0; j < sizeof(ss_mac) / sizeof(ss_mac[0]); j++) { - // we start with SPACE (keycode_spacebar=49) since all deadkeys occur in combinations with space. - // Since mcompile finds only the first occurance of a dk combination, this makes sure that we always find the dk+SPACE combinations for a deadkey. - // If there are more combinations to create a specific character they will not be found. (See comment at the beginning of mac_KMX_DoConvert()) + + /* + we start with SPACE (keycode_spacebar=49) because all deadkeys occur in combinations with space. + Since mcompile finds only the first occurance of a dk combination, this makes sure that we always find the dk+SPACE combinations for a deadkey. + If there are more combinations to create a specific character they will not be found. (See comment at the top of mac_KMX_DoConvert()) + */ for (int i = keycode_spacebar; i >= 0; i--) { status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_convert_Shiftstate_to_MacShiftstate(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); + /* + UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^' + if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 + */ if (deadkeystate != 0) { status = UCKeyTranslate(keyboard_layout, i, kUCKeyActionDown, ss_mac[j], LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); + //deadkeystate might be changed again if (deadkeystate != 0) { KMX_WORD vk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[1], 0); - // ensure to not get key combinations like ^a but only combined characters like â ( exception for ^+space) + // ensure to NOT get key combinations like ^a but only combined characters like â (exception for ^+space) if ((unicodeString[0] != deadkey) || (vk == 32)) { *p++ = vk; *p++ = ss_mac[j]; @@ -621,10 +624,10 @@ int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D& } } *p = 0; - return (p - OutputPairs); + return (p - outputPairs); } - /** @brief print (error) messages */ +/** @brief print (error) messages */ void mac_KMX_LogError(const wchar_t* fmt, ...) { WCHAR fmtbuf[256]; const wchar_t* end = L"\0"; @@ -633,7 +636,7 @@ int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D& int j = 0; va_start(vars, fmt); - vswprintf (fmtbuf, _countof(fmtbuf), fmt, vars); + vswprintf(fmtbuf, _countof(fmtbuf), fmt, vars); fmtbuf[255] = 0; do { @@ -644,8 +647,6 @@ int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D& } - - //################################################################################################################################################ //################################# Code beyond these lines needs to be included in mcompile ##################################################### //################################################################################################################################################ diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 2406b98136e..33397befb0f 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -33,8 +33,6 @@ struct KMX_DeadkeyMapping { // I4353 extern std::vector KMX_FDeadkeys; // I4353 -PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); - /** * @brief print (error) messages * @param fmt text to print @@ -56,4 +54,4 @@ bool test_dk_write_entries_S2(KMX_WORD deadkeys[512]); void fun2(); void testmyFunctions_S2(); -#endif /*MCOMPILE_H*/ \ No newline at end of file +#endif /*MCOMPILE_H*/ diff --git a/mac/mcompile/u16.cpp b/mac/mcompile/u16.cpp index 1c931097cac..d6dce674133 100644 --- a/mac/mcompile/u16.cpp +++ b/mac/mcompile/u16.cpp @@ -1,3 +1,9 @@ +/* + * Keyman is copyright (C) SIL International. MIT License. + * + * Keyboard reading and mapping for mac + */ + #include "u16.h" #include #include @@ -8,9 +14,9 @@ std::vector convert_argv_to_Vector_u16str(int argc, char* argv[] std::vector vector_u16; // for each arg convert to u16string and push to vector - for (char **arg = argv, i = 0; *arg; ++arg, i++) { - std::string S(*arg); - vector_u16.push_back(u16string_from_string(S)); + for (char** arg = argv, i = 0; *arg; ++arg, i++) { + std::string s(*arg); + vector_u16.push_back(u16string_from_string(s)); } return vector_u16; } @@ -19,7 +25,7 @@ std::vector convert_argvW_to_Vector_u16str(int argc, wchar_t* ar std::vector vector_u16; // for each arg convert to u16string and push to vector - for (wchar_t **arg = argv, i = 0; *arg; ++arg, i++) { + for (wchar_t** arg = argv, i = 0; *arg; ++arg, i++) { std::wstring S(*arg); vector_u16.push_back(u16string_from_wstring(S)); } @@ -83,10 +89,10 @@ void u16sprintf(KMX_WCHAR* dst, const size_t max_len, const wchar_t* fmt, ...) { delete[] wbuf; } -std::wstring convert_pchar16T_To_wstr(KMX_WCHAR* Name) { +std::wstring convert_pchar16T_To_wstr(KMX_WCHAR* name) { // convert char16_t* -> std::u16string -> std::string -> std::wstring // char16_t* -> std::u16string - std::u16string u16str(Name); + std::u16string u16str(name); // std::u16string -> std::string std::string stri = string_from_u16string(u16str); // std::string -> std::wstring @@ -117,20 +123,20 @@ const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { return o; } -const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name) { +const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* name) { const KMX_WCHAR* cp = NULL; - cp = u16rchr(Name, '\\'); + cp = u16rchr(name, '\\'); if (cp == NULL) - cp = u16rchr(Name, '/'); + cp = u16rchr(name, '/'); return cp; } /* -KMX_CHAR* strrchr_slash(KMX_CHAR* Name) +KMX_CHAR* strrchr_slash(KMX_CHAR* name) { KMX_CHAR* cp = NULL; - cp = strrchr(Name, '\\'); + cp = strrchr(name, '\\'); if (cp == NULL) - cp = strrchr(Name, '/'); + cp = strrchr(name, '/'); return cp; } */ diff --git a/mac/mcompile/u16.h b/mac/mcompile/u16.h index 644974fb064..70d6d947685 100644 --- a/mac/mcompile/u16.h +++ b/mac/mcompile/u16.h @@ -21,7 +21,7 @@ std::string string_from_u16string(std::u16string const str); void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...); -std::wstring convert_pchar16T_To_wstr(KMX_WCHAR* Name); +std::wstring convert_pchar16T_To_wstr(KMX_WCHAR* name); size_t u16len(const KMX_WCHAR* p); int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q); @@ -38,7 +38,7 @@ KMX_WCHAR* u16tok(KMX_WCHAR* p, KMX_WCHAR* ch, KMX_WCHAR** ctx); long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base); double u16tof(KMX_WCHAR* str); -KMX_CHAR* strrchr_slash(KMX_CHAR* Name); -const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name); +KMX_CHAR* strrchr_slash(KMX_CHAR* name); +const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* name); #endif /* U16_H */ From a9479927c336d4a06a0b8ed12c799aa5e08f54c2 Mon Sep 17 00:00:00 2001 From: Sabine Date: Tue, 16 Jul 2024 10:50:02 +0200 Subject: [PATCH 38/71] feat(mac): still layout stuff --- mac/mcompile/keymap.cpp | 27 ++++++++++----------------- mac/mcompile/keymap.h | 11 ++++------- mac/mcompile/km_types.h | 1 - mac/mcompile/mc_import_rules.cpp | 22 +++++++++------------- mac/mcompile/mc_import_rules.h | 1 - mac/mcompile/mc_kmxfile.cpp | 13 ++++++------- mac/mcompile/mc_kmxfile.h | 2 +- mac/mcompile/mcompile.cpp | 12 +++++------- 8 files changed, 35 insertions(+), 54 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index c439211eafe..c5cb0cb9f44 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -15,9 +15,9 @@ /** @brief map a shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on the mac */ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) { - if (shiftState == 0) return MAC_BASE; // Win ss 0 -> mac ss 0 - else if (shiftState == K_SHIFTFLAG) return MAC_SHIFT; // Win ss 16 -> mac ss 2 - else if (shiftState == (LCTRLFLAG | RALTFLAG)) return MAC_OPT; // Win ss 9 -> mac ss 8 + if (shiftState == 0) return MAC_BASE; // Win ss 0 -> mac ss 0 + else if (shiftState == K_SHIFTFLAG) return MAC_SHIFT; // Win ss 16 -> mac ss 2 + else if (shiftState == (LCTRLFLAG | RALTFLAG)) return MAC_OPT; // Win ss 9 -> mac ss 8 else if (shiftState == (K_SHIFTFLAG | LCTRLFLAG | RALTFLAG)) return MAC_SHIFT_OPT; // Win ss 25 -> mac ss 10 else return shiftState; // Win ss x -> mac ss x } @@ -170,7 +170,6 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^' if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 */ - status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); // If this was a deadkey (deadkeystate != 0), append a space if (deadkeystate != 0) @@ -182,8 +181,6 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou else { return unicodeString[0]; // combined char e.g. â } - - return 0; } /** @brief return the keyvalue for a given Keycode, shiftstate and caps */ @@ -196,13 +193,12 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la OSStatus status; if (!ensureValidInputForKeyboardTranslation(shiftstate_mac, keycode)) - return 0; + return 0; /* UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^' if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 */ - status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); // If this was a deadkey,append a space @@ -224,7 +220,7 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa int caps = 0; if (!ensureValidInputForKeyboardTranslation(mac_convert_Shiftstate_to_MacShiftstate(vk_ShiftState), kc_underlying)) - return 0; + return 0; keyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, kc_underlying, (mac_convert_Shiftstate_to_MacShiftstate(vk_ShiftState)), caps, isdk); @@ -265,14 +261,12 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_ /** @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) { - // first get the keyvalue of the key on the US keyboard (kc_us) - std::u16string u16str = std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_win), caps)); + // first get the keyvalue kv of the key on the US keyboard (kc_us) KMX_DWORD kv = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_win), caps); - //_S2 + // then find the same keyvalue on the underlying keyboard and return the keycode of that key on the underlying keyboard for (int i = 0; i < (int)all_vector[1].size() - 1; i++) { for (int j = 1; j < (int)all_vector[1][0].size(); j++) { - //if (all_vector[1][i][j] == (KMX_DWORD)*u16str.c_str()) if (all_vector[1][i][j] == kv) return all_vector[1][i][0]; } @@ -281,9 +275,9 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* k } /** @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard */ -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us) { +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD virtualKeyUS) { // on the mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an 'artificial' us virtual key - return (mac_USVirtualKeyToScanCode[vk_us]); + return (mac_USVirtualKeyToScanCode[virtualKeyUS]); } /** @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard */ @@ -306,12 +300,11 @@ KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a base character (vk_us) to get the combined dk e.g.'Â' if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 */ - status = UCKeyTranslate(keyboard_layout, vk_dk, kUCKeyActionDown, ss_dk, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); // If this was a deadkey, append a character if (deadkeystate != 0) { - status = UCKeyTranslate(keyboard_layout, vk_us, kUCKeyActionDown, shiftstate_mac + 4 * caps, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); + status = UCKeyTranslate(keyboard_layout, vk_us, kUCKeyActionDown, shiftstate_mac + 4 * caps, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); if (unicodeString[0] == 1) // impossible character return 0; diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index a53f50b59a8..afa6b47f847 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -2,7 +2,6 @@ #ifndef KEYMAP_H #define KEYMAP_H - #include #include #include @@ -49,7 +48,6 @@ const KMX_DWORD KMX_VKMap[] = { VK_xDF, /* ß (?) 223*/ VK_OEM_102, /* < > | 226 */ - 0}; typedef std::vector vec_string_1D; @@ -90,7 +88,7 @@ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState); int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState); /** - * @brief check for correct input parameters that will later be used in UCKeyTranslate() + * @brief check for correct input parameter that will later be used in UCKeyTranslate() * @param shiftstate the currently used shiftstate * @param keycode the code of the key in question * @return true if all parameters are OK; false if not @@ -98,7 +96,7 @@ int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState); bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode); /** - * @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard + * @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard * all_vector [ US_Keyboard ] * [KeyCode_US ] * [Keyval unshifted ] @@ -612,14 +610,13 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_ */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps); - /** * @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard * "Where on an underlying keyboard do we find a character of a US keyboard?" - * @param vk_us a virtual key of the US keyboard + * @param virtualKeyUS a virtual key of the US keyboard * @return the keycode of the currently used (underlying) keyboard */ -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us); +KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD virtualKeyUS); /** * @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard diff --git a/mac/mcompile/km_types.h b/mac/mcompile/km_types.h index 89a806adce6..5381ff1e6a4 100644 --- a/mac/mcompile/km_types.h +++ b/mac/mcompile/km_types.h @@ -11,7 +11,6 @@ #endif */ - #if defined(__LP64__) || defined(_LP64) /* 64-bit, g++ */ #define KMX_64BIT diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 8b5c4f9d4c1..f9cb946c9cd 100644 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -4,7 +4,6 @@ * Mnemonic layout support for mac */ - #include #include #include @@ -52,17 +51,16 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { //_S2 remove! bool test_alDead_S2(std::vector ald); - /** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. */ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, ShiftState ss_rgkey, int caps, const UCKeyboardLayout* keyboard_layout) { KMX_DWORD keyval; UInt32 isdk = 0; - if (!ensureValidInputForKeyboardTranslation(mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_rgkey),keycode)) + if (!ensureValidInputForKeyboardTranslation(mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_rgkey), keycode)) return 0; keyval = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_rgkey), caps, isdk); - std::u16string str =std::u16string(1, keyval ); + std::u16string str = std::u16string(1, keyval); KMX_WCHAR firstchar = *(PKMX_WCHAR)str.c_str(); if ((firstchar >= 0xD800) && (firstchar <= 0xDFFF)) { @@ -236,7 +234,7 @@ class mac_KMX_VirtualKey { } /** @brief edit the row of kmx-file */ - bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector*deadkeys, int deadkeyBase, BOOL bDeadkeyConversion, vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { // I4552 + bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector* deadkeys, int deadkeyBase, BOOL bDeadkeyConversion, vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { // I4552 // Get the CAPSLOCK value /*int capslock = (this->mac_KMX_IsCapsEqualToShift() ? 1 : 0) | @@ -318,7 +316,6 @@ class mac_KMX_VirtualKey { } return true; } - }; /** @brief Base class for KMX_loader*/ @@ -376,9 +373,8 @@ class mac_KMX_Loader { continue; // push only for if combchar is not dk or combchar is dk with space - if ((!(combchar== keyval_underlying_dk)) || (basechar == mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode_spacebar, ss_mac[j], caps))) { + if ((!(combchar == keyval_underlying_dk)) || (basechar == mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, keycode_spacebar, ss_mac[j], caps))) { deadKey->KMX_AddDeadKeyRow(basechar, combchar); - //printf( " processed basechar %i(%c) with dk %i(%c) ===> combchar%i(%c) \t\t ss[%i](%i) caps%i \n", basechar,basechar ,keyval_underlying_dk,keyval_underlying_dk, combchar,combchar, j, ss[j], caps ); } } } @@ -427,10 +423,10 @@ void test_print_All_Entries_S2(std::vector rgKey); * @param bDeadkeyConversion 1 to convert a deadkey to a character; 0 no conversion * @return true in case of success */ -bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKeyboardLayout** keyboard_layout, std::vector* FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 +bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKeyboardLayout** keyboard_layout, std::vector* FDeadkeys, KMX_BOOL bDeadkeyConversion) { // I4353 // I4327 mac_KMX_Loader loader; - std::vector rgKey; //= new VirtualKey[256]; + std::vector rgKey; //= new VirtualKey[256]; std::vector alDead; rgKey.resize(256); @@ -439,7 +435,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK // values in it. Then, store the SC in each valid VK so it can act as both a // flag that the VK is valid, and it can store the SC value. - //Windows and Linux Keycodes start with 1; Mac keycodes start with 0 + // Windows and Linux Keycodes start with 1; Mac keycodes start with 0 for (UINT sc = 0x00; sc <= 0x7f; sc++) { /* HERE IS A BIG DIFFERENCE COMPARED TO MCOMPILE FOR WINDOWS: * mcompile on Windows fills rgkey.m_vk with the VK of the Underlying keyboard @@ -448,7 +444,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK * macOS cannot get a VK for the underling Keyboard since this does not exist * macOS can only get a VK for the US Keyboard (by using USVirtualKeyToScanCode/ScanCodeToUSVirtualKey) - * therefore in rgkey[ ] we use VK_US which we get from all_vector + * therefore we use VK_US in rgkey[ ] which we get from all_vector */ mac_KMX_VirtualKey* key = new mac_KMX_VirtualKey(sc); @@ -491,7 +487,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK } } else if (rc < 0) { sbBuffer[2] = 0; - rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps )); // different to windows since behavior on the mac is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps)); // different to windows since behavior on the mac is different sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps == 0)); diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h index a108acbc4ed..32e88b6217c 100644 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -46,7 +46,6 @@ class DeadKey { */ void KMX_AddDeadKeyRow(KMX_WCHAR baseCharacter, KMX_WCHAR combinedCharacter); - /** @brief return size of array of basecharacters */ int KMX_Count() { return this->m_rgbasechar.size(); diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index 0c5b6136801..54c1f377ff0 100644 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -98,8 +98,8 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX size += (u16len(fkp->dpContext) + 1) * sizeof(KMX_WCHAR); } - if (fgp->dpMatch) size += (u16len(fgp->dpMatch) + 1) * sizeof(KMX_WCHAR); - if (fgp->dpNoMatch) size += (u16len(fgp->dpNoMatch) + 1) * sizeof(KMX_WCHAR); + if (fgp->dpMatch)size += (u16len(fgp->dpMatch) + 1) * sizeof(KMX_WCHAR); + if (fgp->dpNoMatch)size += (u16len(fgp->dpNoMatch) + 1) * sizeof(KMX_WCHAR); } for (i = 0; i < fk->cxStoreArray; i++) { @@ -109,10 +109,11 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX } buf = new KMX_BYTE[size]; - if (!buf) return CERR_CannotAllocateMemory; + if (!buf) + return CERR_CannotAllocateMemory; memset(buf, 0, size); - ck = (PKMX_COMP_KEYBOARD) buf; + ck = (PKMX_COMP_KEYBOARD)buf; ck->dwIdentifier = FILEID_COMPILED; @@ -227,7 +228,6 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX /** @brief save keyboard to file */ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName) { - FILE* fp; fp = Open_File(fileName, "wb"); @@ -448,7 +448,6 @@ KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) { fclose(fp); return FALSE; } -// delete??? _S2 fclose(fp); if (*((PKMX_DWORD)filebase) != (KMX_DWORD)FILEID_COMPILED) { @@ -477,7 +476,7 @@ KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) { if (kbp->dwIdentifier != FILEID_COMPILED) { delete[] buf; - mac_KMX_LogError(L"errNotFileID\n" ); + mac_KMX_LogError(L"errNotFileID\n"); return FALSE; } *lpKeyboard = kbp; diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index b4ab675bbc4..7f57f602dcb 100644 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -74,7 +74,7 @@ typedef struct KMX_tagKEYBOARD { * @param [in,out] lpKeyboard pointer to pointer to keyboard * @return TRUE on success; else FALSE */ -KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) ; +KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard); /** * @brief save keyboard to file diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index dcc96dde55b..ecaef7ddce7 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -14,7 +14,6 @@ #include "mcompile.h" #include "u16.h" - /** * @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard * @param kbd pointer to US keyboard @@ -48,7 +47,7 @@ int mac_run(int argc, char* argv[]); */ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* outputPairs); // returns array of [usvk, ch_out] pairs -std::vector KMX_FDeadkeys; // I4353 +std::vector KMX_FDeadkeys; // I4353 #define _countof(a) (sizeof(a) / sizeof(*(a))) @@ -82,7 +81,7 @@ int mac_run(int argc, char* argv[]) { int n = (bDeadkeyConversion ? 2 : 1); - if (argc < 3 || argc > 4 || (argc - n) != 2) { // I4273// I4273 + if (argc < 3 || argc > 4 || (argc - n) != 2) { // I4273// I4273 printf( "Usage: \tmcompile [-d] infile.kmx outfile.kmx\n" " \tmcompile -u ... (not available for mac)\n " @@ -132,7 +131,7 @@ int mac_run(int argc, char* argv[]) { } #if defined(_WIN32) || defined(_WIN64) // Windows - if (DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F + if (DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); } @@ -510,8 +509,7 @@ KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { /** @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard */ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc) { - - KMX_WCHAR DeadKey=0; + KMX_WCHAR DeadKey = 0; if (!mac_KMX_SetKeyboardToPositional(kbd)) return FALSE; @@ -580,7 +578,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int * @param [out] outputPairs pointer to array of [usvk, ch_out] pairs * @return size of array of [usvk, ch_out] pairs */ -int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* outputPairs) { +int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* outputPairs) { UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; From f71c4aa0dedb49fb45d7692386df34900673aa30 Mon Sep 17 00:00:00 2001 From: Sabine Date: Thu, 18 Jul 2024 17:50:18 +0200 Subject: [PATCH 39/71] feat(mac): little edit --- mac/mcompile/keymap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 2572b944412..726fff1df2a 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -3,7 +3,7 @@ #ifndef KEYMAP_H #define KEYMAP_H -// compile with. gcc -framework Carbon -o xxx.exe yy.cpp +// compile with gcc -framework Carbon -o xxx.exe yy.cpp // #import #include From e545402ab50fb0046fbc5ccb3c0c4f597d9cfa80 Mon Sep 17 00:00:00 2001 From: Sabine Date: Thu, 18 Jul 2024 19:33:58 +0200 Subject: [PATCH 40/71] feat(mac): resolve conflicts --- mac/mcompile/keymap.cpp | 7 ------- mac/mcompile/mcompile.cpp | 3 ++- mac/mcompile/util_filesystem.cpp | 0 mac/mcompile/util_filesystem.h | 16 ---------------- 4 files changed, 2 insertions(+), 24 deletions(-) delete mode 100755 mac/mcompile/util_filesystem.cpp delete mode 100755 mac/mcompile/util_filesystem.h diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 6d1f29f0a38..c5cb0cb9f44 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -233,9 +233,6 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa *deadKey = 0; return keyV; } -//--------------------------------------------------- -// _S2 checked OK -KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(v_dw_3D & All_Vector, KMX_DWORD kv_us) { /** @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard */ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us) { @@ -248,8 +245,6 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, K } return kv_us; } -// _S2 checked OK -KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(v_dw_3D & All_Vector, KMX_DWORD kv_underlying) { /** @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying) { @@ -263,8 +258,6 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_ } return kv_underlying; } -// _S2 checked OK -KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_DWORD kc_us, ShiftState ss, int caps) { /** @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) { diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 3da001adbb9..ecaef7ddce7 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -568,7 +568,6 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int } return TRUE; } -int mac_KMX_GetDeadkeys( const UCKeyboardLayout * keyboard_layout, v_dw_3D &All_Vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD *OutputPairs ) { /** * @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard @@ -703,6 +702,7 @@ bool moreval=false; else ss_rgkey= 999; if ( (ss==1) || (ss==3) || (ss==5) || (ss==7) || (ss==9) ) continue; + int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, ss, caps); count++; @@ -734,6 +734,7 @@ bool print_character_of_key_S2(const UCKeyboardLayout * keyboard_layout, int key int ss_rgkey; for ( int ss=0; ss< 6;ss++) { for ( int caps=0; caps< 2;caps++) { + int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, 2*ss, caps); printf( " key %i has values : %i (%c) ( ss:%i, caps:%i) \n", key, keyvalsearch,keyvalsearch, 2*ss, caps); } diff --git a/mac/mcompile/util_filesystem.cpp b/mac/mcompile/util_filesystem.cpp deleted file mode 100755 index e69de29bb2d..00000000000 diff --git a/mac/mcompile/util_filesystem.h b/mac/mcompile/util_filesystem.h deleted file mode 100755 index 38877bf9f26..00000000000 --- a/mac/mcompile/util_filesystem.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -//#include _S2 "../src/kmx_u16.h" we want to include this... -#include "u16.h" - -// Opens files on windows and non-windows platforms. Datatypes for Filename and mode must be the same. -// returns FILE* if file could be opened; FILE needs to be closed in calling function -FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); -FILE* Open_File(const KMX_WCHART* Filename, const KMX_WCHART* mode); -FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode); -KMX_BOOL kmcmp_FileExists(const KMX_CHAR *filename); -KMX_BOOL kmcmp_FileExists(const KMX_WCHAR *filename); - -bool IsRelativePath(KMX_CHAR const * p); -bool IsRelativePath(KMX_WCHAR const * p); \ No newline at end of file From 06d078336ba277d79ea6a9a39016dc0663e8258e Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 19 Jul 2024 11:21:34 +0200 Subject: [PATCH 41/71] feat(mac): remove all _S2 --- mac/mcompile/keymap.cpp | 23 +-- mac/mcompile/keymap.h | 25 +-- mac/mcompile/kmx_file.h | 5 +- mac/mcompile/mc_import_rules.cpp | 289 +------------------------------ mac/mcompile/mc_import_rules.h | 4 +- mac/mcompile/mc_kmxfile.h | 49 +++--- mac/mcompile/mcompile.cpp | 159 ++--------------- mac/mcompile/mcompile.h | 14 -- mac/mcompile/u16.cpp | 4 +- mac/mcompile/u16.h | 1 - 10 files changed, 61 insertions(+), 512 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index c5cb0cb9f44..9abcf1c72a3 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -4,8 +4,8 @@ * Mnemonic layout support for mac * * Throughout mcompile we use the following naming conventions: - * KEYCODE: The physical position of a key on a keyboard e.g. Keycode for 'Z' on US: 6 on Mac | 52 on Linux/x11 | 44 on Windows - * SCANCODE (naming on windows): The physical position of a key on a keyboard e.g. Keycode for 'Z' on US: 44 on Windows + * KEYCODE: (name on Linux, Mac):The physical position of a key on a keyboard e.g. Keycode for 'Z' on US: 6 on Mac | 52 on Linux/x11 | 44 on Windows + * SCANCODE (name on Windows): The physical position of a key on a keyboard e.g. Keycode for 'Z' on US: 44 on Windows * VIRTUAL KEY: The value of a character on a key e.g. 'A' = 65; 'a' = 97 - not neccessarily the same as ACSII- exists on a Windows keyboard only * KEYVAL(UE): The value of a character on a key e.g. 'A' = 65; 'a' = 97 - not neccessarily the same as ACSII */ @@ -13,7 +13,7 @@ #include "keymap.h" #include "kmx_file.h" -/** @brief map a shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on the mac */ +/** @brief map a shiftstate used on Windows to a shiftstate suitable for UCKeyTranslate() on the mac */ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) { if (shiftState == 0) return MAC_BASE; // Win ss 0 -> mac ss 0 else if (shiftState == K_SHIFTFLAG) return MAC_SHIFT; // Win ss 16 -> mac ss 2 @@ -31,7 +31,6 @@ int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState) { else return rgkey_ShiftState; } -// _S2 todo missing code /** @brief check for correct input parameter that will later be used in UCKeyTranslate() */ bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode) { if ((shiftstate > max_shiftstate)) @@ -313,19 +312,3 @@ KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, } else return 0; } - - -//################################################################################################################################################ -//################################################################################################################################################ - - -void test_printoutKeyboards_S2(vec_dword_3D& all_vector) { - printf(" values of US - Values of underlying"); - for ( int i=0; i< all_vector[0].size(); i++) { - printf("-----------------------------\n"); - for ( int j=0; j< all_vector[0][0].size(); j++) { - printf("i:%i\tUS: %i(%c)\t Underlying: %i(%c)\t \t\t\t%c \n", i,all_vector[0][i][j] , all_vector[0][i][j] , all_vector[1][i][j],all_vector[1][i][j],(all_vector[0][i][j] == all_vector[1][i][j]) ? '.' : '*'); - } - } -} - diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index afa6b47f847..cb3605bd56f 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -66,13 +66,13 @@ static int MAC_OPT = 8; static int MAC_SHIFT_OPT = 10; /** - * @brief map a shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on the mac + * @brief map a shiftstate used on Windows to a shiftstate suitable for UCKeyTranslate() on the mac * Windows: (Base: 00000000 (0); Shift 00010000 (16); AltGr 00001001 (9); Shift+AltGr 00011001 (25)) * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10 ) - * @param shiftState shiftstate used on windows + * @param shiftState shiftstate used on Windows * @return a shiftstate usable for UCKeyTranslate() on mac if available - * if shiftState is a windows ShiftState: convert the windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) - * if shiftState is NOT a windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate + * if shiftState is a Windows ShiftState: convert the Windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) + * if shiftState is NOT a Windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate */ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState); @@ -82,8 +82,8 @@ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState); * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10) * @param rgkey_ShiftState shiftstate used in rgkey * @return a shiftstate usable for UCKeyTranslate() on mac if available - * if shiftState is a windows ShiftState: convert the windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) - * if shiftState is NOT a windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate + * if shiftState is a Windows ShiftState: convert the Windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) + * if shiftState is NOT a Windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate */ int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState); @@ -604,7 +604,7 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_ * @param keyboard_layout the currently used (underlying) keyboard layout * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param kc_us a key of the US keyboard - * @param ss_win a windows-type shiftstate + * @param ss_win a Windows-type shiftstate * @param caps state of the caps key * @return the keycode of the underlying keyboard if found; else the keycode of the US keyboard */ @@ -639,15 +639,4 @@ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); */ KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, int vk_dk, KMX_DWORD ss_dk, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps); -//_S2 TODO CodePointToU16String?? -//################################################################################################################################################ -//################################################################################################################################################ - -void test_printoutKeyboards_S2(vec_dword_3D &all_vector); -KMX_DWORD X_playWithDK_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal) ; -KMX_DWORD X_playWithDK_S2_one(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal); -KMX_DWORD X_compare_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); -KMX_DWORD X_find_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0); -KMX_DWORD printout_dk(const UCKeyboardLayout* keyboard_layout); - #endif /*KEYMAP_H*/ \ No newline at end of file diff --git a/mac/mcompile/kmx_file.h b/mac/mcompile/kmx_file.h index 3901d119e23..b254eb99afe 100644 --- a/mac/mcompile/kmx_file.h +++ b/mac/mcompile/kmx_file.h @@ -8,8 +8,8 @@ Authors: mcdurdin */ -#define UNREFERENCED_PARAMETER(P) (P) -#define TRUNCATE ((size_t)-1) +#define UNREFERENCED_PARAMETER(P) (P) +#define TRUNCATE ((size_t) - 1) #ifdef KMN_KBP // TODO: move this to a common namespace keyman::common::kmx_file or similar in the future namespace km { @@ -312,7 +312,6 @@ struct KMX_COMP_KEY { KMX_DWORD dpContext; }; - struct KMX_COMP_GROUP { KMX_DWORD dpName; KMX_DWORD dpKeyArray; // [LPKEY] address of first item in key array diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index f9cb946c9cd..de39868dad8 100644 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -48,8 +48,6 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { } return false; } -//_S2 remove! -bool test_alDead_S2(std::vector ald); /** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. */ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, ShiftState ss_rgkey, int caps, const UCKeyboardLayout* keyboard_layout) { @@ -81,7 +79,7 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, ShiftState ss_rgkey, i return 1; } -KMX_WCHAR mac_KMX_DeadKeyMap(int index, std::vector*deadkeys, int deadkeyBase, std::vector*deadkeyMappings) { // I4327 // I4353 +KMX_WCHAR mac_KMX_DeadKeyMap(int index, std::vector*deadkeys, int deadkeyBase, std::vector*deadkeyMappings) { // I4327 // I4353 for (size_t i = 0; i < deadkeyMappings->size(); i++) { if ((*deadkeyMappings)[i].deadkey == index) { return (*deadkeyMappings)[i].dkid; @@ -262,7 +260,7 @@ class mac_KMX_VirtualKey { *key->dpContext = 0; key->ShiftFlags = this->KMX_GetShiftStateValue(capslock, caps, (ShiftState)ss); - // we already use VK_US so no need to convert it as we do on windows + // we already use VK_US so no need to convert it as we do on Windows key->Key = this->VK(); key->Line = 0; @@ -289,7 +287,7 @@ class mac_KMX_VirtualKey { } if (isvalid) { /* - * this is different to mcompile windows !!!! + * this is different to mcompile Windows !!!! * this->m_sc stores SC-US = SCUnderlying * this->m_vk stores VK-US ( not underlying !!) * key->Key stores VK-US ( not underlying !!) @@ -357,7 +355,7 @@ class mac_KMX_Loader { DeadKey* deadKey = new DeadKey(rgKey[iKeyDead]->mac_KMX_GetShiftState(shiftStateDead, fCapsLock)[0]); int ss_dead = mac_convert_rgkey_Shiftstate_to_MacShiftstate(shiftStateDead); - KMX_DWORD keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead], ss_dead, 0); + KMX_DWORD keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead], ss_dead, 0); for (int i = 0; i < keycode_spacebar + 1; i++) { for (int j = 0; j <= max_shiftstate_pos; j++) { @@ -398,21 +396,10 @@ int mac_KMX_GetMaxDeadkeyIndex(KMX_WCHAR* p) { return n; } -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - - -bool test_run_verify_S2(std::vector rgKey); -// _S2 need to go -void test_print_All_Entries_S2(std::vector rgKey); -//void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout); -//void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode); - /** * @brief Collect the key data, translate it to kmx and append to the existing keyboard * It is important to understand that this function has different sorting order in rgkey compared to mcompile-windows! - * On windows the values of rgkey are sorted according to the VK of the underlying keyboard + * On Windows the values of rgkey are sorted according to the VK of the underlying keyboard * On Linux the values of rgkey are sorted according to the VK of the the US keyboard * Since Linux Keyboards do not use a VK mcompile uses the VK of the the US keyboard because * these are available in mcompile through USVirtualKeyToScanCode/ScanCodeToUSVirtualKey and an offset of 8 @@ -465,11 +452,6 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe continue; } - //_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! - /*if (ss == MenuCtrl || ss == ShftMenuCtrl) { - continue; - }*/ - KMX_DWORD kc_underlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); for (int caps = 0; caps <= 1; caps++) { @@ -477,17 +459,17 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe if (rc > 0) { if (*sbBuffer == 0) { - rgKey[iKey]->mac_KMX_SetShiftState(ss, u"", false, (caps)); // different to windows since behavior on the mac is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, u"", false, (caps)); // different to Windows since behavior on the mac is different } else { if ((ss == Ctrl || ss == ShftCtrl)) { continue; } sbBuffer[rc] = 0; - rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to windows since behavior on the mac is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, false, (caps)); // different to Windows since behavior on the mac is different } } else if (rc < 0) { sbBuffer[2] = 0; - rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps)); // different to windows since behavior on the mac is different + rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps)); // different to Windows since behavior on the mac is different sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps == 0)); @@ -513,21 +495,8 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe // translate it to kmx and append to the existing keyboard //------------------------------------------------------------- - // _S2 all of my tests need to go ............ - //test_print_All_Entries_S2(rgKey); - //test_print_All_Keys_S2( * keyboard_layout); - //test_print_certain_Keys_S2( * keyboard_layout, 14); - //bool allOK =test_alDead_S2(alDead); - bool allOK=true; - if ( ! allOK ) - printf(" \n::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG DEADKEYS :::::::::::::::::::::::::::::::::::::::::::::::::: \n"); - if ( ! test_run_verify_S2(rgKey)) - printf(" \n::::::::::::::::::::::::::::::::::::::::::::::::::: THERE ARE SOME WRONG ENTRIES ::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); - if ( test_run_verify_S2(rgKey) && allOK) - printf("\n ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :) :) :) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: \n"); - int nDeadkey = 0; - LPKMX_GROUP gp = new KMX_GROUP[kp->cxGroupArray+4]; // leave space for old + LPKMX_GROUP gp = new KMX_GROUP[kp->cxGroupArray + 4]; // leave space for old memcpy(gp, kp->dpGroupArray, sizeof(KMX_GROUP) * kp->cxGroupArray); // @@ -693,243 +662,3 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe } return true; } -// _S2 need to go - -void print_entries_S2(int i, std::vector rgKey , std::string comp1,std::string comp2,std::string erg) { - std::string b0 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 0 )); - std::string b1 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 1 )); - std::string s0 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Shft, 0 )); - std::string s1 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Shft, 1 )); - printf("\n entry nr %i has characters %-30s:(%s|%s|%s|%s)",i, erg.c_str(), (const char * ) b0.c_str(),(const char * ) b1.c_str(),(const char * ) s0.c_str(),(const char * ) s1.c_str()); -} -bool verify_entries_S2(int i, std::vector rgKey, int res1,int res2,int res3,int res4 ,int res5=0, int res6=0, int res7=0, int res8=0 ) { - std::vector st_vec; - std::vector r_vec; - bool all_OK=true;; - - r_vec.push_back(res1); r_vec.push_back(res2); - r_vec.push_back(res3); r_vec.push_back(res4); - r_vec.push_back(res5); r_vec.push_back(res6); - r_vec.push_back(res7); r_vec.push_back(res8); - - st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(Base,0)); - st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(Base,1)); - st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(Shft,0)); - st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(Shft,1)); - st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(MenuCtrl,0)); - st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(MenuCtrl,1)); - st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(ShftMenuCtrl,0)); - st_vec.push_back(rgKey[i]->mac_KMX_GetShiftState(ShftMenuCtrl,1)); - - for ( int k=0; k< st_vec.size();k++) - if (r_vec[k] !=0 ) all_OK = ( *st_vec[k].c_str() == r_vec[k] ) && all_OK; - - if ( !all_OK) - printf(" ERROR FOR i= Nr:%i, %i(%c) - %i (%c) - %i (%c) - %i (%c) \n",i, *st_vec[0].c_str(),*st_vec[1].c_str(),*st_vec[2].c_str(),*st_vec[3].c_str(),*st_vec[4].c_str(),*st_vec[5].c_str(),*st_vec[6].c_str(),*st_vec[7].c_str()); - return all_OK; -} -void test_print_All_Entries_S2( std::vector rgKey) { - for ( int i=48; i<58; i++) - print_entries_S2(i, rgKey," ","",""); - - for ( int i=65; i<91; i++) - print_entries_S2(i, rgKey, " ","", "" ); - - print_entries_S2(186, rgKey, "ö", "Ö", "xc3 xb6"); - print_entries_S2(187, rgKey, "´", ";", "´ ´ ` `"); - print_entries_S2(188, rgKey, ".", ":", ", , ; ;"); - print_entries_S2(189, rgKey, "ß", "?", "ß ß ? ?"); - print_entries_S2(190, rgKey, ".", ":", ". . : :"); - print_entries_S2(191, rgKey, "-", "_", "- - _ _"); - print_entries_S2(192, rgKey, "^", "°", "^ ^ ° °"); - - print_entries_S2(219, rgKey, "ü", "Ü", "ü,Ü;Ü;Ü"); - print_entries_S2(220, rgKey, "#", "'", "# # ' '"); - print_entries_S2(221, rgKey, "+", "*", "+ + * *"); - print_entries_S2(222, rgKey, "ä", "Ä", "ä Ä Ä Ä"); - print_entries_S2(226, rgKey, "<", ">", "< < > >"); -} -/*void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode) { - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - UInt32 deadkeystate = 0; - OSStatus status; - unicodeString[0]=0; - //int shiftarray[] ={0,2,8,10}; - int shiftarray[] ={0,1,2,3,4,5,6,7,8,9,10}; - for (int k=0; k<2;k++) { - for (int j=0; j<(sizeof(shiftarray)/ sizeof(int));j++) { - status = UCKeyTranslate(keyboard_layout, keycode , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - if (deadkeystate ==0) - printf(" key nr %i , ss %i has values %i(%c)\n", keycode, shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); - // If this was a deadkey, append a space - if (deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, keycode_spacebar , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - printf(" dk with caps key nr %i , ss %i has values %i(%c)\n", keycode,shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); - } - } - } -} -*/ -/*void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout){ - UniCharCount maxStringlength = 5; - UniCharCount actualStringlength = 0; - UniChar unicodeString[maxStringlength]; - UInt32 deadkeystate = 0; - OSStatus status; - unicodeString[0]=0; - int shiftarray[] ={0,2,8,10}; - - for (int k=0; k<2;k++) { - for (int j=0; j<4;j++) { - for (int i=0; i< keycode_spacebar+1 ;i++) { - status = UCKeyTranslate(keyboard_layout, i , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - if (deadkeystate ==0) - printf(" key nr %i , ss %i has values %i(%c)\n", i, shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); - // If this was a deadkey, append a space - if (deadkeystate !=0) { - status = UCKeyTranslate(keyboard_layout, keycode_spacebar , kUCKeyActionDown, (shiftarray[j]+ 4*k), LMGetKbdType(), 0, &deadkeystate, maxStringlength, &actualStringlength, unicodeString ); - printf(" dk key nr %i , ss %i has values %i(%c)\n", i,shiftarray[j]+ 4*k, unicodeString[0], unicodeString[0] ); - } - } - } - } -} -*/ -bool test_checkBasechar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) { - return ( DK->KMX_GetBaseCharacter(index) == ch) ; -} -bool test_checkCombchar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) { - return ( DK->KMX_GetCombinedCharacter(index) == ch) ; -} -bool test_alDead_S2(std::vector ald) { - bool OK =true; - - OK = OK && test_checkBasechar_S2(ald[2],0, 0x61); - OK = OK && test_checkBasechar_S2(ald[2],1, 0x41); - OK = OK && test_checkBasechar_S2(ald[2],14, 0x65); - OK = OK && test_checkBasechar_S2(ald[2],15, 0x45); - OK = OK && test_checkBasechar_S2(ald[2],23 ,0x69 ); - OK = OK && test_checkBasechar_S2(ald[2],24 ,0x49 ); - OK = OK && test_checkBasechar_S2(ald[2],19 ,0x6f ); - OK = OK && test_checkBasechar_S2(ald[2],20 ,0x4f ); - OK = OK && test_checkBasechar_S2(ald[2],21 ,0x75 ); - OK = OK && test_checkBasechar_S2(ald[2],22 ,0x55 ); - OK = OK && test_checkBasechar_S2(ald[2],27 ,0x20 ); - OK = OK && test_checkBasechar_S2(ald[2],28 ,0x20 ); - - OK = OK && test_checkCombchar_S2(ald[2],0, 0xe2); - OK = OK && test_checkCombchar_S2(ald[2],1, 0xc2); - OK = OK && test_checkCombchar_S2(ald[2],14 ,0xea); - OK = OK && test_checkCombchar_S2(ald[2],15, 0xca); - OK = OK && test_checkCombchar_S2(ald[2],23 ,0xee ); - OK = OK && test_checkCombchar_S2(ald[2],24 ,0xce ); - OK = OK && test_checkCombchar_S2(ald[2],19 ,0xf4 ); - OK = OK && test_checkCombchar_S2(ald[2],20 ,0xd4 ); - OK = OK && test_checkCombchar_S2(ald[2],21 ,0xfb ); - OK = OK && test_checkCombchar_S2(ald[2],22 ,0xdb ); - OK = OK && test_checkCombchar_S2(ald[2],27 ,0x5e ); - OK = OK && test_checkCombchar_S2(ald[2],28 ,0x5e ); - - OK = OK && test_checkBasechar_S2(ald[0],0, 0x61); - OK = OK && test_checkBasechar_S2(ald[0],1, 0x41); - OK = OK && test_checkBasechar_S2(ald[0],12, 0x65); - OK = OK && test_checkBasechar_S2(ald[0],13, 0x45); - OK = OK && test_checkBasechar_S2(ald[0],24 ,0x69 ); - OK = OK && test_checkBasechar_S2(ald[0],25 ,0x49 ); - OK = OK && test_checkBasechar_S2(ald[0],18 ,0x6f ); - OK = OK && test_checkBasechar_S2(ald[0],19 ,0x4f ); - OK = OK && test_checkBasechar_S2(ald[0],20 ,0x75 ); - OK = OK && test_checkBasechar_S2(ald[0],21 ,0x55 ); - OK = OK && test_checkBasechar_S2(ald[0],36 ,0x20 ); - OK = OK && test_checkBasechar_S2(ald[0],37 ,0x20 ); - - OK = OK && test_checkCombchar_S2(ald[0],0, 0xe2-1); - OK = OK && test_checkCombchar_S2(ald[0],1, 0xc2-1); - OK = OK && test_checkCombchar_S2(ald[0],12 ,0xea-1); - OK = OK && test_checkCombchar_S2(ald[0],13, 0xca-1); - OK = OK && test_checkCombchar_S2(ald[0],24 ,0xee -1); - OK = OK && test_checkCombchar_S2(ald[0],25 ,0xce -1); - OK = OK && test_checkCombchar_S2(ald[0],18 ,0xf4 -1); - OK = OK && test_checkCombchar_S2(ald[0],19 ,0xd4 -1); - OK = OK && test_checkCombchar_S2(ald[0],20 ,0xfb -1); - OK = OK && test_checkCombchar_S2(ald[0],21 ,0xdb -1); - OK = OK && test_checkCombchar_S2(ald[0],36 ,0xb4 ); - OK = OK && test_checkCombchar_S2(ald[0],37 ,0xb4 ); - - OK = OK && test_checkBasechar_S2(ald[1],0, 0x61); - OK = OK && test_checkBasechar_S2(ald[1],1, 0x41); - OK = OK && test_checkBasechar_S2(ald[1],6, 0x65); - OK = OK && test_checkBasechar_S2(ald[1],7, 0x45); - OK = OK && test_checkBasechar_S2(ald[1],12 ,0x69 ); - OK = OK && test_checkBasechar_S2(ald[1],13 ,0x49 ); - OK = OK && test_checkBasechar_S2(ald[1],8 ,0x6f ); - OK = OK && test_checkBasechar_S2(ald[1],9 ,0x4f ); - OK = OK && test_checkBasechar_S2(ald[1],10 ,0x75 ); - OK = OK && test_checkBasechar_S2(ald[1],11 ,0x55 ); - OK = OK && test_checkBasechar_S2(ald[1],16 ,0x20 ); - OK = OK && test_checkBasechar_S2(ald[1],17 ,0x20 ); - - OK = OK && test_checkCombchar_S2(ald[1],0, 0xe2-2); - OK = OK && test_checkCombchar_S2(ald[1],1, 0xc2-2); - OK = OK && test_checkCombchar_S2(ald[1],6 ,0xea-2); - OK = OK && test_checkCombchar_S2(ald[1],7, 0xca-2); - OK = OK && test_checkCombchar_S2(ald[1],12 ,0xee -2); - OK = OK && test_checkCombchar_S2(ald[1],13 ,0xce -2); - OK = OK && test_checkCombchar_S2(ald[1],8 ,0xf4 -2); - OK = OK && test_checkCombchar_S2(ald[1],9 ,0xd4 -2); - OK = OK && test_checkCombchar_S2(ald[1],10 ,0xfb -2); - OK = OK && test_checkCombchar_S2(ald[1],11 ,0xdb -2); - OK = OK && test_checkCombchar_S2(ald[1],16 ,0x60 ); - OK = OK && test_checkCombchar_S2(ald[1],17 ,0x60 ); -return OK; -} -bool test_run_verify_S2(std::vector rgKey) { - - bool allOK= true; - allOK = verify_entries_S2(48, rgKey, 48,48,61,61) && allOK; - allOK = verify_entries_S2(48, rgKey, 48,48,61,61) && allOK; - allOK = verify_entries_S2(49, rgKey, 49,49,33,33) && allOK; - allOK = verify_entries_S2(50, rgKey, 50,50,34,34) && allOK; - allOK = verify_entries_S2(51, rgKey, 51,51,167,167) && allOK; - allOK = verify_entries_S2(52, rgKey, 52,52,36,36) && allOK; - allOK = verify_entries_S2(53, rgKey, 53,53,37,37) && allOK; - allOK = verify_entries_S2(54, rgKey, 54,54,38,38) && allOK; - allOK = verify_entries_S2(55, rgKey, 55,55,47,47) && allOK; - allOK = verify_entries_S2(56, rgKey, 56,56,40,40) && allOK; - allOK = verify_entries_S2(57, rgKey, 57,57,41,41) && allOK; - - for ( int i=65; i<89;i++) - allOK = verify_entries_S2(i, rgKey,i+32,i,i,i) && allOK; - - allOK = verify_entries_S2(89, rgKey, 90+32,90,90,90) && allOK; - allOK = verify_entries_S2(90, rgKey, 89+32,89,89,89) && allOK; - - allOK = verify_entries_S2(186, rgKey, 246,214,214,214) && allOK; - allOK = verify_entries_S2(187, rgKey, 180,180,96,96) && allOK; // dk ´ ` - allOK = verify_entries_S2(188, rgKey, 44,44,59,59) && allOK; - allOK = verify_entries_S2(189, rgKey, 223,223,63,63) && allOK; - allOK = verify_entries_S2(190, rgKey, 46,46,58,58) && allOK; - allOK = verify_entries_S2(191, rgKey, 45,45,95,95) && allOK; - - allOK = verify_entries_S2(192, rgKey, 94,94,176,176) && allOK; // dk ^ ° - allOK = verify_entries_S2(219, rgKey, 252,220,220,220) && allOK; - allOK = verify_entries_S2(220, rgKey, 35,35,39,39) && allOK; - allOK = verify_entries_S2(221, rgKey, 43,43,42,42) && allOK; - allOK = verify_entries_S2(222, rgKey, 228,196,196,196) && allOK; - allOK = verify_entries_S2(226, rgKey, 60,60,62,62) && allOK; // < > -// ------------------------------------------- - /*allOK = verify_entries_S2(48, rgKey, 48,48,61,61,L'}',0,0,0) && allOK; - allOK = verify_entries_S2(49, rgKey, 49,49,33,33,L'’',0,0,0) && allOK; - allOK = verify_entries_S2(50, rgKey, 50,50,34,34,L'²',0,0,0) && allOK; - allOK = verify_entries_S2(51, rgKey, 51,51,167,167,L'³',0,0,0) && allOK; - allOK = verify_entries_S2(52, rgKey, 52,52,36,36,L'—',0,0,0) && allOK; - allOK = verify_entries_S2(53, rgKey, 53,53,37,37,L'¡',0,0,0) && allOK; - allOK = verify_entries_S2(54, rgKey, 54,54,38,38,L'¿',0,0,0) && allOK; - allOK = verify_entries_S2(55, rgKey, 55,55,47,47,L'{',0,0,0) && allOK; - allOK = verify_entries_S2(56, rgKey, 56,56,40,40,L'[',0,0,0) && allOK; - allOK = verify_entries_S2(57, rgKey, 57,57,41,41,L']',0,0,0) && allOK;*/ - - return allOK; -} diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h index 32e88b6217c..033aab15208 100644 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -3,13 +3,13 @@ #ifndef MC_IMPORT_RULES_H #define MC_IMPORT_RULES_H -/** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. +/** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. * Contrary to what the function name might suggest, the function the mac_KMX_ToUnicodeEx does NOT process surrogate pairs. * This is because it is used in mcompile only which only deals with latin scripts. * In case this function is used for surrogate pairs, they will be ignored and a message will be printed out * @param keycode a key of the currently used keyboard Layout * @param pwszBuff Buffer to store resulting character - * @param ss_rgkey a windows-style shiftstate of the currently used keyboard Layout + * @param ss_rgkey a Windows-style shiftstate of the currently used keyboard Layout * @param caps state of the caps key of the currently used keyboard Layout * @param keyboard_layout the currently used (underlying)keyboard Layout * @return -1 if a deadkey was found; diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index 7f57f602dcb..8946c45eee5 100644 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -15,7 +15,6 @@ typedef struct KMX_tagSTORE { PKMX_WCHAR dpString; } KMX_STORE, *LPKMX_STORE; - typedef struct KMX_tagKEY { KMX_WCHAR Key; KMX_DWORD Line; @@ -24,47 +23,45 @@ typedef struct KMX_tagKEY { PKMX_WCHAR dpContext; } KMX_KEY, *LPKMX_KEY; - typedef struct KMX_tagGROUP { KMX_WCHAR* dpName; - LPKMX_KEY dpKeyArray; // [LPKEY] address of first item in key array + LPKMX_KEY dpKeyArray; // [LPKEY] address of first item in key array PKMX_WCHAR dpMatch; PKMX_WCHAR dpNoMatch; - KMX_DWORD cxKeyArray; // in array entries - int32_t fUsingKeys; // group(xx) [using keys] <-- specified or not + KMX_DWORD cxKeyArray; // in array entries + int32_t fUsingKeys; // group(xx) [using keys] <-- specified or not } KMX_GROUP, *LPKMX_GROUP; - typedef struct KMX_tagKEYBOARD { - KMX_DWORD dwIdentifier; // Keyman compiled keyboard id + KMX_DWORD dwIdentifier; // Keyman compiled keyboard id - KMX_DWORD dwFileVersion; // Version of the file - Keyman 4.0 is 0x0400 + KMX_DWORD dwFileVersion; // Version of the file - Keyman 4.0 is 0x0400 - KMX_DWORD dwCheckSum; // As stored in keyboard. DEPRECATED as of 16.0 - KMX_DWORD xxkbdlayout; // as stored in HKEY_LOCAL_MACHINE//system//currentcontrolset//control//keyboard layouts - KMX_DWORD IsRegistered; // layout id, from same registry key - KMX_DWORD version; // keyboard version + KMX_DWORD dwCheckSum; // As stored in keyboard. DEPRECATED as of 16.0 + KMX_DWORD xxkbdlayout; // as stored in HKEY_LOCAL_MACHINE//system//currentcontrolset//control//keyboard layouts + KMX_DWORD IsRegistered; // layout id, from same registry key + KMX_DWORD version; // keyboard version - KMX_DWORD cxStoreArray; // in array entries - KMX_DWORD cxGroupArray; // in array entries + KMX_DWORD cxStoreArray; // in array entries + KMX_DWORD cxGroupArray; // in array entries - LPKMX_STORE dpStoreArray; // [LPSTORE] address of first item in store array, from start of file - LPKMX_GROUP dpGroupArray; // [LPGROUP] address of first item in group array, from start of file + LPKMX_STORE dpStoreArray; // [LPSTORE] address of first item in store array, from start of file + LPKMX_GROUP dpGroupArray; // [LPGROUP] address of first item in group array, from start of file - KMX_DWORD StartGroup[2]; // index of starting groups [2 of them] + KMX_DWORD StartGroup[2]; // index of starting groups [2 of them] // Ansi=0, Unicode=1 - KMX_DWORD dwFlags; // Flags for the keyboard file + KMX_DWORD dwFlags; // Flags for the keyboard file - KMX_DWORD dwHotKey; // standard windows hotkey (hiword=shift/ctrl/alt stuff, loword=vkey) + KMX_DWORD dwHotKey; // standard windows hotkey (hiword=shift/ctrl/alt stuff, loword=vkey) - //PWSTR dpName; // offset of name - //PWSTR dpLanguageName; // offset of language name; - //PWSTR dpCopyright; // offset of copyright - //PWSTR dpMessage; // offset of message in Keyboard About box + // PWSTR dpName; // offset of name + // PWSTR dpLanguageName; // offset of language name; + // PWSTR dpCopyright; // offset of copyright + // PWSTR dpMessage; // offset of message in Keyboard About box - KMX_DWORD dpBitmapOffset; // 0038 offset of the bitmaps in the file - KMX_DWORD dwBitmapSize; // 003C size in bytes of the bitmaps + KMX_DWORD dpBitmapOffset; // 0038 offset of the bitmaps in the file + KMX_DWORD dwBitmapSize; // 003C size in bytes of the bitmaps //HBITMAP hBitmap; // handle to the bitmap in the file; } KMX_KEYBOARD, *LPKMX_KEYBOARD; @@ -99,6 +96,6 @@ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); */ FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); -#endif // _KMXFILE_H +#endif // _KMXFILE_H #endif /*MC_KMXFILE_H*/ diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index ecaef7ddce7..1f26b7fc35e 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -59,6 +59,11 @@ std::vector KMX_FDeadkeys; // I4353 */ #if defined(_WIN32) || defined(_WIN64) int wmain(int argc, wchar_t* argv[]) { + /** + * TODO for cross-platform use: if we want to use wmain instead of main: + * inside wmain convert wchar_t* argv[] to char* argv_ch[] + * to be able to use mac_run(int argc, char* argv_ch[]) + */ #elif ((__linux__) || (__unix__)) // LINUX, UNIX int main(int argc, char* argv[]) { @@ -69,7 +74,6 @@ std::vector KMX_FDeadkeys; // I4353 #endif mac_run(argc, argv); - printf("\n................................ END .............................. _S2 \n"); } /** @brief start of mcompile; load, convert and save keyboard */ @@ -146,7 +150,7 @@ int mac_run(int argc, char* argv[]) { } #endif - // DeleteReallocatedPointers(kmxfile); :TODO // _S2 not my ToDo :-) + // DeleteReallocatedPointers(kmxfile); :TODO // _S2 not my TODO :-) delete kmxfile; return 0; } @@ -279,10 +283,10 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, shift &= ~LCTRLFLAG; if (key->ShiftFlags == 0) { - //mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO dk(%d) + [%x K_%d]", key->Line, key->Key, deadkey, shift, vk); + // mac_KMX_LogError(L"Converted mnemonic rule on line %d, + '%c' TO dk(%d) + [%x K_%d]", key->Line, key->Key, deadkey, shift, vk); key->ShiftFlags = ISVIRTUALKEY | shift; } else { - //mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO dk(%d) + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, deadkey, key->ShiftFlags & ~VIRTUALCHARKEY, vk); + // mac_KMX_LogError(L"Converted mnemonic virtual char key rule on line %d, + [%x '%c'] TO dk(%d) + [%x K_%d]", key->Line, key->ShiftFlags, key->Key, deadkey, key->ShiftFlags & ~VIRTUALCHARKEY, vk); key->ShiftFlags &= ~VIRTUALCHARKEY; } @@ -541,7 +545,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int // Loop through each possible key on the keyboard for (int i = 0; KMX_VKMap[i]; i++) { // I4651 - // windows uses VK as sorting order in rgkey[], Linux and macOS use SC/Keycode as sorting order + // Windows uses VK as sorting order in rgkey[], Linux and macOS use SC/Keycode as sorting order UINT scUnderlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_VKMap[i]); KMX_WCHAR ch = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, scUnderlying, VKShiftState[j], &DeadKey); @@ -594,8 +598,10 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a /* we start with SPACE (keycode_spacebar=49) because all deadkeys occur in combinations with space. - Since mcompile finds only the first occurance of a dk combination, this makes sure that we always find the dk+SPACE combinations for a deadkey. - If there are more combinations to create a specific character they will not be found. (See comment at the top of mac_KMX_DoConvert()) + Since mcompile finds only the first occurance of a dk combination, this makes sure that we always + find the dk+SPACE combinations for a deadkey. + If there are more combinations to create a specific character they will not be found. + (See comment at the top of mac_KMX_DoConvert()) */ for (int i = keycode_spacebar; i >= 0; i--) { status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_convert_Shiftstate_to_MacShiftstate(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); @@ -607,7 +613,7 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a if (deadkeystate != 0) { status = UCKeyTranslate(keyboard_layout, i, kUCKeyActionDown, ss_mac[j], LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - //deadkeystate might be changed again + // deadkeystate might be changed again therefore a new if-clause if (deadkeystate != 0) { KMX_WORD vk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[1], 0); @@ -643,140 +649,3 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a } while (fmtbuf[j] != *end); putwchar(*nl); } - - -//################################################################################################################################################ -//################################# Code beyond these lines needs to be included in mcompile ##################################################### -//################################################################################################################################################ - -//################################################################################################################################################ -//################################################################################################################################################ - - -bool test_dk_S2(KMX_WORD deadkeys[512], KMX_WORD deadkeys1[512]) { - bool tt= true; - KMX_DWORD val, val1; - for ( int i=0; i<512;i++) { - val = deadkeys[i]; - val1 = deadkeys1[i]; - tt= ( (deadkeys[i] == deadkeys1[i]) && tt); - if (!(tt)) - printf("wrong from %i \n",i); - } - return tt; -} -bool test_dk_find_entries_S2(KMX_WORD deadkeys[512], int search) { - for ( int i=0; i<512;i++) { - if (deadkeys[i] == search) { - printf("found value %i (first occurance) in deadkeys[%i] ",search, i); - if ( i%3 ==0 ) printf("as character \n"); - if ( i%3 ==1 ) printf("as shiftstate \n"); - if ( i%3 ==2 ) printf("as combined character \n"); - return true; - } - } - return false; -} -bool test_dk_write_entries_S2(KMX_WORD deadkeys[512]) { - for ( int i=0; i< 512/3;i++) { - if ( deadkeys[3*i] !=0) - printf(" %i set nr \t%i: %i\t-\t%i(%c)\t-\t%i(%c) \n", deadkeys[2], i,deadkeys[3*i+1], deadkeys[3*i], deadkeys[3*i], deadkeys[3*i+2], deadkeys[3*i+2]); - } - return true; -} - -bool find_print_character_S2(const UCKeyboardLayout * keyboard_layout, int keyval, int k, int c, int s) { - int ss_rgkey; -int count =0; -bool moreval=false; - std::vector res_vec; - - for ( int key=0; key< 50;key++) { - for ( int caps=0; caps< 2;caps++) { - for ( int ss=0; ss< 10;ss++) { - - if ( ss == 0 ) ss_rgkey= 0; - else if ( ss == 2 ) ss_rgkey= 1; - else if ( ss == 8 ) ss_rgkey= 6; - else if ( ss == 10 ) ss_rgkey= 7; - else ss_rgkey= 999; -if ( (ss==1) || (ss==3) || (ss==5) || (ss==7) || (ss==9) ) -continue; - - int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, ss, caps); - - count++; - if ((ss_rgkey!= 999 )&& ( keyval!= 0)&& ( keyval== keyvalsearch)&& ( count>1)&& ( key!=k)) { - printf( " key: %i, ss_mac: %i ( ss_rgkey:%i), caps:%i \n",key, ss, ss_rgkey, caps); - moreval=true; - } - } - } - } - return moreval; -} -bool print_dublicates_S2(const UCKeyboardLayout * keyboard_layout){ - for ( int key=0; key< 50;key++) { - for ( int caps=0; caps< 2;caps++) { - for ( int ss=0; ss< 6;ss++) { - int keyval= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, 2*ss, caps); - if (find_print_character_S2(keyboard_layout, keyval, key,caps,ss) && (keyval>0)) { - printf( "Keyval %i(%c): can be found on : \tkey: %i, ss-mac: %i caps:%i\t:\n---------------------------------------------------------\n",keyval,keyval, key, 2*ss,caps); - } - } - } - } - - - return true; -} -bool print_character_of_key_S2(const UCKeyboardLayout * keyboard_layout, int key) { -int ss_rgkey; - for ( int ss=0; ss< 6;ss++) { - for ( int caps=0; caps< 2;caps++) { - - int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, 2*ss, caps); - printf( " key %i has values : %i (%c) ( ss:%i, caps:%i) \n", key, keyvalsearch,keyvalsearch, 2*ss, caps); - } - } - return true; -} -bool find_character_S2(const UCKeyboardLayout * keyboard_layout, int keyval) { -int ss_rgkey; - for ( int ss=0; ss< 10;ss++) { - -if ( ss == 0 ) ss_rgkey= 0; -else if ( ss == 2 ) ss_rgkey= 1; -else if ( ss == 8 ) ss_rgkey= 6; -else if ( ss == 10 ) ss_rgkey= 7; -else ss_rgkey= 999; - -if ( (ss==1) || (ss==3) || (ss==5) || (ss==7) || (ss==9) ) -continue; - - for ( int caps=0; caps< 2;caps++) { - for ( int key=0; key< 50;key++) { - int keyvalsearch= mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, key, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss), caps); - if ((ss_rgkey!= 999 )&& ( keyval== keyvalsearch)) - printf( " found keyval: key: %i, ss_mac:%i ( ss_rgkey:%i), caps:%i -> character: %i (%c) \n", key, ss, ss_rgkey, caps, keyvalsearch,keyvalsearch); - } - } - } - return true; -} - - -//-------------------------- -/*void fun2() { std::cout << "Hier ist fun2 von mcompile.cpp ...\n";} - -void testmyFunctions_S2() { - std::u16string character; - KMX_DWORD val; - - for (int i=0; i<8; i++) { - character = mac_get_character_From_Keycode(24,14,i ); // all Shiftstates for ´` + e - val = mac_get_keyval_From_Keycode(24,14,i ); // all Shiftstates for ´` + e - wprintf( L" ` + e for SHIFTSTATE %i -> %i \n", i, val); - } -}*/ - diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 33397befb0f..6da2c400806 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -40,18 +40,4 @@ extern std::vector KMX_FDeadkeys; // I4353 */ void mac_KMX_LogError(const wchar_t* fmt, ...); -//################################################################################################################################################ -//################################################################################################################################################ - -bool find_print_character_S2(const UCKeyboardLayout * keyboard_layout, int keyval, int k, int c, int s); -bool print_dublicates_S2(const UCKeyboardLayout * keyboard_layout); -bool print_character_of_key_S2(const UCKeyboardLayout * keyboard_layout, int key) ; -bool find_character_S2(const UCKeyboardLayout * keyboard_layout, int keyval) ; - -bool test_dk_S2(KMX_WORD deadkeys[512], KMX_WORD deadkeys1[512]); -bool test_dk_find_entries_S2(KMX_WORD deadkeys[512], int search); -bool test_dk_write_entries_S2(KMX_WORD deadkeys[512]); -void fun2(); -void testmyFunctions_S2(); - #endif /*MCOMPILE_H*/ diff --git a/mac/mcompile/u16.cpp b/mac/mcompile/u16.cpp index d6dce674133..27a1259d3a8 100644 --- a/mac/mcompile/u16.cpp +++ b/mac/mcompile/u16.cpp @@ -9,7 +9,6 @@ #include #include - std::vector convert_argv_to_Vector_u16str(int argc, char* argv[]) { std::vector vector_u16; @@ -85,7 +84,7 @@ void u16sprintf(KMX_WCHAR* dst, const size_t max_len, const wchar_t* fmt, ...) { // UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) std::string utf8str = convert_wstring.to_bytes(wbuf); // UTF16 ( = const wchar_t*) -> std::string std::u16string u16str = convert.from_bytes(utf8str); // std::string -> std::u16string - u16ncpy(dst, u16str.c_str(), max_len); // std::u16string.c_str() -> char16_t* + u16ncpy(dst, u16str.c_str(), max_len); // std::u16string.c_str() -> char16_t* delete[] wbuf; } @@ -259,7 +258,6 @@ KMX_WCHAR* u16tok(KMX_WCHAR* p, KMX_WCHAR ch, KMX_WCHAR** ctx) { return *p ? p : NULL; } -// _S2 delimiters is array of char ( of size 2) KMX_WCHAR* u16tok(KMX_WCHAR* p, KMX_WCHAR* delimiters, KMX_WCHAR** ctx) { if (!p) { p = *ctx; diff --git a/mac/mcompile/u16.h b/mac/mcompile/u16.h index 70d6d947685..673a84dc3b1 100644 --- a/mac/mcompile/u16.h +++ b/mac/mcompile/u16.h @@ -8,7 +8,6 @@ #include #include - std::vector convert_argvW_to_Vector_u16str(int argc, wchar_t* argv[]); std::vector convert_argv_to_Vector_u16str(int argc, char* argv[]); From eae766673edee0db92758c2c041d97dbdf961e63 Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 19 Jul 2024 12:02:44 +0200 Subject: [PATCH 42/71] feat(mac): ensureValidInputForKeyboardTranslation --- mac/mcompile/keymap.cpp | 32 ++++++++++++------------- mac/mcompile/keymap.h | 40 +++++++++++++++++++++----------- mac/mcompile/mc_import_rules.cpp | 6 ++--- mac/mcompile/mc_kmxfile.cpp | 3 ++- mac/mcompile/mcompile.cpp | 14 ++++++----- 5 files changed, 55 insertions(+), 40 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 9abcf1c72a3..d4be957a387 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -18,7 +18,7 @@ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) { if (shiftState == 0) return MAC_BASE; // Win ss 0 -> mac ss 0 else if (shiftState == K_SHIFTFLAG) return MAC_SHIFT; // Win ss 16 -> mac ss 2 else if (shiftState == (LCTRLFLAG | RALTFLAG)) return MAC_OPT; // Win ss 9 -> mac ss 8 - else if (shiftState == (K_SHIFTFLAG | LCTRLFLAG | RALTFLAG)) return MAC_SHIFT_OPT; // Win ss 25 -> mac ss 10 + else if (shiftState == (K_SHIFTFLAG | LCTRLFLAG | RALTFLAG)) return MAC_SHIFT_OPT; // Win ss 25 -> mac ss 10 else return shiftState; // Win ss x -> mac ss x } @@ -33,7 +33,7 @@ int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState) { /** @brief check for correct input parameter that will later be used in UCKeyTranslate() */ bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode) { - if ((shiftstate > max_shiftstate)) + if (!(std::find(std::begin(ss_mac), std::end(ss_mac), shiftstate) != std::end(ss_mac))) return false; if (keycode > keycode_max) @@ -148,7 +148,7 @@ bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout) { printf("ERROR: Can't get keyboard_layout\n"); return 2; } - // intentionally leaking `source` in order to still be able to access `keymap` + // intentionally leaking `source` in order to still be able to access `keyboard_layout` return 0; } @@ -166,8 +166,8 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou return 0; /* - UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^' - if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 + UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^'. + If CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 */ status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); // If this was a deadkey (deadkeystate != 0), append a space @@ -178,7 +178,7 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou if (unicodeString[0] == 1) // impossible character return 0; else { - return unicodeString[0]; // combined char e.g. â + return unicodeString[0]; // combined char e.g. 'â' } } @@ -195,12 +195,12 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la return 0; /* - UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^' - if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 + UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^'. + If CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 */ status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - // If this was a deadkey,append a space + // If this was a deadkey, append a space if (deadkeystate != 0) status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown,(shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); @@ -208,7 +208,7 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la if (unicodeString[0] == 1) // impossible character return 0; else - return unicodeString[0]; // combined char e.g. â + return unicodeString[0]; // combined char e.g. 'â' } /** @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. */ @@ -258,7 +258,7 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_ return kv_underlying; } -/** @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard */ +/** @brief return the keycode of the currently used (underlying) keyboard for a given keycode of a character on the US keyboard */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) { // first get the keyvalue kv of the key on the US keyboard (kc_us) KMX_DWORD kv = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_win), caps); @@ -275,13 +275,13 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* k /** @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD virtualKeyUS) { - // on the mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an 'artificial' us virtual key + // on the mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an 'artificial' us virtual key from a keycode return (mac_USVirtualKeyToScanCode[virtualKeyUS]); } /** @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard */ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { - // on the mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an keycode from an 'artificial' us virtual key + // on the mac virtual keys do not exist. Nevertheless we can use this mapping to obtain a keycode from an 'artificial' us virtual key return mac_ScanCodeToUSVirtualKey[keycode]; } @@ -296,8 +296,8 @@ KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, OSStatus status; /* - UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a base character (vk_us) to get the combined dk e.g.'Â' - if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 + UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a base character (vk_us) to get the combined dk e.g. '^' + 'A' -> 'Â' + If CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 */ status = UCKeyTranslate(keyboard_layout, vk_dk, kUCKeyActionDown, ss_dk, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); @@ -308,7 +308,7 @@ KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, if (unicodeString[0] == 1) // impossible character return 0; else - return unicodeString[0]; // combined char e.g. â + return unicodeString[0]; // combined char e.g. 'â' } else return 0; } diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index cb3605bd56f..d96521aa9d2 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -21,8 +21,6 @@ enum ShiftState { ShftXxxx = Shft | Xxxx, // 9 }; -// shiftstates we can use for mac: Base;Shift, OPTION, Shift+OPTION -static int ss_mac[] = {0, 2, 8, 10}; // Map of all US English virtual key codes that we can translate const KMX_DWORD KMX_VKMap[] = { @@ -60,16 +58,18 @@ static KMX_DWORD keycode_max = 50; static int keycode_spacebar = 49; static KMX_DWORD max_shiftstate = 10; +// shiftstates we can use for mac static int MAC_BASE = 0; static int MAC_SHIFT = 2; static int MAC_OPT = 8; static int MAC_SHIFT_OPT = 10; +static int ss_mac[] = {MAC_BASE, MAC_SHIFT, MAC_OPT, MAC_SHIFT_OPT}; /** * @brief map a shiftstate used on Windows to a shiftstate suitable for UCKeyTranslate() on the mac * Windows: (Base: 00000000 (0); Shift 00010000 (16); AltGr 00001001 (9); Shift+AltGr 00011001 (25)) * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10 ) - * @param shiftState shiftstate used on Windows + * @param shiftState shiftstate used on Windows * @return a shiftstate usable for UCKeyTranslate() on mac if available * if shiftState is a Windows ShiftState: convert the Windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) * if shiftState is NOT a Windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate @@ -80,7 +80,7 @@ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState); * @brief map a shiftstate used in rgkey (a vector of VirtualKey*) to a shiftstate suitable for UCKeyTranslate() on the mac * rgkey: (Base: 0; Shift 1; OPT 6; Shift+OPT 7 ) * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10) - * @param rgkey_ShiftState shiftstate used in rgkey + * @param rgkey_ShiftState shiftstate used in rgkey * @return a shiftstate usable for UCKeyTranslate() on mac if available * if shiftState is a Windows ShiftState: convert the Windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) * if shiftState is NOT a Windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate @@ -91,7 +91,8 @@ int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState); * @brief check for correct input parameter that will later be used in UCKeyTranslate() * @param shiftstate the currently used shiftstate * @param keycode the code of the key in question - * @return true if all parameters are OK; false if not + * @return true if all parameters are OK; + * false if not */ bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode); @@ -107,7 +108,9 @@ bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode); * [Keyval shifted ] * @param[in,out] all_vector Vector that holds the data of the US keyboard as well as the currently used (underlying) keyboard * @param keyboard_layout pointer to currently used (underlying) keyboard layout - * @return 0 on success; 1 if data of US keyboard was not written; 2 if data of underlying keyboard was not written + * @return 0 on success; + * 1 if data of US keyboard was not written; + * 2 if data of underlying keyboard was not written */ int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout); @@ -115,7 +118,8 @@ int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeybo * @brief write data of the US keyboard into a 3D-Vector which later will contain * data of the US keyboard and the currently used (underlying) keyboard * @param[in,out] vec_us Vector that holds the data of the US keyboard - * @return 0 on success; 1 if data of US keyboard was not written; + * @return 0 on success; + * 1 if data of US keyboard was not written; */ int mac_write_US_ToVector(vec_dword_3D& vec_us); @@ -140,7 +144,9 @@ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLay /** * @brief create a pointer to pointer of the current keyboard_layout for later use * @param keyboard_layout pointer to pointer to currently used (underlying) keyborad layout - * @return 0 on success; 1 if the display is not found; 2 if the keymap is not found + * @return 0 on success; + * 1 if the display is not found; + * 2 if the keymap is not found */ bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout); @@ -585,7 +591,8 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa * "What character is on the same position/shiftstats/caps on the currently used (underlying) keyboard as on the US keyboard?" * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param kv_us a keyvalue on the US keyboard - * @return keyval of the underlying keyboard if available; else the keyval of the US keyboard + * @return keyval of the underlying keyboard if available; + * else the keyval of the US keyboard */ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us); @@ -594,19 +601,21 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, K * On what key of the underlying keyboard do we find a certain character? * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param kv_underlying a keyvalue on the currently used (underlying) keyboard - * @return keycode of the underlying keyboard if foundf; else the keyval of the underlying keyboard + * @return keycode of the underlying keyboard if foundf; + * else the keyval of the underlying keyboard */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying); /** - * @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard -> it`s the same!! + * @brief return the keycode of the currently used (underlying) keyboard for a given keycode of a character on the US keyboard * "Where on an underlying keyboard do we find a character that is on a certain key on a US keyboard?" * @param keyboard_layout the currently used (underlying) keyboard layout * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param kc_us a key of the US keyboard * @param ss_win a Windows-type shiftstate * @param caps state of the caps key - * @return the keycode of the underlying keyboard if found; else the keycode of the US keyboard + * @return the keycode of the underlying keyboard if found; + * else the keycode of the US keyboard */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps); @@ -615,6 +624,7 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* k * "Where on an underlying keyboard do we find a character of a US keyboard?" * @param virtualKeyUS a virtual key of the US keyboard * @return the keycode of the currently used (underlying) keyboard + * 0xFFFF if the key is not used */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD virtualKeyUS); @@ -622,7 +632,8 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD virtualKeyUS); * @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard * "Which character is found on a key of the US keyboard?" * @param keycode a keycode of the currently used (underlying) keyboard - * @return the virtual key of the US keyboard or 0 + * @return the virtual key of the US keyboard + * 0 if the key is not used */ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); @@ -635,7 +646,8 @@ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); * @param vk_us a keycode of a character key on the currently used (underlying) keyboard to be combined to a dk * @param shiftstate_mac a shiftstate of a character key on the currently used (underlying) keyboard * @param caps state of the caps key of a character key on the currently used (underlying) keyboard - * @return the combination of deadkey + character if it is available; if not return 0 + * @return the combination of deadkey + character if it is available; + * if not return 0 */ KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, int vk_dk, KMX_DWORD ss_dk, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps); diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index de39868dad8..d09d092b7ee 100644 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -240,7 +240,7 @@ class mac_KMX_VirtualKey { (this->mac_KMX_IsAltGrCapsEqualToAltGrShift() ? 4 : 0) | (this->mac_KMX_IsXxxxGrCapsEqualToXxxxShift() ? 8 : 0);*/ - int capslock = 1; // we do not use the equation to obtain capslock. on the mac we set capslock=1 + int capslock = 1; // on mcompile-mac we do not use the equation to obtain capslock. Here we set capslock = 1 for (int ss = 0; ss <= MaxShiftState; ss++) { if (ss == Menu || ss == ShftMenu) { @@ -289,8 +289,8 @@ class mac_KMX_VirtualKey { /* * this is different to mcompile Windows !!!! * this->m_sc stores SC-US = SCUnderlying - * this->m_vk stores VK-US ( not underlying !!) - * key->Key stores VK-US ( not underlying !!) + * this->m_vk stores VK-US ( not VK underlying !!) + * key->Key stores VK-US ( not VK underlying !!) * key->dpOutput stores character Underlying */ KMX_DWORD sc_underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keyboard_layout, all_vector, this->SC(), (ShiftState)ss, caps); diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index 54c1f377ff0..991ceaf0e38 100644 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -45,7 +45,8 @@ const int CODE__SIZE[] = { * @brief check if the file has correct version * @param filebase containing data of the input file * @param file_size a size - * @return true if successful; false if not + * @return true if successful; + * false if not */ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size); diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 1f26b7fc35e..1bf013b1453 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -19,7 +19,8 @@ * @param kbd pointer to US keyboard * @param bDeadkeyConversion option for converting a deadkey to a character: 1 = dk conversion; 0 = no dk conversion * @param argc number of command line arguments - * @return TRUE if conversion was successful; FALSE if not + * @return TRUE if conversion was successful; + * FALSE if not */ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc); @@ -398,7 +399,8 @@ struct KMX_dkidmap { * @brief find the deadkey id for a given deadkey * @param kbd pointer to the keyboard * @param deadkey for which an id is to be found - * @return 0 if failed; otherwise a deadkey-id + * @return 0 if failed; + * otherwise a deadkey-id */ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { LPKMX_GROUP gp; @@ -600,15 +602,15 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a we start with SPACE (keycode_spacebar=49) because all deadkeys occur in combinations with space. Since mcompile finds only the first occurance of a dk combination, this makes sure that we always find the dk+SPACE combinations for a deadkey. - If there are more combinations to create a specific character they will not be found. + If there are additional combinations to create a specific character they will not be found. (See comment at the top of mac_KMX_DoConvert()) */ for (int i = keycode_spacebar; i >= 0; i--) { status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_convert_Shiftstate_to_MacShiftstate(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); /* - UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^' - if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 + UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^'. + If CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 */ if (deadkeystate != 0) { status = UCKeyTranslate(keyboard_layout, i, kUCKeyActionDown, ss_mac[j], LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); @@ -617,7 +619,7 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a if (deadkeystate != 0) { KMX_WORD vk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[1], 0); - // ensure to NOT get key combinations like ^a but only combined characters like â (exception for ^+space) + // ensure to NOT get key combinations like '^a' but only combined characters like 'â' (exception for '^' + space) if ((unicodeString[0] != deadkey) || (vk == 32)) { *p++ = vk; *p++ = ss_mac[j]; From cb31cebb33c4dbd259e0b27f5c705cf2755a984b Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 19 Jul 2024 12:09:16 +0200 Subject: [PATCH 43/71] feat(mac): remove dublicate #include --- common/include/km_types.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/common/include/km_types.h b/common/include/km_types.h index 5072d76f700..05bc0aa432b 100644 --- a/common/include/km_types.h +++ b/common/include/km_types.h @@ -1,8 +1,4 @@ #pragma once -#include - -#include - #include /* #if defined(_WIN32) || defined(_WIN64) From 63181e9ce75ca951ee63c62a5949a251bada520c Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 24 Jul 2024 10:47:28 +0200 Subject: [PATCH 44/71] feat(mac): chande in u16tol --- mac/mcompile/mc_import_rules.cpp | 10 +++++++--- mac/mcompile/u16.cpp | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index d09d092b7ee..bc98a272a35 100644 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -50,14 +50,14 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { } /** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. */ -int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, ShiftState ss_rgkey, int caps, const UCKeyboardLayout* keyboard_layout) { +int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, ShiftState ss, int caps, const UCKeyboardLayout* keyboard_layout) { KMX_DWORD keyval; UInt32 isdk = 0; - if (!ensureValidInputForKeyboardTranslation(mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_rgkey), keycode)) + if (!ensureValidInputForKeyboardTranslation(mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss), keycode)) return 0; - keyval = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_rgkey), caps, isdk); + keyval = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss), caps, isdk); std::u16string str = std::u16string(1, keyval); KMX_WCHAR firstchar = *(PKMX_WCHAR)str.c_str(); @@ -451,6 +451,10 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe // Alt and Shift+Alt don't work, so skip them (ss 4+5) continue; } +//_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! + /*if (ss == MenuCtrl || ss == ShftMenuCtrl) { + continue; + }*/ KMX_DWORD kc_underlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); diff --git a/mac/mcompile/u16.cpp b/mac/mcompile/u16.cpp index 27a1259d3a8..2489c304f6c 100644 --- a/mac/mcompile/u16.cpp +++ b/mac/mcompile/u16.cpp @@ -103,7 +103,7 @@ long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) { auto s = string_from_u16string(str); char* t; size_t idx; - long int result = stol(s, &idx, base); + long int result = strtol(s, &idx, base); if (endptr != nullptr) *endptr = (KMX_WCHAR*)str + (t - s.c_str()); return result; From aa5ad7af4acc2dab1889c1f77c757c22c241aaf4 Mon Sep 17 00:00:00 2001 From: Sabine Date: Thu, 25 Jul 2024 13:56:31 +0200 Subject: [PATCH 45/71] feat(mac): use new u16 --- mac/mcompile/u16.cpp | 245 ++++++++++++++++++++----------------------- mac/mcompile/u16.h | 196 ++++++++++++++++++++++++++++++---- 2 files changed, 287 insertions(+), 154 deletions(-) diff --git a/mac/mcompile/u16.cpp b/mac/mcompile/u16.cpp index 2489c304f6c..17845538d1d 100644 --- a/mac/mcompile/u16.cpp +++ b/mac/mcompile/u16.cpp @@ -1,127 +1,94 @@ /* - * Keyman is copyright (C) SIL International. MIT License. + * Keyman is copyright 2024 (C) SIL International. MIT License. * - * Keyboard reading and mapping for mac + * Functions for u16string */ #include "u16.h" #include #include #include - -std::vector convert_argv_to_Vector_u16str(int argc, char* argv[]) { - std::vector vector_u16; - - // for each arg convert to u16string and push to vector - for (char** arg = argv, i = 0; *arg; ++arg, i++) { - std::string s(*arg); - vector_u16.push_back(u16string_from_string(s)); - } - return vector_u16; -} - -std::vector convert_argvW_to_Vector_u16str(int argc, wchar_t* argv[]) { - std::vector vector_u16; - - // for each arg convert to u16string and push to vector - for (wchar_t** arg = argv, i = 0; *arg; ++arg, i++) { - std::wstring S(*arg); - vector_u16.push_back(u16string_from_wstring(S)); - } - return vector_u16; -} - -// ToDo codecvt needs to be replaced !! +#include "../../core/src/utfcodec.hpp" // String <- wstring +/** @brief Obtain a std::string from a std::wstring */ std::string string_from_wstring(std::wstring const str) { - std::wstring_convert, wchar_t> converter; - return converter.to_bytes(str); + return convert((const std::wstring)str); } // wstring <- string +/** @brief Obtain a std::wstring from a std::string */ std::wstring wstring_from_string(std::string const str) { - std::wstring_convert, wchar_t> converter; - return converter.from_bytes(str); -} - -// u16String <- wstring -std::u16string u16string_from_wstring(std::wstring const wstr) { - std::string str = string_from_wstring(wstr); - std::u16string str16 = u16string_from_string(str); - return str16; + return convert((const std::string)str); } // u16String <- string +/** @brief Obtain a std::string from a std::wstring */ std::u16string u16string_from_string(std::string const str) { - std::wstring_convert, char16_t> converter; - return converter.from_bytes(str); + return convert((const std::string)str); } // string <- u16string +/** @brief Obtain a std::string from a std::u16string */ std::string string_from_u16string(std::u16string const str) { - std::wstring_convert, char16_t> converter; - return converter.to_bytes(str); + return convert((const std::u16string)str); } + // wstring <- u16string -std::wstring wstring_from_u16string(std::u16string const str16) { - std::string str = string_from_u16string(str16); - std::wstring wstr = wstring_from_string(str); - return wstr; +/** @brief Obtain a std::wstring from a std::u16string */ +std::wstring wstring_from_u16string(std::u16string const str) { + std::string s = convert((const std::u16string)str); + std::wstring ws = convert((const std::string)s); + return ws; } -void u16sprintf(KMX_WCHAR* dst, const size_t max_len, const wchar_t* fmt, ...) { - // UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) - wchar_t* wbuf = new wchar_t[max_len]; - va_list args; - va_start(args, fmt); - vswprintf(wbuf, max_len, fmt, args); - va_end(args); - - std::wstring_convert, wchar_t> convert_wstring; - std::wstring_convert, char16_t> convert; - - // UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) - std::string utf8str = convert_wstring.to_bytes(wbuf); // UTF16 ( = const wchar_t*) -> std::string - std::u16string u16str = convert.from_bytes(utf8str); // std::string -> std::u16string - u16ncpy(dst, u16str.c_str(), max_len); // std::u16string.c_str() -> char16_t* - delete[] wbuf; +// u16string <- wstring +/** @brief Obtain a std::u16string from a std::wstring */ +std::u16string u16string_from_wstring(std::wstring const str) { + std::string s = convert((const std::wstring)str); + std::u16string utf16 = convert((const std::string)s); + return utf16; } -std::wstring convert_pchar16T_To_wstr(KMX_WCHAR* name) { - // convert char16_t* -> std::u16string -> std::string -> std::wstring - // char16_t* -> std::u16string - std::u16string u16str(name); - // std::u16string -> std::string - std::string stri = string_from_u16string(u16str); - // std::string -> std::wstring - std::wstring wstr = wstring_from_string(stri); - return wstr; - } +// UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) +/** @brief @brief Convert pointer to wchar_t to pointer to char16_t and copy sz elements into dst */ +void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...) { + wchar_t* wbuf = new wchar_t[sz]; + va_list args; + va_start(args, fmt); + vswprintf(wbuf, sz, fmt, args); + va_end(args); + + std::u16string u16str = u16string_from_wstring(wbuf); + u16ncpy(dst, u16str.c_str(), sz); + delete[] wbuf; +} +/** @brief @brief Convert u16string to long integer */ long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) { auto s = string_from_u16string(str); char* t; - size_t idx; - long int result = strtol(s, &idx, base); - if (endptr != nullptr) + long int result = strtol(s.c_str(), &t, base); + if (endptr != nullptr) *endptr = (KMX_WCHAR*)str + (t - s.c_str()); return result; } +/** @brief Append n characters from u16string */ const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { KMX_WCHAR* o = dst; dst = (KMX_WCHAR*)u16chr(dst, 0); - // max -= (dst-o); + // max -= (dst-o); while (*src && max > 0) { *dst++ = *src++; max--; } - if (max > 0) - *dst = 0; + if (max > 0) + *dst = 0; return o; } +/** @brief Append a '/' or '\\' to an array of char16_t */ const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* name) { const KMX_WCHAR* cp = NULL; cp = u16rchr(name, '\\'); @@ -129,27 +96,31 @@ const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* name) { cp = u16rchr(name, '/'); return cp; } -/* -KMX_CHAR* strrchr_slash(KMX_CHAR* name) -{ + +/** @brief Append a '/' or '\\' to an array of char */ +KMX_CHAR* strrchr_slash(KMX_CHAR* name) { KMX_CHAR* cp = NULL; cp = strrchr(name, '\\'); if (cp == NULL) cp = strrchr(name, '/'); return cp; } -*/ -// u16rchr returns last occurence of ch in p; It returns '\0' if ch == '\0' and NULL if ch is not found + +/** @brief Locate last occurrence of character in u16string */ const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch) { - const KMX_WCHAR* p_end = p + u16len(p); - while (p_end >= p) { - if (*p_end == ch) + const KMX_WCHAR* p_end = p + u16len(p) - 1; + + if (ch == '\0') + return p_end + 1; + while (p_end >= p) { + if (*p_end == ch) return p_end; - p_end--; - } - return NULL; + p_end--; + } + return NULL; } +/** @brief @brief Locate first occurrence of character in u16string */ const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch) { while (*p) { if (*p == ch) @@ -159,6 +130,7 @@ const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch) { return ch == 0 ? p : NULL; } +/** @brief @brief Copy the u16string pointed to by source into the array pointed to by destination */ const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src) { KMX_WCHAR* o = dst; while (*src) { @@ -168,19 +140,20 @@ const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src) { return o; } +/** @brief Copy n characters of the u16string pointed to by source into the array pointed to by destination */ const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { KMX_WCHAR* o = dst; while (*src && max > 0) { *dst++ = *src++; max--; } - while (max > 0) { - *dst++ = 0; - max--; + if (max > 0) { + *dst = 0; } return o; } +/** @brief @brief Return the length of the u16string str */ size_t u16len(const KMX_WCHAR* p) { int i = 0; while (*p) { @@ -190,20 +163,22 @@ size_t u16len(const KMX_WCHAR* p) { return i; } +/** @brief @brief Compare two u16strings */ int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q) { while (*p && *q) { if (*p != *q) - return *p - *q; + return *p - *q; p++; q++; } return *p - *q; } +/** @brief @brief Case sensitive comparison of up to count characters in two strings */ int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { while (*p && *q && count) { if (toupper(*p) != toupper(*q)) - return *p - *q; + return *p - *q; p++; q++; count--; @@ -213,20 +188,22 @@ int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { return 0; } +/** @brief @brief Case sensitive comparison of two strings */ int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q) { while (*p && *q) { if (toupper(*p) != toupper(*q)) - return *p - *q; + return *p - *q; p++; q++; } return *p - *q; } +/** @brief Comparison of up to count characters in two strings */ int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { while (*p && *q && count) { if (*p != *q) - return *p - *q; + return *p - *q; p++; q++; count--; @@ -236,11 +213,12 @@ int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { return 0; } -KMX_WCHAR* u16tok(KMX_WCHAR* p, KMX_WCHAR ch, KMX_WCHAR** ctx) { +/** @brief Split u16string into tokens */ +KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR ch, KMX_WCHAR** ctx) { if (!p) { p = *ctx; if (!p) - return NULL; + return NULL; } KMX_WCHAR* q = p; while (*q && *q != ch) { @@ -255,53 +233,52 @@ KMX_WCHAR* u16tok(KMX_WCHAR* p, KMX_WCHAR ch, KMX_WCHAR** ctx) { } else { *ctx = NULL; } - return *p ? p : NULL; + return *p ? p : NULL; } -KMX_WCHAR* u16tok(KMX_WCHAR* p, KMX_WCHAR* delimiters, KMX_WCHAR** ctx) { - if (!p) { - p = *ctx; - if (!p) - return NULL; - } +/** @brief Split u16string into tokens */ +KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR* delimiters, KMX_WCHAR** ctx) { + if (!p) { + p = *ctx; + if (!p) + return NULL; + } KMX_WCHAR* q = p; - while (*q && !u16chr(delimiters, *q)) { - q++; - } - if (*q) { - *q = 0; - q++; - while (*q && u16chr(delimiters, *q)) - q++; - *ctx = q; - } else { - *ctx = NULL; - } - return *p ? p : NULL; + while (*q && !u16chr(delimiters, *q)) { + q++; + } + if (*q) { + *q = 0; + q++; + while (*q && u16chr(delimiters, *q)) + q++; + *ctx = q; + } else { + *ctx = NULL; + } + return *p ? p : NULL; } +/** @brief Convert a u16string to a double */ double u16tof(KMX_WCHAR* str) { - double val = 0; - int offsetdot = 0; - char digit; + double val = 0; + int offsetdot = 0; + char digit; - PKMX_WCHAR q = (PKMX_WCHAR)u16chr(str, '.'); - size_t pos_dot = q - str; + PKMX_WCHAR q = (PKMX_WCHAR)u16chr(str, '.'); + size_t pos_dot = (q - str < 0) ? u16len(str) : q - str; - if (pos_dot < 0) - pos_dot = u16len(str); + for (size_t i = 0; i < u16len(str); i++) { + digit = static_cast(towupper(*str)); - for (size_t i = 0; i < u16len(str); i++) { - digit = static_cast(towupper(*str)); + if (i > pos_dot - 1) + offsetdot = 1; - if (i > pos_dot - 1) - offsetdot = 1; + if (digit != '.') + val = val + ((int(digit)) - 48) * pow(10, (pos_dot - 1 - i + offsetdot)); - if (digit != '.') - val = val + ((int(digit)) - 48) * pow(10, (pos_dot - 1 - i + offsetdot)); - - str++; - } - return val; + str++; + } + return val; } diff --git a/mac/mcompile/u16.h b/mac/mcompile/u16.h index 673a84dc3b1..790d2db226d 100644 --- a/mac/mcompile/u16.h +++ b/mac/mcompile/u16.h @@ -1,43 +1,199 @@ #ifndef U16_H #define U16_H +#pragma once #include "km_types.h" #include #include #include #include +#include #include -std::vector convert_argvW_to_Vector_u16str(int argc, wchar_t* argv[]); -std::vector convert_argv_to_Vector_u16str(int argc, char* argv[]); +/** +* @brief Obtain a std::string from a std::wstring +* @param str the std::wstring to be converted +* @return a std::string +*/ std::string string_from_wstring(std::wstring const str); + +/** +* @brief Obtain a std::wstring from a std::string +* @param str the std::string to be converted +* @return a std::wstring +*/ std::wstring wstring_from_string(std::string const str); -std::wstring wstring_from_u16string(std::u16string const str16); + +/** +* @brief Obtain a std::string from a std::wstring +* @param str the std::wstring to be converted +* @return a std::string +*/ std::u16string u16string_from_string(std::string const str); -std::u16string u16string_from_wstring(std::wstring const wstr); + +/** +* @brief Obtain a std::string from a std::u16string +* @param str the std::string to be converted +* @return a std::u16string +*/ std::string string_from_u16string(std::u16string const str); +/** +* @brief Obtain a std::wstring from a std::u16string +* @param str the std::u16string to be converted +* @return a std::wstring +*/ +std::wstring wstring_from_u16string(std::u16string const str); + +/** +* @brief Obtain a std::u16string from a std::wstring +* @param str the std::wstring to be converted +* @return a std::u16string +*/ +std::u16string u16string_from_wstring(std::wstring const str); + +/** +* @brief Convert pointer to wchar_t to pointer to char16_t and copy sz elements into dst +* @param dst destination +* @param sz nr of characters to be copied +* @param fmt source to convert and copy +* @return void +*/ void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...); -std::wstring convert_pchar16T_To_wstr(KMX_WCHAR* name); +/** +* @brief Convert u16string to long integer +* @param str u16string beginning with the representation of an integral number. +* @param endptr Reference to the next character in str +* @param base Numerical base (radix) that determines the valid characters and their interpretation +* @return a std::string +*/ +long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base); + + /** + * @brief Append n characters from u16string + * @param dst Pointer to the destination array + * @param src u16string to be appended + * @param max Maximum number of characters to be appended. + * @return Pointer to the destination array + */ + const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max); + + /** + * @brief Append a '/' or '\\' to an array of char16_t + * @param Name Pointer to the source + * @return Pointer to the source with slash/backslash added + */ + const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name); + + /** + * @brief Append a '/' or '\\' to an array of char + * @param Name Pointer to the source + * @return Pointer to the source with slash/backslash added + */ + KMX_CHAR* strrchr_slash(KMX_CHAR* Name); + /** + * @brief Locate last occurrence of character in u16string + * @param p Pointer to the source + * @param ch The character to be found + * @return A pointer to the last occurrence of character in u16str + */ + const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch); + + /** + * @brief Locate first occurrence of character in u16string + * @param p Pointer to the source + * @param ch The character to be found + * @return A pointer to the first occurrence of character in u16str + */ + const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch); + +/** +* @brief Copy the u16string pointed by source into the array pointed by destination +* @param dst Pointer to the destination +* @param src Pointer to the source to be copied +* @return Pointer to the destination +*/ -size_t u16len(const KMX_WCHAR* p); -int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q); -int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q); -int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count); -int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count); -const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max); const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src); -const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch); -const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch); -const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max); -KMX_WCHAR* u16tok(KMX_WCHAR* p, KMX_WCHAR ch, KMX_WCHAR** ctx); -KMX_WCHAR* u16tok(KMX_WCHAR* p, KMX_WCHAR* ch, KMX_WCHAR** ctx); -long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base); -double u16tof(KMX_WCHAR* str); +/** +* @brief Copy n characters of the u16string pointed by source into the array pointed by destination +* @param dst Pointer to the destination +* @param src Pointer to the source to be copied +* @param max Maximum number of characters to be copied +* @return Pointer to the destination +*/ +const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max); + +/** +* @brief Return the length of the u16string str +* @param p Pointer to the source +* @return The length of u16string +*/ +size_t u16len(const KMX_WCHAR* p); + +/** +* @brief Compare two u16strings +* @param p Pointer one u16string +* @param q Pointer another u16string +* @return 0 if strings are eqaual +* ! = 0 if unequal +*/ +int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q); + +/** +* @brief Case sensitive comparison of up to count characters in two strings +* @param p Pointer one u16string +* @param q Pointer another u16string +* @param count Maximum number of characters to compare +* @return 0 if strings are equal +* ! = 0 if unequal +*/ +int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count); -KMX_CHAR* strrchr_slash(KMX_CHAR* name); -const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* name); +/** +* @brief Case sensitive comparison of two strings +* @param p Pointer one u16string +* @param q Pointer another u16string +* @return 0 if strings are equal +* ! = 0 if unequal +*/ +int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q); + +/** +* @brief Comparison of up to count characters in two strings +* @param p Pointer one u16string +* @param q Pointer another u16string +* @param count Maximum number of characters to compare +* @return 0 if strings are equal +* ! = 0 if unequal +*/ +int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count); + +/** +* @brief Split u16string into tokens +* @param p Pointer to u16string to truncate. +* @param ch the delimiter character +* @param ctx the string until and without the delimiter +* @return Pointer to the destination or NULL +*/ +KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR ch, KMX_WCHAR** ctx); + +/** +* @brief Split u16string into tokens +* @param p Pointer to u16string to truncate. +* @param delim the delimiter character +* @param ctx the string until and without the delimiter +* @return Pointer to the destination or NULL +*/ +KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR* delim, KMX_WCHAR** ctx); + +/** +* @brief Convert a u16string to a double +* @param str Pointer to u16string +* @return double value equivalent to the string +*/ +double u16tof(KMX_WCHAR* str); #endif /* U16_H */ From 4688e4d09745af10307a003aa0ec7e7248fc00c2 Mon Sep 17 00:00:00 2001 From: Sabine Date: Thu, 25 Jul 2024 13:58:54 +0200 Subject: [PATCH 46/71] feat(mac): remove RALT filter --- mac/mcompile/mc_import_rules.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index bc98a272a35..b47a616ebc5 100644 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -451,10 +451,6 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe // Alt and Shift+Alt don't work, so skip them (ss 4+5) continue; } -//_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!! - /*if (ss == MenuCtrl || ss == ShftMenuCtrl) { - continue; - }*/ KMX_DWORD kc_underlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey); From 365d62ea308be84587203d4a7b0ee7046a79be6b Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 2 Aug 2024 12:18:11 +0200 Subject: [PATCH 47/71] feat(mac): include comments from PR 12065 --- mac/mcompile/keymap.cpp | 8 +-- mac/mcompile/keymap.h | 78 ++++++++++++------------- mac/mcompile/mc_import_rules.cpp | 18 +++--- mac/mcompile/mc_import_rules.h | 27 +++++---- mac/mcompile/mc_kmxfile.cpp | 44 +++++++------- mac/mcompile/mc_kmxfile.h | 22 +++---- mac/mcompile/mcompile.cpp | 99 ++++++++++++++------------------ mac/mcompile/mcompile.h | 1 - mac/mcompile/u16.cpp | 62 ++++++++++---------- mac/mcompile/u16.h | 84 +++++++++++++-------------- 10 files changed, 213 insertions(+), 230 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index d4be957a387..ad85c88f740 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -1,5 +1,5 @@ /* - * Keyman is copyright (C) SIL International. MIT License. + * Keyman is copyright (C) 2004 - 2024 SIL International. MIT License. * * Mnemonic layout support for mac * @@ -139,17 +139,17 @@ bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout) { TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); if (!source) { printf("ERROR: can't get source\n"); - return 1; + return TRUE; } CFDataRef layout_data = static_cast((TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData))); *keyboard_layout = reinterpret_cast(CFDataGetBytePtr(layout_data)); if (!keyboard_layout) { printf("ERROR: Can't get keyboard_layout\n"); - return 2; + return TRUE; } // intentionally leaking `source` in order to still be able to access `keyboard_layout` - return 0; + return FALSE; } /** @brief return the keyvalue for a given Keycode, shiftstate and caps */ diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index d96521aa9d2..666741b08cb 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -90,7 +90,7 @@ int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState); /** * @brief check for correct input parameter that will later be used in UCKeyTranslate() * @param shiftstate the currently used shiftstate - * @param keycode the code of the key in question + * @param keycode the code of the key in question * @return true if all parameters are OK; * false if not */ @@ -99,14 +99,14 @@ bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode); /** * @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard * all_vector [ US_Keyboard ] - * [KeyCode_US ] - * [Keyval unshifted ] - * [Keyval shifted ] + * [KeyCode_US ] + * [Keyval unshifted ] + * [Keyval shifted ] * [Underlying Kbd] - * [KeyCode_underlying] - * [Keyval unshifted ] - * [Keyval shifted ] - * @param[in,out] all_vector Vector that holds the data of the US keyboard as well as the currently used (underlying) keyboard + * [KeyCode_underlying] + * [Keyval unshifted ] + * [Keyval shifted ] + * @param[in,out] all_vector Vector that holds the data of the US keyboard as well as the currently used (underlying) keyboard * @param keyboard_layout pointer to currently used (underlying) keyboard layout * @return 0 on success; * 1 if data of US keyboard was not written; @@ -133,7 +133,7 @@ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss); /** * @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector all_vector - * @param[in,out] all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param[in,out] all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param keyboard_layout pointer to currently used (underlying) keybord layout * @return 0 on success; * 1 if the initialization of the underlying vector failes; @@ -143,7 +143,7 @@ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLay /** * @brief create a pointer to pointer of the current keyboard_layout for later use - * @param keyboard_layout pointer to pointer to currently used (underlying) keyborad layout + * @param keyboard_layout pointer to pointer to currently used (underlying) keyboard layout * @return 0 on success; * 1 if the display is not found; * 2 if the keymap is not found @@ -151,8 +151,8 @@ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLay bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout); /** - * @brief array of USVirtualKey-ScanCode-pairs - * we use the same type of array as throughout Keyman even though we have lots of unused fields + * @brief array of USVirtualKey-ScanCode-pairs + * we use the same type of array as throughout Keyman even though we have lots of unused fields */ const UINT mac_USVirtualKeyToScanCode[256] = { 0xFFFF, // not used @@ -414,8 +414,8 @@ const UINT mac_USVirtualKeyToScanCode[256] = { }; /** - * @brief array of ScanCode-USVirtualKey-pairs - * we use the same type of array as throughout Keyman even though we have lots of unused fields + * @brief array of ScanCode-USVirtualKey-pairs + * we use the same type of array as throughout Keyman even though we have lots of unused fields */ const UINT mac_ScanCodeToUSVirtualKey[128] = { 0x41, // L"K_A", // &H41 @@ -553,22 +553,22 @@ const UINT mac_ScanCodeToUSVirtualKey[128] = { * currently used (underlying) keyboard layout * "What character will be produced for a keypress of a key and modifier?" * @param keyboard_layout pointer to the currently used (underlying) keyboard layout - * @param keycode a key of the currently used keyboard layout - * @param shiftstate_mac a shiftstate of the currently used keyboard layout - * @param caps state of the caps key of the currently used keyboard layout + * @param keycode a key of the currently used keyboard layout + * @param shiftstate_mac a shiftstate of the currently used keyboard layout + * @param caps state of the caps key of the currently used keyboard layout * @return the keyval obtained from keycode, shiftstate and caps */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps); /** - * @brief return the keyvalue for a given Keycode, shiftstate and caps of the - * currently used (underlying) keyboard layout taking dk into account - * "What character will be produced for a keypress of a key and modifiers? - * @param keyboard_layout pointer to the currently used (underlying) keyboard layout - * @param keycode a key of the currently used keyboard layout - * @param shiftstate_mac a shiftstate of the currently used keyboard layout - * @param caps state of the caps key of the currently used keyboard layout - * @param[in,out] deadkeystate states wheter a deadkey was used or not + * @brief return the keyvalue for a given Keycode, shiftstate and caps of the + * currently used (underlying) keyboard layout taking dk into account + * "What character will be produced for a keypress of a key and modifiers? + * @param keyboard_layout pointer to the currently used (underlying) keyboard layout + * @param keycode a key of the currently used keyboard layout + * @param shiftstate_mac a shiftstate of the currently used keyboard layout + * @param caps state of the caps key of the currently used keyboard layout + * @param[in,out] deadkeystate states wheter a deadkey was used or not * @return the keyval obtained from keycode, shiftstate and caps */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32& deadkeystate); @@ -578,9 +578,9 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la * "What character will be produced for a keypress of a key and modifiers on the underlying keyboard? * If a deadkey was found return 0xFFFF and copy the deadkey into deadKey * @param keyboard_layout a pointer to the currently used (underlying) keyboard layout - * @param kc_underlying a key of the currently used keyboard - * @param vk_ShiftState a shiftstate of the currently used keyboard layout - * @param deadKey pointer to keyvalue if a deadkey was found; if not NULL + * @param kc_underlying a key of the currently used keyboard + * @param vk_ShiftState a shiftstate of the currently used keyboard layout + * @param deadKey pointer to keyvalue if a deadkey was found; if not NULL * @return 0xFFFF in case a deadkey was found, then the deadkey is stored in deadKey; * or else the keyval obtained from Keycode and shiftstate and caps; */ @@ -590,7 +590,7 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa * @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard * "What character is on the same position/shiftstats/caps on the currently used (underlying) keyboard as on the US keyboard?" * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param kv_us a keyvalue on the US keyboard + * @param kv_us a keyvalue on the US keyboard * @return keyval of the underlying keyboard if available; * else the keyval of the US keyboard */ @@ -599,7 +599,7 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, K /** * @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard * On what key of the underlying keyboard do we find a certain character? - * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param kv_underlying a keyvalue on the currently used (underlying) keyboard * @return keycode of the underlying keyboard if foundf; * else the keyval of the underlying keyboard @@ -610,10 +610,10 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_ * @brief return the keycode of the currently used (underlying) keyboard for a given keycode of a character on the US keyboard * "Where on an underlying keyboard do we find a character that is on a certain key on a US keyboard?" * @param keyboard_layout the currently used (underlying) keyboard layout - * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param kc_us a key of the US keyboard - * @param ss_win a Windows-type shiftstate - * @param caps state of the caps key + * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param kc_us a key of the US keyboard + * @param ss_win a Windows-type shiftstate + * @param caps state of the caps key * @return the keycode of the underlying keyboard if found; * else the keycode of the US keyboard */ @@ -641,11 +641,11 @@ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); * @brief return the keyvalue of a combination of deadkey + character if there is a combination available * "What character will be produced for a deadkey + a character?" e.g. '^' + 'a' -> 'â' * @param keyboard_layout the currently used (underlying)keyboard Layout - * @param vk_dk a keycode of a deadkey of the currently used (underlying) keyboard - * @param ss_dk a shiftstate of a deadkey of the currently used (underlying) keyboard - * @param vk_us a keycode of a character key on the currently used (underlying) keyboard to be combined to a dk - * @param shiftstate_mac a shiftstate of a character key on the currently used (underlying) keyboard - * @param caps state of the caps key of a character key on the currently used (underlying) keyboard + * @param vk_dk a keycode of a deadkey of the currently used (underlying) keyboard + * @param ss_dk a shiftstate of a deadkey of the currently used (underlying) keyboard + * @param vk_us a keycode of a character key on the currently used (underlying) keyboard to be combined to a dk + * @param shiftstate_mac a shiftstate of a character key on the currently used (underlying) keyboard + * @param caps state of the caps key of a character key on the currently used (underlying) keyboard * @return the combination of deadkey + character if it is available; * if not return 0 */ diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index b47a616ebc5..22674d51db1 100644 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -1,5 +1,5 @@ /* - * Keyman is copyright (C) 2004 SIL International. MIT License. + * Keyman is copyright (C) 2004 - 2024 SIL International. MIT License. * * Mnemonic layout support for mac */ @@ -94,7 +94,7 @@ KMX_WCHAR mac_KMX_DeadKeyMap(int index, std::vector*deadkeys, int dead return 0xFFFF; } -/** @brief Base class for dealing with rgkey*/ +/** @brief Base class for dealing with rgkey*/ class mac_KMX_VirtualKey { private: UINT m_vk; @@ -316,7 +316,7 @@ class mac_KMX_VirtualKey { } }; -/** @brief Base class for KMX_loader*/ +/** @brief Base class for KMX_loader*/ class mac_KMX_Loader { private: KMX_BYTE lpKeyStateNull[256]; @@ -382,8 +382,8 @@ class mac_KMX_Loader { }; /** - * @brief find the maximum index of a deadkey - * @param p pointer to deadkey + * @brief find the maximum index of a deadkey + * @param p pointer to deadkey * @return index of deadkey */ int mac_KMX_GetMaxDeadkeyIndex(KMX_WCHAR* p) { @@ -403,10 +403,10 @@ int mac_KMX_GetMaxDeadkeyIndex(KMX_WCHAR* p) { * On Linux the values of rgkey are sorted according to the VK of the the US keyboard * Since Linux Keyboards do not use a VK mcompile uses the VK of the the US keyboard because * these are available in mcompile through USVirtualKeyToScanCode/ScanCodeToUSVirtualKey and an offset of 8 - * @param kp pointer to keyboard - * @param all_vector vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param keyboard_layout the currently used (underlying)keyboard Layout - * @param FDeadkeys vector of all deadkeys for the currently used (underlying)keyboard Layout + * @param kp pointer to keyboard + * @param all_vector vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @param FDeadkeys vector of all deadkeys for the currently used (underlying)keyboard Layout * @param bDeadkeyConversion 1 to convert a deadkey to a character; 0 no conversion * @return true in case of success */ diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h index 033aab15208..f8a4e008787 100644 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -7,14 +7,14 @@ * Contrary to what the function name might suggest, the function the mac_KMX_ToUnicodeEx does NOT process surrogate pairs. * This is because it is used in mcompile only which only deals with latin scripts. * In case this function is used for surrogate pairs, they will be ignored and a message will be printed out - * @param keycode a key of the currently used keyboard Layout - * @param pwszBuff Buffer to store resulting character - * @param ss_rgkey a Windows-style shiftstate of the currently used keyboard Layout - * @param caps state of the caps key of the currently used keyboard Layout + * @param keycode a key of the currently used keyboard Layout + * @param pwszBuff Buffer to store resulting character + * @param ss_rgkey a Windows-style shiftstate of the currently used keyboard Layout + * @param caps state of the caps key of the currently used keyboard Layout * @param keyboard_layout the currently used (underlying)keyboard Layout - * @return -1 if a deadkey was found; - * 0 if no translation is available; - * +1 if character was found and written to pwszBuff + * @return -1 if a deadkey was found; + * 0 if no translation is available; + * +1 if character was found and written to pwszBuff */ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_rgkey, int caps, const UCKeyboardLayout* keyboard_layout); @@ -27,8 +27,8 @@ class DeadKey { public: /** - * @brief Constructor - * @param deadCharacter a deadkey + * @brief Constructor + * @param deadCharacter a deadkey */ DeadKey(KMX_WCHAR deadCharacter); @@ -39,10 +39,9 @@ class DeadKey { KMX_WCHAR KMX_DeadCharacter(); /** - * @brief set member variable with base and combined character - * @param baseCharacter the base character + * @brief set member variable with base and combined character + * @param baseCharacter the base character * @param combinedCharacter the combined character - * @return void */ void KMX_AddDeadKeyRow(KMX_WCHAR baseCharacter, KMX_WCHAR combinedCharacter); @@ -67,8 +66,8 @@ class DeadKey { } /** - * @brief check if character exists in DeadKey - * @param baseCharacter a character to be found + * @brief check if character exists in DeadKey + * @param baseCharacter a character to be found * @return true if found; false if not found */ bool KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter); diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index 991ceaf0e38..0e6e7133657 100644 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -1,5 +1,5 @@ /* - * Keyman is copyright (C) SIL International. MIT License. + * Keyman is copyright (C) 2004 - 2024 SIL International. MIT License. * * Mnemonic layout support for mac */ @@ -42,29 +42,29 @@ const int CODE__SIZE[] = { }; /** - * @brief check if the file has correct version - * @param filebase containing data of the input file - * @param file_size a size + * @brief check if the file has correct version + * @param filebase containing data of the input file + * @param file_size a size * @return true if successful; * false if not */ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size); /** - * @brief Fixup the keyboard by expanding pointers. On disk the pointers are stored relative to the - * beginning of the file, but we need real pointers. This method is used on 32-bit architectures. - * @param bufp pointer to buffer where data will be copied into - * @param base pointer to starting point - * @param dwFileSize size of the file + * @brief Fixup the keyboard by expanding pointers. On disk the pointers are stored relative to the + * beginning of the file, but we need real pointers. This method is used on 32-bit architectures. + * @param bufp pointer to buffer where data will be copied into + * @param base pointer to starting point + * @param dwFileSize size of the file * @return pointer to the keyboard */ LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize); /** - * @brief Save a Keyboard to a file - * @param fk pointer to the keyboard - * @param hOutfile pointer to the output file - * @param FSaveDebug + * @brief Save a Keyboard to a file + * @param fk pointer to the keyboard + * @param hOutfile pointer to the output file + * @param FSaveDebug * @return an Error in case of failure */ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug) { @@ -251,9 +251,9 @@ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName) { } /** - * @brief add an offset - * @param base pointer to starting point - * @param offset a given offset + * @brief add an offset + * @param base pointer to starting point + * @param offset a given offset * @return pointer to base + offset */ PKMX_WCHAR KMX_StringOffset(PKMX_BYTE base, KMX_DWORD offset) { @@ -265,12 +265,12 @@ PKMX_WCHAR KMX_StringOffset(PKMX_BYTE base, KMX_DWORD offset) { #ifdef KMX_64BIT /** - * @brief CopyKeyboard will copy the data into bufp from x86-sized structures into - * x64-sized structures starting at `base`. After this function finishes, we still - * need to keep the original data because we don't copy the strings. The method is - * used on 64-bit architectures. - * @param bufp pointer to buffer where data is copied into - * @param base pointer to starting point + * @brief CopyKeyboard will copy the data into bufp from x86-sized structures into + * x64-sized structures starting at `base`. After this function finishes, we still + * need to keep the original data because we don't copy the strings. The method is + * used on 64-bit architectures. + * @param bufp pointer to buffer where data is copied into + * @param base pointer to starting point * @return pointer to the keyboard */ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index 8946c45eee5..3914aca1825 100644 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -66,32 +66,32 @@ typedef struct KMX_tagKEYBOARD { } KMX_KEYBOARD, *LPKMX_KEYBOARD; /** - * @brief load a keyboard kmx-file - * @param fileName pointer to fileName of kmx-file - * @param [in,out] lpKeyboard pointer to pointer to keyboard + * @brief load a keyboard kmx-file + * @param fileName pointer to fileName of kmx-file + * @param[in,out] lpKeyboard pointer to pointer to keyboard * @return TRUE on success; else FALSE */ KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard); /** - * @brief save keyboard to file - * @param kbd pointer to the keyboard - * @param fileName pointer to fileName of a kmx-file + * @brief save keyboard to file + * @param kbd pointer to the keyboard + * @param fileName pointer to fileName of a kmx-file * @return TRUE on success; else FALSE */ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName); /** - * @brief increment in a string - * @param p pointer to a character + * @brief increment in a string + * @param p pointer to a character * @return pointer to the incremented character */ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); /** - * @brief open a file - * @param Filename name of the file - * @param mode same as mode in fopen + * @brief open a file + * @param Filename name of the file + * @param mode same as mode in fopen * @return pointer to file. On error, returns a null pointer */ FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 1bf013b1453..dfdb5193463 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -1,5 +1,5 @@ /* - * Keyman is copyright (C) 2004 SIL International. MIT License. + * Keyman is copyright (C) 2004 - 2024 SIL International. MIT License. * * Mnemonic layout support for mac * @@ -16,9 +16,9 @@ /** * @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard - * @param kbd pointer to US keyboard + * @param kbd pointer to US keyboard * @param bDeadkeyConversion option for converting a deadkey to a character: 1 = dk conversion; 0 = no dk conversion - * @param argc number of command line arguments + * @param argc number of command line arguments * @return TRUE if conversion was successful; * FALSE if not */ @@ -38,12 +38,12 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D &all_vector, const UCKe int mac_run(int argc, char* argv[]); /** - * @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard - * @param keyboard_layout pointer to the currently used (underlying) keyboard Layout - * @param all_vector vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param deadkey deadkey character - * @param shift_dk shiftstate opf a deadkey character - * @param [out] outputPairs pointer to array of [usvk, ch_out] pairs + * @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard + * @param keyboard_layout pointer to the currently used (underlying) keyboard Layout + * @param all_vector vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param deadkey deadkey character + * @param shift_dk shiftstate opf a deadkey character + * @param[out] outputPairs pointer to array of [usvk, ch_out] pairs * @return size of array of [usvk, ch_out] pairs */ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* outputPairs); // returns array of [usvk, ch_out] pairs @@ -168,11 +168,10 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG | RALTFLAG, K_SHIFTFLAG | /** * @brief translate each key of a group: remap the content of a key (key->Key) of the US keyboard to a character (ch) - * @param key pointer to a key - * @param vk a keyvalue of the US keyboard + * @param key pointer to a key + * @param vk a keyvalue of the US keyboard * @param shift shiftstate - * @param ch character of the underlying keyboard to be remapped - * @return void + * @param ch character of the underlying keyboard to be remapped */ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. @@ -202,10 +201,9 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) /** * @brief translate a group of a keyboard * @param group pointer to a keyboard group - * @param vk a keyvalue of the US keyboard + * @param vk a keyvalue of the US keyboard * @param shift shiftstate - * @param ch character of the underlying keyboard to be remapped - * @return void + * @param ch character of the underlying keyboard to be remapped */ void mac_KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { for (unsigned int i = 0; i < group->cxKeyArray; i++) { @@ -215,11 +213,10 @@ void mac_KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHA /** * @brief translate a keyboard - * @param kbd pointer to the US keyboard - * @param vk a keyvalue of the US keyboard + * @param kbd pointer to the US keyboard + * @param vk a keyvalue of the US keyboard * @param shift shiftstate - * @param ch character of the underlying keyboard to be remapped - * @return void + * @param ch character of the underlying keyboard to be remapped */ void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { for (unsigned int i = 0; i < kbd->cxGroupArray; i++) { @@ -232,7 +229,6 @@ void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_ /** * @brief check key for unconverted key rules * @param key pointer to a key - * @return void */ void mac_KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { if (key->ShiftFlags == 0) { @@ -245,7 +241,6 @@ void mac_KMX_ReportUnconvertedKeyRule(LPKMX_KEY key) { /** * @brief check a group for unconverted rules * @param group pointer to a keyboard group - * @return void */ void mac_KMX_ReportUnconvertedGroupRules(LPKMX_GROUP group) { for (unsigned int i = 0; i < group->cxKeyArray; i++) { @@ -256,7 +251,6 @@ void mac_KMX_ReportUnconvertedGroupRules(LPKMX_GROUP group) { /** * @brief check a keyboard for unconverted rules * @param kbd pointer to the US keyboard - * @return void */ void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { for (unsigned int i = 0; i < kbd->cxGroupArray; i++) { @@ -268,12 +262,11 @@ void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { /** * @brief remap the content of a key (key->dpContext) of the US keyboard to a deadkey sequence - * @param key pointer to a key + * @param key pointer to a key * @param deadkey a deadkey to be remapped - * @param vk a keyvalue of the US keyboard - * @param shift shiftstate - * @param ch character of the underlying keyboard - * @return void + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate + * @param ch character of the underlying keyboard */ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { if ((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) { @@ -306,12 +299,11 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, /** * @brief translate a group - * @param group pointer to a keyboard group - * @param a deadkey to be remapped - * @param vk a keyvalue of the US keyboard - * @param shift shiftstate + * @param group pointer to a keyboard group + * @param a deadkey to be remapped + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate * @param character of the underlying keyboard - * @return void */ void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { for (unsigned int i = 0; i < group->cxKeyArray; i++) { @@ -321,12 +313,11 @@ void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group, KMX_WCHAR deadkey, KMX_WOR /** * @brief translate a keyboard - * @param kbd pointer to the US keyboard - * @param a deadkey to be remapped - * @param vk a keyvalue of the US keyboard - * @param shift shiftstate + * @param kbd pointer to the US keyboard + * @param a deadkey to be remapped + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate * @param character of the underlying keyboard - * @return void */ void mac_KMX_TranslateDeadkeyKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { for (unsigned int i = 0; i < kbd->cxGroupArray; i++) { @@ -338,11 +329,10 @@ void mac_KMX_TranslateDeadkeyKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX /** * @brief add a deadkey rule - * @param kbd pointer to the US keyboard + * @param kbd pointer to the US keyboard * @param deadkey a deadkey to be added - * @param vk a keyvalue of the US keyboard - * @param shift shiftstate - * @return void + * @param vk a keyvalue of the US keyboard + * @param shift shiftstate */ void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. @@ -397,7 +387,7 @@ struct KMX_dkidmap { /** * @brief find the deadkey id for a given deadkey - * @param kbd pointer to the keyboard + * @param kbd pointer to the keyboard * @param deadkey for which an id is to be found * @return 0 if failed; * otherwise a deadkey-id @@ -454,14 +444,13 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { /** * @brief Lookup the deadkey table for the deadkey in the physical keyboard. Then for each character, go through and map it through - * @param kbd pointer to the keyboard - * @param vk_US virtual key of the us keyboard - * @param shift shiftstate - * @param deadkey character produced by a deadkey + * @param kbd pointer to the keyboard + * @param vk_US virtual key of the us keyboard + * @param shift shiftstate + * @param deadkey character produced by a deadkey * @param all_vector vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param keymap pointer to the currently used (underlying) keyboard Layout - * @param dk_Table a vector of all possible deadkey combinations for all Linux keyboards - * @return void + * @param keymap pointer to the currently used (underlying) keyboard Layout + * @param dk_Table a vector of all possible deadkey combinations for all Linux keyboards */ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { KMX_WORD deadkeys[512] = {0}; @@ -577,11 +566,11 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int /** * @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard - * @param keyboard_layout the currently used (underlying) keyboard Layout - * @param all_vector Vector that holds the data of the US keyboard and the currently used (under lying) keyboard - * @param deadkey deadkey character - * @param shift_dk shiftstate of the deadkey - * @param [out] outputPairs pointer to array of [usvk, ch_out] pairs + * @param keyboard_layout the currently used (underlying) keyboard Layout + * @param all_vector Vector that holds the data of the US keyboard and the currently used (under lying) keyboard + * @param deadkey deadkey character + * @param shift_dk shiftstate of the deadkey + * @param[out] outputPairs pointer to array of [usvk, ch_out] pairs * @return size of array of [usvk, ch_out] pairs */ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* outputPairs) { diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 6da2c400806..e1a3cb08fe6 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -36,7 +36,6 @@ extern std::vector KMX_FDeadkeys; // I4353 /** * @brief print (error) messages * @param fmt text to print - * @return void */ void mac_KMX_LogError(const wchar_t* fmt, ...); diff --git a/mac/mcompile/u16.cpp b/mac/mcompile/u16.cpp index 17845538d1d..caa5ca0fa9b 100644 --- a/mac/mcompile/u16.cpp +++ b/mac/mcompile/u16.cpp @@ -1,5 +1,5 @@ /* - * Keyman is copyright 2024 (C) SIL International. MIT License. + * Keyman is copyright (C) 2004 - 2024 SIL International. MIT License. * * Functions for u16string */ @@ -10,10 +10,10 @@ #include #include "../../core/src/utfcodec.hpp" -// String <- wstring +// string <- wstring /** @brief Obtain a std::string from a std::wstring */ -std::string string_from_wstring(std::wstring const str) { - return convert((const std::wstring)str); +std::string string_from_wstring(std::wstring const wstr) { + return convert((const std::wstring)wstr); } // wstring <- string @@ -23,35 +23,33 @@ std::wstring wstring_from_string(std::string const str) { } // u16String <- string -/** @brief Obtain a std::string from a std::wstring */ std::u16string u16string_from_string(std::string const str) { return convert((const std::string)str); } // string <- u16string -/** @brief Obtain a std::string from a std::u16string */ -std::string string_from_u16string(std::u16string const str) { - return convert((const std::u16string)str); +//** @brief Obtain a std::string from a std::u16string */ +std::string string_from_u16string(std::u16string const str16) { + return convert((const std::u16string)str16); } + // wstring <- u16string /** @brief Obtain a std::wstring from a std::u16string */ -std::wstring wstring_from_u16string(std::u16string const str) { - std::string s = convert((const std::u16string)str); - std::wstring ws = convert((const std::string)s); - return ws; +std::wstring wstring_from_u16string(std::u16string const str16) { + return convert((const std::u16string)str16); } + // u16string <- wstring -/** @brief Obtain a std::u16string from a std::wstring */ -std::u16string u16string_from_wstring(std::wstring const str) { - std::string s = convert((const std::wstring)str); - std::u16string utf16 = convert((const std::string)s); - return utf16; +/** @brief Obtain a std::u16string from a std::wstring */ +std::u16string u16string_from_wstring(std::wstring const wstr) { + return convert((const std::wstring)wstr);; } + // UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) -/** @brief @brief Convert pointer to wchar_t to pointer to char16_t and copy sz elements into dst */ +/** @brief Convert pointer to wchar_t to pointer to char16_t and copy sz elements into dst */ void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...) { wchar_t* wbuf = new wchar_t[sz]; va_list args; @@ -64,7 +62,7 @@ void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...) { delete[] wbuf; } -/** @brief @brief Convert u16string to long integer */ +/** @brief Convert u16string to long integer */ long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) { auto s = string_from_u16string(str); char* t; @@ -74,7 +72,7 @@ long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) { return result; } -/** @brief Append n characters from u16string */ +/** @brief Append max characters from u16string */ const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { KMX_WCHAR* o = dst; dst = (KMX_WCHAR*)u16chr(dst, 0); @@ -88,7 +86,7 @@ const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { return o; } -/** @brief Append a '/' or '\\' to an array of char16_t */ +/** @brief find last '/' or '\\' in an array of char16_t */ const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* name) { const KMX_WCHAR* cp = NULL; cp = u16rchr(name, '\\'); @@ -97,7 +95,7 @@ const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* name) { return cp; } -/** @brief Append a '/' or '\\' to an array of char */ +/** @brief find last '/' or '\\' in an array of char */ KMX_CHAR* strrchr_slash(KMX_CHAR* name) { KMX_CHAR* cp = NULL; cp = strrchr(name, '\\'); @@ -108,11 +106,9 @@ KMX_CHAR* strrchr_slash(KMX_CHAR* name) { /** @brief Locate last occurrence of character in u16string */ const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch) { - const KMX_WCHAR* p_end = p + u16len(p) - 1; + const KMX_WCHAR* p_end = p + u16len(p); - if (ch == '\0') - return p_end + 1; - while (p_end >= p) { + while (p_end > p) { if (*p_end == ch) return p_end; p_end--; @@ -120,7 +116,7 @@ const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch) { return NULL; } -/** @brief @brief Locate first occurrence of character in u16string */ +/** @brief Locate first occurrence of character in u16string */ const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch) { while (*p) { if (*p == ch) @@ -130,7 +126,7 @@ const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch) { return ch == 0 ? p : NULL; } -/** @brief @brief Copy the u16string pointed to by source into the array pointed to by destination */ +/** @brief Copy the u16string pointed to by source into the array pointed to by destination */ const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src) { KMX_WCHAR* o = dst; while (*src) { @@ -140,7 +136,7 @@ const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src) { return o; } -/** @brief Copy n characters of the u16string pointed to by source into the array pointed to by destination */ +/** @brief Copy max characters of the u16string pointed to by source into the array pointed to by destination */ const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { KMX_WCHAR* o = dst; while (*src && max > 0) { @@ -153,7 +149,7 @@ const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { return o; } -/** @brief @brief Return the length of the u16string str */ +/** @brief Return the length of the u16string str */ size_t u16len(const KMX_WCHAR* p) { int i = 0; while (*p) { @@ -163,7 +159,7 @@ size_t u16len(const KMX_WCHAR* p) { return i; } -/** @brief @brief Compare two u16strings */ +/** @brief Compare two u16strings */ int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q) { while (*p && *q) { if (*p != *q) @@ -174,7 +170,7 @@ int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q) { return *p - *q; } -/** @brief @brief Case sensitive comparison of up to count characters in two strings */ +/** @brief Case insensitive comparison of up to count characters in two strings */ int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { while (*p && *q && count) { if (toupper(*p) != toupper(*q)) @@ -188,7 +184,7 @@ int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { return 0; } -/** @brief @brief Case sensitive comparison of two strings */ +/** @brief Case insensitive comparison of two strings */ int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q) { while (*p && *q) { if (toupper(*p) != toupper(*q)) diff --git a/mac/mcompile/u16.h b/mac/mcompile/u16.h index 790d2db226d..f83b792cf80 100644 --- a/mac/mcompile/u16.h +++ b/mac/mcompile/u16.h @@ -13,10 +13,10 @@ /** * @brief Obtain a std::string from a std::wstring -* @param str the std::wstring to be converted +* @param wstr the std::wstring to be converted * @return a std::string */ -std::string string_from_wstring(std::wstring const str); +std::string string_from_wstring(std::wstring const wstr); /** * @brief Obtain a std::wstring from a std::string @@ -26,37 +26,37 @@ std::string string_from_wstring(std::wstring const str); std::wstring wstring_from_string(std::string const str); /** -* @brief Obtain a std::string from a std::wstring -* @param str the std::wstring to be converted -* @return a std::string +* @brief Obtain a std::u16tring from a std::string +* @param str the std::string to be converted +* @return a std::u16string */ std::u16string u16string_from_string(std::string const str); /** * @brief Obtain a std::string from a std::u16string -* @param str the std::string to be converted -* @return a std::u16string +* @param str16 the std::u16string to be converted +* @return a std::string */ -std::string string_from_u16string(std::u16string const str); +std::string string_from_u16string(std::u16string const str16); /** * @brief Obtain a std::wstring from a std::u16string -* @param str the std::u16string to be converted +* @param str16 the std::u16string to be converted * @return a std::wstring */ -std::wstring wstring_from_u16string(std::u16string const str); +std::wstring wstring_from_u16string(std::u16string const str16); /** * @brief Obtain a std::u16string from a std::wstring -* @param str the std::wstring to be converted +* @param wstr the std::wstring to be converted * @return a std::u16string */ -std::u16string u16string_from_wstring(std::wstring const str); +std::u16string u16string_from_wstring(std::wstring const wstr); /** * @brief Convert pointer to wchar_t to pointer to char16_t and copy sz elements into dst * @param dst destination -* @param sz nr of characters to be copied +* @param sz nr of characters to be copied * @param fmt source to convert and copy * @return void */ @@ -64,10 +64,10 @@ void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...); /** * @brief Convert u16string to long integer -* @param str u16string beginning with the representation of an integral number. +* @param str u16string beginning with the representation of an integral number. * @param endptr Reference to the next character in str -* @param base Numerical base (radix) that determines the valid characters and their interpretation -* @return a std::string +* @param base Numerical base (radix) that determines the valid characters and their interpretation +* @return a long */ long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base); @@ -81,21 +81,21 @@ long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base); const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max); /** - * @brief Append a '/' or '\\' to an array of char16_t + * @brief Find last '/' or '\\' in an array of char * @param Name Pointer to the source - * @return Pointer to the source with slash/backslash added + * @return Pointer to the last slash/backslash */ const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name); /** - * @brief Append a '/' or '\\' to an array of char + * @brief Find last '/' or '\\' in an array of char16_t * @param Name Pointer to the source - * @return Pointer to the source with slash/backslash added + * @return Pointer to the last slash/backslash */ KMX_CHAR* strrchr_slash(KMX_CHAR* Name); /** * @brief Locate last occurrence of character in u16string - * @param p Pointer to the source + * @param p Pointer to the source * @param ch The character to be found * @return A pointer to the last occurrence of character in u16str */ @@ -103,26 +103,26 @@ long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base); /** * @brief Locate first occurrence of character in u16string - * @param p Pointer to the source + * @param p Pointer to the source * @param ch The character to be found * @return A pointer to the first occurrence of character in u16str */ const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch); /** -* @brief Copy the u16string pointed by source into the array pointed by destination +* @brief Copy the u16string pointed by src into the array pointed by dst * @param dst Pointer to the destination * @param src Pointer to the source to be copied -* @return Pointer to the destination +* @return Pointer to dst */ - const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src); + /** -* @brief Copy n characters of the u16string pointed by source into the array pointed by destination +* @brief Copy max characters of the u16string pointed by src into the array pointed by dst * @param dst Pointer to the destination * @param src Pointer to the source to be copied * @param max Maximum number of characters to be copied -* @return Pointer to the destination +* @return Pointer to dst */ const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max); @@ -143,9 +143,9 @@ size_t u16len(const KMX_WCHAR* p); int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q); /** -* @brief Case sensitive comparison of up to count characters in two strings -* @param p Pointer one u16string -* @param q Pointer another u16string +* @brief Case insensitive comparison of up to count characters in two strings +* @param p Pointer one u16string +* @param q Pointer another u16string * @param count Maximum number of characters to compare * @return 0 if strings are equal * ! = 0 if unequal @@ -153,7 +153,7 @@ int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q); int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count); /** -* @brief Case sensitive comparison of two strings +* @brief Case insensitive comparison of two strings * @param p Pointer one u16string * @param q Pointer another u16string * @return 0 if strings are equal @@ -163,8 +163,8 @@ int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q); /** * @brief Comparison of up to count characters in two strings -* @param p Pointer one u16string -* @param q Pointer another u16string +* @param p Pointer one u16string +* @param q Pointer another u16string * @param count Maximum number of characters to compare * @return 0 if strings are equal * ! = 0 if unequal @@ -173,21 +173,21 @@ int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count); /** * @brief Split u16string into tokens -* @param p Pointer to u16string to truncate. -* @param ch the delimiter character -* @param ctx the string until and without the delimiter -* @return Pointer to the destination or NULL +* @param p Pointer to u16string to parse +* @param ch the delimiter character +* @param ctx the remaining string after the first delimiter +* @return Pointer to the first token in p */ KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR ch, KMX_WCHAR** ctx); /** * @brief Split u16string into tokens -* @param p Pointer to u16string to truncate. -* @param delim the delimiter character -* @param ctx the string until and without the delimiter -* @return Pointer to the destination or NULL +* @param p Pointer to u16string to parse +* @param delimiters an array of delimiter characters +* @param ctx the remaining string after the first delimiter +* @return Pointer to the first token in p */ -KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR* delim, KMX_WCHAR** ctx); +KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR* delimiters, KMX_WCHAR** ctx); /** * @brief Convert a u16string to a double From 53ece797ba248dd1323844630bfab8304687f51f Mon Sep 17 00:00:00 2001 From: Sabine Date: Tue, 6 Aug 2024 10:58:28 +0200 Subject: [PATCH 48/71] feat(mac): swapped comments --- mac/mcompile/keymap.cpp | 173 ++++++++++++++++++++++++++--- mac/mcompile/keymap.h | 171 +++-------------------------- mac/mcompile/mc_import_rules.cpp | 47 ++++++-- mac/mcompile/mc_import_rules.h | 39 ++----- mac/mcompile/mc_kmxfile.cpp | 63 +++++++---- mac/mcompile/mc_kmxfile.h | 27 +---- mac/mcompile/mcompile.cpp | 51 ++++----- mac/mcompile/mcompile.h | 5 +- mac/mcompile/u16.cpp | 172 +++++++++++++++++++++++------ mac/mcompile/u16.h | 182 ++++++------------------------- 10 files changed, 461 insertions(+), 469 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index ad85c88f740..c3ea47c9797 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -13,7 +13,15 @@ #include "keymap.h" #include "kmx_file.h" -/** @brief map a shiftstate used on Windows to a shiftstate suitable for UCKeyTranslate() on the mac */ +/** + * @brief map a shiftstate used on Windows to a shiftstate suitable for UCKeyTranslate() on the mac + * Windows: (Base: 00000000 (0); Shift 00010000 (16); AltGr 00001001 (9); Shift+AltGr 00011001 (25)) + * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10 ) + * @param shiftState shiftstate used on Windows + * @return a shiftstate usable for UCKeyTranslate() on mac if available + * if shiftState is a Windows ShiftState: convert the Windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) + * if shiftState is NOT a Windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate + */ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) { if (shiftState == 0) return MAC_BASE; // Win ss 0 -> mac ss 0 else if (shiftState == K_SHIFTFLAG) return MAC_SHIFT; // Win ss 16 -> mac ss 2 @@ -22,7 +30,15 @@ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) { else return shiftState; // Win ss x -> mac ss x } -/** @brief map a shiftstate used in rgkey (a vector of VirtualKey*) to a shiftstate suitable for UCKeyTranslate() on the mac */ +/** + * @brief map a shiftstate used in rgkey (a vector of VirtualKey*) to a shiftstate suitable for UCKeyTranslate() on the mac + * rgkey: (Base: 0; Shift 1; OPT 6; Shift+OPT 7 ) + * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10) + * @param rgkey_ShiftState shiftstate used in rgkey + * @return a shiftstate usable for UCKeyTranslate() on mac if available + * if shiftState is a Windows ShiftState: convert the Windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) + * if shiftState is NOT a Windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate + */ int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState) { if (rgkey_ShiftState == 0) return MAC_BASE; else if (rgkey_ShiftState == 1) return MAC_SHIFT; @@ -31,7 +47,13 @@ int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState) { else return rgkey_ShiftState; } -/** @brief check for correct input parameter that will later be used in UCKeyTranslate() */ +/** + * @brief check for correct input parameter that will later be used in UCKeyTranslate() + * @param shiftstate the currently used shiftstate + * @param keycode the code of the key in question + * @return true if all parameters are OK; + * false if not + */ bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode) { if (!(std::find(std::begin(ss_mac), std::end(ss_mac), shiftstate) != std::end(ss_mac))) return false; @@ -42,7 +64,22 @@ bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode) { return true; } -/** @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard */ +/** + * @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard + * all_vector [ US_Keyboard ] + * [KeyCode_US ] + * [Keyval unshifted ] + * [Keyval shifted ] + * [Underlying Kbd] + * [KeyCode_underlying] + * [Keyval unshifted ] + * [Keyval shifted ] + * @param[in,out] all_vector Vector that holds the data of the US keyboard as well as the currently used (underlying) keyboard + * @param keyboard_layout pointer to currently used (underlying) keyboard layout + * @return 0 on success; + * 1 if data of US keyboard was not written; + * 2 if data of underlying keyboard was not written + */ int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { // store contents of the English (US) keyboard in all_vector if (mac_write_US_ToVector(all_vector)) { @@ -58,7 +95,13 @@ int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeybo return 0; } -/** @brief write data of the US keyboard into a 3D-Vector */ +/** + * @brief write data of the US keyboard into a 3D-Vector which later will contain + * data of the US keyboard and the currently used (underlying) keyboard + * @param[in,out] vec_us Vector that holds the data of the US keyboard + * @return 0 on success; + * 1 if data of US keyboard was not written; + */ int mac_write_US_ToVector(vec_dword_3D& vec_us) { // Values for US : A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P,CR, L, J, ', K, ;, \, ,, /, N, M, . std::vector us_Base = {97,115,100,102,104,103,122,120,99,118,167,98,113,119,101,114,121,116,49,50,51,52,54,53,61,57,55,45,56,48, 93,111,117, 91,105,112,13,108,106,39,107,59, 92,44,47,110,109,46}; @@ -86,7 +129,12 @@ int mac_write_US_ToVector(vec_dword_3D& vec_us) { return 0; } -/** @brief create an 2D-Vector with all fields initialized to INVALID_NAME */ +/** + * @brief create an 2D-Vector with all fields initialized to INVALID_NAME + * @param dim_rows number of rows in vector + * @param dim_ss number of columns in vector + * @return the 2D-Vector + */ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss) { vec_dword_1D shifts; vec_dword_2D vector_2D; @@ -101,7 +149,14 @@ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss) { return vector_2D; } -/** @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector */ +/** + * @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector all_vector + * @param[in,out] all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param keyboard_layout pointer to currently used (underlying) keybord layout + * @return 0 on success; + * 1 if the initialization of the underlying vector failes; + * 2 if data of less than 2 keyboards is contained in all_vector; + */ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { if (all_vector.size() != 1) { printf("ERROR: data for US keyboard not correct\n"); @@ -134,7 +189,13 @@ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLay return 0; } -/** @brief create a pointer to pointer of the current keymap for later use */ +/** + * @brief create a pointer to pointer of the current keyboard_layout for later use + * @param keyboard_layout pointer to pointer to currently used (underlying) keyboard layout + * @return 0 on success; + * 1 if the display is not found; + * 2 if the keymap is not found + */ bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout) { TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); if (!source) { @@ -152,7 +213,16 @@ bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout) { return FALSE; } -/** @brief return the keyvalue for a given Keycode, shiftstate and caps */ +/** + * @brief return the keyvalue for a given Keycode, shiftstate and caps of the + * currently used (underlying) keyboard layout + * "What character will be produced for a keypress of a key and modifier?" + * @param keyboard_layout pointer to the currently used (underlying) keyboard layout + * @param keycode a key of the currently used keyboard layout + * @param shiftstate_mac a shiftstate of the currently used keyboard layout + * @param caps state of the caps key of the currently used keyboard layout + * @return the keyval obtained from keycode, shiftstate and caps + */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps) { UInt32 deadkeystate; UniCharCount maxStringlength = 5; @@ -182,7 +252,17 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou } } -/** @brief return the keyvalue for a given Keycode, shiftstate and caps */ +/** + * @brief return the keyvalue for a given Keycode, shiftstate and caps of the + * currently used (underlying) keyboard layout taking dk into account + * "What character will be produced for a keypress of a key and modifiers? + * @param keyboard_layout pointer to the currently used (underlying) keyboard layout + * @param keycode a key of the currently used keyboard layout + * @param shiftstate_mac a shiftstate of the currently used keyboard layout + * @param caps state of the caps key of the currently used keyboard layout + * @param[in,out] deadkeystate states wheter a deadkey was used or not + * @return the keyval obtained from keycode, shiftstate and caps + */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32& deadkeystate) { UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; @@ -211,7 +291,17 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la return unicodeString[0]; // combined char e.g. 'â' } -/** @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. */ +/** + * @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. + * "What character will be produced for a keypress of a key and modifiers on the underlying keyboard? + * If a deadkey was found return 0xFFFF and copy the deadkey into deadKey + * @param keyboard_layout a pointer to the currently used (underlying) keyboard layout + * @param kc_underlying a key of the currently used keyboard + * @param vk_ShiftState a shiftstate of the currently used keyboard layout + * @param deadKey pointer to keyvalue if a deadkey was found; if not NULL + * @return 0xFFFF in case a deadkey was found, then the deadkey is stored in deadKey; + * or else the keyval obtained from Keycode and shiftstate and caps; + */ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey) { PKMX_WCHAR dky = NULL; UInt32 isdk = 0; @@ -233,7 +323,14 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa return keyV; } -/** @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard */ +/** + * @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard + * "What character is on the same position/shiftstats/caps on the currently used (underlying) keyboard as on the US keyboard?" + * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param kv_us a keyvalue on the US keyboard + * @return keyval of the underlying keyboard if available; + * else the keyval of the US keyboard + */ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us) { // look for kv_us for any shiftstate of US keyboard for (int i = 0; i < (int)all_vector[0].size() - 1; i++) { @@ -245,7 +342,14 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, K return kv_us; } -/** @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard */ +/** + * @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard + * On what key of the underlying keyboard do we find a certain character? + * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param kv_underlying a keyvalue on the currently used (underlying) keyboard + * @return keycode of the underlying keyboard if foundf; + * else the keyval of the underlying keyboard + */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying) { // look for kv_us for any shiftstate of US keyboard for (int i = 0; i < all_vector[1].size() - 1; i++) { @@ -258,7 +362,17 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_ return kv_underlying; } -/** @brief return the keycode of the currently used (underlying) keyboard for a given keycode of a character on the US keyboard */ +/** + * @brief return the keycode of the currently used (underlying) keyboard for a given keycode of a character on the US keyboard + * "Where on an underlying keyboard do we find a character that is on a certain key on a US keyboard?" + * @param keyboard_layout the currently used (underlying) keyboard layout + * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard + * @param kc_us a key of the US keyboard + * @param ss_win a Windows-type shiftstate + * @param caps state of the caps key + * @return the keycode of the underlying keyboard if found; + * else the keycode of the US keyboard + */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) { // first get the keyvalue kv of the key on the US keyboard (kc_us) KMX_DWORD kv = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_win), caps); @@ -273,20 +387,43 @@ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* k return kc_us; } -/** @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard */ +/** + * @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard + * "Where on an underlying keyboard do we find a character of a US keyboard?" + * @param virtualKeyUS a virtual key of the US keyboard + * @return the keycode of the currently used (underlying) keyboard + * 0xFFFF if the key is not used + */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD virtualKeyUS) { // on the mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an 'artificial' us virtual key from a keycode return (mac_USVirtualKeyToScanCode[virtualKeyUS]); } -/** @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard */ +/** + * @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard + * "Which character is found on a key of the US keyboard?" + * @param keycode a keycode of the currently used (underlying) keyboard + * @return the virtual key of the US keyboard + * 0 if the key is not used + */ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { // on the mac virtual keys do not exist. Nevertheless we can use this mapping to obtain a keycode from an 'artificial' us virtual key return mac_ScanCodeToUSVirtualKey[keycode]; } -/** @brief return the keyvalue of a combination of deadkey + character if there is a combination available */ -KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, int vk_dk, KMX_DWORD ss_dk, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps) { +/** + * @brief return the keyvalue of a combination of deadkey + character if there is a combination available + * "What character will be produced for a deadkey + a character?" e.g. '^' + 'a' -> 'â' + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @param vk_dk a keycode of a deadkey of the currently used (underlying) keyboard + * @param ss_dk a shiftstate of a deadkey of the currently used (underlying) keyboard + * @param vk_us a keycode of a character key on the currently used (underlying) keyboard to be combined to a dk + * @param shiftstate_mac a shiftstate of a character key on the currently used (underlying) keyboard + * @param caps state of the caps key of a character key on the currently used (underlying) keyboard + * @return the combination of deadkey + character if it is available; + * if not return 0 + */ + KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, int vk_dk, KMX_DWORD ss_dk, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps) { UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 666741b08cb..847b1f482b1 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -65,89 +65,28 @@ static int MAC_OPT = 8; static int MAC_SHIFT_OPT = 10; static int ss_mac[] = {MAC_BASE, MAC_SHIFT, MAC_OPT, MAC_SHIFT_OPT}; -/** - * @brief map a shiftstate used on Windows to a shiftstate suitable for UCKeyTranslate() on the mac - * Windows: (Base: 00000000 (0); Shift 00010000 (16); AltGr 00001001 (9); Shift+AltGr 00011001 (25)) - * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10 ) - * @param shiftState shiftstate used on Windows - * @return a shiftstate usable for UCKeyTranslate() on mac if available - * if shiftState is a Windows ShiftState: convert the Windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) - * if shiftState is NOT a Windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate - */ +/** @brief map a shiftstate used on Windows to a shiftstate suitable for UCKeyTranslate() on the mac */ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState); -/** - * @brief map a shiftstate used in rgkey (a vector of VirtualKey*) to a shiftstate suitable for UCKeyTranslate() on the mac - * rgkey: (Base: 0; Shift 1; OPT 6; Shift+OPT 7 ) - * mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10) - * @param rgkey_ShiftState shiftstate used in rgkey - * @return a shiftstate usable for UCKeyTranslate() on mac if available - * if shiftState is a Windows ShiftState: convert the Windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10) - * if shiftState is NOT a Windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate - */ +/** @brief map a shiftstate used in rgkey (a vector of VirtualKey*) to a shiftstate suitable for UCKeyTranslate() on the mac */ int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState); -/** - * @brief check for correct input parameter that will later be used in UCKeyTranslate() - * @param shiftstate the currently used shiftstate - * @param keycode the code of the key in question - * @return true if all parameters are OK; - * false if not - */ +/** @brief check for correct input parameter that will later be used in UCKeyTranslate() */ bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode); -/** - * @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard - * all_vector [ US_Keyboard ] - * [KeyCode_US ] - * [Keyval unshifted ] - * [Keyval shifted ] - * [Underlying Kbd] - * [KeyCode_underlying] - * [Keyval unshifted ] - * [Keyval shifted ] - * @param[in,out] all_vector Vector that holds the data of the US keyboard as well as the currently used (underlying) keyboard - * @param keyboard_layout pointer to currently used (underlying) keyboard layout - * @return 0 on success; - * 1 if data of US keyboard was not written; - * 2 if data of underlying keyboard was not written - */ +/** @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard */ int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout); -/** - * @brief write data of the US keyboard into a 3D-Vector which later will contain - * data of the US keyboard and the currently used (underlying) keyboard - * @param[in,out] vec_us Vector that holds the data of the US keyboard - * @return 0 on success; - * 1 if data of US keyboard was not written; - */ +/** @brief write data of the US keyboard into a 3D-Vector */ int mac_write_US_ToVector(vec_dword_3D& vec_us); -/** - * @brief create an 2D-Vector with all fields initialized to INVALID_NAME - * @param dim_rows number of rows in vector - * @param dim_ss number of columns in vector - * @return the 2D-Vector - */ +/** @brief create an 2D-Vector with all fields initialized to INVALID_NAME */ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss); -/** - * @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector all_vector - * @param[in,out] all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param keyboard_layout pointer to currently used (underlying) keybord layout - * @return 0 on success; - * 1 if the initialization of the underlying vector failes; - * 2 if data of less than 2 keyboards is contained in all_vector; - */ +/** @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector */ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout); -/** - * @brief create a pointer to pointer of the current keyboard_layout for later use - * @param keyboard_layout pointer to pointer to currently used (underlying) keyboard layout - * @return 0 on success; - * 1 if the display is not found; - * 2 if the keymap is not found - */ +/** @brief create a pointer to pointer of the current keymap for later use */ bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout); /** @@ -548,107 +487,31 @@ const UINT mac_ScanCodeToUSVirtualKey[128] = { 0x00, // not used }; -/** - * @brief return the keyvalue for a given Keycode, shiftstate and caps of the - * currently used (underlying) keyboard layout - * "What character will be produced for a keypress of a key and modifier?" - * @param keyboard_layout pointer to the currently used (underlying) keyboard layout - * @param keycode a key of the currently used keyboard layout - * @param shiftstate_mac a shiftstate of the currently used keyboard layout - * @param caps state of the caps key of the currently used keyboard layout - * @return the keyval obtained from keycode, shiftstate and caps - */ +/** @brief return the keyvalue for a given Keycode, shiftstate and caps */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps); -/** - * @brief return the keyvalue for a given Keycode, shiftstate and caps of the - * currently used (underlying) keyboard layout taking dk into account - * "What character will be produced for a keypress of a key and modifiers? - * @param keyboard_layout pointer to the currently used (underlying) keyboard layout - * @param keycode a key of the currently used keyboard layout - * @param shiftstate_mac a shiftstate of the currently used keyboard layout - * @param caps state of the caps key of the currently used keyboard layout - * @param[in,out] deadkeystate states wheter a deadkey was used or not - * @return the keyval obtained from keycode, shiftstate and caps - */ +/** @brief return the keyvalue for a given Keycode, shiftstate and caps */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32& deadkeystate); -/** - * @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. - * "What character will be produced for a keypress of a key and modifiers on the underlying keyboard? - * If a deadkey was found return 0xFFFF and copy the deadkey into deadKey - * @param keyboard_layout a pointer to the currently used (underlying) keyboard layout - * @param kc_underlying a key of the currently used keyboard - * @param vk_ShiftState a shiftstate of the currently used keyboard layout - * @param deadKey pointer to keyvalue if a deadkey was found; if not NULL - * @return 0xFFFF in case a deadkey was found, then the deadkey is stored in deadKey; - * or else the keyval obtained from Keycode and shiftstate and caps; - */ +/** @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. */ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey); -/** - * @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard - * "What character is on the same position/shiftstats/caps on the currently used (underlying) keyboard as on the US keyboard?" - * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param kv_us a keyvalue on the US keyboard - * @return keyval of the underlying keyboard if available; - * else the keyval of the US keyboard - */ +/** @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard */ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us); -/** - * @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard - * On what key of the underlying keyboard do we find a certain character? - * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param kv_underlying a keyvalue on the currently used (underlying) keyboard - * @return keycode of the underlying keyboard if foundf; - * else the keyval of the underlying keyboard - */ +/** @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying); -/** - * @brief return the keycode of the currently used (underlying) keyboard for a given keycode of a character on the US keyboard - * "Where on an underlying keyboard do we find a character that is on a certain key on a US keyboard?" - * @param keyboard_layout the currently used (underlying) keyboard layout - * @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param kc_us a key of the US keyboard - * @param ss_win a Windows-type shiftstate - * @param caps state of the caps key - * @return the keycode of the underlying keyboard if found; - * else the keycode of the US keyboard - */ +/** @brief return the keycode of the currently used (underlying) keyboard for a given keycode of a character on the US keyboard */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps); -/** - * @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard - * "Where on an underlying keyboard do we find a character of a US keyboard?" - * @param virtualKeyUS a virtual key of the US keyboard - * @return the keycode of the currently used (underlying) keyboard - * 0xFFFF if the key is not used - */ +/** @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard */ KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD virtualKeyUS); -/** - * @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard - * "Which character is found on a key of the US keyboard?" - * @param keycode a keycode of the currently used (underlying) keyboard - * @return the virtual key of the US keyboard - * 0 if the key is not used - */ +/** @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard */ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode); -/** - * @brief return the keyvalue of a combination of deadkey + character if there is a combination available - * "What character will be produced for a deadkey + a character?" e.g. '^' + 'a' -> 'â' - * @param keyboard_layout the currently used (underlying)keyboard Layout - * @param vk_dk a keycode of a deadkey of the currently used (underlying) keyboard - * @param ss_dk a shiftstate of a deadkey of the currently used (underlying) keyboard - * @param vk_us a keycode of a character key on the currently used (underlying) keyboard to be combined to a dk - * @param shiftstate_mac a shiftstate of a character key on the currently used (underlying) keyboard - * @param caps state of the caps key of a character key on the currently used (underlying) keyboard - * @return the combination of deadkey + character if it is available; - * if not return 0 - */ +/** @brief return the keyvalue of a combination of deadkey + character if there is a combination available */ KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, int vk_dk, KMX_DWORD ss_dk, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps); #endif /*KEYMAP_H*/ \ No newline at end of file diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 22674d51db1..7515f01e8ee 100644 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -22,23 +22,37 @@ const int KMX_ShiftStateMap[] = { 0, 0}; -/** @brief Constructor */ + /** + * @brief Constructor + * @param deadCharacter a deadkey + */ DeadKey::DeadKey(KMX_WCHAR deadCharacter) { this->m_deadchar = deadCharacter; } -/** @brief return dead character */ + /** + * @brief return dead character + * @return deadkey character + */ KMX_WCHAR DeadKey::KMX_DeadCharacter() { return this->m_deadchar; } -/** @brief set Deadkey with values */ + /** + * @brief set member variable with base and combined character + * @param baseCharacter the base character + * @param combinedCharacter the combined character + */ void DeadKey::KMX_AddDeadKeyRow(KMX_WCHAR baseCharacter, KMX_WCHAR combinedCharacter) { this->m_rgbasechar.push_back(baseCharacter); this->m_rgcombchar.push_back(combinedCharacter); } -/** @brief check if character exists in DeadKey */ +/** + * @brief check if character exists in DeadKey + * @param baseCharacter a character to be found + * @return true if found; false if not found + */ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { std::vector::iterator it; for (it = this->m_rgbasechar.begin(); it < m_rgbasechar.end(); it++) { @@ -49,7 +63,22 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) { return false; } -/** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. */ +/** + * @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. + * + * Contrary to what the function name might suggest, the function the mac_KMX_ToUnicodeEx does NOT process surrogate pairs. + * This is because it is used in mcompile only which only deals with latin scripts. + * In case this function is used for surrogate pairs, they will be ignored and a message will be printed out + * + * @param keycode a key of the currently used keyboard Layout + * @param pwszBuff Buffer to store resulting character + * @param ss_rgkey a Windows-style shiftstate of the currently used keyboard Layout + * @param caps state of the caps key of the currently used keyboard Layout + * @param keyboard_layout the currently used (underlying)keyboard Layout + * @return -1 if a deadkey was found; + * 0 if no translation is available; + * +1 if character was found and written to pwszBuff + */ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, ShiftState ss, int caps, const UCKeyboardLayout* keyboard_layout) { KMX_DWORD keyval; UInt32 isdk = 0; @@ -94,7 +123,9 @@ KMX_WCHAR mac_KMX_DeadKeyMap(int index, std::vector*deadkeys, int dead return 0xFFFF; } -/** @brief Base class for dealing with rgkey*/ +/** + * @brief Base class for dealing with rgkey +*/ class mac_KMX_VirtualKey { private: UINT m_vk; @@ -316,7 +347,9 @@ class mac_KMX_VirtualKey { } }; -/** @brief Base class for KMX_loader*/ +/** + * @brief Base class for KMX_loader +*/ class mac_KMX_Loader { private: KMX_BYTE lpKeyStateNull[256]; diff --git a/mac/mcompile/mc_import_rules.h b/mac/mcompile/mc_import_rules.h index f8a4e008787..ff1cbbe7679 100644 --- a/mac/mcompile/mc_import_rules.h +++ b/mac/mcompile/mc_import_rules.h @@ -3,22 +3,10 @@ #ifndef MC_IMPORT_RULES_H #define MC_IMPORT_RULES_H -/** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. - * Contrary to what the function name might suggest, the function the mac_KMX_ToUnicodeEx does NOT process surrogate pairs. - * This is because it is used in mcompile only which only deals with latin scripts. - * In case this function is used for surrogate pairs, they will be ignored and a message will be printed out - * @param keycode a key of the currently used keyboard Layout - * @param pwszBuff Buffer to store resulting character - * @param ss_rgkey a Windows-style shiftstate of the currently used keyboard Layout - * @param caps state of the caps key of the currently used keyboard Layout - * @param keyboard_layout the currently used (underlying)keyboard Layout - * @return -1 if a deadkey was found; - * 0 if no translation is available; - * +1 if character was found and written to pwszBuff - */ +/** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. */ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_rgkey, int caps, const UCKeyboardLayout* keyboard_layout); -/** @brief Base class for Deadkey*/ +/** @brief Base class for Deadkey*/ class DeadKey { private: KMX_WCHAR m_deadchar; @@ -26,23 +14,14 @@ class DeadKey { std::vector m_rgcombchar; public: - /** - * @brief Constructor - * @param deadCharacter a deadkey - */ + + /** @brief Constructor */ DeadKey(KMX_WCHAR deadCharacter); - /** - * @brief return dead character - * @return deadkey character - */ + /** @brief return dead character */ KMX_WCHAR KMX_DeadCharacter(); - /** - * @brief set member variable with base and combined character - * @param baseCharacter the base character - * @param combinedCharacter the combined character - */ + /** @brief set member variable with base and combined character */ void KMX_AddDeadKeyRow(KMX_WCHAR baseCharacter, KMX_WCHAR combinedCharacter); /** @brief return size of array of basecharacters */ @@ -65,11 +44,7 @@ class DeadKey { return this->m_rgcombchar[index]; } -/** - * @brief check if character exists in DeadKey - * @param baseCharacter a character to be found - * @return true if found; false if not found - */ + /** @brief check if character exists in DeadKey */ bool KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter); }; diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index 0e6e7133657..0f1b7ea272b 100644 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -12,7 +12,6 @@ #define CERR_UnableToWriteFully 0x00008007 #define CERR_SomewhereIGotItWrong 0x00008009 - const int CODE__SIZE[] = { -1, // undefined 0x00 1, // CODE_ANY 0x01 @@ -41,23 +40,10 @@ const int CODE__SIZE[] = { 2 // CODE_SETSYSTEMSTORE 0x18 }; -/** - * @brief check if the file has correct version - * @param filebase containing data of the input file - * @param file_size a size - * @return true if successful; - * false if not - */ +/** @brief check if the file has correct version */ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size); -/** - * @brief Fixup the keyboard by expanding pointers. On disk the pointers are stored relative to the - * beginning of the file, but we need real pointers. This method is used on 32-bit architectures. - * @param bufp pointer to buffer where data will be copied into - * @param base pointer to starting point - * @param dwFileSize size of the file - * @return pointer to the keyboard - */ +/** @brief Fixup the keyboard by expanding pointers. */ LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize); /** @@ -227,7 +213,12 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX return CERR_None; } -/** @brief save keyboard to file */ +/** + * @brief save keyboard to file + * @param kbd pointer to the keyboard + * @param fileName pointer to fileName of a kmx-file + * @return TRUE on success; else FALSE + */ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName) { FILE* fp; fp = Open_File(fileName, "wb"); @@ -339,7 +330,15 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { // else KMX_FixupKeyboard #else -/** @brief Fixup the keyboard by expanding pointers. */ + +/** + * @brief Fixup the keyboard by expanding pointers. On disk the pointers are stored relative to the + * beginning of the file, but we need real pointers. This method is used on 32-bit architectures. + * @param bufp pointer to buffer where data will be copied into + * @param base pointer to starting point + * @param dwFileSize size of the file + * @return pointer to the keyboard + */ LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize) { UNREFERENCED_PARAMETER(dwFileSize); @@ -378,7 +377,12 @@ LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFil #endif -/** @brief load a keyboard kmx-file */ +/** + * @brief load a keyboard kmx-file + * @param fileName pointer to fileName of kmx-file + * @param[in,out] lpKeyboard pointer to pointer to keyboard + * @return TRUE on success; else FALSE + */ KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) { *lpKeyboard = NULL; PKMX_BYTE buf; @@ -484,7 +488,13 @@ KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) { return TRUE; } -/** @brief check if the file has correct version */ +/** + * @brief check if the file has correct version + * @param filebase containing data of the input file + * @param file_size a size + * @return true if successful; + * false if not + */ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size) { KMX_DWORD i; PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)filebase; @@ -510,7 +520,11 @@ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size) { return TRUE; } -/** @brief increment in a string */ +/** + * @brief increment in a string + * @param p pointer to a character + * @return pointer to the incremented character + */ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) { if (p == NULL || *p == 0) return p; @@ -545,7 +559,12 @@ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) { return p; } -/** @brief open a file */ +/** + * @brief open a file + * @param Filename name of the file + * @param mode same as mode in fopen + * @return pointer to file. On error, returns a null pointer + */ FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode) { #ifdef _MSC_VER std::string cpath = Filename; //, cmode = mode; diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index 3914aca1825..e3aadf9c5a3 100644 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -65,35 +65,16 @@ typedef struct KMX_tagKEYBOARD { //HBITMAP hBitmap; // handle to the bitmap in the file; } KMX_KEYBOARD, *LPKMX_KEYBOARD; -/** - * @brief load a keyboard kmx-file - * @param fileName pointer to fileName of kmx-file - * @param[in,out] lpKeyboard pointer to pointer to keyboard - * @return TRUE on success; else FALSE - */ +/** @brief load a keyboard kmx-file */ KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard); -/** - * @brief save keyboard to file - * @param kbd pointer to the keyboard - * @param fileName pointer to fileName of a kmx-file - * @return TRUE on success; else FALSE - */ +/** @brief save keyboard to file */ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName); -/** - * @brief increment in a string - * @param p pointer to a character - * @return pointer to the incremented character - */ +/** @brief increment in a string */ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p); -/** - * @brief open a file - * @param Filename name of the file - * @param mode same as mode in fopen - * @return pointer to file. On error, returns a null pointer - */ +/** @brief open a file */ FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); #endif // _KMXFILE_H diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index dfdb5193463..8f1453f2826 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -14,38 +14,16 @@ #include "mcompile.h" #include "u16.h" -/** - * @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard - * @param kbd pointer to US keyboard - * @param bDeadkeyConversion option for converting a deadkey to a character: 1 = dk conversion; 0 = no dk conversion - * @param argc number of command line arguments - * @return TRUE if conversion was successful; - * FALSE if not - */ +/** @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard */ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc); /** @brief Collect the key data, translate it to kmx and append to the existing keyboard */ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D &all_vector, const UCKeyboardLayout** keyboard_layout, std::vector* KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 -/** - * @brief start of mcompile; load, convert and save keyboard - * @param argc number of commandline arguments - * @param argv pointer to commandline arguments: executable, inputfile, outputfile - * @return 0 on success; - * 1 for wrong usage of calling parameters; - * 3 if unable to load keyboard - */ +/** @brief start of mcompile; load, convert and save keyboard */ int mac_run(int argc, char* argv[]); -/** - * @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard - * @param keyboard_layout pointer to the currently used (underlying) keyboard Layout - * @param all_vector vector that holds the data of the US keyboard and the currently used (underlying) keyboard - * @param deadkey deadkey character - * @param shift_dk shiftstate opf a deadkey character - * @param[out] outputPairs pointer to array of [usvk, ch_out] pairs - * @return size of array of [usvk, ch_out] pairs - */ +/** @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard */ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* outputPairs); // returns array of [usvk, ch_out] pairs std::vector KMX_FDeadkeys; // I4353 @@ -77,7 +55,14 @@ std::vector KMX_FDeadkeys; // I4353 mac_run(argc, argv); } -/** @brief start of mcompile; load, convert and save keyboard */ +/** + * @brief start of mcompile; load, convert and save keyboard + * @param argc number of commandline arguments + * @param argv pointer to commandline arguments: executable, inputfile, outputfile + * @return 0 on success; + * 1 for wrong usage of calling parameters; + * 3 if unable to load keyboard + */ int mac_run(int argc, char* argv[]) { int bDeadkeyConversion = 0; @@ -502,7 +487,14 @@ KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { return FALSE; } -/** @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard */ +/** + * @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard + * @param kbd pointer to US keyboard + * @param bDeadkeyConversion option for converting a deadkey to a character: 1 = dk conversion; 0 = no dk conversion + * @param argc number of command line arguments + * @return TRUE if conversion was successful; + * FALSE if not + */ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc) { KMX_WCHAR DeadKey = 0; if (!mac_KMX_SetKeyboardToPositional(kbd)) @@ -622,7 +614,10 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a return (p - outputPairs); } -/** @brief print (error) messages */ +/** + * @brief print (error) messages + * @param fmt text to print + */ void mac_KMX_LogError(const wchar_t* fmt, ...) { WCHAR fmtbuf[256]; const wchar_t* end = L"\0"; diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index e1a3cb08fe6..9ec05cdff8e 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -33,10 +33,7 @@ struct KMX_DeadkeyMapping { // I4353 extern std::vector KMX_FDeadkeys; // I4353 -/** - * @brief print (error) messages - * @param fmt text to print - */ +/** @brief print (error) messages */ void mac_KMX_LogError(const wchar_t* fmt, ...); #endif /*MCOMPILE_H*/ diff --git a/mac/mcompile/u16.cpp b/mac/mcompile/u16.cpp index caa5ca0fa9b..2ee561e5a6a 100644 --- a/mac/mcompile/u16.cpp +++ b/mac/mcompile/u16.cpp @@ -10,46 +10,67 @@ #include #include "../../core/src/utfcodec.hpp" -// string <- wstring -/** @brief Obtain a std::string from a std::wstring */ +/** string <- wstring +* @brief Obtain a std::string from a std::wstring +* @param wstr the std::wstring to be converted +* @return a std::string +*/ std::string string_from_wstring(std::wstring const wstr) { return convert((const std::wstring)wstr); } -// wstring <- string -/** @brief Obtain a std::wstring from a std::string */ +/** wstring <- string +* @brief Obtain a std::wstring from a std::string +* @param str the std::string to be converted +* @return a std::wstring +*/ std::wstring wstring_from_string(std::string const str) { return convert((const std::string)str); } -// u16String <- string +/** u16String <- string +* @brief Obtain a std::u16tring from a std::string +* @param str the std::string to be converted +* @return a std::u16string +*/ std::u16string u16string_from_string(std::string const str) { return convert((const std::string)str); } -// string <- u16string -//** @brief Obtain a std::string from a std::u16string */ +/** string <- u16string +* @brief Obtain a std::string from a std::u16string +* @param str16 the std::u16string to be converted +* @return a std::string +*/ std::string string_from_u16string(std::u16string const str16) { return convert((const std::u16string)str16); } - -// wstring <- u16string -/** @brief Obtain a std::wstring from a std::u16string */ +/** wstring <- u16string +* @brief Obtain a std::wstring from a std::u16string +* @param str16 the std::u16string to be converted +* @return a std::wstring +*/ std::wstring wstring_from_u16string(std::u16string const str16) { return convert((const std::u16string)str16); } - -// u16string <- wstring -/** @brief Obtain a std::u16string from a std::wstring */ +/** u16string <- wstring +* @brief Obtain a std::u16string from a std::wstring +* @param wstr the std::wstring to be converted +* @return a std::u16string +*/ std::u16string u16string_from_wstring(std::wstring const wstr) { return convert((const std::wstring)wstr);; } - -// UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) -/** @brief Convert pointer to wchar_t to pointer to char16_t and copy sz elements into dst */ +/** UTF16 (=const wchar_t*) -> std::string -> std::u16string -> UTF16 ( = char16_t*) +* @brief Convert pointer to wchar_t to pointer to char16_t and copy sz elements into dst +* @param dst destination +* @param sz nr of characters to be copied +* @param fmt source to convert and copy +* @return void +*/ void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...) { wchar_t* wbuf = new wchar_t[sz]; va_list args; @@ -62,7 +83,13 @@ void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...) { delete[] wbuf; } -/** @brief Convert u16string to long integer */ +/** +* @brief Convert u16string to long integer +* @param str u16string beginning with the representation of an integral number. +* @param endptr Reference to the next character in str +* @param base Numerical base (radix) that determines the valid characters and their interpretation +* @return a long +*/ long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) { auto s = string_from_u16string(str); char* t; @@ -72,7 +99,13 @@ long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) { return result; } -/** @brief Append max characters from u16string */ +/** + * @brief Append n characters from u16string + * @param dst Pointer to the destination array + * @param src u16string to be appended + * @param max Maximum number of characters to be appended. + * @return Pointer to the destination array + */ const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { KMX_WCHAR* o = dst; dst = (KMX_WCHAR*)u16chr(dst, 0); @@ -86,7 +119,11 @@ const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { return o; } -/** @brief find last '/' or '\\' in an array of char16_t */ +/** + * @brief Find last '/' or '\\' in an array of char16_t + * @param name Pointer to the source + * @return Pointer to the last slash/backslash + */ const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* name) { const KMX_WCHAR* cp = NULL; cp = u16rchr(name, '\\'); @@ -95,7 +132,11 @@ const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* name) { return cp; } -/** @brief find last '/' or '\\' in an array of char */ +/** + * @brief Find last '/' or '\\' in an array of char + * @param name Pointer to the source + * @return Pointer to the last slash/backslash + */ KMX_CHAR* strrchr_slash(KMX_CHAR* name) { KMX_CHAR* cp = NULL; cp = strrchr(name, '\\'); @@ -104,7 +145,12 @@ KMX_CHAR* strrchr_slash(KMX_CHAR* name) { return cp; } -/** @brief Locate last occurrence of character in u16string */ +/** + * @brief Locate last occurrence of character in u16string + * @param p Pointer to the source + * @param ch The character to be found + * @return A pointer to the last occurrence of character in u16str + */ const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch) { const KMX_WCHAR* p_end = p + u16len(p); @@ -116,7 +162,12 @@ const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch) { return NULL; } -/** @brief Locate first occurrence of character in u16string */ +/** + * @brief Locate first occurrence of character in u16string + * @param p Pointer to the source + * @param ch The character to be found + * @return A pointer to the first occurrence of character in u16str + */ const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch) { while (*p) { if (*p == ch) @@ -126,7 +177,12 @@ const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch) { return ch == 0 ? p : NULL; } -/** @brief Copy the u16string pointed to by source into the array pointed to by destination */ +/** +* @brief Copy the u16string pointed by src into the array pointed by dst +* @param dst Pointer to the destination +* @param src Pointer to the source to be copied +* @return Pointer to dst +*/ const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src) { KMX_WCHAR* o = dst; while (*src) { @@ -136,7 +192,13 @@ const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src) { return o; } -/** @brief Copy max characters of the u16string pointed to by source into the array pointed to by destination */ +/** +* @brief Copy max characters of the u16string pointed by src into the array pointed by dst +* @param dst Pointer to the destination +* @param src Pointer to the source to be copied +* @param max Maximum number of characters to be copied +* @return Pointer to dst +*/ const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { KMX_WCHAR* o = dst; while (*src && max > 0) { @@ -149,7 +211,11 @@ const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { return o; } -/** @brief Return the length of the u16string str */ +/** +* @brief Return the length of the u16string str +* @param p Pointer to the source +* @return The length of u16string +*/ size_t u16len(const KMX_WCHAR* p) { int i = 0; while (*p) { @@ -159,7 +225,13 @@ size_t u16len(const KMX_WCHAR* p) { return i; } -/** @brief Compare two u16strings */ +/** +* @brief Compare two u16strings +* @param p Pointer one u16string +* @param q Pointer another u16string +* @return 0 if strings are eqaual +* ! = 0 if unequal +*/ int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q) { while (*p && *q) { if (*p != *q) @@ -170,7 +242,14 @@ int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q) { return *p - *q; } -/** @brief Case insensitive comparison of up to count characters in two strings */ +/** +* @brief Case insensitive comparison of up to count characters in two strings +* @param p Pointer one u16string +* @param q Pointer another u16string +* @param count Maximum number of characters to compare +* @return 0 if strings are equal +* ! = 0 if unequal +*/ int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { while (*p && *q && count) { if (toupper(*p) != toupper(*q)) @@ -184,7 +263,13 @@ int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { return 0; } -/** @brief Case insensitive comparison of two strings */ +/** +* @brief Case insensitive comparison of two strings +* @param p Pointer one u16string +* @param q Pointer another u16string +* @return 0 if strings are equal +* ! = 0 if unequal +*/ int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q) { while (*p && *q) { if (toupper(*p) != toupper(*q)) @@ -195,7 +280,14 @@ int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q) { return *p - *q; } -/** @brief Comparison of up to count characters in two strings */ +/** +* @brief Comparison of up to count characters in two strings +* @param p Pointer one u16string +* @param q Pointer another u16string +* @param count Maximum number of characters to compare +* @return 0 if strings are equal +* ! = 0 if unequal +*/ int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { while (*p && *q && count) { if (*p != *q) @@ -209,7 +301,13 @@ int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { return 0; } -/** @brief Split u16string into tokens */ +/** +* @brief Split u16string into tokens +* @param p Pointer to u16string to parse +* @param ch the delimiter character +* @param ctx the remaining string after the first delimiter +* @return Pointer to the first token in p +*/ KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR ch, KMX_WCHAR** ctx) { if (!p) { p = *ctx; @@ -232,7 +330,13 @@ KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR ch, KMX_WCHAR** ctx) { return *p ? p : NULL; } -/** @brief Split u16string into tokens */ +/** +* @brief Split u16string into tokens +* @param p Pointer to u16string to parse +* @param delimiters an array of delimiter characters +* @param ctx the remaining string after the first delimiter +* @return Pointer to the first token in p +*/ KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR* delimiters, KMX_WCHAR** ctx) { if (!p) { p = *ctx; @@ -256,7 +360,11 @@ KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR* delimiters, KMX_WCHAR** ctx) { return *p ? p : NULL; } -/** @brief Convert a u16string to a double */ +/** +* @brief Convert a u16string to a double +* @param str Pointer to u16string +* @return double value equivalent to the string +*/ double u16tof(KMX_WCHAR* str) { double val = 0; int offsetdot = 0; diff --git a/mac/mcompile/u16.h b/mac/mcompile/u16.h index f83b792cf80..54bac4cd03b 100644 --- a/mac/mcompile/u16.h +++ b/mac/mcompile/u16.h @@ -11,189 +11,73 @@ #include -/** -* @brief Obtain a std::string from a std::wstring -* @param wstr the std::wstring to be converted -* @return a std::string -*/ +/** @brief Obtain a std::string from a std::wstring */ std::string string_from_wstring(std::wstring const wstr); -/** -* @brief Obtain a std::wstring from a std::string -* @param str the std::string to be converted -* @return a std::wstring -*/ +/** @brief Obtain a std::wstring from a std::string */ std::wstring wstring_from_string(std::string const str); -/** -* @brief Obtain a std::u16tring from a std::string -* @param str the std::string to be converted -* @return a std::u16string -*/ +/** @brief Obtain a std::u16tring from a std::string*/ std::u16string u16string_from_string(std::string const str); -/** -* @brief Obtain a std::string from a std::u16string -* @param str16 the std::u16string to be converted -* @return a std::string -*/ +/** @brief Obtain a std::string from a std::u16string */ std::string string_from_u16string(std::u16string const str16); -/** -* @brief Obtain a std::wstring from a std::u16string -* @param str16 the std::u16string to be converted -* @return a std::wstring -*/ +/** @brief Obtain a std::wstring from a std::u16string */ std::wstring wstring_from_u16string(std::u16string const str16); -/** -* @brief Obtain a std::u16string from a std::wstring -* @param wstr the std::wstring to be converted -* @return a std::u16string -*/ +/** @brief Obtain a std::u16string from a std::wstring */ std::u16string u16string_from_wstring(std::wstring const wstr); -/** -* @brief Convert pointer to wchar_t to pointer to char16_t and copy sz elements into dst -* @param dst destination -* @param sz nr of characters to be copied -* @param fmt source to convert and copy -* @return void -*/ +/** @brief Convert pointer to wchar_t to pointer to char16_t and copy sz elements into dst */ void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...); -/** -* @brief Convert u16string to long integer -* @param str u16string beginning with the representation of an integral number. -* @param endptr Reference to the next character in str -* @param base Numerical base (radix) that determines the valid characters and their interpretation -* @return a long -*/ +/** @brief Convert u16string to long integer */ long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base); - /** - * @brief Append n characters from u16string - * @param dst Pointer to the destination array - * @param src u16string to be appended - * @param max Maximum number of characters to be appended. - * @return Pointer to the destination array - */ - const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max); - - /** - * @brief Find last '/' or '\\' in an array of char - * @param Name Pointer to the source - * @return Pointer to the last slash/backslash - */ - const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name); - - /** - * @brief Find last '/' or '\\' in an array of char16_t - * @param Name Pointer to the source - * @return Pointer to the last slash/backslash - */ - KMX_CHAR* strrchr_slash(KMX_CHAR* Name); - /** - * @brief Locate last occurrence of character in u16string - * @param p Pointer to the source - * @param ch The character to be found - * @return A pointer to the last occurrence of character in u16str - */ - const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch); - - /** - * @brief Locate first occurrence of character in u16string - * @param p Pointer to the source - * @param ch The character to be found - * @return A pointer to the first occurrence of character in u16str - */ - const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch); - -/** -* @brief Copy the u16string pointed by src into the array pointed by dst -* @param dst Pointer to the destination -* @param src Pointer to the source to be copied -* @return Pointer to dst -*/ +/** @brief Append max characters from u16string */ +const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max); + +/** @brief find last '/' or '\\' in an array of char16_t */ +const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name); + +/** @brief find last '/' or '\\' in an array of char */ +KMX_CHAR* strrchr_slash(KMX_CHAR* Name); + +/** @brief Locate last occurrence of character in u16string */ +const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch); + +/** @brief Locate first occurrence of character in u16string */ +const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch); + +/** @brief Copy the u16string pointed to by src into the array pointed to by dst */ const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src); -/** -* @brief Copy max characters of the u16string pointed by src into the array pointed by dst -* @param dst Pointer to the destination -* @param src Pointer to the source to be copied -* @param max Maximum number of characters to be copied -* @return Pointer to dst -*/ +/** @brief Copy max characters of the u16string pointed to by src into the array pointed to by dst */ const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max); -/** -* @brief Return the length of the u16string str -* @param p Pointer to the source -* @return The length of u16string -*/ +/** @brief Return the length of the u16string str */ size_t u16len(const KMX_WCHAR* p); -/** -* @brief Compare two u16strings -* @param p Pointer one u16string -* @param q Pointer another u16string -* @return 0 if strings are eqaual -* ! = 0 if unequal -*/ +/** @brief Compare two u16strings */ int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q); -/** -* @brief Case insensitive comparison of up to count characters in two strings -* @param p Pointer one u16string -* @param q Pointer another u16string -* @param count Maximum number of characters to compare -* @return 0 if strings are equal -* ! = 0 if unequal -*/ +/** @brief Case insensitive comparison of up to count characters in two strings */ int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count); -/** -* @brief Case insensitive comparison of two strings -* @param p Pointer one u16string -* @param q Pointer another u16string -* @return 0 if strings are equal -* ! = 0 if unequal -*/ +/** @brief Case insensitive comparison of two strings */ int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q); -/** -* @brief Comparison of up to count characters in two strings -* @param p Pointer one u16string -* @param q Pointer another u16string -* @param count Maximum number of characters to compare -* @return 0 if strings are equal -* ! = 0 if unequal -*/ +/** @brief Comparison of up to count characters in two strings */ int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count); -/** -* @brief Split u16string into tokens -* @param p Pointer to u16string to parse -* @param ch the delimiter character -* @param ctx the remaining string after the first delimiter -* @return Pointer to the first token in p -*/ +/** @brief Split u16string into tokens */ KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR ch, KMX_WCHAR** ctx); -/** -* @brief Split u16string into tokens -* @param p Pointer to u16string to parse -* @param delimiters an array of delimiter characters -* @param ctx the remaining string after the first delimiter -* @return Pointer to the first token in p -*/ +/** @brief Split u16string into tokens */ KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR* delimiters, KMX_WCHAR** ctx); -/** -* @brief Convert a u16string to a double -* @param str Pointer to u16string -* @return double value equivalent to the string -*/ +/** @brief Convert a u16string to a double */ double u16tof(KMX_WCHAR* str); #endif /* U16_H */ From e889fd8e7bed1a594528b96bf4536a7254dcff3a Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 14 Aug 2024 14:09:58 +0200 Subject: [PATCH 49/71] refactor(mac): use km_types from common --- mac/mcompile/keymap.cpp | 8 +-- mac/mcompile/keymap.h | 39 +++++++++-- mac/mcompile/km_types.h | 111 ------------------------------- mac/mcompile/mc_import_rules.cpp | 50 +++++++------- mac/mcompile/mc_kmxfile.cpp | 6 +- mac/mcompile/mc_kmxfile.h | 2 +- mac/mcompile/mcompile.cpp | 33 ++++----- mac/mcompile/mcompile.h | 2 +- mac/mcompile/u16.h | 2 +- 9 files changed, 87 insertions(+), 166 deletions(-) delete mode 100644 mac/mcompile/km_types.h diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index c3ea47c9797..0a9e520f63c 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -154,7 +154,7 @@ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss) { * @param[in,out] all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param keyboard_layout pointer to currently used (underlying) keybord layout * @return 0 on success; - * 1 if the initialization of the underlying vector failes; + * 1 if the initialization of the underlying vector fails; * 2 if data of less than 2 keyboards is contained in all_vector; */ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { @@ -190,8 +190,8 @@ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLay } /** - * @brief create a pointer to pointer of the current keyboard_layout for later use - * @param keyboard_layout pointer to pointer to currently used (underlying) keyboard layout + * @brief initializes GDK and return the current keyboard_layout for later use + * @param keyboard_layoutout[out] currently used (underlying) keyboard layout * @return 0 on success; * 1 if the display is not found; * 2 if the keymap is not found @@ -302,7 +302,7 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la * @return 0xFFFF in case a deadkey was found, then the deadkey is stored in deadKey; * or else the keyval obtained from Keycode and shiftstate and caps; */ -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey) { +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, KMX_DWORD kc_underlying, KMX_DWORD vk_ShiftState, PKMX_WCHAR deadKey) { PKMX_WCHAR dky = NULL; UInt32 isdk = 0; KMX_DWORD keyV; diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 847b1f482b1..ff0bcf1f850 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -21,7 +21,38 @@ enum ShiftState { ShftXxxx = Shft | Xxxx, // 9 }; - +#define VK_SPACE 0x20 +#define VK_COLON 0xBA +#define VK_EQUAL 0xBB +#define VK_COMMA 0xBC +#define VK_HYPHEN 0xBD +#define VK_PERIOD 0xBE +#define VK_SLASH 0xBF +#define VK_ACCENT 0xC0 +#define VK_LBRKT 0xDB +#define VK_BKSLASH 0xDC +#define VK_RBRKT 0xDD +#define VK_QUOTE 0xDE +#define VK_xDF 0xDF +#define VK_OEM_102 0xE2 // "<>" or "\|" on RT 102-key kbd. + +#define VK_DIVIDE 0x6F +#define VK_CANCEL 3 +#define VK_DECIMAL 0x2E + +#define VK_OEM_CLEAR 0xFE +#define VK_LSHIFT 0xA0 +#define VK_RSHIFT 0xA1 +#define VK_LCONTROL 0xA2 +#define VK_RCONTROL 0xA3 +#define VK_LMENU 0xA4 +#define VK_RMENU 0xA5 + +#define VK_SHIFT 0x10 +#define VK_CONTROL 0x11 +#define VK_MENU 0x12 +#define VK_PAUSE 0x13 +#define VK_CAPITAL 0x14 // Map of all US English virtual key codes that we can translate const KMX_DWORD KMX_VKMap[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', @@ -93,7 +124,7 @@ bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout); * @brief array of USVirtualKey-ScanCode-pairs * we use the same type of array as throughout Keyman even though we have lots of unused fields */ -const UINT mac_USVirtualKeyToScanCode[256] = { +const KMX_DWORD mac_USVirtualKeyToScanCode[256] = { 0xFFFF, // not used 0xFFFF, // not used 0xFFFF, // not used @@ -356,7 +387,7 @@ const UINT mac_USVirtualKeyToScanCode[256] = { * @brief array of ScanCode-USVirtualKey-pairs * we use the same type of array as throughout Keyman even though we have lots of unused fields */ -const UINT mac_ScanCodeToUSVirtualKey[128] = { +const KMX_DWORD mac_ScanCodeToUSVirtualKey[128] = { 0x41, // L"K_A", // &H41 0x53, // L"K_S", // &H53 0x44, // L"K_D", // &H44 @@ -494,7 +525,7 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32& deadkeystate); /** @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. */ -KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey); +KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, KMX_DWORD kc_underlying, KMX_DWORD vk_ShiftState, PKMX_WCHAR deadKey); /** @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard */ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us); diff --git a/mac/mcompile/km_types.h b/mac/mcompile/km_types.h deleted file mode 100644 index 5381ff1e6a4..00000000000 --- a/mac/mcompile/km_types.h +++ /dev/null @@ -1,111 +0,0 @@ -#pragma once -#ifndef KM_TYPES -#define KM_TYPES -#include -/* -#if defined(_WIN32) || defined(_WIN64) -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#define strcasecmp _stricmp -#define strncasecmp _strnicmp -#endif -*/ - -#if defined(__LP64__) || defined(_LP64) -/* 64-bit, g++ */ -#define KMX_64BIT -#endif - -#if defined(_WIN64) && !defined(USE_64) -/* 64-bit, Windows */ -#define KMX_64BIT -#endif - -typedef uint32_t KMX_DWORD; -typedef int32_t KMX_BOOL; -typedef uint8_t KMX_BYTE; -typedef uint16_t KMX_WORD; - -#if defined(__cplusplus) -typedef char16_t km_kbp_cp; -typedef char32_t km_kbp_usv; -#else -typedef uint16_t km_kbp_cp; // code point -typedef uint32_t km_kbp_usv; // Unicode Scalar Value -#endif - -typedef unsigned int UINT; -typedef unsigned long DWORD; - -typedef unsigned char BYTE; -typedef char KMX_CHAR; - -typedef char16_t KMX_WCHAR; -typedef KMX_WCHAR* PKMX_WCHAR; - -typedef wchar_t WCHAR; -typedef WCHAR KMX_WCHART; -typedef wchar_t* PWSTR; -typedef WCHAR* PWCHAR; - -typedef uint8_t* LPKMX_BYTE; -typedef uint8_t* PKMX_BYTE; - -typedef KMX_BYTE* PKMX_BYTE; -typedef KMX_DWORD* PKMX_DWORD; -typedef int BOOL; - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -// Macros and types to support char16_t vs wchar_t depending on project - -#ifdef USE_CHAR16_T -#define lpuch(x) u ## x -typedef km_kbp_cp KMX_UCHAR; -#else -#define lpuch(x) L ## x -typedef wchar_t KMX_UCHAR; -#endif - -typedef KMX_UCHAR* KMX_PUCHAR; - -#define VK_SPACE 0x20 -#define VK_COLON 0xBA -#define VK_EQUAL 0xBB -#define VK_COMMA 0xBC -#define VK_HYPHEN 0xBD -#define VK_PERIOD 0xBE -#define VK_SLASH 0xBF -#define VK_ACCENT 0xC0 -#define VK_LBRKT 0xDB -#define VK_BKSLASH 0xDC -#define VK_RBRKT 0xDD -#define VK_QUOTE 0xDE -#define VK_xDF 0xDF -#define VK_OEM_102 0xE2 // "<>" or "\|" on RT 102-key kbd. - -#define VK_DIVIDE 0x6F -#define VK_CANCEL 3 -#define VK_DECIMAL 0x2E - -#define VK_OEM_CLEAR 0xFE -#define VK_LSHIFT 0xA0 -#define VK_RSHIFT 0xA1 -#define VK_LCONTROL 0xA2 -#define VK_RCONTROL 0xA3 -#define VK_LMENU 0xA4 -#define VK_RMENU 0xA5 - -#define VK_SHIFT 0x10 -#define VK_CONTROL 0x11 -#define VK_MENU 0x12 -#define VK_PAUSE 0x13 -#define VK_CAPITAL 0x14 - -#endif /*KM_TYPES*/ diff --git a/mac/mcompile/mc_import_rules.cpp b/mac/mcompile/mc_import_rules.cpp index 7515f01e8ee..73e1f25dd93 100644 --- a/mac/mcompile/mc_import_rules.cpp +++ b/mac/mcompile/mc_import_rules.cpp @@ -128,35 +128,35 @@ KMX_WCHAR mac_KMX_DeadKeyMap(int index, std::vector*deadkeys, int dead */ class mac_KMX_VirtualKey { private: - UINT m_vk; - UINT m_sc; + KMX_DWORD m_vk; + KMX_DWORD m_sc; bool m_rgfDeadKey[10][2]; std::u16string m_rgss[10][2]; public: - mac_KMX_VirtualKey(UINT scanCode) { + mac_KMX_VirtualKey(KMX_DWORD scanCode) { this->m_vk = mac_KMX_get_VKUS_From_KeyCodeUnderlying(scanCode); this->m_sc = scanCode; memset(this->m_rgfDeadKey, 0, sizeof(this->m_rgfDeadKey)); } /** @brief return member variable virtual key */ - UINT VK() { + KMX_DWORD VK() { return this->m_vk; } /** @brief return member variable scancode */ - UINT SC() { + KMX_DWORD SC() { return this->m_sc; } std::u16string mac_KMX_GetShiftState(ShiftState shiftState, bool capsLock) { - return this->m_rgss[(UINT)shiftState][(capsLock ? 1 : 0)]; + return this->m_rgss[(KMX_DWORD)shiftState][(capsLock ? 1 : 0)]; } void mac_KMX_SetShiftState(ShiftState shiftState, std::u16string value, bool isDeadKey, bool capsLock) { - this->m_rgfDeadKey[(UINT)shiftState][(capsLock ? 1 : 0)] = isDeadKey; - this->m_rgss[(UINT)shiftState][(capsLock ? 1 : 0)] = value; + this->m_rgfDeadKey[(KMX_DWORD)shiftState][(capsLock ? 1 : 0)] = isDeadKey; + this->m_rgss[(KMX_DWORD)shiftState][(capsLock ? 1 : 0)] = value; } bool mac_KMX_IsSGCAPS() { @@ -222,7 +222,7 @@ class mac_KMX_VirtualKey { return (this->m_vk >= 0x20 && this->m_vk <= 0x5F) || (this->m_vk >= 0x88); } - UINT KMX_GetShiftStateValue(int capslock, int caps, ShiftState ss) { + KMX_DWORD KMX_GetShiftStateValue(int capslock, int caps, ShiftState ss) { return KMX_ShiftStateMap[(int)ss] | (capslock ? (caps ? CAPITALFLAG : NOTCAPITALFLAG) : 0); } @@ -263,7 +263,7 @@ class mac_KMX_VirtualKey { } /** @brief edit the row of kmx-file */ - bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector* deadkeys, int deadkeyBase, BOOL bDeadkeyConversion, vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { // I4552 + bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector* deadkeys, int deadkeyBase, bool bDeadkeyConversion, vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { // I4552 // Get the CAPSLOCK value /*int capslock = (this->mac_KMX_IsCapsEqualToShift() ? 1 : 0) | @@ -353,7 +353,7 @@ class mac_KMX_VirtualKey { class mac_KMX_Loader { private: KMX_BYTE lpKeyStateNull[256]; - UINT m_XxxxVk; + KMX_DWORD m_XxxxVk; public: mac_KMX_Loader() { @@ -361,11 +361,11 @@ class mac_KMX_Loader { memset(lpKeyStateNull, 0, sizeof(lpKeyStateNull)); } - UINT Get_XxxxVk() { + KMX_DWORD Get_XxxxVk() { return m_XxxxVk; } - void Set_XxxxVk(UINT value) { + void Set_XxxxVk(KMX_DWORD value) { m_XxxxVk = value; } @@ -378,7 +378,7 @@ class mac_KMX_Loader { } DeadKey* ProcessDeadKey( - UINT iKeyDead, // The index into the VirtualKey of the dead key + KMX_DWORD iKeyDead, // The index into the VirtualKey of the dead key ShiftState shiftStateDead, // The shiftstate that contains the dead key std::vector rgKey, // Our array of dead keys bool fCapsLock, // Was the caps lock key pressed? @@ -456,7 +456,7 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe // flag that the VK is valid, and it can store the SC value. // Windows and Linux Keycodes start with 1; Mac keycodes start with 0 - for (UINT sc = 0x00; sc <= 0x7f; sc++) { + for (KMX_DWORD sc = 0x00; sc <= 0x7f; sc++) { /* HERE IS A BIG DIFFERENCE COMPARED TO MCOMPILE FOR WINDOWS: * mcompile on Windows fills rgkey.m_vk with the VK of the Underlying keyboard * mcompile for macOS fills rgkey.m_vk with the VK of the US keyboard @@ -476,7 +476,7 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe } // in this part we skip shiftstates 4, 5, 8, 9 - for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { + for (KMX_DWORD iKey = 0; iKey < rgKey.size(); iKey++) { if (rgKey[iKey] != NULL) { KMX_WCHAR sbBuffer[256]; // Scratchpad we use many places for (ShiftState ss = Base; ss <= loader.KMX_MaxShiftState(); ss = (ShiftState)((int)ss + 1)) { @@ -507,7 +507,7 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe sbBuffer[2] = 0; rgKey[iKey]->mac_KMX_SetShiftState(ss, sbBuffer, true, (caps == 0)); DeadKey* dk = NULL; - for (UINT iDead = 0; iDead < alDead.size(); iDead++) { + for (KMX_DWORD iDead = 0; iDead < alDead.size(); iDead++) { dk = alDead[iDead]; if (dk->KMX_DeadCharacter() == rgKey[iKey]->mac_KMX_GetShiftState(ss, caps == 0)[0]) { break; @@ -537,10 +537,10 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe // kp->dpGroupArray = gp; - for (UINT i = 0; i < kp->cxGroupArray; i++, gp++) { + for (KMX_DWORD i = 0; i < kp->cxGroupArray; i++, gp++) { LPKMX_KEY kkp = gp->dpKeyArray; - for (UINT j = 0; j < gp->cxKeyArray; j++, kkp++) { + for (KMX_DWORD j = 0; j < gp->cxKeyArray; j++, kkp++) { nDeadkey = std::max(nDeadkey, mac_KMX_GetMaxDeadkeyIndex(kkp->dpContext)); nDeadkey = std::max(nDeadkey, mac_KMX_GetMaxDeadkeyIndex(kkp->dpOutput)); } @@ -551,8 +551,8 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe // calculate the required size of `gp->dpKeyArray` - UINT nkeys = 0; - for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { + KMX_DWORD nkeys = 0; + for (KMX_DWORD iKey = 0; iKey < rgKey.size(); iKey++) { if ((rgKey[iKey] != NULL) && rgKey[iKey]->mac_KMX_IsKeymanUsedKey() && (!rgKey[iKey]->mac_KMX_IsEmpty())) { nkeys += rgKey[iKey]->mac_KMX_GetKeyCount(loader.KMX_MaxShiftState()); } @@ -571,7 +571,7 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe // Fill in the new rules // nkeys = 0; - for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { + for (KMX_DWORD iKey = 0; iKey < rgKey.size(); iKey++) { if ((rgKey[iKey] != NULL) && rgKey[iKey]->mac_KMX_IsKeymanUsedKey() && (!rgKey[iKey]->mac_KMX_IsEmpty())) { if (rgKey[iKey]->mac_KMX_LayoutRow(loader.KMX_MaxShiftState(), &gp->dpKeyArray[nkeys], &alDead, nDeadkey, bDeadkeyConversion, all_vector, *keyboard_layout)) { // I4552 nkeys += rgKey[iKey]->mac_KMX_GetKeyCount(loader.KMX_MaxShiftState()); @@ -585,7 +585,7 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe // Add nomatch control to each terminating 'using keys' group // I4550 // LPKMX_GROUP gp2 = kp->dpGroupArray; - for (UINT i = 0; i < kp->cxGroupArray - 1; i++, gp2++) { + for (KMX_DWORD i = 0; i < kp->cxGroupArray - 1; i++, gp2++) { if (gp2->fUsingKeys && gp2->dpNoMatch == NULL) { KMX_WCHAR* p = gp2->dpNoMatch = new KMX_WCHAR[4]; *p++ = UC_SENTINEL; @@ -597,7 +597,7 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe // the AltGr and ShiftAltGr combinations as rules to allow them to be matched as well. Yes, this // loop is not very efficient but it's not worthy of optimisation. // - UINT j; + KMX_DWORD j; LPKMX_KEY kkp; for (j = 0, kkp = gp->dpKeyArray; j < gp->cxKeyArray; j++, kkp++) { if ((kkp->ShiftFlags & (K_CTRLFLAG | K_ALTFLAG | LCTRLFLAG | LALTFLAG | RCTRLFLAG | RALTFLAG)) != 0) { @@ -652,7 +652,7 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCKe int nStoreBase = kp->cxStoreArray; kp->cxStoreArray += alDead.size() * 2; - for (UINT i = 0; i < alDead.size(); i++) { + for (KMX_DWORD i = 0; i < alDead.size(); i++) { DeadKey* dk = alDead[i]; sp->dpName = NULL; diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index 0f1b7ea272b..86845f81653 100644 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -41,7 +41,7 @@ const int CODE__SIZE[] = { }; /** @brief check if the file has correct version */ -KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size); +KMX_BOOL KMX_VerifyKeyboard(PKMX_BYTE filebase, KMX_DWORD file_size); /** @brief Fixup the keyboard by expanding pointers. */ LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize); @@ -64,7 +64,7 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX PKMX_COMP_KEY kp; PKMX_BYTE buf; KMX_DWORD size, offset; - DWORD i, j; + KMX_DWORD i, j; // Calculate how much memory to allocate size = sizeof(KMX_COMP_KEYBOARD) + @@ -495,7 +495,7 @@ KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) { * @return true if successful; * false if not */ -KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size) { +KMX_BOOL KMX_VerifyKeyboard(PKMX_BYTE filebase, KMX_DWORD file_size) { KMX_DWORD i; PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)filebase; PKMX_COMP_STORE csp; diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index e3aadf9c5a3..12d9ba4a8c9 100644 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -2,7 +2,7 @@ #ifndef MC_KMXFILE_H #define MC_KMXFILE_H -#include "km_types.h" +#include "../../common/include/km_types.h" #include "kmx_file.h" #include "mcompile.h" diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 8f1453f2826..a13d04d7fa1 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -10,6 +10,7 @@ */ #include +#include #include #include "mcompile.h" #include "u16.h" @@ -24,7 +25,7 @@ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D &all_vector, const UCKe int mac_run(int argc, char* argv[]); /** @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard */ -int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* outputPairs); // returns array of [usvk, ch_out] pairs +int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, KMX_DWORD shift_dk, KMX_WORD* outputPairs); // returns array of [usvk, ch_out] pairs std::vector KMX_FDeadkeys; // I4353 @@ -142,7 +143,7 @@ int mac_run(int argc, char* argv[]) { } // Map of all shift states that we will work with -const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG | RALTFLAG, K_SHIFTFLAG | LCTRLFLAG | RALTFLAG, 0xFFFF}; +const KMX_DWORD VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG | RALTFLAG, K_SHIFTFLAG | LCTRLFLAG | RALTFLAG, 0xFFFF}; // // TranslateKey @@ -158,7 +159,7 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG | RALTFLAG, K_SHIFTFLAG | * @param shift shiftstate * @param ch character of the underlying keyboard to be remapped */ -void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { +void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, KMX_DWORD shift, KMX_WCHAR ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. @@ -190,7 +191,7 @@ void mac_KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, UINT shift, KMX_WCHAR ch) * @param shift shiftstate * @param ch character of the underlying keyboard to be remapped */ -void mac_KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { +void mac_KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, KMX_DWORD shift, KMX_WCHAR ch) { for (unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_TranslateKey(&group->dpKeyArray[i], vk, shift, ch); } @@ -203,7 +204,7 @@ void mac_KMX_TranslateGroup(LPKMX_GROUP group, KMX_WORD vk, UINT shift, KMX_WCHA * @param shift shiftstate * @param ch character of the underlying keyboard to be remapped */ -void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR ch) { +void mac_KMX_TranslateKeyboard(LPKMX_KEYBOARD kbd, KMX_WORD vk, KMX_DWORD shift, KMX_WCHAR ch) { for (unsigned int i = 0; i < kbd->cxGroupArray; i++) { if (kbd->dpGroupArray[i].fUsingKeys) { mac_KMX_TranslateGroup(&kbd->dpGroupArray[i], vk, shift, ch); @@ -253,7 +254,7 @@ void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { * @param shift shiftstate * @param ch character of the underlying keyboard */ -void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { +void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, KMX_DWORD shift, KMX_WORD ch) { if ((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" @@ -290,7 +291,7 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, * @param shift shiftstate * @param character of the underlying keyboard */ -void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { +void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group, KMX_WCHAR deadkey, KMX_WORD vk, KMX_DWORD shift, KMX_WORD ch) { for (unsigned int i = 0; i < group->cxKeyArray; i++) { mac_KMX_TranslateDeadkeyKey(&group->dpKeyArray[i], deadkey, vk, shift, ch); } @@ -304,7 +305,7 @@ void mac_KMX_TranslateDeadkeyGroup(LPKMX_GROUP group, KMX_WCHAR deadkey, KMX_WOR * @param shift shiftstate * @param character of the underlying keyboard */ -void mac_KMX_TranslateDeadkeyKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch) { +void mac_KMX_TranslateDeadkeyKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, KMX_DWORD shift, KMX_WORD ch) { for (unsigned int i = 0; i < kbd->cxGroupArray; i++) { if (kbd->dpGroupArray[i].fUsingKeys) { mac_KMX_TranslateDeadkeyGroup(&kbd->dpGroupArray[i], deadkey, vk, shift, ch); @@ -319,7 +320,7 @@ void mac_KMX_TranslateDeadkeyKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX * @param vk a keyvalue of the US keyboard * @param shift shiftstate */ -void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift) { +void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk, KMX_DWORD shift) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. @@ -381,7 +382,7 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { LPKMX_GROUP gp; LPKMX_KEY kp; LPKMX_STORE sp; - UINT i, j; + KMX_DWORD i, j; KMX_WCHAR dkid = 0; static KMX_WCHAR s_next_dkid = 0; static KMX_dkidmap* s_dkids = NULL; @@ -437,7 +438,7 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { * @param keymap pointer to the currently used (underlying) keyboard Layout * @param dk_Table a vector of all possible deadkey combinations for all Linux keyboards */ -void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_WCHAR deadkey, vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { +void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, KMX_DWORD shift, KMX_WCHAR deadkey, vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { KMX_WORD deadkeys[512] = {0}; KMX_WORD* pdk; @@ -454,7 +455,7 @@ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_ while (*pdk) { // Look up the ch - UINT KeyValUnderlying = mac_KMX_get_KeyValUnderlying_From_KeyValUS(all_vector, *pdk); + KMX_DWORD KeyValUnderlying = mac_KMX_get_KeyValUnderlying_From_KeyValUS(all_vector, *pdk); mac_KMX_TranslateDeadkeyKeyboard(kbd, dkid, KeyValUnderlying, *(pdk + 1), *(pdk + 2)); pdk += 3; } @@ -468,7 +469,7 @@ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, UINT shift, KMX_ */ KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { LPKMX_STORE sp; - UINT i; + KMX_DWORD i; for (i = 0, sp = kbd->dpStoreArray; i < kbd->cxStoreArray; i++, sp++) { if (sp->dwSystemID == TSS_MNEMONIC) { if (!sp->dpString) { @@ -529,7 +530,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int for (int i = 0; KMX_VKMap[i]; i++) { // I4651 // Windows uses VK as sorting order in rgkey[], Linux and macOS use SC/Keycode as sorting order - UINT scUnderlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_VKMap[i]); + KMX_DWORD scUnderlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_VKMap[i]); KMX_WCHAR ch = mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(keyboard_layout, scUnderlying, VKShiftState[j], &DeadKey); // wprintf(L"--- VK_%d -> SC_ [%c] dk=%d ( ss %i) \n", KMX_VKMap[i], ch == 0 ? 32 : ch, DeadKey, VKShiftState[j]); @@ -565,7 +566,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int * @param[out] outputPairs pointer to array of [usvk, ch_out] pairs * @return size of array of [usvk, ch_out] pairs */ -int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* outputPairs) { +int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, KMX_DWORD shift_dk, KMX_WORD* outputPairs) { UInt32 deadkeystate; UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; @@ -619,7 +620,7 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a * @param fmt text to print */ void mac_KMX_LogError(const wchar_t* fmt, ...) { - WCHAR fmtbuf[256]; + wchar_t fmtbuf[256]; const wchar_t* end = L"\0"; const wchar_t* nl = L"\n"; va_list vars; diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 9ec05cdff8e..3fa7f6d6ce7 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -27,7 +27,7 @@ struct KMX_DeadkeyMapping { // I4353 KMX_WCHAR deadkey, dkid; - UINT shift; + KMX_DWORD shift; KMX_WORD vk; }; diff --git a/mac/mcompile/u16.h b/mac/mcompile/u16.h index 54bac4cd03b..aeafde33c07 100644 --- a/mac/mcompile/u16.h +++ b/mac/mcompile/u16.h @@ -2,7 +2,7 @@ #define U16_H #pragma once -#include "km_types.h" +#include "../../common/include/km_types.h" #include #include #include From e79c5343359cfd075e2fb3d0d7dd7dd87a8ddfdb Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 14 Aug 2024 15:33:14 +0200 Subject: [PATCH 50/71] feat(mac): mcompile remove u16, kmx_file from mcompile-mac and use from common --- mac/mcompile/bu_phonetic.kmx | Bin 73444 -> 0 bytes mac/mcompile/keymap.h | 3 +- mac/mcompile/kmx_file.h | 388 ----------------------------------- mac/mcompile/mc_kmxfile.cpp | 66 +++--- mac/mcompile/mc_kmxfile.h | 2 +- mac/mcompile/mcompile.cpp | 2 +- mac/mcompile/meson.build | 29 +++ mac/mcompile/sil_sahu.kmx | Bin 1418 -> 0 bytes mac/mcompile/u16.cpp | 388 ----------------------------------- mac/mcompile/u16.h | 83 -------- 10 files changed, 66 insertions(+), 895 deletions(-) delete mode 100755 mac/mcompile/bu_phonetic.kmx delete mode 100644 mac/mcompile/kmx_file.h create mode 100644 mac/mcompile/meson.build delete mode 100755 mac/mcompile/sil_sahu.kmx delete mode 100644 mac/mcompile/u16.cpp delete mode 100644 mac/mcompile/u16.h diff --git a/mac/mcompile/bu_phonetic.kmx b/mac/mcompile/bu_phonetic.kmx deleted file mode 100755 index bf5f8b54a221a6431ae78976d1711c22ac6bc42c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73444 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 BjVij5cR2;D{OOJaG@`C>D~`a<^; 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 bDc9P+-~P+0?d|gWvfb;u_HAFq`+5HlZ@II~ diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index ff0bcf1f850..d0cf0c10ab5 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -6,7 +6,8 @@ #include #include #include -#include "u16.h" + +#include "../../common/include/km_u16.h" enum ShiftState { Base = 0, // 0 diff --git a/mac/mcompile/kmx_file.h b/mac/mcompile/kmx_file.h deleted file mode 100644 index b254eb99afe..00000000000 --- a/mac/mcompile/kmx_file.h +++ /dev/null @@ -1,388 +0,0 @@ - -#pragma once -#ifndef KMX_FILE_H -#define KMX_FILE_H - -/* - Copyright: Copyright (C) 2003-2018 SIL International. - Authors: mcdurdin -*/ - -#define UNREFERENCED_PARAMETER(P) (P) -#define TRUNCATE ((size_t) - 1) -#ifdef KMN_KBP -// TODO: move this to a common namespace keyman::common::kmx_file or similar in the future -namespace km { -namespace kbp { -namespace kmx { -#endif - -#define KMX_MAX_ALLOWED_FILE_SIZE (128 * 1024 * 1024) // 128MB // - -#define KEYMAN_LAYOUT_DEFAULT 0x000005FE - -#define KEYMANID_NONKEYMAN 0xFFFFFFFF -#define KEYMANID_IGNORE 0xFFFFFFFE -#define KEYMANID_INVALID 0xFFFFFFFD - -// Shift flags for hotkeys (version 1.0) // -#define SHIFTFLAG 0x2000 -#define CTRLFLAG 0x4000 -#define ALTFLAG 0x8000 - -// Miscellaneous flags and defines // - -#define MAXGROUPS 128 - -// File version identifiers // - -#define VERSION_30 0x00000300 -#define VERSION_31 0x00000301 -#define VERSION_32 0x00000302 -#define VERSION_40 0x00000400 -#define VERSION_50 0x00000500 -#define VERSION_501 0x00000501 -#define VERSION_60 0x00000600 -#define VERSION_70 0x00000700 -#define VERSION_80 0x00000800 -#define VERSION_90 0x00000900 -#define VERSION_100 0x00000A00 -#define VERSION_140 0x00000E00 -#define VERSION_150 0x00000F00 - -#define VERSION_160 0x00001000 - -#define VERSION_MIN VERSION_50 -#define VERSION_MAX VERSION_160 - -// -// Backspace types -// - -#define BK_DEFAULT 0 -#define BK_DEADKEY 1 - -// Different begin types -#define BEGIN_ANSI 0 -#define BEGIN_UNICODE 1 -#define BEGIN_NEWCONTEXT 2 -#define BEGIN_POSTKEYSTROKE 3 - -#define TSS_NONE 0 -#define TSS_BITMAP 1 -#define TSS_COPYRIGHT 2 -#define TSS_HOTKEY 3 -#define TSS_LANGUAGE 4 -#define TSS_LAYOUT 5 -#define TSS_MESSAGE 6 -#define TSS_NAME 7 -#define TSS_VERSION 8 -#define TSS_CAPSONONLY 9 -#define TSS_CAPSALWAYSOFF 10 -#define TSS_SHIFTFREESCAPS 11 -#define TSS_LANGUAGENAME 12 - -#define TSS_CALLDEFINITION 13 -#define TSS_CALLDEFINITION_LOADFAILED 14 - -#define TSS_ETHNOLOGUECODE 15 - -#define TSS_DEBUG_LINE 16 - -#define TSS_MNEMONIC 17 - -#define TSS_INCLUDECODES 18 - -#define TSS_OLDCHARPOSMATCHING 19 - -#define TSS_COMPILEDVERSION 20 -#define TSS_KEYMANCOPYRIGHT 21 - -#define TSS_CUSTOMKEYMANEDITION 22 -#define TSS_CUSTOMKEYMANEDITIONNAME 23 - -// Keyman 7.0 system stores // - -#define TSS__KEYMAN_60_MAX 23 - -#define TSS_VISUALKEYBOARD 24 -#define TSS_KMW_RTL 25 -#define TSS_KMW_HELPFILE 26 -#define TSS_KMW_HELPTEXT 27 -#define TSS_KMW_EMBEDJS 28 - -#define TSS_WINDOWSLANGUAGES 29 - -#define TSS__KEYMAN_70_MAX 29 - -// Keyman 8.0 system stores // - -#define TSS_COMPARISON 30 - -#define TSS__KEYMAN_80_MAX 30 - -// Keyman 9.0 system stores // - -#define TSS_PLATFORM 31 -#define TSS_BASELAYOUT 32 -#define TSS_LAYER 33 - -#define TSS_PLATFORM_NOMATCH 0x8001 // Reserved for internal use - after platform statement is run, set to either TSS_PLATFORM_NOMATCH or TSS_PLATFORM_MATCH -#define TSS_PLATFORM_MATCH 0x8002 // Reserved for internal use - as the result will never change for the lifetime of the process. - -#define TSS_VKDICTIONARY 34 // Dictionary of virtual key names for v9 dynamic layouts -#define TSS_LAYOUTFILE 35 // Keyman 9 layer-based JSON OSK -#define TSS_KEYBOARDVERSION 36 // &keyboardversion system store // I4140 -#define TSS_KMW_EMBEDCSS 37 - -#define TSS_TARGETS 38 - -#define TSS__KEYMAN_90_MAX 38 - -// Keyman 14.0 system stores // - -#define TSS_CASEDKEYS 39 - -#define TSS__KEYMAN_140_MAX 39 - -// Keyman 15.0 system stores // - -#define TSS_BEGIN_NEWCONTEXT 40 -#define TSS_BEGIN_POSTKEYSTROKE 41 -#define TSS_NEWLAYER 42 -#define TSS_OLDLAYER 43 - -#define TSS__KEYMAN_150_MAX 43 - -#define TSS__MAX 43 - -// wm_keyman_control_internal message control codes // - -#define KMCI_SELECTKEYBOARD 3 // I3933 -#define KMCI_SELECTKEYBOARD_TSF 4 // I3933 -#define KMCI_GETACTIVEKEYBOARD 5 // I3933 -#define KMCI_SETFOREGROUND 6 // I3933 -#define KMCI_SELECTKEYBOARD_BACKGROUND 7 // I4271 -#define KMCI_SELECTKEYBOARD_BACKGROUND_TSF 8 // I4271 - -#define FILEID_COMPILED 0x5354584B - -#define SZMAX_LANGUAGENAME 80 -#define SZMAX_KEYBOARDNAME 80 -#define SZMAX_COPYRIGHT 256 -#define SZMAX_MESSAGE 1024 - -#define UC_SENTINEL 0xFFFF -#define UC_SENTINEL_EXTENDEDEND 0x10 // was ((CODE_LASTCODE)+1)... what was I thinking? - -#define U_UC_SENTINEL u"\uFFFF" - -/* - VK__MAX defines the highest virtual key code defined in the system = 0xFF. Custom VK codes start at 256 -*/ -#define VK__MAX 255 - -#define CODE_ANY 0x01 -#define CODE_INDEX 0x02 -#define CODE_CONTEXT 0x03 -#define CODE_NUL 0x04 -#define CODE_USE 0x05 -#define CODE_RETURN 0x06 -#define CODE_BEEP 0x07 -#define CODE_DEADKEY 0x08 -// 0x09 = bkspace.-- we don't need to keep this separate though with UC_SENTINEL -#define CODE_EXTENDED 0x0A -//#define CODE_EXTENDEDEND 0x0B deprecated -#define CODE_SWITCH 0x0C -#define CODE_KEY 0x0D -#define CODE_CLEARCONTEXT 0x0E -#define CODE_CALL 0x0F -// UC_SENTINEL_EXTENDEDEND 0x10 -#define CODE_CONTEXTEX 0x11 - -#define CODE_NOTANY 0x12 - -#define CODE_KEYMAN70_LASTCODE 0x12 - -#define CODE_SETOPT 0x13 -#define CODE_IFOPT 0x14 -#define CODE_SAVEOPT 0x15 -#define CODE_RESETOPT 0x16 - -#define CODE_KEYMAN80_LASTCODE 0x16 - -// Keyman 9.0 codes // - -#define CODE_IFSYSTEMSTORE 0x17 -#define CODE_SETSYSTEMSTORE 0x18 - -#define CODE_LASTCODE 0x18 - -#define U_CODE_ANY u"\u0001" -#define U_CODE_INDEX u"\u0002" -#define U_CODE_CONTEXT u"\u0003" -#define U_CODE_NUL u"\u0004" -#define U_CODE_USE u"\u0005" -#define U_CODE_RETURN u"\u0006" -#define U_CODE_BEEP u"\u0007" -#define U_CODE_DEADKEY u"\u0008" -#define U_CODE_EXTENDED u"\u000A" -#define U_CODE_SWITCH u"\u000C" -#define U_CODE_CLEARCONTEXT u"\u000E" -#define U_CODE_CALL u"\u000F" -#define U_CODE_EXTENDEDEND u"\u0010" -#define U_CODE_CONTEXTEX u"\u0011" -#define U_CODE_NOTANY u"\u0012" -#define U_CODE_SETOPT u"\u0013" -#define U_CODE_IFOPT u"\u0014" -#define U_CODE_SAVEOPT u"\u0015" -#define U_CODE_RESETOPT u"\u0016" -#define U_CODE_IFSYSTEMSTORE u"\u0017" -#define U_CODE_SETSYSTEMSTORE u"\u0018" - -#define C_CODE_ANY(store) U_UC_SENTINEL U_CODE_ANY store -#define C_CODE_INDEX(val1, val2) U_UC_SENTINEL U_CODE_INDEX val1 val2 -#define C_CODE_CONTEXT() U_UC_SENTINEL U_CODE_CONTEXT -#define C_CODE_NUL() U_UC_SENTINEL U_CODE_NUL -#define C_CODE_USE(val) U_UC_SENTINEL U_CODE_USE val -#define C_CODE_RETURN() U_UC_SENTINEL U_CODE_RETURN -#define C_CODE_BEEP() U_UC_SENTINEL U_CODE_BEEP -#define C_CODE_DEADKEY(deadkey) U_UC_SENTINEL U_CODE_DEADKEY deadkey -#define C_CODE_EXTENDED(varargs) U_UC_SENTINEL U_CODE_EXTENDED varargs -#define C_CODE_SWITCH(val) U_UC_SENTINEL U_CODE_SWITCH val -#define C_CODE_CLEARCONTEXT() U_UC_SENTINEL U_CODE_CLEARCONTEXT -#define C_CODE_CALL(val) U_UC_SENTINEL U_CODE_CALL val -#define C_CODE_CONTEXTEX(val) U_UC_SENTINEL U_CODE_CONTEXTEX val -#define C_CODE_NOTANY(val) U_UC_SENTINEL U_CODE_NOTANY val -#define C_CODE_SETOPT(val1, val2) U_UC_SENTINEL U_CODE_SETOPT val1 val2 -#define C_CODE_IFOPT(opt, val1, val2) U_UC_SENTINEL U_CODE_IFOPT opt val1 val2 -#define C_CODE_SAVEOPT(opt) U_UC_SENTINEL U_CODE_SAVEOPT opt -#define C_CODE_RESETOPT(opt) U_UC_SENTINEL U_CODE_RESETOPT opt -#define C_CODE_IFSYSTEMSTORE(store, val1, val2) U_UC_SENTINEL U_CODE_IFSYSTEMSTORE store val1 val2 -#define C_CODE_SETSYSTEMSTORE(store, val) U_UC_SENTINEL U_CODE_SETSYSTEMSTORE store val - -#define KF_SHIFTFREESCAPS 0x0001 -#define KF_CAPSONONLY 0x0002 -#define KF_CAPSALWAYSOFF 0x0004 -#define KF_LOGICALLAYOUT 0x0008 -#define KF_AUTOMATICVERSION 0x0010 - -// 16.0: Support for LDML Keyboards in KMXPlus file format -#define KF_KMXPLUS 0x0020 - -#define HK_ALT 0x00010000 -#define HK_CTRL 0x00020000 -#define HK_SHIFT 0x00040000 - -#define LCTRLFLAG 0x0001 // Left Control flag -#define RCTRLFLAG 0x0002 // Right Control flag -#define LALTFLAG 0x0004 // Left Alt flag -#define RALTFLAG 0x0008 // Right Alt flag -#define K_SHIFTFLAG 0x0010 // Either shift flag -#define K_CTRLFLAG 0x0020 // Either ctrl flag -#define K_ALTFLAG 0x0040 // Either alt flag -//#define K_METAFLAG 0x0080 // Either Meta-key flag (tentative). Not usable in keyboard rules; - // Used internally (currently, only by KMW) to ensure Meta-key - // shortcuts safely bypass rules - // Meta key = Command key on macOS, Windows key on Windows -#define CAPITALFLAG 0x0100 // Caps lock on -#define NOTCAPITALFLAG 0x0200 // Caps lock NOT on -#define NUMLOCKFLAG 0x0400 // Num lock on -#define NOTNUMLOCKFLAG 0x0800 // Num lock NOT on -#define SCROLLFLAG 0x1000 // Scroll lock on -#define NOTSCROLLFLAG 0x2000 // Scroll lock NOT on -#define ISVIRTUALKEY 0x4000 // It is a Virtual Key Sequence -#define VIRTUALCHARKEY 0x8000 // Keyman 6.0: Virtual Key Cap Sequence NOT YET - -#define K_MODIFIERFLAG 0x007F -#define K_NOTMODIFIERFLAG 0xFF00 // I4548 - -struct KMX_COMP_STORE { - KMX_DWORD dwSystemID; - KMX_DWORD dpName; - KMX_DWORD dpString; - }; - -struct KMX_COMP_KEY { - KMX_WORD Key; - KMX_WORD _reserved; - KMX_DWORD Line; - KMX_DWORD ShiftFlags; - KMX_DWORD dpOutput; - KMX_DWORD dpContext; - }; - -struct KMX_COMP_GROUP { - KMX_DWORD dpName; - KMX_DWORD dpKeyArray; // [LPKEY] address of first item in key array - KMX_DWORD dpMatch; - KMX_DWORD dpNoMatch; - KMX_DWORD cxKeyArray; // in array entries - KMX_BOOL fUsingKeys; // group(xx) [using keys] <-- specified or not - }; - -struct KMX_COMP_KEYBOARD { - KMX_DWORD dwIdentifier; // 0000 Keyman compiled keyboard id - - KMX_DWORD dwFileVersion; // 0004 Version of the file - Keyman 4.0 is 0x0400 - - KMX_DWORD dwCheckSum; // 0008 As stored in keyboard. DEPRECATED as of 16.0 - KMX_DWORD KeyboardID; // 000C as stored in HKEY_LOCAL_MACHINE//system//currentcontrolset//control//keyboard layouts - KMX_DWORD IsRegistered; // 0010 - KMX_DWORD version; // 0014 keyboard version - - KMX_DWORD cxStoreArray; // 0018 in array entries - KMX_DWORD cxGroupArray; // 001C in array entries - - KMX_DWORD dpStoreArray; // 0020 [LPSTORE] address of first item in store array - KMX_DWORD dpGroupArray; // 0024 [LPGROUP] address of first item in group array - - KMX_DWORD StartGroup[2]; // 0028 index of starting groups [2 of them] - - KMX_DWORD dwFlags; // 0030 Flags for the keyboard file - - KMX_DWORD dwHotKey; // 0034 standard windows hotkey (hiword=shift/ctrl/alt stuff, loword=vkey) - - KMX_DWORD dpBitmapOffset; // 0038 offset of the bitmaps in the file - KMX_DWORD dwBitmapSize; // 003C size in bytes of the bitmaps -}; - -struct KMX_COMP_KEYBOARD_KMXPLUSINFO { - KMX_DWORD dpKMXPlus; // 0040 offset of KMXPlus data, header is first - KMX_DWORD dwKMXPlusSize; // 0044 size in bytes of entire KMXPlus data -}; - -// - //* Only valid if comp_keyboard.dwFlags&KF_KMXPLUS - // -struct KMX_COMP_KEYBOARD_EX { - KMX_COMP_KEYBOARD header; // 0000 see COMP_KEYBOARD - KMX_COMP_KEYBOARD_KMXPLUSINFO kmxplus; // 0040 see COMP_KEYBOARD_EXTRA -}; - -typedef KMX_COMP_KEYBOARD *PKMX_COMP_KEYBOARD; -typedef KMX_COMP_STORE *PKMX_COMP_STORE; -typedef KMX_COMP_KEY *PKMX_COMP_KEY; -typedef KMX_COMP_GROUP *PKMX_COMP_GROUP; - - -extern const int CODE__SIZE[]; -#define CODE__SIZE_MAX 5 - -#define KEYBOARDFILEHEADER_SIZE 64 -#define KEYBOARDFILESTORE_SIZE 12 -#define KEYBOARDFILEGROUP_SIZE 24 -#define KEYBOARDFILEKEY_SIZE 20 - -static_assert(sizeof(KMX_COMP_STORE) == KEYBOARDFILESTORE_SIZE, "COMP_STORE must be KEYBOARDFILESTORE_SIZE bytes"); -static_assert(sizeof(KMX_COMP_KEY) == KEYBOARDFILEKEY_SIZE, "COMP_KEY must be KEYBOARDFILEKEY_SIZE bytes"); -static_assert(sizeof(KMX_COMP_GROUP) == KEYBOARDFILEGROUP_SIZE, "COMP_GROUP must be KEYBOARDFILEGROUP_SIZE bytes"); -static_assert(sizeof(KMX_COMP_KEYBOARD) == KEYBOARDFILEHEADER_SIZE, "COMP_KEYBOARD must be KEYBOARDFILEHEADER_SIZE bytes"); - -#ifdef KMN_KBP -} // namespace kmx -} // namespace kbp -} // namespace km -#endif -#endif //KMX_FILE_H - diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index 86845f81653..d75f3076de5 100644 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -58,18 +58,18 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX LPKMX_STORE fsp; LPKMX_KEY fkp; - PKMX_COMP_KEYBOARD ck; - PKMX_COMP_GROUP gp; - PKMX_COMP_STORE sp; - PKMX_COMP_KEY kp; + PCOMP_KEYBOARD ck; + PCOMP_GROUP gp; + PCOMP_STORE sp; + PCOMP_KEY kp; PKMX_BYTE buf; KMX_DWORD size, offset; KMX_DWORD i, j; // Calculate how much memory to allocate - size = sizeof(KMX_COMP_KEYBOARD) + - fk->cxGroupArray * sizeof(KMX_COMP_GROUP) + - fk->cxStoreArray * sizeof(KMX_COMP_STORE) + + size = sizeof(COMP_KEYBOARD) + + fk->cxGroupArray * sizeof(COMP_GROUP) + + fk->cxStoreArray * sizeof(COMP_STORE) + //wcslen(fk->szName)*2 + 2 + //wcslen(fk->szCopyright)*2 + 2 + //wcslen(fk->szLanguageName)*2 + 2 + @@ -79,7 +79,7 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX for (i = 0, fgp = fk->dpGroupArray; i < fk->cxGroupArray; i++, fgp++) { if (fgp->dpName) size += (u16len(fgp->dpName) + 1) * sizeof(KMX_WCHAR); - size += fgp->cxKeyArray * sizeof(KMX_COMP_KEY); + size += fgp->cxKeyArray * sizeof(COMP_KEY); for (j = 0, fkp = fgp->dpKeyArray; j < fgp->cxKeyArray; j++, fkp++) { size += (u16len(fkp->dpOutput) + 1) * sizeof(KMX_WCHAR); size += (u16len(fkp->dpContext) + 1) * sizeof(KMX_WCHAR); @@ -100,7 +100,7 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX return CERR_CannotAllocateMemory; memset(buf, 0, size); - ck = (PKMX_COMP_KEYBOARD)buf; + ck = (PCOMP_KEYBOARD)buf; ck->dwIdentifier = FILEID_COMPILED; @@ -116,12 +116,12 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX ck->dwFlags = fk->dwFlags; - offset = sizeof(KMX_COMP_KEYBOARD); + offset = sizeof(COMP_KEYBOARD); ck->dpStoreArray = offset; - sp = (PKMX_COMP_STORE)(buf + offset); + sp = (PCOMP_STORE)(buf + offset); fsp = fk->dpStoreArray; - offset += sizeof(KMX_COMP_STORE) * ck->cxStoreArray; + offset += sizeof(COMP_STORE) * ck->cxStoreArray; for (i = 0; i < ck->cxStoreArray; i++, sp++, fsp++) { sp->dwSystemID = fsp->dwSystemID; sp->dpString = offset; @@ -138,9 +138,9 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX } ck->dpGroupArray = offset; - gp = (PKMX_COMP_GROUP)(buf + offset); + gp = (PCOMP_GROUP)(buf + offset); - offset += sizeof(KMX_COMP_GROUP) * ck->cxGroupArray; + offset += sizeof(COMP_GROUP) * ck->cxGroupArray; for (i = 0, fgp = fk->dpGroupArray; i < ck->cxGroupArray; i++, gp++, fgp++) { gp->cxKeyArray = fgp->cxKeyArray; @@ -168,8 +168,8 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX } gp->dpKeyArray = offset; - kp = (PKMX_COMP_KEY)(buf + offset); - offset += gp->cxKeyArray * sizeof(KMX_COMP_KEY); + kp = (PCOMP_KEY)(buf + offset); + offset += gp->cxKeyArray * sizeof(COMP_KEY); for (j = 0, fkp = fgp->dpKeyArray; j < gp->cxKeyArray; j++, kp++, fkp++) { kp->Key = fkp->Key; @@ -265,7 +265,7 @@ PKMX_WCHAR KMX_StringOffset(PKMX_BYTE base, KMX_DWORD offset) { * @return pointer to the keyboard */ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { - PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)base; + PCOMP_KEYBOARD ckbp = (PCOMP_KEYBOARD)base; // Copy keyboard structure // @@ -291,20 +291,20 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { kbp->dpGroupArray = (LPKMX_GROUP)bufp; bufp += sizeof(KMX_GROUP) * kbp->cxGroupArray; - PKMX_COMP_STORE csp; + PCOMP_STORE csp; LPKMX_STORE sp; KMX_DWORD i; - for (csp = (PKMX_COMP_STORE)(base + ckbp->dpStoreArray), sp = kbp->dpStoreArray, i = 0; i < kbp->cxStoreArray; i++, sp++, csp++) { + for (csp = (PCOMP_STORE)(base + ckbp->dpStoreArray), sp = kbp->dpStoreArray, i = 0; i < kbp->cxStoreArray; i++, sp++, csp++) { sp->dwSystemID = csp->dwSystemID; sp->dpName = KMX_StringOffset(base, csp->dpName); sp->dpString = KMX_StringOffset(base, csp->dpString); } - PKMX_COMP_GROUP cgp; + PCOMP_GROUP cgp; LPKMX_GROUP gp; - for (cgp = (PKMX_COMP_GROUP)(base + ckbp->dpGroupArray), gp = kbp->dpGroupArray, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) { + for (cgp = (PCOMP_GROUP)(base + ckbp->dpGroupArray), gp = kbp->dpGroupArray, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) { gp->dpName = KMX_StringOffset(base, cgp->dpName); gp->dpKeyArray = cgp->cxKeyArray > 0 ? (LPKMX_KEY)bufp : NULL; gp->cxKeyArray = cgp->cxKeyArray; @@ -313,11 +313,11 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { gp->dpNoMatch = KMX_StringOffset(base, cgp->dpNoMatch); gp->fUsingKeys = cgp->fUsingKeys; - PKMX_COMP_KEY ckp; + PCOMP_KEY ckp; LPKMX_KEY kp; KMX_DWORD j; - for (ckp = (PKMX_COMP_KEY)(base + cgp->dpKeyArray), kp = gp->dpKeyArray, j = 0; j < gp->cxKeyArray; j++, kp++, ckp++) { + for (ckp = (PCOMP_KEY)(base + cgp->dpKeyArray), kp = gp->dpKeyArray, j = 0; j < gp->cxKeyArray; j++, kp++, ckp++) { kp->Key = ckp->Key; kp->Line = ckp->Line; kp->ShiftFlags = ckp->ShiftFlags; @@ -343,10 +343,10 @@ LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFil UNREFERENCED_PARAMETER(dwFileSize); KMX_DWORD i, j; - PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)base; - PKMX_COMP_GROUP cgp; - PKMX_COMP_STORE csp; - PKMX_COMP_KEY ckp; + PCOMP_KEYBOARD ckbp = (PCOMP_KEYBOARD)base; + PCOMP_GROUP cgp; + PCOMP_STORE csp; + PCOMP_KEY ckp; LPKMX_KEYBOARD kbp = (LPKMX_KEYBOARD)bufp; LPKMX_STORE sp; LPKMX_GROUP gp; @@ -355,18 +355,18 @@ LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFil kbp->dpStoreArray = (LPKMX_STORE)(base + ckbp->dpStoreArray); kbp->dpGroupArray = (LPKMX_GROUP)(base + ckbp->dpGroupArray); - for (sp = kbp->dpStoreArray, csp = (PKMX_COMP_STORE)sp, i = 0; i < kbp->cxStoreArray; i++, sp++, csp++) { + for (sp = kbp->dpStoreArray, csp = (PCOMP_STORE)sp, i = 0; i < kbp->cxStoreArray; i++, sp++, csp++) { sp->dpName = KMX_StringOffset(base, csp->dpName); sp->dpString = KMX_StringOffset(base, csp->dpString); } - for (gp = kbp->dpGroupArray, cgp = (PKMX_COMP_GROUP)gp, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) { + for (gp = kbp->dpGroupArray, cgp = (PCOMP_GROUP)gp, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) { gp->dpName = KMX_StringOffset(base, cgp->dpName); gp->dpKeyArray = (LPKMX_KEY)(base + cgp->dpKeyArray); if (cgp->dpMatch != NULL)gp->dpMatch = (PKMX_WCHAR)(base + cgp->dpMatch); if (cgp->dpNoMatch != NULL)gp->dpNoMatch = (PKMX_WCHAR)(base + cgp->dpNoMatch); - for (kp = gp->dpKeyArray, ckp = (PKMX_COMP_KEY)kp, j = 0; j < gp->cxKeyArray; j++, kp++, ckp++) { + for (kp = gp->dpKeyArray, ckp = (PCOMP_KEY)kp, j = 0; j < gp->cxKeyArray; j++, kp++, ckp++) { kp->dpOutput = (PKMX_WCHAR)(base + ckp->dpOutput); kp->dpContext = (PKMX_WCHAR)(base + ckp->dpContext); } @@ -497,14 +497,14 @@ KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) { */ KMX_BOOL KMX_VerifyKeyboard(PKMX_BYTE filebase, KMX_DWORD file_size) { KMX_DWORD i; - PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)filebase; - PKMX_COMP_STORE csp; + PCOMP_KEYBOARD ckbp = (PCOMP_KEYBOARD)filebase; + PCOMP_STORE csp; // Check file version // if (ckbp->dwFileVersion < VERSION_MIN || ckbp->dwFileVersion > VERSION_MAX) { // Old or new version -- identify the desired program version // - for (csp = (PKMX_COMP_STORE)(filebase + ckbp->dpStoreArray), i = 0; i < ckbp->cxStoreArray; i++, csp++) { + for (csp = (PCOMP_STORE)(filebase + ckbp->dpStoreArray), i = 0; i < ckbp->cxStoreArray; i++, csp++) { if (csp->dwSystemID == TSS_COMPILEDVERSION) { if (csp->dpString == 0) { mac_KMX_LogError(L"errWrongFileVersion:NULL"); diff --git a/mac/mcompile/mc_kmxfile.h b/mac/mcompile/mc_kmxfile.h index 12d9ba4a8c9..014a8146bf9 100644 --- a/mac/mcompile/mc_kmxfile.h +++ b/mac/mcompile/mc_kmxfile.h @@ -3,7 +3,7 @@ #define MC_KMXFILE_H #include "../../common/include/km_types.h" -#include "kmx_file.h" +#include "../../common/include/kmx_file.h" #include "mcompile.h" #ifndef _KMXFILE_H diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index a13d04d7fa1..e3ccd0353e7 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -13,7 +13,7 @@ #include #include #include "mcompile.h" -#include "u16.h" +#include "../../common/include/km_u16.h" /** @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard */ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc); diff --git a/mac/mcompile/meson.build b/mac/mcompile/meson.build new file mode 100644 index 00000000000..30e9d2e3753 --- /dev/null +++ b/mac/mcompile/meson.build @@ -0,0 +1,29 @@ +project('mcompile', 'c', 'cpp', + license: 'MIT', + meson_version: '>=1.0') + +carbon = dependency('Carbon') + +deps = [carbon] + +# subdir('resources') + +cpp_files = files( + 'keymap.cpp', + 'mcompile.cpp', + 'mc_kmxfile.cpp', + 'mc_import_rules.cpp', + '../../common/cpp/km_u16.cpp', + ) + +comon_include_dir = [ + include_directories('../../common/include') +] + +mcompile = executable( + 'mcompile', + cpp_args: ['-std=c++17'], # this should be defined from resources/standard.meson.build + sources: [cpp_files], + dependencies: deps, + include_directories : comon_include_dir + ) \ No newline at end of file diff --git a/mac/mcompile/sil_sahu.kmx b/mac/mcompile/sil_sahu.kmx deleted file mode 100755 index e5548549a7b9ad70c5cb5f53fa0fd0b5d948a323..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1418 zcmai!%}-NN5XDa)eh@VT{6NHnR3)`8XecX5NQ6?T&>{pXh%O4Hq)@RXP>i^6;gXdL z7j8`y_wL;KCm3V=6IdAI%CIoh-`saKBqnl`!^}B%-nlck?~%QipV294EB>J%R>c0W zT7cz)V53QDut@)|o#SEJPWT4)z(w#2d;;XUF{NeQT5@P zRKI#$)<+)oE>TXXQoGD^RnDmMbj@XJ&VQKmr!-G5W6J2Z@~BDIWrAoOWI26aDe8u( zO8?V&ST#YXBXnxhjL~b3>Ur2*=V&*u?cDOtB|~kV4y8@{SyO=+&Y#f3L$}sLzcp@U ziFtddTg1h9-FY28W0X^K?w*pa?+iB*b$7qY+2Y9}E+xFnoLE7tapo3&x7aPRzsa7> z@;I0Yc7wU#L9h_41aE_EBp_U@OEH+aj$j2yMX!G zdvA47cnqYV9j3A3@B~PcUvi4n2fqn2@J_D{z*Arxe%WiI@Ej<@&v|VMJ_}0l^Ip3T zUjSwJ1+SIh6$9M<2idB^>);uAms6xC@aG_=)| mc|#AIGIX)oLLZwbbh0@@FY7*Zvz{A`Kxf?V-e^R08s#_66QKbB diff --git a/mac/mcompile/u16.cpp b/mac/mcompile/u16.cpp deleted file mode 100644 index 2ee561e5a6a..00000000000 --- a/mac/mcompile/u16.cpp +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Keyman is copyright (C) 2004 - 2024 SIL International. MIT License. - * - * Functions for u16string - */ - -#include "u16.h" -#include -#include -#include -#include "../../core/src/utfcodec.hpp" - -/** string <- wstring -* @brief Obtain a std::string from a std::wstring -* @param wstr the std::wstring to be converted -* @return a std::string -*/ -std::string string_from_wstring(std::wstring const wstr) { - return convert((const std::wstring)wstr); -} - -/** wstring <- string -* @brief Obtain a std::wstring from a std::string -* @param str the std::string to be converted -* @return a std::wstring -*/ -std::wstring wstring_from_string(std::string const str) { - return convert((const std::string)str); -} - -/** u16String <- string -* @brief Obtain a std::u16tring from a std::string -* @param str the std::string to be converted -* @return a std::u16string -*/ -std::u16string u16string_from_string(std::string const str) { - return convert((const std::string)str); -} - -/** string <- u16string -* @brief Obtain a std::string from a std::u16string -* @param str16 the std::u16string to be converted -* @return a std::string -*/ -std::string string_from_u16string(std::u16string const str16) { - return convert((const std::u16string)str16); -} - -/** wstring <- u16string -* @brief Obtain a std::wstring from a std::u16string -* @param str16 the std::u16string to be converted -* @return a std::wstring -*/ -std::wstring wstring_from_u16string(std::u16string const str16) { - return convert((const std::u16string)str16); -} - -/** u16string <- wstring -* @brief Obtain a std::u16string from a std::wstring -* @param wstr the std::wstring to be converted -* @return a std::u16string -*/ -std::u16string u16string_from_wstring(std::wstring const wstr) { - return convert((const std::wstring)wstr);; -} - -/** UTF16 (=const wchar_t*) -> std::string -> std::u16string -> UTF16 ( = char16_t*) -* @brief Convert pointer to wchar_t to pointer to char16_t and copy sz elements into dst -* @param dst destination -* @param sz nr of characters to be copied -* @param fmt source to convert and copy -* @return void -*/ -void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...) { - wchar_t* wbuf = new wchar_t[sz]; - va_list args; - va_start(args, fmt); - vswprintf(wbuf, sz, fmt, args); - va_end(args); - - std::u16string u16str = u16string_from_wstring(wbuf); - u16ncpy(dst, u16str.c_str(), sz); - delete[] wbuf; -} - -/** -* @brief Convert u16string to long integer -* @param str u16string beginning with the representation of an integral number. -* @param endptr Reference to the next character in str -* @param base Numerical base (radix) that determines the valid characters and their interpretation -* @return a long -*/ -long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) { - auto s = string_from_u16string(str); - char* t; - long int result = strtol(s.c_str(), &t, base); - if (endptr != nullptr) - *endptr = (KMX_WCHAR*)str + (t - s.c_str()); - return result; -} - -/** - * @brief Append n characters from u16string - * @param dst Pointer to the destination array - * @param src u16string to be appended - * @param max Maximum number of characters to be appended. - * @return Pointer to the destination array - */ -const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { - KMX_WCHAR* o = dst; - dst = (KMX_WCHAR*)u16chr(dst, 0); - // max -= (dst-o); - while (*src && max > 0) { - *dst++ = *src++; - max--; - } - if (max > 0) - *dst = 0; - return o; -} - -/** - * @brief Find last '/' or '\\' in an array of char16_t - * @param name Pointer to the source - * @return Pointer to the last slash/backslash - */ -const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* name) { - const KMX_WCHAR* cp = NULL; - cp = u16rchr(name, '\\'); - if (cp == NULL) - cp = u16rchr(name, '/'); - return cp; -} - -/** - * @brief Find last '/' or '\\' in an array of char - * @param name Pointer to the source - * @return Pointer to the last slash/backslash - */ -KMX_CHAR* strrchr_slash(KMX_CHAR* name) { - KMX_CHAR* cp = NULL; - cp = strrchr(name, '\\'); - if (cp == NULL) - cp = strrchr(name, '/'); - return cp; -} - -/** - * @brief Locate last occurrence of character in u16string - * @param p Pointer to the source - * @param ch The character to be found - * @return A pointer to the last occurrence of character in u16str - */ -const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch) { - const KMX_WCHAR* p_end = p + u16len(p); - - while (p_end > p) { - if (*p_end == ch) - return p_end; - p_end--; - } - return NULL; -} - -/** - * @brief Locate first occurrence of character in u16string - * @param p Pointer to the source - * @param ch The character to be found - * @return A pointer to the first occurrence of character in u16str - */ -const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch) { - while (*p) { - if (*p == ch) - return p; - p++; - } - return ch == 0 ? p : NULL; -} - -/** -* @brief Copy the u16string pointed by src into the array pointed by dst -* @param dst Pointer to the destination -* @param src Pointer to the source to be copied -* @return Pointer to dst -*/ -const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src) { - KMX_WCHAR* o = dst; - while (*src) { - *dst++ = *src++; - } - *dst = 0; - return o; -} - -/** -* @brief Copy max characters of the u16string pointed by src into the array pointed by dst -* @param dst Pointer to the destination -* @param src Pointer to the source to be copied -* @param max Maximum number of characters to be copied -* @return Pointer to dst -*/ -const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) { - KMX_WCHAR* o = dst; - while (*src && max > 0) { - *dst++ = *src++; - max--; - } - if (max > 0) { - *dst = 0; - } - return o; -} - -/** -* @brief Return the length of the u16string str -* @param p Pointer to the source -* @return The length of u16string -*/ -size_t u16len(const KMX_WCHAR* p) { - int i = 0; - while (*p) { - p++; - i++; - } - return i; -} - -/** -* @brief Compare two u16strings -* @param p Pointer one u16string -* @param q Pointer another u16string -* @return 0 if strings are eqaual -* ! = 0 if unequal -*/ -int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q) { - while (*p && *q) { - if (*p != *q) - return *p - *q; - p++; - q++; - } - return *p - *q; -} - -/** -* @brief Case insensitive comparison of up to count characters in two strings -* @param p Pointer one u16string -* @param q Pointer another u16string -* @param count Maximum number of characters to compare -* @return 0 if strings are equal -* ! = 0 if unequal -*/ -int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { - while (*p && *q && count) { - if (toupper(*p) != toupper(*q)) - return *p - *q; - p++; - q++; - count--; - } - if (count) - return *p - *q; - return 0; -} - -/** -* @brief Case insensitive comparison of two strings -* @param p Pointer one u16string -* @param q Pointer another u16string -* @return 0 if strings are equal -* ! = 0 if unequal -*/ -int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q) { - while (*p && *q) { - if (toupper(*p) != toupper(*q)) - return *p - *q; - p++; - q++; - } - return *p - *q; -} - -/** -* @brief Comparison of up to count characters in two strings -* @param p Pointer one u16string -* @param q Pointer another u16string -* @param count Maximum number of characters to compare -* @return 0 if strings are equal -* ! = 0 if unequal -*/ -int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) { - while (*p && *q && count) { - if (*p != *q) - return *p - *q; - p++; - q++; - count--; - } - if (count) - return *p - *q; - return 0; -} - -/** -* @brief Split u16string into tokens -* @param p Pointer to u16string to parse -* @param ch the delimiter character -* @param ctx the remaining string after the first delimiter -* @return Pointer to the first token in p -*/ -KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR ch, KMX_WCHAR** ctx) { - if (!p) { - p = *ctx; - if (!p) - return NULL; - } - KMX_WCHAR* q = p; - while (*q && *q != ch) { - q++; - } - if (*q) { - *q = 0; - q++; - while (*q == ch) - q++; - *ctx = q; - } else { - *ctx = NULL; - } - return *p ? p : NULL; -} - -/** -* @brief Split u16string into tokens -* @param p Pointer to u16string to parse -* @param delimiters an array of delimiter characters -* @param ctx the remaining string after the first delimiter -* @return Pointer to the first token in p -*/ -KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR* delimiters, KMX_WCHAR** ctx) { - if (!p) { - p = *ctx; - if (!p) - return NULL; - } - - KMX_WCHAR* q = p; - while (*q && !u16chr(delimiters, *q)) { - q++; - } - if (*q) { - *q = 0; - q++; - while (*q && u16chr(delimiters, *q)) - q++; - *ctx = q; - } else { - *ctx = NULL; - } - return *p ? p : NULL; -} - -/** -* @brief Convert a u16string to a double -* @param str Pointer to u16string -* @return double value equivalent to the string -*/ -double u16tof(KMX_WCHAR* str) { - double val = 0; - int offsetdot = 0; - char digit; - - PKMX_WCHAR q = (PKMX_WCHAR)u16chr(str, '.'); - size_t pos_dot = (q - str < 0) ? u16len(str) : q - str; - - for (size_t i = 0; i < u16len(str); i++) { - digit = static_cast(towupper(*str)); - - if (i > pos_dot - 1) - offsetdot = 1; - - if (digit != '.') - val = val + ((int(digit)) - 48) * pow(10, (pos_dot - 1 - i + offsetdot)); - - str++; - } - return val; -} diff --git a/mac/mcompile/u16.h b/mac/mcompile/u16.h deleted file mode 100644 index aeafde33c07..00000000000 --- a/mac/mcompile/u16.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef U16_H -#define U16_H -#pragma once - -#include "../../common/include/km_types.h" -#include -#include -#include -#include -#include -#include - - -/** @brief Obtain a std::string from a std::wstring */ -std::string string_from_wstring(std::wstring const wstr); - -/** @brief Obtain a std::wstring from a std::string */ -std::wstring wstring_from_string(std::string const str); - -/** @brief Obtain a std::u16tring from a std::string*/ -std::u16string u16string_from_string(std::string const str); - -/** @brief Obtain a std::string from a std::u16string */ -std::string string_from_u16string(std::u16string const str16); - -/** @brief Obtain a std::wstring from a std::u16string */ -std::wstring wstring_from_u16string(std::u16string const str16); - -/** @brief Obtain a std::u16string from a std::wstring */ -std::u16string u16string_from_wstring(std::wstring const wstr); - -/** @brief Convert pointer to wchar_t to pointer to char16_t and copy sz elements into dst */ -void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...); - -/** @brief Convert u16string to long integer */ -long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base); - -/** @brief Append max characters from u16string */ -const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max); - -/** @brief find last '/' or '\\' in an array of char16_t */ -const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name); - -/** @brief find last '/' or '\\' in an array of char */ -KMX_CHAR* strrchr_slash(KMX_CHAR* Name); - -/** @brief Locate last occurrence of character in u16string */ -const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch); - -/** @brief Locate first occurrence of character in u16string */ -const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch); - -/** @brief Copy the u16string pointed to by src into the array pointed to by dst */ -const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src); - -/** @brief Copy max characters of the u16string pointed to by src into the array pointed to by dst */ -const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max); - -/** @brief Return the length of the u16string str */ -size_t u16len(const KMX_WCHAR* p); - -/** @brief Compare two u16strings */ -int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q); - -/** @brief Case insensitive comparison of up to count characters in two strings */ -int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count); - -/** @brief Case insensitive comparison of two strings */ -int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q); - -/** @brief Comparison of up to count characters in two strings */ -int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count); - -/** @brief Split u16string into tokens */ -KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR ch, KMX_WCHAR** ctx); - -/** @brief Split u16string into tokens */ -KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR* delimiters, KMX_WCHAR** ctx); - -/** @brief Convert a u16string to a double */ -double u16tof(KMX_WCHAR* str); - -#endif /* U16_H */ From 8c480ac1312187a2d6311820a6fe8b0a067bb7d1 Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 14 Aug 2024 16:00:27 +0200 Subject: [PATCH 51/71] feat(mac): add build.sh --- mac/mcompile/.gitignore | 2 ++ mac/mcompile/build.sh | 61 ++++++++++++++++++++++++++++++++++++++++ mac/mcompile/meson.build | 2 +- 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 mac/mcompile/.gitignore create mode 100755 mac/mcompile/build.sh diff --git a/mac/mcompile/.gitignore b/mac/mcompile/.gitignore new file mode 100644 index 00000000000..f59fab25960 --- /dev/null +++ b/mac/mcompile/.gitignore @@ -0,0 +1,2 @@ +resources/ +build/ \ No newline at end of file diff --git a/mac/mcompile/build.sh b/mac/mcompile/build.sh new file mode 100755 index 00000000000..b04c20e04a4 --- /dev/null +++ b/mac/mcompile/build.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../resources/build/builder.inc.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +################################ Main script ################################ + +builder_describe \ + "Mnemonic layout recompiler for macOS" \ + "@/common/include" \ + "clean" \ + "configure" \ + "build" \ + "test" + +builder_parse "$@" + +builder_describe_outputs \ + configure build/build.ninja \ + build build/mcompile + +TARGET_PATH="$THIS_SCRIPT_PATH/build" + +do_clean() { + rm -rf "$THIS_SCRIPT_PATH/resources" + rm -rf "$TARGET_PATH" +} + +do_configure() { + # Import our standard compiler defines; this is copied from + # /resources/build/meson/standard.meson.build by build.sh, because meson doesn't + # allow us to reference a file outside its root + mkdir -p "$THIS_SCRIPT_PATH/resources" + cp "$KEYMAN_ROOT/resources/build/meson/standard.meson.build" "$THIS_SCRIPT_PATH/resources/meson.build" + + pushd "$THIS_SCRIPT_PATH" > /dev/null + # Additional arguments are used by Linux build, e.g. -Dprefix=${INSTALLDIR} + meson setup build --buildtype $BUILDER_CONFIGURATION "${builder_extra_params[@]}" + popd > /dev/null + +} + +do_build() { + pushd "$TARGET_PATH" > /dev/null + ninja + popd > /dev/null +} + +do_test() { + pushd "$TARGET_PATH" > /dev/null + meson test "${builder_extra_params[@]}" + popd > /dev/null +} + +builder_run_action clean do_clean +builder_run_action configure do_configure +builder_run_action build do_build +builder_run_action test do_test \ No newline at end of file diff --git a/mac/mcompile/meson.build b/mac/mcompile/meson.build index 30e9d2e3753..469c5805374 100644 --- a/mac/mcompile/meson.build +++ b/mac/mcompile/meson.build @@ -6,7 +6,7 @@ carbon = dependency('Carbon') deps = [carbon] -# subdir('resources') +subdir('resources') cpp_files = files( 'keymap.cpp', From 07edecd17fb090d7b82d76342a49f2c8f6e0a6b3 Mon Sep 17 00:00:00 2001 From: Sabine Date: Thu, 15 Aug 2024 09:08:40 +0200 Subject: [PATCH 52/71] chore(mac): disable optimization for mcompile See https://github.com/keymanapp/keyman/pull/11334#issuecomment-2290784399 for details, but with anything other than -O0, the output is not correct This is intended to be a temporary workaround --- mac/mcompile/mcompile.cpp | 6 +++--- mac/mcompile/meson.build | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index e3ccd0353e7..10cfe7eb8a2 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -398,9 +398,9 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { return 0; } - for (int i = 0; i < s_ndkids; i++) { - if (s_dkids[i].src_deadkey == deadkey) { - return s_dkids[i].dst_deadkey; + for (int xi = 0; xi < s_ndkids; xi++) { + if (s_dkids[xi].src_deadkey == deadkey) { + return s_dkids[xi].dst_deadkey; } } diff --git a/mac/mcompile/meson.build b/mac/mcompile/meson.build index 469c5805374..5c46335674e 100644 --- a/mac/mcompile/meson.build +++ b/mac/mcompile/meson.build @@ -2,6 +2,9 @@ project('mcompile', 'c', 'cpp', license: 'MIT', meson_version: '>=1.0') +# see https://github.com/keymanapp/keyman/pull/11334#issuecomment-2290784399 +add_project_arguments('-O0', language : 'cpp') + carbon = dependency('Carbon') deps = [carbon] From d9260457258b75b2dc5c1c7e0746022c2e1a7e0c Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 16 Aug 2024 10:47:13 +0200 Subject: [PATCH 53/71] chore(mac): add mcompile to build.sh --- mac/build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/mac/build.sh b/mac/build.sh index fbca48bd05f..0db1a84f5f0 100755 --- a/mac/build.sh +++ b/mac/build.sh @@ -20,6 +20,7 @@ builder_describe "Builds Keyman for macOS." \ "install Installs result of Keyman4MacIM locally." \ ":engine KeymanEngine4Mac" \ ":app Keyman4MacIM" \ + ":mcompile mnemonic layout recompiler- mac" ":testapp Keyman4Mac (test harness)" \ "--quick,-q Bypasses notarization for $(builder_term install)" From dd0ebc43252d9fb375d646f7586b63407cefbce7 Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 16 Aug 2024 10:58:41 +0200 Subject: [PATCH 54/71] chore(mac): add backslash to build.sh --- mac/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mac/build.sh b/mac/build.sh index 0db1a84f5f0..c9dedc04ae6 100755 --- a/mac/build.sh +++ b/mac/build.sh @@ -20,7 +20,7 @@ builder_describe "Builds Keyman for macOS." \ "install Installs result of Keyman4MacIM locally." \ ":engine KeymanEngine4Mac" \ ":app Keyman4MacIM" \ - ":mcompile mnemonic layout recompiler- mac" + ":mcompile mnemonic layout recompiler- mac" \ ":testapp Keyman4Mac (test harness)" \ "--quick,-q Bypasses notarization for $(builder_term install)" From 963bb5218ec1346606107841d33e7a61248a643e Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 16 Aug 2024 17:11:51 +0200 Subject: [PATCH 55/71] chore(mac): change bitmapoffset + bitmapsize to prvent buffer problems --- mac/mcompile/keymap.cpp | 5 +++-- mac/mcompile/mc_kmxfile.cpp | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 0a9e520f63c..c4ae0d6c3ff 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -303,7 +303,6 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la * or else the keyval obtained from Keycode and shiftstate and caps; */ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, KMX_DWORD kc_underlying, KMX_DWORD vk_ShiftState, PKMX_WCHAR deadKey) { - PKMX_WCHAR dky = NULL; UInt32 isdk = 0; KMX_DWORD keyV; int caps = 0; @@ -315,7 +314,9 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa // if there was a deadkey return 0xFFFF and copy deadkey into dky; else return the keyvalue if (isdk != 0) { - dky = (PKMX_WCHAR)(std::u16string(1, keyV)).c_str(); + PKMX_WCHAR dky = NULL; + std::u16string keyVS(1, keyV); + dky = (PKMX_WCHAR) keyVS.c_str(); *deadKey = *dky; return 0xFFFF; } diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index d75f3076de5..78aa40615cc 100644 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -285,6 +285,9 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { kbp->dwFlags = ckbp->dwFlags; kbp->dwHotKey = ckbp->dwHotKey; + kbp->dpBitmapOffset = ckbp->dpBitmapOffset; + kbp->dwBitmapSize = ckbp->dwBitmapSize; + kbp->dpStoreArray = (LPKMX_STORE)bufp; bufp += sizeof(KMX_STORE) * kbp->cxStoreArray; From 23c66922ce1ec27252cbf2adba3f26b2c7fcd895 Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 16 Aug 2024 17:11:51 +0200 Subject: [PATCH 56/71] chore(mac): change bitmapoffset + bitmapsize to prevent buffer problems --- mac/mcompile/keymap.cpp | 5 +++-- mac/mcompile/mc_kmxfile.cpp | 3 +++ mac/mcompile/meson.build | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 0a9e520f63c..c4ae0d6c3ff 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -303,7 +303,6 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la * or else the keyval obtained from Keycode and shiftstate and caps; */ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, KMX_DWORD kc_underlying, KMX_DWORD vk_ShiftState, PKMX_WCHAR deadKey) { - PKMX_WCHAR dky = NULL; UInt32 isdk = 0; KMX_DWORD keyV; int caps = 0; @@ -315,7 +314,9 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa // if there was a deadkey return 0xFFFF and copy deadkey into dky; else return the keyvalue if (isdk != 0) { - dky = (PKMX_WCHAR)(std::u16string(1, keyV)).c_str(); + PKMX_WCHAR dky = NULL; + std::u16string keyVS(1, keyV); + dky = (PKMX_WCHAR) keyVS.c_str(); *deadKey = *dky; return 0xFFFF; } diff --git a/mac/mcompile/mc_kmxfile.cpp b/mac/mcompile/mc_kmxfile.cpp index d75f3076de5..78aa40615cc 100644 --- a/mac/mcompile/mc_kmxfile.cpp +++ b/mac/mcompile/mc_kmxfile.cpp @@ -285,6 +285,9 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) { kbp->dwFlags = ckbp->dwFlags; kbp->dwHotKey = ckbp->dwHotKey; + kbp->dpBitmapOffset = ckbp->dpBitmapOffset; + kbp->dwBitmapSize = ckbp->dwBitmapSize; + kbp->dpStoreArray = (LPKMX_STORE)bufp; bufp += sizeof(KMX_STORE) * kbp->cxStoreArray; diff --git a/mac/mcompile/meson.build b/mac/mcompile/meson.build index 5c46335674e..161112a3055 100644 --- a/mac/mcompile/meson.build +++ b/mac/mcompile/meson.build @@ -3,7 +3,9 @@ project('mcompile', 'c', 'cpp', meson_version: '>=1.0') # see https://github.com/keymanapp/keyman/pull/11334#issuecomment-2290784399 -add_project_arguments('-O0', language : 'cpp') +add_project_arguments('-O1', language : 'cpp') + +// _S2 was // add_project_arguments('-O0', language : 'cpp') carbon = dependency('Carbon') From 6a8c815c7cef698140817a1c9f7f85e58120298a Mon Sep 17 00:00:00 2001 From: Sabine Date: Thu, 12 Sep 2024 17:34:59 +0200 Subject: [PATCH 57/71] chore (mac): remove (w)main for windows/Linux; define arrays+variables in *.cpp and declare as extern in *.h --- mac/mcompile/keymap.cpp | 444 ++++++++++++++++++++++++++++++++++++- mac/mcompile/keymap.h | 446 ++------------------------------------ mac/mcompile/mcompile.cpp | 14 +- mac/mcompile/meson.build | 2 - 4 files changed, 458 insertions(+), 448 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index c4ae0d6c3ff..47b2c5338c7 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -13,6 +13,447 @@ #include "keymap.h" #include "kmx_file.h" +const KMX_DWORD max_shiftstate = 10; +const KMX_DWORD INVALID_NAME = 0; +const KMX_DWORD keycode_max = 50; +const int keycode_spacebar = 49; + +const int MAC_BASE = 0; +const int MAC_SHIFT = 2; +const int MAC_OPT = 8; +const int MAC_SHIFT_OPT = 10; + +const int ss_mac[] = {MAC_BASE, MAC_SHIFT, MAC_OPT, MAC_SHIFT_OPT}; +int sizeof_ss_mac = sizeof(ss_mac) / sizeof(ss_mac[0]); + +// KeyValues for the US English keyboard: A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P,CR, L, J, ', K, ;, \, ,, /, N, M, . +const std::vector us_Base = {97,115,100,102,104,103,122,120,99,118,167,98,113,119,101,114,121,116,49,50,51,52,54,53,61,57,55,45,56,48, 93,111,117, 91,105,112,13,108,106,39,107,59, 92,44,47,110,109,46}; +const std::vector us_Shift = {65, 83, 68, 70, 72, 71, 90, 88,67, 86,177,66, 81, 87, 69, 82, 89, 84,33,64,35,36,94,37,43,40,38,95,42,41,125, 79, 85,123, 73, 80,13, 76, 74,34, 75,58,124,60,63, 78, 77,62}; + +// Map of all US English virtual key codes that we can translate +const KMX_DWORD KMX_VKMap[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + + VK_SPACE, /* 32 */ + + VK_ACCENT, /* 192 VK_OEM_3 K_BKQUOTE */ + VK_HYPHEN, /* - 189 VK_OEM_MINUS */ + VK_EQUAL, /* = 187 VK_OEM_PLUS */ + + VK_LBRKT, /* [ 219 VK_OEM_4 */ + VK_RBRKT, /* ] 221 VK_OEM_6 */ + VK_BKSLASH, /* \ 220 VK_OEM_5 */ + + VK_COLON, /* ; 186 VK_OEM_1 */ + VK_QUOTE, /* ' 222 VK_OEM_7 */ + + VK_COMMA, /* , 188 VK_OEM_COMMA */ + VK_PERIOD, /* . 190 VK_OEM_PERIOD */ + VK_SLASH, /* / 191 VK_OEM_2 */ + + VK_xDF, /* ß (?) 223*/ + VK_OEM_102, /* < > | 226 */ + 0}; + +/** + * @brief array of USVirtualKey-ScanCode-pairs + * we use the same type of array as throughout Keyman even though we have lots of unused fields + */ +const KMX_DWORD mac_USVirtualKeyToScanCode[256] = { + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x31, // L"K_SPACE", // &H20 + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x1D, // L"K_0", // &H30 + 0x12, // L"K_1", // &H31 + 0x13, // L"K_2", // &H32 + 0x14, // L"K_3", // &H33 + 0x15, // L"K_4", // &H34 + 0x17, // L"K_5", // &H35 + 0x16, // L"K_6", // &H36 + 0x1A, // L"K_7", // &H37 + 0x1C, // L"K_8", // &H38 + 0x19, // L"K_9", // &H39 + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x00, // L"K_A", // &H41 + 0x0B, // L"K_B", // &H42 + 0x08, // L"K_C", // &H43 + 0x02, // L"K_D", // &H44 + 0x0E, // L"K_E", // &H45 + 0x03, // L"K_F", // &H46 + 0x05, // L"K_G", // &H47 + 0x04, // L"K_H", // &H48 + 0x22, // L"K_I", // &H49 + 0x26, // L"K_J", // &H4A + 0x28, // L"K_K", // &H4B + 0x25, // L"K_L", // &H4C + 0x2E, // L"K_M", // &H4D + 0x2D, // L"K_N", // &H4E + 0x1F, // L"K_O", // &H4F + 0x23, // L"K_P", // &H50 + 0x0C, // L"K_Q", // &H51 + 0x0F, // L"K_R", // &H52 + 0x01, // L"K_S", // &H53 + 0x11, // L"K_T", // &H54 + 0x20, // L"K_U", // &H55 + 0x09, // L"K_V", // &H56 + 0x0D, // L"K_W", // &H57 + 0x07, // L"K_X", // &H58 + 0x10, // L"K_Y", // &H59 + 0x06, // L"K_Z", // &H5A + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x29, // L"K_COLON", // &HBA (186) + 0x18, // L"K_EQUAL", // &HBB (187) + 0x2B, // L"K_COMMA", // &HBC (188) + 0x1B, // L"K_HYPHEN", // &HBD (189) + 0x2F, // L"K_PERIOD", // &HBE (190) + 0x2C, // L"K_SLASH", // &HBF (191) + 0x0A, // L"K_BKQUOTE", // &HC0 (192) + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0x21, // L"K_LBRKT", // &HDB (219) + 0x2A, // L"K_BKSLASH", // &HDC (220) + 0x1E, // L"K_RBRKT", // &HDD (221) + 0x27, // L"K_QUOTE", // &HDE (222) + 0x1B, // L"K_oDF", // &HDF (223) + 0xFFFF, // not used + 0xFFFF, // not used + 0x32, // L"K_oE2", // &HE2 (226) + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used + 0xFFFF, // not used +}; + +/** + * @brief array of ScanCode-USVirtualKey-pairs + * we use the same type of array as throughout Keyman even though we have lots of unused fields + */ +const KMX_DWORD mac_ScanCodeToUSVirtualKey[128] = { + 0x41, // L"K_A", // &H41 + 0x53, // L"K_S", // &H53 + 0x44, // L"K_D", // &H44 + 0x46, // L"K_F", // &H46 + 0x48, // L"K_H", // &H48 + 0x47, // L"K_G", // &H47 + 0x5A, // L"K_Z", // &H5A + 0x58, // L"K_X", // &H58 + 0x43, // L"K_C", // &H43 + 0x56, // L"K_V", // &H56 + 0xC0, // L"K_BKQUOTE", // &HC0 (192) + 0x42, // L"K_B", // &H42 + 0x51, // L"K_Q", // &H51 + 0x57, // L"K_W", // &H57 + 0x45, // L"K_E", // &H45 + 0x52, // L"K_R", // &H52 + 0x59, // L"K_Y", // &H59 + 0x54, // L"K_T", // &H54 + 0x31, // L"K_1", // &H31 + 0x32, // L"K_2", // &H32 + 0x33, // L"K_3", // &H33 + 0x34, // L"K_4", // &H34 + 0x36, // L"K_6", // &H36 + 0x35, // L"K_5", // &H35 + 0xBB, // L"K_EQUAL", // &HBB (187) + 0x39, // L"K_9", // &H39 + 0x37, // L"K_7", // &H37 + 0xBD, // L"K_H YPHEN", // &HBD (189) + 0x38, // L"K_8", // &H38 + 0x30, // L"K_0", // &H30 + 0xDD, // L"K_RBRKT", // &HDD (221) + 0x4F, // L"K_O", // &H4F + 0x55, // L"K_U", // &H55 + 0xDB, // L"K_LBRKT", // &HDB (219) + 0x49, // L"K_I", // &H49 + 0x50, // L"K_P", // &H50 + 0x00, // not used // ---- + 0x4C, // L"K_L", // &H4C + 0x4A, // L"K_J", // &H4A + 0xDE, // L"K_QUOTE", // &HDE (222) + 0x4B, // L"K_K", // &H4B + 0xBA, // L"K_COLON", // &HBA (186) + 0xDC, // L"K_BKSLASH", // &HDC (220) + 0xBC, // L"K_COMMA", // &HBC (188) + 0xBF, // L"K_SLASH", // &HBF (191) + 0x4E, // L"K_N", // &H4E + 0x4D, // L"K_M", // &H4D + 0xBE, // L"K_PERIOD", // &HBE (190) + 0x00, // not used // ---- + 0x20, // L"K_SPACE", // &H1 + 0xE2, // L"K_oE2", // &HE2 (226) + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used + 0x00, // not used +}; + /** * @brief map a shiftstate used on Windows to a shiftstate suitable for UCKeyTranslate() on the mac * Windows: (Base: 00000000 (0); Shift 00010000 (16); AltGr 00001001 (9); Shift+AltGr 00011001 (25)) @@ -103,9 +544,6 @@ int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeybo * 1 if data of US keyboard was not written; */ int mac_write_US_ToVector(vec_dword_3D& vec_us) { - // Values for US : A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P,CR, L, J, ', K, ;, \, ,, /, N, M, . - std::vector us_Base = {97,115,100,102,104,103,122,120,99,118,167,98,113,119,101,114,121,116,49,50,51,52,54,53,61,57,55,45,56,48, 93,111,117, 91,105,112,13,108,106,39,107,59, 92,44,47,110,109,46}; - std::vector us_Shift = {65, 83, 68, 70, 72, 71, 90, 88,67, 86,177,66, 81, 87, 69, 82, 89, 84,33,64,35,36,94,37,43,40,38,95,42,41,125, 79, 85,123, 73, 80,13, 76, 74,34, 75,58,124,60,63, 78, 77,62}; vec_dword_1D values; vec_dword_2D key; diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index d0cf0c10ab5..5dc5582f72a 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -54,48 +54,26 @@ enum ShiftState { #define VK_MENU 0x12 #define VK_PAUSE 0x13 #define VK_CAPITAL 0x14 -// Map of all US English virtual key codes that we can translate -const KMX_DWORD KMX_VKMap[] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - - VK_SPACE, /* 32 */ - - VK_ACCENT, /* 192 VK_OEM_3 K_BKQUOTE */ - VK_HYPHEN, /* - 189 VK_OEM_MINUS */ - VK_EQUAL, /* = 187 VK_OEM_PLUS */ - - VK_LBRKT, /* [ 219 VK_OEM_4 */ - VK_RBRKT, /* ] 221 VK_OEM_6 */ - VK_BKSLASH, /* \ 220 VK_OEM_5 */ - - VK_COLON, /* ; 186 VK_OEM_1 */ - VK_QUOTE, /* ' 222 VK_OEM_7 */ - - VK_COMMA, /* , 188 VK_OEM_COMMA */ - VK_PERIOD, /* . 190 VK_OEM_PERIOD */ - VK_SLASH, /* / 191 VK_OEM_2 */ - - VK_xDF, /* ß (?) 223*/ - VK_OEM_102, /* < > | 226 */ - 0}; typedef std::vector vec_string_1D; typedef std::vector vec_dword_1D; typedef std::vector > vec_dword_2D; typedef std::vector > > vec_dword_3D; -static KMX_DWORD INVALID_NAME = 0; -static KMX_DWORD keycode_max = 50; -static int keycode_spacebar = 49; -static KMX_DWORD max_shiftstate = 10; +extern const KMX_DWORD max_shiftstate; +extern const KMX_DWORD INVALID_NAME; +extern const KMX_DWORD keycode_max; +extern const int keycode_spacebar; // shiftstates we can use for mac -static int MAC_BASE = 0; -static int MAC_SHIFT = 2; -static int MAC_OPT = 8; -static int MAC_SHIFT_OPT = 10; -static int ss_mac[] = {MAC_BASE, MAC_SHIFT, MAC_OPT, MAC_SHIFT_OPT}; +extern const int MAC_BASE; +extern const int MAC_SHIFT; +extern const int MAC_OPT; +extern const int MAC_SHIFT_OPT; + +extern const KMX_DWORD KMX_VKMap[]; +extern const int ss_mac[]; +extern int sizeof_ss_mac; /** @brief map a shiftstate used on Windows to a shiftstate suitable for UCKeyTranslate() on the mac */ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState); @@ -121,403 +99,11 @@ int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLay /** @brief create a pointer to pointer of the current keymap for later use */ bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout); -/** - * @brief array of USVirtualKey-ScanCode-pairs - * we use the same type of array as throughout Keyman even though we have lots of unused fields - */ -const KMX_DWORD mac_USVirtualKeyToScanCode[256] = { - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0x31, // L"K_SPACE", // &H20 - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0x1D, // L"K_0", // &H30 - 0x12, // L"K_1", // &H31 - 0x13, // L"K_2", // &H32 - 0x14, // L"K_3", // &H33 - 0x15, // L"K_4", // &H34 - 0x17, // L"K_5", // &H35 - 0x16, // L"K_6", // &H36 - 0x1A, // L"K_7", // &H37 - 0x1C, // L"K_8", // &H38 - 0x19, // L"K_9", // &H39 - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0x00, // L"K_A", // &H41 - 0x0B, // L"K_B", // &H42 - 0x08, // L"K_C", // &H43 - 0x02, // L"K_D", // &H44 - 0x0E, // L"K_E", // &H45 - 0x03, // L"K_F", // &H46 - 0x05, // L"K_G", // &H47 - 0x04, // L"K_H", // &H48 - 0x22, // L"K_I", // &H49 - 0x26, // L"K_J", // &H4A - 0x28, // L"K_K", // &H4B - 0x25, // L"K_L", // &H4C - 0x2E, // L"K_M", // &H4D - 0x2D, // L"K_N", // &H4E - 0x1F, // L"K_O", // &H4F - 0x23, // L"K_P", // &H50 - 0x0C, // L"K_Q", // &H51 - 0x0F, // L"K_R", // &H52 - 0x01, // L"K_S", // &H53 - 0x11, // L"K_T", // &H54 - 0x20, // L"K_U", // &H55 - 0x09, // L"K_V", // &H56 - 0x0D, // L"K_W", // &H57 - 0x07, // L"K_X", // &H58 - 0x10, // L"K_Y", // &H59 - 0x06, // L"K_Z", // &H5A - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0x29, // L"K_COLON", // &HBA (186) - 0x18, // L"K_EQUAL", // &HBB (187) - 0x2B, // L"K_COMMA", // &HBC (188) - 0x1B, // L"K_HYPHEN", // &HBD (189) - 0x2F, // L"K_PERIOD", // &HBE (190) - 0x2C, // L"K_SLASH", // &HBF (191) - 0x0A, // L"K_BKQUOTE", // &HC0 (192) - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0x21, // L"K_LBRKT", // &HDB (219) - 0x2A, // L"K_BKSLASH", // &HDC (220) - 0x1E, // L"K_RBRKT", // &HDD (221) - 0x27, // L"K_QUOTE", // &HDE (222) - 0x1B, // L"K_oDF", // &HDF (223) - 0xFFFF, // not used - 0xFFFF, // not used - 0x32, // L"K_oE2", // &HE2 (226) - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used - 0xFFFF, // not used -}; +/** @brief array of USVirtualKey-ScanCode-pairs */ +extern const KMX_DWORD mac_USVirtualKeyToScanCode[256]; -/** - * @brief array of ScanCode-USVirtualKey-pairs - * we use the same type of array as throughout Keyman even though we have lots of unused fields - */ -const KMX_DWORD mac_ScanCodeToUSVirtualKey[128] = { - 0x41, // L"K_A", // &H41 - 0x53, // L"K_S", // &H53 - 0x44, // L"K_D", // &H44 - 0x46, // L"K_F", // &H46 - 0x48, // L"K_H", // &H48 - 0x47, // L"K_G", // &H47 - 0x5A, // L"K_Z", // &H5A - 0x58, // L"K_X", // &H58 - 0x43, // L"K_C", // &H43 - 0x56, // L"K_V", // &H56 - 0xC0, // L"K_BKQUOTE", // &HC0 (192) - 0x42, // L"K_B", // &H42 - 0x51, // L"K_Q", // &H51 - 0x57, // L"K_W", // &H57 - 0x45, // L"K_E", // &H45 - 0x52, // L"K_R", // &H52 - 0x59, // L"K_Y", // &H59 - 0x54, // L"K_T", // &H54 - 0x31, // L"K_1", // &H31 - 0x32, // L"K_2", // &H32 - 0x33, // L"K_3", // &H33 - 0x34, // L"K_4", // &H34 - 0x36, // L"K_6", // &H36 - 0x35, // L"K_5", // &H35 - 0xBB, // L"K_EQUAL", // &HBB (187) - 0x39, // L"K_9", // &H39 - 0x37, // L"K_7", // &H37 - 0xBD, // L"K_H YPHEN", // &HBD (189) - 0x38, // L"K_8", // &H38 - 0x30, // L"K_0", // &H30 - 0xDD, // L"K_RBRKT", // &HDD (221) - 0x4F, // L"K_O", // &H4F - 0x55, // L"K_U", // &H55 - 0xDB, // L"K_LBRKT", // &HDB (219) - 0x49, // L"K_I", // &H49 - 0x50, // L"K_P", // &H50 - 0x00, // not used // ---- - 0x4C, // L"K_L", // &H4C - 0x4A, // L"K_J", // &H4A - 0xDE, // L"K_QUOTE", // &HDE (222) - 0x4B, // L"K_K", // &H4B - 0xBA, // L"K_COLON", // &HBA (186) - 0xDC, // L"K_BKSLASH", // &HDC (220) - 0xBC, // L"K_COMMA", // &HBC (188) - 0xBF, // L"K_SLASH", // &HBF (191) - 0x4E, // L"K_N", // &H4E - 0x4D, // L"K_M", // &H4D - 0xBE, // L"K_PERIOD", // &HBE (190) - 0x00, // not used // ---- - 0x20, // L"K_SPACE", // &H1 - 0xE2, // L"K_oE2", // &HE2 (226) - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used - 0x00, // not used -}; +/** @brief array of ScanCode-USVirtualKey-pairs */ +extern const KMX_DWORD mac_ScanCodeToUSVirtualKey[128]; /** @brief return the keyvalue for a given Keycode, shiftstate and caps */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps); diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 10cfe7eb8a2..d916739f8df 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -37,21 +37,9 @@ std::vector KMX_FDeadkeys; // I4353 * @param argv commandline arguments * @return 0 on success */ -#if defined(_WIN32) || defined(_WIN64) - int wmain(int argc, wchar_t* argv[]) { - /** - * TODO for cross-platform use: if we want to use wmain instead of main: - * inside wmain convert wchar_t* argv[] to char* argv_ch[] - * to be able to use mac_run(int argc, char* argv_ch[]) - */ - -#elif ((__linux__) || (__unix__)) // LINUX, UNIX - int main(int argc, char* argv[]) { -#elif (__APPLE__ && TARGET_OS_MAC) #include int main(int argc, char* argv[]) { -#endif mac_run(argc, argv); } @@ -578,7 +566,7 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a KMX_WORD* p = outputPairs; KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(all_vector, deadkey); - for (int j = 0; j < sizeof(ss_mac) / sizeof(ss_mac[0]); j++) { + for (int j = 0; j < sizeof_ss_mac; j++) { /* we start with SPACE (keycode_spacebar=49) because all deadkeys occur in combinations with space. diff --git a/mac/mcompile/meson.build b/mac/mcompile/meson.build index 161112a3055..76509e27601 100644 --- a/mac/mcompile/meson.build +++ b/mac/mcompile/meson.build @@ -5,8 +5,6 @@ project('mcompile', 'c', 'cpp', # see https://github.com/keymanapp/keyman/pull/11334#issuecomment-2290784399 add_project_arguments('-O1', language : 'cpp') -// _S2 was // add_project_arguments('-O0', language : 'cpp') - carbon = dependency('Carbon') deps = [carbon] From f385652435a20f2e1c29ec63f88dd32e487ede35 Mon Sep 17 00:00:00 2001 From: Sabine Date: Thu, 12 Sep 2024 18:16:11 +0200 Subject: [PATCH 58/71] chore (mac): mac_run and minor things (edits, comments,...) --- mac/mcompile/mcompile.cpp | 46 ++++++--------------------------------- mac/mcompile/mcompile.h | 21 ++++-------------- 2 files changed, 11 insertions(+), 56 deletions(-) diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index d916739f8df..e893c838ddc 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -1,5 +1,5 @@ /* - * Keyman is copyright (C) 2004 - 2024 SIL International. MIT License. + * Keyman is copyright (C) SIL International. MIT License. * * Mnemonic layout support for mac * @@ -12,6 +12,7 @@ #include #include #include +#include #include "mcompile.h" #include "../../common/include/km_u16.h" @@ -21,9 +22,6 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int /** @brief Collect the key data, translate it to kmx and append to the existing keyboard */ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D &all_vector, const UCKeyboardLayout** keyboard_layout, std::vector* KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 -/** @brief start of mcompile; load, convert and save keyboard */ -int mac_run(int argc, char* argv[]); - /** @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard */ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, KMX_DWORD shift_dk, KMX_WORD* outputPairs); // returns array of [usvk, ch_out] pairs @@ -37,22 +35,7 @@ std::vector KMX_FDeadkeys; // I4353 * @param argv commandline arguments * @return 0 on success */ - - #include - int main(int argc, char* argv[]) { - - mac_run(argc, argv); -} - -/** - * @brief start of mcompile; load, convert and save keyboard - * @param argc number of commandline arguments - * @param argv pointer to commandline arguments: executable, inputfile, outputfile - * @return 0 on success; - * 1 for wrong usage of calling parameters; - * 3 if unable to load keyboard - */ -int mac_run(int argc, char* argv[]) { +int main(int argc, char* argv[]) { int bDeadkeyConversion = 0; if (argc > 1) @@ -63,12 +46,11 @@ int mac_run(int argc, char* argv[]) { if (argc < 3 || argc > 4 || (argc - n) != 2) { // I4273// I4273 printf( "Usage: \tmcompile [-d] infile.kmx outfile.kmx\n" - " \tmcompile -u ... (not available for mac)\n " " \tmcompile converts a Keyman mnemonic layout to\n" " \ta positional one based on the currently used \n" " \tmac keyboard layout\n" " \t(-d convert deadkeys to plain keys) \n \n"); // I4552 - } + } // -u option is not available for Linux and macOS @@ -84,7 +66,6 @@ int mac_run(int argc, char* argv[]) { // state. This fixup will transform the char to a vk, which will avoid any issues // with the key. // - // --> deadkeys we will attack after the POC // // For each deadkey, we need to determine its possible outputs. Then we generate a VK // rule for that deadkey, e.g. [K_LBRKT] > dk(c101) @@ -109,23 +90,10 @@ int mac_run(int argc, char* argv[]) { return 3; } - #if defined(_WIN32) || defined(_WIN64) // Windows - if (DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F - KMX_SaveKeyboard(kmxfile, outfile); - } - - #elif ((__linux__) || (__unix__)) // LINUX, UNIX - if (mac_KMX_DoConvert(kmxfile, bDeadkeyConversion, argc)) { // I4552F - KMX_SaveKeyboard(kmxfile, outfile); - } - - #elif (__APPLE__ && TARGET_OS_MAC) // macOS - if (mac_KMX_DoConvert(kmxfile, bDeadkeyConversion, argc)) { // I4552F - KMX_SaveKeyboard(kmxfile, outfile); + if (mac_KMX_DoConvert(kmxfile, bDeadkeyConversion, argc)) { // I4552F + KMX_SaveKeyboard(kmxfile, outfile); } - #endif - // DeleteReallocatedPointers(kmxfile); :TODO // _S2 not my TODO :-) delete kmxfile; return 0; } @@ -247,7 +215,7 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. - if ((shift & (LCTRLFLAG | RALTFLAG)) == (LCTRLFLAG | RALTFLAG)) // I4327 + if ((shift & (LCTRLFLAG | RALTFLAG)) == (LCTRLFLAG | RALTFLAG)) // I4327 shift &= ~LCTRLFLAG; if (key->ShiftFlags == 0) { diff --git a/mac/mcompile/mcompile.h b/mac/mcompile/mcompile.h index 3fa7f6d6ce7..0e3744925c1 100644 --- a/mac/mcompile/mcompile.h +++ b/mac/mcompile/mcompile.h @@ -1,21 +1,8 @@ /* - Name: mcompile - Copyright: Copyright (C) 2003-2017 SIL International. - Documentation: - Description: - Create Date: 3 Aug 2014 - - Modified Date: 3 Aug 2014 - Authors: mcdurdin - Related Files: - Dependencies: - - Bugs: - Todo: - Notes: - History: 03 Aug 2014 - mcdurdin - I4353 - V9.0 - mnemonic layout recompiler mixes up deadkey rules - -*/ + * Keyman is copyright (C) SIL International. MIT License. + * + * Mnemonic layout support for mac + */ #ifndef MCOMPILE_H #define MCOMPILE_H From c045b9442996e5b09bc1c1ec6d3a21a3df0f4bbe Mon Sep 17 00:00:00 2001 From: Sabine Date: Fri, 13 Sep 2024 09:50:42 +0200 Subject: [PATCH 59/71] chore (mac): remove argc, use VK_SPACE, use _countof() --- mac/mcompile/keymap.cpp | 3 --- mac/mcompile/keymap.h | 3 +-- mac/mcompile/mcompile.cpp | 11 +++++------ 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 47b2c5338c7..30dbebd20e4 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -23,9 +23,6 @@ const int MAC_SHIFT = 2; const int MAC_OPT = 8; const int MAC_SHIFT_OPT = 10; -const int ss_mac[] = {MAC_BASE, MAC_SHIFT, MAC_OPT, MAC_SHIFT_OPT}; -int sizeof_ss_mac = sizeof(ss_mac) / sizeof(ss_mac[0]); - // KeyValues for the US English keyboard: A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P,CR, L, J, ', K, ;, \, ,, /, N, M, . const std::vector us_Base = {97,115,100,102,104,103,122,120,99,118,167,98,113,119,101,114,121,116,49,50,51,52,54,53,61,57,55,45,56,48, 93,111,117, 91,105,112,13,108,106,39,107,59, 92,44,47,110,109,46}; const std::vector us_Shift = {65, 83, 68, 70, 72, 71, 90, 88,67, 86,177,66, 81, 87, 69, 82, 89, 84,33,64,35,36,94,37,43,40,38,95,42,41,125, 79, 85,123, 73, 80,13, 76, 74,34, 75,58,124,60,63, 78, 77,62}; diff --git a/mac/mcompile/keymap.h b/mac/mcompile/keymap.h index 5dc5582f72a..99e563b4c01 100644 --- a/mac/mcompile/keymap.h +++ b/mac/mcompile/keymap.h @@ -72,8 +72,7 @@ extern const int MAC_OPT; extern const int MAC_SHIFT_OPT; extern const KMX_DWORD KMX_VKMap[]; -extern const int ss_mac[]; -extern int sizeof_ss_mac; +const int ss_mac[] = {MAC_BASE, MAC_SHIFT, MAC_OPT, MAC_SHIFT_OPT}; /** @brief map a shiftstate used on Windows to a shiftstate suitable for UCKeyTranslate() on the mac */ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState); diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index e893c838ddc..eb2fdde4019 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -17,7 +17,7 @@ #include "../../common/include/km_u16.h" /** @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard */ -KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc); +KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion); /** @brief Collect the key data, translate it to kmx and append to the existing keyboard */ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D &all_vector, const UCKeyboardLayout** keyboard_layout, std::vector* KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 @@ -90,7 +90,7 @@ int main(int argc, char* argv[]) { return 3; } - if (mac_KMX_DoConvert(kmxfile, bDeadkeyConversion, argc)) { // I4552F + if (mac_KMX_DoConvert(kmxfile, bDeadkeyConversion)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); } @@ -448,11 +448,10 @@ KMX_BOOL mac_KMX_SetKeyboardToPositional(LPKMX_KEYBOARD kbd) { * @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard * @param kbd pointer to US keyboard * @param bDeadkeyConversion option for converting a deadkey to a character: 1 = dk conversion; 0 = no dk conversion - * @param argc number of command line arguments * @return TRUE if conversion was successful; * FALSE if not */ -KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc) { +KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion) { KMX_WCHAR DeadKey = 0; if (!mac_KMX_SetKeyboardToPositional(kbd)) return FALSE; @@ -534,7 +533,7 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a KMX_WORD* p = outputPairs; KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(all_vector, deadkey); - for (int j = 0; j < sizeof_ss_mac; j++) { + for (int j = 0; j < _countof(ss_mac); j++) { /* we start with SPACE (keycode_spacebar=49) because all deadkeys occur in combinations with space. @@ -558,7 +557,7 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a KMX_WORD vk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[1], 0); // ensure to NOT get key combinations like '^a' but only combined characters like 'â' (exception for '^' + space) - if ((unicodeString[0] != deadkey) || (vk == 32)) { + if ((unicodeString[0] != deadkey) || (vk == VK_SPACE)) { *p++ = vk; *p++ = ss_mac[j]; *p++ = unicodeString[0]; From e449437146a43e540d2985d4e3a491e4ce38e412 Mon Sep 17 00:00:00 2001 From: Sabine Date: Tue, 17 Sep 2024 14:14:27 +0200 Subject: [PATCH 60/71] chore (mac): catch possible overflow of dk array; check for noErr in status = UCKeyTranslate(...) --- mac/mcompile/keymap.cpp | 23 +++++++++++++++++------ mac/mcompile/mcompile.cpp | 34 +++++++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 30dbebd20e4..a3c36089882 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -541,7 +541,6 @@ int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeybo * 1 if data of US keyboard was not written; */ int mac_write_US_ToVector(vec_dword_3D& vec_us) { - vec_dword_1D values; vec_dword_2D key; @@ -675,10 +674,13 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou If CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 */ status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - // If this was a deadkey (deadkeystate != 0), append a space - if (deadkeystate != 0) - status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); + // If this was a deadkey (deadkeystate != 0), append a space + if (deadkeystate != 0) { + status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); + if (status != noErr) // in case UCKeyTranslate returned an error + return 0; + } // if there is no character assigned to the Key+Shift+CAPS UCKeyTranslate writes 0x01 into unicodeString[0] if (unicodeString[0] == 1) // impossible character return 0; @@ -714,10 +716,15 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la If CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 */ status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); + if (status != noErr) // in case UCKeyTranslate returned an error + return 0; // If this was a deadkey, append a space - if (deadkeystate != 0) + if (deadkeystate != 0) { status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown,(shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); + if (status != noErr) // in case UCKeyTranslate returned an error + return 0; + } // if there is no character assigned to the Key+Shift+CAPS UCKeyTranslate writes 0x01 into unicodeString[0] if (unicodeString[0] == 1) // impossible character @@ -751,7 +758,7 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa if (isdk != 0) { PKMX_WCHAR dky = NULL; std::u16string keyVS(1, keyV); - dky = (PKMX_WCHAR) keyVS.c_str(); + dky = (PKMX_WCHAR)keyVS.c_str(); *deadKey = *dky; return 0xFFFF; } @@ -873,10 +880,14 @@ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { If CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 */ status = UCKeyTranslate(keyboard_layout, vk_dk, kUCKeyActionDown, ss_dk, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); + if (status != noErr) // in case UCKeyTranslate returned an error + return 0; // If this was a deadkey, append a character if (deadkeystate != 0) { status = UCKeyTranslate(keyboard_layout, vk_us, kUCKeyActionDown, shiftstate_mac + 4 * caps, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); + if (status != noErr) // in case UCKeyTranslate returned an error + return 0; if (unicodeString[0] == 1) // impossible character return 0; diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index eb2fdde4019..bdcda964de9 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -16,6 +16,9 @@ #include "mcompile.h" #include "../../common/include/km_u16.h" +const int nr_DK_pairs = 1000; +static const int size_DK_array = (nr_DK_pairs + 1) * 3; + /** @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard */ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion); @@ -395,7 +398,7 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { * @param dk_Table a vector of all possible deadkey combinations for all Linux keyboards */ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, KMX_DWORD shift, KMX_WCHAR deadkey, vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { - KMX_WORD deadkeys[512] = {0}; + KMX_WORD deadkeys[size_DK_array] = {0}; KMX_WORD* pdk; // Lookup the deadkey table for the deadkey in the physical keyboard @@ -496,7 +499,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion) { } } - switch(ch) { + switch (ch) { case 0x0000: break; case 0xFFFF: mac_KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, all_vector, keyboard_layout); break; default: mac_KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); @@ -531,10 +534,11 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a unicodeString[0] = 0; KMX_WORD* p = outputPairs; + int no_dk_counter = 0; + int p_counter = 0; KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(all_vector, deadkey); for (int j = 0; j < _countof(ss_mac); j++) { - /* we start with SPACE (keycode_spacebar=49) because all deadkeys occur in combinations with space. Since mcompile finds only the first occurance of a dk combination, this makes sure that we always @@ -544,13 +548,16 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a */ for (int i = keycode_spacebar; i >= 0; i--) { status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_convert_Shiftstate_to_MacShiftstate(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - + if (status != noErr) // in case UCKeyTranslate returned an error + return 0; /* UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^'. If CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 */ if (deadkeystate != 0) { status = UCKeyTranslate(keyboard_layout, i, kUCKeyActionDown, ss_mac[j], LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); + if (status != noErr) // in case UCKeyTranslate returned an error + return 0; // deadkeystate might be changed again therefore a new if-clause if (deadkeystate != 0) { @@ -558,14 +565,27 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a // ensure to NOT get key combinations like '^a' but only combined characters like 'â' (exception for '^' + space) if ((unicodeString[0] != deadkey) || (vk == VK_SPACE)) { - *p++ = vk; - *p++ = ss_mac[j]; - *p++ = unicodeString[0]; + + // prevent overflow of deadkey-array + if (p_counter < size_DK_array - 3) { + + *p++ = vk; + *p++ = ss_mac[j]; + *p++ = unicodeString[0]; + + p_counter = p_counter + 3; + + } else { + no_dk_counter++; + } } } } } } + if (p_counter >= size_DK_array - 3) + wprintf(L" WARNING: %i deadkeys have not been processed.\n", no_dk_counter); + *p = 0; return (p - outputPairs); } From 335bfb711507a7fee870ea04407995d1060ba772 Mon Sep 17 00:00:00 2001 From: Sabine Date: Tue, 17 Sep 2024 18:36:27 +0200 Subject: [PATCH 61/71] chore (mac): replace UniCharCount with const UniCharCount in datatype for maxStringlength --- mac/mcompile/keymap.cpp | 6 +++--- mac/mcompile/mcompile.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index a3c36089882..50a3c62b40b 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -659,7 +659,7 @@ bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout) { */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps) { UInt32 deadkeystate; - UniCharCount maxStringlength = 5; + const UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; OptionBits keyTranslateOptions = 0; UniChar unicodeString[maxStringlength]; @@ -701,7 +701,7 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou * @return the keyval obtained from keycode, shiftstate and caps */ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32& deadkeystate) { - UniCharCount maxStringlength = 5; + const UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; OptionBits keyTranslateOptions = 0; UniChar unicodeString[maxStringlength]; @@ -868,7 +868,7 @@ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { */ KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, int vk_dk, KMX_DWORD ss_dk, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps) { UInt32 deadkeystate; - UniCharCount maxStringlength = 5; + const UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; OptionBits keyTranslateOptions = 0; UniChar unicodeString[maxStringlength]; diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index bdcda964de9..0ee8f1a5d6f 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -214,7 +214,7 @@ void mac_KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { * @param ch character of the underlying keyboard */ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, KMX_DWORD shift, KMX_WORD ch) { - if ((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) { + if ((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. // We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt" // to provide an alternate.. @@ -526,7 +526,7 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion) { */ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, KMX_DWORD shift_dk, KMX_WORD* outputPairs) { UInt32 deadkeystate; - UniCharCount maxStringlength = 5; + const UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; OptionBits keyTranslateOptions = 0; UniChar unicodeString[maxStringlength]; From 84b4391d6a765c45b6b9afd78dea2bf45dae7888 Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 18 Sep 2024 10:54:26 +0200 Subject: [PATCH 62/71] chore (mac): marked another possible C++ -O1, -O2, -O3 standard-compilant problem using UCKeyTranslate --- mac/mcompile/keymap.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 50a3c62b40b..54ccb81e3e9 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -675,6 +675,21 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou */ status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); + /* + // here is another possible C++ -O1, -O2, -O3 standard-compilant problem: + // The problem occurs when I run with C++ -O1 + // The problem does not occur when I run it with C++ -O0 + + // As soon as I check status != noErr, deadkeys[] will be filled with wrong data. This happens even when I only print out a message + + if (status != noErr) // gives wrong output + return 0; + + if (status != noErr) // gives wrong output + wprintf(L"Test status\n"); + */ + + // If this was a deadkey (deadkeystate != 0), append a space if (deadkeystate != 0) { status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); From 5ea67fc4a436677f22b475c1e45110e9b77c9276 Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 18 Sep 2024 10:54:26 +0200 Subject: [PATCH 63/71] chore (mac): marked another possible C++ -O1, -O2, -O3 standard-compliant problem using UCKeyTranslate --- mac/mcompile/keymap.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 50a3c62b40b..54ccb81e3e9 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -675,6 +675,21 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou */ status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); + /* + // here is another possible C++ -O1, -O2, -O3 standard-compilant problem: + // The problem occurs when I run with C++ -O1 + // The problem does not occur when I run it with C++ -O0 + + // As soon as I check status != noErr, deadkeys[] will be filled with wrong data. This happens even when I only print out a message + + if (status != noErr) // gives wrong output + return 0; + + if (status != noErr) // gives wrong output + wprintf(L"Test status\n"); + */ + + // If this was a deadkey (deadkeystate != 0), append a space if (deadkeystate != 0) { status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); From de7b654428d80ee8c12aa0149e1c9efdd750b840 Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 2 Oct 2024 17:17:03 +0200 Subject: [PATCH 64/71] feat (mac): set OPtimize Option to -O2; resolve problem in UCKeyTranslate: check noErr only after 2nd use of UCKeyTranslate --- mac/mcompile/keymap.cpp | 43 +++++++++++---------------------------- mac/mcompile/mcompile.cpp | 8 +++----- mac/mcompile/meson.build | 2 +- 3 files changed, 16 insertions(+), 37 deletions(-) diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 54ccb81e3e9..bb939e0cd0c 100644 --- a/mac/mcompile/keymap.cpp +++ b/mac/mcompile/keymap.cpp @@ -675,28 +675,14 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou */ status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - /* - // here is another possible C++ -O1, -O2, -O3 standard-compilant problem: - // The problem occurs when I run with C++ -O1 - // The problem does not occur when I run it with C++ -O0 - - // As soon as I check status != noErr, deadkeys[] will be filled with wrong data. This happens even when I only print out a message + // If this was a deadkey (deadkeystate != 0), append a space + if (deadkeystate != 0) + status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - if (status != noErr) // gives wrong output + if (status != noErr) // in case UCKeyTranslate returned an error return 0; - if (status != noErr) // gives wrong output - wprintf(L"Test status\n"); - */ - - - // If this was a deadkey (deadkeystate != 0), append a space - if (deadkeystate != 0) { - status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - if (status != noErr) // in case UCKeyTranslate returned an error - return 0; - } - // if there is no character assigned to the Key+Shift+CAPS UCKeyTranslate writes 0x01 into unicodeString[0] + // if there is no character assigned to the Key+Shift+CAPS UCKeyTranslate writes 0x01 into unicodeString[0] if (unicodeString[0] == 1) // impossible character return 0; else { @@ -731,15 +717,13 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la If CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 */ status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - if (status != noErr) // in case UCKeyTranslate returned an error - return 0; // If this was a deadkey, append a space - if (deadkeystate != 0) { + if (deadkeystate != 0) status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown,(shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - if (status != noErr) // in case UCKeyTranslate returned an error - return 0; - } + + if (status != noErr) // in case UCKeyTranslate returned an error + return 0; // if there is no character assigned to the Key+Shift+CAPS UCKeyTranslate writes 0x01 into unicodeString[0] if (unicodeString[0] == 1) // impossible character @@ -895,19 +879,16 @@ KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) { If CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 */ status = UCKeyTranslate(keyboard_layout, vk_dk, kUCKeyActionDown, ss_dk, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - if (status != noErr) // in case UCKeyTranslate returned an error - return 0; // If this was a deadkey, append a character - if (deadkeystate != 0) { + if (deadkeystate != 0) status = UCKeyTranslate(keyboard_layout, vk_us, kUCKeyActionDown, shiftstate_mac + 4 * caps, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - if (status != noErr) // in case UCKeyTranslate returned an error + + if (status != noErr) // in case UCKeyTranslate returned an error return 0; if (unicodeString[0] == 1) // impossible character return 0; else return unicodeString[0]; // combined char e.g. 'â' - } else - return 0; } diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 0ee8f1a5d6f..611dc7ca5b1 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -548,12 +548,10 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a */ for (int i = keycode_spacebar; i >= 0; i--) { status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_convert_Shiftstate_to_MacShiftstate(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - if (status != noErr) // in case UCKeyTranslate returned an error + if ( (deadkeystate == 0) && (status != noErr )) // in case UCKeyTranslate returned an error return 0; - /* - UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^'. - If CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6 - */ + + // UCKeyTranslate: deadkeystate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the character e.g.'^'. if (deadkeystate != 0) { status = UCKeyTranslate(keyboard_layout, i, kUCKeyActionDown, ss_mac[j], LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); if (status != noErr) // in case UCKeyTranslate returned an error diff --git a/mac/mcompile/meson.build b/mac/mcompile/meson.build index 76509e27601..6a359f9f5c8 100644 --- a/mac/mcompile/meson.build +++ b/mac/mcompile/meson.build @@ -3,7 +3,7 @@ project('mcompile', 'c', 'cpp', meson_version: '>=1.0') # see https://github.com/keymanapp/keyman/pull/11334#issuecomment-2290784399 -add_project_arguments('-O1', language : 'cpp') +add_project_arguments('-O2', language : 'cpp') carbon = dependency('Carbon') From 8fa72080d1d63b398ca18311239086032d10be35 Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 2 Oct 2024 17:54:45 +0200 Subject: [PATCH 65/71] chore (common): move do_clean, do_configure, do_build and do_test to meson-utils.inc.sh --- mac/mcompile/build.sh | 32 +------------------ resources/build/meson-utils.inc.sh | 51 ++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 31 deletions(-) create mode 100644 resources/build/meson-utils.inc.sh diff --git a/mac/mcompile/build.sh b/mac/mcompile/build.sh index b04c20e04a4..2f163144638 100755 --- a/mac/mcompile/build.sh +++ b/mac/mcompile/build.sh @@ -4,6 +4,7 @@ # adjust relative paths as necessary THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "${THIS_SCRIPT%/*}/../../resources/build/builder.inc.sh" +. "${THIS_SCRIPT%/*}/../../resources/build/meson-utils.inc.sh" ## END STANDARD BUILD SCRIPT INCLUDE ################################ Main script ################################ @@ -24,37 +25,6 @@ builder_describe_outputs \ TARGET_PATH="$THIS_SCRIPT_PATH/build" -do_clean() { - rm -rf "$THIS_SCRIPT_PATH/resources" - rm -rf "$TARGET_PATH" -} - -do_configure() { - # Import our standard compiler defines; this is copied from - # /resources/build/meson/standard.meson.build by build.sh, because meson doesn't - # allow us to reference a file outside its root - mkdir -p "$THIS_SCRIPT_PATH/resources" - cp "$KEYMAN_ROOT/resources/build/meson/standard.meson.build" "$THIS_SCRIPT_PATH/resources/meson.build" - - pushd "$THIS_SCRIPT_PATH" > /dev/null - # Additional arguments are used by Linux build, e.g. -Dprefix=${INSTALLDIR} - meson setup build --buildtype $BUILDER_CONFIGURATION "${builder_extra_params[@]}" - popd > /dev/null - -} - -do_build() { - pushd "$TARGET_PATH" > /dev/null - ninja - popd > /dev/null -} - -do_test() { - pushd "$TARGET_PATH" > /dev/null - meson test "${builder_extra_params[@]}" - popd > /dev/null -} - builder_run_action clean do_clean builder_run_action configure do_configure builder_run_action build do_build diff --git a/resources/build/meson-utils.inc.sh b/resources/build/meson-utils.inc.sh new file mode 100644 index 00000000000..e3e5e8d994d --- /dev/null +++ b/resources/build/meson-utils.inc.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# This script contains common meson functions + + +# ---------------------------------------------------------------------------- +# clean +# ---------------------------------------------------------------------------- + +do_clean() { + rm -rf "$THIS_SCRIPT_PATH/resources" + rm -rf "$TARGET_PATH" +} + +# ---------------------------------------------------------------------------- +# configure +# ---------------------------------------------------------------------------- + +do_configure() { + # Import our standard compiler defines; this is copied from + # /resources/build/meson/standard.meson.build by build.sh, because meson doesn't + # allow us to reference a file outside its root + mkdir -p "$THIS_SCRIPT_PATH/resources" + cp "$KEYMAN_ROOT/resources/build/meson/standard.meson.build" "$THIS_SCRIPT_PATH/resources/meson.build" + + pushd "$THIS_SCRIPT_PATH" > /dev/null + # Additional arguments are used by Linux build, e.g. -Dprefix=${INSTALLDIR} + meson setup build --buildtype $BUILDER_CONFIGURATION "${builder_extra_params[@]}" + popd > /dev/null + +} + +# ---------------------------------------------------------------------------- +# build +# ---------------------------------------------------------------------------- + +do_build() { + pushd "$TARGET_PATH" > /dev/null + ninja + popd > /dev/null +} + +# ---------------------------------------------------------------------------- +# test +# ---------------------------------------------------------------------------- + +do_test() { + pushd "$TARGET_PATH" > /dev/null + meson test "${builder_extra_params[@]}" + popd > /dev/null +} \ No newline at end of file From afc82297eab9d26307875da9a525fe14834245ab Mon Sep 17 00:00:00 2001 From: Sabine Date: Wed, 2 Oct 2024 17:54:45 +0200 Subject: [PATCH 66/71] chore (common): on mcompile-linux->move do_clean, do_configure, do_build and do_test to meson-utils.inc.sh --- linux/mcompile/keymap/build.sh | 32 +------------------ mac/mcompile/build.sh | 32 +------------------ resources/build/meson-utils.inc.sh | 51 ++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 62 deletions(-) create mode 100644 resources/build/meson-utils.inc.sh diff --git a/linux/mcompile/keymap/build.sh b/linux/mcompile/keymap/build.sh index 7c66e4b0b49..838ec86c38c 100755 --- a/linux/mcompile/keymap/build.sh +++ b/linux/mcompile/keymap/build.sh @@ -4,6 +4,7 @@ # adjust relative paths as necessary THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh" +. "${THIS_SCRIPT%/*}/../../../resources/build/meson-utils.inc.sh" ## END STANDARD BUILD SCRIPT INCLUDE #. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" @@ -26,37 +27,6 @@ builder_describe_outputs \ TARGET_PATH="$THIS_SCRIPT_PATH/build" -do_clean() { - rm -rf "$THIS_SCRIPT_PATH/resources" - rm -rf "$TARGET_PATH" -} - -do_configure() { - # Import our standard compiler defines; this is copied from - # /resources/build/meson/standard.meson.build by build.sh, because meson doesn't - # allow us to reference a file outside its root - mkdir -p "$THIS_SCRIPT_PATH/resources" - cp "$KEYMAN_ROOT/resources/build/meson/standard.meson.build" "$THIS_SCRIPT_PATH/resources/meson.build" - - pushd "$THIS_SCRIPT_PATH" > /dev/null - # Additional arguments are used by Linux build, e.g. -Dprefix=${INSTALLDIR} - meson setup build --buildtype $BUILDER_CONFIGURATION "${builder_extra_params[@]}" - popd > /dev/null - -} - -do_build() { - pushd "$TARGET_PATH" > /dev/null - ninja - popd > /dev/null -} - -do_test() { - pushd "$TARGET_PATH" > /dev/null - meson test "${builder_extra_params[@]}" - popd > /dev/null -} - builder_run_action clean do_clean builder_run_action configure do_configure builder_run_action build do_build diff --git a/mac/mcompile/build.sh b/mac/mcompile/build.sh index b04c20e04a4..2f163144638 100755 --- a/mac/mcompile/build.sh +++ b/mac/mcompile/build.sh @@ -4,6 +4,7 @@ # adjust relative paths as necessary THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "${THIS_SCRIPT%/*}/../../resources/build/builder.inc.sh" +. "${THIS_SCRIPT%/*}/../../resources/build/meson-utils.inc.sh" ## END STANDARD BUILD SCRIPT INCLUDE ################################ Main script ################################ @@ -24,37 +25,6 @@ builder_describe_outputs \ TARGET_PATH="$THIS_SCRIPT_PATH/build" -do_clean() { - rm -rf "$THIS_SCRIPT_PATH/resources" - rm -rf "$TARGET_PATH" -} - -do_configure() { - # Import our standard compiler defines; this is copied from - # /resources/build/meson/standard.meson.build by build.sh, because meson doesn't - # allow us to reference a file outside its root - mkdir -p "$THIS_SCRIPT_PATH/resources" - cp "$KEYMAN_ROOT/resources/build/meson/standard.meson.build" "$THIS_SCRIPT_PATH/resources/meson.build" - - pushd "$THIS_SCRIPT_PATH" > /dev/null - # Additional arguments are used by Linux build, e.g. -Dprefix=${INSTALLDIR} - meson setup build --buildtype $BUILDER_CONFIGURATION "${builder_extra_params[@]}" - popd > /dev/null - -} - -do_build() { - pushd "$TARGET_PATH" > /dev/null - ninja - popd > /dev/null -} - -do_test() { - pushd "$TARGET_PATH" > /dev/null - meson test "${builder_extra_params[@]}" - popd > /dev/null -} - builder_run_action clean do_clean builder_run_action configure do_configure builder_run_action build do_build diff --git a/resources/build/meson-utils.inc.sh b/resources/build/meson-utils.inc.sh new file mode 100644 index 00000000000..e3e5e8d994d --- /dev/null +++ b/resources/build/meson-utils.inc.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# This script contains common meson functions + + +# ---------------------------------------------------------------------------- +# clean +# ---------------------------------------------------------------------------- + +do_clean() { + rm -rf "$THIS_SCRIPT_PATH/resources" + rm -rf "$TARGET_PATH" +} + +# ---------------------------------------------------------------------------- +# configure +# ---------------------------------------------------------------------------- + +do_configure() { + # Import our standard compiler defines; this is copied from + # /resources/build/meson/standard.meson.build by build.sh, because meson doesn't + # allow us to reference a file outside its root + mkdir -p "$THIS_SCRIPT_PATH/resources" + cp "$KEYMAN_ROOT/resources/build/meson/standard.meson.build" "$THIS_SCRIPT_PATH/resources/meson.build" + + pushd "$THIS_SCRIPT_PATH" > /dev/null + # Additional arguments are used by Linux build, e.g. -Dprefix=${INSTALLDIR} + meson setup build --buildtype $BUILDER_CONFIGURATION "${builder_extra_params[@]}" + popd > /dev/null + +} + +# ---------------------------------------------------------------------------- +# build +# ---------------------------------------------------------------------------- + +do_build() { + pushd "$TARGET_PATH" > /dev/null + ninja + popd > /dev/null +} + +# ---------------------------------------------------------------------------- +# test +# ---------------------------------------------------------------------------- + +do_test() { + pushd "$TARGET_PATH" > /dev/null + meson test "${builder_extra_params[@]}" + popd > /dev/null +} \ No newline at end of file From 92d5f93ffd10d5b84690ad1ff04c4d11ddcf53fc Mon Sep 17 00:00:00 2001 From: Sabine Date: Mon, 7 Oct 2024 10:25:39 +0200 Subject: [PATCH 67/71] feat (mac): use a vector instead of an array in mac_KMX_GetDeadkeys --- mac/mcompile/mcompile.cpp | 56 +++++++++++++-------------------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 611dc7ca5b1..c4c5e59288e 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -16,17 +16,14 @@ #include "mcompile.h" #include "../../common/include/km_u16.h" -const int nr_DK_pairs = 1000; -static const int size_DK_array = (nr_DK_pairs + 1) * 3; - /** @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard */ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion); /** @brief Collect the key data, translate it to kmx and append to the existing keyboard */ bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D &all_vector, const UCKeyboardLayout** keyboard_layout, std::vector* KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327 -/** @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard */ -int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, KMX_DWORD shift_dk, KMX_WORD* outputPairs); // returns array of [usvk, ch_out] pairs +/** @brief return a vector of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard */ +int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, KMX_DWORD shift_dk, std::vector &dk_vec); std::vector KMX_FDeadkeys; // I4353 @@ -398,8 +395,7 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { * @param dk_Table a vector of all possible deadkey combinations for all Linux keyboards */ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, KMX_DWORD shift, KMX_WCHAR deadkey, vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { - KMX_WORD deadkeys[size_DK_array] = {0}; - KMX_WORD* pdk; + std::vector vec_deadkeys; // Lookup the deadkey table for the deadkey in the physical keyboard // Then for each character, go through and map it through @@ -410,13 +406,14 @@ void mac_KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk_US, KMX_DWORD shift, KMX_FDeadkeys.push_back(KMX_deadkeyMapping); // dkid, vk, shift); // I4353 mac_KMX_AddDeadkeyRule(kbd, dkid, vk_US, shift); - mac_KMX_GetDeadkeys(keyboard_layout, all_vector, deadkey, shift, pdk = deadkeys); // returns array of [usvk, ch_out] pairs + mac_KMX_GetDeadkeys(keyboard_layout, all_vector, deadkey, shift, vec_deadkeys); // returns vector of [usvk, ch_out] pairs - while (*pdk) { + int n = 0; + while (n < vec_deadkeys.size()) { // Look up the ch - KMX_DWORD KeyValUnderlying = mac_KMX_get_KeyValUnderlying_From_KeyValUS(all_vector, *pdk); - mac_KMX_TranslateDeadkeyKeyboard(kbd, dkid, KeyValUnderlying, *(pdk + 1), *(pdk + 2)); - pdk += 3; + KMX_DWORD KeyValUnderlying = mac_KMX_get_KeyValUnderlying_From_KeyValUS(all_vector, vec_deadkeys[n]); + mac_KMX_TranslateDeadkeyKeyboard(kbd, dkid, KeyValUnderlying, vec_deadkeys[n + 1], vec_deadkeys[n + 2]); + n += 3; } } @@ -516,15 +513,15 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion) { } /** - * @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard + * @brief return a vector of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard * @param keyboard_layout the currently used (underlying) keyboard Layout - * @param all_vector Vector that holds the data of the US keyboard and the currently used (under lying) keyboard + * @param all_vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard * @param deadkey deadkey character * @param shift_dk shiftstate of the deadkey - * @param[out] outputPairs pointer to array of [usvk, ch_out] pairs + * @param[out] dk_vec vector of [usvk, ch_out] pairs * @return size of array of [usvk, ch_out] pairs */ -int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, KMX_DWORD shift_dk, KMX_WORD* outputPairs) { +int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, KMX_DWORD shift_dk, std::vector &dk_vec) { UInt32 deadkeystate; const UniCharCount maxStringlength = 5; UniCharCount actualStringlength = 0; @@ -533,9 +530,6 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a OSStatus status; unicodeString[0] = 0; - KMX_WORD* p = outputPairs; - int no_dk_counter = 0; - int p_counter = 0; KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(all_vector, deadkey); for (int j = 0; j < _countof(ss_mac); j++) { @@ -548,7 +542,7 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a */ for (int i = keycode_spacebar; i >= 0; i--) { status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_convert_Shiftstate_to_MacShiftstate(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString); - if ( (deadkeystate == 0) && (status != noErr )) // in case UCKeyTranslate returned an error + if ((deadkeystate == 0) && (status != noErr)) // in case UCKeyTranslate returned an error return 0; // UCKeyTranslate: deadkeystate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the character e.g.'^'. @@ -563,29 +557,15 @@ int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& a // ensure to NOT get key combinations like '^a' but only combined characters like 'â' (exception for '^' + space) if ((unicodeString[0] != deadkey) || (vk == VK_SPACE)) { - - // prevent overflow of deadkey-array - if (p_counter < size_DK_array - 3) { - - *p++ = vk; - *p++ = ss_mac[j]; - *p++ = unicodeString[0]; - - p_counter = p_counter + 3; - - } else { - no_dk_counter++; - } + dk_vec.push_back(vk); + dk_vec.push_back(ss_mac[j]); + dk_vec.push_back(unicodeString[0]); } } } } } - if (p_counter >= size_DK_array - 3) - wprintf(L" WARNING: %i deadkeys have not been processed.\n", no_dk_counter); - - *p = 0; - return (p - outputPairs); + return dk_vec.size(); } /** From b9bd855a781238a1be7de5a86a85bc116ef0dddf Mon Sep 17 00:00:00 2001 From: Sabine Date: Tue, 8 Oct 2024 18:47:49 +0200 Subject: [PATCH 68/71] feat (mac): new message if DoConvert fails --- mac/mcompile/mcompile.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index c4c5e59288e..1d4591ead09 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -92,6 +92,9 @@ int main(int argc, char* argv[]) { if (mac_KMX_DoConvert(kmxfile, bDeadkeyConversion)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); + } else { + mac_KMX_LogError(L"Failed to convert keyboard (%d)\n", errno); + return 3; } delete kmxfile; From f079aae6fa9a6bc7a1350600f72a8638e7e56aa8 Mon Sep 17 00:00:00 2001 From: Sabine Date: Tue, 8 Oct 2024 18:56:03 +0200 Subject: [PATCH 69/71] feat (mac): new message if SaveKeyboard fails --- mac/mcompile/mcompile.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mac/mcompile/mcompile.cpp b/mac/mcompile/mcompile.cpp index 1d4591ead09..fedd3a3a810 100644 --- a/mac/mcompile/mcompile.cpp +++ b/mac/mcompile/mcompile.cpp @@ -91,7 +91,10 @@ int main(int argc, char* argv[]) { } if (mac_KMX_DoConvert(kmxfile, bDeadkeyConversion)) { // I4552F - KMX_SaveKeyboard(kmxfile, outfile); + if(!KMX_SaveKeyboard(kmxfile, outfile)) { + mac_KMX_LogError(L"Failed to save keyboard (%d)\n", errno); + return 3; + } } else { mac_KMX_LogError(L"Failed to convert keyboard (%d)\n", errno); return 3; From 33dcf94c0989838c7c7abb322b379692976974ba Mon Sep 17 00:00:00 2001 From: Sabine Date: Thu, 10 Oct 2024 11:13:59 +0200 Subject: [PATCH 70/71] chore (common): rename do_clean, do_configure, do_build, do_test to do_meson_... --- linux/mcompile/keymap/build.sh | 8 ++++---- mac/mcompile/build.sh | 8 ++++---- resources/build/meson-utils.inc.sh | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/linux/mcompile/keymap/build.sh b/linux/mcompile/keymap/build.sh index 838ec86c38c..d7c6aac34f8 100755 --- a/linux/mcompile/keymap/build.sh +++ b/linux/mcompile/keymap/build.sh @@ -27,7 +27,7 @@ builder_describe_outputs \ TARGET_PATH="$THIS_SCRIPT_PATH/build" -builder_run_action clean do_clean -builder_run_action configure do_configure -builder_run_action build do_build -builder_run_action test do_test +builder_run_action clean do_meson_clean +builder_run_action configure do_meson_configure +builder_run_action build do_meson_build +builder_run_action test do_meson_test diff --git a/mac/mcompile/build.sh b/mac/mcompile/build.sh index 2f163144638..c689cd7a39b 100755 --- a/mac/mcompile/build.sh +++ b/mac/mcompile/build.sh @@ -25,7 +25,7 @@ builder_describe_outputs \ TARGET_PATH="$THIS_SCRIPT_PATH/build" -builder_run_action clean do_clean -builder_run_action configure do_configure -builder_run_action build do_build -builder_run_action test do_test \ No newline at end of file +builder_run_action clean do_meson_clean +builder_run_action configure do_meson_configure +builder_run_action build do_meson_build +builder_run_action test do_meson_test diff --git a/resources/build/meson-utils.inc.sh b/resources/build/meson-utils.inc.sh index e3e5e8d994d..24375a840a7 100644 --- a/resources/build/meson-utils.inc.sh +++ b/resources/build/meson-utils.inc.sh @@ -7,7 +7,7 @@ # clean # ---------------------------------------------------------------------------- -do_clean() { +do_meson_clean() { rm -rf "$THIS_SCRIPT_PATH/resources" rm -rf "$TARGET_PATH" } @@ -16,7 +16,7 @@ do_clean() { # configure # ---------------------------------------------------------------------------- -do_configure() { +do_meson_configure() { # Import our standard compiler defines; this is copied from # /resources/build/meson/standard.meson.build by build.sh, because meson doesn't # allow us to reference a file outside its root @@ -34,7 +34,7 @@ do_configure() { # build # ---------------------------------------------------------------------------- -do_build() { +do_meson_build() { pushd "$TARGET_PATH" > /dev/null ninja popd > /dev/null @@ -44,7 +44,7 @@ do_build() { # test # ---------------------------------------------------------------------------- -do_test() { +do_meson_test() { pushd "$TARGET_PATH" > /dev/null meson test "${builder_extra_params[@]}" popd > /dev/null From 62380afb38527b5cb23288fdf0e5a068f053f3dc Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 11 Oct 2024 04:54:48 +0200 Subject: [PATCH 71/71] Update VERSION.md