# This is a combination of 8 commits.

# This is the 1st commit message:

feat(mac): remove unused func

# This is the commit message #2:

feat(mac): edit, remove unused code

# This is the commit message #3:

feat(mac): more edit

# This is the commit message #4:

feat(mac): comments keymap

# This is the commit message #5:

feat(mac): comments importRules

# This is the commit message #6:

feat(mac): comments

# This is the commit message #7:

feat(mac): more comments

# This is the commit message #8:

feat(mac): adapt data types return para
This commit is contained in:
Sabine 2024-07-11 14:29:34 +02:00
parent 96870c4926
commit 927154cebb
10 changed files with 473 additions and 616 deletions

View file

@ -1,13 +1,19 @@
/*
* Keyman is copyright (C) SIL International. MIT License.
*
* Keyboard reading and mapping for mac
* Mnemonic layout support for mac
*
* Throughout mcompile we use the following naming conventions:
* KEYCODE: The physical position of a key on a keyboard e.g. Keycode for 'Z' on US: 6 on Mac | 52 on Linux/x11 | 44 on Windows
* SCANCODE (naming on windows): The physical position of a key on a keyboard e.g. Keycode for 'Z' on US: 44 on Windows
* VIRTUAL KEY: The value of a character on a key e.g. 'A' = 65; 'a' = 97 - not neccessarily the same as ACSII- exists on a Windows keyboard only
* KEYVAL(UE): The value of a character on a key e.g. 'A' = 65; 'a' = 97 - not neccessarily the same as ACSII
*/
#include "keymap.h"
#include "kmx_file.h"
/** @brief map a shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on the mac */
/** @brief map a shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on the mac */
int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) {
if (shiftState == 0) return MAC_BASE; // Win ss 0 -> mac ss 0
else if (shiftState == K_SHIFTFLAG) return MAC_SHIFT; // Win ss 16 -> mac ss 2
@ -16,39 +22,15 @@ int mac_convert_Shiftstate_to_MacShiftstate(int shiftState) {
else return shiftState; // Win ss x -> mac ss x
}
/** @brief map a shiftstate used in rgkey (a vector of VirtualKey*) to a shiftstate suitable for UCKeyTranslate() on the mac */
int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState) {
if (rgkey_ShiftState == 0) return MAC_BASE;
else if (rgkey_ShiftState == 1) return MAC_SHIFT;
else if (rgkey_ShiftState == 6) return MAC_OPT;
else if (rgkey_ShiftState == 7) return MAC_SHIFT_OPT;
if (rgkey_ShiftState == 0) return MAC_BASE;
else if (rgkey_ShiftState == 1) return MAC_SHIFT;
else if (rgkey_ShiftState == 6) return MAC_OPT;
else if (rgkey_ShiftState == 7) return MAC_SHIFT_OPT;
else return rgkey_ShiftState;
}
// _S2 Todo
bool is_correct_win_shiftstate(int win_ss) {
return ((win_ss == 0) || (win_ss == 16) || (win_ss == 9) || (win_ss == 25) || (win_ss == 0xFFFF));
}
// _S2 todo missing code
/** @brief check for correct input parameter that will later be used in UCKeyTranslate() */
bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate, int caps = 0) {
if (!keyboard_layout)
return false;
if (keycode > keycode_max)
return false;
if ((shiftstate > max_shiftstate))
return false;
if ((caps > 1))
return false;
return true;
}
// _S2 todo missing code
/** @brief check for correct input parameter that will later be used in UCKeyTranslate() */
bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode) {
@ -61,11 +43,11 @@ bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode) {
return true;
}
/** @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard */
/** @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard */
int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) {
// store contents of the English (US) keyboard in all_vector
if (mac_write_US_ToVector(all_vector)) {
printf("ERROR: can't write US to Vector \n");
printf("ERROR: can't write full US to Vector \n");
return 1;
}
@ -77,9 +59,8 @@ int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeybo
return 0;
}
/** @brief write data of the US keyboard into a 3D-Vector */
/** @brief write data of the US keyboard into a 3D-Vector */
int mac_write_US_ToVector(vec_dword_3D& vec_us) {
//_S2 TODO
// Values for US : A, S, D, F, H, G, Z, X, C, V, §, B, Q, W, E, R, Y, T, 1, 2, 3, 4, 6, 5, =, 9, 7, -, 8, 0, ], O, U, [, I, P,CR, L, J, ', K, ;, \, ,, /, N, M, .
std::vector<int> 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<int> us_Shift = {65, 83, 68, 70, 72, 71, 90, 88,67, 86,177,66, 81, 87, 69, 82, 89, 84,33,64,35,36,94,37,43,40,38,95,42,41,125, 79, 85,123, 73, 80,13, 76, 74,34, 75,58,124,60,63, 78, 77,62};
@ -99,11 +80,14 @@ int mac_write_US_ToVector(vec_dword_3D& vec_us) {
if (key.size() == 0) {
printf("ERROR: can't Create Vector for US keyboard\n");
return 1;
} else if (key.size() < 48) {
printf("ERROR: keyboard not created completely\n");
return 1;
} else
return 0;
}
/** @brief create an 2D-Vector with all fields containing INVALID_NAME */
/** @brief create an 2D-Vector with all fields initialized to INVALID_NAME */
vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss) {
vec_dword_1D shifts;
vec_dword_2D vector_2D;
@ -118,9 +102,8 @@ vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss) {
return vector_2D;
}
/** @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector */
/** @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector */
int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) {
int caps = 0;
if (all_vector.size() != 1) {
printf("ERROR: data for US keyboard not correct\n");
return 1;
@ -170,16 +153,7 @@ bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout) {
return 0;
}
/** old
* @brief return the keyvalue for a given Keycode, shiftstate and caps of the currently used (underlying) keyboard Layout
* What character will be produced for a keypress of a key and modifiers?
* @param keyboard_layout the currently used (underlying)keyboard Layout
* @param keycode a key of the currently used keyboard Layout
* @param shiftstate_mac a shiftstate of the currently used keyboard Layout
* @param caps state of the caps key of the currently used keyboard Layout
* @return the keyval obtained from Keycode, shiftstate and caps
*/
/** @brief return the keyvalue for a given Keycode, shiftstate and caps */
/** @brief return the keyvalue for a given Keycode, shiftstate and caps */
KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps) {
UInt32 deadkeystate;
UniCharCount maxStringlength = 5;
@ -189,13 +163,16 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou
OSStatus status;
unicodeString[0] = 0;
//if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps))
if (!ensureValidInputForKeyboardTranslation(shiftstate_mac, keycode))
return 0;
/*
UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^'
if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6
*/
status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString);
// If this was a deadkey,append a space
// If this was a deadkey (deadkeystate != 0), append a space
if (deadkeystate != 0)
status = UCKeyTranslate(keyboard_layout, keycode_spacebar, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString);
@ -209,7 +186,7 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layou
return 0;
}
//_S2 ToDO
/** @brief return the keyvalue for a given Keycode, shiftstate and caps */
KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32& deadkeystate) {
UniCharCount maxStringlength = 5;
UniCharCount actualStringlength = 0;
@ -218,22 +195,14 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la
unicodeString[0] = 0;
OSStatus status;
/*if (!keyboard_layout)
return 0;
if (!(keycode <= keycode_max))
return 0;
if (!(shiftstate_mac <= max_shiftstate))
return 0;
if (!(caps <= 1))
return 0;*/
//if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, shiftstate_mac, caps))
if (!ensureValidInputForKeyboardTranslation(shiftstate_mac, keycode))
return 0;
// if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6
/*
UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^'
if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6
*/
status = UCKeyTranslate(keyboard_layout, keycode, kUCKeyActionDown, (shiftstate_mac + 4 * caps), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString);
// If this was a deadkey,append a space
@ -247,21 +216,19 @@ KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_la
return unicodeString[0]; // combined char e.g. â
}
/** @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout and copy deadkey into deadKey */
/** @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout. */
KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey) {
PKMX_WCHAR dky = NULL;
UInt32 isdk = 0;
KMX_DWORD keyV;
int caps = 0;
// _S2 WOW NO! convert??
//if (!ensureValidInputForKeyboardTranslation(keyboard_layout, kc_underlying, is_correct_win_shiftstate(vk_ShiftState)))
if (!ensureValidInputForKeyboardTranslation(mac_convert_Shiftstate_to_MacShiftstate(vk_ShiftState), kc_underlying))
return 0;
keyV = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, kc_underlying, (mac_convert_Shiftstate_to_MacShiftstate(vk_ShiftState)), caps, isdk);
// if there was a deadkey return 0xFFFF and copy deadkey into dky
// if there was a deadkey return 0xFFFF and copy deadkey into dky; else return the keyvalue
if (isdk != 0) {
dky = (PKMX_WCHAR)(std::u16string(1, keyV)).c_str();
*deadKey = *dky;
@ -272,7 +239,7 @@ KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLa
}
/** @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard */
KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us) {
KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us) {
// look for kv_us for any shiftstate of US keyboard
for (int i = 0; i < (int)all_vector[0].size() - 1; i++) {
for (int j = 1; j < (int)all_vector[0][0].size(); j++) {
@ -283,16 +250,8 @@ KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, K
return kv_us;
}
// _S2 ToDo
/** old
*
* @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard
* On what key of the underlying keyboard do we find a certain character?
* @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard
* @param kv_underlying a keyvalue on the currently used (underlying) keyboard
* @return keycode of the underlying keyboardif foundf; else the keyval of the underlying keyboard
*/
KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying) {
/** @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard */
KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying) {
// look for kv_us for any shiftstate of US keyboard
for (int i = 0; i < all_vector[1].size() - 1; i++) {
for (int j = 1; j < all_vector[1][0].size(); j++) {
@ -303,47 +262,38 @@ KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_
}
return kv_underlying;
}
/** @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard */
/** @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard */
KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps) {
// first get the keyvalue of the key on the US keyboard (kc_us)
std::u16string u16str = std::u16string(1, mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_win), caps));
KMX_DWORD kv = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, kc_us, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_win), caps);
//_S2
// then find the same keyvalue on the underlying keyboard and return the keycode of that key on the underlying keyboard
for (int i = 0; i < (int)all_vector[1].size() - 1; i++) {
for (int j = 1; j < (int)all_vector[1][0].size(); j++) {
if (all_vector[1][i][j] == (KMX_DWORD)*u16str.c_str())
//if (all_vector[1][i][j] == (KMX_DWORD)*u16str.c_str())
if (all_vector[1][i][j] == kv)
return all_vector[1][i][0];
}
}
return kc_us;
}
/** @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard */
UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us) {
KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us) {
// on the mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an 'artificial' us virtual key
return (mac_USVirtualKeyToScanCode[vk_us]);
}
/** @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard */
/** @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard */
KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode) {
// on the mac virtual keys do not exist. Nevertheless we can use this mapping to obtain an keycode from an 'artificial' us virtual key
return mac_ScanCodeToUSVirtualKey[keycode];
}
//_S2 TODO
/** old
*
* @brief return the keyvalue of a combination of deadkey + character if there is a combination available
* What character will be produced for a deadkey + a character?
* @param vk_dk a keycode of a deadkey on the currently used (underlying) keyboard
* @param ss a shiftstate of a deadkey on the currently used (underlying) keyboard
* @param keyboard_layout the currently used (underlying)keyboard Layout
* @param vk_us a keycode of a character key on the currently used (underlying) keyboard
* @param shiftstate_mac a shiftstate of a character key on the currently used (underlying) keyboard
* @param caps state of the caps key of a character key on the currently used (underlying) keyboard
* @return the combination of deadkey + character if it is available; if not return 0
*/
KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps) {
/** @brief return the keyvalue of a combination of deadkey + character if there is a combination available */
KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, int vk_dk, KMX_DWORD ss_dk, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps) {
UInt32 deadkeystate;
UniCharCount maxStringlength = 5;
UniCharCount actualStringlength = 0;
@ -352,11 +302,16 @@ KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeybo
unicodeString[0] = 0;
OSStatus status;
/*
UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a base character (vk_us) to get the combined dk e.g.'Â'
if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6
*/
status = UCKeyTranslate(keyboard_layout, vk_dk, kUCKeyActionDown, ss_dk, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString);
// If this was a deadkey,append a character
// If this was a deadkey, append a character
if (deadkeystate != 0) {
status = UCKeyTranslate(keyboard_layout,(UInt16) vk_us, kUCKeyActionDown, shiftstate_mac+4*caps, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString);
status = UCKeyTranslate(keyboard_layout, vk_us, kUCKeyActionDown, shiftstate_mac + 4 * caps, LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString);
if (unicodeString[0] == 1) // impossible character
return 0;
@ -381,11 +336,3 @@ void test_printoutKeyboards_S2(vec_dword_3D& all_vector) {
}
}
/*bool is_correct_mac_shiftstate(int win_ss) {
return ( (win_ss ==0) || (win_ss ==2) || (win_ss ==8) || (win_ss ==10) );
}*/
/*bool is_correct_rgkey_shiftstate(int win_ss) {
return ( (win_ss ==0) || (win_ss ==1) || (win_ss ==6) || (win_ss ==7) );
}*/

View file

@ -49,7 +49,8 @@ const KMX_DWORD KMX_VKMap[] = {
VK_xDF, /* ß (?) 223*/
VK_OEM_102, /* < > | 226 */
0};
0};
typedef std::vector<std::string> vec_string_1D;
typedef std::vector<KMX_DWORD> vec_dword_1D;
@ -65,41 +66,39 @@ static int MAC_BASE = 0;
static int MAC_SHIFT = 2;
static int MAC_OPT = 8;
static int MAC_SHIFT_OPT = 10;
/**
* @brief map a shiftstate used on windows to a shiftstate suitable for UCKeyTranslate() on the mac
* Windows: (Base: 00000000 (0); Shift 00010000 (16); AltGr 00001001 (9); Shift+AltGr 00011001 (25))
* mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10 )
* mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10 )
* @param shiftState shiftstate used on windows
* @return a shiftstate usable for UCKeyTranslate() on mac if available
* if shiftState is a windows ShiftState: convert the windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10)
* if shiftState is NOT a windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate
*/
int mac_convert_Shiftstate_to_MacShiftstate(int shiftState);
/**
* @brief map a shiftstate used in rgkey ( a vector of VirtualKey*) to a shiftstate suitable for UCKeyTranslate() on the mac
* @brief map a shiftstate used in rgkey (a vector of VirtualKey*) to a shiftstate suitable for UCKeyTranslate() on the mac
* rgkey: (Base: 0; Shift 1; OPT 6; Shift+OPT 7 )
* mac: (Base: 0; Shift 2; OPT 8; Shift+OPT 10)
* @param shiftState shiftstate used in rgkey
* @param rgkey_ShiftState shiftstate used in rgkey
* @return a shiftstate usable for UCKeyTranslate() on mac if available
* if shiftState is a windows ShiftState: convert the windows ShiftState (0,16,9,25) to a mac ShiftState (0,2,8,10)
* if shiftState is NOT a windows ShiftState (then in_ShiftState is already a mac shiftstate): return the entered shiftstate
*/
int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int win_ShiftState);
// _S2 TODO
bool is_correct_win_shiftstate(int comp_ss);
int mac_convert_rgkey_Shiftstate_to_MacShiftstate(int rgkey_ShiftState);
/**
* @brief check for correct input parameter that will later be used in UCKeyTranslate()
* @brief check for correct input parameters that will later be used in UCKeyTranslate()
* @param shiftstate the currently used shiftstate
* @param keycode the code of the key in question
* @return true if all parameters are OK; false if not
*/
bool ensureValidInputForKeyboardTranslation(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate, int cap);
bool ensureValidInputForKeyboardTranslation(int shiftstate,int keycode);
// _S2 TODO
bool ensureValidInputForKeyboardTranslation(int shiftstate, int keycode);
/**
* @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard :
* @brief create a 3D-Vector containing data of the US keyboard and the currently used (underlying) keyboard
* all_vector [ US_Keyboard ]
* [KeyCode_US ]
* [Keyval unshifted ]
@ -109,42 +108,48 @@ bool ensureValidInputForKeyboardTranslation(int shiftstate,int keycode);
* [Keyval unshifted ]
* [Keyval shifted ]
* @param[in,out] all_vector Vector that holds the data of the US keyboard as well as the currently used (underlying) keyboard
* @param keyboard_layout ptr to currently used (underlying) keyboard layout
* @param keyboard_layout pointer to currently used (underlying) keyboard layout
* @return 0 on success; 1 if data of US keyboard was not written; 2 if data of underlying keyboard was not written
*/
int mac_createOneVectorFromBothKeyboards(vec_dword_3D &all_vector, const UCKeyboardLayout * keyboard_layout);
int mac_createOneVectorFromBothKeyboards(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout);
/**
* @brief write data of the US keyboard into a 3D-Vector which later will contain
* data of the US keyboard and the currently used (underlying) keyboard
* @param[in,out] vec Vector that holds the data of the US keyboard
* @param[in,out] vec_us Vector that holds the data of the US keyboard
* @return 0 on success; 1 if data of US keyboard was not written;
*/
int mac_write_US_ToVector(vec_dword_3D &vec);
int mac_write_US_ToVector(vec_dword_3D& vec_us);
/**
* @brief create an 2D-Vector with all fields containing INVALID_NAME
* @brief create an 2D-Vector with all fields initialized to INVALID_NAME
* @param dim_rows number of rows in vector
* @param dim_ss number of columns in vector
* @return the 2D-Vector
*/
vec_dword_2D mac_create_empty_2D_Vector(int dim_rows, int dim_ss);
/**
* @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector
/**
* @brief append a 2D-vector containing data of the currently used (underlying) keyboard to the 3D-vector all_vector
* @param[in,out] all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard
* @param keyboard_layout ptr to currently used (underlying) keybord layout
* @param keyboard_layout pointer to currently used (underlying) keybord layout
* @return 0 on success;
* 1 if the initialization of the underlying vector failes;
* 2 if data of less than 2 keyboards is contained in all_vector;
*/
int mac_append_underlying_ToVector(vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout);
/**
* @brief create a pointer to pointer of the current keyboard_layout for later use
* @param keyboard_layout ptr to ptr to currently used (underlying) keyborad layout
* @param keyboard_layout pointer to pointer to currently used (underlying) keyborad layout
* @return 0 on success; 1 if the display is not found; 2 if the keymap is not found
*/
bool mac_InitializeUCHR(const UCKeyboardLayout** keyboard_layout);
// we use the same type of array as throughout Keyman even though we have lots of unused fields
/**
* @brief array of USVirtualKey-ScanCode-pairs
* we use the same type of array as throughout Keyman even though we have lots of unused fields
*/
const UINT mac_USVirtualKeyToScanCode[256] = {
0xFFFF, // not used
0xFFFF, // not used
@ -404,8 +409,10 @@ const UINT mac_USVirtualKeyToScanCode[256] = {
0xFFFF, // not used
};
// we use the same type of array as throughout Keyman even though we have lots of unused fields
/**
* @brief array of ScanCode-USVirtualKey-pairs
* we use the same type of array as throughout Keyman even though we have lots of unused fields
*/
const UINT mac_ScanCodeToUSVirtualKey[128] = {
0x41, // L"K_A", // &H41
0x53, // L"K_S", // &H53
@ -536,91 +543,105 @@ const UINT mac_ScanCodeToUSVirtualKey[128] = {
0x00, // not used
0x00, // not used
};
// _S2 TODO IsKeymanUsedChar()??
// _S2 TODO convert_DeadkeyValues_To_U16str??
/**
* @brief return the keyvalue for a given Keycode, shiftstate and caps of the
* currently used (underlying) keyboard layout
* "What character will be produced for a keypress of a key and modifiers?"
* "What character will be produced for a keypress of a key and modifier?"
* @param keyboard_layout pointer to the currently used (underlying) keyboard layout
* @param keycode a key of the currently used keyboard layout
* @param ss a (windows-)shiftstate of the currently used keyboard layout _S2
* @param shiftstate_mac a shiftstate of the currently used keyboard layout
* @param caps state of the caps key of the currently used keyboard layout
* @return the keyval obtained from keycode, shiftstate and caps
*/
// _S2 ShiftState ss vs int shiftstate_mac
KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps);
//_S2 TODO
KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32& deadkeystate);
/** // _S2 shift_state_pos vs int shiftstate_mac
* @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout.
* "What character will be produced for a keypress of a key and modifiers on the underlying keyboard?"
* @param keyboard_layout a pointer to the currently used (underlying) keyboard layout
* @param keycode a key of the currently used keyboard
* @param shift_state_pos a shiftstate of the currently used keyboard layout
* @return the keyval obtained from Keycode and shiftstate;
/**
* @brief return the keyvalue for a given Keycode, shiftstate and caps of the
* currently used (underlying) keyboard layout taking dk into account
* "What character will be produced for a keypress of a key and modifiers?
* @param keyboard_layout pointer to the currently used (underlying) keyboard layout
* @param keycode a key of the currently used keyboard layout
* @param shiftstate_mac a shiftstate of the currently used keyboard layout
* @param caps state of the caps key of the currently used keyboard layout
* @param[in,out] deadkeystate states wheter a deadkey was used or not
* @return the keyval obtained from keycode, shiftstate and caps
*/
KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac);
KMX_DWORD mac_KMX_get_KeyVal_From_KeyCode_dk(const UCKeyboardLayout* keyboard_layout, int keycode, int shiftstate_mac, int caps, UInt32& deadkeystate);
/**
* @brief return the keyvalue for a given Keycode and shiftstate of the currently used (underlying) keyboard layout.
* "What character will be produced for a keypress of a key and modifiers on the underlying keyboard?
* If a deadkey was found return 0xFFFF and copy the deadkey into deadKey
* This function is similar to KMX_DWORD KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(GdkKeymap* keymap, guint keycode, int shiftState)
* but processes deadkeys
* @param keyboard_layout a pointer to the currently used (underlying) keyboard layout
* @param keycode a key of the currently used keyboard
* @param shiftState a shiftstate of the currently used keyboard layout
* @param deadKey* ptr to keyvalue if a deadkey was found; if not NULL
* @return 0xFFFF in case a deadkey was found, then the deadkey is stored in deadKey
* the keyval obtained from Keycode and shiftstate and caps;
* @param kc_underlying a key of the currently used keyboard
* @param vk_ShiftState a shiftstate of the currently used keyboard layout
* @param deadKey pointer to keyvalue if a deadkey was found; if not NULL
* @return 0xFFFF in case a deadkey was found, then the deadkey is stored in deadKey;
* or else the keyval obtained from Keycode and shiftstate and caps;
*/
KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, UINT keycode, UINT shiftState, PKMX_WCHAR deadKey);
KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyCodeUnderlying(const UCKeyboardLayout* keyboard_layout, UINT kc_underlying, UINT vk_ShiftState, PKMX_WCHAR deadKey);
/**
* @brief return the keyvalue of a key of the the currently used (underlying) keyboard for a given keyvalue of the US keyboard
* "What character is on the same position/shiftstats/caps on the currently used (underlying) keyboard?"
* "What character is on the same position/shiftstats/caps on the currently used (underlying) keyboard as on the US keyboard?"
* @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard
* @param kv_us a keyvalue on the US keyboard
* @return keyval of the underlying keyboard if available; else the keyval of the US keyboard
*/
KMX_WCHAR mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us);
KMX_DWORD mac_KMX_get_KeyValUnderlying_From_KeyValUS(vec_dword_3D& all_vector, KMX_DWORD kv_us);
/**
* @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard
* @brief return the keycode of the currently used (underlying) keyboard for a given keyvalue of the underlying keyboard
* On what key of the underlying keyboard do we find a certain character?
* @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard
* @param kv_underlying a keyvalue on the currently used (underlying) keyboard
* @return keycode of the underlying keyboard if foundf; else the keyval of the underlying keyboard
*/
KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying);
/**
* @brief return the keycode of the currently used (underlying) keyboard for a given keycode of the US keyboard -> it`s the same!!
* "Where on an underlying keyboard do we find a character that is on a certain key on a US keyboard?"
* @param keyboard_layout the currently used (underlying) keyboard layout
* @param all_vector 3D-vector that holds the data of the US keyboard and the currently used (underlying) keyboard
* @param kc_us a key of the US keyboard
* @param ss a windows-type shiftstate
* @param ss_win a windows-type shiftstate
* @param caps state of the caps key
* @return the keycode of the underlying keyboard if found; else the keycode of the US keyboard
*/
KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss, int caps);
KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_DWORD kc_us, ShiftState ss_win, int caps);
/**
* @brief return the keycode of the currently used (underlying) keyboard for a given virtual key of the US keyboard
* "Which keycode of an underlying keyboard will be mapped to a virtuaĺ key of a US keyboard?"
* @param virtualKeyUS a virtual key of the US keyboard
* "Where on an underlying keyboard do we find a character of a US keyboard?"
* @param vk_us a virtual key of the US keyboard
* @return the keycode of the currently used (underlying) keyboard
*/
UINT mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD virtualKeyUS);
KMX_DWORD mac_KMX_get_KeyCodeUnderlying_From_VKUS(KMX_DWORD vk_us);
/**
/**
* @brief return a virtual key of the US keyboard for a given keycode of the currently used (underlying) keyboard
* "Which key of a underlying keyboard will be mapped to a virtual key of a US keyboard?"
* "Which character is found on a key of the US keyboard?"
* @param keycode a keycode of the currently used (underlying) keyboard
* @return the virtual key of the US keyboard or 0
*/
KMX_DWORD mac_KMX_get_VKUS_From_KeyCodeUnderlying(KMX_DWORD keycode);
//_S2 TODO
KMX_WCHAR mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(vec_dword_3D& all_vector, KMX_DWORD kv_underlying);
//_S2 TODO
KMX_DWORD mac_get_CombinedChar_From_DK(int vk_dk, KMX_DWORD ss_dk, const UCKeyboardLayout* keyboard_layout, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps);
/**
* @brief return the keyvalue of a combination of deadkey + character if there is a combination available
* "What character will be produced for a deadkey + a character?" e.g. '^' + 'a' -> 'â'
* @param keyboard_layout the currently used (underlying)keyboard Layout
* @param vk_dk a keycode of a deadkey of the currently used (underlying) keyboard
* @param ss_dk a shiftstate of a deadkey of the currently used (underlying) keyboard
* @param vk_us a keycode of a character key on the currently used (underlying) keyboard to be combined to a dk
* @param shiftstate_mac a shiftstate of a character key on the currently used (underlying) keyboard
* @param caps state of the caps key of a character key on the currently used (underlying) keyboard
* @return the combination of deadkey + character if it is available; if not return 0
*/
KMX_DWORD mac_get_CombinedChar_From_DK(const UCKeyboardLayout* keyboard_layout, int vk_dk, KMX_DWORD ss_dk, KMX_DWORD vk_us, KMX_DWORD shiftstate_mac, int caps);
//_S2 TODO CodePointToU16String??
//################################################################################################################################################
//################################################################################################################################################
@ -632,4 +653,4 @@ KMX_DWORD X_compare_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboa
KMX_DWORD X_find_Shiftstates_S2(int shiftstate,const UCKeyboardLayout* keyboard_layout , KMX_DWORD charVal=0);
KMX_DWORD printout_dk(const UCKeyboardLayout* keyboard_layout);
#endif // KEYMAP_H
#endif /*KEYMAP_H*/

