diff --git a/mac/mcompile/keymap.cpp b/mac/mcompile/keymap.cpp index 8e0f43c4c3..d75fe18d78 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) ); -}*/ - -bool is_correct_win_shiftstate(int comp_ss) { - return ( (comp_ss ==0) || (comp_ss ==16) || (comp_ss ==9) || (comp_ss ==25) || (comp_ss ==0xFFFF) ); + /** + * @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) ); } -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 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; + + if (!(caps <= 1)) + return false; + +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) { 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;*/ - keyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, kc_underlying,(mac_map_VKShiftState_to_MacModifier(vk_ShiftState)), caps, isdk); + 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_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 e9ca11ca0d..a73005092a 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 85c9086958..b66fd417c8 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 @@ public: 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 @@ public: 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 5e54454552..773eaa3947 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 53afeef9ef..3a0fda673f 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 d384cc3836..0e4848f638 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, ...);