Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
99baacb
adding unit tests for Linux mcompile
Markus-SWAG Apr 28, 2026
77acb6f
adding dependency to libglibmm-2.4-dev
Markus-SWAG Apr 28, 2026
c040314
adding dependency to libglibmm-2.4-dev typo
Markus-SWAG Apr 28, 2026
0ed8eb1
Prevent running unit tests on Wayland
Markus-SWAG Apr 28, 2026
f309d90
incorporating review results for adding unit tests
Markus-SWAG May 5, 2026
8bd47e4
parametrized unit tests for mcompile
Markus-SWAG May 6, 2026
d5accca
Update linux/mcompile/keymap/deadkey.h
Markus-SWAG May 6, 2026
6e38fc0
renamed files according test standards
Markus-SWAG May 6, 2026
c05bba9
Merge remote-tracking branch 'refs/remotes/origin/feat/linux/mnemonic…
Markus-SWAG May 6, 2026
bb87e1d
substituting SIL International by SIL Global in all file headers
Markus-SWAG May 6, 2026
0646808
erasing year from the file headers
Markus-SWAG May 6, 2026
e3dd7f1
added delete kmxfile as before
Markus-SWAG May 6, 2026
8ba6a13
added 1 more file header
Markus-SWAG May 6, 2026
9cf4e78
fixing typo
Markus-SWAG May 6, 2026
471c6c4
adding test suite for KMX_get_KeyVal_From_KeyCode
Markus-SWAG May 7, 2026
61f1a2b
incorporating review results
Markus-SWAG May 7, 2026
8803089
reformatting test parameters
Markus-SWAG May 7, 2026
c9c45a0
German Unit test now alos successfully finishing
Markus-SWAG May 11, 2026
0ccc9af
Update linux/mcompile/keymap/test/meson.build
Markus-SWAG May 11, 2026
8cf0c41
Update linux/mcompile/keymap/mc_kmxfile.cpp
Markus-SWAG May 11, 2026
cc9e0be
Update linux/mcompile/keymap/deadkey.h
Markus-SWAG May 11, 2026
7b367e9
Update linux/mcompile/keymap/main.cpp
Markus-SWAG May 11, 2026
28b0c96
changes after review
Markus-SWAG May 11, 2026
fcea563
improving tests, check on deadkey variable
Markus-SWAG May 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions linux/debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Build-Depends:
gir1.2-webkit2-4.1,
ibus,
libevdev-dev,
libglibmm-2.4-dev,
libgtk-3-dev,
libibus-1.0-dev (>= 1.2),
libicu-dev,
Expand Down
78 changes: 78 additions & 0 deletions linux/mcompile/keymap/converter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "mcompile.h"

/**
* @brief main function for mcompile for Linux
* @param argc number of commandline arguments
* @param argv pointer to commandline arguments: executable, inputfile, outputfile
* @return 0 on success
*/

int main(int argc, char* argv[]) {

Comment thread
ermshiperete marked this conversation as resolved.
Outdated

int bDeadkeyConversion = 0;

if (argc > 1)
bDeadkeyConversion = (strcmp(argv[1], "-d") == 0); // I4552

int n = (bDeadkeyConversion ? 2 : 1);

if (argc < 3 || argc > 4 || (argc - n) != 2) { // I4273// I4273
printf(
"Usage: \tmcompile [-d] infile.kmx outfile.kmx\n"
" \tmcompile converts a Keyman mnemonic layout to\n"
" \ta positional one based on the currently used \n"
" \tLinux keyboard layout\n"
" \t(-d convert deadkeys to plain keys) \n \n"); // I4552

return 1;
}

// -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

// 1. Load the keyman keyboard file

// 2. For each key on the system layout, determine its output character and perform a
// 1-1 replacement on the keyman keyboard of that character with the base VK + shift
// state. This fixup will transform the char to a vk, which will avoid any issues
// with the key.
//
//
// For each deadkey, we need to determine its possible outputs. Then we generate a VK
// rule for that deadkey, e.g. [K_LBRKT] > dk(c101)
//
// Next, update each rule that references the output from that deadkey to add an extra
// context deadkey at the end of the context match, e.g. 'a' dk(c101) + [K_SPACE] > 'b'.
// This will require a memory layout change for the .kmx file, plus fixups on the
// context+output index offsets
//
// --> virtual character keys
//
// [CTRL ' '] : we look at the character, and replace it in the same way, but merely
// switch the shift state from the VIRTUALCHARKEY to VIRTUALKEY, without changing any
// other properties of the key.
//
// 3. Write the new keyman keyboard file

LPKMX_KEYBOARD kmxfile;
Comment thread
ermshiperete marked this conversation as resolved.
Outdated

if (!KMX_LoadKeyboard(infile, &kmxfile)) {
KMX_LogError(L"Failed to load keyboard (%d)\n", errno);
return 3;
}

if (KMX_DoConvert(kmxfile, bDeadkeyConversion, argc, (gchar**)argv)) { // I4552F
Comment thread
ermshiperete marked this conversation as resolved.
Outdated
if(!KMX_SaveKeyboard(kmxfile, outfile)) {
KMX_LogError(L"Failed to save keyboard (%d)\n", errno);
return 3;
}
}

delete kmxfile;
return 0;
}
7 changes: 7 additions & 0 deletions linux/mcompile/keymap/deadkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@

#include "mc_import_rules.h"
#include <map>
#include <keymap.h>
Comment thread
Markus-SWAG marked this conversation as resolved.
Outdated

struct KMX_DeadkeyMapping { // I4353
KMX_WCHAR deadkey, dkid;
KMX_DWORD shift;
KMX_WORD vk;
};

/** @brief create a Vector of DeadKey containing all combinations of deadkey + character for ALL possible Linux keyboards */
std::vector<DeadKey*> create_deadkeys_by_basechar();
Expand Down
3 changes: 3 additions & 0 deletions linux/mcompile/keymap/mc_import_rules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include <stdio.h>
#include "mc_kmxfile.h"
#include "keymap.h"
#include "deadkey.h"

extern std::vector<KMX_DeadkeyMapping> KMX_FDeadkeys; // I4353