View file

@ -1,7 +1,7 @@
/*
* Keyman is copyright (C) 2004 SIL International. MIT License.
*
* Mnemonic layout support for Linux
* Mnemonic layout support for mac
*/
@ -28,7 +28,7 @@ DeadKey::DeadKey(KMX_WCHAR deadCharacter) {
this->m_deadchar = deadCharacter;
}
/** @brief return character */
/** @brief return dead character */
KMX_WCHAR DeadKey::KMX_DeadCharacter() {
return this->m_deadchar;
}
@ -53,22 +53,12 @@ bool DeadKey::KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter) {
bool test_alDead_S2(std::vector<DeadKey*> ald);
/** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function.
* Contrary to what the function name might suggest, the function the mac_KMX_ToUnicodeEx does NOT process surrogate pairs.
* This is because it is used in mcompile only which only deals with latin scripts.
* In case this function is used for surrogate pairs, they will be ignored and a message will be printed out
* @param keycode a key of the currently used keyboard Layout
* @param pwszBuff Buffer to store resulting character
* @param ss_win a windows-style shiftstate of the currently used keyboard Layout
* @param caps state of the caps key of the currently used keyboard Layout
* @param keyboard_layout the currently used (underlying)keyboard Layout
* @return -1 if a deadkey was found; 0 if no translation is available; +1 if character was found and written to pwszBuff
*/
/** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function. */
int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, ShiftState ss_rgkey, int caps, const UCKeyboardLayout* keyboard_layout) {
KMX_DWORD keyval;
UInt32 isdk = 0;
if (!ensureValidInputForKeyboardTranslation(keyboard_layout, keycode, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_rgkey), caps))
if (!ensureValidInputForKeyboardTranslation(mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_rgkey),keycode))
return 0;
keyval = mac_KMX_get_KeyVal_From_KeyCode_dk(keyboard_layout, keycode, mac_convert_rgkey_Shiftstate_to_MacShiftstate(ss_rgkey), caps, isdk);
@ -84,6 +74,7 @@ int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, ShiftState ss_rgkey, i
if (u16len(pwszBuff) < 1)
return 0;
if ((isdk) && (keycode != 0xFFFF)) // deadkeys
return -1;
if (keyval == 0) // no character
@ -101,7 +92,7 @@ KMX_WCHAR mac_KMX_DeadKeyMap(int index, std::vector<DeadKey*>*deadkeys, int dead
for (size_t i = 0; i < deadkeys->size(); i++) {
if ((*deadkeys)[i]->KMX_DeadCharacter() == index) {
return (KMX_WCHAR)deadkeyBase + i;
return (KMX_WCHAR)(deadkeyBase + i);
}
}
return 0xFFFF;
@ -122,10 +113,12 @@ public:
memset(this->m_rgfDeadKey, 0, sizeof(this->m_rgfDeadKey));
}
/** @brief return member variable virtual key */
UINT VK() {
return this->m_vk;
}
/** @brief return member variable scancode */
UINT SC() {
return this->m_sc;
}
@ -197,6 +190,7 @@ public:
return true;
}
/** @brief check if we use only keys used in mcompile */
bool mac_KMX_IsKeymanUsedKey() {
return (this->m_vk >= 0x20 && this->m_vk <= 0x5F) || (this->m_vk >= 0x88);
}
@ -205,6 +199,7 @@ public:
return KMX_ShiftStateMap[(int)ss] | (capslock ? (caps ? CAPITALFLAG : NOTCAPITALFLAG) : 0);
}
/** @brief count the number of keys */
int mac_KMX_GetKeyCount(int MaxShiftState) {
int nkeys = 0;
@ -216,7 +211,7 @@ public:
}
for (int caps = 0; caps <= 1; caps++) {
std::u16string st = this->mac_KMX_GetShiftState((ShiftState)ss, (caps == 1));
// ctrl and sh+ctrl will be skipped since rgkey has no entries in m_rgss[2] m_rgss[3]
// ctrl and shift+ctrl will be skipped since rgkey has no entries in m_rgss[2] m_rgss[3]
if (st.size() == 0) {
// No character assigned here
} else if (this->m_rgfDeadKey[(int)ss][caps]) {
@ -240,6 +235,7 @@ public:
return nkeys;
}
/** @brief edit the row of kmx-file */
bool mac_KMX_LayoutRow(int MaxShiftState, LPKMX_KEY key, std::vector<DeadKey*>*deadkeys, int deadkeyBase, BOOL bDeadkeyConversion, vec_dword_3D& all_vector, const UCKeyboardLayout* keyboard_layout) { // I4552
// Get the CAPSLOCK value
/*int capslock =
@ -294,14 +290,16 @@ public:
}
}
if (isvalid) {
// this is different to mcompile windows !!!!
// this->m_sc stores SC-US = SCUnderlying
// this->m_vk stores VK-US ( not underlying !!)
// key->Key stores VK-US ( not underlying !!)
// key->dpOutput stores character Underlying
KMX_DWORD SC_Underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keyboard_layout, all_vector, this->SC(), (ShiftState)ss, caps);
/*
* this is different to mcompile windows !!!!
* this->m_sc stores SC-US = SCUnderlying
* this->m_vk stores VK-US ( not underlying !!)
* key->Key stores VK-US ( not underlying !!)
* key->dpOutput stores character Underlying
*/
KMX_DWORD sc_underlying = mac_KMX_get_KeyCodeUnderlying_From_KeyCodeUS(keyboard_layout, all_vector, this->SC(), (ShiftState)ss, caps);
key->Key = mac_KMX_get_VKUS_From_KeyCodeUnderlying(SC_Underlying);
key->Key = mac_KMX_get_VKUS_From_KeyCodeUnderlying(sc_underlying);
key->Line = 0;
key->ShiftFlags = this->KMX_GetShiftStateValue(capslock, caps, (ShiftState)ss);
@ -320,6 +318,7 @@ public:
}
return true;
}
};
/** @brief Base class for KMX_loader*/
@ -357,21 +356,21 @@ public:
bool fCapsLock, // Was the caps lock key pressed?
const UCKeyboardLayout* keyboard_layout) { // The keyboard layout
int maxshiftstate = 2; //_S2 MAC_SHIFT??
int max_shiftstate_pos = 1; // use BASE + SHIFT only
DeadKey* deadKey = new DeadKey(rgKey[iKeyDead]->mac_KMX_GetShiftState(shiftStateDead, fCapsLock)[0]);
int ss_dead = mac_convert_rgkey_Shiftstate_to_MacShiftstate(shiftStateDead);
KMX_DWORD keyval_underlying_dk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, mac_USVirtualKeyToScanCode[iKeyDead], ss_dead, 0);
for (int i = 0; i < keycode_spacebar + 1; i++) {
for (int j = 0; j < maxshiftstate; j++) {
for (int j = 0; j <= max_shiftstate_pos; j++) {
for (int caps = 0; caps < 1; caps++) {
// e.g. a basechar
KMX_DWORD basechar = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[j], caps);
// e.g. â combchar
KMX_DWORD KC_Underlying_dk = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKeyDead);
KMX_DWORD combchar = mac_get_CombinedChar_From_DK(KC_Underlying_dk, ss_dead, keyboard_layout, i, ss_mac[j], caps);
KMX_DWORD kc_Underlying_dk = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKeyDead);
KMX_DWORD combchar = mac_get_CombinedChar_From_DK(keyboard_layout, kc_Underlying_dk, ss_dead, i, ss_mac[j], caps);
if (combchar == 0)
continue;
@ -386,14 +385,6 @@ public:
}
return deadKey;
}
/*void ClearKeyboardBuffer(UINT vk, UINT sc, HKL hkl) {
WCHAR sb[16];
int rc = 0;
do {
rc = ::ToUnicodeEx(vk, sc, lpKeyStateNull, sb, _countof(sb), 0, hkl);
} while (rc != 1 && rc != 0);
}*/
};
/**
@ -416,13 +407,13 @@ int mac_KMX_GetMaxDeadkeyIndex(KMX_WCHAR* p) {
//################################################################################################################################################
bool test_run_verify_S2(std::vector<mac_KMX_VirtualKey*> rgKey);
// _S2 need to go
void test_print_All_Entries_S2(std::vector<mac_KMX_VirtualKey*> rgKey);
bool test_run_verify_S2(std::vector<mac_KMX_VirtualKey*> rgKey);
void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout);
void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode);
//void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout);
//void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode);
/**
/**
* @brief Collect the key data, translate it to kmx and append to the existing keyboard
* It is important to understand that this function has different sorting order in rgkey compared to mcompile-windows!
* On windows the values of rgkey are sorted according to the VK of the underlying keyboard
@ -450,15 +441,15 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK
//Windows and Linux Keycodes start with 1; Mac keycodes start with 0
for (UINT sc = 0x00; sc <= 0x7f; sc++) {
// HERE IS A BIG DIFFERENCE COMPARED TO MCOMPILE FOR WINDOWS:
// mcompile on Windows fills rgkey.m_vk with the VK of the Underlying keyboard
// mcompile for macOS fills rgkey.m_vk with the VK of the US keyboard
// this results in a different sorting order in rgkey[] !
// macOS cannot get a VK for the underling Keyboard since this does not exist
// macOS can only get a VK for the US Keyboard (by using USVirtualKeyToScanCode/ScanCodeToUSVirtualKey)
// therefore in rgkey[ ] we use VK_US which we get from all_vector
/* HERE IS A BIG DIFFERENCE COMPARED TO MCOMPILE FOR WINDOWS:
* mcompile on Windows fills rgkey.m_vk with the VK of the Underlying keyboard
* mcompile for macOS fills rgkey.m_vk with the VK of the US keyboard
* this results in a different sorting order in rgkey[] !
* macOS cannot get a VK for the underling Keyboard since this does not exist
* macOS can only get a VK for the US Keyboard (by using USVirtualKeyToScanCode/ScanCodeToUSVirtualKey)
* therefore in rgkey[ ] we use VK_US which we get from all_vector
*/
mac_KMX_VirtualKey* key = new mac_KMX_VirtualKey(sc);
if ((key->VK() != 0)) {
@ -478,15 +469,15 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK
continue;
}
//_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!!
if (ss == MenuCtrl || ss == ShftMenuCtrl) {
//_S2 TOP_6 TODO to compare win-lin kmn-files skip ss6+7; MUST BE removed later!!!!
/*if (ss == MenuCtrl || ss == ShftMenuCtrl) {
continue;
}
}*/
KMX_DWORD KC_US = (KMX_DWORD)mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey);
KMX_DWORD kc_underlying = mac_KMX_get_KeyCodeUnderlying_From_VKUS(iKey);
for (int caps = 0; caps <= 1; caps++) {
int rc = mac_KMX_ToUnicodeEx(KC_US, sbBuffer, ss, caps, *keyboard_layout);
int rc = mac_KMX_ToUnicodeEx(kc_underlying, sbBuffer, ss, caps, *keyboard_layout);
if (rc > 0) {
if (*sbBuffer == 0) {
@ -688,8 +679,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK
KMX_WCHAR* p = kkp->dpContext = new KMX_WCHAR[8];
*p++ = UC_SENTINEL;
*p++ = CODE_DEADKEY;
*p++ = mac_KMX_DeadKeyMap(dk->KMX_DeadCharacter(), &alDead, nDeadkey, FDeadkeys); // I4353
*p++ = mac_KMX_DeadKeyMap(dk->KMX_DeadCharacter(), &alDead, nDeadkey, FDeadkeys); // I4353
// *p++ = nDeadkey+i;
*p++ = UC_SENTINEL;
*p++ = CODE_ANY;
@ -708,6 +698,7 @@ bool mac_KMX_ImportRules( LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, const UCK
return true;
}
// _S2 need to go
void print_entries_S2(int i, std::vector<mac_KMX_VirtualKey*> rgKey , std::string comp1,std::string comp2,std::string erg) {
std::string b0 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 0 ));
std::string b1 =string_from_u16string(rgKey[i]->mac_KMX_GetShiftState(Base, 1 ));
@ -762,7 +753,7 @@ void test_print_All_Entries_S2( std::vector<mac_KMX_VirtualKey*> rgKey) {
print_entries_S2(222, rgKey, "ä", "Ä", "ä Ä Ä Ä");
print_entries_S2(226, rgKey, "<", ">", "< < > >");
}
void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode) {
/*void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int keycode) {
UniCharCount maxStringlength = 5;
UniCharCount actualStringlength = 0;
UniChar unicodeString[maxStringlength];
@ -784,7 +775,8 @@ void test_print_certain_Keys_S2(const UCKeyboardLayout * keyboard_layout, int ke
}
}
}
void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout){
*/
/*void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout){
UniCharCount maxStringlength = 5;
UniCharCount actualStringlength = 0;
UniChar unicodeString[maxStringlength];
@ -808,6 +800,7 @@ void test_print_All_Keys_S2(const UCKeyboardLayout * keyboard_layout){
}
}
}
*/
bool test_checkBasechar_S2 (DeadKey* DK, int index, KMX_WCHAR ch) {
return ( DK->KMX_GetBaseCharacter(index) == ch) ;
}

View file

@ -3,8 +3,20 @@
#ifndef MC_IMPORT_RULES_H
#define MC_IMPORT_RULES_H
int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int shift_state_pos, int caps, const UCKeyboardLayout* keyboard_layout);
/** @brief Find a keyvalue for given keycode, shiftstate and caps. A function similar to Window`s ToUnicodeEx() function.
* Contrary to what the function name might suggest, the function the mac_KMX_ToUnicodeEx does NOT process surrogate pairs.
* This is because it is used in mcompile only which only deals with latin scripts.
* In case this function is used for surrogate pairs, they will be ignored and a message will be printed out
* @param keycode a key of the currently used keyboard Layout
* @param pwszBuff Buffer to store resulting character
* @param ss_rgkey a windows-style shiftstate of the currently used keyboard Layout
* @param caps state of the caps key of the currently used keyboard Layout
* @param keyboard_layout the currently used (underlying)keyboard Layout
* @return -1 if a deadkey was found;
* 0 if no translation is available;
* +1 if character was found and written to pwszBuff
*/
int mac_KMX_ToUnicodeEx(int keycode, PKMX_WCHAR pwszBuff, int ss_rgkey, int caps, const UCKeyboardLayout* keyboard_layout);
/** @brief Base class for Deadkey*/
class DeadKey {
@ -14,48 +26,53 @@ private:
std::vector<KMX_WCHAR> m_rgcombchar;
public:
/**
* @brief Constructor
* @param deadCharacter a deadkey
*/
/**
* @brief Constructor
* @param deadCharacter a deadkey
*/
DeadKey(KMX_WCHAR deadCharacter);
/**
* @brief return dead character
* @return deadkey character
*/
KMX_WCHAR KMX_DeadCharacter();
/**
* @brief return dead character
* @return deadkey character
*/
KMX_WCHAR KMX_DeadCharacter();
/**
* @brief set Deadkey with values
* @param baseCharacter the base character
* @param combinedCharacter the combined character
* @return void
*/
/**
* @brief set member variable with base and combined character
* @param baseCharacter the base character
* @param combinedCharacter the combined character
* @return void
*/
void KMX_AddDeadKeyRow(KMX_WCHAR baseCharacter, KMX_WCHAR combinedCharacter);
/** @brief return size of array of basecharacters */
int KMX_Count() {
return this->m_rgbasechar.size();
}
/** @brief get member variable m_deadchar */
KMX_WCHAR KMX_GetDeadCharacter() {
return this->m_deadchar;
}
/** @brief return base character at index */
KMX_WCHAR KMX_GetBaseCharacter(int index) {
return this->m_rgbasechar[index];
}
/** @brief return combined character at index */
KMX_WCHAR KMX_GetCombinedCharacter(int index) {
return this->m_rgcombchar[index];
}
/**
* @brief check if character exists in DeadKey
* @param baseCharacter
* @param baseCharacter a character to be found
* @return true if found; false if not found
*/
bool KMX_ContainsBaseCharacter(KMX_WCHAR baseCharacter);
};
#endif // MC_IMPORT_RULES_H
#endif /*MC_IMPORT_RULES_H*/

View file

@ -1,3 +1,8 @@
/*
* Keyman is copyright (C) SIL International. MIT License.
*
* Mnemonic layout support for mac
*/
#include "mc_kmxfile.h"
#include <typeinfo>
@ -36,8 +41,32 @@ const int CODE__SIZE[] = {
2 // CODE_SETSYSTEMSTORE 0x18
};
KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug) {
/**
* @brief check if the file has correct version
* @param filebase containing data of the input file
* @param file_size a size
* @return true if successful; false if not
*/
KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size);
/**
* @brief Fixup the keyboard by expanding pointers. On disk the pointers are stored relative to the
* beginning of the file, but we need real pointers. This method is used on 32-bit architectures.
* @param bufp pointer to buffer where data will be copied into
* @param base pointer to starting point
* @param dwFileSize size of the file
* @return pointer to the keyboard
*/
LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize);
/**
* @brief Save a Keyboard to a file
* @param fk pointer to the keyboard
* @param hOutfile pointer to the output file
* @param FSaveDebug
* @return an Error in case of failure
*/
KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX_BOOL FSaveDebug) {
LPKMX_GROUP fgp;
LPKMX_STORE fsp;
LPKMX_KEY fkp;
@ -60,28 +89,27 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX
//wcslen(fk->szMessage)*2 + 2 +
fk->dwBitmapSize;
for(i = 0, fgp = fk->dpGroupArray; i < fk->cxGroupArray; i++, fgp++) {
if(fgp->dpName)
for (i = 0, fgp = fk->dpGroupArray; i < fk->cxGroupArray; i++, fgp++) {
if (fgp->dpName)
size += (u16len(fgp->dpName) + 1) * sizeof(KMX_WCHAR);
size += fgp->cxKeyArray * sizeof(KMX_COMP_KEY);
for(j = 0, fkp = fgp->dpKeyArray; j < fgp->cxKeyArray; j++, fkp++) {
for (j = 0, fkp = fgp->dpKeyArray; j < fgp->cxKeyArray; j++, fkp++) {
size += (u16len(fkp->dpOutput) + 1) * sizeof(KMX_WCHAR);
size += (u16len(fkp->dpContext) + 1) * sizeof(KMX_WCHAR);
}
if( fgp->dpMatch ) size += (u16len(fgp->dpMatch) + 1) * sizeof(KMX_WCHAR);
if( fgp->dpNoMatch ) size += (u16len(fgp->dpNoMatch) + 1) * sizeof(KMX_WCHAR);
if (fgp->dpMatch) size += (u16len(fgp->dpMatch) + 1) * sizeof(KMX_WCHAR);
if (fgp->dpNoMatch) size += (u16len(fgp->dpNoMatch) + 1) * sizeof(KMX_WCHAR);
}
for(i = 0; i < fk->cxStoreArray; i++)
{
for (i = 0; i < fk->cxStoreArray; i++) {
size += (u16len(fk->dpStoreArray[i].dpString) + 1) * sizeof(KMX_WCHAR);
if(fk->dpStoreArray[i].dpName)
if (fk->dpStoreArray[i].dpName)
size += (u16len(fk->dpStoreArray[i].dpName) + 1) * sizeof(KMX_WCHAR);
}
buf = new KMX_BYTE[size];
if(!buf) return CERR_CannotAllocateMemory;
if (!buf) return CERR_CannotAllocateMemory;
memset(buf, 0, size);
ck = (PKMX_COMP_KEYBOARD) buf;
@ -103,74 +131,74 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX
offset = sizeof(KMX_COMP_KEYBOARD);
ck->dpStoreArray = offset;
sp = (PKMX_COMP_STORE)(buf+offset);
sp = (PKMX_COMP_STORE)(buf + offset);
fsp = fk->dpStoreArray;
offset += sizeof(KMX_COMP_STORE) * ck->cxStoreArray;
for(i = 0; i < ck->cxStoreArray; i++, sp++, fsp++) {
for (i = 0; i < ck->cxStoreArray; i++, sp++, fsp++) {
sp->dwSystemID = fsp->dwSystemID;
sp->dpString = offset;
u16ncpy((PKMX_WCHAR)(buf+offset), fsp->dpString, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
offset += (u16len(fsp->dpString) + 1) * sizeof(KMX_WCHAR);
u16ncpy((PKMX_WCHAR)(buf + offset), fsp->dpString, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
if(!fsp->dpName) {
offset += (u16len(fsp->dpString) + 1) * sizeof(KMX_WCHAR);
if (!fsp->dpName) {
sp->dpName = 0;
} else {
sp->dpName = offset;
u16ncpy((PKMX_WCHAR)(buf+offset), fsp->dpName, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
u16ncpy((PKMX_WCHAR)(buf + offset), fsp->dpName, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
offset += (u16len(fsp->dpName) + 1) * sizeof(KMX_WCHAR);
}
}
ck->dpGroupArray = offset;
gp = (PKMX_COMP_GROUP)(buf+offset);
fgp = fk->dpGroupArray;
gp = (PKMX_COMP_GROUP)(buf + offset);
offset += sizeof(KMX_COMP_GROUP) * ck->cxGroupArray;
for(i = 0; i < ck->cxGroupArray; i++, gp++, fgp++) {
for (i = 0, fgp = fk->dpGroupArray; i < ck->cxGroupArray; i++, gp++, fgp++) {
gp->cxKeyArray = fgp->cxKeyArray;
gp->fUsingKeys = fgp->fUsingKeys;
gp->dpMatch = gp->dpNoMatch = 0;
if(fgp->dpMatch) {
if (fgp->dpMatch) {
gp->dpMatch = offset;
u16ncpy((PKMX_WCHAR)(buf+offset), fgp->dpMatch, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
u16ncpy((PKMX_WCHAR)(buf + offset), fgp->dpMatch, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
offset += (u16len(fgp->dpMatch) + 1) * sizeof(KMX_WCHAR);
}
if(fgp->dpNoMatch) {
if (fgp->dpNoMatch) {
gp->dpNoMatch = offset;
u16ncpy((PKMX_WCHAR)(buf+offset), fgp->dpNoMatch, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
u16ncpy((PKMX_WCHAR)(buf + offset), fgp->dpNoMatch, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
offset += (u16len(fgp->dpNoMatch) + 1) * sizeof(KMX_WCHAR);
}
if(fgp->dpName) {
if (fgp->dpName) {
gp->dpName = offset;
u16ncpy((PKMX_WCHAR)(buf+offset), fgp->dpName, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
u16ncpy((PKMX_WCHAR)(buf + offset), fgp->dpName, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
offset += (u16len(fgp->dpName) + 1) * sizeof(KMX_WCHAR);
} else {
} else {
gp->dpName = 0;
}
gp->dpKeyArray = offset;
kp = (PKMX_COMP_KEY) (buf + offset);
kp = (PKMX_COMP_KEY)(buf + offset);
offset += gp->cxKeyArray * sizeof(KMX_COMP_KEY);
for(j = 0, fkp = fgp->dpKeyArray; j < gp->cxKeyArray; j++, kp++, fkp++) {
for (j = 0, fkp = fgp->dpKeyArray; j < gp->cxKeyArray; j++, kp++, fkp++) {
kp->Key = fkp->Key;
kp->Line = fkp->Line;
kp->ShiftFlags = fkp->ShiftFlags;
kp->dpOutput = offset;
u16ncpy((PKMX_WCHAR)(buf+offset), fkp->dpOutput, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
u16ncpy((PKMX_WCHAR)(buf + offset), fkp->dpOutput, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
offset += (u16len(fkp->dpOutput) + 1) * sizeof(KMX_WCHAR);
kp->dpContext = offset;
u16ncpy((PKMX_WCHAR)(buf+offset), fkp->dpContext, (size-offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
u16ncpy((PKMX_WCHAR)(buf + offset), fkp->dpContext, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641
offset += (u16len(fkp->dpContext) + 1) * sizeof(KMX_WCHAR);
}
}
if(fk->dwBitmapSize > 0) {
if (fk->dwBitmapSize > 0) {
ck->dwBitmapSize = fk->dwBitmapSize;
ck->dpBitmapOffset = offset;
memcpy(buf + offset, ((PKMX_BYTE)fk) + fk->dpBitmapOffset, fk->dwBitmapSize);
@ -178,11 +206,16 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX
} else {
ck->dwBitmapSize = 0;
ck->dpBitmapOffset = 0;
}
size_t nr_elements = fwrite(buf, size, 1, hOutfile);
if (nr_elements < 1) {
delete[] buf;
return CERR_SomewhereIGotItWrong;
}
fwrite(buf, size,1, hOutfile);
if(offset != size)
{
if (offset != size) {
delete[] buf;
return CERR_UnableToWriteFully;
}
@ -192,43 +225,13 @@ KMX_DWORD KMX_WriteCompiledKeyboardToFile(LPKMX_KEYBOARD fk, FILE* hOutfile, KMX
return CERR_None;
}
KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size);
LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize);
KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, PKMX_WCHAR fileName) {
FILE *fp;
fp = Open_File(fileName, u"wb");
if(fp == NULL)
{
mac_KMX_LogError(L"Failed to create output file (%d)", errno);
return FALSE;
}
KMX_DWORD err = KMX_WriteCompiledKeyboardToFile(kbd, fp, FALSE);
fclose(fp);
if(err != CERR_None) {
mac_KMX_LogError(L"Failed to write compiled keyboard with error %d", err);
std::u16string u16_filname(fileName);
std::string s = string_from_u16string(u16_filname);
remove(s.c_str());
return FALSE;
}
return TRUE;
}
/** @brief save keyboard to file */
KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName) {
FILE *fp;
FILE* fp;
fp = Open_File(fileName, "wb");
if(fp == NULL)
{
if (fp == NULL) {
mac_KMX_LogError(L"Failed to create output file (%d)", errno);
return FALSE;
}
@ -236,7 +239,7 @@ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName) {
KMX_DWORD err = KMX_WriteCompiledKeyboardToFile(kbd, fp, FALSE);
fclose(fp);
if(err != CERR_None) {
if (err != CERR_None) {
mac_KMX_LogError(L"Failed to write compiled keyboard with error %d", err);
std::string s(fileName);
remove(s.c_str());
@ -246,25 +249,35 @@ KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName) {
return TRUE;
}
/**
* @brief add an offset
* @param base pointer to starting point
* @param offset a given offset
* @return pointer to base + offset
*/
PKMX_WCHAR KMX_StringOffset(PKMX_BYTE base, KMX_DWORD offset) {
if(offset == 0) return NULL;
if (offset == 0)
return NULL;
return (PKMX_WCHAR)(base + offset);
}
#ifdef KMX_64BIT
/** CopyKeyboard will copy the data read into bufp from x86-sized structures into
x64-sized structures starting at `base`
* After this function finishes, we still need to keep the original data because
we don't copy the strings
This method is used on 64-bit architectures.
*/
/**
* @brief CopyKeyboard will copy the data into bufp from x86-sized structures into
* x64-sized structures starting at `base`. After this function finishes, we still
* need to keep the original data because we don't copy the strings. The method is
* used on 64-bit architectures.
* @param bufp pointer to buffer where data is copied into
* @param base pointer to starting point
* @return pointer to the keyboard
*/
LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) {
PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD) base;
PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)base;
// Copy keyboard structure //
LPKMX_KEYBOARD kbp = (LPKMX_KEYBOARD) bufp;
LPKMX_KEYBOARD kbp = (LPKMX_KEYBOARD)bufp;
bufp += sizeof(KMX_KEYBOARD);
kbp->dwIdentifier = ckbp->dwIdentifier;
@ -280,21 +293,17 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) {
kbp->dwFlags = ckbp->dwFlags;
kbp->dwHotKey = ckbp->dwHotKey;
kbp->dpStoreArray = (LPKMX_STORE) bufp;
kbp->dpStoreArray = (LPKMX_STORE)bufp;
bufp += sizeof(KMX_STORE) * kbp->cxStoreArray;
kbp->dpGroupArray = (LPKMX_GROUP) bufp;
kbp->dpGroupArray = (LPKMX_GROUP)bufp;
bufp += sizeof(KMX_GROUP) * kbp->cxGroupArray;
PKMX_COMP_STORE csp;
LPKMX_STORE sp;
KMX_DWORD i;
for(
csp = (PKMX_COMP_STORE)(base + ckbp->dpStoreArray), sp = kbp->dpStoreArray, i = 0;
i < kbp->cxStoreArray;
i++, sp++, csp++)
{
for (csp = (PKMX_COMP_STORE)(base + ckbp->dpStoreArray), sp = kbp->dpStoreArray, i = 0; i < kbp->cxStoreArray; i++, sp++, csp++) {
sp->dwSystemID = csp->dwSystemID;
sp->dpName = KMX_StringOffset(base, csp->dpName);
sp->dpString = KMX_StringOffset(base, csp->dpString);
@ -303,13 +312,9 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) {
PKMX_COMP_GROUP cgp;
LPKMX_GROUP gp;
for(
cgp = (PKMX_COMP_GROUP)(base + ckbp->dpGroupArray), gp = kbp->dpGroupArray, i = 0;
i < kbp->cxGroupArray;
i++, gp++, cgp++)
{
for (cgp = (PKMX_COMP_GROUP)(base + ckbp->dpGroupArray), gp = kbp->dpGroupArray, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) {
gp->dpName = KMX_StringOffset(base, cgp->dpName);
gp->dpKeyArray = cgp->cxKeyArray > 0 ? (LPKMX_KEY) bufp : NULL;
gp->dpKeyArray = cgp->cxKeyArray > 0 ? (LPKMX_KEY)bufp : NULL;
gp->cxKeyArray = cgp->cxKeyArray;
bufp += sizeof(KMX_KEY) * gp->cxKeyArray;
gp->dpMatch = KMX_StringOffset(base, cgp->dpMatch);
@ -320,11 +325,7 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) {
LPKMX_KEY kp;
KMX_DWORD j;
for(
ckp = (PKMX_COMP_KEY)(base + cgp->dpKeyArray), kp = gp->dpKeyArray, j = 0;
j < gp->cxKeyArray;
j++, kp++, ckp++)
{
for (ckp = (PKMX_COMP_KEY)(base + cgp->dpKeyArray), kp = gp->dpKeyArray, j = 0; j < gp->cxKeyArray; j++, kp++, ckp++) {
kp->Key = ckp->Key;
kp->Line = ckp->Line;
kp->ShiftFlags = ckp->ShiftFlags;
@ -336,41 +337,38 @@ LPKMX_KEYBOARD KMX_CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base) {
}
// else KMX_FixupKeyboard
#else /* Fixup the keyboard by expanding pointers. On disk the pointers are stored relative to the
beginning of the file, but we need real pointers. This method is used on 32-bit architectures.
*/
#else
/** @brief Fixup the keyboard by expanding pointers. */
LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFileSize) {
UNREFERENCED_PARAMETER(dwFileSize);
KMX_DWORD i, j;
PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD) base;
PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)base;
PKMX_COMP_GROUP cgp;
PKMX_COMP_STORE csp;
PKMX_COMP_KEY ckp;
LPKMX_KEYBOARD kbp = (LPKMX_KEYBOARD) bufp;
LPKMX_KEYBOARD kbp = (LPKMX_KEYBOARD)bufp;
LPKMX_STORE sp;
LPKMX_GROUP gp;
LPKMX_KEY kp;
kbp->dpStoreArray = (LPKMX_STORE) (base + ckbp->dpStoreArray);
kbp->dpGroupArray = (LPKMX_GROUP) (base + ckbp->dpGroupArray);
kbp->dpStoreArray = (LPKMX_STORE)(base + ckbp->dpStoreArray);
kbp->dpGroupArray = (LPKMX_GROUP)(base + ckbp->dpGroupArray);
for(sp = kbp->dpStoreArray, csp = (PKMX_COMP_STORE) sp, i = 0; i < kbp->cxStoreArray; i++, sp++, csp++) {
for (sp = kbp->dpStoreArray, csp = (PKMX_COMP_STORE)sp, i = 0; i < kbp->cxStoreArray; i++, sp++, csp++) {
sp->dpName = KMX_StringOffset(base, csp->dpName);
sp->dpString = KMX_StringOffset(base, csp->dpString);
}
for(gp = kbp->dpGroupArray, cgp = (PKMX_COMP_GROUP) gp, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) {
for (gp = kbp->dpGroupArray, cgp = (PKMX_COMP_GROUP)gp, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) {
gp->dpName = KMX_StringOffset(base, cgp->dpName);
gp->dpKeyArray = (LPKMX_KEY) (base + cgp->dpKeyArray);
if(cgp->dpMatch != NULL) gp->dpMatch = (PKMX_WCHAR) (base + cgp->dpMatch);
if(cgp->dpNoMatch != NULL) gp->dpNoMatch = (PKMX_WCHAR) (base + cgp->dpNoMatch);
gp->dpKeyArray = (LPKMX_KEY)(base + cgp->dpKeyArray);
if (cgp->dpMatch != NULL)gp->dpMatch = (PKMX_WCHAR)(base + cgp->dpMatch);
if (cgp->dpNoMatch != NULL)gp->dpNoMatch = (PKMX_WCHAR)(base + cgp->dpNoMatch);
for(kp = gp->dpKeyArray, ckp = (PKMX_COMP_KEY) kp, j = 0; j < gp->cxKeyArray; j++, kp++, ckp++) {
kp->dpOutput = (PKMX_WCHAR) (base + ckp->dpOutput);
kp->dpContext = (PKMX_WCHAR) (base + ckp->dpContext);
for (kp = gp->dpKeyArray, ckp = (PKMX_COMP_KEY)kp, j = 0; j < gp->cxKeyArray; j++, kp++, ckp++) {
kp->dpOutput = (PKMX_WCHAR)(base + ckp->dpOutput);
kp->dpContext = (PKMX_WCHAR)(base + ckp->dpContext);
}
}
@ -379,133 +377,29 @@ LPKMX_KEYBOARD KMX_FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base, KMX_DWORD dwFil
#endif
KMX_BOOL KMX_LoadKeyboard(char16_t* fileName, LPKMX_KEYBOARD* lpKeyboard) {
/** @brief load a keyboard kmx-file */
KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) {
*lpKeyboard = NULL;
PKMX_BYTE buf;
FILE* fp;
LPKMX_KEYBOARD kbp;
PKMX_BYTE filebase;
if(!fileName || !lpKeyboard) {
mac_KMX_LogError(L"Bad Filename\n" );
return FALSE;
}
fp = Open_File((const KMX_WCHAR*)fileName, u"rb");
if(fp == NULL) {
mac_KMX_LogError(L"Could not open file\n" );
return FALSE;
}
if (fseek(fp, 0, SEEK_END) != 0) {
fclose(fp);
mac_KMX_LogError(L"Could not fseek file\n" );
return FALSE;
}
auto file_size = ftell(fp);
if (file_size <= 0) {
fclose(fp);
return FALSE;
}
if (fseek(fp, 0, SEEK_SET) != 0) {
fclose(fp);
mac_KMX_LogError(L"Could not fseek(set) file\n" );
return FALSE;
}
#ifdef KMX_64BIT
// allocate enough memory for expanded data structure + original data.
// Expanded data structure is double the size of data on disk (8-byte
// pointers) - on disk the "pointers" are relative to the beginning of
// the file.
// We save the original data at the end of buf; we don't copy strings, so
// those will remain in the location at the end of the buffer.
buf = new KMX_BYTE[file_size * 3];
#else
buf = new KMX_BYTE[file_size];
#endif
if (!buf) {
delete[] buf;
fclose(fp);
mac_KMX_LogError(L"Not allocmem\n" );
return FALSE;
}
#ifdef KMX_64BIT
filebase = buf + file_size*2;
#else
filebase = buf;
#endif
if (fread(filebase, 1, file_size, fp) < (size_t)file_size) {
mac_KMX_LogError(L"Could not read file\n" );
delete[] buf;
fclose(fp);
return FALSE;
}
// delete???
fclose(fp);
if (*((PKMX_DWORD)filebase) != (KMX_DWORD)FILEID_COMPILED)
{
delete [] buf;
mac_KMX_LogError(L"Invalid file - signature is invalid\n");
return FALSE;
}
if (!KMX_VerifyKeyboard(filebase, file_size)) {
mac_KMX_LogError(L"errVerifyKeyboard\n" );
delete[] buf;
return FALSE;
}
#ifdef KMX_64BIT
kbp = KMX_CopyKeyboard(buf, filebase);
#else
kbp = KMX_FixupKeyboard(buf, filebase, file_size);
#endif
if (!kbp) {
mac_KMX_LogError(L"errFixupKeyboard\n" );
delete[] buf;
return FALSE;
}
if (kbp->dwIdentifier != FILEID_COMPILED) {
delete[] buf;
mac_KMX_LogError(L"errNotFileID\n" );
return FALSE;
}
*lpKeyboard = kbp;
return TRUE;
}
KMX_BOOL KMX_LoadKeyboard(char* fileName, LPKMX_KEYBOARD* lpKeyboard) {
*lpKeyboard = NULL;
PKMX_BYTE buf;
FILE* fp;
LPKMX_KEYBOARD kbp;
PKMX_BYTE filebase;
if(!fileName || !lpKeyboard) {
mac_KMX_LogError(L"Bad Filename\n" );
if (!fileName || !lpKeyboard) {
mac_KMX_LogError(L"Bad Filename\n");
return FALSE;
}
fp = Open_File((const KMX_CHAR*)fileName, "rb");
if(fp == NULL) {
mac_KMX_LogError(L"Could not open file\n" );
if (fp == NULL) {
mac_KMX_LogError(L"Could not open file\n");
return FALSE;
}
if (fseek(fp, 0, SEEK_END) != 0) {
fclose(fp);
mac_KMX_LogError(L"Could not fseek file\n" );
mac_KMX_LogError(L"Could not fseek file\n");
return FALSE;
}
@ -517,17 +411,19 @@ KMX_BOOL KMX_LoadKeyboard(char* fileName, LPKMX_KEYBOARD* lpKeyboard) {
if (fseek(fp, 0, SEEK_SET) != 0) {
fclose(fp);
mac_KMX_LogError(L"Could not fseek(set) file\n" );
mac_KMX_LogError(L"Could not fseek(set) file\n");
return FALSE;
}
#ifdef KMX_64BIT
// allocate enough memory for expanded data structure + original data.
// Expanded data structure is double the size of data on disk (8-byte
// pointers) - on disk the "pointers" are relative to the beginning of
// the file.
// We save the original data at the end of buf; we don't copy strings, so
// those will remain in the location at the end of the buffer.
/**
* allocate enough memory for expanded data structure + original data.
* Expanded data structure is double the size of data on disk (8-byte
* pointers) - on disk the "pointers" are relative to the beginning of
* the file.
* We save the original data at the end of buf; we don't copy strings, so
* those will remain in the location at the end of the buffer.
*/
buf = new KMX_BYTE[file_size * 3];
#else
buf = new KMX_BYTE[file_size];
@ -536,35 +432,34 @@ KMX_BOOL KMX_LoadKeyboard(char* fileName, LPKMX_KEYBOARD* lpKeyboard) {
if (!buf) {
delete[] buf;
fclose(fp);
mac_KMX_LogError(L"Not allocmem\n" );
mac_KMX_LogError(L"Not allocmem\n");
return FALSE;
}
#ifdef KMX_64BIT
filebase = buf + file_size*2;
filebase = buf + file_size * 2;
#else
filebase = buf;
#endif
if (fread(filebase, 1, file_size, fp) < (size_t)file_size) {
mac_KMX_LogError(L"Could not read file\n" );
mac_KMX_LogError(L"Could not read file\n");
delete[] buf;
fclose(fp);
return FALSE;
}
// delete???
// delete??? _S2
fclose(fp);
if (*((PKMX_DWORD)filebase) != (KMX_DWORD)FILEID_COMPILED)
{
delete [] buf;
if (*((PKMX_DWORD)filebase) != (KMX_DWORD)FILEID_COMPILED) {
delete[] buf;
mac_KMX_LogError(L"Invalid file - signature is invalid\n");
return FALSE;
}
if (!KMX_VerifyKeyboard(filebase, file_size)) {
mac_KMX_LogError(L"errVerifyKeyboard\n" );
delete[] buf;
mac_KMX_LogError(L"errVerifyKeyboard\n");
return FALSE;
}
@ -574,10 +469,9 @@ KMX_BOOL KMX_LoadKeyboard(char* fileName, LPKMX_KEYBOARD* lpKeyboard) {
kbp = KMX_FixupKeyboard(buf, filebase, file_size);
#endif
if (!kbp) {
mac_KMX_LogError(L"errFixupKeyboard\n" );
delete[] buf;
mac_KMX_LogError(L"errFixupKeyboard\n");
return FALSE;
}
@ -590,8 +484,8 @@ KMX_BOOL KMX_LoadKeyboard(char* fileName, LPKMX_KEYBOARD* lpKeyboard) {
return TRUE;
}
KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size){
/** @brief check if the file has correct version */
KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size) {
KMX_DWORD i;
PKMX_COMP_KEYBOARD ckbp = (PKMX_COMP_KEYBOARD)filebase;
PKMX_COMP_STORE csp;
@ -605,7 +499,7 @@ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size){
if (csp->dpString == 0) {
mac_KMX_LogError(L"errWrongFileVersion:NULL");
} else {
mac_KMX_LogError(L"errWrongFileVersion:%10.10ls",(const PKMX_WCHAR) KMX_StringOffset((PKMX_BYTE)filebase, csp->dpString));
mac_KMX_LogError(L"errWrongFileVersion:%10.10ls", (const PKMX_WCHAR)KMX_StringOffset((PKMX_BYTE)filebase, csp->dpString));
}
return FALSE;
}
@ -616,8 +510,8 @@ KMX_BOOL KMX_VerifyKeyboard(LPKMX_BYTE filebase, KMX_DWORD file_size){
return TRUE;
}
/** @brief increment in a string */
PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) {
if (p == NULL || *p == 0)
return p;
if (*p != UC_SENTINEL) {
@ -625,13 +519,14 @@ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) {
return p + 2;
return p + 1;
}
// UC_SENTINEL(FFFF) with UC_SENTINEL_EXTENDEDEND(0x10) == variable length
// UC_SENTINEL(FFFF) with UC_SENTINEL_EXTENDEDEND(0x10) ==> variable length
if (*(p + 1) == CODE_EXTENDED) {
p += 2;
while (*p && *p != UC_SENTINEL_EXTENDEDEND)
p++;
if (*p == 0) return p;
if (*p == 0)
return p;
return p + 1;
}
@ -650,36 +545,17 @@ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p) {
return p;
}
//################################################################################################################################################
//################################# Code beyond these lines needs to be included in mcompile #####################################################
//################################################################################################################################################
/** @brief open a file */
FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode) {
#ifdef _MSC_VER
std::string cpath = Filename; //, cmode = mode;
std::string cpath = Filename; //, cmode = mode;
std::replace(cpath.begin(), cpath.end(), '/', '\\');
return fopen(cpath.c_str(), (const KMX_CHAR*) mode);
return fopen(cpath.c_str(), (const KMX_CHAR*)mode);
#else
return fopen(Filename, mode);
std::string cpath, cmode;
cpath = (const KMX_CHAR*) Filename;
cmode = (const KMX_CHAR*) mode;
return fopen(cpath.c_str(), cmode.c_str());
#endif
};
FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode) {
#ifdef _MSC_VER
std::wstring cpath = convert_pchar16T_To_wstr((KMX_WCHAR*) Filename);
std::wstring cmode = convert_pchar16T_To_wstr((KMX_WCHAR*) mode);
std::replace(cpath.begin(), cpath.end(), '/', '\\');
return _wfsopen(cpath.c_str(), cmode.c_str(), _SH_DENYWR);
#else
std::string cpath, cmode;
cpath = string_from_u16string(Filename);
cmode = string_from_u16string(mode);
cpath = (const KMX_CHAR*)Filename;
cmode = (const KMX_CHAR*)mode;
return fopen(cpath.c_str(), cmode.c_str());
#endif
};

View file

@ -70,25 +70,24 @@ typedef struct KMX_tagKEYBOARD {
/**
* @brief load a keyboard kmx-file
* @param fileName ptr to fileName of kmx-file
* @param [in,out] lpKeyboard ptr to ptr to keyboard
* @param fileName pointer to fileName of kmx-file
* @param [in,out] lpKeyboard pointer to pointer to keyboard
* @return TRUE on success; else FALSE
*/
KMX_BOOL KMX_LoadKeyboard(KMX_WCHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) ;
KMX_BOOL KMX_LoadKeyboard(KMX_CHAR* fileName, LPKMX_KEYBOARD* lpKeyboard) ;
/**
* @brief save keyboard to file
* @param kbd ptr to the keyboard
* @param fileName ptr to fileName of a kmx-file
* @param kbd pointer to the keyboard
* @param fileName pointer to fileName of a kmx-file
* @return TRUE on success; else FALSE
*/
KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_WCHAR* fileName);
KMX_BOOL KMX_SaveKeyboard(LPKMX_KEYBOARD kbd, KMX_CHAR* fileName);
/**
* @brief increment in a string
* @param p ptr to a character
* @return ptr to the incremented character
* @param p pointer to a character
* @return pointer to the incremented character
*/
PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p);
@ -96,10 +95,9 @@ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p);
* @brief open a file
* @param Filename name of the file
* @param mode same as mode in fopen
* @return ptr to file. On error, returns a null pointer
* @return pointer to file. On error, returns a null pointer
*/
FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode);
FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode);
#endif // _KMXFILE_H

View file

@ -1,14 +1,12 @@
/*
* Keyman is copyright (C) 2004 SIL International. MIT License.
*
* Mnemonic layout support for Linux
*/
/*
Defines the entry point for the console application.
Note: this program deliberately leaks memory as it has a very short life cycle and managing the memory allocations
for the subcomponents of the compiled keyboard is an unnecessary optimisation. Just so you know.
* Mnemonic layout support for mac
*
* Defines the entry point for the console application.
*
* Note: this program deliberately leaks memory as it has a very short life cycle and managing the memory allocations
* for the subcomponents of the compiled keyboard is an unnecessary optimisation. Just so you know.
*/
#include <stdio.h>
@ -17,15 +15,11 @@
#include "u16.h"
int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* OutputPairs); // returns array of [usvk, ch_out] pairs
int mac_run(int argc, char* argv[]);
/**
* @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard
* @param kbd pointer to US keyboard
* @param bDeadkeyConversion option for converting a deadkey to a character: 1=conversion; 0= no conversion
* @param argc number of commandline arguments
* @param bDeadkeyConversion option for converting a deadkey to a character: 1 = dk conversion; 0 = no dk conversion
* @param argc number of command line arguments
* @return TRUE if conversion was successful; FALSE if not
*/
KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int argc);
@ -33,12 +27,32 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int
/** @brief Collect the key data, translate it to kmx and append to the existing keyboard */
bool mac_KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D &all_vector, const UCKeyboardLayout** keyboard_layout, std::vector<KMX_DeadkeyMapping>* KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327
/**
* @brief start of mcompile; load, convert and save keyboard
* @param argc number of commandline arguments
* @param argv pointer to commandline arguments: executable, inputfile, outputfile
* @return 0 on success;
* 1 for wrong usage of calling parameters;
* 3 if unable to load keyboard
*/
int mac_run(int argc, char* argv[]);
/**
* @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard
* @param keyboard_layout pointer to the currently used (underlying) keyboard Layout
* @param all_vector vector that holds the data of the US keyboard and the currently used (underlying) keyboard
* @param deadkey deadkey character
* @param shift_dk shiftstate opf a deadkey character
* @param [out] outputPairs pointer to array of [usvk, ch_out] pairs
* @return size of array of [usvk, ch_out] pairs
*/
int mac_KMX_GetDeadkeys(const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* outputPairs); // returns array of [usvk, ch_out] pairs
std::vector<KMX_DeadkeyMapping> KMX_FDeadkeys; // I4353
// _S2 run and getdeadkeys to here
#define _countof(a) (sizeof(a) / sizeof(*(a)))
/**
/**
* @brief main function for mcompile for Windows, Linux, Mac
* @param argc number of commandline arguments
* @param argv commandline arguments
@ -57,12 +71,10 @@ std::vector<KMX_DeadkeyMapping> KMX_FDeadkeys; // I4353
mac_run(argc, argv);
printf("\n................................ END .............................. _S2 \n");
}
/** @brief start of mcompile; load, convert and save keyboard */
int mac_run(int argc, char* argv[] ) {
/** @brief start of mcompile; load, convert and save keyboard */
int mac_run(int argc, char* argv[]) {
int bDeadkeyConversion = 0;
if (argc > 1)
@ -79,14 +91,13 @@ int mac_run(int argc, char* argv[] ) {
" \tmac keyboard layout\n"
" \t(-d convert deadkeys to plain keys) \n \n"); // I4552
}
// -u option is not available for Linux and macOS
// -u option is not available for Linux and macOS
KMX_CHAR* infile = argv[n];
KMX_CHAR* outfile = argv[n + 1];
printf("mcompile%s \"%s\" \"%s\"\n", bDeadkeyConversion ? " -d" : "", infile, outfile); // I4174
// _S2 TODO open again!!
//wprintf(L"mcompile%ls \"%ls\" \"%ls\"\n", bDeadkeyConversion ? L" -d" : L"", u16fmt((const char16_t*) infile).c_str(), u16fmt((const char16_t*) outfile).c_str() ); // I4174
// 1. Load the keyman keyboard file
@ -121,16 +132,16 @@ int mac_run(int argc, char* argv[] ) {
}
#if defined(_WIN32) || defined(_WIN64) // Windows
if (DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F
if (DoConvert(kmxfile, kbid, bDeadkeyConversion)) { // I4552F
KMX_SaveKeyboard(kmxfile, outfile);
}
#elif ((__linux__) || (__unix__)) // LINUX, UNIX
#elif ((__linux__) || (__unix__)) // LINUX, UNIX
if (mac_KMX_DoConvert(kmxfile, bDeadkeyConversion, argc)) { // I4552F
KMX_SaveKeyboard(kmxfile, outfile);
}
#elif (__APPLE__ && TARGET_OS_MAC) // macOS
#elif (__APPLE__ && TARGET_OS_MAC) // macOS
if (mac_KMX_DoConvert(kmxfile, bDeadkeyConversion, argc)) { // I4552F
KMX_SaveKeyboard(kmxfile, outfile);
}
@ -265,7 +276,7 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk,
// The weird LCTRL+RALT is Windows' way of mapping the AltGr key.
// We store that as just RALT, and use the option "Simulate RAlt with Ctrl+Alt"
// to provide an alternate..
if ((shift & (LCTRLFLAG|RALTFLAG)) == (LCTRLFLAG|RALTFLAG)) // I4327
if ((shift & (LCTRLFLAG | RALTFLAG)) == (LCTRLFLAG | RALTFLAG)) // I4327
shift &= ~LCTRLFLAG;
if (key->ShiftFlags == 0) {
@ -281,9 +292,9 @@ void mac_KMX_TranslateDeadkeyKey(LPKMX_KEY key, KMX_WCHAR deadkey, KMX_WORD vk,
PKMX_WCHAR context = new KMX_WCHAR[len + 4];
memcpy(context, key->dpContext, len * sizeof(KMX_WCHAR));
context[len] = UC_SENTINEL;
context[len+1] = CODE_DEADKEY;
context[len+2] = deadkey;
context[len+3] = 0;
context[len + 1] = CODE_DEADKEY;
context[len + 2] = deadkey;
context[len + 3] = 0;
key->dpContext = context;
key->Key = vk;
}
@ -340,7 +351,7 @@ void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk,
for (unsigned int i = 0; i < kbd->cxGroupArray; i++) {
if (kbd->dpGroupArray[i].fUsingKeys) {
LPKMX_KEY keys = new KMX_KEY[kbd->dpGroupArray[i].cxKeyArray + 1];
memcpy(keys+1, kbd->dpGroupArray[i].dpKeyArray, kbd->dpGroupArray[i].cxKeyArray * sizeof(KMX_KEY));
memcpy(keys + 1, kbd->dpGroupArray[i].dpKeyArray, kbd->dpGroupArray[i].cxKeyArray * sizeof(KMX_KEY));
keys[0].dpContext = new KMX_WCHAR[1];
keys[0].dpContext[0] = 0;
keys[0].dpOutput = new KMX_WCHAR[4];
@ -367,9 +378,9 @@ void mac_KMX_AddDeadkeyRule(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey, KMX_WORD vk,
*/
KMX_WCHAR mac_KMX_ScanXStringForMaxDeadkeyID(PKMX_WCHAR str) {
KMX_WCHAR dkid = 0;
while(str && *str) {
if(*str == UC_SENTINEL && *(str+1) == CODE_DEADKEY) {
dkid = std::max(dkid, *(str+2));
while (str && *str) {
if (*str == UC_SENTINEL && *(str + 1) == CODE_DEADKEY) {
dkid = std::max(dkid, *(str + 2));
}
str = KMX_incxstr(str);
}
@ -393,7 +404,7 @@ KMX_WCHAR mac_KMX_GetUniqueDeadkeyID(LPKMX_KEYBOARD kbd, KMX_WCHAR deadkey) {
UINT i, j;
KMX_WCHAR dkid = 0;
static KMX_WCHAR s_next_dkid = 0;
static KMX_dkidmap* s_dkids = NULL;
static KMX_dkidmap* s_dkids = NULL;
static int s_ndkids = 0;
if (!kbd) {
@ -510,10 +521,10 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int
// evident for the 102nd key on UK, for example, where \ can be generated with VK_OEM_102 or AltGr+VK_QUOTE.
// For now, we get the least shifted version, which is hopefully adequate.
// Sadly it`s not e.g.: on a German WINDOWS keyboard one will get '~' with ALTGR + K_221(+) only which is the usual combination to get ~.
// Sadly it`s not e.g.: on a German WINDOWS keyboard one will get '~' with ALTGR + K_221(+) which is the usual combination to get ~.
// on a German MAC keyboard one will get '~' with either OPT + K_221(+) or OPT + K_84(T) or CAPS + OPT + K_78(N)
// K_84(T) will be caught first, so one of the the least obvious version for creating the '~' is found and processed.
// -> meeting with Marc May 21 2024: We leave it as it is; it is OK if different combinations are found.
// -> meeting with @MD May 21 2024: We leave it as it is; it is OK if different combinations are found.
const UCKeyboardLayout* keyboard_layout;
if (mac_InitializeUCHR(&keyboard_layout)) {
@ -527,12 +538,6 @@ KMX_BOOL mac_KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, int
return FALSE;
}
//printoutKeyboards(all_vector);
find_character_S2(keyboard_layout, 180);
printf("-------\n");
//print_dublicates_S2(keyboard_layout);
//find_double_keys(keyboard_layout,1);
for (int j = 0; VKShiftState[j] != 0xFFFF; j++) { // I4651
// Loop through each possible key on the keyboard
@ -563,29 +568,19 @@ printf("-------\n");
if (!mac_KMX_ImportRules(kbd, all_vector, &keyboard_layout, &KMX_FDeadkeys, bDeadkeyConversion)) { // I4353 // I4552
return FALSE;
}
return TRUE;
}
/**
* @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard
* @param keyboard_layout the currently used (underlying) keyboard Layout
* @param all_vector Vector that holds the data of the US keyboard and the currently used (underlying) keyboard
* @param deadkey deadkey character
* @param shift_dk shiftstate of the deadkey
* @param OutputPairs ptr to array of deadkeys
* @return size of array of deadkeys
*/
/** _S2 TODO thids is from linux:
/**
* @brief return an array of [usvk, ch_out] pairs: all existing combinations of a deadkey + character for the underlying keyboard
* @param deadkey deadkey character
* @param [out] OutputPairs pointer to array of [usvk, ch_out] pairs
* @param keymap pointer to the currently used (underlying) keyboard Layout
* @param dk_Table shiftstate of the deadkey
* @return size of array of [usvk, ch_out] pairs
* @param keyboard_layout the currently used (underlying) keyboard Layout
* @param all_vector Vector that holds the data of the US keyboard and the currently used (under lying) keyboard
* @param deadkey deadkey character
* @param shift_dk shiftstate of the deadkey
* @param [out] outputPairs pointer to array of [usvk, ch_out] pairs
* @return size of array of [usvk, ch_out] pairs
*/
int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* OutputPairs) {
int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D& all_vector, KMX_WCHAR deadkey, UINT shift_dk, KMX_WORD* outputPairs) {
UInt32 deadkeystate;
UniCharCount maxStringlength = 5;
UniCharCount actualStringlength = 0;
@ -594,23 +589,31 @@ int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D&
OSStatus status;
unicodeString[0] = 0;
KMX_WORD* p = OutputPairs;
KMX_WORD* p = outputPairs;
KMX_DWORD sc_dk = mac_KMX_get_KeyCodeUnderlying_From_KeyValUnderlying(all_vector, deadkey);
for (int j = 0; j < sizeof(ss_mac) / sizeof(ss_mac[0]); j++) {
// we start with SPACE (keycode_spacebar=49) since all deadkeys occur in combinations with space.
// Since mcompile finds only the first occurance of a dk combination, this makes sure that we always find the dk+SPACE combinations for a deadkey.
// If there are more combinations to create a specific character they will not be found. (See comment at the beginning of mac_KMX_DoConvert())
/*
we start with SPACE (keycode_spacebar=49) because all deadkeys occur in combinations with space.
Since mcompile finds only the first occurance of a dk combination, this makes sure that we always find the dk+SPACE combinations for a deadkey.
If there are more combinations to create a specific character they will not be found. (See comment at the top of mac_KMX_DoConvert())
*/
for (int i = keycode_spacebar; i >= 0; i--) {
status = UCKeyTranslate(keyboard_layout, sc_dk, kUCKeyActionDown, mac_convert_Shiftstate_to_MacShiftstate(shift_dk), LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString);
/*
UCKeyTranslate != 0 if a dk was found; then run UCKeyTranslate again with a SPACE (keycode_spacebar) to get the plain dk e.g.'^'
if CAPS is used: always add 4 e.g. SHIFT = 2; SHIFT+CAPS = 6
*/
if (deadkeystate != 0) {
status = UCKeyTranslate(keyboard_layout, i, kUCKeyActionDown, ss_mac[j], LMGetKbdType(), keyTranslateOptions, &deadkeystate, maxStringlength, &actualStringlength, unicodeString);
//deadkeystate might be changed again
if (deadkeystate != 0) {
KMX_WORD vk = mac_KMX_get_KeyVal_From_KeyCode(keyboard_layout, i, ss_mac[1], 0);
// ensure to not get key combinations like ^a but only combined characters like â ( exception for ^+space)
// ensure to NOT get key combinations like ^a but only combined characters like â (exception for ^+space)
if ((unicodeString[0] != deadkey) || (vk == 32)) {
*p++ = vk;
*p++ = ss_mac[j];
@ -621,10 +624,10 @@ int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D&
}
}
*p = 0;
return (p - OutputPairs);
return (p - outputPairs);
}
/** @brief print (error) messages */
/** @brief print (error) messages */
void mac_KMX_LogError(const wchar_t* fmt, ...) {
WCHAR fmtbuf[256];
const wchar_t* end = L"\0";
@ -633,7 +636,7 @@ int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D&
int j = 0;
va_start(vars, fmt);
vswprintf (fmtbuf, _countof(fmtbuf), fmt, vars);
vswprintf(fmtbuf, _countof(fmtbuf), fmt, vars);
fmtbuf[255] = 0;
do {
@ -644,8 +647,6 @@ int mac_KMX_GetDeadkeys( const UCKeyboardLayout* keyboard_layout, vec_dword_3D&
}
//################################################################################################################################################
//################################# Code beyond these lines needs to be included in mcompile #####################################################
//################################################################################################################################################

View file

@ -33,8 +33,6 @@ struct KMX_DeadkeyMapping { // I4353
extern std::vector<KMX_DeadkeyMapping> KMX_FDeadkeys; // I4353
PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p);
/**
* @brief print (error) messages
* @param fmt text to print
@ -56,4 +54,4 @@ bool test_dk_write_entries_S2(KMX_WORD deadkeys[512]);
void fun2();
void testmyFunctions_S2();
#endif /*MCOMPILE_H*/
#endif /*MCOMPILE_H*/

View file

@ -1,3 +1,9 @@
/*
* Keyman is copyright (C) SIL International. MIT License.
*
* Keyboard reading and mapping for mac
*/
#include "u16.h"
#include <codecvt>
#include <locale>
@ -8,9 +14,9 @@ std::vector<std::u16string> convert_argv_to_Vector_u16str(int argc, char* argv[]
std::vector<std::u16string> vector_u16;
// for each arg convert to u16string and push to vector
for (char **arg = argv, i = 0; *arg; ++arg, i++) {
std::string S(*arg);
vector_u16.push_back(u16string_from_string(S));
for (char** arg = argv, i = 0; *arg; ++arg, i++) {
std::string s(*arg);
vector_u16.push_back(u16string_from_string(s));
}
return vector_u16;
}
@ -19,7 +25,7 @@ std::vector<std::u16string> convert_argvW_to_Vector_u16str(int argc, wchar_t* ar
std::vector<std::u16string> vector_u16;
// for each arg convert to u16string and push to vector
for (wchar_t **arg = argv, i = 0; *arg; ++arg, i++) {
for (wchar_t** arg = argv, i = 0; *arg; ++arg, i++) {
std::wstring S(*arg);
vector_u16.push_back(u16string_from_wstring(S));
}
@ -83,10 +89,10 @@ void u16sprintf(KMX_WCHAR* dst, const size_t max_len, const wchar_t* fmt, ...) {
delete[] wbuf;
}
std::wstring convert_pchar16T_To_wstr(KMX_WCHAR* Name) {
std::wstring convert_pchar16T_To_wstr(KMX_WCHAR* name) {
// convert char16_t* -> std::u16string -> std::string -> std::wstring
// char16_t* -> std::u16string
std::u16string u16str(Name);
std::u16string u16str(name);
// std::u16string -> std::string
std::string stri = string_from_u16string(u16str);
// std::string -> std::wstring
@ -117,20 +123,20 @@ const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) {
return o;
}
const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name) {
const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* name) {
const KMX_WCHAR* cp = NULL;
cp = u16rchr(Name, '\\');
cp = u16rchr(name, '\\');
if (cp == NULL)
cp = u16rchr(Name, '/');
cp = u16rchr(name, '/');
return cp;
}
/*
KMX_CHAR* strrchr_slash(KMX_CHAR* Name)
KMX_CHAR* strrchr_slash(KMX_CHAR* name)
{
KMX_CHAR* cp = NULL;
cp = strrchr(Name, '\\');
cp = strrchr(name, '\\');
if (cp == NULL)
cp = strrchr(Name, '/');
cp = strrchr(name, '/');
return cp;
}
*/

View file

@ -21,7 +21,7 @@ std::string string_from_u16string(std::u16string const str);
void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...);
std::wstring convert_pchar16T_To_wstr(KMX_WCHAR* Name);
std::wstring convert_pchar16T_To_wstr(KMX_WCHAR* name);
size_t u16len(const KMX_WCHAR* p);
int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q);
@ -38,7 +38,7 @@ KMX_WCHAR* u16tok(KMX_WCHAR* p, KMX_WCHAR* ch, KMX_WCHAR** ctx);
long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base);
double u16tof(KMX_WCHAR* str);
KMX_CHAR* strrchr_slash(KMX_CHAR* Name);
const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name);
KMX_CHAR* strrchr_slash(KMX_CHAR* name);
const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* name);
#endif /* U16_H */