mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-29 11:07:41 +00:00
chore(web): Merge branch 'refactor/web/common-layout-typing' into feat/web/base-recognizer-integration
This commit is contained in:
commit
00f119e566
365 changed files with 7668 additions and 8255 deletions
25
HISTORY.md
25
HISTORY.md
|
|
@ -1,5 +1,30 @@
|
|||
# Keyman Version History
|
||||
|
||||
## 17.0.186 alpha 2023-10-04
|
||||
|
||||
* feat(developer): show an INFO message when warnings have failed a build (#9652)
|
||||
* chore(developer): reduce duplicate words warning to hint (#9653)
|
||||
* feat(developer): issue hint if package includes keyboard source files (#9658)
|
||||
* chore(developer): switch on code coverage reporting for kmc (#9662)
|
||||
* fix(core): clean cached ICU in core (#9668)
|
||||
* feat(developer): warn if .kps includes a .js which is not touch-capable (#9667)
|
||||
|
||||
## 17.0.185 alpha 2023-10-03
|
||||
|
||||
* chore(web): Add non-printing characters to the OSK (#9547)
|
||||
* feat(developer): support `store(&version) '17.0'` (#9656)
|
||||
* chore(developer): add test for `checkFilenameConventions == false` or unset (#9661)
|
||||
* feat(developer): ldml scan codes support (#9615)
|
||||
|
||||
## 17.0.184 alpha 2023-10-02
|
||||
|
||||
* fix(web): fixes toolbar refocus timing after a keyboard change (#9618)
|
||||
|
||||
## 17.0.183 alpha 2023-09-29
|
||||
|
||||
* feat(web): browser-KMW support for default subkeys (#9496)
|
||||
* refactor(linux): Add more tests for `keymanutil.c` ️ (#9595)
|
||||
|
||||
## 17.0.182 alpha 2023-09-28
|
||||
|
||||
* chore(web): builds that output to web/build/publish should also clean it (#9613)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
17.0.183
|
||||
17.0.187
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -10,6 +10,8 @@ and consists of these engineering keyboards:
|
|||
* web/testing/chirality/chirality.js
|
||||
* web/testing/platform/platformtest.js
|
||||
|
||||
test9469.kmp is another engineering keyboard to show non-printing characters on the OSK.
|
||||
|
||||
### Compiling From Command Line
|
||||
1. Launch a command prompt to the `android/` folder
|
||||
2. Compile KMEA. This will build and copy `keyman-engine.aar` to the Samples and Test projects
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@ typedef uint8_t KMX_BYTE;
|
|||
typedef uint16_t KMX_WORD;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
typedef char16_t km_kbp_cp;
|
||||
typedef char32_t km_kbp_usv;
|
||||
typedef char16_t km_core_cp;
|
||||
typedef char32_t km_core_usv;
|
||||
#else
|
||||
typedef uint16_t km_kbp_cp; // code point
|
||||
typedef uint32_t km_kbp_usv; // Unicode Scalar Value
|
||||
typedef uint16_t km_core_cp; // code point
|
||||
typedef uint32_t km_core_usv; // Unicode Scalar Value
|
||||
#endif
|
||||
|
||||
typedef km_kbp_cp KMX_WCHAR; // wc, 16-bit UNICODE character
|
||||
typedef km_core_cp KMX_WCHAR; // wc, 16-bit UNICODE character
|
||||
typedef KMX_WCHAR* PKMX_WCHAR;
|
||||
|
||||
typedef char KMX_CHAR;
|
||||
|
|
@ -60,7 +60,7 @@ typedef KMX_DWORD* PKMX_DWORD;
|
|||
|
||||
#ifdef USE_CHAR16_T
|
||||
#define lpuch(x) u ## x
|
||||
typedef km_kbp_cp KMX_UCHAR;
|
||||
typedef km_core_cp KMX_UCHAR;
|
||||
#else
|
||||
#define lpuch(x) L ## x
|
||||
typedef wchar_t KMX_UCHAR;
|
||||
|
|
|
|||
|
|
@ -68,9 +68,10 @@ namespace kmx {
|
|||
#define VERSION_150 0x00000F00
|
||||
|
||||
#define VERSION_160 0x00001000
|
||||
#define VERSION_170 0x00001100
|
||||
|
||||
#define VERSION_MIN VERSION_50
|
||||
#define VERSION_MAX VERSION_160
|
||||
#define VERSION_MAX VERSION_170
|
||||
|
||||
//
|
||||
// Backspace types
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#endif
|
||||
#define try_status(expr) { \
|
||||
auto __s = (expr); \
|
||||
if (__s != KM_KBP_STATUS_OK) { \
|
||||
if (__s != KM_CORE_STATUS_OK) { \
|
||||
_assert_failed(__s, u ## #expr); \
|
||||
} \
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,7 @@
|
|||
"exports": {
|
||||
".": "./build/obj/index.js",
|
||||
"./lib": {
|
||||
"types": "./build/lib/index.d.ts",
|
||||
"import": "./build/lib/index.mjs",
|
||||
"require": "./build/lib/index.cjs"
|
||||
"types": "./build/lib/index.d.ts"
|
||||
},
|
||||
"./obj/*.js": "./build/obj/*.js"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@
|
|||
"exports": {
|
||||
".": "./build/obj/index.js",
|
||||
"./lib": {
|
||||
"import": "./build/lib/index.mjs",
|
||||
"require": "./build/lib/index.cjs"
|
||||
"types": "./build/lib/index.d.ts"
|
||||
},
|
||||
"./obj/*.js": "./build/obj/*.js"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<!-- Set the viewport width to match iOS device widths -->
|
||||
<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no" /> -->
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
|
||||
<!-- Enable IE9 Standards mode -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<title>LMLayer Testing</title>
|
||||
<style type='text/css'>
|
||||
body {padding-left:20px;margin-left:12px; font-family:Tahoma,Helvetica}
|
||||
h1 {color: #800;margin-left:10px;}
|
||||
h2 {color: #008;margin-left:20px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Language-Modeling Layer module testing</h1>
|
||||
<h2><a href="./simple-webworker">A simple basic WebWorker.</a></h2> Designed as a baseline functionality test we can run against various platforms as a first-stage canary of sorts.
|
||||
<h2><a href="./one-stage-embedded-webworker">An embedded WebWorker prototype.</a></h2> A prototype for directly embedding a WebWorker's code within a "master" script.
|
||||
<h2><a href="./two-stage-embedded-webworker">A better embedded WebWorker prototype.</a></h2> A prototype for two-stage compilation of a master/slave main-script/WebWorker pair.
|
||||
<h2><a href="./post-blob-webworker/">Sending code via a Blob URI</a></h2> A prototype for sending code over to a WebWorker via a Blob URI reference.
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
main.js
|
||||
main.js.map
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Compiles the Language Modeling Layer for common use in predictive text and autocorrective applications.
|
||||
# Designed for optimal compatibility with the Keyman Suite.
|
||||
#
|
||||
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
. "${THIS_SCRIPT%/*}/../../../../resources/build/build-utils.sh"
|
||||
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
|
||||
## END STANDARD BUILD SCRIPT INCLUDE
|
||||
|
||||
display_usage ( ) {
|
||||
echo "build.sh [-clean]"
|
||||
echo
|
||||
echo " -clean to erase pre-existing build products before a re-build"
|
||||
}
|
||||
|
||||
SOURCE="testing/one-stage-embedded-webworker"
|
||||
|
||||
echo "Node.js + dependencies check"
|
||||
npm install --no-optional
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Build environment setup error detected! Please ensure Node.js is installed!"
|
||||
fi
|
||||
|
||||
# A nice, extensible method for -clean operations. Add to this as necessary.
|
||||
clean ( ) {
|
||||
rm -rf "./*.js"
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Failed to erase the prior build."
|
||||
fi
|
||||
}
|
||||
|
||||
# Process command-line arguments
|
||||
while [[ $# -gt 0 ]] ; do
|
||||
key="$1"
|
||||
case $key in
|
||||
-clean)
|
||||
clean
|
||||
;;
|
||||
esac
|
||||
shift # past the processed argument
|
||||
done
|
||||
|
||||
npm run tsc -- -p $SOURCE/tsconfig.json
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Compilation failed."
|
||||
fi
|
||||
|
||||
echo "Typescript compilation successful."
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<!-- Set the viewport width to match phone and tablet device widths -->
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
||||
|
||||
<!-- Allow KeymanWeb to be saved to the iPhone home screen -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
|
||||
<!-- Enable IE9 Standards mode -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<title>Embedded WebWorker test</title>
|
||||
|
||||
<!-- Your page CSS -->
|
||||
<style type='text/css'>
|
||||
body {font-family: Tahoma,helvetica;}
|
||||
h3 {font-size: 1em;font-weight:normal;color: darkred; margin-bottom: 4px}
|
||||
.test {font-size: 1.5em; width:80%; min-height:30px; border: 1px solid gray;}
|
||||
#KeymanWebControl {width:50%;min-width:600px;}
|
||||
</style>
|
||||
|
||||
<script src="main.js"></script>
|
||||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body>
|
||||
<h2>LM Layer Testing - One-Stage Embedded WebWorkers</h2>
|
||||
<p>This page serves as a prototype for embedding a WebWorker's code within its "master" script
|
||||
across the TypeScript transpilation boundary.</p>
|
||||
<input type='text' id='txtFeedback' value="No clicks yet." readonly></input> <br>
|
||||
<script>
|
||||
var txtFeedback = document.getElementById("txtFeedback");
|
||||
txtFeedback.value = "No clicks yet.";
|
||||
</script>
|
||||
<input type='button' id='btnInput' onclick='canaryWorker.postMessage("Hello.");' value='Message the WebWorker.' />
|
||||
|
||||
<h3><a href="../index.html">Return to testing home page</a></h3>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
// Useful for passing class constructors
|
||||
type Workable<T> = {
|
||||
new (...args: any[]): T;
|
||||
// Requires a static implementation.
|
||||
onmessage(e: any): void;
|
||||
};
|
||||
|
||||
class A {
|
||||
a(x: number, y: number):number {
|
||||
return x + y;
|
||||
}
|
||||
}
|
||||
|
||||
var WorkerGlobals = {
|
||||
counter: 0,
|
||||
a: A
|
||||
}
|
||||
|
||||
class WorkerCore {
|
||||
static WorkerGlobals = WorkerGlobals;
|
||||
//static counter: number;
|
||||
|
||||
static onmessage(e: any) {
|
||||
WorkerGlobals.counter++;
|
||||
|
||||
console.log("Message received from main page: ", e.data);
|
||||
|
||||
// Forces TypeScript to interpret this line as plain JavaScript, as it uses a non-Worker definition.
|
||||
// @ts-ignore
|
||||
postMessage(WorkerGlobals.counter);
|
||||
}
|
||||
}
|
||||
|
||||
function createWorkerFromClasses(globals: object, fn: Workable<object>): Worker {
|
||||
var sep = ";\n";
|
||||
let glb = "var WorkerGlobals = " + JSON.stringify(globals);
|
||||
let wc = "var onmessage = " + fn.onmessage.toString();
|
||||
var blob = new Blob([glb, sep, wc], { type: 'text/javascript' });
|
||||
let url = URL.createObjectURL(blob);
|
||||
|
||||
return new Worker(url);
|
||||
}
|
||||
|
||||
var canaryWorker = createWorkerFromClasses(WorkerGlobals, WorkerCore);
|
||||
|
||||
canaryWorker.onmessage = function(e) {
|
||||
var counter = e.data; // Number of times the WebWorker has been messaged.
|
||||
console.log("Received message from the WebWorker: " + e.data);
|
||||
|
||||
var txtFeedback = <HTMLInputElement>document.getElementById("txtFeedback");
|
||||
txtFeedback.value = counter + " click(s)";
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": false,
|
||||
"module": "none",
|
||||
"outDir": "./",
|
||||
"inlineSources": true,
|
||||
"sourceMap": true,
|
||||
"target": "es5"
|
||||
},
|
||||
"files" : [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
// receive a message and execute its uri
|
||||
onmessage = function (e) {
|
||||
let uri = e.data.uri;
|
||||
importScripts(uri);
|
||||
};
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<!-- Set the viewport width to match phone and tablet device widths -->
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
||||
|
||||
<!-- Allow KeymanWeb to be saved to the iPhone home screen -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
|
||||
<!-- Enable IE9 Standards mode -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<title>Blob URI test</title>
|
||||
|
||||
<!-- Your page CSS -->
|
||||
<style type='text/css'>
|
||||
body {font-family: Tahoma,helvetica;}
|
||||
h3 {font-size: 1em;font-weight:normal;color: darkred; margin-bottom: 4px}
|
||||
.test {font-size: 1.5em; width:80%; min-height:30px; border: 1px solid gray;}
|
||||
#KeymanWebControl {width:50%;min-width:600px;}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
if (window.Worker) {
|
||||
var canaryWorker = new Worker('canaryWorker.js');
|
||||
|
||||
canaryWorker.onmessage = function(e) {
|
||||
var message = e.data; // Number of times the WebWorker has been messaged.
|
||||
console.log("Received message from the WebWorker: " + e.data);
|
||||
var txtFeedback = document.getElementById("txtFeedback");
|
||||
txtFeedback.value = message;
|
||||
}
|
||||
} else {
|
||||
console.error("WebWorkers are not supported in this browser!");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body>
|
||||
<h2>LM Layer Testing - Sending a function to a WebWorker via a Blob URI test</h2>
|
||||
<p>This page sends a function over to the Worker via a Blob URI, and
|
||||
expects the function to reply back.
|
||||
</p>
|
||||
<input type='text' id='txtFeedback' value="Haven't heard back yet" readonly> <br>
|
||||
<script>
|
||||
var txtFeedback = document.getElementById("txtFeedback");
|
||||
txtFeedback.value = "Have not heard back from worker";
|
||||
|
||||
function sendCode () {
|
||||
function payload () {
|
||||
postMessage('Hello, from the blobified code!');
|
||||
}
|
||||
|
||||
// Create an immediately-invoked function expression... to immediately
|
||||
// invoke the code!
|
||||
let iife = ['(', payload.toString(), '())'];
|
||||
let blob = new Blob(iife, { type: 'text/javascript' });
|
||||
let uri = URL.createObjectURL(blob);
|
||||
|
||||
// Go!
|
||||
canaryWorker.postMessage({ uri: uri });
|
||||
}
|
||||
|
||||
</script>
|
||||
<input type='button' id='btnInput' onclick='sendCode()' value='Send the source code!' />
|
||||
|
||||
<h3><a href="../index.html">Return to testing home page</a></h3>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
var counter = 0;
|
||||
|
||||
onmessage = function(e) {
|
||||
counter++;
|
||||
|
||||
console.log("Message received from main page: ", e.data);
|
||||
|
||||
postMessage(counter);
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<!-- Set the viewport width to match phone and tablet device widths -->
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
||||
|
||||
<!-- Allow KeymanWeb to be saved to the iPhone home screen -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
|
||||
<!-- Enable IE9 Standards mode -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<title>Basic WebWorker test</title>
|
||||
|
||||
<!-- Your page CSS -->
|
||||
<style type='text/css'>
|
||||
body {font-family: Tahoma,helvetica;}
|
||||
h3 {font-size: 1em;font-weight:normal;color: darkred; margin-bottom: 4px}
|
||||
.test {font-size: 1.5em; width:80%; min-height:30px; border: 1px solid gray;}
|
||||
#KeymanWebControl {width:50%;min-width:600px;}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
if(window.Worker) {
|
||||
var canaryWorker = new Worker('canaryWorker.js');
|
||||
|
||||
canaryWorker.onmessage = function(e) {
|
||||
var counter = e.data; // Number of times the WebWorker has been messaged.
|
||||
console.log("Received message from the WebWorker: " + e.data);
|
||||
|
||||
var txtFeedback = document.getElementById("txtFeedback");
|
||||
txtFeedback.value = counter + " click(s)";
|
||||
}
|
||||
} else {
|
||||
console.error("WebWorkers are not supported in this browser!");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body>
|
||||
<h2>LM Layer Testing - basic WebWorker canary</h2>
|
||||
<p>This page uses a simple WebWorker useful for ensuring functionality on various platforms.</p>
|
||||
<input type='text' id='txtFeedback' value="No clicks yet." readonly></input> <br>
|
||||
<script>
|
||||
var txtFeedback = document.getElementById("txtFeedback");
|
||||
txtFeedback.value = "No clicks yet.";
|
||||
</script>
|
||||
<input type='button' id='btnInput' onclick='canaryWorker.postMessage("Hello.");' value='Message the WebWorker.' />
|
||||
|
||||
<h3><a href="../index.html">Return to testing home page</a></h3>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
**/*.js
|
||||
**/*.js.map
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Compiles the Language Modeling Layer for common use in predictive text and autocorrective applications.
|
||||
# Designed for optimal compatibility with the Keyman Suite.
|
||||
#
|
||||
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
. "${THIS_SCRIPT%/*}/../../../../resources/build/build-utils.sh"
|
||||
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
|
||||
## END STANDARD BUILD SCRIPT INCLUDE
|
||||
|
||||
display_usage ( ) {
|
||||
echo "build.sh [-clean]"
|
||||
echo
|
||||
echo " -clean to erase pre-existing build products before a re-build"
|
||||
}
|
||||
|
||||
SOURCE="testing/two-stage-embedded-webworker"
|
||||
|
||||
COMPILED_WORKER="worker.js"
|
||||
EMBEDDED_WORKER="embedded_worker.js"
|
||||
|
||||
echo "Node.js + dependencies check"
|
||||
npm install --no-optional
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Build environment setup error detected! Please ensure Node.js is installed!"
|
||||
fi
|
||||
|
||||
# A nice, extensible method for -clean operations. Add to this as necessary.
|
||||
clean ( ) {
|
||||
rm -rf "./*.js"
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Failed to erase the prior build."
|
||||
fi
|
||||
}
|
||||
|
||||
# Process command-line arguments
|
||||
while [[ $# -gt 0 ]] ; do
|
||||
key="$1"
|
||||
case $key in
|
||||
-clean)
|
||||
clean
|
||||
;;
|
||||
esac
|
||||
shift # past the processed argument
|
||||
done
|
||||
|
||||
npm run tsc -- -p $SOURCE/worker/tsconfig.json
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Worker compilation failed."
|
||||
fi
|
||||
|
||||
rm $EMBEDDED_WORKER &> /dev/null
|
||||
|
||||
echo "var LMLayerWorker = function() {" >> $EMBEDDED_WORKER
|
||||
cat $COMPILED_WORKER >> $EMBEDDED_WORKER
|
||||
echo "" >> $EMBEDDED_WORKER
|
||||
echo "}" >> $EMBEDDED_WORKER
|
||||
|
||||
npm run tsc -- -p $SOURCE/tsconfig.json
|
||||
if [ $? -ne 0 ]; then
|
||||
builder_die "Final compilation failed."
|
||||
fi
|
||||
|
||||
echo "Typescript compilation successful."
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<!-- Set the viewport width to match phone and tablet device widths -->
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
||||
|
||||
<!-- Allow KeymanWeb to be saved to the iPhone home screen -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
|
||||
<!-- Enable IE9 Standards mode -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<title>Embedded WebWorker test</title>
|
||||
|
||||
<!-- Your page CSS -->
|
||||
<style type='text/css'>
|
||||
body {font-family: Tahoma,helvetica;}
|
||||
h3 {font-size: 1em;font-weight:normal;color: darkred; margin-bottom: 4px}
|
||||
.test {font-size: 1.5em; width:80%; min-height:30px; border: 1px solid gray;}
|
||||
#KeymanWebControl {width:50%;min-width:600px;}
|
||||
</style>
|
||||
|
||||
<script src="main.js"></script>
|
||||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body>
|
||||
<h2>LM Layer Testing - One-Stage Embedded WebWorkers</h2>
|
||||
<p>This page serves as a prototype for embedding a WebWorker's code within its "master" script
|
||||
across the TypeScript transpilation boundary.</p>
|
||||
<input type='text' id='txtFeedback' value="No clicks yet." readonly></input> <br>
|
||||
<script>
|
||||
var txtFeedback = document.getElementById("txtFeedback");
|
||||
txtFeedback.value = "No clicks yet.";
|
||||
</script>
|
||||
<input type='button' id='btnInput' onclick='canaryWorker.postMessage("Hello.");' value='Message the WebWorker.' />
|
||||
|
||||
<h3><a href="../index.html">Return to testing home page</a></h3>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
// Provides the final source for our compiled WebWorker within a wrapping function.
|
||||
/// <reference path="embedded_worker.js" />
|
||||
|
||||
function createWorker(fn: Function): Worker {
|
||||
var str_fn = fn.toString();
|
||||
|
||||
// We now unwrap our WebWorker from its function.
|
||||
var str_lines = str_fn.split("\n");
|
||||
var blob_lines = []
|
||||
|
||||
for(var i=1; i < str_lines.length -1; i++) {
|
||||
blob_lines.push(str_lines[i] + "\n");
|
||||
}
|
||||
// Unwrapping complete.
|
||||
|
||||
var blob = new Blob(blob_lines, { type: 'text/javascript' });
|
||||
let url = URL.createObjectURL(blob);
|
||||
|
||||
return new Worker(url);
|
||||
}
|
||||
|
||||
var canaryWorker = createWorker(LMLayerWorker);
|
||||
|
||||
canaryWorker.onmessage = function(e) {
|
||||
var counter = e.data; // Number of times the WebWorker has been messaged.
|
||||
console.log("Received message from the WebWorker: " + e.data);
|
||||
|
||||
var txtFeedback = <HTMLInputElement>document.getElementById("txtFeedback");
|
||||
txtFeedback.value = counter + " click(s)";
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"module": "none",
|
||||
"outFile": "./main.js",
|
||||
"inlineSources": true,
|
||||
"inlineSourceMap": true,
|
||||
"target": "es5"
|
||||
},
|
||||
"files" : [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
var counter = 0;
|
||||
|
||||
onmessage = function(e) {
|
||||
counter++;
|
||||
|
||||
console.log("Message received from main page: ", e.data);
|
||||
|
||||
postMessage(counter);
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": false,
|
||||
"module": "none",
|
||||
"outFile": "../worker.js",
|
||||
"inlineSources": true,
|
||||
"sourceMap": true,
|
||||
"lib": ["webworker", "es6"],
|
||||
"target": "es5"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Builds hextobin.js
|
||||
#
|
||||
|
||||
# Exit on command failure and when using unset variables:
|
||||
set -eu
|
||||
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
|
|
@ -22,21 +15,10 @@ cd "$THIS_SCRIPT_PATH"
|
|||
builder_describe "Build hextobin" clean configure build
|
||||
builder_describe_outputs \
|
||||
configure /node_modules \
|
||||
build build/index.js
|
||||
build /common/tools/hextobin/build/index.js
|
||||
|
||||
builder_parse "$@"
|
||||
|
||||
if builder_start_action clean; then
|
||||
npm run clean
|
||||
builder_finish_action success clean
|
||||
fi
|
||||
|
||||
if builder_start_action configure; then
|
||||
verify_npm_setup
|
||||
builder_finish_action success configure
|
||||
fi
|
||||
|
||||
if builder_start_action build; then
|
||||
npm run build
|
||||
builder_finish_action success build
|
||||
fi
|
||||
|
||||
builder_run_action clean rm -rf build/ node_modules/
|
||||
builder_run_action configure verify_npm_setup
|
||||
builder_run_action build tsc --build
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#!/usr/bin/env node
|
||||
import * as fs from 'fs';
|
||||
import * as rd from 'readline';
|
||||
import * as program from 'commander';
|
||||
import { Command } from 'commander';
|
||||
import hextobin from './index.js';
|
||||
|
||||
let inputFilename: string = "";
|
||||
let outputFilename: string = "";
|
||||
|
||||
const program = new Command();
|
||||
program
|
||||
.description(
|
||||
`Will convert the input file which is a hex dump to the output file. Hex dump can contain
|
||||
|
|
@ -43,6 +43,4 @@ function exitDueToUsageError(message: string): never {
|
|||
return process.exit(64); // SysExits.EX_USAGE
|
||||
}
|
||||
|
||||
import hextobin from './index';
|
||||
|
||||
hextobin(inputFilename, outputFilename, {silent: false});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"name": "@keymanapp/hextobin",
|
||||
"description": "hextobin conversion tool",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"keywords": [
|
||||
"keyman",
|
||||
"hex",
|
||||
|
|
@ -14,14 +16,6 @@
|
|||
"bin": {
|
||||
"hextobin": "build/hextobin.js"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "tsc -b --clean",
|
||||
"build": "tsc -b"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/keymanapp/keyman.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.7.18"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,9 @@
|
|||
{
|
||||
"extends": "../../../tsconfig-base.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"target": "ES2020",
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "node",
|
||||
"rootDir": ".",
|
||||
"outDir": "build/",
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
],
|
||||
"files": [
|
||||
"index.ts",
|
||||
"hextobin.ts"
|
||||
]
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": ".",
|
||||
"outDir": "build/"
|
||||
},
|
||||
"exclude": ["node_modules"],
|
||||
"files": ["index.ts", "hextobin.ts"]
|
||||
}
|
||||
|
|
|
|||
1
common/tools/sourcemap-path-remapper/src/convert-source-map.d.ts
vendored
Normal file
1
common/tools/sourcemap-path-remapper/src/convert-source-map.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
declare module 'convert-source-map';
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
{
|
||||
"extends": "../../../tsconfig-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"allowJs": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"declaration": true,
|
||||
"module": "es6",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": true,
|
||||
"inlineSources": true,
|
||||
"sourceRoot": "/common/tools/sourcemap-path-remapper/src",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.esm-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"outDir": "build/",
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ export class HostFixtureLayoutController extends EventEmitter {
|
|||
};
|
||||
};
|
||||
|
||||
private _setup: () => boolean = function(this: HostFixtureLayoutController) {
|
||||
private _setup: () => void = function(this: HostFixtureLayoutController) {
|
||||
let config = this.buildBaseFixtureConfig();
|
||||
this._recognizer = new GestureRecognizer<any>(null /* TODO */, config);
|
||||
this._hostFixture = document.getElementById('host-fixture');
|
||||
|
|
|
|||
|
|
@ -51,6 +51,12 @@ class ActiveKeyBase {
|
|||
_baseKeyEvent: KeyEvent;
|
||||
isMnemonic: boolean = false;
|
||||
|
||||
/**
|
||||
* Only available on subkeys, but we don't distinguish between base keys and subkeys
|
||||
* at this level yet in KMW.
|
||||
*/
|
||||
default?: boolean;
|
||||
|
||||
proportionalPad: number;
|
||||
proportionalX: number;
|
||||
proportionalWidth: number;
|
||||
|
|
@ -207,7 +213,7 @@ class ActiveKeyBase {
|
|||
rawKey.sp ||= 0; // The default button class.
|
||||
}
|
||||
|
||||
static polyfill(key: LayoutKey, keyboard: Keyboard, layout: ActiveLayout, displayLayer: string) {
|
||||
static polyfill(key: LayoutKey | LayoutSubKey, keyboard: Keyboard, layout: ActiveLayout, displayLayer: string) {
|
||||
// Add class functions to the existing layout object, allowing it to act as an ActiveLayout.
|
||||
let dummy = new ActiveKeyBase();
|
||||
let proto = Object.getPrototypeOf(dummy);
|
||||
|
|
@ -225,8 +231,8 @@ class ActiveKeyBase {
|
|||
}
|
||||
|
||||
// Ensure subkeys are also properly extended.
|
||||
if(key.sk) {
|
||||
for(let subkey of key.sk) {
|
||||
if((key as LayoutKey).sk) {
|
||||
for(let subkey of (key as LayoutKey).sk) {
|
||||
ActiveSubkey.polyfill(subkey, keyboard, layout, displayLayer);
|
||||
}
|
||||
}
|
||||
|
|
@ -235,6 +241,8 @@ class ActiveKeyBase {
|
|||
aKey.displayLayer = displayLayer;
|
||||
aKey.layer = aKey.layer || displayLayer;
|
||||
|
||||
aKey.default = (key as LayoutSubKey).default;
|
||||
|
||||
// Compute the key's base KeyEvent properties for use in future event generation
|
||||
aKey.constructBaseKeyEvent(keyboard, layout, displayLayer);
|
||||
}
|
||||
|
|
@ -299,10 +307,6 @@ class ActiveKeyBase {
|
|||
|
||||
|
||||
export class ActiveKey extends ActiveKeyBase implements LayoutKey {
|
||||
public polyfill() {
|
||||
|
||||
}
|
||||
|
||||
public getSubkey(coreID: string): ActiveKey {
|
||||
if(this.sk) {
|
||||
for(let key of this.sk) {
|
||||
|
|
|
|||
|
|
@ -22,8 +22,11 @@ export type KLS = {[layerName: string]: string[]};
|
|||
export type ButtonClass = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
|
||||
export type ButtonClassString = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"|"10";
|
||||
|
||||
export interface LayoutLayer extends LayoutLayerBase {
|
||||
// Post-processing elements tracked by Web.
|
||||
export type LayoutLayer = {
|
||||
"id": string,
|
||||
"row": LayoutRow[],
|
||||
|
||||
// Post-processing elements.
|
||||
shiftKey?: LayoutKey,
|
||||
capsKey?: LayoutKey,
|
||||
numKey?: LayoutKey,
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Bundles @keymanapp/keyman-version as a single-file CommonJS module for components
|
||||
* still in need of it.
|
||||
*/
|
||||
|
||||
import esbuild from 'esbuild';
|
||||
|
||||
// Bundles to a compact ESModule
|
||||
esbuild.buildSync({
|
||||
entryPoints: ['build/version.inc.js'],
|
||||
bundle: true,
|
||||
sourcemap: true,
|
||||
//minify: true, // No need to minify a module.
|
||||
//keepNames: true,
|
||||
format: "cjs",
|
||||
// Sets 'common/web' as a root folder for module resolution;
|
||||
// this allows the keyman-version import to resolve.
|
||||
nodePaths: ['..'],
|
||||
outfile: "build/version.inc.cjs",
|
||||
tsconfig: 'tsconfig.json',
|
||||
target: "es5"
|
||||
});
|
||||
|
|
@ -1,11 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Builds the include script for the current Keyman version.
|
||||
#
|
||||
|
||||
# Exit on command failure and when using unset variables:
|
||||
set -eu
|
||||
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
|
|
@ -13,6 +6,7 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
|||
## END STANDARD BUILD SCRIPT INCLUDE
|
||||
|
||||
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
|
||||
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
|
||||
|
||||
# This script runs from its own folder
|
||||
cd "$THIS_SCRIPT_PATH"
|
||||
|
|
@ -25,8 +19,7 @@ builder_describe "Build the include script for current Keyman version" \
|
|||
build \
|
||||
"pack build a local .tgz pack for testing" \
|
||||
"publish publish to npm" \
|
||||
test \
|
||||
--dry-run
|
||||
test
|
||||
|
||||
builder_describe_outputs \
|
||||
configure "/node_modules" \
|
||||
|
|
@ -34,21 +27,7 @@ builder_describe_outputs \
|
|||
|
||||
builder_parse "$@"
|
||||
|
||||
|
||||
if builder_start_action configure; then
|
||||
verify_npm_setup
|
||||
builder_finish_action success configure
|
||||
fi
|
||||
|
||||
if builder_start_action clean; then
|
||||
npm run clean
|
||||
rm -f ./version.inc.ts
|
||||
rm -f ./keyman-version.mts
|
||||
rm -rf build
|
||||
builder_finish_action success clean
|
||||
fi
|
||||
|
||||
if builder_start_action build; then
|
||||
function do_build() {
|
||||
# Generate version.inc.ts
|
||||
echo "
|
||||
// Generated by common/web/keyman-version/build.sh
|
||||
|
|
@ -72,22 +51,11 @@ export class KEYMAN_VERSION {
|
|||
export default KEYMAN_VERSION;
|
||||
" > ./version.inc.ts
|
||||
|
||||
tsc -b $builder_verbose
|
||||
# kmlmc (the lexical model compiler) relies on a Node-based import, but after some of the earlier
|
||||
# ES-modularization work, our main output's an ES module. Fortunately, esbuild can provide an easy stopgap.
|
||||
tsc --build $builder_verbose
|
||||
}
|
||||
|
||||
# Generates a CommonJS variant (in case other modules still need it).
|
||||
node ./build-bundler.js
|
||||
|
||||
builder_finish_action success build
|
||||
fi
|
||||
|
||||
if builder_start_action publish; then
|
||||
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
|
||||
builder_publish_to_npm
|
||||
builder_finish_action success publish
|
||||
elif builder_start_action pack; then
|
||||
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
|
||||
builder_publish_to_pack
|
||||
builder_finish_action success pack
|
||||
fi
|
||||
builder_run_action clean rm -rf version.inc.ts keyman-version.mts build/
|
||||
builder_run_action configure verify_npm_setup
|
||||
builder_run_action build do_build
|
||||
builder_run_action publish builder_publish_to_npm
|
||||
builder_run_action pack builder_publish_to_pack
|
||||
|
|
|
|||
|
|
@ -1,26 +1,15 @@
|
|||
{
|
||||
"name": "@keymanapp/keyman-version",
|
||||
"description": "Keyman global version data",
|
||||
"main": "./build/version.inc.cjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./build/version.inc.js",
|
||||
"require": "./build/version.inc.cjs"
|
||||
},
|
||||
"./build/version.inc.cjs": "./build/version.inc.cjs"
|
||||
".": "./build/version.inc.js"
|
||||
},
|
||||
"files": [
|
||||
"/build/"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "echo 'Building @keymanapp/keyman-version' && tsc -b",
|
||||
"clean": "tsc -b --clean",
|
||||
"tsc": "tsc"
|
||||
},
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.4.1",
|
||||
"typescript": "^4.9.5"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,12 @@
|
|||
{
|
||||
"extends": "../../../tsconfig-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"allowJs": false,
|
||||
"declaration": true,
|
||||
"module": "es6",
|
||||
"sourceMap": true,
|
||||
"outDir": "./build",
|
||||
"lib": ["es6"],
|
||||
"target": "es5",
|
||||
"downlevelIteration": true,
|
||||
"rootDir": "."
|
||||
},
|
||||
|
||||
"include": [
|
||||
"version.inc.ts"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../tsconfig-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"module": "none",
|
||||
|
|
|
|||
|
|
@ -1,13 +1,22 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig-base.json",
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
|
||||
// TODO: These override /tsconfig.base.json settings, and so should be removed if possible,
|
||||
// but existing code in web/ breaks some of these settinsg
|
||||
"noImplicitThis": false,
|
||||
"noImplicitReturns": false,
|
||||
"noImplicitAny": false,
|
||||
"strictFunctionTypes": false,
|
||||
"noUnusedLocals": false,
|
||||
|
||||
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"baseUrl": "./",
|
||||
"inlineSources": true,
|
||||
"lib": ["es6", "dom"],
|
||||
"module": "es6",
|
||||
"moduleResolution": "Node16",
|
||||
"outDir": "../build/obj",
|
||||
"rootDir": "./",
|
||||
"sourceMap": true,
|
||||
|
|
|
|||
|
|
@ -122,8 +122,8 @@ export const USVirtualKeyCodes = {
|
|||
*/
|
||||
K_oE2:226,
|
||||
K_OE2:226,
|
||||
k_oC1:193, // ISO B11, ABNT-2 key to left of right shift, not on US keyboard
|
||||
k_OC1:193,
|
||||
K_oC1:193, // ISO B11, ABNT-2 key to left of right shift, not on US keyboard
|
||||
K_OC1:193,
|
||||
'K_?C1':193,
|
||||
'k_?C1':193,
|
||||
K_oDF:0xDF,
|
||||
|
|
@ -144,125 +144,90 @@ export const USVirtualKeyCodes = {
|
|||
|
||||
const k = USVirtualKeyCodes;
|
||||
|
||||
/** Map a CLDR scancode to a US VKey ala USVirtualKeyCodes */
|
||||
export const CLDRScanToUSVirtualKeyCodes = {
|
||||
0x02: k.K_1,
|
||||
0x03: k.K_2,
|
||||
0x04: k.K_3,
|
||||
0x05: k.K_4,
|
||||
0x06: k.K_5,
|
||||
0x07: k.K_6,
|
||||
0x08: k.K_7,
|
||||
0x09: k.K_8,
|
||||
0x0A: k.K_9,
|
||||
0x0B: k.K_0,
|
||||
0x0C: k.K_HYPHEN,
|
||||
0x0D: k.K_EQUAL,
|
||||
|
||||
0x10: k.K_Q,
|
||||
0x11: k.K_W,
|
||||
0x12: k.K_E,
|
||||
0x13: k.K_R,
|
||||
0x14: k.K_T,
|
||||
0x15: k.K_Y,
|
||||
0x16: k.K_U,
|
||||
0x17: k.K_I,
|
||||
0x18: k.K_O,
|
||||
0x19: k.K_P,
|
||||
0x1A: k.K_LBRKT,
|
||||
0x1B: k.K_RBRKT,
|
||||
|
||||
0x1E: k.K_A,
|
||||
0x1F: k.K_S,
|
||||
0x20: k.K_D,
|
||||
0x21: k.K_F,
|
||||
0x22: k.K_G,
|
||||
0x23: k.K_H,
|
||||
0x24: k.K_J,
|
||||
0x25: k.K_K,
|
||||
0x26: k.K_L,
|
||||
0x27: k.K_COLON,
|
||||
0x28: k.K_QUOTE,
|
||||
0x29: k.K_BKQUOTE,
|
||||
|
||||
0x2B: k.K_BKSLASH,
|
||||
0x2C: k.K_Z,
|
||||
0x2D: k.K_X,
|
||||
0x2E: k.K_C,
|
||||
0x2F: k.K_V,
|
||||
0x30: k.K_B,
|
||||
0x31: k.K_N,
|
||||
0x32: k.K_M,
|
||||
0x33: k.K_COMMA,
|
||||
0x34: k.K_PERIOD,
|
||||
0x35: k.K_SLASH,
|
||||
|
||||
0x39: k.K_SPACE,
|
||||
|
||||
0x56: k.K_oE2, // << Same as 0x7D; found on iso, abnt2
|
||||
0x73: k.K_oC1,
|
||||
0x7D: k.K_oE2, // << Same as 0x56; found on jis
|
||||
|
||||
};
|
||||
|
||||
export type KeyMap = number[][];
|
||||
|
||||
export const USVirtualKeyMap: KeyMap = [
|
||||
// ` 1 2 3 4 5 6 7 8 9 0 - = [bksp]
|
||||
[ k.K_BKQUOTE, k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL ],
|
||||
// [tab] Q W E R T Y U I O P [ ] \
|
||||
[ k.K_Q, k.K_W, k.K_E, k.K_R, k.K_T, k.K_Y, k.K_U, k.K_I, k.K_O, k.K_P, k.K_LBRKT, k.K_RBRKT, k.K_BKSLASH ],
|
||||
// [caps] A S D F G H J K L ; ' [enter]
|
||||
[ k.K_A, k.K_S, k.K_D, k.K_F, k.K_G, k.K_H, k.K_J, k.K_K, k.K_L, k.K_COLON, k.K_QUOTE ],
|
||||
// [shift] Z X C V B N M , . / [shift] *=oE2
|
||||
[ k.K_Z, k.K_X, k.K_C, k.K_V, k.K_B, k.K_N, k.K_M, k.K_COMMA, k.K_PERIOD, k.K_SLASH ],
|
||||
// space
|
||||
[ k.K_SPACE ],
|
||||
];
|
||||
|
||||
export const ISOVirtualKeyMap: KeyMap = [
|
||||
// ` 1 2 3 4 5 6 7 8 9 0 - = [bksp]
|
||||
[ k.K_BKQUOTE, k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL ],
|
||||
// [tab] Q W E R T Y U I O P [ ]
|
||||
[ k.K_Q, k.K_W, k.K_E, k.K_R, k.K_T, k.K_Y, k.K_U, k.K_I, k.K_O, k.K_P, k.K_LBRKT, k.K_RBRKT ],
|
||||
// [caps] A S D F G H J K L ; ' \ [enter]
|
||||
[ k.K_A, k.K_S, k.K_D, k.K_F, k.K_G, k.K_H, k.K_J, k.K_K, k.K_L, k.K_COLON, k.K_QUOTE, k.K_BKSLASH ],
|
||||
// [shift] * Z X C V B N M , . / [shift] *=oE2
|
||||
[ k.K_oE2, k.K_Z, k.K_X, k.K_C, k.K_V, k.K_B, k.K_N, k.K_M, k.K_COMMA, k.K_PERIOD, k.K_SLASH ],
|
||||
// space
|
||||
[ k.K_SPACE ],
|
||||
];
|
||||
|
||||
export const JISVirtualKeyMap: KeyMap = [
|
||||
// [Hankaku/Zenkaku] 1 2 3 4 5 6 7 8 9 0 - ^ ¥ [bksp]
|
||||
[ k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL, k.K_BKSLASH /* YEN */ ],
|
||||
// [tab] Q W E R T Y U I O P @«`» [ [enter]
|
||||
[ k.K_Q, k.K_W, k.K_E, k.K_R, k.K_T, k.K_Y, k.K_U, k.K_I, k.K_O, k.K_P, k.K_BKQUOTE, k.K_LBRKT ],
|
||||
// [caps] A S D F G H J K L ; : ] [enter]
|
||||
[ k.K_A, k.K_S, k.K_D, k.K_F, k.K_G, k.K_H, k.K_J, k.K_K, k.K_L, k.K_COLON, k.K_QUOTE, k.K_RBRKT ],
|
||||
// [shift] Z X C V B N M , . / _ [shift]
|
||||
[ k.K_Z, k.K_X, k.K_C, k.K_V, k.K_B, k.K_N, k.K_M, k.K_COMMA, k.K_PERIOD, k.K_SLASH, k.K_oE2 /* ろ */ ],
|
||||
// space
|
||||
[ k.K_SPACE ],
|
||||
];
|
||||
|
||||
export const ABNT2VirtualKeyMap: KeyMap = [
|
||||
// ' 1 2 3 4 5 6 7 8 9 0 - = [bksp]
|
||||
[ k.K_BKQUOTE, k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL ],
|
||||
// [tab] Q W E R T Y U I O P ´ [
|
||||
[ k.K_Q, k.K_W, k.K_E, k.K_R, k.K_T, k.K_Y, k.K_U, k.K_I, k.K_O, k.K_P, k.K_LBRKT, k.K_RBRKT ],
|
||||
// [caps] A S D F G H J K L ç ~ ] [enter]
|
||||
[ k.K_A, k.K_S, k.K_D, k.K_F, k.K_G, k.K_H, k.K_J, k.K_K, k.K_L, k.K_COLON, k.K_QUOTE, k.K_BKSLASH ],
|
||||
// [shift] \ Z X C V B N M , . ; / [shift]
|
||||
[ k.K_oE2, k.K_Z, k.K_X, k.K_C, k.K_V, k.K_B, k.K_N, k.K_M, k.K_COMMA, k.K_PERIOD, k.K_SLASH, k.k_oC1 /* ABNT2 */ ],
|
||||
// space
|
||||
[ k.K_SPACE ],
|
||||
];
|
||||
|
||||
/**
|
||||
* Map from a hardware constant to a keymap
|
||||
* For the 'key' see constants.layr_list_hardware_map
|
||||
* Convert a scan code numerical KeyMap to VKeys
|
||||
* @param scans keymap to convert
|
||||
* @param badScans output: set of not-found scancodes
|
||||
* @returns
|
||||
*/
|
||||
export const HardwareToKeymap: Map<string, KeyMap> = new Map(
|
||||
[
|
||||
["us", USVirtualKeyMap],
|
||||
["iso", ISOVirtualKeyMap],
|
||||
["jis", JISVirtualKeyMap],
|
||||
["abnt2", ABNT2VirtualKeyMap],
|
||||
]
|
||||
);
|
||||
export function CLDRScanToKeyMap(scans: KeyMap, badScans?: Set<number>): KeyMap {
|
||||
return scans.map((row) => row.map((scan) => CLDRScanToVkey(scan, badScans)));
|
||||
}
|
||||
|
||||
/** Convert one scan code to vkey, or undefined */
|
||||
export function CLDRScanToVkey(scan: number, badScans?: Set<number>): number {
|
||||
/** typescript fun to index the scan table */
|
||||
function hasScanCode(key: PropertyKey): key is keyof typeof CLDRScanToUSVirtualKeyCodes {
|
||||
return key in CLDRScanToUSVirtualKeyCodes;
|
||||
}
|
||||
if (hasScanCode(scan)) {
|
||||
return CLDRScanToUSVirtualKeyCodes[scan];
|
||||
} else {
|
||||
badScans?.add(scan);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps LDML VKey Names from CLDR VKey Enum in TR35 to Keyman virtual key codes
|
||||
*/
|
||||
export const LdmlVkeyNames: Record<string, number> = {
|
||||
'SPACE': k.K_SPACE, // 0x20, // A03
|
||||
'0': k.K_0, // 0x30, // E10
|
||||
'1': k.K_1, // 0x31, // E01
|
||||
'2': k.K_2, // 0x32, // E02
|
||||
'3': k.K_3, // 0x33, // E03
|
||||
'4': k.K_4, // 0x34, // E04
|
||||
'5': k.K_5, // 0x35, // E05
|
||||
'6': k.K_6, // 0x36, // E06
|
||||
'7': k.K_7, // 0x37, // E07
|
||||
'8': k.K_8, // 0x38, // E08
|
||||
'9': k.K_9, // 0x39, // E09
|
||||
'A': k.K_A, // 0x41, // C01
|
||||
'B': k.K_B, // 0x42, // B05
|
||||
'C': k.K_C, // 0x43, // B03
|
||||
'D': k.K_D, // 0x44, // C03
|
||||
'E': k.K_E, // 0x45, // D03
|
||||
'F': k.K_F, // 0x46, // C04
|
||||
'G': k.K_G, // 0x47, // C05
|
||||
'H': k.K_H, // 0x48, // C06
|
||||
'I': k.K_I, // 0x49, // D08
|
||||
'J': k.K_J, // 0x4A, // C07
|
||||
'K': k.K_K, // 0x4B, // C08
|
||||
'L': k.K_L, // 0x4C, // C09
|
||||
'M': k.K_M, // 0x4D, // B07
|
||||
'N': k.K_N, // 0x4E, // B06
|
||||
'O': k.K_O, // 0x4F, // D09
|
||||
'P': k.K_P, // 0x50, // D10
|
||||
'Q': k.K_Q, // 0x51, // D01
|
||||
'R': k.K_R, // 0x52, // D04
|
||||
'S': k.K_S, // 0x53, // C02
|
||||
'T': k.K_T, // 0x54, // D05
|
||||
'U': k.K_U, // 0x55, // D07
|
||||
'V': k.K_V, // 0x56, // B05
|
||||
'W': k.K_W, // 0x57, // D02
|
||||
'X': k.K_X, // 0x58, // B02
|
||||
'Y': k.K_Y, // 0x59, // D06
|
||||
'Z': k.K_Z, // 0x5A, // B01
|
||||
'SEMICOLON': k.K_COLON, // 0xBA, // C10
|
||||
'EQUAL': k.K_EQUAL, // 0xBB, // E12
|
||||
'COMMA': k.K_COMMA, // 0xBC, // B08
|
||||
'HYPHEN': k.K_HYPHEN, // 0xBD, // E11
|
||||
'PERIOD': k.K_PERIOD, // 0xBE, // B09
|
||||
'SLASH': k.K_SLASH, // 0xBF, // B10
|
||||
'GRAVE': k.K_BKQUOTE, // 0xC0, // E00
|
||||
'LBRACKET': k.K_LBRKT, // 0xDB, // D11
|
||||
'BACKSLASH': k.K_BKSLASH, // 0xDC, // D13
|
||||
'RBRACKET': k.K_RBRKT, // 0xDD, // D12
|
||||
'QUOTE': k.K_QUOTE, // 0xDE, // C11
|
||||
'LESS-THAN': k.K_oE2, // 0xE2, // B00 102nd key on European layouts, right of left shift.
|
||||
'ABNT2': k.k_oC1, // 0xC1, // B11 Extra key, left of right-shift, ABNT2
|
||||
};
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ export class ElementString extends Array<ElemElement> {
|
|||
* @param source if a string array, does not get reinterpreted as UnicodeSet. This is used with vars, etc. Or pass `["str"]` for an explicit 1-element elem.
|
||||
* If it is a string, will be interpreted per reorder element rules.
|
||||
*/
|
||||
constructor(sections: DependencySections, source: string | string[], order?: string, tertiary?: string, tertiary_base?: string, prebase?: string) {
|
||||
super();
|
||||
//TODO-LDML: full UnicodeSet and parsing
|
||||
static fromStrings(sections: DependencySections, source: string | string[], order?: string, tertiary?: string, tertiary_base?: string, prebase?: string) : ElementString {
|
||||
// the returned array
|
||||
const array = new ElementString();
|
||||
if(!source) {
|
||||
return;
|
||||
return array;
|
||||
}
|
||||
|
||||
let items : ElementSegment[];
|
||||
|
|
@ -80,16 +80,16 @@ export class ElementString extends Array<ElemElement> {
|
|||
throw Error(`Could not parse uset ${item.segment}`);
|
||||
}
|
||||
elem.uset = sections.uset.allocUset(uset, sections);
|
||||
elem.value = sections.strs.allocString('', true); // no string
|
||||
elem.value = sections.strs.allocString('', {singleOk: true}); // no string
|
||||
} else if (item.type === ElementType.codepoint || item.type === ElementType.escaped || item.type === ElementType.string) {
|
||||
// some kind of a string
|
||||
let str = item.segment;
|
||||
if (item.type === ElementType.escaped && !MATCH_HEX_ESCAPE.test(str)) {
|
||||
str = unescapeOneQuadString(str);
|
||||
// TODO-LDML: any other escape forms here?
|
||||
elem.value = sections.strs.allocString(str, true);
|
||||
elem.value = sections.strs.allocString(str, { singleOk: true });
|
||||
} else {
|
||||
elem.value = sections.strs.allocAndUnescapeString(str, true);
|
||||
elem.value = sections.strs.allocString(str, { unescape: true, singleOk: true });
|
||||
}
|
||||
// Now did we end up with one char or no?
|
||||
if (elem.value.isOneChar) {
|
||||
|
|
@ -104,8 +104,9 @@ export class ElementString extends Array<ElemElement> {
|
|||
(ElemElementFlags.type & typeFlag) |
|
||||
(tertiary_bases?.[i] == '1' /* TODO-LDML: or 'true'? */ ? ElemElementFlags.tertiary_base : 0) |
|
||||
(prebases?.[i] == '1' /* TODO-LDML: or 'true'? */ ? ElemElementFlags.prebase : 0);
|
||||
this.push(elem);
|
||||
array.push(elem);
|
||||
};
|
||||
return array;
|
||||
}
|
||||
isEqual(a: ElementString): boolean {
|
||||
if (a.length != this.length) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { BUILDER_SECTION } from "./builder-section.js";
|
|||
* List of layers, the <layers> element
|
||||
*/
|
||||
interface BUILDER_LAYR_LIST {
|
||||
hardware: number; // hardware indicator
|
||||
hardware: BUILDER_STR_REF; // hardware or 'touch'
|
||||
layer: number; // index of first layer in the list, in the
|
||||
count: number; // number of layer entries in the list
|
||||
minDeviceWidth: number; // width in millimeters
|
||||
|
|
@ -82,7 +82,7 @@ export function build_layr(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS, sect_l
|
|||
|
||||
layr.lists = kmxplus.layr.lists.map((list) => {
|
||||
const blist: BUILDER_LAYR_LIST = {
|
||||
hardware: list.hardware,
|
||||
hardware: build_strs_index(sect_strs, list.hardware),
|
||||
layer: null, // to be set below
|
||||
_layers: list.layers,
|
||||
count: list.layers.length,
|
||||
|
|
@ -92,6 +92,7 @@ export function build_layr(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS, sect_l
|
|||
});
|
||||
// now sort the lists
|
||||
layr.lists.sort((a, b) => {
|
||||
// sort by string #
|
||||
if (a.hardware < b.hardware) {
|
||||
return -1;
|
||||
} else if (a.hardware > b.hardware) {
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
import { constants } from '@keymanapp/ldml-keyboard-constants';
|
||||
import { KMXPlusData } from "../kmx-plus.js";
|
||||
import { BUILDER_SECTION } from './builder-section.js';
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* vkey section
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* Builder for the 'vkey' section
|
||||
*/
|
||||
interface BUILDER_VKEY_ITEM {
|
||||
vkey: number;
|
||||
target: number;
|
||||
};
|
||||
|
||||
export interface BUILDER_VKEY extends BUILDER_SECTION {
|
||||
count: number;
|
||||
items: BUILDER_VKEY_ITEM[];
|
||||
};
|
||||
|
||||
export function build_vkey(kmxplus: KMXPlusData): BUILDER_VKEY {
|
||||
if(!kmxplus.vkey.vkeys.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let vkey: BUILDER_VKEY = {
|
||||
ident: constants.hex_section_id(constants.section.vkey),
|
||||
size: constants.length_vkey + constants.length_vkey_item * kmxplus.vkey.vkeys.length,
|
||||
_offset: 0,
|
||||
count: kmxplus.vkey.vkeys.length,
|
||||
items: []
|
||||
};
|
||||
|
||||
for(let item of kmxplus.vkey.vkeys) {
|
||||
vkey.items.push({
|
||||
vkey: item.vkey,
|
||||
target: item.target
|
||||
});
|
||||
}
|
||||
|
||||
return vkey;
|
||||
}
|
||||
|
|
@ -15,7 +15,6 @@ import { BUILDER_STRS, build_strs } from './build-strs.js';
|
|||
import { BUILDER_TRAN, build_tran } from './build-tran.js';
|
||||
import { BUILDER_USET, build_uset } from './build-uset.js';
|
||||
import { BUILDER_VARS, build_vars } from './build-vars.js';
|
||||
import { BUILDER_VKEY, build_vkey } from './build-vkey.js';
|
||||
|
||||
type BUILDER_BKSP = BUILDER_TRAN;
|
||||
// type BUILDER_FINL = BUILDER_TRAN;
|
||||
|
|
@ -36,7 +35,6 @@ type SectionBuilders = {
|
|||
tran?: BUILDER_TRAN;
|
||||
uset?: BUILDER_USET;
|
||||
vars?: BUILDER_VARS;
|
||||
vkey?: BUILDER_VKEY;
|
||||
};
|
||||
|
||||
export default class KMXPlusBuilder {
|
||||
|
|
@ -73,7 +71,6 @@ export default class KMXPlusBuilder {
|
|||
this.emitSection(file, this.file.COMP_PLUS_TRAN, this.sect.tran);
|
||||
this.emitSection(file, this.file.COMP_PLUS_USET, this.sect.uset);
|
||||
this.emitSection(file, this.file.COMP_PLUS_VARS, this.sect.vars);
|
||||
this.emitSection(file, this.file.COMP_PLUS_VKEY, this.sect.vkey);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
|
@ -100,7 +97,6 @@ export default class KMXPlusBuilder {
|
|||
this.sect.tran = build_tran(this.file.kmxplus.tran, this.sect.strs, this.sect.elem);
|
||||
this.sect.uset = build_uset(this.file.kmxplus, this.sect.strs);
|
||||
this.sect.vars = build_vars(this.file.kmxplus, this.sect.strs, this.sect.elem, this.sect.list);
|
||||
this.sect.vkey = build_vkey(this.file.kmxplus);
|
||||
|
||||
// Finalize the sect (index) section
|
||||
|
||||
|
|
@ -138,7 +134,6 @@ export default class KMXPlusBuilder {
|
|||
offset = this.finalize_sect_item(this.sect.tran, offset);
|
||||
offset = this.finalize_sect_item(this.sect.uset, offset);
|
||||
offset = this.finalize_sect_item(this.sect.vars, offset);
|
||||
offset = this.finalize_sect_item(this.sect.vkey, offset);
|
||||
|
||||
this.sect.sect.total = offset;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,14 +35,14 @@ export class Elem extends Section {
|
|||
strings: ElementString[] = [];
|
||||
constructor(sections: DependencySections) {
|
||||
super();
|
||||
this.strings.push(new ElementString(sections, '')); // C7043: null element string
|
||||
this.strings.push(ElementString.fromStrings(sections, '')); // C7043: null element string
|
||||
}
|
||||
/**
|
||||
* @param source if a string array, does not get reinterpreted as UnicodeSet. This is used with vars, etc. Or pass `["str"]` for an explicit 1-element elem.
|
||||
* If it is a string, will be interpreted per reorder element ruls.
|
||||
*/
|
||||
allocElementString(sections: DependencySections, source: string | string[], order?: string, tertiary?: string, tertiary_base?: string, prebase?: string): ElementString {
|
||||
let s = new ElementString(sections, source, order, tertiary, tertiary_base, prebase);
|
||||
let s = ElementString.fromStrings(sections, source, order, tertiary, tertiary_base, prebase);
|
||||
let result = this.strings.find(item => item.isEqual(s));
|
||||
if(result === undefined) {
|
||||
result = s;
|
||||
|
|
@ -143,45 +143,67 @@ export class CharStrsItem extends StrsItem {
|
|||
}
|
||||
};
|
||||
|
||||
/** class for string manipulation options. These are in order of the pipeline. */
|
||||
export interface StrsOptions {
|
||||
/** apply string variables (requires sections) */
|
||||
stringVariables?: boolean;
|
||||
/** apply markers (requires sections) */
|
||||
markers?: boolean;
|
||||
/** unescape with unescapeString */
|
||||
unescape?: boolean;
|
||||
/** string can be stored as a single CharStrsItem, not in strs table. */
|
||||
singleOk?: boolean;
|
||||
};
|
||||
|
||||
export class Strs extends Section {
|
||||
strings: StrsItem[] = [ new StrsItem('') ]; // C7043: The null string is always requierd
|
||||
/**
|
||||
* Allocate a StrsItem given the string, unescaping if necessary.
|
||||
* @param s escaped string
|
||||
* @param singleOk if true, allocate a CharStrsItem (not in strs table) if single-char capable.
|
||||
* @returns
|
||||
* @param opts options for allocation
|
||||
* @param sections other sections, if needed
|
||||
* @returns StrsItem
|
||||
*/
|
||||
allocAndUnescapeString(s?: string, singleOk?: boolean): StrsItem {
|
||||
return this.allocString(unescapeString(s), singleOk);
|
||||
}
|
||||
/**
|
||||
* Allocate a StrsItem given the string.
|
||||
* @param s string
|
||||
* @param singleOk if true, allocate a CharStrsItem (not in strs table) if single-char capable.
|
||||
* @returns
|
||||
*/
|
||||
allocString(s?: string, singleOk?: boolean): StrsItem {
|
||||
if(s === undefined || s === null) {
|
||||
// undefined or null are always equivalent to empty string, see C7043
|
||||
s = '';
|
||||
}
|
||||
allocString(s?: string, opts?: StrsOptions, sections?: DependencySections): StrsItem {
|
||||
// Run the string processing pipeline
|
||||
s = Strs.processString(s, opts, sections);
|
||||
|
||||
if(typeof s !== 'string') {
|
||||
throw new Error('alloc_string: s must be a string, undefined, or null.');
|
||||
}
|
||||
|
||||
// if it's a single char, don't push it into the list
|
||||
if (singleOk && isOneChar(s)) {
|
||||
// if it's a single char, don't push it into the strs table
|
||||
if (opts?.singleOk && isOneChar(s)) {
|
||||
return new CharStrsItem(s);
|
||||
}
|
||||
|
||||
// default: look to see if the string is already present
|
||||
let result = this.strings.find(item => item.value === s);
|
||||
if(result === undefined) {
|
||||
// only add if not already present
|
||||
result = new StrsItem(s);
|
||||
this.strings.push(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** process everything according to opts */
|
||||
static processString(s: string, opts: StrsOptions, sections: DependencySections) {
|
||||
s = s ?? '';
|
||||
// type check everything else
|
||||
if (typeof s !== 'string') {
|
||||
throw new Error('alloc_string: s must be a string, undefined, or null.');
|
||||
}
|
||||
// substitute variables
|
||||
if (opts?.stringVariables) {
|
||||
s = sections.vars.substituteStrings(s, sections);
|
||||
}
|
||||
// substitute markers
|
||||
if (opts?.markers) {
|
||||
s = sections.vars.substituteMarkerString(s);
|
||||
}
|
||||
// unescape \u{…}
|
||||
if (opts?.unescape) {
|
||||
s = unescapeString(s);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -234,6 +256,7 @@ export class Vars extends Section {
|
|||
});
|
||||
}
|
||||
substituteStrings(str: string, sections: DependencySections): string {
|
||||
if (!str) return str;
|
||||
return str.replaceAll(VariableParser.STRING_REFERENCE, (_entire, id) => {
|
||||
const val = this.findStringVariableValue(id);
|
||||
if (val === null) {
|
||||
|
|
@ -293,8 +316,8 @@ export class Vars extends Section {
|
|||
return v[0];
|
||||
}
|
||||
}
|
||||
substituteMarkerString(s : string) : string {
|
||||
return MarkerParser.toSentinelString(s, this.markers);
|
||||
substituteMarkerString(s : string, forMatch? : boolean) : string {
|
||||
return MarkerParser.toSentinelString(s, this.markers, forMatch);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -309,7 +332,7 @@ export class VarsItem extends Section {
|
|||
constructor(id: string, value: string, sections: DependencySections) {
|
||||
super();
|
||||
this.id = sections.strs.allocString(id);
|
||||
this.value = sections.strs.allocAndUnescapeString(value);
|
||||
this.value = sections.strs.allocString(value, {unescape: true});
|
||||
}
|
||||
|
||||
valid() : boolean {
|
||||
|
|
@ -404,17 +427,6 @@ export class Bksp extends Tran {
|
|||
}
|
||||
};
|
||||
|
||||
// 'vkey'
|
||||
|
||||
export class VkeyItem {
|
||||
vkey: number;
|
||||
target: number;
|
||||
}
|
||||
|
||||
export class Vkey extends Section {
|
||||
vkeys: VkeyItem[] = [];
|
||||
};
|
||||
|
||||
// 'disp'
|
||||
export class DispItem {
|
||||
to: StrsItem;
|
||||
|
|
@ -433,7 +445,7 @@ export class Disp extends Section {
|
|||
* In-memory `<layers>`
|
||||
*/
|
||||
export class LayrList {
|
||||
hardware: number;
|
||||
hardware: StrsItem;
|
||||
layers: LayrEntry[] = [];
|
||||
minDeviceWidth: number; // millimeters
|
||||
};
|
||||
|
|
@ -510,19 +522,14 @@ export class List extends Section {
|
|||
* Allocate a list from a space-separated list of items.
|
||||
* Note that passing undefined or null or `''` will
|
||||
* end up being the same as the empty list `[]`
|
||||
* @param strs Strs section for allocation
|
||||
* @param s space-separated list of items
|
||||
* @param opts string options
|
||||
* @param sections sections
|
||||
* @returns a List object
|
||||
*/
|
||||
allocListFromSpaces(strs: Strs, s?: string): ListItem {
|
||||
allocListFromSpaces(s: string, opts: StrsOptions, sections: DependencySections): ListItem {
|
||||
s = s ?? '';
|
||||
return this.allocList(strs, s.split(' '));
|
||||
}
|
||||
allocListFromEscapedSpaces(strs: Strs, s?: string): ListItem {
|
||||
if(s === undefined || s === null) {
|
||||
s = '';
|
||||
}
|
||||
return this.allocList(strs, s.split(' ').map(unescapeString));
|
||||
return this.allocList(s.split(' '), opts, sections);
|
||||
}
|
||||
/**
|
||||
* Return a List object referring to the string list.
|
||||
|
|
@ -532,7 +539,7 @@ export class List extends Section {
|
|||
* @param s string list to allocate
|
||||
* @returns
|
||||
*/
|
||||
allocList(strs: Strs, s?: string[]): ListItem {
|
||||
allocList(s: string[], opts: StrsOptions, sections: DependencySections): ListItem {
|
||||
// Special case the 'null' list for [] or ['']
|
||||
if (!s || (s.length === 1 && s[0] === '')) {
|
||||
return this.lists[0];
|
||||
|
|
@ -540,14 +547,14 @@ export class List extends Section {
|
|||
let result = this.lists.find(item => item.isEqual(s));
|
||||
if(result === undefined) {
|
||||
// allocate a new ListItem
|
||||
result = new ListItem(strs, s);
|
||||
result = ListItem.fromStrings(s, opts, sections);
|
||||
this.lists.push(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
constructor(strs: Strs) {
|
||||
super();
|
||||
this.lists.push(new ListItem(strs, [])); // C7043: null element string
|
||||
this.lists.push(ListItem.fromStrings([], {}, { strs })); // C7043: null element string
|
||||
}
|
||||
lists: ListItem[] = [];
|
||||
};
|
||||
|
|
@ -569,7 +576,6 @@ export interface KMXPlusData {
|
|||
tran?: Tran;
|
||||
uset?: Uset; // uset is ignored in-memory
|
||||
vars?: Vars;
|
||||
vkey?: Vkey;
|
||||
};
|
||||
|
||||
export class KMXPlusFile extends KMXFile {
|
||||
|
|
@ -720,7 +726,7 @@ export class KMXPlusFile extends KMXFile {
|
|||
});
|
||||
|
||||
this.COMP_PLUS_LAYR_LIST = new r.Struct({
|
||||
hardware: r.uint32le, //enum
|
||||
hardware: STR_REF, // str: hardware name
|
||||
layer: r.uint32le, // index into layers
|
||||
count: r.uint32le,
|
||||
minDeviceWidth: r.uint32le, // integer: millimeters
|
||||
|
|
|
|||
|
|
@ -144,9 +144,10 @@ export class KMXFile {
|
|||
public static readonly VERSION_150 = 0x00000F00;
|
||||
|
||||
public static readonly VERSION_160 = 0x00001000;
|
||||
public static readonly VERSION_170 = 0x00001100;
|
||||
|
||||
public static readonly VERSION_MIN = this.VERSION_50;
|
||||
public static readonly VERSION_MAX = this.VERSION_160;
|
||||
public static readonly VERSION_MAX = this.VERSION_170;
|
||||
|
||||
//
|
||||
// Backspace types
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { OrderedStringList } from 'src/ldml-keyboard/pattern-parser.js';
|
||||
import { Strs, StrsItem } from './kmx-plus.js';
|
||||
import { DependencySections, StrsItem, StrsOptions } from './kmx-plus.js';
|
||||
|
||||
/**
|
||||
* A single entry in a ListItem.
|
||||
|
|
@ -27,20 +27,22 @@ export class ListItem extends Array<ListIndex> implements OrderedStringList {
|
|||
/**
|
||||
* Construct a new list from an array of strings.
|
||||
* Use List. This is meant to be called by the List.allocString*() functions.
|
||||
* @param strs the Strs section is needed to construct this object.
|
||||
* @param source array of strings
|
||||
* @param opts string handling options
|
||||
* @param sections the Strs section is needed to construct this object, and other sections may
|
||||
* be needed depending on the options
|
||||
* @returns
|
||||
*/
|
||||
constructor(strs: Strs, source: Array<string>) {
|
||||
super();
|
||||
if(!source) {
|
||||
return;
|
||||
static fromStrings(source: Array<string>, opts: StrsOptions, sections: DependencySections) : ListItem {
|
||||
const a = new ListItem();
|
||||
if (!source) {
|
||||
return a;
|
||||
}
|
||||
|
||||
for (const str of source) {
|
||||
let index = new ListIndex(strs.allocString(str));
|
||||
this.push(index);
|
||||
let index = new ListIndex(sections.strs.allocString(str, opts, sections));
|
||||
a.push(index);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
getItemOrder(item: string): number {
|
||||
return this.findIndex(({value}) => value.value === item);
|
||||
|
|
@ -72,12 +74,13 @@ export class ListItem extends Array<ListIndex> implements OrderedStringList {
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
/** for debugging, print as single string */
|
||||
/** for debugging and tests, print as single string */
|
||||
toString(): string {
|
||||
return this.toStringArray().join(' ');
|
||||
}
|
||||
/** for debugging, map to string array */
|
||||
/** for debugging and tests, map to string array */
|
||||
toStringArray(): string[] {
|
||||
return this.map(v => v.value.value);
|
||||
// TODO-LDML: this crashes: return this.map(v => v.toString());
|
||||
return Array.from(this.values()).map(v => v.toString());
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ export interface BUILDER_KVK_KEY {
|
|||
export const BUILDER_KVK_KEY_Size = 9; // size of fixed elements of BUILDER_KVK_KEY
|
||||
|
||||
export const enum BUILDER_KVK_HEADER_FLAGS {
|
||||
kvkhNone = 0x00, // no flags
|
||||
kvkh102 = 0x01,
|
||||
kvkhDisplayUnderlying = 0x02,
|
||||
kvkhUseUnderlying = 0x04,
|
||||
|
|
@ -122,4 +123,4 @@ export default class KVKFile {
|
|||
});
|
||||
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
///<reference lib="dom" />
|
||||
|
||||
import * as xml2js from 'xml2js';
|
||||
import { LDMLKeyboardXMLSourceFile, LKImport } from './ldml-keyboard-xml.js';
|
||||
import { LDMLKeyboardXMLSourceFile, LKImport, ImportStatus } from './ldml-keyboard-xml.js';
|
||||
import { default as AjvModule } from 'ajv';
|
||||
const Ajv = AjvModule.default; // The actual expected Ajv type.
|
||||
import { boxXmlArray } from '../util/util.js';
|
||||
|
|
@ -52,11 +52,18 @@ export class LDMLKeyboardXMLSourceFileReader {
|
|||
if (!source.keyboard3.keys.import) {
|
||||
source.keyboard3.keys.import = [];
|
||||
}
|
||||
if (!source.keyboard3.forms) {
|
||||
source.keyboard3.forms = {
|
||||
form: [],
|
||||
};
|
||||
}
|
||||
if (!source.keyboard3.forms.import) {
|
||||
source.keyboard3.forms.import = [];
|
||||
}
|
||||
}
|
||||
boxXmlArray(source?.keyboard3, 'layers');
|
||||
boxXmlArray(source?.keyboard3?.displays, 'display');
|
||||
boxXmlArray(source?.keyboard3?.names, 'name');
|
||||
boxXmlArray(source?.keyboard3?.vkeys, 'vkey');
|
||||
boxXmlArray(source?.keyboard3?.keys, 'key');
|
||||
boxXmlArray(source?.keyboard3?.keys, 'flicks');
|
||||
boxXmlArray(source?.keyboard3?.locales, 'locale');
|
||||
|
|
@ -71,6 +78,12 @@ export class LDMLKeyboardXMLSourceFileReader {
|
|||
}
|
||||
}
|
||||
}
|
||||
if(source?.keyboard3?.forms?.form) {
|
||||
boxXmlArray(source?.keyboard3?.forms, 'form');
|
||||
for(let form of source?.keyboard3?.forms?.form) {
|
||||
boxXmlArray(form, 'scanCodes');
|
||||
}
|
||||
}
|
||||
if(source?.keyboard3?.keys?.flicks) {
|
||||
for(let flicks of source?.keyboard3?.keys?.flicks) {
|
||||
boxXmlArray(flicks, 'flick');
|
||||
|
|
@ -152,7 +165,15 @@ export class LDMLKeyboardXMLSourceFileReader {
|
|||
if (!this.resolveOneImport(obj, subtag, {
|
||||
base: constants.cldr_import_base,
|
||||
path: constants.cldr_implied_keys_import
|
||||
})) {
|
||||
}, true)) {
|
||||
return false;
|
||||
}
|
||||
} else if (subtag === 'forms') {
|
||||
// <import base="cldr" path="techpreview/scanCodes-implied.xml"/>
|
||||
if (!this.resolveOneImport(obj, subtag, {
|
||||
base: constants.cldr_import_base,
|
||||
path: constants.cldr_implied_forms_import
|
||||
}, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -163,9 +184,10 @@ export class LDMLKeyboardXMLSourceFileReader {
|
|||
* @param obj the object being imported into
|
||||
* @param subtag obj's element tag, e.g. `keys`
|
||||
* @param asImport the import structure
|
||||
* @param implied true if it is an implied import
|
||||
* @returns true on success, false on failure
|
||||
*/
|
||||
private resolveOneImport(obj: any, subtag: string, asImport: LKImport) : boolean {
|
||||
private resolveOneImport(obj: any, subtag: string, asImport: LKImport, implied? : boolean) : boolean {
|
||||
const { base, path } = asImport;
|
||||
if (base !== constants.cldr_import_base) {
|
||||
this.callbacks.reportMessage(CommonTypesMessages.Error_ImportInvalidBase({base, path, subtag}));
|
||||
|
|
@ -192,12 +214,20 @@ export class LDMLKeyboardXMLSourceFileReader {
|
|||
// pull all children of importXml[subtag] into obj
|
||||
for (const subsubtag of Object.keys(importRootNode).reverse()) { // e.g. <key/>
|
||||
const subsubval = importRootNode[subsubtag];
|
||||
const basePath = `${base}/${path}`;
|
||||
if (!Array.isArray(subsubval)) {
|
||||
// This is somewhat of an internal error, indicating that a non-mergeable XML file was imported
|
||||
// Not exercisable with the standard LDML imports.
|
||||
this.callbacks.reportMessage(CommonTypesMessages.Error_ImportMergeFail({base, path, subtag, subsubtag}));
|
||||
return false;
|
||||
}
|
||||
// Mark all children as an import
|
||||
subsubval.forEach(o => o[ImportStatus.import] = basePath);
|
||||
if (implied) {
|
||||
// mark all children as an implied import
|
||||
subsubval.forEach(o => o[ImportStatus.impliedImport] = basePath);
|
||||
}
|
||||
|
||||
if (!obj[subsubtag]) {
|
||||
obj[subsubtag] = []; // start with empty array
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export interface LDMLKeyboardXMLSourceFile {
|
|||
* <keyboard> -- the root element.
|
||||
*/
|
||||
keyboard3: LKKeyboard;
|
||||
}
|
||||
};
|
||||
|
||||
export interface LKKeyboard {
|
||||
locale?: string;
|
||||
|
|
@ -24,9 +24,9 @@ export interface LKKeyboard {
|
|||
names?: LKNames;
|
||||
settings?: LKSettings;
|
||||
keys?: LKKeys;
|
||||
forms?: LKForms;
|
||||
displays?: LKDisplays;
|
||||
layers?: LKLayers[];
|
||||
vkeys?: LKVkeys;
|
||||
variables?: LKVariables;
|
||||
transforms?: LKTransforms[];
|
||||
};
|
||||
|
|
@ -128,15 +128,6 @@ export interface LKRow {
|
|||
keys?: string;
|
||||
};
|
||||
|
||||
export interface LKVkeys {
|
||||
vkey?: LKVkey[];
|
||||
};
|
||||
|
||||
export interface LKVkey {
|
||||
from?: string;
|
||||
to?: string;
|
||||
};
|
||||
|
||||
export interface LKVariables {
|
||||
string?: LKString[];
|
||||
set?: LKSet[];
|
||||
|
|
@ -193,3 +184,36 @@ export interface LKDisplays {
|
|||
display?: LKDisplay[];
|
||||
displayOptions?: LKDisplayOptions;
|
||||
};
|
||||
|
||||
export interface LKForms {
|
||||
form?: LKForm[];
|
||||
};
|
||||
|
||||
export interface LKForm {
|
||||
id?: string;
|
||||
scanCodes?: LKScanCodes[];
|
||||
};
|
||||
|
||||
export interface LKScanCodes {
|
||||
codes?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Utilities for determining the import status of items
|
||||
*/
|
||||
export class ImportStatus {
|
||||
/** item came in via implied (spec based) import, such as keys-Latn-implied.xml */
|
||||
static impliedImport = Symbol('LDML implied import');
|
||||
/** item came in via import */
|
||||
static import = Symbol('LDML import');
|
||||
|
||||
/** @returns true if the object was loaded through an implied import */
|
||||
static isImpliedImport(o : any) : boolean {
|
||||
return o && !!o[ImportStatus.impliedImport];
|
||||
}
|
||||
/** @returns true if the object was loaded through an explicit import */
|
||||
static isImport(o : any) : boolean {
|
||||
return o && !!o[ImportStatus.import];
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,15 @@ export class MarkerParser {
|
|||
/** Max count of markers */
|
||||
public static readonly MAX_MARKER_COUNT = constants.marker_max_count;
|
||||
|
||||
private static anyMarkerMatch() : string {
|
||||
const start = (`0000` + (this.MIN_MARKER_INDEX).toString(16)).slice(-4);
|
||||
const end = (`0000` + (this.MAX_MARKER_INDEX).toString(16)).slice(-4);
|
||||
return `${this.SENTINEL}${this.MARKER_CODE}[\\u${start}-\\u${end}]`;
|
||||
}
|
||||
|
||||
/** Expression that matches any marker */
|
||||
public static readonly ANY_MARKER_MATCH = MarkerParser.anyMarkerMatch();
|
||||
|
||||
/**
|
||||
* Pattern for matching a marker reference, OR the special marker \m{.}
|
||||
*/
|
||||
|
|
@ -91,10 +100,13 @@ export class MarkerParser {
|
|||
}
|
||||
|
||||
/** @returns all marker strings as sentinel values */
|
||||
public static toSentinelString(s: string, markers?: OrderedStringList) : string {
|
||||
public static toSentinelString(s: string, markers?: OrderedStringList, forMatch?: boolean) : string {
|
||||
if (!s) return s;
|
||||
return s.replaceAll(this.REFERENCE, (sub, arg) => {
|
||||
if (arg === MarkerParser.ANY_MARKER_ID) {
|
||||
if (forMatch) {
|
||||
return this.ANY_MARKER_MATCH;
|
||||
}
|
||||
return MarkerParser.markerOutput(MarkerParser.ANY_MARKER_INDEX);
|
||||
}
|
||||
if (!markers) {
|
||||
|
|
@ -103,10 +115,10 @@ export class MarkerParser {
|
|||
const order = markers.getItemOrder(arg);
|
||||
if (order === -1) {
|
||||
throw RangeError(`Internal Error: Could not find marker \\m{${arg}}`);
|
||||
} else if(order >= MarkerParser.MAX_MARKER_INDEX) {
|
||||
} else if(order > MarkerParser.MAX_MARKER_INDEX) {
|
||||
throw RangeError(`Internal Error: marker \\m{${arg}} has out of range index ${order}`);
|
||||
} else {
|
||||
return MarkerParser.markerOutput(order+1);
|
||||
return MarkerParser.markerOutput(order + 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { LKKey } from './../../src/ldml-keyboard/ldml-keyboard-xml.js';
|
||||
import { LKKey, ImportStatus } from './../../src/ldml-keyboard/ldml-keyboard-xml.js';
|
||||
import 'mocha';
|
||||
import {assert} from 'chai';
|
||||
import { CommonTypesMessages } from '../../src/util/common-events.js';
|
||||
import { testReaderCases } from '../helpers/reader-callback-test.js';
|
||||
import { CLDRScanToVkey, CLDRScanToKeyMap, USVirtualKeyCodes } from '../../src/consts/virtual-key-constants.js';
|
||||
|
||||
function pluckKeysFromKeybag(keys: LKKey[], ids: string[]) {
|
||||
return keys.filter(({id}) => ids.indexOf(id) !== -1);
|
||||
|
|
@ -40,6 +41,9 @@ describe('ldml keyboard xml reader tests', function () {
|
|||
{id: 'b', to: 'b'},
|
||||
{id: 'c', to: 'c'},
|
||||
]);
|
||||
// all of the keys are implied imports here
|
||||
assert.isTrue(ImportStatus.isImpliedImport(source?.keyboard3?.keys.key.find(({id}) => id === 'a')));
|
||||
assert.isTrue(ImportStatus.isImport(source?.keyboard3?.keys.key.find(({id}) => id === 'a')));
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -81,6 +85,15 @@ describe('ldml keyboard xml reader tests', function () {
|
|||
{id: 'zz', to: 'zz'}, // new key
|
||||
{id: 'hash', to: '##'}, // override
|
||||
]);
|
||||
// 'a' is an implied import
|
||||
assert.isTrue(ImportStatus.isImpliedImport(k.find(({id}) => id === 'a')));
|
||||
assert.isTrue(ImportStatus.isImport(k.find(({id}) => id === 'a')));
|
||||
// 'hash' is an import but not implied
|
||||
assert.isFalse(ImportStatus.isImpliedImport(k.find(({id}) => id === 'hash')));
|
||||
assert.isTrue(ImportStatus.isImport(k.find(({id}) => id === 'hash')));
|
||||
// 'zz' is not imported
|
||||
assert.isFalse(ImportStatus.isImpliedImport(k.find(({id}) => id === 'zz')));
|
||||
assert.isFalse(ImportStatus.isImport(k.find(({id}) => id === 'zz')));
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -129,3 +142,41 @@ describe('ldml keyboard xml reader tests', function () {
|
|||
},
|
||||
]);
|
||||
});
|
||||
|
||||
describe('check scan code routines', () => {
|
||||
it('should be able to detect bad single scancodes', () => {
|
||||
const badScans = new Set<number>();
|
||||
const ckey = CLDRScanToVkey(0xFF, badScans);
|
||||
assert.isUndefined(ckey, `expected undefined 0xFF`);
|
||||
assert.equal(badScans.size, 1);
|
||||
assert.sameDeepMembers(Array.from(badScans.values()), [0xFF]);
|
||||
});
|
||||
it('should be able to detect bad list scancodes', () => {
|
||||
const badScans = new Set<number>();
|
||||
const ckeys = CLDRScanToKeyMap([[0x02, 0xFF]], badScans);
|
||||
assert.sameDeepMembers(ckeys, [[49, undefined]]);
|
||||
assert.equal(badScans.size, 1);
|
||||
assert.sameDeepMembers(Array.from(badScans.values()), [0xFF]);
|
||||
});
|
||||
it('CLDRScanToUSVirtualKeyCodes should be 1:1', () => {
|
||||
const vkeyToScan = new Map<number, number>();
|
||||
// check all scancodes
|
||||
for (let scan = 0; scan <= 0xFF; scan++) {
|
||||
const vkey = CLDRScanToVkey(scan);
|
||||
if (vkey === undefined) {
|
||||
// not mapped, which is OK
|
||||
continue;
|
||||
}
|
||||
if (scan === 0x56 || scan === 0x7D) {
|
||||
// These both can map to this scancode
|
||||
assert.equal(vkey, USVirtualKeyCodes.K_oE2);
|
||||
} else {
|
||||
// don't check those exceptions
|
||||
assert.isFalse(vkeyToScan.has(vkey),
|
||||
`vkey ${vkey} mapped from more than one scancode: ${Number(vkeyToScan.get(vkey)).toString(16)} and ${Number(scan).toString(16)}`);
|
||||
}
|
||||
// do make sure nothing else maps to that vkey
|
||||
vkeyToScan.set(vkey, scan);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ describe('Test of Pattern Parsers', () => {
|
|||
'a': 0,
|
||||
'b': 1,
|
||||
'c': 2,
|
||||
'zz': MarkerParser.MAX_MARKER_INDEX - 1, // this is an ordering, so needs to be -1
|
||||
'zzz': 0x2FFFFF,
|
||||
};
|
||||
const o = m[item];
|
||||
|
|
@ -103,6 +104,21 @@ describe('Test of Pattern Parsers', () => {
|
|||
markers
|
||||
)
|
||||
);
|
||||
// verify the matching behavior of these
|
||||
assert.isTrue(new RegExp(MarkerParser.toSentinelString(`^Q\\m{a}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`Q\\m{a}`, markers, false)), `Q\\m{a} did not match`);
|
||||
assert.isFalse(new RegExp(MarkerParser.toSentinelString(`^Q\\m{a}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`Q\\m{b}`, markers, false)), `Q\\m{a} should not match Q\\m{b}`);
|
||||
assert.isTrue(new RegExp(MarkerParser.toSentinelString(`^Q\\m{.}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`Q\\m{a}`, markers, false)), `Q\\m{.} did not match Q\\m{a}`);
|
||||
assert.isTrue(new RegExp(MarkerParser.toSentinelString(`^Q\\m{.}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`Q\\m{zz}`, markers, false)), `Q\\m{.} did not match Q\\m{zz} (max marker)`);
|
||||
assert.isFalse(new RegExp(MarkerParser.toSentinelString(`^Q\\m{.}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`\\m{a}`, markers, false)), `Q\\m{.} did not match \\m{a}`);
|
||||
assert.isTrue(new RegExp(MarkerParser.toSentinelString(`^\\m{.}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`\\m{a}`, markers, false)), `\\m{.} did not match \\m{a}`);
|
||||
assert.isFalse(new RegExp(MarkerParser.toSentinelString(`^\\m{.}$`, markers, true), 'u')
|
||||
.test(MarkerParser.toSentinelString(`\\m{a}\\m{b}`, markers, false)), `\\m{.} did not match \\m{a}\\m{b}`);
|
||||
});
|
||||
it('should match some marker constants', () => {
|
||||
assert.equal(constants.uc_sentinel, KMXFile.UC_SENTINEL);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.esm-base.json",
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": ".",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.esm-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"outDir": "build/src/",
|
||||
|
|
|
|||
|
|
@ -74,8 +74,9 @@
|
|||
#define VERSION_140 0x00000E00
|
||||
#define VERSION_150 0x00000F00
|
||||
#define VERSION_160 0x00001000
|
||||
#define VERSION_170 0x00001100
|
||||
#define VERSION_MIN VERSION_50
|
||||
#define VERSION_MAX VERSION_160
|
||||
#define VERSION_MAX VERSION_170
|
||||
|
||||
/*
|
||||
Special flag for WM_CHAR/WM_KEY???/WM_SYSKEY???: says that key has been
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
!include ..\..\..\Defines.mak
|
||||
|
||||
build: dirs # version.res manifest.res
|
||||
build: dirs
|
||||
# version.res manifest.res
|
||||
$(DELPHI_MSBUILD) SentryClientTest.dproj "/p:Platform=Win32"
|
||||
$(DELPHI_MSBUILD) SentryClientVclTest.dproj "/p:Platform=Win32"
|
||||
|
||||
|
|
|
|||
|
|
@ -99,9 +99,10 @@ const
|
|||
VERSION_140 = $00000E00;
|
||||
VERSION_150 = $00000F00;
|
||||
VERSION_160 = $00001000;
|
||||
VERSION_170 = $00001100;
|
||||
|
||||
VERSION_MIN = VERSION_50;
|
||||
VERSION_MAX = VERSION_160;
|
||||
VERSION_MAX = VERSION_170;
|
||||
|
||||
VERSION_MASK_MINOR = $00FF;
|
||||
VERSION_MASK_MAJOR = $FF00;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ NOTARGET_SIGNCODE=yes
|
|||
!ifdef NODELPHI
|
||||
TARGETS=.virtual
|
||||
!else
|
||||
TARGETS=build_standards_data buildunidata devtools sentrytool test-klog
|
||||
TARGETS=build_standards_data buildunidata devtools sentrytool test-klog verify_signatures
|
||||
!endif
|
||||
|
||||
CLEANS=clean-tools
|
||||
|
|
@ -28,6 +28,10 @@ buildunidata: .virtual
|
|||
cd $(COMMON_ROOT)\tools\buildunidata
|
||||
$(MAKE) $(TARGET)
|
||||
|
||||
verify_signatures: .virtual
|
||||
cd $(COMMON_ROOT)\tools\verify_signatures
|
||||
$(MAKE) $(TARGET)
|
||||
|
||||
devtools: .virtual
|
||||
!ifdef NODELPHI
|
||||
echo Skipping devtools
|
||||
|
|
|
|||
13
common/windows/delphi/tools/verify_signatures/Makefile
Normal file
13
common/windows/delphi/tools/verify_signatures/Makefile
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# test for signatures and version information being correct in ?install directory or ?bin directory
|
||||
#
|
||||
|
||||
!include ..\..\Defines.mak
|
||||
|
||||
build:
|
||||
$(DELPHI_MSBUILD) verify_signatures.dproj
|
||||
copy sigcheck.bin $(WIN32_TARGET_PATH)\sigcheck.exe
|
||||
|
||||
clean: def-clean
|
||||
|
||||
!include ..\..\Target.mak
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
program verify;
|
||||
program verify_signatures;
|
||||
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
|
|
@ -36,6 +36,7 @@ begin
|
|||
Delete(s,1,1);
|
||||
end;
|
||||
|
||||
// TODO: sign these files and move the check down to the EndsWith node test
|
||||
if str[0].ToLower.Contains('sentry.') or str[0].ToLower.Contains('crashpad_handler') or str[0].ToLower.Contains('keymanmc') then
|
||||
// We don't verify sentry.dll or sentry.x64.dll or crashpad_handler.exe because they're not our files
|
||||
// We don't verify keymanmc.dll because it has no version resources, as it is mc-generated
|
||||
|
|
@ -62,6 +63,14 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
if str[0].ToLower.EndsWith('node') then
|
||||
begin
|
||||
// It's one of the node addons -- in developer server at time of writing
|
||||
// we don't have a version resource but we have signed it, so treat it
|
||||
// as valid
|
||||
Exit('');
|
||||
end;
|
||||
|
||||
if str[3] <> 'SIL International' then
|
||||
begin
|
||||
Exit('File has wrong company name');
|
||||
|
|
@ -90,7 +99,7 @@ begin
|
|||
|
||||
if (ParamStr(1) = '-?') or (ParamCount < 1) then
|
||||
begin
|
||||
writeln('verify [-d] VERSION.md: Verify the output of sigcheck to ensure all executables are signed and have proper version.');
|
||||
writeln('verify_signatures [-d] VERSION.md: Verify the output of sigcheck to ensure all executables are signed and have proper version.');
|
||||
writeln(' -d: Check the timestamp on the signature is less than 2 days old.');
|
||||
writeln(' VERSION.md: path to the version to verify against');
|
||||
Halt(2);
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
<ProjectGuid>{A6DCA558-8DD0-4FFF-8DAE-F305AB8D2AF4}</ProjectGuid>
|
||||
<ProjectVersion>18.8</ProjectVersion>
|
||||
<FrameworkType>None</FrameworkType>
|
||||
<MainSource>verify.dpr</MainSource>
|
||||
<MainSource>verify_signatures.dpr</MainSource>
|
||||
<Base>True</Base>
|
||||
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base)'!=''">
|
||||
<SanitizedProjectName>verify</SanitizedProjectName>
|
||||
<SanitizedProjectName>verify_signatures</SanitizedProjectName>
|
||||
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
|
||||
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
|
||||
<DCC_UsePackage>bindcompfmx;fmx;rtl;dbrtl;DbxClientDriver;bindcomp;inetdb;DBXInterBaseDriver;xmlrtl;DbxCommonDriver;DBXMySQLDriver;dbxcds;soaprtl;bindengine;CustomIPTransport;dsnap;fmxase;inet;fmxobj;inetdbxpress;fmxdae;dbexpress;$(DCC_UsePackage)</DCC_UsePackage>
|
||||
|
|
@ -161,7 +161,7 @@
|
|||
<VersionInfoKeys Name="Comments"/>
|
||||
</VersionInfoKeys>
|
||||
<Source>
|
||||
<Source Name="MainSource">verify.dpr</Source>
|
||||
<Source Name="MainSource">verify_signatures.dpr</Source>
|
||||
</Source>
|
||||
<Excluded_Packages>
|
||||
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k260.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
|
||||
|
|
@ -11,7 +11,18 @@ do_clean() {
|
|||
# clean: note build/<target> will be left, but build/<target>/<configuration> should be gone
|
||||
local target=$1
|
||||
builder_start_action clean:$target || return 0
|
||||
|
||||
rm -rf "$MESON_PATH"
|
||||
|
||||
# Removes ICU cached components so it will be re-downloaded and built. Note:
|
||||
# we could use `git clean`, but this clarifies exactly what is deleted, and
|
||||
# but we try not to use git commands in build scripts, to maintain clear
|
||||
# responsibility
|
||||
rm -rf \
|
||||
"$THIS_SCRIPT_PATH/subprojects/icu" \
|
||||
"$THIS_SCRIPT_PATH/subprojects/*.tgz" \
|
||||
"$THIS_SCRIPT_PATH/subprojects/*.zip"
|
||||
|
||||
builder_finish_action success clean:$target
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"sitemap": "@doc_dir@/sitemap.txt",
|
||||
"index": "@doc_dir@/markdown_files/index.md",
|
||||
"c_sources": [
|
||||
"@include_dir@/keyman/keyboardprocessor.h"
|
||||
"@include_dir@/keyman/keyman_core_api.h"
|
||||
],
|
||||
"c_include_directories": [
|
||||
"@include_dir@",
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
}
|
||||
},
|
||||
"properties": {
|
||||
"$schema": { "const": "keyman/keyboardprocessor/doc/introspection.schema" },
|
||||
"$schema": { "const": "keyman/core/doc/introspection.schema" },
|
||||
"keyboard": { "$ref": "#/definitions/keyboard" },
|
||||
"options": {
|
||||
"type": "object",
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ A virtual key board event and modifier map recevied from the Platform layer to b
|
|||
processed with the state object for this Client application.
|
||||
- __Virtual Key:__
|
||||
A code based on the US English layout, with values matching the Windows
|
||||
virtual key codes. See `keyboardprocessor_vkeys.h` for definitions.
|
||||
virtual key codes. See `keyman_core_api_vkeys.h` for definitions.
|
||||
- __Modifier Key:__
|
||||
The set of Control, Shift, Alt, Caps Lock keys. On some platforms these may
|
||||
have other names (e.g. Alt is called Option on macOS); other platform-specific
|
||||
|
|
@ -58,4 +58,4 @@ Caps Lock.
|
|||
|
||||
### Namespace
|
||||
|
||||
All calls, types and enums are prefixed with the namespace identifier `km_kbp_`
|
||||
All calls, types and enums are prefixed with the namespace identifier `km_core_`
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ if hotdoc.found()
|
|||
output: 'hotdoc.json',
|
||||
configuration: cfg)
|
||||
deps = files(
|
||||
'../include/keyman/keyboardprocessor.h',
|
||||
'../include/keyman/keyman_core_api.h',
|
||||
'../src/jsonpp.hpp',
|
||||
'../src/utfcodec.hpp'
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
// Defined environment options for KMX processor
|
||||
#define KM_KBP_KMX_ENV_PLATFORM u"platform"
|
||||
#define KM_KBP_KMX_ENV_BASELAYOUT u"baseLayout"
|
||||
#define KM_KBP_KMX_ENV_BASELAYOUTALT u"baseLayoutAlt"
|
||||
#define KM_KBP_KMX_ENV_SIMULATEALTGR u"simulateAltgr"
|
||||
#define KM_KBP_KMX_ENV_CAPSLOCK u"capsLock"
|
||||
#define KM_KBP_KMX_ENV_BASELAYOUTGIVESCTRLRALTFORRALT u"baseLayoutGivesCtrlRAltForRAlt"
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
#define km_kbp_version_stringify(x) km_kbp_version_to_string(x)
|
||||
#define km_kbp_version_to_string(x) #x
|
||||
|
||||
// Product versioning
|
||||
|
||||
#define KM_KBP_VERSION_MAJOR @majorver@
|
||||
#define KM_KBP_VERSION_MINOR @minorver@
|
||||
#define KM_KBP_VERSION_PATCH @patchver@
|
||||
#define KM_KBP_VERSION_STRING km_kbp_version_stringify(@majorver@ ## . ## @minorver@ ## . ## @patchver@ ## .0)
|
||||
|
||||
// API versioning
|
||||
|
||||
#define KM_KBP_LIB_CURRENT @lib_curr@
|
||||
#define KM_KBP_LIB_AGE @lib_age@
|
||||
#define KM_KBP_LIB_REVISION @lib_rev@
|
||||
|
|
@ -1,312 +0,0 @@
|
|||
/*
|
||||
Copyright: © 2018 SIL International.
|
||||
Description: API declarations for modifier keys, handy access masks and
|
||||
Keyman VKEY names. These follow the same keytop->code
|
||||
associations as the Windows API. This is a separate header to
|
||||
maintain readability of the primary API header.
|
||||
Create Date: 17 Oct 2018
|
||||
Authors: Tim Eves (TSE)
|
||||
History: 17 Oct 2018 - TSE - Moved & refactored km_kbp_modifier_state
|
||||
from keyboardprocessor.h.
|
||||
- Added VKey and mask definitions.
|
||||
6 Oct 2018 - TSE - Move into keyman folder.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum km_kbp_modifier_state {
|
||||
KM_KBP_MODIFIER_LCTRL = 1 << 0,
|
||||
KM_KBP_MODIFIER_RCTRL = 1 << 1,
|
||||
KM_KBP_MODIFIER_LALT = 1 << 2,
|
||||
KM_KBP_MODIFIER_RALT = 1 << 3,
|
||||
KM_KBP_MODIFIER_SHIFT = 1 << 4,
|
||||
KM_KBP_MODIFIER_CTRL = 1 << 5,
|
||||
KM_KBP_MODIFIER_ALT = 1 << 6,
|
||||
/*
|
||||
KM_KBP_MODIFIER_META = 1 << 7, // Either Meta-key flag (tentative). Not usable by keyboards currently
|
||||
// Used internally (currently, only by KMW) to ensure Meta-key
|
||||
// shortcuts safely bypass rules
|
||||
// Meta key = Command key on macOS, Windows key on Windows
|
||||
*/
|
||||
KM_KBP_MODIFIER_CAPS = 1 << 8,
|
||||
KM_KBP_MODIFIER_NOCAPS = 1 << 9,
|
||||
/*
|
||||
KM_KBP_MODIFIER_NUMLOCK = 1 << 10,
|
||||
KM_KBP_MODIFIER_NONUMLOCK = 1 << 11,
|
||||
KM_KBP_MODIFIER_SCROLLOCK = 1 << 12,
|
||||
KM_KBP_MODIFIER_NOSCROLLOCK = 1 << 13,
|
||||
KM_KBP_MODIFIER_VIRTUALKEY = 1 << 14,
|
||||
*/
|
||||
};
|
||||
|
||||
enum km_kbp_modifier_mask {
|
||||
KM_KBP_MODIFIER_MASK_ALL = 0x7f,
|
||||
KM_KBP_MODIFIER_MASK_ALT_GR_SIM = KM_KBP_MODIFIER_LCTRL|KM_KBP_MODIFIER_LALT,
|
||||
KM_KBP_MODIFIER_MASK_CHIRAL = 0x1f,
|
||||
KM_KBP_MODIFIER_MASK_IS_CHIRAL = 0x0f,
|
||||
KM_KBP_MODIFIER_MASK_NON_CHIRAL = 0x7f,
|
||||
KM_KBP_MODIFIER_MASK_CAPS = 0x0300,
|
||||
/*KM_KBP_MODIFIER_MASK_NUMLOCK = 0x0C00,
|
||||
KM_KBP_MODIFIER_MASK_SCROLLLOCK = 0x3000,*/
|
||||
};
|
||||
|
||||
// These are Windows API VKEYs, using Keyman VKEY names.
|
||||
enum km_kpb_virtual_key {
|
||||
KM_KBP_VKEY__00,
|
||||
KM_KBP_VKEY_LBUTTON,
|
||||
KM_KBP_VKEY_RBUTTON,
|
||||
KM_KBP_VKEY_CANCEL,
|
||||
KM_KBP_VKEY_MBUTTON,
|
||||
KM_KBP_VKEY__05,
|
||||
KM_KBP_VKEY__06,
|
||||
KM_KBP_VKEY__07,
|
||||
KM_KBP_VKEY_BKSP,
|
||||
KM_KBP_VKEY_TAB,
|
||||
KM_KBP_VKEY__0A,
|
||||
KM_KBP_VKEY__0B,
|
||||
KM_KBP_VKEY_KP5,
|
||||
KM_KBP_VKEY_ENTER,
|
||||
KM_KBP_VKEY__0E,
|
||||
KM_KBP_VKEY__0F,
|
||||
KM_KBP_VKEY_SHIFT,
|
||||
KM_KBP_VKEY_CONTROL,
|
||||
KM_KBP_VKEY_ALT,
|
||||
KM_KBP_VKEY_PAUSE,
|
||||
KM_KBP_VKEY_CAPS,
|
||||
KM_KBP_VKEY__15,
|
||||
KM_KBP_VKEY__16,
|
||||
KM_KBP_VKEY__17,
|
||||
KM_KBP_VKEY__18,
|
||||
KM_KBP_VKEY__19,
|
||||
KM_KBP_VKEY__1A,
|
||||
KM_KBP_VKEY_ESC,
|
||||
KM_KBP_VKEY__1C,
|
||||
KM_KBP_VKEY__1D,
|
||||
KM_KBP_VKEY__1E,
|
||||
KM_KBP_VKEY__1F,
|
||||
KM_KBP_VKEY_SPACE,
|
||||
KM_KBP_VKEY_PGUP,
|
||||
KM_KBP_VKEY_PGDN,
|
||||
KM_KBP_VKEY_END,
|
||||
KM_KBP_VKEY_HOME,
|
||||
KM_KBP_VKEY_LEFT,
|
||||
KM_KBP_VKEY_UP,
|
||||
KM_KBP_VKEY_RIGHT,
|
||||
KM_KBP_VKEY_DOWN,
|
||||
KM_KBP_VKEY_SEL,
|
||||
KM_KBP_VKEY_PRINT,
|
||||
KM_KBP_VKEY_EXEC,
|
||||
KM_KBP_VKEY_PRTSCN,
|
||||
KM_KBP_VKEY_INS,
|
||||
KM_KBP_VKEY_DEL,
|
||||
KM_KBP_VKEY_HELP,
|
||||
KM_KBP_VKEY_0,
|
||||
KM_KBP_VKEY_1,
|
||||
KM_KBP_VKEY_2,
|
||||
KM_KBP_VKEY_3,
|
||||
KM_KBP_VKEY_4,
|
||||
KM_KBP_VKEY_5,
|
||||
KM_KBP_VKEY_6,
|
||||
KM_KBP_VKEY_7,
|
||||
KM_KBP_VKEY_8,
|
||||
KM_KBP_VKEY_9,
|
||||
KM_KBP_VKEY__3A,
|
||||
KM_KBP_VKEY__3B,
|
||||
KM_KBP_VKEY__3C,
|
||||
KM_KBP_VKEY__3D,
|
||||
KM_KBP_VKEY__3E,
|
||||
KM_KBP_VKEY__3F,
|
||||
KM_KBP_VKEY__40,
|
||||
KM_KBP_VKEY_A,
|
||||
KM_KBP_VKEY_B,
|
||||
KM_KBP_VKEY_C,
|
||||
KM_KBP_VKEY_D,
|
||||
KM_KBP_VKEY_E,
|
||||
KM_KBP_VKEY_F,
|
||||
KM_KBP_VKEY_G,
|
||||
KM_KBP_VKEY_H,
|
||||
KM_KBP_VKEY_I,
|
||||
KM_KBP_VKEY_J,
|
||||
KM_KBP_VKEY_K,
|
||||
KM_KBP_VKEY_L,
|
||||
KM_KBP_VKEY_M,
|
||||
KM_KBP_VKEY_N,
|
||||
KM_KBP_VKEY_O,
|
||||
KM_KBP_VKEY_P,
|
||||
KM_KBP_VKEY_Q,
|
||||
KM_KBP_VKEY_R,
|
||||
KM_KBP_VKEY_S,
|
||||
KM_KBP_VKEY_T,
|
||||
KM_KBP_VKEY_U,
|
||||
KM_KBP_VKEY_V,
|
||||
KM_KBP_VKEY_W,
|
||||
KM_KBP_VKEY_X,
|
||||
KM_KBP_VKEY_Y,
|
||||
KM_KBP_VKEY_Z,
|
||||
KM_KBP_VKEY__5B,
|
||||
KM_KBP_VKEY__5C,
|
||||
KM_KBP_VKEY__5D,
|
||||
KM_KBP_VKEY__5E,
|
||||
KM_KBP_VKEY__5F,
|
||||
KM_KBP_VKEY_NP0,
|
||||
KM_KBP_VKEY_NP1,
|
||||
KM_KBP_VKEY_NP2,
|
||||
KM_KBP_VKEY_NP3,
|
||||
KM_KBP_VKEY_NP4,
|
||||
KM_KBP_VKEY_NP5,
|
||||
KM_KBP_VKEY_NP6,
|
||||
KM_KBP_VKEY_NP7,
|
||||
KM_KBP_VKEY_NP8,
|
||||
KM_KBP_VKEY_NP9,
|
||||
KM_KBP_VKEY_NPSTAR,
|
||||
KM_KBP_VKEY_NPPLUS,
|
||||
KM_KBP_VKEY_SEPARATOR,
|
||||
KM_KBP_VKEY_NPMINUS,
|
||||
KM_KBP_VKEY_NPDOT,
|
||||
KM_KBP_VKEY_NPSLASH,
|
||||
KM_KBP_VKEY_F1,
|
||||
KM_KBP_VKEY_F2,
|
||||
KM_KBP_VKEY_F3,
|
||||
KM_KBP_VKEY_F4,
|
||||
KM_KBP_VKEY_F5,
|
||||
KM_KBP_VKEY_F6,
|
||||
KM_KBP_VKEY_F7,
|
||||
KM_KBP_VKEY_F8,
|
||||
KM_KBP_VKEY_F9,
|
||||
KM_KBP_VKEY_F10,
|
||||
KM_KBP_VKEY_F11,
|
||||
KM_KBP_VKEY_F12,
|
||||
KM_KBP_VKEY_F13,
|
||||
KM_KBP_VKEY_F14,
|
||||
KM_KBP_VKEY_F15,
|
||||
KM_KBP_VKEY_F16,
|
||||
KM_KBP_VKEY_F17,
|
||||
KM_KBP_VKEY_F18,
|
||||
KM_KBP_VKEY_F19,
|
||||
KM_KBP_VKEY_F20,
|
||||
KM_KBP_VKEY_F21,
|
||||
KM_KBP_VKEY_F22,
|
||||
KM_KBP_VKEY_F23,
|
||||
KM_KBP_VKEY_F24,
|
||||
KM_KBP_VKEY__88,
|
||||
KM_KBP_VKEY__89,
|
||||
KM_KBP_VKEY__8A,
|
||||
KM_KBP_VKEY__8B,
|
||||
KM_KBP_VKEY__8C,
|
||||
KM_KBP_VKEY__8D,
|
||||
KM_KBP_VKEY__8E,
|
||||
KM_KBP_VKEY__8F,
|
||||
KM_KBP_VKEY_NUMLOCK,
|
||||
KM_KBP_VKEY_SCROLL,
|
||||
KM_KBP_VKEY__92,
|
||||
KM_KBP_VKEY__93,
|
||||
KM_KBP_VKEY__94,
|
||||
KM_KBP_VKEY__95,
|
||||
KM_KBP_VKEY__96,
|
||||
KM_KBP_VKEY__97,
|
||||
KM_KBP_VKEY__98,
|
||||
KM_KBP_VKEY__99,
|
||||
KM_KBP_VKEY__9A,
|
||||
KM_KBP_VKEY__9B,
|
||||
KM_KBP_VKEY__9C,
|
||||
KM_KBP_VKEY__9D,
|
||||
KM_KBP_VKEY__9E,
|
||||
KM_KBP_VKEY__9F,
|
||||
KM_KBP_VKEY__A0,
|
||||
KM_KBP_VKEY__A1,
|
||||
KM_KBP_VKEY__A2,
|
||||
KM_KBP_VKEY__A3,
|
||||
KM_KBP_VKEY__A4,
|
||||
KM_KBP_VKEY__A5,
|
||||
KM_KBP_VKEY__A6,
|
||||
KM_KBP_VKEY__A7,
|
||||
KM_KBP_VKEY__A8,
|
||||
KM_KBP_VKEY__A9,
|
||||
KM_KBP_VKEY__AA,
|
||||
KM_KBP_VKEY__AB,
|
||||
KM_KBP_VKEY__AC,
|
||||
KM_KBP_VKEY__AD,
|
||||
KM_KBP_VKEY__AE,
|
||||
KM_KBP_VKEY__AF,
|
||||
KM_KBP_VKEY__B0,
|
||||
KM_KBP_VKEY__B1,
|
||||
KM_KBP_VKEY__B2,
|
||||
KM_KBP_VKEY__B3,
|
||||
KM_KBP_VKEY__B4,
|
||||
KM_KBP_VKEY__B5,
|
||||
KM_KBP_VKEY__B6,
|
||||
KM_KBP_VKEY__B7,
|
||||
KM_KBP_VKEY__B8,
|
||||
KM_KBP_VKEY__B9,
|
||||
KM_KBP_VKEY_COLON,
|
||||
KM_KBP_VKEY_EQUAL,
|
||||
KM_KBP_VKEY_COMMA,
|
||||
KM_KBP_VKEY_HYPHEN,
|
||||
KM_KBP_VKEY_PERIOD,
|
||||
KM_KBP_VKEY_SLASH,
|
||||
KM_KBP_VKEY_BKQUOTE,
|
||||
KM_KBP_VKEY__C1,
|
||||
KM_KBP_VKEY__C2,
|
||||
KM_KBP_VKEY__C3,
|
||||
KM_KBP_VKEY__C4,
|
||||
KM_KBP_VKEY__C5,
|
||||
KM_KBP_VKEY__C6,
|
||||
KM_KBP_VKEY__C7,
|
||||
KM_KBP_VKEY__C8,
|
||||
KM_KBP_VKEY__C9,
|
||||
KM_KBP_VKEY__CA,
|
||||
KM_KBP_VKEY__CB,
|
||||
KM_KBP_VKEY__CC,
|
||||
KM_KBP_VKEY__CD,
|
||||
KM_KBP_VKEY__CE,
|
||||
KM_KBP_VKEY__CF,
|
||||
KM_KBP_VKEY__D0,
|
||||
KM_KBP_VKEY__D1,
|
||||
KM_KBP_VKEY__D2,
|
||||
KM_KBP_VKEY__D3,
|
||||
KM_KBP_VKEY__D4,
|
||||
KM_KBP_VKEY__D5,
|
||||
KM_KBP_VKEY__D6,
|
||||
KM_KBP_VKEY__D7,
|
||||
KM_KBP_VKEY__D8,
|
||||
KM_KBP_VKEY__D9,
|
||||
KM_KBP_VKEY__DA,
|
||||
KM_KBP_VKEY_LBRKT,
|
||||
KM_KBP_VKEY_BKSLASH,
|
||||
KM_KBP_VKEY_RBRKT,
|
||||
KM_KBP_VKEY_QUOTE,
|
||||
KM_KBP_VKEY_oDF,
|
||||
KM_KBP_VKEY_oE0,
|
||||
KM_KBP_VKEY_oE1,
|
||||
KM_KBP_VKEY_oE2, // 102nd key on European layouts
|
||||
KM_KBP_VKEY_oE3,
|
||||
KM_KBP_VKEY_oE4,
|
||||
KM_KBP_VKEY__E5,
|
||||
KM_KBP_VKEY_oE6,
|
||||
KM_KBP_VKEY__E7,
|
||||
KM_KBP_VKEY__E8,
|
||||
KM_KBP_VKEY_oE9,
|
||||
KM_KBP_VKEY_oEA,
|
||||
KM_KBP_VKEY_oEB,
|
||||
KM_KBP_VKEY_oEC,
|
||||
KM_KBP_VKEY_oED,
|
||||
KM_KBP_VKEY_oEE,
|
||||
KM_KBP_VKEY_oEF,
|
||||
KM_KBP_VKEY_oF0,
|
||||
KM_KBP_VKEY_oF1,
|
||||
KM_KBP_VKEY_oF2,
|
||||
KM_KBP_VKEY_oF3,
|
||||
KM_KBP_VKEY_oF4,
|
||||
KM_KBP_VKEY_oF5,
|
||||
KM_KBP_VKEY__F6,
|
||||
KM_KBP_VKEY__F7,
|
||||
KM_KBP_VKEY__F8,
|
||||
KM_KBP_VKEY__F9,
|
||||
KM_KBP_VKEY__FA,
|
||||
KM_KBP_VKEY__FB,
|
||||
KM_KBP_VKEY__FC,
|
||||
KM_KBP_VKEY__FD,
|
||||
KM_KBP_VKEY__FE,
|
||||
KM_KBP_VKEY__FF,
|
||||
};
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -27,7 +27,7 @@
|
|||
#endif
|
||||
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
typedef wchar_t const * km_kbp_path_name;
|
||||
typedef wchar_t const * km_core_path_name;
|
||||
#define _KM_KBP_PATH_SEPARATOR (L'\\')
|
||||
#define _KM_KBP_EXT_SEPARATOR (L'.')
|
||||
#if defined __GNUC__ // These three will be redefined for Windows
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
#define _kmn_import_flag dllimport
|
||||
#define _kmn_static_flag
|
||||
#else
|
||||
typedef char const * km_kbp_path_name;
|
||||
typedef char const * km_core_path_name;
|
||||
#define _KM_KBP_PATH_SEPARATOR ('/')
|
||||
#define _KM_KBP_EXT_SEPARATOR ('.')
|
||||
#endif
|
||||
9
core/include/keyman/keyman_core_api_consts.h
Normal file
9
core/include/keyman/keyman_core_api_consts.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
// Defined environment options for KMX processor
|
||||
#define KM_CORE_KMX_ENV_PLATFORM u"platform"
|
||||
#define KM_CORE_KMX_ENV_BASELAYOUT u"baseLayout"
|
||||
#define KM_CORE_KMX_ENV_BASELAYOUTALT u"baseLayoutAlt"
|
||||
#define KM_CORE_KMX_ENV_SIMULATEALTGR u"simulateAltgr"
|
||||
#define KM_CORE_KMX_ENV_CAPSLOCK u"capsLock"
|
||||
#define KM_CORE_KMX_ENV_BASELAYOUTGIVESCTRLRALTFORRALT u"baseLayoutGivesCtrlRAltForRAlt"
|
||||
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <keyman/keyboardprocessor_bits.h>
|
||||
#include <keyman/keyboardprocessor_vkeys.h>
|
||||
#include <keyman/keyman_core_api_bits.h>
|
||||
#include <keyman/keyman_core_api_vkeys.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
|
|
@ -24,7 +24,7 @@ extern "C"
|
|||
#endif
|
||||
|
||||
/**
|
||||
* The maximum size of context in km_kbp_cp units for a single debug
|
||||
* The maximum size of context in km_core_cp units for a single debug
|
||||
* event. This is taken from MAXCONTEXT in keyman32 (Windows) and is purely
|
||||
* a convenience value. We can increase it if there is a demonstrated need.
|
||||
*/
|
||||
|
|
@ -42,31 +42,31 @@ extern "C"
|
|||
* These modifier flags are used internally in the kmx engine, so will be
|
||||
* exposed only in debugging modifier states.
|
||||
*/
|
||||
#define KM_KBP_MODIFIER_VIRTUALKEY 0x4000
|
||||
#define KM_KBP_MODIFIER_VIRTUALCHARKEY 0x8000
|
||||
#define KM_CORE_MODIFIER_VIRTUALKEY 0x4000
|
||||
#define KM_CORE_MODIFIER_VIRTUALCHARKEY 0x8000
|
||||
|
||||
/**
|
||||
* Input key event data. The `character` member is derived from
|
||||
* a US English key event for vk + modifier_state, and is 0 if
|
||||
* the vk + modifier_state do not generate a character.
|
||||
*
|
||||
* Used only in event type KM_KBP_DEBUG_BEGIN.
|
||||
* Used only in event type KM_CORE_DEBUG_BEGIN.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t vk;
|
||||
uint16_t modifier_state;
|
||||
char16_t character;
|
||||
} km_kbp_state_debug_key_info;
|
||||
} km_core_state_debug_key_info;
|
||||
|
||||
/**
|
||||
* Option event data.
|
||||
*
|
||||
* Used only in event type KM_KBP_DEBUG_SET_OPTION.
|
||||
* Used only in event type KM_CORE_DEBUG_SET_OPTION.
|
||||
*/
|
||||
typedef struct {
|
||||
void *store; // LPSTORE
|
||||
km_kbp_cp value[DEBUG_MAX_CONTEXT]; // value to be saved into the store
|
||||
} km_kbp_state_debug_kmx_option_info;
|
||||
km_core_cp value[DEBUG_MAX_CONTEXT]; // value to be saved into the store
|
||||
} km_core_state_debug_kmx_option_info;
|
||||
|
||||
/**
|
||||
* KMX processor data for each event. kmx_base.h defines the types that are
|
||||
|
|
@ -76,11 +76,11 @@ typedef struct {
|
|||
* The context value here will be an intermediate value, and may differ
|
||||
* from event to event as the context can be rewritten for each rule match.
|
||||
*
|
||||
* Used in all event types except KM_KBP_DEBUG_BEGIN, KM_KBP_DEBUG_END.
|
||||
* Used in all event types except KM_CORE_DEBUG_BEGIN, KM_CORE_DEBUG_END.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
km_kbp_cp context[DEBUG_MAX_CONTEXT]; // The context matched by the rule (? may not need this?) // TODO: rename to context_matched
|
||||
km_core_cp context[DEBUG_MAX_CONTEXT]; // The context matched by the rule (? may not need this?) // TODO: rename to context_matched
|
||||
void *group; // LPGROUP
|
||||
void *rule; // LPKEY
|
||||
uint16_t store_offsets[DEBUG_STORE_OFFSETS_SIZE]; // pairs--store, char position, terminated by 0xFFFF // TODO use a better structure here
|
||||
|
|
@ -89,8 +89,8 @@ typedef struct {
|
|||
/// the debugger; the debugger uses this to determine when to
|
||||
/// execute the actions when single-stepping.
|
||||
uint16_t first_action;
|
||||
km_kbp_state_debug_kmx_option_info option;
|
||||
} km_kbp_state_debug_kmx_info;
|
||||
km_core_state_debug_kmx_option_info option;
|
||||
} km_core_state_debug_kmx_info;
|
||||
|
||||
/**
|
||||
* A single debug event.
|
||||
|
|
@ -98,38 +98,38 @@ typedef struct {
|
|||
typedef struct {
|
||||
uint32_t type; // 32 bits is better optimized than 8 bits
|
||||
uint32_t flags;
|
||||
km_kbp_state_debug_key_info key_info;
|
||||
km_kbp_state_debug_kmx_info kmx_info;
|
||||
} km_kbp_state_debug_item;
|
||||
km_core_state_debug_key_info key_info;
|
||||
km_core_state_debug_kmx_info kmx_info;
|
||||
} km_core_state_debug_item;
|
||||
|
||||
/**
|
||||
* A single debug event.
|
||||
*/
|
||||
enum km_kbp_debug_type {
|
||||
KM_KBP_DEBUG_BEGIN = 0,
|
||||
//KM_KBP_DEBUG_BEGIN_ANSI = 1, // not supported; instead rewrite ansi keyboards to Unicode with mcompile
|
||||
KM_KBP_DEBUG_GROUP_ENTER = 2,
|
||||
KM_KBP_DEBUG_GROUP_EXIT = 3,
|
||||
KM_KBP_DEBUG_RULE_ENTER = 4,
|
||||
KM_KBP_DEBUG_RULE_EXIT = 5,
|
||||
KM_KBP_DEBUG_MATCH_ENTER = 6,
|
||||
KM_KBP_DEBUG_MATCH_EXIT = 7,
|
||||
KM_KBP_DEBUG_NOMATCH_ENTER = 8,
|
||||
KM_KBP_DEBUG_NOMATCH_EXIT = 9,
|
||||
KM_KBP_DEBUG_END = 10,
|
||||
KM_KBP_DEBUG_SET_OPTION = 11,
|
||||
enum km_core_debug_type {
|
||||
KM_CORE_DEBUG_BEGIN = 0,
|
||||
//KM_CORE_DEBUG_BEGIN_ANSI = 1, // not supported; instead rewrite ansi keyboards to Unicode with mcompile
|
||||
KM_CORE_DEBUG_GROUP_ENTER = 2,
|
||||
KM_CORE_DEBUG_GROUP_EXIT = 3,
|
||||
KM_CORE_DEBUG_RULE_ENTER = 4,
|
||||
KM_CORE_DEBUG_RULE_EXIT = 5,
|
||||
KM_CORE_DEBUG_MATCH_ENTER = 6,
|
||||
KM_CORE_DEBUG_MATCH_EXIT = 7,
|
||||
KM_CORE_DEBUG_NOMATCH_ENTER = 8,
|
||||
KM_CORE_DEBUG_NOMATCH_EXIT = 9,
|
||||
KM_CORE_DEBUG_END = 10,
|
||||
KM_CORE_DEBUG_SET_OPTION = 11,
|
||||
};
|
||||
|
||||
// Flags for KM_KBP_DEBUG_GROUP_EXIT
|
||||
#define KM_KBP_DEBUG_FLAG_RECURSIVE_OVERFLOW 0x0001
|
||||
#define KM_KBP_DEBUG_FLAG_NOMATCH 0x0002
|
||||
// Flags for KM_CORE_DEBUG_GROUP_EXIT
|
||||
#define KM_CORE_DEBUG_FLAG_RECURSIVE_OVERFLOW 0x0001
|
||||
#define KM_CORE_DEBUG_FLAG_NOMATCH 0x0002
|
||||
|
||||
// Flags for KM_KBP_DEBUG_BEGIN
|
||||
// Flags for KM_CORE_DEBUG_BEGIN
|
||||
// TODO: do we need this at all?
|
||||
#define KM_KBP_DEBUG_FLAG_UNICODE 0x0001 // Always set
|
||||
#define KM_CORE_DEBUG_FLAG_UNICODE 0x0001 // Always set
|
||||
|
||||
// Flags for KM_KBP_DEBUG_END
|
||||
#define KM_KBP_DEBUG_FLAG_OUTPUTKEYSTROKE 0x0001
|
||||
// Flags for KM_CORE_DEBUG_END
|
||||
#define KM_CORE_DEBUG_FLAG_OUTPUTKEYSTROKE 0x0001
|
||||
|
||||
/**
|
||||
* Enable or disable debug tracing
|
||||
|
|
@ -137,11 +137,11 @@ enum km_kbp_debug_type {
|
|||
* @param state Pointer to initialized state
|
||||
* @param value Set to 1 to enable debugging, 0 to disable
|
||||
*
|
||||
* @returns KM_KBP_STATUS_OK on success
|
||||
* @returns KM_CORE_STATUS_OK on success
|
||||
*/
|
||||
KMN_API
|
||||
km_kbp_status
|
||||
km_kbp_state_debug_set(km_kbp_state *state, int value);
|
||||
km_core_status
|
||||
km_core_state_debug_set(km_core_state *state, int value);
|
||||
|
||||
/**
|
||||
* Get current debug tracing status
|
||||
|
|
@ -152,7 +152,7 @@ km_kbp_state_debug_set(km_kbp_state *state, int value);
|
|||
*/
|
||||
KMN_API
|
||||
uint8_t
|
||||
km_kbp_state_debug_get(km_kbp_state const *state);
|
||||
km_core_state_debug_get(km_core_state const *state);
|
||||
|
||||
/**
|
||||
* Read current debug trace log
|
||||
|
|
@ -162,11 +162,11 @@ km_kbp_state_debug_get(km_kbp_state const *state);
|
|||
* nullptr if not required.
|
||||
*
|
||||
* @returns pointer to read only array of debug item events,
|
||||
* with last entry guaranteed to be KM_KBP_DEBUG_END.
|
||||
* with last entry guaranteed to be KM_CORE_DEBUG_END.
|
||||
*/
|
||||
KMN_API
|
||||
km_kbp_state_debug_item const *
|
||||
km_kbp_state_debug_items(km_kbp_state const *state, size_t *num_items);
|
||||
km_core_state_debug_item const *
|
||||
km_core_state_debug_items(km_core_state const *state, size_t *num_items);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern "C"
|
||||
15
core/include/keyman/keyman_core_api_version.h.in
Normal file
15
core/include/keyman/keyman_core_api_version.h.in
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#define km_core_version_stringify(x) km_core_version_to_string(x)
|
||||
#define km_core_version_to_string(x) #x
|
||||
|
||||
// Product versioning
|
||||
|
||||
#define KM_CORE_VERSION_MAJOR @majorver@
|
||||
#define KM_CORE_VERSION_MINOR @minorver@
|
||||
#define KM_CORE_VERSION_PATCH @patchver@
|
||||
#define KM_CORE_VERSION_STRING km_core_version_stringify(@majorver@ ## . ## @minorver@ ## . ## @patchver@ ## .0)
|
||||
|
||||
// API versioning
|
||||
|
||||
#define KM_CORE_LIB_CURRENT @lib_curr@
|
||||
#define KM_CORE_LIB_AGE @lib_age@
|
||||
#define KM_CORE_LIB_REVISION @lib_rev@
|
||||
312
core/include/keyman/keyman_core_api_vkeys.h
Normal file
312
core/include/keyman/keyman_core_api_vkeys.h
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
Copyright: © 2018 SIL International.
|
||||
Description: API declarations for modifier keys, handy access masks and
|
||||
Keyman VKEY names. These follow the same keytop->code
|
||||
associations as the Windows API. This is a separate header to
|
||||
maintain readability of the primary API header.
|
||||
Create Date: 17 Oct 2018
|
||||
Authors: Tim Eves (TSE)
|
||||
History: 17 Oct 2018 - TSE - Moved & refactored km_core_modifier_state
|
||||
from keyman_core_api.h.
|
||||
- Added VKey and mask definitions.
|
||||
6 Oct 2018 - TSE - Move into keyman folder.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum km_core_modifier_state {
|
||||
KM_CORE_MODIFIER_LCTRL = 1 << 0,
|
||||
KM_CORE_MODIFIER_RCTRL = 1 << 1,
|
||||
KM_CORE_MODIFIER_LALT = 1 << 2,
|
||||
KM_CORE_MODIFIER_RALT = 1 << 3,
|
||||
KM_CORE_MODIFIER_SHIFT = 1 << 4,
|
||||
KM_CORE_MODIFIER_CTRL = 1 << 5,
|
||||
KM_CORE_MODIFIER_ALT = 1 << 6,
|
||||
/*
|
||||
KM_CORE_MODIFIER_META = 1 << 7, // Either Meta-key flag (tentative). Not usable by keyboards currently
|
||||
// Used internally (currently, only by KMW) to ensure Meta-key
|
||||
// shortcuts safely bypass rules
|
||||
// Meta key = Command key on macOS, Windows key on Windows
|
||||
*/
|
||||
KM_CORE_MODIFIER_CAPS = 1 << 8,
|
||||
KM_CORE_MODIFIER_NOCAPS = 1 << 9,
|
||||
/*
|
||||
KM_CORE_MODIFIER_NUMLOCK = 1 << 10,
|
||||
KM_CORE_MODIFIER_NONUMLOCK = 1 << 11,
|
||||
KM_CORE_MODIFIER_SCROLLOCK = 1 << 12,
|
||||
KM_CORE_MODIFIER_NOSCROLLOCK = 1 << 13,
|
||||
KM_CORE_MODIFIER_VIRTUALKEY = 1 << 14,
|
||||
*/
|
||||
};
|
||||
|
||||
enum km_core_modifier_mask {
|
||||
KM_CORE_MODIFIER_MASK_ALL = 0x7f,
|
||||
KM_CORE_MODIFIER_MASK_ALT_GR_SIM = KM_CORE_MODIFIER_LCTRL|KM_CORE_MODIFIER_LALT,
|
||||
KM_CORE_MODIFIER_MASK_CHIRAL = 0x1f,
|
||||
KM_CORE_MODIFIER_MASK_IS_CHIRAL = 0x0f,
|
||||
KM_CORE_MODIFIER_MASK_NON_CHIRAL = 0x7f,
|
||||
KM_CORE_MODIFIER_MASK_CAPS = 0x0300,
|
||||
/*KM_CORE_MODIFIER_MASK_NUMLOCK = 0x0C00,
|
||||
KM_CORE_MODIFIER_MASK_SCROLLLOCK = 0x3000,*/
|
||||
};
|
||||
|
||||
// These are Windows API VKEYs, using Keyman VKEY names.
|
||||
enum km_kpb_virtual_key {
|
||||
KM_CORE_VKEY__00,
|
||||
KM_CORE_VKEY_LBUTTON,
|
||||
KM_CORE_VKEY_RBUTTON,
|
||||
KM_CORE_VKEY_CANCEL,
|
||||
KM_CORE_VKEY_MBUTTON,
|
||||
KM_CORE_VKEY__05,
|
||||
KM_CORE_VKEY__06,
|
||||
KM_CORE_VKEY__07,
|
||||
KM_CORE_VKEY_BKSP,
|
||||
KM_CORE_VKEY_TAB,
|
||||
KM_CORE_VKEY__0A,
|
||||
KM_CORE_VKEY__0B,
|
||||
KM_CORE_VKEY_KP5,
|
||||
KM_CORE_VKEY_ENTER,
|
||||
KM_CORE_VKEY__0E,
|
||||
KM_CORE_VKEY__0F,
|
||||
KM_CORE_VKEY_SHIFT,
|
||||
KM_CORE_VKEY_CONTROL,
|
||||
KM_CORE_VKEY_ALT,
|
||||
KM_CORE_VKEY_PAUSE,
|
||||
KM_CORE_VKEY_CAPS,
|
||||
KM_CORE_VKEY__15,
|
||||
KM_CORE_VKEY__16,
|
||||
KM_CORE_VKEY__17,
|
||||
KM_CORE_VKEY__18,
|
||||
KM_CORE_VKEY__19,
|
||||
KM_CORE_VKEY__1A,
|
||||
KM_CORE_VKEY_ESC,
|
||||
KM_CORE_VKEY__1C,
|
||||
KM_CORE_VKEY__1D,
|
||||
KM_CORE_VKEY__1E,
|
||||
KM_CORE_VKEY__1F,
|
||||
KM_CORE_VKEY_SPACE,
|
||||
KM_CORE_VKEY_PGUP,
|
||||
KM_CORE_VKEY_PGDN,
|
||||
KM_CORE_VKEY_END,
|
||||
KM_CORE_VKEY_HOME,
|
||||
KM_CORE_VKEY_LEFT,
|
||||
KM_CORE_VKEY_UP,
|
||||
KM_CORE_VKEY_RIGHT,
|
||||
KM_CORE_VKEY_DOWN,
|
||||
KM_CORE_VKEY_SEL,
|
||||
KM_CORE_VKEY_PRINT,
|
||||
KM_CORE_VKEY_EXEC,
|
||||
KM_CORE_VKEY_PRTSCN,
|
||||
KM_CORE_VKEY_INS,
|
||||
KM_CORE_VKEY_DEL,
|
||||
KM_CORE_VKEY_HELP,
|
||||
KM_CORE_VKEY_0,
|
||||
KM_CORE_VKEY_1,
|
||||
KM_CORE_VKEY_2,
|
||||
KM_CORE_VKEY_3,
|
||||
KM_CORE_VKEY_4,
|
||||
KM_CORE_VKEY_5,
|
||||
KM_CORE_VKEY_6,
|
||||
KM_CORE_VKEY_7,
|
||||
KM_CORE_VKEY_8,
|
||||
KM_CORE_VKEY_9,
|
||||
KM_CORE_VKEY__3A,
|
||||
KM_CORE_VKEY__3B,
|
||||
KM_CORE_VKEY__3C,
|
||||
KM_CORE_VKEY__3D,
|
||||
KM_CORE_VKEY__3E,
|
||||
KM_CORE_VKEY__3F,
|
||||
KM_CORE_VKEY__40,
|
||||
KM_CORE_VKEY_A,
|
||||
KM_CORE_VKEY_B,
|
||||
KM_CORE_VKEY_C,
|
||||
KM_CORE_VKEY_D,
|
||||
KM_CORE_VKEY_E,
|
||||
KM_CORE_VKEY_F,
|
||||
KM_CORE_VKEY_G,
|
||||
KM_CORE_VKEY_H,
|
||||
KM_CORE_VKEY_I,
|
||||
KM_CORE_VKEY_J,
|
||||
KM_CORE_VKEY_K,
|
||||
KM_CORE_VKEY_L,
|
||||
KM_CORE_VKEY_M,
|
||||
KM_CORE_VKEY_N,
|
||||
KM_CORE_VKEY_O,
|
||||
KM_CORE_VKEY_P,
|
||||
KM_CORE_VKEY_Q,
|
||||
KM_CORE_VKEY_R,
|
||||
KM_CORE_VKEY_S,
|
||||
KM_CORE_VKEY_T,
|
||||
KM_CORE_VKEY_U,
|
||||
KM_CORE_VKEY_V,
|
||||
KM_CORE_VKEY_W,
|
||||
KM_CORE_VKEY_X,
|
||||
KM_CORE_VKEY_Y,
|
||||
KM_CORE_VKEY_Z,
|
||||
KM_CORE_VKEY__5B,
|
||||
KM_CORE_VKEY__5C,
|
||||
KM_CORE_VKEY__5D,
|
||||
KM_CORE_VKEY__5E,
|
||||
KM_CORE_VKEY__5F,
|
||||
KM_CORE_VKEY_NP0,
|
||||
KM_CORE_VKEY_NP1,
|
||||
KM_CORE_VKEY_NP2,
|
||||
KM_CORE_VKEY_NP3,
|
||||
KM_CORE_VKEY_NP4,
|
||||
KM_CORE_VKEY_NP5,
|
||||
KM_CORE_VKEY_NP6,
|
||||
KM_CORE_VKEY_NP7,
|
||||
KM_CORE_VKEY_NP8,
|
||||
KM_CORE_VKEY_NP9,
|
||||
KM_CORE_VKEY_NPSTAR,
|
||||
KM_CORE_VKEY_NPPLUS,
|
||||
KM_CORE_VKEY_SEPARATOR,
|
||||
KM_CORE_VKEY_NPMINUS,
|
||||
KM_CORE_VKEY_NPDOT,
|
||||
KM_CORE_VKEY_NPSLASH,
|
||||
KM_CORE_VKEY_F1,
|
||||
KM_CORE_VKEY_F2,
|
||||
KM_CORE_VKEY_F3,
|
||||
KM_CORE_VKEY_F4,
|
||||
KM_CORE_VKEY_F5,
|
||||
KM_CORE_VKEY_F6,
|
||||
KM_CORE_VKEY_F7,
|
||||
KM_CORE_VKEY_F8,
|
||||
KM_CORE_VKEY_F9,
|
||||
KM_CORE_VKEY_F10,
|
||||
KM_CORE_VKEY_F11,
|
||||
KM_CORE_VKEY_F12,
|
||||
KM_CORE_VKEY_F13,
|
||||
KM_CORE_VKEY_F14,
|
||||
KM_CORE_VKEY_F15,
|
||||
KM_CORE_VKEY_F16,
|
||||
KM_CORE_VKEY_F17,
|
||||
KM_CORE_VKEY_F18,
|
||||
KM_CORE_VKEY_F19,
|
||||
KM_CORE_VKEY_F20,
|
||||
KM_CORE_VKEY_F21,
|
||||
KM_CORE_VKEY_F22,
|
||||
KM_CORE_VKEY_F23,
|
||||
KM_CORE_VKEY_F24,
|
||||
KM_CORE_VKEY__88,
|
||||
KM_CORE_VKEY__89,
|
||||
KM_CORE_VKEY__8A,
|
||||
KM_CORE_VKEY__8B,
|
||||
KM_CORE_VKEY__8C,
|
||||
KM_CORE_VKEY__8D,
|
||||
KM_CORE_VKEY__8E,
|
||||
KM_CORE_VKEY__8F,
|
||||
KM_CORE_VKEY_NUMLOCK,
|
||||
KM_CORE_VKEY_SCROLL,
|
||||
KM_CORE_VKEY__92,
|
||||
KM_CORE_VKEY__93,
|
||||
KM_CORE_VKEY__94,
|
||||
KM_CORE_VKEY__95,
|
||||
KM_CORE_VKEY__96,
|
||||
KM_CORE_VKEY__97,
|
||||
KM_CORE_VKEY__98,
|
||||
KM_CORE_VKEY__99,
|
||||
KM_CORE_VKEY__9A,
|
||||
KM_CORE_VKEY__9B,
|
||||
KM_CORE_VKEY__9C,
|
||||
KM_CORE_VKEY__9D,
|
||||
KM_CORE_VKEY__9E,
|
||||
KM_CORE_VKEY__9F,
|
||||
KM_CORE_VKEY__A0,
|
||||
KM_CORE_VKEY__A1,
|
||||
KM_CORE_VKEY__A2,
|
||||
KM_CORE_VKEY__A3,
|
||||
KM_CORE_VKEY__A4,
|
||||
KM_CORE_VKEY__A5,
|
||||
KM_CORE_VKEY__A6,
|
||||
KM_CORE_VKEY__A7,
|
||||
KM_CORE_VKEY__A8,
|
||||
KM_CORE_VKEY__A9,
|
||||
KM_CORE_VKEY__AA,
|
||||
KM_CORE_VKEY__AB,
|
||||
KM_CORE_VKEY__AC,
|
||||
KM_CORE_VKEY__AD,
|
||||
KM_CORE_VKEY__AE,
|
||||
KM_CORE_VKEY__AF,
|
||||
KM_CORE_VKEY__B0,
|
||||
KM_CORE_VKEY__B1,
|
||||
KM_CORE_VKEY__B2,
|
||||
KM_CORE_VKEY__B3,
|
||||
KM_CORE_VKEY__B4,
|
||||
KM_CORE_VKEY__B5,
|
||||
KM_CORE_VKEY__B6,
|
||||
KM_CORE_VKEY__B7,
|
||||
KM_CORE_VKEY__B8,
|
||||
KM_CORE_VKEY__B9,
|
||||
KM_CORE_VKEY_COLON,
|
||||
KM_CORE_VKEY_EQUAL,
|
||||
KM_CORE_VKEY_COMMA,
|
||||
KM_CORE_VKEY_HYPHEN,
|
||||
KM_CORE_VKEY_PERIOD,
|
||||
KM_CORE_VKEY_SLASH,
|
||||
KM_CORE_VKEY_BKQUOTE,
|
||||
KM_CORE_VKEY__C1,
|
||||
KM_CORE_VKEY__C2,
|
||||
KM_CORE_VKEY__C3,
|
||||
KM_CORE_VKEY__C4,
|
||||
KM_CORE_VKEY__C5,
|
||||
KM_CORE_VKEY__C6,
|
||||
KM_CORE_VKEY__C7,
|
||||
KM_CORE_VKEY__C8,
|
||||
KM_CORE_VKEY__C9,
|
||||
KM_CORE_VKEY__CA,
|
||||
KM_CORE_VKEY__CB,
|
||||
KM_CORE_VKEY__CC,
|
||||
KM_CORE_VKEY__CD,
|
||||
KM_CORE_VKEY__CE,
|
||||
KM_CORE_VKEY__CF,
|
||||
KM_CORE_VKEY__D0,
|
||||
KM_CORE_VKEY__D1,
|
||||
KM_CORE_VKEY__D2,
|
||||
KM_CORE_VKEY__D3,
|
||||
KM_CORE_VKEY__D4,
|
||||
KM_CORE_VKEY__D5,
|
||||
KM_CORE_VKEY__D6,
|
||||
KM_CORE_VKEY__D7,
|
||||
KM_CORE_VKEY__D8,
|
||||
KM_CORE_VKEY__D9,
|
||||
KM_CORE_VKEY__DA,
|
||||
KM_CORE_VKEY_LBRKT,
|
||||
KM_CORE_VKEY_BKSLASH,
|
||||
KM_CORE_VKEY_RBRKT,
|
||||
KM_CORE_VKEY_QUOTE,
|
||||
KM_CORE_VKEY_oDF,
|
||||
KM_CORE_VKEY_oE0,
|
||||
KM_CORE_VKEY_oE1,
|
||||
KM_CORE_VKEY_oE2, // 102nd key on European layouts
|
||||
KM_CORE_VKEY_oE3,
|
||||
KM_CORE_VKEY_oE4,
|
||||
KM_CORE_VKEY__E5,
|
||||
KM_CORE_VKEY_oE6,
|
||||
KM_CORE_VKEY__E7,
|
||||
KM_CORE_VKEY__E8,
|
||||
KM_CORE_VKEY_oE9,
|
||||
KM_CORE_VKEY_oEA,
|
||||
KM_CORE_VKEY_oEB,
|
||||
KM_CORE_VKEY_oEC,
|
||||
KM_CORE_VKEY_oED,
|
||||
KM_CORE_VKEY_oEE,
|
||||
KM_CORE_VKEY_oEF,
|
||||
KM_CORE_VKEY_oF0,
|
||||
KM_CORE_VKEY_oF1,
|
||||
KM_CORE_VKEY_oF2,
|
||||
KM_CORE_VKEY_oF3,
|
||||
KM_CORE_VKEY_oF4,
|
||||
KM_CORE_VKEY_oF5,
|
||||
KM_CORE_VKEY__F6,
|
||||
KM_CORE_VKEY__F7,
|
||||
KM_CORE_VKEY__F8,
|
||||
KM_CORE_VKEY__F9,
|
||||
KM_CORE_VKEY__FA,
|
||||
KM_CORE_VKEY__FB,
|
||||
KM_CORE_VKEY__FC,
|
||||
KM_CORE_VKEY__FD,
|
||||
KM_CORE_VKEY__FE,
|
||||
KM_CORE_VKEY__FF,
|
||||
};
|
||||
|
|
@ -19,16 +19,16 @@ cfg.set('patchver', project_ver[2])
|
|||
|
||||
configure_file(
|
||||
configuration: cfg,
|
||||
input: 'keyboardprocessor_version.h.in',
|
||||
output: 'keyboardprocessor_version.h',
|
||||
input: 'keyman_core_api_version.h.in',
|
||||
output: 'keyman_core_api_version.h',
|
||||
)
|
||||
|
||||
install_headers('keyboardprocessor.h',
|
||||
'keyboardprocessor_bits.h',
|
||||
'keyboardprocessor_consts.h',
|
||||
'keyboardprocessor_debug.h',
|
||||
'keyboardprocessor_vkeys.h',
|
||||
join_paths(meson.current_build_dir(), 'keyboardprocessor_version.h'),
|
||||
install_headers('keyman_core_api.h',
|
||||
'keyman_core_api_bits.h',
|
||||
'keyman_core_api_consts.h',
|
||||
'keyman_core_api_debug.h',
|
||||
'keyman_core_api_vkeys.h',
|
||||
join_paths(meson.current_build_dir(), 'keyman_core_api_version.h'),
|
||||
'../../../common/include/km_types.h',
|
||||
'../../../common/include/kmx_file.h',
|
||||
subdir: 'keyman')
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#pragma once
|
||||
|
||||
#define LDML_BKSP_FLAGS_ERROR 0x1
|
||||
#define LDML_CLDR_IMPLIED_FORMS_IMPORT "techpreview/scanCodes-implied.xml"
|
||||
#define LDML_CLDR_IMPLIED_KEYS_IMPORT "techpreview/keys-Latn-implied.xml"
|
||||
#define LDML_CLDR_IMPORT_BASE "cldr"
|
||||
#define LDML_CLDR_VERSION_LATEST "techpreview"
|
||||
|
|
@ -45,11 +46,7 @@
|
|||
#define LDML_KEYS_MOD_CTRLR 0x2
|
||||
#define LDML_KEYS_MOD_NONE 0x0
|
||||
#define LDML_KEYS_MOD_SHIFT 0x10
|
||||
#define LDML_LAYR_LIST_HARDWARE_ABNT2 0x1
|
||||
#define LDML_LAYR_LIST_HARDWARE_ISO 0x2
|
||||
#define LDML_LAYR_LIST_HARDWARE_JIS 0x3
|
||||
#define LDML_LAYR_LIST_HARDWARE_TOUCH 0x0
|
||||
#define LDML_LAYR_LIST_HARDWARE_US 0x4
|
||||
#define LDML_LAYR_LIST_HARDWARE_TOUCH "touch"
|
||||
#define LDML_LENGTH_BKSP 0xC
|
||||
#define LDML_LENGTH_BKSP_ITEM 0x10
|
||||
#define LDML_LENGTH_DISP 0x10
|
||||
|
|
@ -91,8 +88,6 @@
|
|||
#define LDML_LENGTH_USET_USET 0xC
|
||||
#define LDML_LENGTH_VARS 0x10
|
||||
#define LDML_LENGTH_VARS_ITEM 0x10
|
||||
#define LDML_LENGTH_VKEY 0xC
|
||||
#define LDML_LENGTH_VKEY_ITEM 0x8
|
||||
#define LDML_MARKER_ANY_INDEX 0xD7FF
|
||||
#define LDML_MARKER_CODE 0x8
|
||||
#define LDML_MARKER_MAX_COUNT 0xD7FE
|
||||
|
|
@ -129,8 +124,6 @@
|
|||
#define LDML_SECTIONNAME_USET "uset"
|
||||
#define LDML_SECTIONID_VARS 0x73726176 /* "vars" */
|
||||
#define LDML_SECTIONNAME_VARS "vars"
|
||||
#define LDML_SECTIONID_VKEY 0x79656B76 /* "vkey" */
|
||||
#define LDML_SECTIONNAME_VKEY "vkey"
|
||||
#define LDML_TRAN_FLAGS_ERROR 0x1
|
||||
#define LDML_TRAN_GROUP_TYPE_REORDER 0x1
|
||||
#define LDML_TRAN_GROUP_TYPE_TRANSFORM 0x0
|
||||
|
|
|
|||
|
|
@ -37,8 +37,7 @@ export type SectionIdent =
|
|||
'strs' |
|
||||
'tran' |
|
||||
'uset' |
|
||||
'vars' |
|
||||
'vkey';
|
||||
'vars';
|
||||
|
||||
|
||||
type SectionMap = {
|
||||
|
|
@ -74,6 +73,10 @@ class Constants {
|
|||
* implied keys file
|
||||
*/
|
||||
readonly cldr_implied_keys_import = `${this.cldr_version_techpreview}/keys-Latn-implied.xml`;
|
||||
/**
|
||||
* implied scancodes file
|
||||
*/
|
||||
readonly cldr_implied_forms_import = `${this.cldr_version_techpreview}/scanCodes-implied.xml`;
|
||||
/**
|
||||
* Length of a raw section header, in bytes
|
||||
*/
|
||||
|
|
@ -350,35 +353,7 @@ class Constants {
|
|||
/**
|
||||
* for the 'hardware' field indicating a touch keyboard, non-hardware
|
||||
*/
|
||||
readonly layr_list_hardware_touch = 0;
|
||||
/**
|
||||
* for the 'hardware' field indicating an abnt2 layout
|
||||
*/
|
||||
readonly layr_list_hardware_abnt2 = 1;
|
||||
/**
|
||||
* for the 'hardware' field indicating an iso layout
|
||||
*/
|
||||
readonly layr_list_hardware_iso = 2;
|
||||
/**
|
||||
* for the 'hardware' field indicating a jis layout
|
||||
*/
|
||||
readonly layr_list_hardware_jis = 3;
|
||||
/**
|
||||
* for the 'hardware' field indicating a us layout
|
||||
*/
|
||||
readonly layr_list_hardware_us = 4;
|
||||
/**
|
||||
* Convenience map of layr_list_hardware field values
|
||||
*/
|
||||
readonly layr_list_hardware_map: Map<String, number> = new Map(
|
||||
[
|
||||
["touch", this.layr_list_hardware_touch],
|
||||
["abnt2", this.layr_list_hardware_abnt2],
|
||||
["iso", this.layr_list_hardware_iso],
|
||||
["jis", this.layr_list_hardware_jis],
|
||||
["us", this.layr_list_hardware_us],
|
||||
]
|
||||
);
|
||||
readonly layr_list_hardware_touch = 'touch';
|
||||
/**
|
||||
* Length of each layer entry in the 'layr' section variable part
|
||||
*/
|
||||
|
|
@ -504,19 +479,6 @@ class Constants {
|
|||
*/
|
||||
readonly tran_group_type_reorder = 1;
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* vkey section
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* Minimum length of the 'vkey' section not including variable parts
|
||||
*/
|
||||
readonly length_vkey = 12;
|
||||
/**
|
||||
* Length of each item in the 'vkey' section variable part
|
||||
*/
|
||||
readonly length_vkey_item = 8;
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* vars section
|
||||
* ------------------------------------------------------------------ */
|
||||
|
|
@ -581,7 +543,6 @@ class Constants {
|
|||
tran: 'tran',
|
||||
uset: 'uset',
|
||||
vars: 'vars',
|
||||
vkey: 'vkey',
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.esm-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
{
|
||||
"extends": "../../../tsconfig-base.json",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"module": "es2020",
|
||||
"moduleResolution": "node",
|
||||
"rootDir": ".",
|
||||
"outDir": "build/",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@
|
|||
Description: Internal context class and adaptor class for the API.
|
||||
Create Date: 2 Oct 2018
|
||||
Authors: Tim Eves (TSE)
|
||||
History: 2 Oct 2018 - TSE - Refactored out of km_kbp_context_api.cpp
|
||||
History: 2 Oct 2018 - TSE - Refactored out of km_core_context_api.cpp
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <keyman/keyboardprocessor.h>
|
||||
#include <keyman/keyman_core_api.h>
|
||||
|
||||
// Forward declarations
|
||||
class json;
|
||||
|
|
@ -20,32 +20,32 @@ namespace kbp
|
|||
|
||||
// This will likely be replaced with a class implementing a more space
|
||||
// efficient data structure such as a ring buffer or bounded queue.
|
||||
class context: public std::list<km_kbp_context_item>
|
||||
class context: public std::list<km_core_context_item>
|
||||
{
|
||||
public:
|
||||
void push_character(km_kbp_usv);
|
||||
void push_character(km_core_usv);
|
||||
void push_marker(uint32_t);
|
||||
};
|
||||
|
||||
|
||||
inline
|
||||
void context::push_character(km_kbp_usv usv) {
|
||||
emplace_back(km_kbp_context_item { KM_KBP_CT_CHAR, {0,}, {usv} });
|
||||
void context::push_character(km_core_usv usv) {
|
||||
emplace_back(km_core_context_item { KM_CORE_CT_CHAR, {0,}, {usv} });
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
void context::push_marker(uint32_t marker) {
|
||||
emplace_back(km_kbp_context_item { KM_KBP_CT_MARKER, {0,}, {marker} });
|
||||
emplace_back(km_core_context_item { KM_CORE_CT_MARKER, {0,}, {marker} });
|
||||
}
|
||||
|
||||
} // namespace kbp
|
||||
} // namespace km
|
||||
|
||||
json & operator << (json &, km::kbp::context const &);
|
||||
json & operator << (json &, km_kbp_context_item const &);
|
||||
json & operator << (json &, km_core_context_item const &);
|
||||
|
||||
|
||||
struct km_kbp_context : public km::kbp::context
|
||||
struct km_core_context : public km::kbp::context
|
||||
{
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,20 +9,20 @@
|
|||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
#include <keyman/keyboardprocessor.h>
|
||||
#include <keyman/keyboardprocessor_debug.h>
|
||||
#include <keyman/keyman_core_api.h>
|
||||
#include <keyman/keyman_core_api_debug.h>
|
||||
|
||||
namespace km {
|
||||
namespace kbp
|
||||
{
|
||||
|
||||
class debug_items : public std::vector<km_kbp_state_debug_item>
|
||||
class debug_items : public std::vector<km_core_state_debug_item>
|
||||
{
|
||||
private:
|
||||
bool _is_enabled;
|
||||
public:
|
||||
template<typename... Args> debug_items(Args&&... args);
|
||||
void push_begin(km_kbp_state_debug_key_info *key_info, uint32_t flags);
|
||||
void push_begin(km_core_state_debug_key_info *key_info, uint32_t flags);
|
||||
void push_end(uint16_t first_action, uint32_t flags);
|
||||
void assert_push_entry();
|
||||
bool is_enabled() const noexcept;
|
||||
|
|
@ -31,29 +31,29 @@ public:
|
|||
|
||||
template<typename... Args>
|
||||
debug_items::debug_items(Args&&... args)
|
||||
: std::vector<km_kbp_state_debug_item>(std::forward<Args>(args)...)
|
||||
: std::vector<km_core_state_debug_item>(std::forward<Args>(args)...)
|
||||
{
|
||||
// Ensure the debug_items list is terminated in case the client calls
|
||||
// km_kbp_state_debug_items before they call process_event.
|
||||
// km_core_state_debug_items before they call process_event.
|
||||
_is_enabled = false;
|
||||
push_end(0, 0);
|
||||
}
|
||||
|
||||
inline
|
||||
void debug_items::assert_push_entry() {
|
||||
assert(empty() || (!empty() && back().type != KM_KBP_DEBUG_END));
|
||||
assert(empty() || (!empty() && back().type != KM_CORE_DEBUG_END));
|
||||
}
|
||||
|
||||
inline
|
||||
void debug_items::push_begin(km_kbp_state_debug_key_info *key_info, uint32_t flags) {
|
||||
void debug_items::push_begin(km_core_state_debug_key_info *key_info, uint32_t flags) {
|
||||
assert_push_entry();
|
||||
emplace_back(km_kbp_state_debug_item{ KM_KBP_DEBUG_BEGIN, flags, {*key_info, }, { }});
|
||||
emplace_back(km_core_state_debug_item{ KM_CORE_DEBUG_BEGIN, flags, {*key_info, }, { }});
|
||||
}
|
||||
|
||||
inline
|
||||
void debug_items::push_end(uint16_t first_action, uint32_t flags) {
|
||||
assert_push_entry();
|
||||
emplace_back(km_kbp_state_debug_item{ KM_KBP_DEBUG_END, flags, { }, { u"", nullptr, nullptr, { }, first_action, {} } });
|
||||
emplace_back(km_core_state_debug_item{ KM_CORE_DEBUG_END, flags, { }, { u"", nullptr, nullptr, { }, first_action, {} } });
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* Debugging */
|
||||
|
||||
#include <keyman/keyboardprocessor_bits.h>
|
||||
#include <keyman/keyman_core_api_bits.h>
|
||||
|
||||
namespace km {
|
||||
namespace kbp {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
Description: Internal keyboard class and adaptor class for the API.
|
||||
Create Date: 2 Oct 2018
|
||||
Authors: Tim Eves (TSE)
|
||||
History: 7 Oct 2018 - TSE - Refactored out of km_kbp_keyboard_api.cpp
|
||||
History: 7 Oct 2018 - TSE - Refactored out of km_core_keyboard_api.cpp
|
||||
*/
|
||||
#include "keyboard.hpp"
|
||||
#include "jsonpp.hpp"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
Description: Internal keyboard class and adaptor class for the API.
|
||||
Create Date: 2 Oct 2018
|
||||
Authors: Tim Eves (TSE)
|
||||
History: 2 Oct 2018 - TSE - Refactored out of km_kbp_keyboard_api.cpp
|
||||
History: 2 Oct 2018 - TSE - Refactored out of km_core_keyboard_api.cpp
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <keyman/keyboardprocessor.h>
|
||||
#include <keyman/keyman_core_api.h>
|
||||
|
||||
#include "option.hpp"
|
||||
#include "path.hpp"
|
||||
|
|
@ -22,7 +22,7 @@ class json;
|
|||
namespace km {
|
||||
namespace kbp
|
||||
{
|
||||
class keyboard_attributes : public km_kbp_keyboard_attrs
|
||||
class keyboard_attributes : public km_core_keyboard_attrs
|
||||
{
|
||||
std::u16string _keyboard_id;
|
||||
std::u16string _version_string;
|
||||
|
|
@ -36,7 +36,7 @@ namespace kbp
|
|||
using path_type = decltype(_folder_path);
|
||||
|
||||
keyboard_attributes()
|
||||
: km_kbp_keyboard_attrs {nullptr, nullptr, nullptr, nullptr} {}
|
||||
: km_core_keyboard_attrs {nullptr, nullptr, nullptr, nullptr} {}
|
||||
keyboard_attributes(keyboard_attributes const &) = delete;
|
||||
keyboard_attributes(keyboard_attributes &&);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include <keyman/keyboardprocessor.h>
|
||||
#include <keyman/keyman_core_api.h>
|
||||
|
||||
#include "context.hpp"
|
||||
#include "jsonpp.hpp"
|
||||
|
|
@ -20,44 +20,44 @@
|
|||
|
||||
namespace {
|
||||
template<class U>
|
||||
km_kbp_status
|
||||
km_core_status
|
||||
_context_items_from(typename U::codeunit_t const *text,
|
||||
km_kbp_context_item **out_ptr)
|
||||
km_core_context_item **out_ptr)
|
||||
{
|
||||
assert(text); assert(out_ptr);
|
||||
if (!text || !out_ptr) return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
if (!text || !out_ptr) return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
*out_ptr = nullptr;
|
||||
try
|
||||
{
|
||||
std::vector<km_kbp_context_item> res;
|
||||
std::vector<km_core_context_item> res;
|
||||
|
||||
for (auto i = typename U::const_iterator(text); *i; ++i)
|
||||
{
|
||||
if(i.error()) return KM_KBP_STATUS_INVALID_UTF;
|
||||
res.emplace_back(km_kbp_context_item {KM_KBP_CT_CHAR, {0,}, {*i}});
|
||||
if(i.error()) return KM_CORE_STATUS_INVALID_UTF;
|
||||
res.emplace_back(km_core_context_item {KM_CORE_CT_CHAR, {0,}, {*i}});
|
||||
}
|
||||
// Terminate the context_items array.
|
||||
res.emplace_back(km_kbp_context_item KM_KBP_CONTEXT_ITEM_END);
|
||||
res.emplace_back(km_core_context_item KM_CORE_CONTEXT_ITEM_END);
|
||||
|
||||
*out_ptr = new km_kbp_context_item[res.size()];
|
||||
*out_ptr = new km_core_context_item[res.size()];
|
||||
std::move(res.begin(), res.end(), *out_ptr);
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
return KM_KBP_STATUS_NO_MEM;
|
||||
return KM_CORE_STATUS_NO_MEM;
|
||||
}
|
||||
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
template<class U>
|
||||
km_kbp_status _context_items_to(km_kbp_context_item const *ci,
|
||||
km_core_status _context_items_to(km_core_context_item const *ci,
|
||||
typename U::codeunit_t *buf,
|
||||
size_t * sz_ptr)
|
||||
{
|
||||
assert(ci); assert(sz_ptr);
|
||||
if (!ci || !sz_ptr) return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
if (!ci || !sz_ptr) return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
auto const buf_size = *sz_ptr;
|
||||
|
||||
if (buf && buf_size > 0)
|
||||
|
|
@ -65,9 +65,9 @@ namespace {
|
|||
auto i = typename U::iterator(buf);
|
||||
auto const e = decltype(i)(buf + buf_size - 1);
|
||||
|
||||
for (;i != e && ci->type != KM_KBP_CT_END && !i.error(); ++ci)
|
||||
for (;i != e && ci->type != KM_CORE_CT_END && !i.error(); ++ci)
|
||||
{
|
||||
if (ci->type == KM_KBP_CT_CHAR)
|
||||
if (ci->type == KM_CORE_CT_CHAR)
|
||||
{
|
||||
*i = ci->character; ++i;
|
||||
}
|
||||
|
|
@ -77,13 +77,13 @@ namespace {
|
|||
*sz_ptr = buf_size - (e - i);
|
||||
|
||||
// Skip over any final markers - they are execluded from context
|
||||
while(ci->type == KM_KBP_CT_MARKER) {
|
||||
while(ci->type == KM_CORE_CT_MARKER) {
|
||||
ci++;
|
||||
}
|
||||
|
||||
return ci->type == KM_KBP_CT_END
|
||||
? KM_KBP_STATUS_OK
|
||||
: KM_KBP_STATUS_INSUFFICENT_BUFFER;
|
||||
return ci->type == KM_CORE_CT_END
|
||||
? KM_CORE_STATUS_OK
|
||||
: KM_CORE_STATUS_INSUFFICENT_BUFFER;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -92,38 +92,38 @@ namespace {
|
|||
|
||||
do
|
||||
{
|
||||
if (ci->type == KM_KBP_CT_CHAR)
|
||||
if (ci->type == KM_CORE_CT_CHAR)
|
||||
{
|
||||
int8_t l = 4;
|
||||
U::codec::put(cps, ci->character, l);
|
||||
n += l;
|
||||
}
|
||||
}
|
||||
while(ci++->type != KM_KBP_CT_END);
|
||||
while(ci++->type != KM_CORE_CT_END);
|
||||
|
||||
*sz_ptr = n+1;
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
km_kbp_status
|
||||
km_kbp_context_items_from_utf16(km_kbp_cp const *text,
|
||||
km_kbp_context_item **out_ptr)
|
||||
km_core_status
|
||||
km_core_context_items_from_utf16(km_core_cp const *text,
|
||||
km_core_context_item **out_ptr)
|
||||
{
|
||||
return _context_items_from<utf16>(reinterpret_cast<utf16::codeunit_t const *>(text), out_ptr);
|
||||
}
|
||||
|
||||
|
||||
km_kbp_status
|
||||
km_kbp_context_items_from_utf8(char const *text,
|
||||
km_kbp_context_item **out_ptr)
|
||||
km_core_status
|
||||
km_core_context_items_from_utf8(char const *text,
|
||||
km_core_context_item **out_ptr)
|
||||
{
|
||||
return _context_items_from<utf8>(reinterpret_cast<utf8::codeunit_t const *>(text), out_ptr);
|
||||
}
|
||||
|
||||
|
||||
km_kbp_status km_kbp_context_items_to_utf8(km_kbp_context_item const *ci,
|
||||
km_core_status km_core_context_items_to_utf8(km_core_context_item const *ci,
|
||||
char *buf, size_t * sz_ptr)
|
||||
{
|
||||
return _context_items_to<utf8>(ci,
|
||||
|
|
@ -132,8 +132,8 @@ km_kbp_status km_kbp_context_items_to_utf8(km_kbp_context_item const *ci,
|
|||
}
|
||||
|
||||
|
||||
km_kbp_status km_kbp_context_items_to_utf16(km_kbp_context_item const *ci,
|
||||
km_kbp_cp *buf, size_t * sz_ptr)
|
||||
km_core_status km_core_context_items_to_utf16(km_core_context_item const *ci,
|
||||
km_core_cp *buf, size_t * sz_ptr)
|
||||
{
|
||||
return _context_items_to<utf16>(ci,
|
||||
reinterpret_cast<utf16::codeunit_t *>(buf),
|
||||
|
|
@ -141,41 +141,41 @@ km_kbp_status km_kbp_context_items_to_utf16(km_kbp_context_item const *ci,
|
|||
}
|
||||
|
||||
|
||||
void km_kbp_context_items_dispose(km_kbp_context_item *ci)
|
||||
void km_core_context_items_dispose(km_core_context_item *ci)
|
||||
{
|
||||
delete [] ci;
|
||||
}
|
||||
|
||||
|
||||
km_kbp_status km_kbp_context_set(km_kbp_context *ctxt, km_kbp_context_item const *ci)
|
||||
km_core_status km_core_context_set(km_core_context *ctxt, km_core_context_item const *ci)
|
||||
{
|
||||
km_kbp_context_clear(ctxt);
|
||||
return km_kbp_context_append(ctxt, ci);
|
||||
km_core_context_clear(ctxt);
|
||||
return km_core_context_append(ctxt, ci);
|
||||
}
|
||||
|
||||
|
||||
km_kbp_status km_kbp_context_get(km_kbp_context const *ctxt,
|
||||
km_kbp_context_item **out_ptr)
|
||||
km_core_status km_core_context_get(km_core_context const *ctxt,
|
||||
km_core_context_item **out_ptr)
|
||||
{
|
||||
assert(ctxt); assert(out_ptr);
|
||||
if (!ctxt || !out_ptr) return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
if (!ctxt || !out_ptr) return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
try
|
||||
{
|
||||
*out_ptr = new km_kbp_context_item[ctxt->size() + 1];
|
||||
*out_ptr = new km_core_context_item[ctxt->size() + 1];
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
return KM_KBP_STATUS_NO_MEM;
|
||||
return KM_CORE_STATUS_NO_MEM;
|
||||
}
|
||||
std::copy(ctxt->begin(), ctxt->end(), *out_ptr);
|
||||
(*out_ptr)[ctxt->size()].type = KM_KBP_CT_END;
|
||||
(*out_ptr)[ctxt->size()].type = KM_CORE_CT_END;
|
||||
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
void km_kbp_context_clear(km_kbp_context *ctxt)
|
||||
void km_core_context_clear(km_core_context *ctxt)
|
||||
{
|
||||
assert(ctxt);
|
||||
if (ctxt)
|
||||
|
|
@ -185,38 +185,38 @@ void km_kbp_context_clear(km_kbp_context *ctxt)
|
|||
}
|
||||
|
||||
|
||||
size_t km_kbp_context_length(km_kbp_context *ctxt)
|
||||
size_t km_core_context_length(km_core_context *ctxt)
|
||||
{
|
||||
assert(ctxt);
|
||||
return ctxt ? ctxt->size() : 0;
|
||||
}
|
||||
|
||||
|
||||
km_kbp_status km_kbp_context_append(km_kbp_context *ctxt,
|
||||
km_kbp_context_item const *ci)
|
||||
km_core_status km_core_context_append(km_core_context *ctxt,
|
||||
km_core_context_item const *ci)
|
||||
{
|
||||
assert(ctxt); assert(ci);
|
||||
if (!ctxt || !ci) return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
if (!ctxt || !ci) return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
try
|
||||
{
|
||||
for (;ci->type != KM_KBP_CT_END; ++ci)
|
||||
for (;ci->type != KM_CORE_CT_END; ++ci)
|
||||
{
|
||||
ctxt->emplace_back(*ci);
|
||||
}
|
||||
} catch (std::bad_alloc &) {
|
||||
return KM_KBP_STATUS_NO_MEM;
|
||||
return KM_CORE_STATUS_NO_MEM;
|
||||
}
|
||||
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
km_kbp_status km_kbp_context_shrink(km_kbp_context *ctxt, size_t num,
|
||||
km_kbp_context_item const * ci)
|
||||
km_core_status km_core_context_shrink(km_core_context *ctxt, size_t num,
|
||||
km_core_context_item const * ci)
|
||||
{
|
||||
assert(ctxt);
|
||||
if (!ctxt) return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
if (!ctxt) return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -225,21 +225,21 @@ km_kbp_status km_kbp_context_shrink(km_kbp_context *ctxt, size_t num,
|
|||
if (ci)
|
||||
{
|
||||
auto const ip = ctxt->begin();
|
||||
while(num-- && ci->type != KM_KBP_CT_END)
|
||||
while(num-- && ci->type != KM_CORE_CT_END)
|
||||
{
|
||||
ctxt->emplace(ip, *ci);
|
||||
ci++;
|
||||
}
|
||||
}
|
||||
} catch (std::bad_alloc &) {
|
||||
return KM_KBP_STATUS_NO_MEM;
|
||||
return KM_CORE_STATUS_NO_MEM;
|
||||
}
|
||||
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
size_t
|
||||
km_kbp_context_item_list_size(km_kbp_context_item const *context_items)
|
||||
km_core_context_item_list_size(km_core_context_item const *context_items)
|
||||
{
|
||||
assert(context_items);
|
||||
if (!context_items) return 0;
|
||||
|
|
@ -258,18 +258,18 @@ json & operator << (json & j, km::kbp::context const & ctxt) {
|
|||
return j << json::close;
|
||||
}
|
||||
|
||||
json & operator << (json & j, km_kbp_context_item const & i)
|
||||
json & operator << (json & j, km_core_context_item const & i)
|
||||
{
|
||||
utf8::codeunit_t cps[7] = {0,}; // 6 bytes for maximal UTF-8 char (e.g. U+10FFFF) + nul terminator
|
||||
int8_t l = 4;
|
||||
|
||||
switch (i.type)
|
||||
{
|
||||
case KM_KBP_CT_CHAR:
|
||||
case KM_CORE_CT_CHAR:
|
||||
utf8::codec::put(cps, i.character, l);
|
||||
j << json::string(&cps[0]);
|
||||
break;
|
||||
case KM_KBP_CT_MARKER:
|
||||
case KM_CORE_CT_MARKER:
|
||||
j << json::integer_u(i.marker);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -8,29 +8,29 @@
|
|||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
#include <keyman/keyboardprocessor.h>
|
||||
#include <keyman/keyman_core_api.h>
|
||||
|
||||
#include "processor.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
using namespace km::kbp;
|
||||
|
||||
km_kbp_status
|
||||
km_kbp_state_debug_set(
|
||||
km_kbp_state *state,
|
||||
km_core_status
|
||||
km_core_state_debug_set(
|
||||
km_core_state *state,
|
||||
int value
|
||||
) {
|
||||
assert(state);
|
||||
if(!state) {
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
state->debug_items().set_enabled(value ? true : false);
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
km_kbp_state_debug_get(
|
||||
km_kbp_state const *state
|
||||
km_core_state_debug_get(
|
||||
km_core_state const *state
|
||||
) {
|
||||
assert(state);
|
||||
if(!state) {
|
||||
|
|
@ -39,9 +39,9 @@ km_kbp_state_debug_get(
|
|||
return state->debug_items().is_enabled() ? 1 : 0;
|
||||
}
|
||||
|
||||
km_kbp_state_debug_item const *
|
||||
km_kbp_state_debug_items(
|
||||
km_kbp_state const *state,
|
||||
km_core_state_debug_item const *
|
||||
km_core_state_debug_items(
|
||||
km_core_state const *state,
|
||||
size_t *num_items
|
||||
) {
|
||||
assert(state && state->debug_items().size() > 0);
|
||||
|
|
@ -58,6 +58,6 @@ km_kbp_state_debug_items(
|
|||
|
||||
// Process events will ensure that the debug vector is always well
|
||||
// terminated
|
||||
assert(state->debug_items().back().type == KM_KBP_DEBUG_END);
|
||||
assert(state->debug_items().back().type == KM_CORE_DEBUG_END);
|
||||
return state->debug_items().data();
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
#include <keyman/keyboardprocessor.h>
|
||||
#include <keyman/keyman_core_api.h>
|
||||
#include "keyboard.hpp"
|
||||
#include "processor.hpp"
|
||||
#include "kmx/kmx_processor.hpp"
|
||||
|
|
@ -43,85 +43,85 @@ namespace
|
|||
|
||||
|
||||
}
|
||||
km_kbp_status
|
||||
km_kbp_keyboard_load(km_kbp_path_name kb_path, km_kbp_keyboard **keyboard)
|
||||
km_core_status
|
||||
km_core_keyboard_load(km_core_path_name kb_path, km_core_keyboard **keyboard)
|
||||
{
|
||||
assert(keyboard);
|
||||
if (!keyboard)
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
try
|
||||
{
|
||||
abstract_processor *kp = processor_factory(kb_path);
|
||||
km_kbp_status status = kp->validate();
|
||||
if (status != KM_KBP_STATUS_OK) {
|
||||
km_core_status status = kp->validate();
|
||||
if (status != KM_CORE_STATUS_OK) {
|
||||
delete kp;
|
||||
return status;
|
||||
}
|
||||
*keyboard = static_cast<km_kbp_keyboard *>(kp);
|
||||
*keyboard = static_cast<km_core_keyboard *>(kp);
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
return KM_KBP_STATUS_NO_MEM;
|
||||
return KM_CORE_STATUS_NO_MEM;
|
||||
}
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
km_kbp_keyboard_dispose(km_kbp_keyboard *keyboard)
|
||||
km_core_keyboard_dispose(km_core_keyboard *keyboard)
|
||||
{
|
||||
delete keyboard;
|
||||
}
|
||||
|
||||
km_kbp_status
|
||||
km_kbp_keyboard_get_attrs(km_kbp_keyboard const *keyboard,
|
||||
km_kbp_keyboard_attrs const **out)
|
||||
km_core_status
|
||||
km_core_keyboard_get_attrs(km_core_keyboard const *keyboard,
|
||||
km_core_keyboard_attrs const **out)
|
||||
{
|
||||
assert(keyboard); assert(out);
|
||||
if (!keyboard || !out)
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
*out = &keyboard->keyboard();
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
km_kbp_status
|
||||
km_kbp_keyboard_get_key_list(km_kbp_keyboard const *keyboard,
|
||||
km_kbp_keyboard_key **out)
|
||||
km_core_status
|
||||
km_core_keyboard_get_key_list(km_core_keyboard const *keyboard,
|
||||
km_core_keyboard_key **out)
|
||||
{
|
||||
assert(keyboard); assert(out);
|
||||
if (!keyboard || !out)
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
*out = keyboard->get_key_list();
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
void km_kbp_keyboard_key_list_dispose(km_kbp_keyboard_key *key_list)
|
||||
void km_core_keyboard_key_list_dispose(km_core_keyboard_key *key_list)
|
||||
{
|
||||
delete[] key_list;
|
||||
}
|
||||
|
||||
km_kbp_status km_kbp_keyboard_get_imx_list(
|
||||
km_kbp_keyboard const *keyboard,
|
||||
km_kbp_keyboard_imx** imx_list
|
||||
km_core_status km_core_keyboard_get_imx_list(
|
||||
km_core_keyboard const *keyboard,
|
||||
km_core_keyboard_imx** imx_list
|
||||
) {
|
||||
assert(keyboard); assert(imx_list);
|
||||
if (!keyboard || !imx_list) {
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
*imx_list = keyboard->get_imx_list();
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
void km_kbp_keyboard_imx_list_dispose(km_kbp_keyboard_imx *imx_list)
|
||||
void km_core_keyboard_imx_list_dispose(km_core_keyboard_imx *imx_list)
|
||||
{
|
||||
if(!imx_list) {
|
||||
return;
|
||||
}
|
||||
|
||||
km_kbp_keyboard_imx *imx_rule_it = imx_list;
|
||||
km_core_keyboard_imx *imx_rule_it = imx_list;
|
||||
for (; imx_rule_it->library_name; ++imx_rule_it) {
|
||||
delete [] imx_rule_it->library_name; // from u16dup
|
||||
delete [] imx_rule_it->function_name; // from u16dup
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
||||
#include <keyman/keyboardprocessor.h>
|
||||
#include <keyman/keyman_core_api.h>
|
||||
#include "processor.hpp"
|
||||
|
||||
#include "jsonpp.hpp"
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
|
||||
size_t
|
||||
km_kbp_options_list_size(km_kbp_option_item const *opts)
|
||||
km_core_options_list_size(km_core_option_item const *opts)
|
||||
{
|
||||
assert(opts);
|
||||
if (!opts) return 0;
|
||||
|
|
@ -33,31 +33,31 @@ km_kbp_options_list_size(km_kbp_option_item const *opts)
|
|||
}
|
||||
|
||||
|
||||
km_kbp_status
|
||||
km_kbp_state_option_lookup(km_kbp_state const *state,
|
||||
uint8_t scope, km_kbp_cp const *key,
|
||||
km_kbp_cp const **value_out)
|
||||
km_core_status
|
||||
km_core_state_option_lookup(km_core_state const *state,
|
||||
uint8_t scope, km_core_cp const *key,
|
||||
km_core_cp const **value_out)
|
||||
{
|
||||
assert(state); assert(key); assert(value_out);
|
||||
if (!state || !key || !value_out) return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
if (!state || !key || !value_out) return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
if (scope == KM_KBP_OPT_UNKNOWN || scope > KM_KBP_OPT_MAX_SCOPES)
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
if (scope == KM_CORE_OPT_UNKNOWN || scope > KM_CORE_OPT_MAX_SCOPES)
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
auto & processor = state->processor();
|
||||
|
||||
*value_out = processor.lookup_option(km_kbp_option_scope(scope), key);
|
||||
if (!*value_out) return KM_KBP_STATUS_KEY_ERROR;
|
||||
*value_out = processor.lookup_option(km_core_option_scope(scope), key);
|
||||
if (!*value_out) return KM_CORE_STATUS_KEY_ERROR;
|
||||
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
km_kbp_status
|
||||
km_kbp_state_options_update(km_kbp_state *state, km_kbp_option_item const *opt)
|
||||
km_core_status
|
||||
km_core_state_options_update(km_core_state *state, km_core_option_item const *opt)
|
||||
{
|
||||
assert(state); assert(opt);
|
||||
if (!state|| !opt) return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
if (!state|| !opt) return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
auto & processor = state->processor();
|
||||
|
||||
|
|
@ -65,32 +65,32 @@ km_kbp_state_options_update(km_kbp_state *state, km_kbp_option_item const *opt)
|
|||
{
|
||||
for (;opt->key; ++opt)
|
||||
{
|
||||
if (opt->scope == KM_KBP_OPT_UNKNOWN || opt->scope > KM_KBP_OPT_MAX_SCOPES)
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
if (opt->scope == KM_CORE_OPT_UNKNOWN || opt->scope > KM_CORE_OPT_MAX_SCOPES)
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
if (processor.update_option(
|
||||
km_kbp_option_scope(opt->scope),
|
||||
km_core_option_scope(opt->scope),
|
||||
opt->key,
|
||||
opt->value).empty())
|
||||
return KM_KBP_STATUS_KEY_ERROR;
|
||||
return KM_CORE_STATUS_KEY_ERROR;
|
||||
}
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
return KM_KBP_STATUS_NO_MEM;
|
||||
return KM_CORE_STATUS_NO_MEM;
|
||||
}
|
||||
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
// This function doesn't need to use the json pretty printer for such a simple
|
||||
// list of key:value pairs but it's a good introduction to it.
|
||||
km_kbp_status
|
||||
km_kbp_state_options_to_json(km_kbp_state const *state, char *buf, size_t *space)
|
||||
km_core_status
|
||||
km_core_state_options_to_json(km_core_state const *state, char *buf, size_t *space)
|
||||
{
|
||||
assert(state); assert(space);
|
||||
if (!state || !space)
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
std::stringstream _buf;
|
||||
json jo(_buf);
|
||||
|
|
@ -103,7 +103,7 @@ km_kbp_state_options_to_json(km_kbp_state const *state, char *buf, size_t *space
|
|||
catch (std::bad_alloc &)
|
||||
{
|
||||
*space = 0;
|
||||
return KM_KBP_STATUS_NO_MEM;
|
||||
return KM_CORE_STATUS_NO_MEM;
|
||||
}
|
||||
|
||||
// Fetch the finished doc and copy it to the buffer if there enough space.
|
||||
|
|
@ -116,5 +116,5 @@ km_kbp_state_options_to_json(km_kbp_state const *state, char *buf, size_t *space
|
|||
|
||||
// Return space needed/used.
|
||||
*space = doc.size()+1;
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
|
@ -8,63 +8,63 @@
|
|||
History: 17 Oct 2018 - TSE - Initial implementation.
|
||||
*/
|
||||
|
||||
#include <keyman/keyboardprocessor.h>
|
||||
#include <keyman/keyman_core_api.h>
|
||||
#include "processor.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
km_kbp_status
|
||||
km_kbp_event(
|
||||
km_kbp_state *state,
|
||||
km_core_status
|
||||
km_core_event(
|
||||
km_core_state *state,
|
||||
uint32_t event,
|
||||
void* data
|
||||
) {
|
||||
assert(state != nullptr);
|
||||
if(state == nullptr) {
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
// event: KM_KBP_EVENT_KEYBOARD_ACTIVATED; data should be nullptr
|
||||
// future event: KM_KBP_EVENT_KEYBOARD_DEACTIVATED
|
||||
// event: KM_CORE_EVENT_KEYBOARD_ACTIVATED; data should be nullptr
|
||||
// future event: KM_CORE_EVENT_KEYBOARD_DEACTIVATED
|
||||
switch(event) {
|
||||
case KM_KBP_EVENT_KEYBOARD_ACTIVATED:
|
||||
case KM_CORE_EVENT_KEYBOARD_ACTIVATED:
|
||||
assert(data == nullptr);
|
||||
if(data != nullptr) {
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
return state->processor().external_event(state, event, data);
|
||||
}
|
||||
|
||||
km_kbp_status
|
||||
km_kbp_process_event(km_kbp_state *state,
|
||||
km_kbp_virtual_key vk,
|
||||
km_core_status
|
||||
km_core_process_event(km_core_state *state,
|
||||
km_core_virtual_key vk,
|
||||
uint16_t modifier_state,
|
||||
uint8_t is_key_down,
|
||||
uint16_t event_flags) {
|
||||
assert(state != nullptr);
|
||||
if(state == nullptr) {
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
return state->processor().process_event(state, vk, modifier_state, is_key_down, event_flags);
|
||||
}
|
||||
|
||||
km_kbp_status
|
||||
km_kbp_process_queued_actions(
|
||||
km_kbp_state *state
|
||||
km_core_status
|
||||
km_core_process_queued_actions(
|
||||
km_core_state *state
|
||||
) {
|
||||
assert(state != nullptr);
|
||||
if(state == nullptr) {
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
return state->processor().process_queued_actions(state);
|
||||
}
|
||||
|
||||
km_kbp_attr const *
|
||||
km_kbp_get_engine_attrs(km_kbp_state const *state)
|
||||
km_core_attr const *
|
||||
km_core_get_engine_attrs(km_core_state const *state)
|
||||
{
|
||||
assert(state != nullptr);
|
||||
if(state == nullptr) {
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
#include <keyman/keyboardprocessor.h>
|
||||
#include <keyman/keyman_core_api.h>
|
||||
#include "jsonpp.hpp"
|
||||
|
||||
#include "processor.hpp"
|
||||
|
|
@ -23,68 +23,68 @@ using namespace km::kbp;
|
|||
// Forward declarations
|
||||
class context;
|
||||
|
||||
km_kbp_status km_kbp_state_create(km_kbp_keyboard * keyboard,
|
||||
km_kbp_option_item const *env,
|
||||
km_kbp_state ** out)
|
||||
km_core_status km_core_state_create(km_core_keyboard * keyboard,
|
||||
km_core_option_item const *env,
|
||||
km_core_state ** out)
|
||||
{
|
||||
assert(keyboard); assert(env); assert(out);
|
||||
if (!keyboard || !env || !out)
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
try
|
||||
{
|
||||
*out = new km_kbp_state(static_cast<abstract_processor&>(*keyboard), env);
|
||||
*out = new km_core_state(static_cast<abstract_processor&>(*keyboard), env);
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
return KM_KBP_STATUS_NO_MEM;
|
||||
return KM_CORE_STATUS_NO_MEM;
|
||||
}
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
km_kbp_status km_kbp_state_clone(km_kbp_state const *state,
|
||||
km_kbp_state ** out)
|
||||
km_core_status km_core_state_clone(km_core_state const *state,
|
||||
km_core_state ** out)
|
||||
{
|
||||
assert(state); assert(out);
|
||||
if (!state || !out)
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
*out = new km_kbp_state(*state);
|
||||
return KM_KBP_STATUS_OK;
|
||||
*out = new km_core_state(*state);
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
void km_kbp_state_dispose(km_kbp_state *state)
|
||||
void km_core_state_dispose(km_core_state *state)
|
||||
{
|
||||
delete state;
|
||||
}
|
||||
|
||||
|
||||
km_kbp_context *km_kbp_state_context(km_kbp_state *state)
|
||||
km_core_context *km_core_state_context(km_core_state *state)
|
||||
{
|
||||
assert(state);
|
||||
if (!state) return nullptr;
|
||||
|
||||
return static_cast<km_kbp_context *>(&state->context());
|
||||
return static_cast<km_core_context *>(&state->context());
|
||||
}
|
||||
|
||||
km_kbp_status kbp_state_get_intermediate_context(
|
||||
km_kbp_state *state,
|
||||
km_kbp_context_item ** context_items
|
||||
km_core_status kbp_state_get_intermediate_context(
|
||||
km_core_state *state,
|
||||
km_core_context_item ** context_items
|
||||
) {
|
||||
assert(state);
|
||||
assert(context_items);
|
||||
if (!state || !context_items) {
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
auto & processor = state->processor();
|
||||
*context_items = processor.get_intermediate_context();
|
||||
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
km_kbp_action_item const * km_kbp_state_action_items(km_kbp_state const *state,
|
||||
km_core_action_item const * km_core_state_action_items(km_core_state const *state,
|
||||
size_t *num_items)
|
||||
{
|
||||
assert(state && state->actions().size() > 0);
|
||||
|
|
@ -95,33 +95,33 @@ km_kbp_action_item const * km_kbp_state_action_items(km_kbp_state const *state,
|
|||
|
||||
// Process events will ensure that the actions vector is always well
|
||||
// teminated
|
||||
assert(state->actions().back().type == KM_KBP_IT_END);
|
||||
assert(state->actions().back().type == KM_CORE_IT_END);
|
||||
return state->actions().data();
|
||||
}
|
||||
|
||||
km_kbp_status km_kbp_state_queue_action_items(
|
||||
km_kbp_state *state,
|
||||
km_kbp_action_item const *action_items
|
||||
km_core_status km_core_state_queue_action_items(
|
||||
km_core_state *state,
|
||||
km_core_action_item const *action_items
|
||||
) {
|
||||
assert(state);
|
||||
assert(action_items);
|
||||
if (!state|| !action_items) {
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
auto & processor = state->processor();
|
||||
|
||||
for (; action_items->type != KM_KBP_IT_END; ++action_items) {
|
||||
if (action_items->type >= KM_KBP_IT_MAX_TYPE_ID) {
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
for (; action_items->type != KM_CORE_IT_END; ++action_items) {
|
||||
if (action_items->type >= KM_CORE_IT_MAX_TYPE_ID) {
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!processor.queue_action(state, action_items)) {
|
||||
return KM_KBP_STATUS_KEY_ERROR;
|
||||
return KM_CORE_STATUS_KEY_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
namespace {
|
||||
char const * action_item_name_lut[] = {
|
||||
|
|
@ -146,10 +146,10 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
json & operator << (json & j, km_kbp_action_item const &act)
|
||||
json & operator << (json & j, km_core_action_item const &act)
|
||||
{
|
||||
j << json::flat << json::object;
|
||||
if (act.type >= KM_KBP_IT_MAX_TYPE_ID)
|
||||
if (act.type >= KM_CORE_IT_MAX_TYPE_ID)
|
||||
{
|
||||
j << "invalid" << json::null << json::close;
|
||||
return j;
|
||||
|
|
@ -158,16 +158,16 @@ json & operator << (json & j, km_kbp_action_item const &act)
|
|||
j << action_item_name_lut[act.type];
|
||||
switch (act.type)
|
||||
{
|
||||
case KM_KBP_IT_END:
|
||||
case KM_KBP_IT_ALERT:
|
||||
case KM_KBP_IT_BACK:
|
||||
case KM_CORE_IT_END:
|
||||
case KM_CORE_IT_ALERT:
|
||||
case KM_CORE_IT_BACK:
|
||||
j << json::null;
|
||||
break;
|
||||
case KM_KBP_IT_CHAR:
|
||||
case KM_KBP_IT_MARKER:
|
||||
j << km_kbp_context_item {act.type, {0,}, {act.character}}; // TODO: is act.type correct here? it may map okay but this is bad practice to mix constants across types. Similarly using act.character instead of act.type
|
||||
case KM_CORE_IT_CHAR:
|
||||
case KM_CORE_IT_MARKER:
|
||||
j << km_core_context_item {act.type, {0,}, {act.character}}; // TODO: is act.type correct here? it may map okay but this is bad practice to mix constants across types. Similarly using act.character instead of act.type
|
||||
break;
|
||||
case KM_KBP_IT_PERSIST_OPT:
|
||||
case KM_CORE_IT_PERSIST_OPT:
|
||||
j << json::object
|
||||
<< scope_names_lut[act.option->scope]
|
||||
<< json::flat << json::object
|
||||
|
|
@ -187,7 +187,7 @@ json & operator << (json & j, actions const & acts)
|
|||
j << json::array;
|
||||
for (auto & act: acts)
|
||||
{
|
||||
if (act.type != KM_KBP_IT_END)
|
||||
if (act.type != KM_CORE_IT_END)
|
||||
{
|
||||
j << act;
|
||||
}
|
||||
|
|
@ -197,13 +197,13 @@ json & operator << (json & j, actions const & acts)
|
|||
}
|
||||
|
||||
|
||||
km_kbp_status km_kbp_state_to_json(km_kbp_state const *state,
|
||||
km_core_status km_core_state_to_json(km_core_state const *state,
|
||||
char *buf,
|
||||
size_t *space)
|
||||
{
|
||||
assert(state);
|
||||
if (!state)
|
||||
return KM_KBP_STATUS_INVALID_ARGUMENT;
|
||||
return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
||||
std::stringstream _buf;
|
||||
json jo(_buf);
|
||||
|
|
@ -212,7 +212,7 @@ km_kbp_status km_kbp_state_to_json(km_kbp_state const *state,
|
|||
{
|
||||
// Pretty print the document.
|
||||
jo << json::object
|
||||
<< "$schema" << "keyman/keyboardprocessor/doc/introspection.schema"
|
||||
<< "$schema" << "keyman/core/doc/introspection.schema"
|
||||
<< "keyboard" << state->processor().keyboard()
|
||||
// << "options" << state->options() TODO: Fix
|
||||
<< "context" << state->context()
|
||||
|
|
@ -222,7 +222,7 @@ km_kbp_status km_kbp_state_to_json(km_kbp_state const *state,
|
|||
catch (std::bad_alloc &)
|
||||
{
|
||||
*space = 0;
|
||||
return KM_KBP_STATUS_NO_MEM;
|
||||
return KM_CORE_STATUS_NO_MEM;
|
||||
}
|
||||
|
||||
// Fetch the finished doc and copy it to the buffer if there enough space.
|
||||
|
|
@ -235,13 +235,13 @@ km_kbp_status km_kbp_state_to_json(km_kbp_state const *state,
|
|||
|
||||
// Return space needed/used.
|
||||
*space = doc.size()+1;
|
||||
return KM_KBP_STATUS_OK;
|
||||
return KM_CORE_STATUS_OK;
|
||||
|
||||
}
|
||||
|
||||
void km_kbp_state_imx_register_callback(
|
||||
km_kbp_state *state,
|
||||
km_kbp_keyboard_imx_platform imx_callback,
|
||||
void km_core_state_imx_register_callback(
|
||||
km_core_state *state,
|
||||
km_core_keyboard_imx_platform imx_callback,
|
||||
void *callback_object
|
||||
) {
|
||||
assert(state);
|
||||
|
|
@ -251,7 +251,7 @@ void km_kbp_state_imx_register_callback(
|
|||
state->imx_register_callback(imx_callback, callback_object);
|
||||
}
|
||||
|
||||
void km_kbp_state_imx_deregister_callback(km_kbp_state *state)
|
||||
void km_core_state_imx_deregister_callback(km_core_state *state)
|
||||
{
|
||||
assert(state);
|
||||
if (!state) {
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <keyman/keyboardprocessor_bits.h>
|
||||
#include <keyman/keyboardprocessor.h>
|
||||
#include <keyman/keyman_core_api_bits.h>
|
||||
#include <keyman/keyman_core_api.h>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define snprintf _snprintf
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Copyright: Copyright (C) 2003-2018 SIL International.
|
||||
Authors: mcdurdin
|
||||
*/
|
||||
#include <keyman/keyboardprocessor_consts.h>
|
||||
#include <keyman/keyman_core_api_consts.h>
|
||||
#include <kmx/kmx_processevent.h>
|
||||
|
||||
using namespace km::kbp;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue