From d2cee893f29e7d10d4168151f2ba57b11672933f Mon Sep 17 00:00:00 2001 From: Sabine Date: Mon, 12 Feb 2024 15:30:20 +0100 Subject: [PATCH] feat(linux): mcompile-dk resolved problem for deadkey(2) --- linux/mcompile/keymap/deadkey.cpp | 38 +---- linux/mcompile/keymap/deadkey.h | 9 +- linux/mcompile/keymap/helpers.cpp | 194 ++++++++++++++++++++++ linux/mcompile/keymap/keymap.cpp | 49 +----- linux/mcompile/keymap/keymap.h | 2 +- linux/mcompile/keymap/km_types.h | 2 +- linux/mcompile/keymap/mc_import_rules.cpp | 172 ++----------------- linux/mcompile/keymap/mc_import_rules.h | 2 +- linux/mcompile/keymap/mc_kmxfile.cpp | 2 +- linux/mcompile/keymap/mcompile.cpp | 74 ++++----- 10 files changed, 265 insertions(+), 279 deletions(-) diff --git a/linux/mcompile/keymap/deadkey.cpp b/linux/mcompile/keymap/deadkey.cpp index a97f24d323..512dce12fe 100755 --- a/linux/mcompile/keymap/deadkey.cpp +++ b/linux/mcompile/keymap/deadkey.cpp @@ -10,11 +10,10 @@ v_dw_1D createLine(std::wstring first, std::wstring second, KMX_DWORD number, s return line; } -// _S2 DEADKEY STUFF - DO NOT REVIEW YET bool find_dk_combinations_for_single_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++) { - // _S2 is there a better way to find a-z,A-Z? + // _S2 QUESTION is there a better way to find a-z,A-Z? //if (((*p_dk_ComposeTable)[i][0] == dk) ) { if (((*p_dk_ComposeTable)[i][0] == dk) && (IsKeymanUsedChar((*p_dk_ComposeTable)[i][1]))) { line.push_back((*p_dk_ComposeTable)[i][0]); @@ -61,7 +60,7 @@ bool found_dk_inVector(KMX_WCHAR dk, std::vector &dkVec) { return false; } -void Create_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) { std::vector dkVec_unsorted; if( dk == 0) @@ -114,28 +113,7 @@ void sort_alDead(std::vector &small_Vec, std::vector *p_All_ small_Vec = small_sorted; } -/* _S2 probably not needed //_S2 REVIEW this is for testing only and needs to go later -std::vector reduce_alDead(std::vector dk_big) { - std::vector dk_small; - bool foundInSmall=false; - - for ( int i=1; iKMX_DeadCharacter()==94 || dk_big[i]->KMX_DeadCharacter()==96 || dk_big[i]->KMX_DeadCharacter()==180|| dk_big[i]->KMX_DeadCharacter()==126|| dk_big[i]->KMX_DeadCharacter()==168)) { - for( int k=0; k< dk_small.size();k++) { - if(dk_big[i]->KMX_DeadCharacter() == dk_small[k]->KMX_DeadCharacter()) - foundInSmall=true; - } - if(!foundInSmall) - dk_small.push_back(dk_big[i]); - foundInSmall=false; - } - } - return dk_small; -} -*/ -// _S2 DEADKEY STUFF - DO NOT REVIEW YET -// _S2 might be used when deadkeys are implemented . is it correct?? +// _S2 TODO might be used when deadkeys are implemented . is it correct?? KMX_DWORD KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap* keymap) { guint Keyval = (guint) KVal; GdkKeymapKey* keys; @@ -156,16 +134,14 @@ KMX_DWORD KMX_changeKeynameToCapital(KMX_DWORD KVal, KMX_DWORD &shift, GdkKeymap return Name; } -// _S2 DEADKEY STUFF - DO NOT REVIEW YET // _S2 DESIGN NEEDED is this the right place to get dk from? if not wher are they stored? KMX_DWORD create_DKTable(v_dw_2D & dk_ComposeTable) { // values taken from: https://help.ubuntu.com/community/GtkDeadKeyTable#Latin - //dk_ComposeTable[i][0] : First - //dk_ComposeTable[i][1] : Second - //dk_ComposeTable[i][3] : Unicode-Value - //dk_ComposeTable[i][4] : Character - + //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) + //dk_ComposeTable[i][4] : Character (e.g. small A with circumflex) v_dw_1D line; line = createLine(L"dead_circumflex", L"a", 0x00E2, L"small A with circumflex"); diff --git a/linux/mcompile/keymap/deadkey.h b/linux/mcompile/keymap/deadkey.h index 4566756ee1..aa4ea2e21d 100755 --- a/linux/mcompile/keymap/deadkey.h +++ b/linux/mcompile/keymap/deadkey.h @@ -12,11 +12,16 @@ v_dw_1D createLine(std::wstring first, std::wstring second, KMX_DWORD number, s // creates a 2D-vector of all dk combinations ( ` + a -> à ; ^ + a -> â ; `+ e -> è; ...) KMX_DWORD create_DKTable(v_dw_2D & dk_ComposeTable); -//_S2 REVIEW +//_S2 TODO REVIEW +//_S2 finds all possible dk combinations that exist std::vector create_alDead(); +//_S2 refines dk to those used in the underlying keyboard +void refine_alDead(KMX_WCHAR dk, std::vector &myVec, std::vector *p_All_Vec); + +// _S2 TODO maybe not used std::vector reduce_alDead(std::vector dk_big); -void Create_alDead(KMX_WCHAR dk, std::vector &myVec, std::vector *p_All_Vec); + void sort_alDead(std::vector &myVec, std::vector *p_All_Vec); bool found_dk_inVector(KMX_WCHAR dk, std::vector &myVec); diff --git a/linux/mcompile/keymap/helpers.cpp b/linux/mcompile/keymap/helpers.cpp index d977ff4960..6b2c4201b3 100755 --- a/linux/mcompile/keymap/helpers.cpp +++ b/linux/mcompile/keymap/helpers.cpp @@ -1152,6 +1152,200 @@ KMX_DWORD KMX_get_KeyvalsUnderlying_From_KeyCodeUnderlying_GDK_old(GdkKeymap *ke } */ +/* _S2 probably not needed //_S2 REVIEW this is for testing only and needs to go later +std::vector reduce_alDead(std::vector dk_big) { + std::vector dk_small; + bool foundInSmall=false; + + for ( int i=1; iKMX_DeadCharacter()==94 || dk_big[i]->KMX_DeadCharacter()==96 || dk_big[i]->KMX_DeadCharacter()==180|| dk_big[i]->KMX_DeadCharacter()==126|| dk_big[i]->KMX_DeadCharacter()==168)) { + for( int k=0; k< dk_small.size();k++) { + if(dk_big[i]->KMX_DeadCharacter() == dk_small[k]->KMX_DeadCharacter()) + foundInSmall=true; + } + if(!foundInSmall) + dk_small.push_back(dk_big[i]); + foundInSmall=false; + } + } + return dk_small; +} +*/ + + +// _S2 DEADKEY STUFF - DO NOT REVIEW YET +/*std::wstring convert_DeadkeyValues_ToChar_old(int in) { + + KMX_DWORD lname; + + if (in < (int) deadkey_min) { // no deadkey; no Unicode + if (!IsKeymanUsedKeyVal(std::wstring(1, in))) + return L"\0"; + return std::wstring(1, in); + } + else { + std::string long_name((const char*) gdk_keyval_name (in)); + + if ( long_name.substr (0,2) == "U+" ) // U+... Unicode value + return CodePointToWString(in-0x1000000); + + lname = convertNamesToIntegerValue( wstring_from_string(long_name)); // 65106 => "dead_circumflex " => 94 => "^" + + if (lname != returnIfCharInvalid) { + return std::wstring(1, lname ); + } + else + return L"\0"; + } + return L"\0"; +}*/ + + + // _S2 DEADKEY STUFF - DO NOT REVIEW YET --- Do we need this at all? + // _S2 ToDo ToUnicodeEx needs to be replaced here + /* DeadKey *KMX_ProcessDeadKey( + UINT iKeyDead, // The index into the VirtualKey of the dead key + ShiftState shiftStateDead, // The shiftstate that contains the dead key + KMX_BYTE *lpKeyStateDead, // The key state for the dead key + std::vector rgKey, // Our array of dead keys + bool fCapsLock, // Was the caps lock key pressed? + KMX_HKL KMX_hkl, // The keyboard layout + GdkKeymap *keymap) { // _S2 keymap, The keyboard layout + + + KMX_BYTE lpKeyState[256]; + DeadKey *deadKey = new DeadKey(rgKey[iKeyDead]->KMX_GetShiftState(shiftStateDead, fCapsLock)[0]); + +KMX_WCHAR sbBuffer1[16]; + KMX_WCHAR sbBuffer2[16]; + KMX_WCHAR sbBuffer3[16]; + KMX_WCHAR sbBuffer4[16]; + KMX_WCHAR sbBuffer5[16]; + int rc1 = KMX_ToUnicodeEx(49, lpKeyState, sbBuffer1, 0, 0, keymap) ; + int rc4 = KMX_ToUnicodeEx(21, lpKeyState, sbBuffer4, 0, 0, keymap) ; + int rc3 = KMX_ToUnicodeEx( 3, lpKeyState, sbBuffer3, 0, 0, keymap) ; + /*int rc2 = KMX_ToUnicodeEx( 49, lpKeyState, sbBuffer2, 0, 0, keymap) ; + int rc5 = KMX_ToUnicodeEx( 65, lpKeyState, sbBuffer5, 0, 0, keymap) ;*/ + + /*int rc1 = KMX_ToUnicodeEx(192, lpKeyState, sbBuffer1, 0, 0, keymap) ; + int rc4 = KMX_ToUnicodeEx(220, lpKeyState, sbBuffer4, 0, 0, keymap) ; + int rc3 = KMX_ToUnicodeEx( 3, lpKeyState, sbBuffer3, 0, 0, keymap) ; + int rc2 = KMX_ToUnicodeEx( 49, lpKeyState, sbBuffer2, 0, 0, keymap) ; + int rc5 = KMX_ToUnicodeEx( 65, lpKeyState, sbBuffer5, 0, 0, keymap) ;*/ + + + +/* + for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { + if (rgKey[iKey] != NULL) { + KMX_WCHAR sbBuffer[16]; + + for (ShiftState ss = Base; ss <= KMX_MaxShiftState(); ss = (ShiftState)((int)ss+1)) { + int rc = 0; + if (ss == Menu || ss == ShftMenu) { + // Alt and Shift+Alt don't work, so skip them + continue; + } + + for (int caps = 0; caps <= 1; caps++) { + + //------_S2 To find a deadkey in a possibly messed up key ------------------------ + // _S2 My fun does not loop to shorten keys :-(( + + // First the dead key + while (rc >= 0) { + // We know that this is a dead key coming up, otherwise + // this function would never have been called. If we do + // *not* get a dead key then that means the state is + // messed up so we run again and again to clear it up. + // Risk is technically an infinite loop but per Hiroyama + // that should be impossible here. + + rc = KMX_ToUnicodeEx(rgKey[iKeyDead]->SC(), lpKeyState, sbBuffer, ss, caps, keymap); + //wprintf(L"ikey: %i rc = %i\n",iKey,rc); + rc=-1; //_S2 + } + + //---------------------------------------------------------------------------------- + + // Now fill the key state for the potential base character + KMX_FillKeyState(lpKeyState, ss, (caps != 0)); + + //---------------------------------------------------------------------------------- + + rc = KMX_ToUnicodeEx( rgKey[iKey]->SC(), lpKeyState, sbBuffer, ss, caps, keymap) ; + + //--------- ONE character found = combined char (e.g. â ) -------------------------- + // ***** E.G: ToUnicodeEx FOUND Â ***** // + + if (rc == 1) { + Â */ // That was indeed a base character for our dead key. + // And we now have a composite character. Let's run + // through one more time to get the actual base + + // character that made it all possible? + + // _s2 store combined char + // ***** E.G: combchar = Â ***** // + /*KMX_WCHAR combchar = sbBuffer[0]; + + // _S2 again split to get base char ( e.g. a) + // ***** E.G: ToUnicodeEx FOUND A ***** // + rc = KMX_ToUnicodeEx(rgKey[iKey]->SC(), lpKeyState, sbBuffer, ss, caps, keymap) ; + + KMX_WCHAR basechar = sbBuffer[0]; + + if (deadKey->KMX_DeadCharacter() == combchar) { + // Since the combined character is the same as the dead key, + // we must clear out the keyboard buffer. + //KMX_ClearKeyboardBuffer(VK_DECIMAL, rgKey[VK_DECIMAL]->SC(), KMX_hkl); + KMX_ClearKeyboardBuffer(); + } + + if ((((ss == Ctrl) || (ss == ShftCtrl)) && + (KMX_IsControlChar(basechar))) || + (basechar == combchar)) { + // ToUnicodeEx has an internal knowledge about those + // VK_A ~ VK_Z keys to produce the control characters, + // when the conversion rule is not provided in keyboard + // layout files + + // Additionally, dead key state is lost for some of these + // character combinations, for unknown reasons. + + // Therefore, if the base character and combining are equal, + // and its a CTRL or CTRL+SHIFT state, and a control character + // is returned, then we do not add this "dead key" (which + // is not really a dead key). + continue; + } + + if (!deadKey->KMX_ContainsBaseCharacter(basechar)) { + deadKey->KMX_AddDeadKeyRow(basechar, combchar); + } + } + + //---------no valid key combi -> IGNORE --------------------------------------------- + + else if (rc > 1) { + // Not a valid dead key combination, sorry! We just ignore it. + } + + //---------another dead key-> IGNORE ----------------------------------------------- + else if (rc < 0) { + // It's another dead key, so we ignore it (other than to flush it from the state) + //ClearKeyboardBuffer(VK_DECIMAL, rgKey[VK_DECIMAL]->SC(), KMX_hkl); + KMX_ClearKeyboardBuffer(); + } + } + } + } + } + return deadKey; + }*/ + + /* diff --git a/linux/mcompile/keymap/keymap.cpp b/linux/mcompile/keymap/keymap.cpp index a9ac90102c..908b947a3c 100755 --- a/linux/mcompile/keymap/keymap.cpp +++ b/linux/mcompile/keymap/keymap.cpp @@ -358,8 +358,7 @@ bool InitializeGDK(GdkKeymap **keymap,int argc, gchar *argv[]) { } //------------------------------ -// _S2 DEADKEY STUFF - DO NOT REVIEW YET -// _S2 ToDo deadkeys. Do we need this ? +// _S2 TODO deadkeys. Do we need this ? bool IsKeymanUsedKeyVal(std::wstring Keyval) { int KV = (int) (*Keyval.c_str()); @@ -396,35 +395,7 @@ bool IsKeymanUsedChar(int KV) { return false; } -// _S2 DEADKEY STUFF - DO NOT REVIEW YET -std::wstring convert_DeadkeyValues_ToChar_old(int in) { - KMX_DWORD lname; - - if (in < (int) deadkey_min) { // no deadkey; no Unicode - if (!IsKeymanUsedKeyVal(std::wstring(1, in))) - return L"\0"; - return std::wstring(1, in); - } - else { - std::string long_name((const char*) gdk_keyval_name (in)); - - if ( long_name.substr (0,2) == "U+" ) // U+... Unicode value - return CodePointToWString(in-0x1000000); - - lname = convertNamesToIntegerValue( wstring_from_string(long_name)); // 65106 => "dead_circumflex " => 94 => "^" - - if (lname != returnIfCharInvalid) { - return std::wstring(1, lname ); - } - else - return L"\0"; - } - return L"\0"; -} - - -// _S2 DEADKEY STUFF - DO NOT REVIEW YET std::wstring convert_DeadkeyValues_ToChar(int in) { KMX_DWORD lname; @@ -451,7 +422,7 @@ std::wstring convert_DeadkeyValues_ToChar(int in) { else return L"\0"; } - +//_S2 REview and change?? std::u16string convert_DeadkeyValues_To_U16str(int in) { KMX_DWORD lname; @@ -587,7 +558,7 @@ KMX_DWORD KMX_get_KeyvalsUnderlying_From_KeyCodeUnderlying_GDK(GdkKeymap *keymap if (!(keycode <= 94)) return 0; - // _S2 take caps to this function + // _S2 TODO take caps to this function // here I get all kvals: normal char , my Deadkeys, allothr DK KMX_DWORD All_Keyvals = KMX_get_keyvals_From_Keycode(keymap, keycode, ShiftState(shift_state_pos), 0) ; //wprintf(L"All_Keyvals: %i----\n", All_Keyvals); @@ -601,7 +572,7 @@ KMX_DWORD KMX_get_KeyvalsUnderlying_From_KeyCodeUnderlying_GDK(GdkKeymap *keymap out = KMX_get_FFFF_Underlying_according_to_keycode_and_Shiftstate_GDK_dw(keymap, keycode, (ShiftState) shift_state_pos, 0); //wprintf(L" out is :.....................................%i\n", out); - // _S2 g_free used everywhere? + // _S2 TODO g_free used everywhere? g_free(keyvals); g_free(maps); @@ -625,7 +596,7 @@ KMX_DWORD KMX_get_KeyvalsUnderlying_From_KeyCodeUnderlying_GDK(GdkKeymap *keymap out = KMX_get_CharsUnderlying_according_to_keycode_and_Shiftstate_GDK_dw(keymap, keycode, (ShiftState) shift_state_pos, 0); - // _S2 g_free used everywhere? + // _S2 TODO g_free used everywhere? g_free(keyvals); g_free(maps); @@ -638,9 +609,7 @@ KMX_DWORD KMX_get_FFFF_Underlying_according_to_keycode_and_Shiftstate_GDK_dw(Gdk KMX_DWORD keyvals_dw= (KMX_DWORD) KMX_get_keyvals_From_Keycode(keymap, keycode, ss, caps) ; // _S2 AHA output for dk4-12 at the top after dk... from here - // _S2 only for testing - if((keyvals_dw >= deadkey_min) && (keyvals_dw <= deadkey_max)) - //if((keyvals_dw >= 65104) && (keyvals_dw <= 65106)) // deadkeys + if((keyvals_dw >= deadkey_min) && (keyvals_dw <= deadkey_max)) // deadkeys return 0xFFFF; else if((keyvals_dw > deadkey_max) || ((keyvals_dw < deadkey_min) && ( keyvals_dw > 0xFF))) // out of range return 0xFFFE; @@ -655,7 +624,7 @@ KMX_DWORD KMX_get_CharsUnderlying_according_to_keycode_and_Shiftstate_GDK_dw(Gdk std::wstring KMX_get_CharsUnderlying_according_to_keycode_and_Shiftstate_GDK(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps){ - // _S2 skip ss 2+3 remove?? + // _S2 QUESTION skip ss 2+3 remove?? if( (ss ==2 ) ||(ss ==3 )) return L"\0"; @@ -689,7 +658,7 @@ KMX_DWORD KMX_get_VKUS_From_KeyCodeUnderlying_GDK( GdkKeymap *keymap, KMX_DWORD if ( keyvals[i]>0) gdk_keyval_convert_case (*kv_name, &lowerCase, &upperCase); - // _S2 is ( lowerCase == upperCase ) true for all number keys for all keyboards? + // _S2 QUESTION is ( lowerCase == upperCase ) true for all number keys for all keyboards? if ( lowerCase == upperCase ) return (KMX_DWORD) upperCase; } @@ -698,7 +667,7 @@ KMX_DWORD testvar_S2 = ScanCodeToUSVirtualKey[keycode-8]; if ( keycode >7) return (KMX_DWORD) ScanCodeToUSVirtualKey[keycode-8]; - return 0; //_S2 what to return if not found + return 0; } KMX_DWORD KMX_get_KeyCodeUnderlying_From_VKUS( KMX_DWORD VK_US) { diff --git a/linux/mcompile/keymap/keymap.h b/linux/mcompile/keymap/keymap.h index f06d1b2cc3..c3428cd1bb 100755 --- a/linux/mcompile/keymap/keymap.h +++ b/linux/mcompile/keymap/keymap.h @@ -520,7 +520,7 @@ KMX_DWORD KMX_get_KeyvalsUnderlying_From_KeyCodeUnderlying_GDK(GdkKeymap *keymap std::wstring KMX_get_CharsUnderlying_according_to_keycode_and_Shiftstate_GDK(GdkKeymap *keymap, guint VK, ShiftState ss, int caps); KMX_DWORD KMX_get_CharsUnderlying_according_to_keycode_and_Shiftstate_GDK_dw(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps); -// _S2 returns char or FFFF / FFFE ???? +// _S2 TODO returns char or FFFF / FFFE ???? KMX_DWORD KMX_get_FFFF_Underlying_according_to_keycode_and_Shiftstate_GDK_dw(GdkKeymap *keymap, guint keycode, ShiftState ss, int caps); diff --git a/linux/mcompile/keymap/km_types.h b/linux/mcompile/keymap/km_types.h index 5953b67b27..addadd7666 100755 --- a/linux/mcompile/keymap/km_types.h +++ b/linux/mcompile/keymap/km_types.h @@ -72,7 +72,7 @@ typedef int BOOL; // PVOID A pointer to any type. // typedef PVOID HANDLE; // typedef HANDLE HKL; -typedef void* KMX_HKL; // _S2 what is the equivalent to HKL and do I need it?? I assume a void* +typedef void* KMX_HKL; // _S2 QUESTION what is the equivalent to HKL and do I need it?? I assume a void* #ifndef FALSE diff --git a/linux/mcompile/keymap/mc_import_rules.cpp b/linux/mcompile/keymap/mc_import_rules.cpp index ee61456b3b..3b26c5ec2f 100755 --- a/linux/mcompile/keymap/mc_import_rules.cpp +++ b/linux/mcompile/keymap/mc_import_rules.cpp @@ -76,8 +76,6 @@ const int KMX_ShiftStateMap[] = { 0 }; -// _S2 DEADKEY STUFF - DO NOT REVIEW YET - DeadKey::DeadKey(KMX_WCHAR deadCharacter) { this->m_deadchar = deadCharacter; } @@ -121,7 +119,7 @@ int KMX_ToUnicodeEx(guint keycode, const BYTE *lpKeyState, PKMX_WCHAR pwszBuff, KMX_DWORD keyvals_dw= (KMX_DWORD) KMX_get_keyvals_From_Keycode(keymap, keycode, ShiftState(shift_state_pos), caps) ; - // _S2 g_free used everywhere? + // _S2 TODO g_free used everywhere? g_free(keyvals); g_free(maps); @@ -150,7 +148,7 @@ int KMX_DeadKeyMap(int index, std::vector *deadkeys, int deadkeyBase, class KMX_VirtualKey { private: - KMX_HKL m_hkl; // _S2 do I need this and is void* OK to assume? If I remove this, will there be changes in Data-Vectors? + KMX_HKL m_hkl; // _S2 QUESTION do I need this and is void* OK to assume? If I remove this, will there be changes in Data-Vectors? UINT m_vk; UINT m_sc; bool m_rgfDeadKey[10][2]; @@ -162,7 +160,7 @@ public: this->m_sc=KMX_get_SCUnderlying_From_VKUS(virtualKey); this->m_hkl = hkl; this->m_vk = virtualKey; - // _S2 ToDo deadkey + // _S2 TODO deadkey // memset(this->m_rgfDeadKey,0,sizeof(this->m_rgfDeadKey)); } @@ -207,7 +205,7 @@ public: this->m_rgss[(UINT)shiftState][(capsLock ? 1 : 0)] = value; } -// _S2 why are there sometimes numbers in m_rgfDeadKey??? +// _S2 QUESTION why are there sometimes numbers in m_rgfDeadKey??? void KMX_SetShiftState(ShiftState shiftState, std::u16string value16, bool isDeadKey, bool capsLock) { std::wstring value = wstring_from_u16string(value16); this->m_rgfDeadKey[(UINT)shiftState][(capsLock ? 1 : 0)] = isDeadKey; @@ -276,7 +274,7 @@ public: 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) { //wprintf(L"GetShiftStateValue takes capslock: %i, caps: %i, ss: %i and returns: %i \n", //capslock, caps, ss, (KMX_ShiftStateMap[(int)ss] | (capslock ? (caps ? CAPITALFLAG : NOTCAPITALFLAG) : 0))); @@ -468,150 +466,6 @@ public: return (ch < 0x0020) || (ch >= 0x007F && ch <= 0x009F); } - // _S2 DEADKEY STUFF - DO NOT REVIEW YET --- Do we need this at all? - // _S2 ToDo ToUnicodeEx needs to be replaced here - DeadKey *KMX_ProcessDeadKey( - UINT iKeyDead, // The index into the VirtualKey of the dead key - ShiftState shiftStateDead, // The shiftstate that contains the dead key - KMX_BYTE *lpKeyStateDead, // The key state for the dead key - std::vector rgKey, // Our array of dead keys - bool fCapsLock, // Was the caps lock key pressed? - KMX_HKL KMX_hkl, // The keyboard layout - GdkKeymap *keymap) { // _S2 keymap, The keyboard layout - - - KMX_BYTE lpKeyState[256]; - DeadKey *deadKey = new DeadKey(rgKey[iKeyDead]->KMX_GetShiftState(shiftStateDead, fCapsLock)[0]); - -KMX_WCHAR sbBuffer1[16]; - KMX_WCHAR sbBuffer2[16]; - KMX_WCHAR sbBuffer3[16]; - KMX_WCHAR sbBuffer4[16]; - KMX_WCHAR sbBuffer5[16]; - int rc1 = KMX_ToUnicodeEx(49, lpKeyState, sbBuffer1, 0, 0, keymap) ; - int rc4 = KMX_ToUnicodeEx(21, lpKeyState, sbBuffer4, 0, 0, keymap) ; - int rc3 = KMX_ToUnicodeEx( 3, lpKeyState, sbBuffer3, 0, 0, keymap) ; - /*int rc2 = KMX_ToUnicodeEx( 49, lpKeyState, sbBuffer2, 0, 0, keymap) ; - int rc5 = KMX_ToUnicodeEx( 65, lpKeyState, sbBuffer5, 0, 0, keymap) ;*/ - - /*int rc1 = KMX_ToUnicodeEx(192, lpKeyState, sbBuffer1, 0, 0, keymap) ; - int rc4 = KMX_ToUnicodeEx(220, lpKeyState, sbBuffer4, 0, 0, keymap) ; - int rc3 = KMX_ToUnicodeEx( 3, lpKeyState, sbBuffer3, 0, 0, keymap) ; - int rc2 = KMX_ToUnicodeEx( 49, lpKeyState, sbBuffer2, 0, 0, keymap) ; - int rc5 = KMX_ToUnicodeEx( 65, lpKeyState, sbBuffer5, 0, 0, keymap) ;*/ - - - - - for (UINT iKey = 0; iKey < rgKey.size(); iKey++) { - if (rgKey[iKey] != NULL) { - KMX_WCHAR sbBuffer[16]; - - for (ShiftState ss = Base; ss <= KMX_MaxShiftState(); ss = (ShiftState)((int)ss+1)) { - int rc = 0; - if (ss == Menu || ss == ShftMenu) { - // Alt and Shift+Alt don't work, so skip them - continue; - } - - for (int caps = 0; caps <= 1; caps++) { - - //------_S2 To find a deadkey in a possibly messed up key ------------------------ - // _S2 My fun does not loop to shorten keys :-(( - - // First the dead key - while (rc >= 0) { - // We know that this is a dead key coming up, otherwise - // this function would never have been called. If we do - // *not* get a dead key then that means the state is - // messed up so we run again and again to clear it up. - // Risk is technically an infinite loop but per Hiroyama - // that should be impossible here. - - rc = KMX_ToUnicodeEx(rgKey[iKeyDead]->SC(), lpKeyState, sbBuffer, ss, caps, keymap); - //wprintf(L"ikey: %i rc = %i\n",iKey,rc); - rc=-1; //_S2 - } - - //---------------------------------------------------------------------------------- - - // Now fill the key state for the potential base character - KMX_FillKeyState(lpKeyState, ss, (caps != 0)); - - //---------------------------------------------------------------------------------- - - rc = KMX_ToUnicodeEx( rgKey[iKey]->SC(), lpKeyState, sbBuffer, ss, caps, keymap) ; - - //--------- ONE character found = combined char (e.g. â ) -------------------------- - // ***** E.G: ToUnicodeEx FOUND Â ***** // - - if (rc == 1) { - /* Â */ // That was indeed a base character for our dead key. - // And we now have a composite character. Let's run - // through one more time to get the actual base - - // character that made it all possible? - - // _s2 store combined char - // ***** E.G: combchar = Â ***** // - KMX_WCHAR combchar = sbBuffer[0]; - - // _S2 again split to get base char ( e.g. a) - // ***** E.G: ToUnicodeEx FOUND A ***** // - /* A */ rc = KMX_ToUnicodeEx(rgKey[iKey]->SC(), lpKeyState, sbBuffer, ss, caps, keymap) ; - - KMX_WCHAR basechar = sbBuffer[0]; - - if (deadKey->KMX_DeadCharacter() == combchar) { - // Since the combined character is the same as the dead key, - // we must clear out the keyboard buffer. - //KMX_ClearKeyboardBuffer(VK_DECIMAL, rgKey[VK_DECIMAL]->SC(), KMX_hkl); - KMX_ClearKeyboardBuffer(); - } - - if ((((ss == Ctrl) || (ss == ShftCtrl)) && - (KMX_IsControlChar(basechar))) || - (basechar == combchar)) { - // ToUnicodeEx has an internal knowledge about those - // VK_A ~ VK_Z keys to produce the control characters, - // when the conversion rule is not provided in keyboard - // layout files - - // Additionally, dead key state is lost for some of these - // character combinations, for unknown reasons. - - // Therefore, if the base character and combining are equal, - // and its a CTRL or CTRL+SHIFT state, and a control character - // is returned, then we do not add this "dead key" (which - // is not really a dead key). - continue; - } - - if (!deadKey->KMX_ContainsBaseCharacter(basechar)) { - deadKey->KMX_AddDeadKeyRow(basechar, combchar); - } - } - - //---------no valid key combi -> IGNORE --------------------------------------------- - - else if (rc > 1) { - // Not a valid dead key combination, sorry! We just ignore it. - } - - //---------another dead key-> IGNORE ----------------------------------------------- - else if (rc < 0) { - // It's another dead key, so we ignore it (other than to flush it from the state) - //ClearKeyboardBuffer(VK_DECIMAL, rgKey[VK_DECIMAL]->SC(), KMX_hkl); - KMX_ClearKeyboardBuffer(); - } - } - } - } - } - return deadKey; - } - - void KMX_ClearKeyboardBuffer() { KMX_WCHAR sb[16]; for( int i=0; i<16; i++) { @@ -656,7 +510,7 @@ bool KMX_ImportRules(LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, GdkKeymap **keymap, //_S2 REVIEW std::vector alDead2 ; - std::vector alDead_cpl = create_alDead(); // _S2 finds all possible dk combinations that exist - will be refined to those used in the underlying keyboard + std::vector alDead_cpl = create_alDead(); rgKey.resize(256); @@ -734,7 +588,7 @@ bool KMX_ImportRules(LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, GdkKeymap **keymap, KMX_DWORD SC_US = KMX_get_KeyCodeUnderlying_From_VKUS(iKey); - // _S2 deadkey not finished; Ctrl, Shft +40 not tested + // _S2 TODO deadkey not finished; Ctrl, Shft +40 not tested for(int caps = 0; caps <= 1; caps++) { loader.KMX_ClearKeyboardBuffer(); loader.KMX_FillKeyState(lpKeyState, ss, (caps == 0)); @@ -771,30 +625,24 @@ bool KMX_ImportRules(LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, GdkKeymap **keymap, } } else if(rc < 0) { - //wprintf(L"iKey: %i- ss: %i, caps: %i - bsBuffer[0] = %i\n", iKey, ss, caps,sbBuffer[0]); - //_S2 TODO sbBuffer[2] = 0; //rgKey[iKey]->SetShiftState(ss, sbBuffer, true, (caps == 0)); - rgKey[iKey]->KMX_SetShiftState(ss, sbBuffer, true, (caps )); - //wprintf(L"rc<0 for iKey nr. %i (%c) \n",iKey,iKey ); + rgKey[iKey]->KMX_SetShiftState(ss, sbBuffer, true, (caps )); //_S2 // It's a dead key; let's flush out whats stored in the keyboard state. loader.KMX_ClearKeyboardBuffer(); DeadKey *dk = NULL; - Create_alDead(sbBuffer[0], alDead, &alDead_cpl); + refine_alDead(sbBuffer[0], alDead, &alDead_cpl); int testI= alDead.size(); /* for(UINT iDead = 0; iDead < alDead.size(); iDead++) { dk = alDead[iDead]; - KMX_WCHAR dktest1 = dk->KMX_DeadCharacter(); // _S2 can go later ; just for testing - KMX_WCHAR dktest2 = rgKey[iKey]->KMX_GetShiftState(ss, caps == 0)[0]; // _S2 can go later ; just for testing if(dk->KMX_DeadCharacter() == rgKey[iKey]->KMX_GetShiftState(ss, caps == 0)[0]) { break; } dk = NULL; } if(dk == NULL) { - //_S2 TODO //alDead.push_back(loader.KMX_ProcessDeadKey(iKey, ss, lpKeyState, rgKey, caps == 0, hkl, *keymap)); alDead2 = create_alDead(); alDead = reduce_alDead(alDead2); @@ -808,7 +656,7 @@ bool KMX_ImportRules(LPKMX_KEYBOARD kp,v_dw_3D &All_Vector, GdkKeymap **keymap, } } } - // _S2 do we need to sort alDead?? + // do we need to sort alDead?? sort_alDead(alDead, &alDead_cpl) ; //_S2 this gan co later diff --git a/linux/mcompile/keymap/mc_import_rules.h b/linux/mcompile/keymap/mc_import_rules.h index b80b4466a8..83e667f597 100644 --- a/linux/mcompile/keymap/mc_import_rules.h +++ b/linux/mcompile/keymap/mc_import_rules.h @@ -31,7 +31,7 @@ public: return this->m_rgcombchar[index]; } - // _S2 only use one + // _S2 TODO only use one bool ContainsBaseCharacter(WCHAR baseCharacter); bool KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) ; diff --git a/linux/mcompile/keymap/mc_kmxfile.cpp b/linux/mcompile/keymap/mc_kmxfile.cpp index 6a879bbcf4..ed2be90363 100755 --- a/linux/mcompile/keymap/mc_kmxfile.cpp +++ b/linux/mcompile/keymap/mc_kmxfile.cpp @@ -475,7 +475,7 @@ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD sz){ return TRUE; } -// __S2 use incxstr from elsewhere +// __S2 TODO use incxstr from elsewhere PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) { if (*p == 0) diff --git a/linux/mcompile/keymap/mcompile.cpp b/linux/mcompile/keymap/mcompile.cpp index 2ecaa9de59..d52e3cedd9 100755 --- a/linux/mcompile/keymap/mcompile.cpp +++ b/linux/mcompile/keymap/mcompile.cpp @@ -132,7 +132,6 @@ int run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ #if defined(_WIN32) || defined(_WIN64) - // _S2 DoConvert for windows needs to be done later ( can it be copied from engine/mcompile ?) /*if(DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F KMX_SaveKeyboard(kmxfile, outfile); }*/ @@ -144,7 +143,7 @@ int run(int argc, std::vector str_argv, char* argv_ch[] = NULL){ #endif - //DeleteReallocatedPointers(kmxfile); :TODO // _S2 not my ToDo :-) + //DeleteReallocatedPointers(kmxfile); :TODO // not my ToDo :-) delete kmxfile; wprintf(L"\nmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm end\n"); @@ -157,15 +156,15 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCT // _S2 my comment for Lin version // Ubuntu: Each of the 4 columns specifies a different modifier: unmodified, shift, right alt (altgr), shift+right alt(altgr) -// some hold up to 8 what are those ??? // we have assigned these to columns 1-4 ( column o holds the keycode) -//const UINT VKShiftState[] = {0, 1, 2, 3, 0xFFFF}; +// const UINT VKShiftState[] = {0, 1, 2, 3, 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 +// _S2 exchange key->Key with the new value ( use vk instead of ch) // void KMX_TranslateKey(LPKMX_KEY key, KMX_WORD vk, KMX_UINT shift, KMX_WCHAR ch) { // The weird LCTRL+RALT is Windows' way of mapping the AltGr key. @@ -237,28 +236,28 @@ void KMX_ReportUnconvertedKeyboardRules(LPKMX_KEYBOARD kbd) { void KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk, UINT shift, KMX_WORD ch, int abcd) { -// deadkey2 should not run this routine !!! but it does _S2 FEHLER HIER !!!!! + //_S2 AHA Hier ist das Problem : für dk==2 springt er hier rein, was er nicht darf... + // this is because SHIFTFLAG has the wrong value + // which is because KMX_GetShiftStateValue gets the wrong value + // which is because capslock is not set correctlyS + // which is because WIN<->Lin shiftstares are different 4 $ $ 4 <-> 4 4 $ $ etc. - - //if (key->Key == 94) - // wprintf(L"key->ShiftFlags: %i isEqual: %i %i(%c) %i(%c) ---> %i \n", key->ShiftFlags, key->ShiftFlags & VIRTUALCHARKEY , key->Key , key->Key, ch,ch , ((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch)); -//wprintf(L"key->Key %i\n",key->Key); -/*if(abcd >1 && abcd < 815 ) { - -wprintf(L"key->Key %i\tkey->dpContext: %i %i %i %i %i %i %i %i %i \tkey->dpoutput: %i %i %i %i %i %i\n", key->Key, -*key->dpContext, *(key->dpContext+1),*(key->dpContext+2),*(key->dpContext+3),*(key->dpContext+4),*(key->dpContext+5),*(key->dpContext+6),*(key->dpContext+7),*(key->dpContext+8), -*key->dpOutput, *(key->dpOutput+1),*(key->dpOutput+2),*(key->dpOutput+3),*(key->dpOutput+4),*(key->dpOutput+5) ); -}*/ - - - if (deadkey == 2) { - wprintf(L"\ndeadkey %i, key->ShiftFlags:%i key->ShiftFlags & VIRTUALCHARKEY %i key->Key == ch %i",deadkey, key->ShiftFlags, key->ShiftFlags & VIRTUALCHARKEY, key->Key == ch); - } -Hier ist das Problem : für dk==2 springt er hier rein, was er nicht darf... +int wertzu=688; +// _S2 why is key->Key == ch -> false ???? if((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) { //if(((key->ShiftFlags == 0 || key->ShiftFlags & VIRTUALCHARKEY) && key->Key == ch) && (!(deadkey==2 && shift==0))) { + if(((deadkey==2 ))) { + //wprintf(L"\nXXdeadkey %i, vk: %i\tkey->ShiftFlags:%i \tkey->ShiftFlags & VIRTUALCHARKEY %i\tkey->Key == ch %i key->Key: %i ch: %i",deadkey, vk, key->ShiftFlags, key->ShiftFlags & VIRTUALCHARKEY, key->Key == ch, key->Key, ch); - wprintf(L"TRUE!!!!!!!!!"); + wprintf(L"\nXXdeadkey %i, vk: %i\tkey->Key: %i ch: %i",deadkey, vk, key->Key, ch); + + + wprintf(L" TRUE!!!!!!!!!"); + } + //wprintf(L"\ndeadkey %i, key->ShiftFlags:%i key->ShiftFlags & VIRTUALCHARKEY %i key->Key == ch %i",deadkey, key->ShiftFlags, key->ShiftFlags & VIRTUALCHARKEY, key->Key == ch); + + + //wprintf(L" TRUE!!!!!!!!!"); // 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.. @@ -414,6 +413,8 @@ KMX_WCHAR KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) { void KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR deadkey, v_dw_3D &All_Vector, GdkKeymap* keymap) { KMX_WORD deadkeys[512], *pdk; + KMX_WORD* pd_S2; + KMX_DWORD* pdd_S2; //wprintf(L" ***************************************** key: %i %i %i \n",vk,shift, deadkey); // _S2 create dkTable once only and use as static/ define before func // create dk_createDK_ComposeTable @@ -427,28 +428,17 @@ void KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR d // Add the deadkey to the mapping table for use in the import rules phase KMX_DeadkeyMapping KMX_deadkeyMapping = { deadkey, dkid, shift, vk}; // I4353 - //__S2 NEEDS to be here later KMX_FDeadkeys.push_back(KMX_deadkeyMapping); //dkid, vk, shift); // I4353 KMX_AddDeadkeyRule(kbd, dkid, vk, shift); - // _S2 NEEDS to go! -------- - /*// _S2 is only for testing &to compare 3 dk of windows - if(KMX_FDeadkeys.size()<3 ) - KMX_FDeadkeys.push_back(KMX_deadkeyMapping); //dkid, vk, shift); // I4353 - if(shift== 0 || shift== 16 ) - KMX_AddDeadkeyRule(kbd, dkid, vk, shift); - else - return;;*/ - // _S2 ----------------------------- - KMX_GetDeadkeys(dk_Table, deadkey, pdk = deadkeys, keymap); // returns array of [usvk, ch_out] pairs - while(*pdk) { - +pd_S2=pdk; +//pdd_S2=pdk; // Look up the ch UINT vkUnderlying = KMX_get_VKUS_From_VKUnderlying_VEC(All_Vector, *pdk); - //wprintf(L" vkUnderlying %i *pdk %i %i %ixxx", vkUnderlying, *pdk, *(pdk+1), *(pdk+2)); + wprintf(L" vkUnderlying %i *pdk %i %i %ixxx \n", vkUnderlying, *pd_S2, *(pd_S2+1), *(pd_S2+2)); KMX_TranslateDeadkeyKeyboard(kbd, dkid, vkUnderlying, *(pdk+1), *(pdk+2)); if(vkUnderlying != (UINT) *pdk) { @@ -457,6 +447,7 @@ void KMX_ConvertDeadkey(LPKMX_KEYBOARD kbd, KMX_WORD vk, UINT shift, KMX_WCHAR d //else //wprintf(L" \n"); pdk+=3; + pd_S2+=3; } } @@ -532,14 +523,17 @@ int sdfghjkl=0; //wprintf(L" scunderlying: SS: %i Nr: %i VKMap[i] %i ch:%i (%c)\n", VKShiftState[j],i, KMX_VKMap[i],ch,ch );` switch(ch) { case 0x0000: break; - case 0xFFFF: - KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keymap); break; //test_keyboard_S2(kbd); //-> mit Convert DK FALSCH; Ohne ConvertDK the same - default: KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); + case 0xFFFF: // _S2 in kbd (=loaded from kmx-file): replace LCTRL+RALT -> Ctrl+Alt + write deadkey-> FFFF + CODE_DEADKEY + deadkey into context + KMX_ConvertDeadkey(kbd, KMX_VKMap[i], VKShiftState[j], DeadKey, All_Vector, keymap); break; + default: // _S2 in kbd (=loaded from kmx-file): replace LCTRL+RALT -> Ctrl+Alt + switch keyvalues e.g. y<->z + KMX_TranslateKeyboard(kbd, KMX_VKMap[i], VKShiftState[j], ch); } } } KMX_ReportUnconvertedKeyboardRules(kbd); + + // _S2 use translated kbd and write data to rgkey[] then add things to rgkey[] to enable to write to kmx-format if(!KMX_ImportRules(kbd, All_Vector, &keymap, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552 return FALSE; } @@ -577,7 +571,7 @@ KMX_WCHAR KMX_get_VKUS_From_VKUnderlying_VEC(v_dw_3D All_Vector, KMX_DWORD VK_OT } // takes SC of underlying keyboard and returns character of underlying keyboard with shiftstate VKShiftState[j] or deadkey -// _S2 KMX_UINT ??? +// _S2 QUESTION KMX_UINT ??? KMX_WCHAR KMX_get_CharUnderlying_From_SCUnderlying_GDK(GdkKeymap *keymap, KMX_UINT VKShiftState, UINT SC_OTHER, PKMX_WCHAR DeadKey) { PKMX_WCHAR dky;