const int KMX_ShiftStateMap[] = {
ISVIRTUALKEY,
Expand Down
3 changes: 3 additions & 0 deletions linux/mcompile/keymap/mc_import_rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#ifndef MC_IMPORT_RULES_H
#define MC_IMPORT_RULES_H

#include <vector>
#include "km_types.h"

/** @brief Base class for Deadkey*/
class DeadKey {
private:
Expand Down
29 changes: 29 additions & 0 deletions linux/mcompile/keymap/mc_kmxfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
*/

#include "mc_kmxfile.h"
#include <km_u16.h>
#include <typeinfo>
#include <cstring>
#include <stdarg.h>


#define CERR_None 0x00000000
#define CERR_CannotAllocateMemory 0x00008004
Expand Down Expand Up @@ -582,3 +586,28 @@ FILE* Open_File(const KMX_CHAR* filename, const KMX_CHAR* mode) {
return fopen(cpath.c_str(), cmode.c_str());
Comment thread
ermshiperete marked this conversation as resolved.
Outdated
#endif
};

#define _countof(a) (sizeof(a) / sizeof(*(a)))

/**
* @brief print (error) messages
* @param fmt text to print
*/
void KMX_LogError(const wchar_t* fmt, ...) {
Comment thread
ermshiperete marked this conversation as resolved.
wchar_t fmtbuf[256];
const wchar_t* end = L"\0";
const wchar_t* nl = L"\n";
va_list vars;
int j = 0;

va_start(vars, fmt);
vswprintf(fmtbuf, _countof(fmtbuf), fmt, vars);
fmtbuf[255] = 0;

do {
putwchar(fmtbuf[j]);
j++;
} while (fmtbuf[j] != *end);
putwchar(*nl);
Comment thread
Markus-SWAG marked this conversation as resolved.
}

5 changes: 4 additions & 1 deletion linux/mcompile/keymap/mc_kmxfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include "km_types.h"
#include <kmx_file.h>
#include "mcompile.h"
#include <cstdio>

#ifndef _KMXFILE_H
#define _KMXFILE_H
Expand Down Expand Up @@ -78,6 +78,9 @@ PKMX_WCHAR KMX_incxstr(PKMX_WCHAR p);
/** @brief open a file */
FILE* Open_File(const KMX_CHAR* filename, const KMX_CHAR* mode);

/** @brief print (error) messages */
void KMX_LogError(const wchar_t* fmt, ...);

#endif // _KMXFILE_H

#endif /*MC_KMXFILE_H*/
106 changes: 3 additions & 103 deletions linux/mcompile/keymap/mcompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
*/

#include "mcompile.h"
#include "keymap.h"
#include "deadkey.h"


const int nr_DK_pairs = 1000;
static const int size_DK_array = (nr_DK_pairs + 1) *3;

/** @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard */
KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, gint argc, gchar* argv[]);

/** @brief Collect the key data, translate it to kmx and append to the existing keyboard */
bool KMX_ImportRules(LPKMX_KEYBOARD kp, vec_dword_3D& all_vector, GdkKeymap** keymap, std::vector<KMX_DeadkeyMapping>* KMX_FDeadkeys, KMX_BOOL bDeadkeyConversion); // I4353 // I4327

Expand All @@ -25,85 +25,6 @@ int KMX_GetDeadkeys(vec_dword_2D& dk_Table, KMX_WORD deadkey, std::vector<KMX_WO

std::vector<KMX_DeadkeyMapping> KMX_FDeadkeys; // I4353

#define _countof(a) (sizeof(a) / sizeof(*(a)))

/**
* @brief main function for mcompile for Linux
* @param argc number of commandline arguments
* @param argv pointer to commandline arguments: executable, inputfile, outputfile
* @return 0 on success
*/

int main(int argc, char* argv[]) {


int bDeadkeyConversion = 0;

if (argc > 1)
bDeadkeyConversion = (strcmp(argv[1], "-d") == 0); // I4552

int n = (bDeadkeyConversion ? 2 : 1);

if (argc < 3 || argc > 4 || (argc - n) != 2) { // I4273// I4273
printf(
"Usage: \tmcompile [-d] infile.kmx outfile.kmx\n"
" \tmcompile converts a Keyman mnemonic layout to\n"
" \ta positional one based on the currently used \n"
" \tLinux keyboard layout\n"
" \t(-d convert deadkeys to plain keys) \n \n"); // I4552

return 1;
}

// -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

// 1. Load the keyman keyboard file

// 2. For each key on the system layout, determine its output character and perform a
// 1-1 replacement on the keyman keyboard of that character with the base VK + shift
// state. This fixup will transform the char to a vk, which will avoid any issues
// with the key.
//
//
// For each deadkey, we need to determine its possible outputs. Then we generate a VK
// rule for that deadkey, e.g. [K_LBRKT] > dk(c101)
//
// Next, update each rule that references the output from that deadkey to add an extra
// context deadkey at the end of the context match, e.g. 'a' dk(c101) + [K_SPACE] > 'b'.
// This will require a memory layout change for the .kmx file, plus fixups on the
// context+output index offsets
//
// --> virtual character keys
//
// [CTRL ' '] : we look at the character, and replace it in the same way, but merely
// switch the shift state from the VIRTUALCHARKEY to VIRTUALKEY, without changing any
// other properties of the key.
//
// 3. Write the new keyman keyboard file

LPKMX_KEYBOARD kmxfile;

if (!KMX_LoadKeyboard(infile, &kmxfile)) {
KMX_LogError(L"Failed to load keyboard (%d)\n", errno);
return 3;
}

if (KMX_DoConvert(kmxfile, bDeadkeyConversion, argc, (gchar**)argv)) { // I4552F
if(!KMX_SaveKeyboard(kmxfile, outfile)) {
KMX_LogError(L"Failed to save keyboard (%d)\n", errno);
return 3;
}
}

delete kmxfile;
return 0;
}

// Map of all shift states that we will work with
const KMX_DWORD VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG | RALTFLAG, K_SHIFTFLAG | LCTRLFLAG | RALTFLAG, 0xFFFF};

Expand Down Expand Up @@ -555,24 +476,3 @@ int KMX_GetDeadkeys(vec_dword_2D& dk_Table, KMX_WORD deadkey, std::vector<KMX_WO
return dk_vec.size();
}

/**
* @brief print (error) messages
* @param fmt text to print
*/
void KMX_LogError(const wchar_t* fmt, ...) {
wchar_t fmtbuf[256];
const wchar_t* end = L"\0";
const wchar_t* nl = L"\n";
va_list vars;
int j = 0;

va_start(vars, fmt);
vswprintf(fmtbuf, _countof(fmtbuf), fmt, vars);
fmtbuf[255] = 0;

do {
putwchar(fmtbuf[j]);
j++;
} while (fmtbuf[j] != *end);
putwchar(*nl);
}
15 changes: 3 additions & 12 deletions linux/mcompile/keymap/mcompile.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,10 @@
#ifndef MCOMPILE_H
#define MCOMPILE_H
#include <vector>
#include "keymap.h"
#include "deadkey.h"
#include <gdk/gdk.h>
#include "mc_kmxfile.h"

struct KMX_DeadkeyMapping { // I4353
KMX_WCHAR deadkey, dkid;
KMX_DWORD shift;
KMX_WORD vk;
};

extern std::vector<KMX_DeadkeyMapping> KMX_FDeadkeys; // I4353

/** @brief print (error) messages */
void KMX_LogError(const wchar_t* fmt, ...);
/** @brief convert mnemonic keyboard layout to positional keyboard layout and translate keyboard */
KMX_BOOL KMX_DoConvert(LPKMX_KEYBOARD kbd, KMX_BOOL bDeadkeyConversion, gint argc, gchar* argv[]);

#endif /*MCOMPILE_H*/
24 changes: 21 additions & 3 deletions linux/mcompile/keymap/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ project(
gtk = dependency('gtk+-3.0', version: '>= 2.4')
xkb = dependency('xkbcommon')

giomm_dep = dependency('giomm-2.4')
glibmm_dep = dependency('glibmm-2.4')
Comment thread
ermshiperete marked this conversation as resolved.
Outdated

deps = [gtk, xkb]

subdir('resources')

cpp_files = files(
'converter.cpp',
'keymap.cpp',
'deadkey.cpp',
'mcompile.cpp',
Expand All @@ -23,13 +27,27 @@ cpp_files = files(
'../../../common/cpp/utfcodec.cpp',
)

comon_include_dir = [
include_directories('../../../common/include')
test_files = files(
'keymap.cpp',
'deadkey.cpp',
'mc_kmxfile.cpp',
'mcompile.cpp',
'mc_import_rules.cpp',
'../../../common/cpp/km_u16.cpp',
'../../../common/cpp/utfcodec.cpp',
)

common_include_dir = [
include_directories('../../../common/include','.'),
]

mcompile = executable(
'mcompile',
sources: [cpp_files],
dependencies: deps,
include_directories : comon_include_dir
include_directories : common_include_dir
)

gtest = subproject('gtest')
Comment thread
ermshiperete marked this conversation as resolved.
Outdated

subdir('test')
4 changes: 4 additions & 0 deletions linux/mcompile/keymap/subprojects/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/*.zip
/*.tgz
/packagecache
/googletest-*
Loading
Loading