mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-23 16:17:40 +00:00
chore(developer): Merge branch 'master' into test/developer/kmcmplib-compiler-unit-tests
This commit is contained in:
commit
810c9720d3
98 changed files with 740 additions and 440 deletions
49
HISTORY.md
49
HISTORY.md
|
|
@ -1,5 +1,28 @@
|
|||
# Keyman Version History
|
||||
|
||||
## 18.0.33 alpha 2024-05-10
|
||||
|
||||
* chore(common): Merge beta to master for Sprint A18S1 (part 2) (#11413)
|
||||
|
||||
## 18.0.32 alpha 2024-05-09
|
||||
|
||||
* chore(common): Add `minimum-versions.inc.sh` (#11380)
|
||||
* chore(core): km_core_cp -> km_core_cu (#11341)
|
||||
|
||||
## 18.0.31 alpha 2024-05-08
|
||||
|
||||
* fix(windows): "Keyboard" should be lower case in UI string for font helper tool (#11392)
|
||||
|
||||
## 18.0.30 alpha 2024-05-07
|
||||
|
||||
* chore(web): Improve dependencies (#11377)
|
||||
* test(developer) keyboard info compiler unit tests 3 (#11255)
|
||||
|
||||
## 18.0.29 alpha 2024-05-06
|
||||
|
||||
* chore(web): Improve web/test.sh script (#11355)
|
||||
* chore(linux): Fix typo (#11356)
|
||||
|
||||
## 18.0.28 alpha 2024-05-04
|
||||
|
||||
* chore(common): maintenance on build scripts - cd (#11329)
|
||||
|
|
@ -121,6 +144,32 @@
|
|||
* chore(common): move to 18.0 alpha (#10713)
|
||||
* chore: move to 18.0 alpha
|
||||
|
||||
## 17.0.322 beta 2024-05-10
|
||||
|
||||
* fix(web): fixes illegal KMW event state - can't focus a null element (#11385)
|
||||
|
||||
## 17.0.321 beta 2024-05-09
|
||||
|
||||
* fix(android/engine): Skip updating selection range if invalid (#11384)
|
||||
* refactor(android/engine): Refactor updateSelection (#11389)
|
||||
|
||||
## 17.0.320 beta 2024-05-07
|
||||
|
||||
* fix(android): prevents mid-keystroke desynchronization when deleting selected text (#11367)
|
||||
* fix(web): support SVG elements when checking className (#11365)
|
||||
* fix(developer): define `lastSelLength` variable (#11366)
|
||||
|
||||
## 17.0.319 beta 2024-05-04
|
||||
|
||||
* fix(android): inverting a selection range would crash Keyman (#11345)
|
||||
* fix(developer): handle missing Name element for File element in package compiler (#11352)
|
||||
* fix(developer): handle missing Description element for File element in package compiler (#11354)
|
||||
|
||||
## 17.0.318 beta 2024-05-02
|
||||
|
||||
* fix(web): longpress shortcut activation should only consider northward part (#11306)
|
||||
* chore(ios,mac): support build on Apple Silicon using Xcode 15.3 (#11302)
|
||||
|
||||
## 17.0.317 beta 2024-05-01
|
||||
|
||||
* (#11322)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
18.0.29
|
||||
18.0.34
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
|
|||
if (DependencyUtil.libraryExists(LibraryType.SENTRY) && !Sentry.isEnabled()) {
|
||||
Log.d(TAG, "Initializing Sentry");
|
||||
SentryAndroid.init(getApplicationContext(), options -> {
|
||||
options.setEnableAutoSessionTracking(false);
|
||||
options.setRelease(com.tavultesoft.kmapro.BuildConfig.VERSION_GIT_TAG);
|
||||
options.setEnvironment(com.tavultesoft.kmapro.BuildConfig.VERSION_ENVIRONMENT);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
|
|||
checkSendCrashReport();
|
||||
if (KMManager.getMaySendCrashReport()) {
|
||||
SentryAndroid.init(context, options -> {
|
||||
options.setEnableAutoSessionTracking(false);
|
||||
options.setRelease(com.tavultesoft.kmapro.BuildConfig.VERSION_GIT_TAG);
|
||||
options.setEnvironment(com.tavultesoft.kmapro.BuildConfig.VERSION_ENVIRONMENT);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -170,51 +170,63 @@ final class KMKeyboard extends WebView {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the selection range of the current context.
|
||||
* Returns boolean - true if the selection range was updated successfully
|
||||
*/
|
||||
protected boolean updateSelectionRange() {
|
||||
boolean result = false;
|
||||
|
||||
InputConnection ic = KMManager.getInputConnection(this.keyboardType);
|
||||
if (ic != null) {
|
||||
ExtractedText icText = ic.getExtractedText(new ExtractedTextRequest(), 0);
|
||||
if (icText == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String rawText = icText.text.toString();
|
||||
updateText(rawText.toString());
|
||||
|
||||
int selStart = icText.selectionStart;
|
||||
int selEnd = icText.selectionEnd;
|
||||
|
||||
int selMin = selStart, selMax = selEnd;
|
||||
if (selStart > selEnd) {
|
||||
// Selection is reversed so "swap"
|
||||
selMin = selEnd;
|
||||
selMax = selStart;
|
||||
}
|
||||
|
||||
/*
|
||||
The values of selStart & selEnd provided by the system are in code units,
|
||||
not code-points. We need to account for surrogate pairs here.
|
||||
|
||||
Fortunately, it uses UCS-2 encoding... just like JS.
|
||||
|
||||
References:
|
||||
- https://stackoverflow.com/a/23980211
|
||||
- https://android.googlesource.com/platform/frameworks/base/+/152944f/core/java/android/view/inputmethod/InputConnection.java#326
|
||||
*/
|
||||
|
||||
// Count the number of characters which are surrogate pairs.
|
||||
int pairsAtStart = CharSequenceUtil.countSurrogatePairs(rawText.substring(0, selStart), rawText.length());
|
||||
String selectedText = rawText.substring(selStart, selEnd);
|
||||
int pairsSelected = CharSequenceUtil.countSurrogatePairs(selectedText, selectedText.length());
|
||||
|
||||
selStart -= pairsAtStart;
|
||||
selEnd -= (pairsAtStart + pairsSelected);
|
||||
this.loadJavascript(KMString.format("updateKMSelectionRange(%d,%d)", selStart, selEnd));
|
||||
if (ic == null) {
|
||||
// Unable to get connection to the text
|
||||
return false;
|
||||
}
|
||||
result = true;
|
||||
|
||||
return result;
|
||||
ExtractedText icText = ic.getExtractedText(new ExtractedTextRequest(), 0);
|
||||
if (icText == null) {
|
||||
// Failed to get text becausee either input connection became invalid or client is taking too long to respond
|
||||
// https://developer.android.com/reference/android/view/inputmethod/InputConnection#getExtractedText(android.view.inputmethod.ExtractedTextRequest,%20int)
|
||||
return false;
|
||||
}
|
||||
|
||||
String rawText = icText.text.toString();
|
||||
updateText(rawText.toString());
|
||||
|
||||
int selMin = icText.selectionStart, selMax = icText.selectionEnd;
|
||||
|
||||
if (selMin < 0 || selMax < 0) {
|
||||
// There is no selection or cursor
|
||||
// Reference https://developer.android.com/reference/android/text/Selection#getSelectionEnd(java.lang.CharSequence)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (selMin > selMax) {
|
||||
// Selection is reversed so "swap"
|
||||
selMin = icText.selectionEnd;
|
||||
selMax = icText.selectionStart;
|
||||
}
|
||||
|
||||
/*
|
||||
The values of selStart & selEnd provided by the system are in code units,
|
||||
not code-points. We need to account for surrogate pairs here.
|
||||
|
||||
Fortunately, it uses UCS-2 encoding... just like JS.
|
||||
|
||||
References:
|
||||
- https://stackoverflow.com/a/23980211
|
||||
- https://android.googlesource.com/platform/frameworks/base/+/152944f/core/java/android/view/inputmethod/InputConnection.java#326
|
||||
*/
|
||||
|
||||
// Count the number of characters which are surrogate pairs.
|
||||
int pairsAtStart = CharSequenceUtil.countSurrogatePairs(rawText.substring(0, selMin), rawText.length());
|
||||
String selectedText = rawText.substring(selMin, selMax);
|
||||
int pairsSelected = CharSequenceUtil.countSurrogatePairs(selectedText, selectedText.length());
|
||||
|
||||
selMin -= pairsAtStart;
|
||||
selMax -= (pairsAtStart + pairsSelected);
|
||||
this.loadJavascript(KMString.format("updateKMSelectionRange(%d,%d)", selMin, selMax));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -135,13 +135,13 @@ public class KMKeyboardJSHandler {
|
|||
end = temp;
|
||||
}
|
||||
if (end > start) {
|
||||
k.setShouldIgnoreSelectionChange(true);
|
||||
if (s.length() == 0) {
|
||||
ic.setSelection(start, start);
|
||||
ic.deleteSurroundingText(0, end - start);
|
||||
ic.endBatchEdit();
|
||||
return;
|
||||
} else {
|
||||
k.setShouldIgnoreSelectionChange(true);
|
||||
ic.setSelection(start, start);
|
||||
ic.deleteSurroundingText(0, end - start);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@ typedef uint8_t KMX_BYTE;
|
|||
typedef uint16_t KMX_WORD;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
typedef char16_t km_core_cp;
|
||||
typedef char16_t km_core_cu;
|
||||
typedef char32_t km_core_usv;
|
||||
#else
|
||||
typedef uint16_t km_core_cp; // code point
|
||||
typedef uint16_t km_core_cu; // code unit
|
||||
typedef uint32_t km_core_usv; // Unicode Scalar Value
|
||||
#endif
|
||||
|
||||
typedef km_core_cp KMX_WCHAR; // wc, 16-bit UNICODE character
|
||||
typedef km_core_cu 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_core_cp KMX_UCHAR;
|
||||
typedef km_core_cu KMX_UCHAR;
|
||||
#else
|
||||
#define lpuch(x) L ## x
|
||||
typedef wchar_t KMX_UCHAR;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
|||
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
|
||||
|
||||
builder_describe "Build Keyman common file types module" \
|
||||
"@/core/include/ldml" \
|
||||
"@/common/web/keyman-version" \
|
||||
"configure" \
|
||||
"build" \
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
"url": "https://github.com/keymanapp/keyman/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"@keymanapp/ldml-keyboard-constants": "*",
|
||||
"@keymanapp/keyman-version": "*",
|
||||
"restructure": "git+https://github.com/keymanapp/dependency-restructure.git#7a188a1e26f8f36a175d95b67ffece8702363dfc",
|
||||
"semver": "^7.5.2",
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
1.0.0
|
||||
2.0.0
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ interface.
|
|||
|
||||
Fundamental types for representing data passed across the API.
|
||||
|
||||
### km_core_cp type
|
||||
### km_core_cu type
|
||||
|
||||
`uint16_t/char16_t`
|
||||
|
||||
|
|
@ -683,7 +683,7 @@ KMN_API
|
|||
km_core_context_status
|
||||
km_core_state_context_set_if_needed(
|
||||
km_core_state *state,
|
||||
km_core_cp const *application_context
|
||||
km_core_cu const *application_context
|
||||
);
|
||||
|
||||
/*
|
||||
|
|
@ -800,8 +800,8 @@ Platform layer.
|
|||
## Specification
|
||||
```c */
|
||||
struct km_core_option_item {
|
||||
km_core_cp const * key;
|
||||
km_core_cp const * value;
|
||||
km_core_cu const * key;
|
||||
km_core_cu const * value;
|
||||
uint8_t scope;
|
||||
};
|
||||
|
||||
|
|
@ -860,8 +860,8 @@ KMN_API
|
|||
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);
|
||||
km_core_cu const *key,
|
||||
km_core_cu const **value);
|
||||
|
||||
/*
|
||||
```
|
||||
|
|
@ -1005,8 +1005,8 @@ Provides read-only information about a keyboard.
|
|||
```c
|
||||
*/
|
||||
typedef struct {
|
||||
km_core_cp const * version_string;
|
||||
km_core_cp const * id;
|
||||
km_core_cu const * version_string;
|
||||
km_core_cu const * id;
|
||||
km_core_path_name folder_path;
|
||||
km_core_option_item const * default_options;
|
||||
} km_core_keyboard_attrs;
|
||||
|
|
@ -1070,8 +1070,8 @@ Describes a single Input Method eXtension library and entry point.
|
|||
|
||||
```c */
|
||||
typedef struct {
|
||||
km_core_cp const * library_name;
|
||||
km_core_cp const * function_name;
|
||||
km_core_cu const * library_name;
|
||||
km_core_cu const * function_name;
|
||||
uint32_t imx_id;
|
||||
} km_core_keyboard_imx;
|
||||
|
||||
|
|
@ -1332,7 +1332,7 @@ void km_core_state_imx_register_callback(km_core_state *state, km_core_keyboard_
|
|||
: pointer to a function that implements the IMX callback
|
||||
|
||||
`callback_object`
|
||||
: An opaque pointer that can be used to pass context information to the callback function,
|
||||
: An opaque pointer that can be used to pass context information to the callback function,
|
||||
usually it is a user-defined data structure.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
|
@ -1523,7 +1523,7 @@ Returns a debug formatted string of the context from the state.
|
|||
|
||||
```c */
|
||||
KMN_API
|
||||
km_core_cp *
|
||||
km_core_cu *
|
||||
km_core_state_context_debug(km_core_state *state, km_core_debug_context_type context_type);
|
||||
|
||||
/*
|
||||
|
|
@ -1538,16 +1538,16 @@ km_core_state_context_debug(km_core_state *state, km_core_debug_context_type con
|
|||
|
||||
## Returns
|
||||
|
||||
A pointer to a [km_core_cp] UTF-16 string. Must be disposed of by a call
|
||||
to [km_core_cp_dispose].
|
||||
A pointer to a [km_core_cu] UTF-16 string. Must be disposed of by a call
|
||||
to [km_core_cu_dispose].
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
# km_core_cp_dispose()
|
||||
# km_core_cu_dispose()
|
||||
|
||||
## Description
|
||||
|
||||
Free the allocated memory belonging to a [km_core_cp] array previously
|
||||
Free the allocated memory belonging to a [km_core_cu] array previously
|
||||
returned by [km_core_state_context_debug]. May be `nullptr`.
|
||||
|
||||
## Specification
|
||||
|
|
@ -1555,14 +1555,14 @@ returned by [km_core_state_context_debug]. May be `nullptr`.
|
|||
```c */
|
||||
KMN_API
|
||||
void
|
||||
km_core_cp_dispose(km_core_cp *cp);
|
||||
km_core_cu_dispose(km_core_cu *cp);
|
||||
|
||||
/*
|
||||
```
|
||||
## Parameters
|
||||
|
||||
`cp`
|
||||
: A pointer to the start of the [km_core_cp] array to be disposed of.
|
||||
: A pointer to the start of the [km_core_cu] array to be disposed of.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ extern "C"
|
|||
#endif
|
||||
|
||||
/**
|
||||
* The maximum size of context in km_core_cp units for a single debug
|
||||
* The maximum size of context in km_core_cu 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.
|
||||
*/
|
||||
|
|
@ -65,7 +65,7 @@ typedef struct {
|
|||
*/
|
||||
typedef struct {
|
||||
void *store; // LPSTORE
|
||||
km_core_cp value[DEBUG_MAX_CONTEXT]; // value to be saved into the store
|
||||
km_core_cu value[DEBUG_MAX_CONTEXT]; // value to be saved into the store
|
||||
} km_core_state_debug_kmx_option_info;
|
||||
|
||||
/**
|
||||
|
|
@ -80,7 +80,7 @@ typedef struct {
|
|||
*/
|
||||
|
||||
typedef struct {
|
||||
km_core_cp context[DEBUG_MAX_CONTEXT]; // The context matched by the rule (? may not need this?) // TODO: rename to context_matched
|
||||
km_core_cu 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
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ void context::push_marker(uint32_t marker) {
|
|||
|
||||
// Context helper functions
|
||||
|
||||
km_core_cp* get_context_as_string(km_core_context *context);
|
||||
km_core_status set_context_from_string(km_core_context *context, km_core_cp const *new_context);
|
||||
km_core_cu* get_context_as_string(km_core_context *context);
|
||||
km_core_status set_context_from_string(km_core_context *context, km_core_cu const *new_context);
|
||||
|
||||
} // namespace core
|
||||
} // namespace km
|
||||
|
|
@ -84,7 +84,7 @@ struct km_core_context : public km::core::context
|
|||
* `km_core_context_items_dispose`.
|
||||
*/
|
||||
km_core_status
|
||||
context_items_from_utf16(km_core_cp const *text,
|
||||
context_items_from_utf16(km_core_cu const *text,
|
||||
km_core_context_item **out_ptr);
|
||||
|
||||
/**
|
||||
|
|
@ -113,7 +113,7 @@ context_items_from_utf16(km_core_cp const *text,
|
|||
*/
|
||||
km_core_status
|
||||
context_items_to_utf16(km_core_context_item const *item,
|
||||
km_core_cp *buf,
|
||||
km_core_cu *buf,
|
||||
size_t *buf_size);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@
|
|||
using namespace km::core;
|
||||
|
||||
/**
|
||||
* Retrieves the context as a km_core_cp string, dropping markers
|
||||
* Retrieves the context as a km_core_cu string, dropping markers
|
||||
*/
|
||||
km_core_cp* km::core::get_context_as_string(km_core_context *context) {
|
||||
km_core_cu* km::core::get_context_as_string(km_core_context *context) {
|
||||
assert(context != nullptr);
|
||||
if(context == nullptr) {
|
||||
return nullptr;
|
||||
|
|
@ -33,7 +33,7 @@ km_core_cp* km::core::get_context_as_string(km_core_context *context) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
km_core_cp *app_context_string = new km_core_cp[buf_size];
|
||||
km_core_cu *app_context_string = new km_core_cu[buf_size];
|
||||
|
||||
km_core_status status = context_items_to_utf16(context_items, app_context_string, &buf_size);
|
||||
km_core_context_items_dispose(context_items);
|
||||
|
|
@ -46,9 +46,9 @@ km_core_cp* km::core::get_context_as_string(km_core_context *context) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Updates the context from the new_context km_core_cp string
|
||||
* Updates the context from the new_context km_core_cu string
|
||||
*/
|
||||
km_core_status km::core::set_context_from_string(km_core_context *context, km_core_cp const *new_context) {
|
||||
km_core_status km::core::set_context_from_string(km_core_context *context, km_core_cu const *new_context) {
|
||||
assert(context != nullptr);
|
||||
assert(new_context != nullptr);
|
||||
if(context == nullptr || new_context == nullptr) {
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ namespace {
|
|||
}
|
||||
|
||||
km_core_status
|
||||
context_items_from_utf16(km_core_cp const *text,
|
||||
context_items_from_utf16(km_core_cu const *text,
|
||||
km_core_context_item **out_ptr)
|
||||
{
|
||||
return _context_items_from<utf16>(reinterpret_cast<utf16::codeunit_t const *>(text), out_ptr);
|
||||
|
|
@ -125,7 +125,7 @@ km_core_status context_items_to_utf8(km_core_context_item const *ci,
|
|||
|
||||
|
||||
km_core_status context_items_to_utf16(km_core_context_item const *ci,
|
||||
km_core_cp *buf, size_t * sz_ptr)
|
||||
km_core_cu *buf, size_t * sz_ptr)
|
||||
{
|
||||
return _context_items_to<utf16>(ci,
|
||||
reinterpret_cast<utf16::codeunit_t *>(buf),
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ km_core_options_list_size(km_core_option_item const *opts)
|
|||
|
||||
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)
|
||||
uint8_t scope, km_core_cu const *key,
|
||||
km_core_cu const **value_out)
|
||||
{
|
||||
assert(state); assert(key); assert(value_out);
|
||||
if (!state || !key || !value_out) return KM_CORE_STATUS_INVALID_ARGUMENT;
|
||||
|
|
|
|||
|
|
@ -285,22 +285,22 @@ km_core_status km_core_state_context_clear(
|
|||
return KM_CORE_STATUS_OK;
|
||||
}
|
||||
|
||||
void km_core_cp_dispose(
|
||||
km_core_cp *cp
|
||||
void km_core_cu_dispose(
|
||||
km_core_cu *cp
|
||||
) {
|
||||
if(cp != nullptr) {
|
||||
delete [] cp;
|
||||
}
|
||||
}
|
||||
|
||||
km_core_cp * _new_error_string(std::u16string const str) {
|
||||
km_core_cp* result = new km_core_cp[str.size()+1];
|
||||
km_core_cu * _new_error_string(std::u16string const str) {
|
||||
km_core_cu* result = new km_core_cu[str.size()+1];
|
||||
str.copy(result, str.size());
|
||||
result[str.size()] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
km_core_cp * km_core_state_context_debug(
|
||||
km_core_cu * km_core_state_context_debug(
|
||||
km_core_state *state,
|
||||
km_core_debug_context_type context_type
|
||||
) {
|
||||
|
|
@ -359,7 +359,7 @@ km_core_cp * km_core_state_context_debug(
|
|||
|
||||
std::u16string s = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(buffer.str());
|
||||
|
||||
km_core_cp* result = new km_core_cp[s.size() + 1];
|
||||
km_core_cu* result = new km_core_cu[s.size() + 1];
|
||||
s.copy(result, s.size());
|
||||
result[s.size()] = 0;
|
||||
|
||||
|
|
@ -385,11 +385,11 @@ state_should_invalidate_context(km_core_state *state,
|
|||
// if emit_keystroke is present, check if a context reset is needed
|
||||
if (state_has_action_type(state, KM_CORE_IT_EMIT_KEYSTROKE)) {
|
||||
if (
|
||||
// when a backspace keystroke is emitted, it is because we are at the start of
|
||||
// context, and we want to give the application the chance to process it, e.g.
|
||||
// by moving to previous field. Note that context manipulation does not result
|
||||
// in an emit_keystroke backspace action, as this is handled through the
|
||||
// `code_points_to_delete` field. So we always invalidate context when a
|
||||
// when a backspace keystroke is emitted, it is because we are at the start of
|
||||
// context, and we want to give the application the chance to process it, e.g.
|
||||
// by moving to previous field. Note that context manipulation does not result
|
||||
// in an emit_keystroke backspace action, as this is handled through the
|
||||
// `code_points_to_delete` field. So we always invalidate context when a
|
||||
// processor emits a backspace.
|
||||
vk == KM_CORE_VKEY_BKSP ||
|
||||
// certain modifiers invalidate context
|
||||
|
|
|
|||
|
|
@ -39,12 +39,12 @@ typedef struct {
|
|||
|
||||
// Forward declarations
|
||||
|
||||
bool replace_context(context_change_result context_change, km_core_context *context, km_core_cp const *new_context);
|
||||
bool replace_context(context_change_result context_change, km_core_context *context, km_core_cu const *new_context);
|
||||
bool should_normalize(km_core_state *state);
|
||||
context_change_result get_context_change(km_core_cp const *new_context, km_core_context *context);
|
||||
context_change_result get_context_change(km_core_cu const *new_context, km_core_context *context);
|
||||
context_change_result get_context_items_change(km_core_context_item *new_context_items, km_core_context_item *context_items);
|
||||
|
||||
bool do_normalize_nfd(km_core_cp const * src, std::u16string &dst);
|
||||
bool do_normalize_nfd(km_core_cu const * src, std::u16string &dst);
|
||||
km_core_context_status do_fail(km_core_context *app_context, km_core_context *cached_context, const char* error);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -52,7 +52,7 @@ km_core_context_status do_fail(km_core_context *app_context, km_core_context *ca
|
|||
km_core_context_status
|
||||
km_core_state_context_set_if_needed(
|
||||
km_core_state *state,
|
||||
km_core_cp const *new_app_context
|
||||
km_core_cu const *new_app_context
|
||||
) {
|
||||
assert(state != nullptr);
|
||||
assert(new_app_context != nullptr);
|
||||
|
|
@ -91,7 +91,7 @@ km_core_state_context_set_if_needed(
|
|||
// Finally, we normalize and replace the cached context
|
||||
|
||||
std::u16string normalized_buffer;
|
||||
km_core_cp const *new_cached_context = nullptr;
|
||||
km_core_cu const *new_cached_context = nullptr;
|
||||
|
||||
if (should_normalize(state)) {
|
||||
if (!do_normalize_nfd(new_app_context, normalized_buffer)) {
|
||||
|
|
@ -128,7 +128,7 @@ bool
|
|||
replace_context(
|
||||
context_change_result context_change,
|
||||
km_core_context *context,
|
||||
km_core_cp const *new_context
|
||||
km_core_cu const *new_context
|
||||
) {
|
||||
if (context_change.type == CONTEXT_DIFFERENT) {
|
||||
if (set_context_from_string(context, new_context) != KM_CORE_STATUS_OK) {
|
||||
|
|
@ -189,7 +189,7 @@ context_previous_char(
|
|||
*/
|
||||
context_change_result
|
||||
get_context_change(
|
||||
km_core_cp const *new_context_string,
|
||||
km_core_cu const *new_context_string,
|
||||
km_core_context *context
|
||||
) {
|
||||
context_change_result change_type({CONTEXT_DIFFERENT, 0});
|
||||
|
|
@ -286,7 +286,7 @@ get_context_items_change(
|
|||
/**
|
||||
* Normalize the input string using ICU
|
||||
*/
|
||||
bool do_normalize_nfd(km_core_cp const * src, std::u16string &dst) {
|
||||
bool do_normalize_nfd(km_core_cu const * src, std::u16string &dst) {
|
||||
UErrorCode icu_status = U_ZERO_ERROR;
|
||||
const icu::Normalizer2 *nfd = icu::Normalizer2::getNFDInstance(icu_status);
|
||||
assert(U_SUCCESS(icu_status));
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ void KMX_DebugItems::fill_store_offsets(km_core_state_debug_kmx_info *info, PKMX
|
|||
|
||||
int i, n;
|
||||
|
||||
km_core_cp *p;
|
||||
km_core_cu *p;
|
||||
|
||||
// TODO turn this into a struct rather than interwoven values
|
||||
for(i = n = 0, p = static_cast<LPKEY>(info->rule)->dpContext; p && *p; p = incxstr(p), i++) {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ using namespace km::core;
|
|||
using namespace kmx;
|
||||
|
||||
namespace {
|
||||
km_core_cp const
|
||||
km_core_cu const
|
||||
*DEFAULT_PLATFORM = u"windows hardware desktop native",
|
||||
*DEFAULT_BASELAYOUT = u"kbdus.dll",
|
||||
*DEFAULT_BASELAYOUTALT = u"en-US",
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ private:
|
|||
std::u16string _platform;
|
||||
void InitOption(
|
||||
std::vector<option> & default_env,
|
||||
km_core_cp const * key,
|
||||
km_core_cp const * default_value);
|
||||
km_core_cu const * key,
|
||||
km_core_cu const * default_value);
|
||||
public:
|
||||
KMX_Environment();
|
||||
void Set(std::u16string const & key, std::u16string const & value);
|
||||
|
|
|
|||
|
|
@ -535,8 +535,8 @@ int KMX_ProcessEvent::PostString(PKMX_WCHAR str, LPKEYBOARD lpkb, PKMX_WCHAR end
|
|||
|
||||
KMX_BOOL KMX_ProcessEvent::IsMatchingBaseLayout(PKMX_WCHAR layoutName) // I3432
|
||||
{
|
||||
KMX_BOOL bEqual = u16icmp(layoutName, static_cast<const km_core_cp *>(m_environment.baseLayout().c_str())) == 0 || // I4583
|
||||
u16icmp(layoutName, static_cast<const km_core_cp*>(m_environment.baseLayoutAlt().c_str())) == 0; // I4583
|
||||
KMX_BOOL bEqual = u16icmp(layoutName, static_cast<const km_core_cu *>(m_environment.baseLayout().c_str())) == 0 || // I4583
|
||||
u16icmp(layoutName, static_cast<const km_core_cu*>(m_environment.baseLayoutAlt().c_str())) == 0; // I4583
|
||||
|
||||
return bEqual;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
using namespace km::core;
|
||||
using namespace kmx;
|
||||
|
||||
const km_core_cp *km::core::kmx::u16chr(const km_core_cp *p, km_core_cp ch) {
|
||||
const km_core_cu *km::core::kmx::u16chr(const km_core_cu *p, km_core_cu ch) {
|
||||
while (*p) {
|
||||
if (*p == ch) return p;
|
||||
p++;
|
||||
|
|
@ -20,8 +20,8 @@ const km_core_cp *km::core::kmx::u16chr(const km_core_cp *p, km_core_cp ch) {
|
|||
return ch == 0 ? p : NULL;
|
||||
}
|
||||
|
||||
const km_core_cp *km::core::kmx::u16cpy(km_core_cp *dst, const km_core_cp *src) {
|
||||
km_core_cp *o = dst;
|
||||
const km_core_cu *km::core::kmx::u16cpy(km_core_cu *dst, const km_core_cu *src) {
|
||||
km_core_cu *o = dst;
|
||||
while (*src) {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
|
@ -29,8 +29,8 @@ const km_core_cp *km::core::kmx::u16cpy(km_core_cp *dst, const km_core_cp *src)
|
|||
return o;
|
||||
}
|
||||
|
||||
const km_core_cp *km::core::kmx::u16ncpy(km_core_cp *dst, const km_core_cp *src, size_t max) {
|
||||
km_core_cp *o = dst;
|
||||
const km_core_cu *km::core::kmx::u16ncpy(km_core_cu *dst, const km_core_cu *src, size_t max) {
|
||||
km_core_cu *o = dst;
|
||||
while (*src && max > 0) {
|
||||
*dst++ = *src++;
|
||||
max--;
|
||||
|
|
@ -42,7 +42,7 @@ const km_core_cp *km::core::kmx::u16ncpy(km_core_cp *dst, const km_core_cp *src,
|
|||
return o;
|
||||
}
|
||||
|
||||
size_t km::core::kmx::u16len(const km_core_cp *p) {
|
||||
size_t km::core::kmx::u16len(const km_core_cu *p) {
|
||||
int i = 0;
|
||||
while (*p) {
|
||||
p++;
|
||||
|
|
@ -51,7 +51,7 @@ size_t km::core::kmx::u16len(const km_core_cp *p) {
|
|||
return i;
|
||||
}
|
||||
|
||||
int km::core::kmx::u16cmp(const km_core_cp *p, const km_core_cp *q) {
|
||||
int km::core::kmx::u16cmp(const km_core_cu *p, const km_core_cu *q) {
|
||||
while (*p && *q) {
|
||||
if (*p != *q) return *p - *q;
|
||||
p++;
|
||||
|
|
@ -60,7 +60,7 @@ int km::core::kmx::u16cmp(const km_core_cp *p, const km_core_cp *q) {
|
|||
return *p - *q;
|
||||
}
|
||||
|
||||
int km::core::kmx::u16icmp(const km_core_cp *p, const km_core_cp *q) {
|
||||
int km::core::kmx::u16icmp(const km_core_cu *p, const km_core_cu *q) {
|
||||
while (*p && *q) {
|
||||
if (toupper(*p) != toupper(*q)) return *p - *q;
|
||||
p++;
|
||||
|
|
@ -69,7 +69,7 @@ int km::core::kmx::u16icmp(const km_core_cp *p, const km_core_cp *q) {
|
|||
return *p - *q;
|
||||
}
|
||||
|
||||
int km::core::kmx::u16ncmp(const km_core_cp *p, const km_core_cp *q, size_t count) {
|
||||
int km::core::kmx::u16ncmp(const km_core_cu *p, const km_core_cu *q, size_t count) {
|
||||
while (*p && *q && count) {
|
||||
if (*p != *q) return *p - *q;
|
||||
p++;
|
||||
|
|
@ -81,13 +81,13 @@ int km::core::kmx::u16ncmp(const km_core_cp *p, const km_core_cp *q, size_t coun
|
|||
return 0;
|
||||
}
|
||||
|
||||
km_core_cp *km::core::kmx::u16tok(km_core_cp *p, km_core_cp ch, km_core_cp **ctx) {
|
||||
km_core_cu *km::core::kmx::u16tok(km_core_cu *p, km_core_cu ch, km_core_cu **ctx) {
|
||||
if (!p) {
|
||||
p = *ctx;
|
||||
if (!p) return NULL;
|
||||
}
|
||||
|
||||
km_core_cp *q = p;
|
||||
km_core_cu *q = p;
|
||||
while (*q && *q != ch) {
|
||||
q++;
|
||||
}
|
||||
|
|
@ -103,9 +103,9 @@ km_core_cp *km::core::kmx::u16tok(km_core_cp *p, km_core_cp ch, km_core_cp **ctx
|
|||
return p;
|
||||
}
|
||||
|
||||
km_core_cp *km::core::kmx::u16dup(km_core_cp *src) {
|
||||
km_core_cp *dup = new km_core_cp[u16len(src) + 1];
|
||||
memcpy(dup, src, (u16len(src) + 1) * sizeof(km_core_cp));
|
||||
km_core_cu *km::core::kmx::u16dup(km_core_cu *src) {
|
||||
km_core_cu *dup = new km_core_cu[u16len(src) + 1];
|
||||
memcpy(dup, src, (u16len(src) + 1) * sizeof(km_core_cu));
|
||||
return dup;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,15 +107,15 @@ int xchrcmp(PKMX_WCHAR ch1, PKMX_WCHAR ch2);
|
|||
PKMX_CHAR wstrtostr(PKMX_WCHAR in);
|
||||
PKMX_WCHAR strtowstr(PKMX_CHAR in);
|
||||
|
||||
const km_core_cp *u16chr(const km_core_cp *p, km_core_cp ch);
|
||||
const km_core_cp *u16cpy(km_core_cp *dst, const km_core_cp *src); // TODO: deprecate all usages
|
||||
const km_core_cp *u16ncpy(km_core_cp *dst, const km_core_cp *src, size_t max);
|
||||
size_t u16len(const km_core_cp *p);
|
||||
int u16cmp(const km_core_cp *p, const km_core_cp *q);
|
||||
int u16icmp(const km_core_cp *p, const km_core_cp *q);
|
||||
int u16ncmp(const km_core_cp *p, const km_core_cp *q, size_t count);
|
||||
km_core_cp *u16tok(km_core_cp *p, km_core_cp ch, km_core_cp **ctx);
|
||||
km_core_cp *u16dup(km_core_cp *src);
|
||||
const km_core_cu *u16chr(const km_core_cu *p, km_core_cu ch);
|
||||
const km_core_cu *u16cpy(km_core_cu *dst, const km_core_cu *src); // TODO: deprecate all usages
|
||||
const km_core_cu *u16ncpy(km_core_cu *dst, const km_core_cu *src, size_t max);
|
||||
size_t u16len(const km_core_cu *p);
|
||||
int u16cmp(const km_core_cu *p, const km_core_cu *q);
|
||||
int u16icmp(const km_core_cu *p, const km_core_cu *q);
|
||||
int u16ncmp(const km_core_cu *p, const km_core_cu *q, size_t count);
|
||||
km_core_cu *u16tok(km_core_cu *p, km_core_cu ch, km_core_cu **ctx);
|
||||
km_core_cu *u16dup(km_core_cu *src);
|
||||
|
||||
//KMX_BOOL MapUSCharToVK(KMX_WORD ch, PKMX_WORD puKey, PKMX_DWORD puShiftFlags);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ option::option(km_core_option_scope s, char16_t const *k, char16_t const *v)
|
|||
{
|
||||
auto n_k = std::char_traits<char16_t>::length(k)+1,
|
||||
n_v = std::char_traits<char16_t>::length(v)+1;
|
||||
auto _key = new km_core_cp[n_k],
|
||||
_val = new km_core_cp[n_v];
|
||||
auto _key = new km_core_cu[n_k],
|
||||
_val = new km_core_cu[n_v];
|
||||
std::copy_n(k, n_k, _key);
|
||||
std::copy_n(v, n_v, _val);
|
||||
|
||||
|
|
|
|||
|
|
@ -62,10 +62,10 @@ KmxTestSource::parse_source_string(std::string const &s) {
|
|||
assert(v >= 0x0001 && v <= 0x10FFFF);
|
||||
p += n - 1;
|
||||
if (v < 0x10000) {
|
||||
t += km_core_cp(v);
|
||||
t += km_core_cu(v);
|
||||
} else {
|
||||
t += km_core_cp(Uni_UTF32ToSurrogate1(v));
|
||||
t += km_core_cp(Uni_UTF32ToSurrogate2(v));
|
||||
t += km_core_cu(Uni_UTF32ToSurrogate1(v));
|
||||
t += km_core_cu(Uni_UTF32ToSurrogate2(v));
|
||||
}
|
||||
} else if (*p == 'd') {
|
||||
// Deadkey
|
||||
|
|
@ -191,13 +191,13 @@ KmxTestSource::get_keyboard_options(kmx_options options) {
|
|||
keyboard_opts[i].scope = KM_CORE_OPT_KEYBOARD;
|
||||
}
|
||||
|
||||
km_core_cp *cp = new km_core_cp[key.length() + 1];
|
||||
km_core_cu *cp = new km_core_cu[key.length() + 1];
|
||||
key.copy(cp, key.length());
|
||||
cp[key.length()] = 0;
|
||||
|
||||
keyboard_opts[i].key = cp;
|
||||
|
||||
cp = new km_core_cp[it->value.length() + 1];
|
||||
cp = new km_core_cu[it->value.length() + 1];
|
||||
it->value.copy(cp, it->value.length());
|
||||
cp[it->value.length()] = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ void teardown() {
|
|||
}
|
||||
}
|
||||
|
||||
void setup(const char *keyboard, const km_core_cp* context) {
|
||||
void setup(const char *keyboard, const km_core_cu* context) {
|
||||
teardown();
|
||||
|
||||
km::core::path path = km::core::path::join(arg_path, keyboard);
|
||||
|
|
|
|||
|
|
@ -52,14 +52,14 @@ int main(int, char * [])
|
|||
// Check context_item to UTF16 conversion, roundtrip test.
|
||||
char16_t ctxt_buffer[512] ={0,};
|
||||
// First call measure space 2nd call do conversion.
|
||||
size_t ctxt_size = sizeof ctxt_buffer/sizeof(km_core_cp);
|
||||
size_t ctxt_size = sizeof ctxt_buffer/sizeof(km_core_cu);
|
||||
try_status(context_items_to_utf16(ctxt1, nullptr, &ctxt_size));
|
||||
if (ctxt_size > sizeof ctxt_buffer/sizeof(km_core_cp)) return __LINE__;
|
||||
if (ctxt_size > sizeof ctxt_buffer/sizeof(km_core_cu)) return __LINE__;
|
||||
try_status(context_items_to_utf16(ctxt1, ctxt_buffer, &ctxt_size));
|
||||
if (initial_bmp_context != ctxt_buffer) return __LINE__;
|
||||
|
||||
// Test roundtripping SMP characters in surrogate pairs.
|
||||
ctxt_size=sizeof ctxt_buffer/sizeof(km_core_cp);
|
||||
ctxt_size=sizeof ctxt_buffer/sizeof(km_core_cu);
|
||||
try_status(context_items_to_utf16(ctxt2, ctxt_buffer, &ctxt_size));
|
||||
if (initial_smp_context != ctxt_buffer) return __LINE__;
|
||||
// Test buffer overrun protection.
|
||||
|
|
@ -85,14 +85,14 @@ int main(int, char * [])
|
|||
// retrieve bmp context and check it's okay.
|
||||
km_core_context_item *tmp_ctxt;
|
||||
try_status(km_core_context_get(&mock_ctxt1, &tmp_ctxt));
|
||||
ctxt_size=sizeof ctxt_buffer/sizeof(km_core_cp);
|
||||
ctxt_size=sizeof ctxt_buffer/sizeof(km_core_cu);
|
||||
try_status(context_items_to_utf16(tmp_ctxt, ctxt_buffer, &ctxt_size));
|
||||
km_core_context_items_dispose(tmp_ctxt);
|
||||
if (initial_bmp_context != ctxt_buffer) return __LINE__;
|
||||
|
||||
// retrieve smp context and check it's okay.
|
||||
try_status(km_core_context_get(&mock_ctxt2, &tmp_ctxt));
|
||||
ctxt_size=sizeof ctxt_buffer/sizeof(km_core_cp);
|
||||
ctxt_size=sizeof ctxt_buffer/sizeof(km_core_cu);
|
||||
try_status(context_items_to_utf16(tmp_ctxt, ctxt_buffer, &ctxt_size));
|
||||
km_core_context_items_dispose(tmp_ctxt);
|
||||
if (initial_smp_context != ctxt_buffer) return __LINE__;
|
||||
|
|
@ -116,7 +116,7 @@ int main(int, char * [])
|
|||
km_core_context_items_dispose(ctxt2);
|
||||
|
||||
// Check it matches. The marker will be elided during the conversion.
|
||||
ctxt_size=sizeof ctxt_buffer/sizeof(km_core_cp);
|
||||
ctxt_size=sizeof ctxt_buffer/sizeof(km_core_cu);
|
||||
try_status(km_core_context_get(&mock_ctxt1, &tmp_ctxt));
|
||||
try_status(context_items_to_utf16(tmp_ctxt, ctxt_buffer, &ctxt_size));
|
||||
if (std::u16string(u"Hello World!") != ctxt_buffer) return __LINE__;
|
||||
|
|
@ -128,7 +128,7 @@ int main(int, char * [])
|
|||
// expected if you go by the test string above.
|
||||
try_status(context_shrink(&mock_ctxt1, 8));
|
||||
try_status(context_prepend(&mock_ctxt1, ctxt1, 8));
|
||||
ctxt_size=sizeof ctxt_buffer/sizeof(km_core_cp);
|
||||
ctxt_size=sizeof ctxt_buffer/sizeof(km_core_cu);
|
||||
try_status(km_core_context_get(&mock_ctxt1, &tmp_ctxt));
|
||||
try_status(context_items_to_utf16(tmp_ctxt, ctxt_buffer, &ctxt_size));
|
||||
if (std::u16string(u"Bye, Hello") != ctxt_buffer) return __LINE__;
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ namespace
|
|||
bool _assert_lookup_equals(std::u16string const key, std::u16string value, km_core_option_scope scope)
|
||||
{
|
||||
|
||||
km_core_cp const * ret = nullptr;
|
||||
km_core_cu const * ret = nullptr;
|
||||
auto s = km_core_state_option_lookup(api_mock_options, scope,
|
||||
key.c_str(),
|
||||
&ret);
|
||||
|
|
@ -129,7 +129,7 @@ int main(int, char * [])
|
|||
return __LINE__;
|
||||
|
||||
#if 0
|
||||
km_core_cp const *value;
|
||||
km_core_cu const *value;
|
||||
auto s = km_core_options_lookup(api_empty_options,
|
||||
KM_CORE_OPT_ENVIRONMENT,
|
||||
u"isdummy", &value);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ teardown() {
|
|||
}
|
||||
|
||||
void
|
||||
setup(const char *keyboard, const km_core_cp *context, bool setup_app_context = true) {
|
||||
setup(const char *keyboard, const km_core_cu *context, bool setup_app_context = true) {
|
||||
teardown();
|
||||
|
||||
km::core::path path = km::core::path::join(arg_path, keyboard);
|
||||
|
|
@ -51,11 +51,11 @@ setup(const char *keyboard, const km_core_cp *context, bool setup_app_context =
|
|||
}
|
||||
|
||||
bool
|
||||
is_identical_context(km_core_cp const *cached_context) {
|
||||
is_identical_context(km_core_cu const *cached_context) {
|
||||
size_t buf_size;
|
||||
try_status(km_core_context_get(km_core_state_context(test_state), &citems));
|
||||
try_status(context_items_to_utf16(citems, nullptr, &buf_size));
|
||||
km_core_cp *new_cached_context = new km_core_cp[buf_size];
|
||||
km_core_cu *new_cached_context = new km_core_cu[buf_size];
|
||||
try_status(context_items_to_utf16(citems, new_cached_context, &buf_size));
|
||||
bool result = std::u16string(cached_context) == new_cached_context;
|
||||
delete[] new_cached_context;
|
||||
|
|
@ -122,8 +122,8 @@ is_identical_context(km_core_cp const *cached_context) {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__identical_context() {
|
||||
km_core_cp const *cached_context = u"This is a test";
|
||||
km_core_cp const *new_app_context = u"This is a test";
|
||||
km_core_cu const *cached_context = u"This is a test";
|
||||
km_core_cu const *new_app_context = u"This is a test";
|
||||
setup("k_000___null_keyboard.kmx", cached_context, false);
|
||||
assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UNCHANGED);
|
||||
assert(is_identical_context(cached_context));
|
||||
|
|
@ -132,8 +132,8 @@ test_context_set_if_needed__identical_context() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__different_context() {
|
||||
km_core_cp const *cached_context = u"This isn't a test";
|
||||
km_core_cp const *new_app_context = u"This is a test";
|
||||
km_core_cu const *cached_context = u"This isn't a test";
|
||||
km_core_cu const *new_app_context = u"This is a test";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED);
|
||||
assert(!is_identical_context(cached_context));
|
||||
|
|
@ -143,8 +143,8 @@ test_context_set_if_needed__different_context() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__cached_context_cleared() {
|
||||
km_core_cp const *cached_context = u"";
|
||||
km_core_cp const *new_app_context = u"This is a test";
|
||||
km_core_cu const *cached_context = u"";
|
||||
km_core_cu const *new_app_context = u"This is a test";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
km_core_state_context_clear(test_state);
|
||||
assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED);
|
||||
|
|
@ -155,8 +155,8 @@ test_context_set_if_needed__cached_context_cleared() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__application_context_empty() {
|
||||
km_core_cp const *cached_context = u"This is a test";
|
||||
km_core_cp const *new_app_context = u"";
|
||||
km_core_cu const *cached_context = u"This is a test";
|
||||
km_core_cu const *new_app_context = u"";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED);
|
||||
assert(!is_identical_context(cached_context));
|
||||
|
|
@ -166,8 +166,8 @@ test_context_set_if_needed__application_context_empty() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__app_context_is_longer() {
|
||||
km_core_cp const *cached_context = u"This is a test";
|
||||
km_core_cp const *new_app_context = u"Longer This is a test";
|
||||
km_core_cu const *cached_context = u"This is a test";
|
||||
km_core_cu const *new_app_context = u"Longer This is a test";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED);
|
||||
assert(!is_identical_context(cached_context));
|
||||
|
|
@ -177,8 +177,8 @@ test_context_set_if_needed__app_context_is_longer() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__app_context_is_shorter() {
|
||||
km_core_cp const *cached_context = u"This is a test";
|
||||
km_core_cp const *new_app_context = u"is a test";
|
||||
km_core_cu const *cached_context = u"This is a test";
|
||||
km_core_cu const *new_app_context = u"is a test";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED);
|
||||
assert(!is_identical_context(cached_context));
|
||||
|
|
@ -188,8 +188,8 @@ test_context_set_if_needed__app_context_is_shorter() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__identical_context_and_markers() {
|
||||
km_core_cp const *cached_context = u"123";
|
||||
km_core_cp const *new_app_context = u"123";
|
||||
km_core_cu const *cached_context = u"123";
|
||||
km_core_cu const *new_app_context = u"123";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
|
||||
km_core_context_item const citems[] = {
|
||||
|
|
@ -209,8 +209,8 @@ test_context_set_if_needed__identical_context_and_markers() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__cached_context_shorter_and_markers() {
|
||||
km_core_cp const *cached_context = u"123";
|
||||
km_core_cp const *new_app_context = u"0123";
|
||||
km_core_cu const *cached_context = u"123";
|
||||
km_core_cu const *new_app_context = u"0123";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
|
||||
km_core_context_item const citems[] = {
|
||||
|
|
@ -235,8 +235,8 @@ test_context_set_if_needed__cached_context_shorter_and_markers() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__cached_context_shorter_and_markers_nfu() {
|
||||
km_core_cp const *cached_context = u"bce\u0323\u0302";
|
||||
km_core_cp const *new_app_context = u"abcệ";
|
||||
km_core_cu const *cached_context = u"bce\u0323\u0302";
|
||||
km_core_cu const *new_app_context = u"abcệ";
|
||||
setup("/a/dummy/keyboard.mock", cached_context);
|
||||
|
||||
km_core_context_item const citems[] = {
|
||||
|
|
@ -268,8 +268,8 @@ test_context_set_if_needed__cached_context_shorter_and_markers_nfu() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__cached_context_longer_and_markers() {
|
||||
km_core_cp const *cached_context = u"0123";
|
||||
km_core_cp const *new_app_context = u"123";
|
||||
km_core_cu const *cached_context = u"0123";
|
||||
km_core_cu const *new_app_context = u"123";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
|
||||
km_core_context_item const citems[] = {
|
||||
|
|
@ -293,8 +293,8 @@ test_context_set_if_needed__cached_context_longer_and_markers() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__cached_context_longer_and_markers_nfu() {
|
||||
km_core_cp const *cached_context = u"abce\u0323\u0302";
|
||||
km_core_cp const *new_app_context = u"bcệ";
|
||||
km_core_cu const *cached_context = u"abce\u0323\u0302";
|
||||
km_core_cu const *new_app_context = u"bcệ";
|
||||
setup("/a/dummy/keyboard.mock", cached_context);
|
||||
|
||||
km_core_context_item const citems[] = {
|
||||
|
|
@ -326,8 +326,8 @@ test_context_set_if_needed__cached_context_longer_and_markers_nfu() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__surrogate_pairs_unchanged() {
|
||||
km_core_cp const *cached_context = u"a\U00010100";
|
||||
km_core_cp const *new_app_context = u"a\U00010100";
|
||||
km_core_cu const *cached_context = u"a\U00010100";
|
||||
km_core_cu const *new_app_context = u"a\U00010100";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UNCHANGED);
|
||||
assert(is_identical_context(new_app_context));
|
||||
|
|
@ -336,8 +336,8 @@ test_context_set_if_needed__surrogate_pairs_unchanged() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__surrogate_pairs_app_context_longer() {
|
||||
km_core_cp const *cached_context = u"a\U00010100";
|
||||
km_core_cp const *new_app_context = u"xa\U00010100";
|
||||
km_core_cu const *cached_context = u"a\U00010100";
|
||||
km_core_cu const *new_app_context = u"xa\U00010100";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED);
|
||||
assert(is_identical_context(new_app_context));
|
||||
|
|
@ -346,8 +346,8 @@ test_context_set_if_needed__surrogate_pairs_app_context_longer() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__surrogate_pairs_cached_context_longer() {
|
||||
km_core_cp const *cached_context = u"xa\U00010100";
|
||||
km_core_cp const *new_app_context = u"a\U00010100";
|
||||
km_core_cu const *cached_context = u"xa\U00010100";
|
||||
km_core_cu const *new_app_context = u"a\U00010100";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED);
|
||||
assert(is_identical_context(new_app_context));
|
||||
|
|
@ -356,8 +356,8 @@ test_context_set_if_needed__surrogate_pairs_cached_context_longer() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__surrogate_pairs_unchanged_and_markers() {
|
||||
km_core_cp const *cached_context = u"a\U00010100";
|
||||
km_core_cp const *new_app_context = u"a\U00010100";
|
||||
km_core_cu const *cached_context = u"a\U00010100";
|
||||
km_core_cu const *new_app_context = u"a\U00010100";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
|
||||
km_core_context_item const citems[] = {
|
||||
|
|
@ -376,8 +376,8 @@ test_context_set_if_needed__surrogate_pairs_unchanged_and_markers() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__surrogate_pairs_app_context_longer_and_markers() {
|
||||
km_core_cp const *cached_context = u"a\U00010100";
|
||||
km_core_cp const *new_app_context = u"\U00010200a\U00010100";
|
||||
km_core_cu const *cached_context = u"a\U00010100";
|
||||
km_core_cu const *new_app_context = u"\U00010200a\U00010100";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
|
||||
km_core_context_item const citems[] = {
|
||||
|
|
@ -403,8 +403,8 @@ test_context_set_if_needed__surrogate_pairs_app_context_longer_and_markers() {
|
|||
|
||||
void
|
||||
test_context_set_if_needed__surrogate_pairs_cached_context_longer_and_markers() {
|
||||
km_core_cp const *cached_context = u"\U00010200a\U00010100";
|
||||
km_core_cp const *new_app_context = u"a\U00010100";
|
||||
km_core_cu const *cached_context = u"\U00010200a\U00010100";
|
||||
km_core_cu const *new_app_context = u"a\U00010100";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
|
||||
km_core_context_item const citems[] = {
|
||||
|
|
@ -464,7 +464,7 @@ test_context_set_if_needed() {
|
|||
|
||||
void
|
||||
test_context_clear() {
|
||||
km_core_cp const *cached_context = u"This is a test";
|
||||
km_core_cu const *cached_context = u"This is a test";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
try_status(km_core_state_context_clear(test_state));
|
||||
assert(!is_identical_context(cached_context));
|
||||
|
|
@ -475,16 +475,16 @@ test_context_clear() {
|
|||
//-------------------------------------------------------------------------------------
|
||||
|
||||
void test_context_debug_empty() {
|
||||
km_core_cp const *cached_context = u"";
|
||||
km_core_cu const *cached_context = u"";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
auto str = km_core_state_context_debug(test_state, KM_CORE_DEBUG_CONTEXT_CACHED);
|
||||
// std::cout << str << std::endl;
|
||||
assert(std::u16string(str) == u"|| (len: 0) [ ]");
|
||||
km_core_cp_dispose(str);
|
||||
km_core_cu_dispose(str);
|
||||
}
|
||||
|
||||
void test_context_debug_various() {
|
||||
km_core_cp const *cached_context = u"123\U0001F923";
|
||||
km_core_cu const *cached_context = u"123\U0001F923";
|
||||
setup("k_000___null_keyboard.kmx", cached_context);
|
||||
|
||||
km_core_context_item const citems[] = {
|
||||
|
|
@ -505,7 +505,7 @@ void test_context_debug_various() {
|
|||
auto str = km_core_state_context_debug(test_state, KM_CORE_DEBUG_CONTEXT_CACHED);
|
||||
// std::cout << str << std::endl;
|
||||
assert(std::u16string(str) == u"|123🤣| (len: 9) [ M(5) U+0031 M(1) U+0032 M(2) U+0033 M(3) M(4) U+1f923 ]");
|
||||
km_core_cp_dispose(str);
|
||||
km_core_cu_dispose(str);
|
||||
}
|
||||
|
||||
void test_context_debug() {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ void teardown() {
|
|||
|
||||
|
||||
|
||||
void setup(const km_core_cp *app_context, const km_core_cp *cached_context, int actions_code_points_to_delete, const std::u32string actions_output) {
|
||||
void setup(const km_core_cu *app_context, const km_core_cu *cached_context, int actions_code_points_to_delete, const std::u32string actions_output) {
|
||||
teardown();
|
||||
|
||||
km::core::path path = km::core::path::join(arg_path, "..", "ldml", "keyboards", "k_001_tiny.kmx");
|
||||
|
|
@ -107,14 +107,14 @@ void setup(const km_core_cp *app_context, const km_core_cp *cached_context, int
|
|||
*/
|
||||
void test(
|
||||
const char *name,
|
||||
const km_core_cp *initial_app_context,
|
||||
const km_core_cp *final_cached_context,
|
||||
const km_core_cu *initial_app_context,
|
||||
const km_core_cu *final_cached_context,
|
||||
int actions_code_points_to_delete,
|
||||
const std::u32string actions_output,
|
||||
|
||||
const unsigned int expected_delete,
|
||||
const std::u32string expected_output,
|
||||
const km_core_cp *expected_final_app_context,
|
||||
const km_core_cu *expected_final_app_context,
|
||||
const std::u32string expected_deleted_context
|
||||
) {
|
||||
std::cout << "test: " << name << std::endl;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#include <test_assert.h>
|
||||
#include "../emscripten_filesystem.h"
|
||||
|
||||
void compare_context(km_core_context *app_context, const km_core_cp* expected_final_app_context);
|
||||
void compare_context(km_core_context *app_context, const km_core_cu* expected_final_app_context);
|
||||
|
||||
km_core_option_item test_env_opts[] =
|
||||
{
|
||||
|
|
@ -42,7 +42,7 @@ void teardown() {
|
|||
|
||||
|
||||
|
||||
void setup(const km_core_cp *app_context, const km_core_cp *cached_context_string, const km_core_context_item *cached_context_items, int actions_code_points_to_delete, const std::u32string actions_output) {
|
||||
void setup(const km_core_cu *app_context, const km_core_cu *cached_context_string, const km_core_context_item *cached_context_items, int actions_code_points_to_delete, const std::u32string actions_output) {
|
||||
teardown();
|
||||
|
||||
km::core::path path = km::core::path::join(arg_path, "..", "ldml", "keyboards", "k_001_tiny.kmx");
|
||||
|
|
@ -105,15 +105,15 @@ void setup(const km_core_cp *app_context, const km_core_cp *cached_context_strin
|
|||
*/
|
||||
void test_actions_normalize(
|
||||
const char *name,
|
||||
const km_core_cp *initial_app_context,
|
||||
const km_core_cp *final_cached_context_string,
|
||||
const km_core_cu *initial_app_context,
|
||||
const km_core_cu *final_cached_context_string,
|
||||
const km_core_context_item *final_cached_context_items,
|
||||
int actions_code_points_to_delete,
|
||||
const std::u32string actions_output,
|
||||
|
||||
const unsigned int expected_delete,
|
||||
const std::u32string expected_output,
|
||||
const km_core_cp *expected_final_app_context
|
||||
const km_core_cu *expected_final_app_context
|
||||
) {
|
||||
std::cout << "test_actions_normalize: " << name << std::endl;
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ void test_actions_normalize(
|
|||
|
||||
auto debug = km_core_state_context_debug(test_state, KM_CORE_DEBUG_CONTEXT_APP);
|
||||
std::cout << " final app context: " << debug << std::endl;
|
||||
km_core_cp_dispose(debug);
|
||||
km_core_cu_dispose(debug);
|
||||
|
||||
compare_context(km_core_state_app_context(test_state), expected_final_app_context);
|
||||
teardown();
|
||||
|
|
@ -179,15 +179,15 @@ void test_actions_normalize(
|
|||
*/
|
||||
void test_actions_update_app_context_nfu(
|
||||
const char *name,
|
||||
const km_core_cp *initial_app_context,
|
||||
const km_core_cp *final_cached_context_string,
|
||||
const km_core_cu *initial_app_context,
|
||||
const km_core_cu *final_cached_context_string,
|
||||
const km_core_context_item *final_cached_context_items,
|
||||
int actions_code_points_to_delete,
|
||||
const std::u32string actions_output,
|
||||
|
||||
const unsigned int expected_delete,
|
||||
const std::u32string expected_output,
|
||||
const km_core_cp *expected_final_app_context
|
||||
const km_core_cu *expected_final_app_context
|
||||
) {
|
||||
std::cout << "test_actions_update_app_context_nfu: " << name << std::endl;
|
||||
|
||||
|
|
@ -207,7 +207,7 @@ void test_actions_update_app_context_nfu(
|
|||
|
||||
auto debug = km_core_state_context_debug(test_state, KM_CORE_DEBUG_CONTEXT_APP);
|
||||
std::cout << " final app context: " << debug << std::endl;
|
||||
km_core_cp_dispose(debug);
|
||||
km_core_cu_dispose(debug);
|
||||
|
||||
compare_context(km_core_state_app_context(test_state), expected_final_app_context);
|
||||
teardown();
|
||||
|
|
@ -618,7 +618,7 @@ int main(int argc, char *argv []) {
|
|||
}
|
||||
|
||||
|
||||
void compare_context(km_core_context *app_context, const km_core_cp* expected_final_app_context) {
|
||||
void compare_context(km_core_context *app_context, const km_core_cu* expected_final_app_context) {
|
||||
// Compare context items -- to ensure no markers have leaked into app context
|
||||
km_core_context_item *actual_final_app_context_items = nullptr, *expected_final_app_context_items = nullptr;
|
||||
try_status(km_core_context_get(app_context, &actual_final_app_context_items));
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ run_test(const km::core::path &source, const km::core::path &compiled) {
|
|||
size_t n = 0;
|
||||
try_status(km_core_context_get(km_core_state_context(test_state), &citems));
|
||||
try_status(context_items_to_utf16(citems, nullptr, &n));
|
||||
km_core_cp *core_context_str = new km_core_cp[n];
|
||||
km_core_cu *core_context_str = new km_core_cu[n];
|
||||
try_status(context_items_to_utf16(citems, core_context_str, &n));
|
||||
|
||||
// Verify that both our local test_context and the core's test_state.context have
|
||||
|
|
@ -273,7 +273,7 @@ run_test(const km::core::path &source, const km::core::path &compiled) {
|
|||
size_t n = 0;
|
||||
try_status(km_core_context_get(km_core_state_context(test_state), &citems));
|
||||
try_status(context_items_to_utf16(citems, nullptr, &n));
|
||||
km_core_cp *core_context_str = new km_core_cp[n];
|
||||
km_core_cu *core_context_str = new km_core_cu[n];
|
||||
try_status(context_items_to_utf16(citems, core_context_str, &n));
|
||||
|
||||
// Verify that both our local test_context and the core's test_state.context have
|
||||
|
|
@ -301,7 +301,7 @@ run_test(const km::core::path &source, const km::core::path &compiled) {
|
|||
for (auto it = options.begin(); it != options.end(); it++) {
|
||||
if (it->type == km::tests::KOT_OUTPUT) {
|
||||
std::cout << "output option-key: " << it->key << " expected: " << it->value;
|
||||
km_core_cp const *value;
|
||||
km_core_cu const *value;
|
||||
try_status(km_core_state_option_lookup(test_state, KM_CORE_OPT_KEYBOARD, it->key.c_str(), &value));
|
||||
std::cout << " actual: " << value << std::endl;
|
||||
if (it->value.compare(value) != 0) return __LINE__;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ uint8_t test_imx_callback(km_core_state *state, uint32_t imx_id, void *callback_
|
|||
|
||||
size_t n = 0;
|
||||
try_status(context_items_to_utf16(entry_context, nullptr, &n))
|
||||
km_core_cp *buf = new km_core_cp[n];
|
||||
km_core_cu *buf = new km_core_cu[n];
|
||||
try_status(context_items_to_utf16(entry_context, buf, &n));
|
||||
|
||||
std::cout << "imx entry context : " << " [" << buf << "]" << std::endl;
|
||||
|
|
@ -146,7 +146,7 @@ uint8_t test_imx_callback(km_core_state *state, uint32_t imx_id, void *callback_
|
|||
|
||||
n = 0;
|
||||
try_status(context_items_to_utf16(exit_context, nullptr, &n))
|
||||
km_core_cp *tmp_buf = new km_core_cp[n];
|
||||
km_core_cu *tmp_buf = new km_core_cu[n];
|
||||
try_status(context_items_to_utf16(exit_context, tmp_buf, &n));
|
||||
|
||||
std::cout << "imx exit context : " << " [" << tmp_buf << "]" << std::endl;
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ verify_context(std::u16string &text_store, km_core_state *&test_state, std::vect
|
|||
km_core_context_item *citems = nullptr;
|
||||
try_status(km_core_context_get(km_core_state_context(test_state), &citems));
|
||||
try_status(context_items_to_utf16(citems, nullptr, &n));
|
||||
km_core_cp *buf = new km_core_cp[n];
|
||||
km_core_cu *buf = new km_core_cu[n];
|
||||
try_status(context_items_to_utf16(citems, buf, &n));
|
||||
std::cout << "context (raw): "; // output including markers (which aren't in 'buf' here)
|
||||
for (auto ci = citems; ci->type != KM_CORE_CT_END; ci++) {
|
||||
|
|
|
|||
|
|
@ -174,10 +174,10 @@ LdmlTestSource::parse_source_string(std::string const &s) {
|
|||
assert(v >= 0x0001 && v <= 0x10FFFF);
|
||||
p += n - 1;
|
||||
if (v < 0x10000) {
|
||||
t += km_core_cp(v);
|
||||
t += km_core_cu(v);
|
||||
} else {
|
||||
t += km_core_cp(Uni_UTF32ToSurrogate1(v));
|
||||
t += km_core_cp(Uni_UTF32ToSurrogate2(v));
|
||||
t += km_core_cu(Uni_UTF32ToSurrogate1(v));
|
||||
t += km_core_cu(Uni_UTF32ToSurrogate2(v));
|
||||
}
|
||||
if (had_open_curly) {
|
||||
p++;
|
||||
|
|
@ -225,10 +225,10 @@ LdmlTestSource::parse_u8_source_string(std::string const &u8s) {
|
|||
assert(v >= 0x0001 && v <= 0x10FFFF);
|
||||
p += n - 1;
|
||||
if (v < 0x10000) {
|
||||
t += km_core_cp(v);
|
||||
t += km_core_cu(v);
|
||||
} else {
|
||||
t += km_core_cp(Uni_UTF32ToSurrogate1(v));
|
||||
t += km_core_cp(Uni_UTF32ToSurrogate2(v));
|
||||
t += km_core_cu(Uni_UTF32ToSurrogate1(v));
|
||||
t += km_core_cu(Uni_UTF32ToSurrogate2(v));
|
||||
}
|
||||
if (had_open_curly) {
|
||||
p++;
|
||||
|
|
|
|||
|
|
@ -53,10 +53,10 @@ void debug_context(km_core_debug_context_type context_type) {
|
|||
} else {
|
||||
std::cout << "cached context: " << context << std::endl;
|
||||
}
|
||||
km_core_cp_dispose(context);
|
||||
km_core_cu_dispose(context);
|
||||
}
|
||||
|
||||
bool is_identical_context(km_core_cp const *cached_context, km_core_debug_context_type context_type) {
|
||||
bool is_identical_context(km_core_cu const *cached_context, km_core_debug_context_type context_type) {
|
||||
size_t buf_size;
|
||||
km_core_context_item * citems = nullptr;
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ bool is_identical_context(km_core_cp const *cached_context, km_core_debug_contex
|
|||
try_status(km_core_context_get(km_core_state_context(test_state), &citems));
|
||||
}
|
||||
try_status(context_items_to_utf16(citems, nullptr, &buf_size));
|
||||
km_core_cp* new_cached_context = new km_core_cp[buf_size];
|
||||
km_core_cu* new_cached_context = new km_core_cu[buf_size];
|
||||
try_status(context_items_to_utf16(citems, new_cached_context, &buf_size));
|
||||
|
||||
km_core_context_items_dispose(citems);
|
||||
|
|
@ -79,7 +79,7 @@ bool is_identical_context(km_core_cp const *cached_context, km_core_debug_contex
|
|||
}
|
||||
|
||||
void test_context_normalization_already_nfd() {
|
||||
km_core_cp const *app_context_nfd = u"A\u0300";
|
||||
km_core_cu const *app_context_nfd = u"A\u0300";
|
||||
setup("k_001_tiny.kmx");
|
||||
assert(km_core_state_context_set_if_needed(test_state, app_context_nfd) == KM_CORE_CONTEXT_STATUS_UPDATED);
|
||||
assert(is_identical_context(app_context_nfd, KM_CORE_DEBUG_CONTEXT_APP));
|
||||
|
|
@ -88,8 +88,8 @@ void test_context_normalization_already_nfd() {
|
|||
}
|
||||
|
||||
void test_context_normalization_basic() {
|
||||
km_core_cp const *application_context = u"This is a test À";
|
||||
km_core_cp const *cached_context = u"This is a test A\u0300";
|
||||
km_core_cu const *application_context = u"This is a test À";
|
||||
km_core_cu const *cached_context = u"This is a test A\u0300";
|
||||
setup("k_001_tiny.kmx");
|
||||
assert(km_core_state_context_set_if_needed(test_state, application_context) == KM_CORE_CONTEXT_STATUS_UPDATED);
|
||||
assert(is_identical_context(application_context, KM_CORE_DEBUG_CONTEXT_APP));
|
||||
|
|
@ -99,8 +99,8 @@ void test_context_normalization_basic() {
|
|||
|
||||
void test_context_normalization_hefty() {
|
||||
// Latin Latin "ṩ" "Å" Tirhuta U+114bc -> U+114B9 U+114B0
|
||||
km_core_cp const *application_context = u"À" u"é̖" u"\u1e69" u"\u212b" u"\U000114BC";
|
||||
km_core_cp const *cached_context = u"A\u0300" u"e\u0316\u0301" u"\u0073\u0323\u0307" u"\u0041\u030a" u"\U000114B9\U000114B0";
|
||||
km_core_cu const *application_context = u"À" u"é̖" u"\u1e69" u"\u212b" u"\U000114BC";
|
||||
km_core_cu const *cached_context = u"A\u0300" u"e\u0316\u0301" u"\u0073\u0323\u0307" u"\u0041\u030a" u"\U000114B9\U000114B0";
|
||||
setup("k_001_tiny.kmx");
|
||||
assert(km_core_state_context_set_if_needed(test_state, application_context) == KM_CORE_CONTEXT_STATUS_UPDATED);
|
||||
assert(is_identical_context(application_context, KM_CORE_DEBUG_CONTEXT_APP));
|
||||
|
|
@ -110,8 +110,8 @@ void test_context_normalization_hefty() {
|
|||
|
||||
void test_context_normalization_invalid_unicode() {
|
||||
// unpaired surrogate illegal
|
||||
km_core_cp const application_context[] = { 0xDC01, 0x0020, 0x0020, 0xFFFF, 0x0000 };
|
||||
km_core_cp const cached_context[] = { 0xDC01, 0x0020, 0x0020, 0xFFFF, 0x0000 };
|
||||
km_core_cu const application_context[] = { 0xDC01, 0x0020, 0x0020, 0xFFFF, 0x0000 };
|
||||
km_core_cu const cached_context[] = { 0xDC01, 0x0020, 0x0020, 0xFFFF, 0x0000 };
|
||||
setup("k_001_tiny.kmx");
|
||||
assert(km_core_state_context_set_if_needed(test_state, application_context) == KM_CORE_CONTEXT_STATUS_UPDATED);
|
||||
assert(is_identical_context(application_context, KM_CORE_DEBUG_CONTEXT_APP));
|
||||
|
|
@ -121,8 +121,8 @@ void test_context_normalization_invalid_unicode() {
|
|||
|
||||
void test_context_normalization_lone_trailing_surrogate() {
|
||||
// unpaired trail surrogate
|
||||
km_core_cp const application_context[] = { 0xDC01, 0x0020, 0x0020, 0x0000 };
|
||||
km_core_cp const cached_context[] = /* skipped*/ { 0x0020, 0x0020, 0x0000 };
|
||||
km_core_cu const application_context[] = { 0xDC01, 0x0020, 0x0020, 0x0000 };
|
||||
km_core_cu const cached_context[] = /* skipped*/ { 0x0020, 0x0020, 0x0000 };
|
||||
setup("k_001_tiny.kmx");
|
||||
assert(km_core_state_context_set_if_needed(test_state, application_context) == KM_CORE_CONTEXT_STATUS_UPDATED);
|
||||
assert(is_identical_context(application_context+1, KM_CORE_DEBUG_CONTEXT_APP)); // first code unit is skipped
|
||||
|
|
|
|||
|
|
@ -18,3 +18,5 @@ DEVELOPER_DCC32DPK=cmd /c "$(DCC32PATH)\dcc32.exe" $(DEVELOPER_DELPHIDPKPARAMS)
|
|||
# Temporary import of windows/src/Defines.mak
|
||||
# TODO: include COMMON_ROOT's defines.mak instead
|
||||
!include $(WINDOWS_ROOT)\src\Defines.mak
|
||||
|
||||
KEYMANCORE=keymancore-2
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@
|
|||
</Component>
|
||||
|
||||
<Component>
|
||||
<File Name="keymancore-1.dll" KeyPath="yes" />
|
||||
<File Name="keymancore-2.dll" KeyPath="yes" />
|
||||
</Component>
|
||||
|
||||
<Component>
|
||||
|
|
|
|||
|
|
@ -372,6 +372,7 @@ export class KeyboardInfoCompiler implements KeymanCompiler {
|
|||
|
||||
const jsonOutput = JSON.stringify(keyboard_info, null, 2);
|
||||
|
||||
/* c8 ignore next 8 */
|
||||
if(!SchemaValidators.default.keyboard_info(keyboard_info)) {
|
||||
// This is an internal fatal error; we should not be capable of producing
|
||||
// invalid output, so it is best to throw and die
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ describe('keyboard-info-compiler', function () {
|
|||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
|
||||
it('check preinit creates langtagsByTag correctly', async function() {
|
||||
it('check preinit creates langtagsByTag correctly', function() {
|
||||
const compiler = new KeyboardInfoCompiler(); // indirectly call preinit()
|
||||
assert.isNotNull(compiler);
|
||||
const en_langtag = langtags.find(({ tag }) => tag === 'en');
|
||||
|
|
@ -146,7 +146,6 @@ describe('keyboard-info-compiler', function () {
|
|||
});
|
||||
|
||||
it('check run returns null if KmpCompiler.transformKpsToKmpObject fails', async function() {
|
||||
const kpjFilename = KHMER_ANGKOR_KPJ;
|
||||
const sources = KHMER_ANGKOR_SOURCES;
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
assert.isTrue(await compiler.init(callbacks, {sources}));
|
||||
|
|
@ -154,7 +153,7 @@ describe('keyboard-info-compiler', function () {
|
|||
let result: KeyboardInfoCompilerResult;
|
||||
try {
|
||||
KmpCompiler.prototype.transformKpsToKmpObject = (_kpsFilename: string): KmpJsonFile.KmpJsonFile => null;
|
||||
result = await compiler.run(kpjFilename, null);
|
||||
result = await compiler.run(KHMER_ANGKOR_KPJ, null);
|
||||
} catch(e) {
|
||||
assert.fail(e);
|
||||
} finally {
|
||||
|
|
@ -164,40 +163,36 @@ describe('keyboard-info-compiler', function () {
|
|||
});
|
||||
|
||||
it('check run returns null if loadJsFile fails', async function() {
|
||||
const kpjFilename = KHMER_ANGKOR_KPJ;
|
||||
const sources = KHMER_ANGKOR_SOURCES
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
assert.isTrue(await compiler.init(callbacks, {sources}));
|
||||
compiler['loadJsFile'] = (_filename: string): string => null;
|
||||
const result = await compiler.run(kpjFilename, null);
|
||||
const result = await compiler.run(KHMER_ANGKOR_KPJ, null);
|
||||
assert.isNull(result);
|
||||
});
|
||||
|
||||
it('check run returns null if license is not MIT', async function() {
|
||||
const kpjFilename = KHMER_ANGKOR_KPJ;
|
||||
const sources = KHMER_ANGKOR_SOURCES;
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
assert.isTrue(await compiler.init(callbacks, {sources}));
|
||||
compiler['isLicenseMIT'] = (_filename: string): boolean => false;
|
||||
const result = await compiler.run(kpjFilename, null);
|
||||
const result = await compiler.run(KHMER_ANGKOR_KPJ, null);
|
||||
assert.isNull(result);
|
||||
});
|
||||
|
||||
it('check run leaves keyboard_info.isRTL undefined if not set in jsFile', async function() {
|
||||
const kpjFilename = KHMER_ANGKOR_KPJ;
|
||||
const sources = KHMER_ANGKOR_SOURCES;
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
assert.isTrue(await compiler.init(callbacks, {sources}));
|
||||
const jsFile = compiler['loadJsFile'](sources.jsFilename);
|
||||
assert.isNull(jsFile.match(/this\.KRTL=1/));
|
||||
const result = await compiler.run(kpjFilename, null);
|
||||
const result = await compiler.run(KHMER_ANGKOR_KPJ, null);
|
||||
assert.isNotNull(result);
|
||||
const keyboard_info = JSON.parse(new TextDecoder().decode(result.artifacts.keyboard_info.data));
|
||||
assert.isUndefined(keyboard_info.isRTL);
|
||||
});
|
||||
|
||||
it('check run sets keyboard_info.isRTL if set in jsFile', async function() {
|
||||
const kpjFilename = KHMER_ANGKOR_KPJ;
|
||||
const sources = KHMER_ANGKOR_SOURCES;
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
assert.isTrue(await compiler.init(callbacks, {sources}));
|
||||
|
|
@ -205,7 +200,7 @@ describe('keyboard-info-compiler', function () {
|
|||
jsFile = jsFile.replace('this\.KN="Khmer Angkor";', '$&\n this\.KRTL=1;'); // insert this.KRTL=1
|
||||
const origCompilerLoadJsFile = compiler['loadJsFile'];
|
||||
compiler['loadJsFile'] = (_filename: string) => jsFile;
|
||||
const result = await compiler.run(kpjFilename, null);
|
||||
const result = await compiler.run(KHMER_ANGKOR_KPJ, null);
|
||||
compiler['loadJsFile'] = origCompilerLoadJsFile;
|
||||
assert.isNotNull(result);
|
||||
const keyboard_info = JSON.parse(new TextDecoder().decode(result.artifacts.keyboard_info.data));
|
||||
|
|
@ -213,7 +208,6 @@ describe('keyboard-info-compiler', function () {
|
|||
});
|
||||
|
||||
it('check run sets author.url correctly if mailto provided', async function() {
|
||||
const kpjFilename = KHMER_ANGKOR_KPJ;
|
||||
const sources = KHMER_ANGKOR_SOURCES;
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
assert.isTrue(await compiler.init(callbacks, {sources}));
|
||||
|
|
@ -221,14 +215,13 @@ describe('keyboard-info-compiler', function () {
|
|||
await kmpCompiler.init(callbacks, {});
|
||||
const kmpJsonData = kmpCompiler.transformKpsToKmpObject(sources.kpsFilename);
|
||||
assert.isNotNull(kmpJsonData.info.author.url.match(/^mailto\:/));
|
||||
const result = await compiler.run(kpjFilename, null);
|
||||
const result = await compiler.run(KHMER_ANGKOR_KPJ, null);
|
||||
assert.isNotNull(result);
|
||||
const keyboard_info = JSON.parse(new TextDecoder().decode(result.artifacts.keyboard_info.data));
|
||||
assert.deepEqual(keyboard_info.authorEmail, 'makara_sok@sil.org');
|
||||
});
|
||||
|
||||
it('check run sets author.url correctly if just email provided', async function() {
|
||||
const kpjFilename = KHMER_ANGKOR_KPJ;
|
||||
const sources = KHMER_ANGKOR_SOURCES;
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
assert.isTrue(await compiler.init(callbacks, {sources}));
|
||||
|
|
@ -240,7 +233,7 @@ describe('keyboard-info-compiler', function () {
|
|||
let result: KeyboardInfoCompilerResult;
|
||||
try {
|
||||
KmpCompiler.prototype.transformKpsToKmpObject = (_kpsFilename: string): KmpJsonFile.KmpJsonFile => kmpJsonData;
|
||||
result = await compiler.run(kpjFilename, null);
|
||||
result = await compiler.run(KHMER_ANGKOR_KPJ, null);
|
||||
} catch(e) {
|
||||
assert.fail(e);
|
||||
} finally {
|
||||
|
|
@ -252,12 +245,11 @@ describe('keyboard-info-compiler', function () {
|
|||
});
|
||||
|
||||
it('check run returns null if fillLanguages fails', async function() {
|
||||
const kpjFilename = KHMER_ANGKOR_KPJ;
|
||||
const sources = KHMER_ANGKOR_SOURCES;
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
assert.isTrue(await compiler.init(callbacks, {sources}));
|
||||
compiler['fillLanguages'] = async (_kpsFilename: string, _keyboard_info: KeyboardInfoFile, _kmpJsonData: KmpJsonFile.KmpJsonFile): Promise<boolean> => false;
|
||||
const result = await compiler.run(kpjFilename, null);
|
||||
const result = await compiler.run(KHMER_ANGKOR_KPJ, null);
|
||||
assert.isNull(result);
|
||||
});
|
||||
|
||||
|
|
@ -283,7 +275,6 @@ describe('keyboard-info-compiler', function () {
|
|||
];
|
||||
|
||||
packageIncludesTestCases.forEach((testCase, idx) => it(`check run sets packageIncludes correctly (test case #${idx})`, async function() {
|
||||
const kpjFilename = KHMER_ANGKOR_KPJ;
|
||||
const sources = KHMER_ANGKOR_SOURCES;
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
assert.isTrue(await compiler.init(callbacks, {sources}));
|
||||
|
|
@ -291,17 +282,16 @@ describe('keyboard-info-compiler', function () {
|
|||
compiler['fontSourceToKeyboardInfoFont'] = async (_kpsFilename: string, _kmpJsonData: KmpJsonFile.KmpJsonFile, _source: string[]) => {
|
||||
return (_source[0] == KHMER_ANGKOR_DISPLAY_FONT) ? KHMER_ANGKOR_DISPLAY_FONT_INFO : KHMER_ANGKOR_OSK_FONT_INFO;
|
||||
}
|
||||
const kpsFilename = KHMER_ANGKOR_KPS;
|
||||
const kmpCompiler = new KmpCompiler();
|
||||
assert.isTrue(await kmpCompiler.init(callbacks, {}));
|
||||
const kmpJsonData = kmpCompiler.transformKpsToKmpObject(kpsFilename);
|
||||
const kmpJsonData = kmpCompiler.transformKpsToKmpObject(KHMER_ANGKOR_KPS);
|
||||
assert.isNotNull(kmpJsonData);
|
||||
const origKmpCompilerTransformKpsToKmpObject = KmpCompiler.prototype.transformKpsToKmpObject;
|
||||
kmpJsonData.files = testCase.files;
|
||||
let result: KeyboardInfoCompilerResult;
|
||||
try {
|
||||
KmpCompiler.prototype.transformKpsToKmpObject = (_kpsFilename: string): KmpJsonFile.KmpJsonFile => kmpJsonData;
|
||||
result = await compiler.run(kpjFilename, null);
|
||||
result = await compiler.run(KHMER_ANGKOR_KPJ, null);
|
||||
} catch(e) {
|
||||
assert.fail(e);
|
||||
} finally {
|
||||
|
|
@ -321,7 +311,6 @@ describe('keyboard-info-compiler', function () {
|
|||
];
|
||||
|
||||
minKeymanVersionTestCases.forEach((testCase, idx) => it(`check run sets minKeymanVersion correctly (test case #${idx})`, async function() {
|
||||
const kpjFilename = KHMER_ANGKOR_KPJ;
|
||||
const sources = KHMER_ANGKOR_SOURCES;
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
assert.isTrue(await compiler.init(callbacks, {sources}));
|
||||
|
|
@ -332,7 +321,7 @@ describe('keyboard-info-compiler', function () {
|
|||
jsFile = jsFile.replace('this.KMINVER="10.0";', insert);
|
||||
compiler['loadJsFile'] = (_filename: string) => jsFile;
|
||||
compiler['kmxFileVersionToString'] = (_version: number) => testCase.kmx;
|
||||
const result = await compiler.run(kpjFilename, null);
|
||||
const result = await compiler.run(KHMER_ANGKOR_KPJ, null);
|
||||
compiler['loadJsFile'] = origCompilerLoadJsFile;
|
||||
compiler['kmxFileVersionToString'] = origKmxFileVersionToString;
|
||||
assert.isNotNull(result);
|
||||
|
|
@ -341,35 +330,33 @@ describe('keyboard-info-compiler', function () {
|
|||
}));
|
||||
|
||||
const platformsTestCases = [
|
||||
{ hasJsFile: true, targets: 'any', expected: { windows: "full",macos: "full",linux: "full",desktopWeb: "full",ios: "full",android: "full",mobileWeb: "full" } },
|
||||
{ hasJsFile: false, targets: '', expected: { desktopWeb: "full",mobileWeb: "full" } },
|
||||
{ hasJsFile: true, targets: '', expected: { desktopWeb: "full",ios: "full",android: "full",mobileWeb: "full" } },
|
||||
{ hasJsFile: true, targets: 'androidphone', expected: { android: "full",mobileWeb: "full" } },
|
||||
{ hasJsFile: true, targets: 'iphone', expected: { ios: "full",mobileWeb: "full" } },
|
||||
{ hasJsFile: true, targets: 'linux', expected: { linux: "full",desktopWeb: "full" } },
|
||||
{ hasJsFile: true, targets: 'macosx', expected: { macos: "full",desktopWeb: "full" } },
|
||||
{ hasJsFile: true, targets: 'windows', expected: { windows: "full",desktopWeb: "full" } },
|
||||
{ hasJsFile: true, targets: 'androidphone iphone', expected: { android: "full",ios: "full",mobileWeb: "full" } },
|
||||
{ hasJsFileInKps: true, targets: 'any', expected: { windows: "full",macos: "full",linux: "full",desktopWeb: "full",ios: "full",android: "full",mobileWeb: "full" } },
|
||||
{ hasJsFileInKps: false, targets: '', expected: { desktopWeb: "full",mobileWeb: "full" } },
|
||||
{ hasJsFileInKps: true, targets: '', expected: { desktopWeb: "full",ios: "full",android: "full",mobileWeb: "full" } },
|
||||
{ hasJsFileInKps: true, targets: 'androidphone', expected: { android: "full",mobileWeb: "full" } },
|
||||
{ hasJsFileInKps: true, targets: 'iphone', expected: { ios: "full",mobileWeb: "full" } },
|
||||
{ hasJsFileInKps: true, targets: 'linux', expected: { linux: "full",desktopWeb: "full" } },
|
||||
{ hasJsFileInKps: true, targets: 'macosx', expected: { macos: "full",desktopWeb: "full" } },
|
||||
{ hasJsFileInKps: true, targets: 'windows', expected: { windows: "full",desktopWeb: "full" } },
|
||||
{ hasJsFileInKps: true, targets: 'androidphone iphone', expected: { android: "full",ios: "full",mobileWeb: "full" } },
|
||||
];
|
||||
|
||||
platformsTestCases.forEach((testCase, idx) => it(`check run sets platforms correctly (test case #${idx})`, async function() {
|
||||
const kpjFilename = KHMER_ANGKOR_KPJ;
|
||||
const sources = KHMER_ANGKOR_SOURCES;
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
assert.isTrue(await compiler.init(callbacks, {sources}));
|
||||
const kpsFilename = KHMER_ANGKOR_KPS;
|
||||
const kmpCompiler = new KmpCompiler();
|
||||
assert.isTrue(await kmpCompiler.init(callbacks, {}));
|
||||
const kmpJsonData = kmpCompiler.transformKpsToKmpObject(kpsFilename);
|
||||
const kmpJsonData = kmpCompiler.transformKpsToKmpObject(KHMER_ANGKOR_KPS);
|
||||
assert.isNotNull(kmpJsonData);
|
||||
if (!testCase.hasJsFile) {
|
||||
if (!testCase.hasJsFileInKps) {
|
||||
// remove .js file
|
||||
kmpJsonData.files = kmpJsonData.files.filter(file => !KeymanFileTypes.filenameIs(file.name, KeymanFileTypes.Binary.WebKeyboard));
|
||||
}
|
||||
const kmxFiles: {
|
||||
filename: string,
|
||||
data: KMX.KEYBOARD
|
||||
}[] = compiler['loadKmxFiles'](kpsFilename, kmpJsonData);
|
||||
}[] = compiler['loadKmxFiles'](KHMER_ANGKOR_KPS, kmpJsonData);
|
||||
// set targets
|
||||
kmxFiles[0].data.targets = testCase.targets;
|
||||
const origLoadKmxFiles = compiler['loadKmxFiles'];
|
||||
|
|
@ -378,7 +365,7 @@ describe('keyboard-info-compiler', function () {
|
|||
try {
|
||||
KmpCompiler.prototype.transformKpsToKmpObject = (_kpsFilename: string): KmpJsonFile.KmpJsonFile => kmpJsonData;
|
||||
compiler['loadKmxFiles'] = (_kpsFilename: string, _kmpJsonData: KmpJsonFile.KmpJsonFile) => kmxFiles;
|
||||
result = await compiler.run(kpjFilename, null);
|
||||
result = await compiler.run(KHMER_ANGKOR_KPJ, null);
|
||||
} catch(e) {
|
||||
assert.fail(e);
|
||||
} finally {
|
||||
|
|
@ -390,15 +377,43 @@ describe('keyboard-info-compiler', function () {
|
|||
assert.deepEqual(keyboard_info.platformSupport, testCase.expected);
|
||||
}));
|
||||
|
||||
it('check run sets related packages correctly', async function() {
|
||||
const sources = KHMER_ANGKOR_SOURCES;
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
assert.isTrue(await compiler.init(callbacks, {sources}));
|
||||
const kmpCompiler = new KmpCompiler();
|
||||
await kmpCompiler.init(callbacks, {});
|
||||
const kmpJsonData = kmpCompiler.transformKpsToKmpObject(sources.kpsFilename);
|
||||
kmpJsonData.relatedPackages = [
|
||||
{ id: "dep1", relationship: "deprecates" },
|
||||
{ id: "dep2", relationship: "deprecates" },
|
||||
{ id: "rel1", relationship: "related" },
|
||||
];
|
||||
const origKmpCompilerTransformKpsToKmpObject = KmpCompiler.prototype.transformKpsToKmpObject;
|
||||
let result: KeyboardInfoCompilerResult;
|
||||
try {
|
||||
KmpCompiler.prototype.transformKpsToKmpObject = (_kpsFilename: string): KmpJsonFile.KmpJsonFile => kmpJsonData;
|
||||
result = await compiler.run(KHMER_ANGKOR_KPJ, null);
|
||||
} catch(e) {
|
||||
assert.fail(e);
|
||||
} finally {
|
||||
KmpCompiler.prototype.transformKpsToKmpObject = origKmpCompilerTransformKpsToKmpObject;
|
||||
}
|
||||
assert.isNotNull(result);
|
||||
const keyboard_info = JSON.parse(new TextDecoder().decode(result.artifacts.keyboard_info.data));
|
||||
assert.deepEqual(keyboard_info.related['dep1'], {deprecates: true});
|
||||
assert.deepEqual(keyboard_info.related['dep2'], {deprecates: true});
|
||||
assert.deepEqual(keyboard_info.related['rel1'], {deprecates: false});
|
||||
});
|
||||
|
||||
it('should write artifacts to disk', async function() {
|
||||
const kpjFilename = KHMER_ANGKOR_KPJ;
|
||||
const actualFilename = makePathToFixture('khmer_angkor', 'build', 'actual.keyboard_info');
|
||||
const expectedFilename = makePathToFixture('khmer_angkor', 'build', 'khmer_angkor.keyboard_info');
|
||||
const sources = KHMER_ANGKOR_SOURCES;
|
||||
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
assert.isTrue(await compiler.init(callbacks, {sources}));
|
||||
const result = await compiler.run(kpjFilename, null);
|
||||
const result = await compiler.run(KHMER_ANGKOR_KPJ, null);
|
||||
assert.isNotNull(result);
|
||||
|
||||
if(fs.existsSync(actualFilename)) {
|
||||
|
|
@ -459,32 +474,30 @@ describe('keyboard-info-compiler', function () {
|
|||
});
|
||||
|
||||
it('check loadKmxFiles returns empty array if .kmx file is missing from .kmp', async function() {
|
||||
const kpsFilename = KHMER_ANGKOR_KPS;
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
const kmpCompiler = new KmpCompiler();
|
||||
assert.isTrue(await kmpCompiler.init(callbacks, {}));
|
||||
const kmpJsonData = kmpCompiler.transformKpsToKmpObject(kpsFilename);
|
||||
const kmpJsonData = kmpCompiler.transformKpsToKmpObject(KHMER_ANGKOR_KPS);
|
||||
assert.isNotNull(kmpJsonData);
|
||||
// remove .kmx file
|
||||
kmpJsonData.files = kmpJsonData.files.filter(file => !KeymanFileTypes.filenameIs(file.name, KeymanFileTypes.Binary.Keyboard));
|
||||
const kmxFiles: {
|
||||
filename: string,
|
||||
data: KMX.KEYBOARD
|
||||
}[] = compiler['loadKmxFiles'](kpsFilename, kmpJsonData);
|
||||
}[] = compiler['loadKmxFiles'](KHMER_ANGKOR_KPS, kmpJsonData);
|
||||
assert.deepEqual(kmxFiles, []);
|
||||
});
|
||||
|
||||
it('check loadKmxFiles throws error if .kmx file is missing from disk', async function() {
|
||||
const kpsFilename = KHMER_ANGKOR_KPS;
|
||||
const compiler = new KeyboardInfoCompiler();
|
||||
const kmpCompiler = new KmpCompiler();
|
||||
assert.isTrue(await kmpCompiler.init(callbacks, {}));
|
||||
const kmpJsonData = kmpCompiler.transformKpsToKmpObject(kpsFilename);
|
||||
const kmpJsonData = kmpCompiler.transformKpsToKmpObject(KHMER_ANGKOR_KPS);
|
||||
assert.isNotNull(kmpJsonData);
|
||||
// rename .kmx file in files list so it cannot be loaded from disk
|
||||
const kmpIndex = kmpJsonData.files.findIndex(file => KeymanFileTypes.filenameIs(file.name, KeymanFileTypes.Binary.Keyboard));
|
||||
kmpJsonData.files[kmpIndex].name = '../build/throw_error.kmx';
|
||||
assert.throws(() => compiler['loadKmxFiles'](kpsFilename, kmpJsonData));
|
||||
assert.throws(() => compiler['loadKmxFiles'](KHMER_ANGKOR_KPS, kmpJsonData));
|
||||
});
|
||||
|
||||
it('check loadKmxFiles can handle two .kmx files', async function() {
|
||||
|
|
|
|||
|
|
@ -269,11 +269,21 @@ export class KmpCompiler implements KeymanCompiler {
|
|||
kmp.files = this.arrayWrap(kps.Files.File).map((file: KpsFile.KpsFileContentFile) => {
|
||||
return {
|
||||
name: this.normalizePath(file.Name),
|
||||
description: file.Description.trim(),
|
||||
description: (file.Description ?? '').trim(),
|
||||
copyLocation: parseInt(file.CopyLocation, 10) || undefined
|
||||
// note: we don't emit fileType as that is not permitted in kmp.json
|
||||
};
|
||||
});
|
||||
if(!kmp.files.reduce((result: boolean, file) => {
|
||||
if(!file.name) {
|
||||
// as the filename field is missing or blank, we'll try with the description instead
|
||||
this.callbacks.reportMessage(CompilerMessages.Error_FileRecordIsMissingName({description: file.description ?? '(no description)'}));
|
||||
return false;
|
||||
}
|
||||
return result;
|
||||
}, true)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
kmp.files = kmp.files ?? [];
|
||||
|
||||
|
|
|
|||
|
|
@ -130,5 +130,9 @@ export class CompilerMessages {
|
|||
static ERROR_InvalidPackageFile = SevError | 0x001E;
|
||||
static Error_InvalidPackageFile = (o:{e:any}) => m(this.ERROR_InvalidPackageFile,
|
||||
`Package source file is invalid: ${(o.e ?? 'unknown error').toString()}`);
|
||||
|
||||
static ERROR_FileRecordIsMissingName = SevError | 0x001F;
|
||||
static Error_FileRecordIsMissingName = (o:{description:string}) => m(this.ERROR_FileRecordIsMissingName,
|
||||
`File record in the package with description '${o.description}' is missing a filename.`);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ export class PackageKeyboardTargetValidator {
|
|||
// package also includes the .js
|
||||
const targets = KeymanTargets.keymanTargetsFromString(targetsText, {expandTargets: true});
|
||||
if(targets.some(target => KeymanTargets.TouchKeymanTargets.includes(target))) {
|
||||
if(!kmp.files.find(file => this.callbacks.path.basename(file.name, '.js') == keyboard.id)) {
|
||||
if(!kmp.files.find(file => this.callbacks.path.basename(file.name ?? '', '.js') == keyboard.id)) {
|
||||
// .js version of the keyboard is not found, warn
|
||||
this.callbacks.reportMessage(CompilerMessages.Warn_JsKeyboardFileIsMissing({id: keyboard.id}));
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -40,16 +40,21 @@ export class PackageMetadataCollector {
|
|||
): KeyboardMetadata {
|
||||
|
||||
let isJavascript = false;
|
||||
let file = kmp.files.find(file => this.callbacks.path.basename(file.name, KeymanFileTypes.Binary.Keyboard) == keyboard.id);
|
||||
let file = kmp.files.find(file => this.callbacks.path.basename(file.name ?? '', KeymanFileTypes.Binary.Keyboard) == keyboard.id);
|
||||
if(!file) {
|
||||
isJavascript = true;
|
||||
file = kmp.files.find(file => this.callbacks.path.basename(file.name, KeymanFileTypes.Binary.WebKeyboard) == keyboard.id);
|
||||
file = kmp.files.find(file => this.callbacks.path.basename(file.name ?? '', KeymanFileTypes.Binary.WebKeyboard) == keyboard.id);
|
||||
if(!file) {
|
||||
this.callbacks.reportMessage(CompilerMessages.Error_KeyboardContentFileNotFound({id:keyboard.id}));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if(!file.name) {
|
||||
this.callbacks.reportMessage(CompilerMessages.Error_FileRecordIsMissingName({description: file.description ?? '(no description)'}));
|
||||
return null;
|
||||
}
|
||||
|
||||
const filename = this.callbacks.resolveFilename(kpsFilename, file.name);
|
||||
if(!this.callbacks.fs.existsSync(filename)) {
|
||||
this.callbacks.reportMessage(CompilerMessages.Error_KeyboardFileNotFound({filename}));
|
||||
|
|
|
|||
|
|
@ -1060,7 +1060,7 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE
|
|||
u16ncpy(q, pp2, u16len(pp2) + 1);
|
||||
|
||||
// Change compiled reference file extension to .kvk
|
||||
pp2 = ( km_core_cp *) u16chr(q, 0) - 5;
|
||||
pp2 = ( km_core_cu *) u16chr(q, 0) - 5;
|
||||
if (pp2 > q && u16icmp(pp2, u".kvks") == 0) {
|
||||
pp2[4] = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
lastContent = ta1.value;
|
||||
}
|
||||
|
||||
var lastSelStart = -1;
|
||||
var lastSelStart = -1, lastSelLength = -1;
|
||||
|
||||
function calculateLengthByCodepoint(text, base, x) {
|
||||
var stop = base + x;
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ build: version.res manifest.res icons dirs xml xsd pull-core
|
|||
$(COPY) kmlmc.cmd $(DEVELOPER_PROGRAM)
|
||||
$(COPY) kmlmp.cmd $(DEVELOPER_PROGRAM)
|
||||
$(COPY) kmc.cmd $(DEVELOPER_PROGRAM)
|
||||
$(COPY) $(KEYMAN_ROOT)\core\build\x86\$(TARGET_PATH)\src\keymancore-1.dll $(DEVELOPER_PROGRAM)
|
||||
$(COPY) $(KEYMAN_ROOT)\core\build\x86\$(TARGET_PATH)\src\$(KEYMANCORE).dll $(DEVELOPER_PROGRAM)
|
||||
if exist $(WIN32_TARGET_PATH)\tike.dbg $(COPY) $(WIN32_TARGET_PATH)\tike.dbg $(DEVELOPER_DEBUGPATH)
|
||||
$(COPY) $(KEYMAN_ROOT)\core\build\x86\$(TARGET_PATH)\src\keymancore-1.dll $(WIN32_TARGET_PATH)
|
||||
$(COPY) $(KEYMAN_ROOT)\core\build\x86\$(TARGET_PATH)\src\keymancore-1.pdb $(WIN32_TARGET_PATH)
|
||||
$(COPY) $(KEYMAN_ROOT)\core\build\x86\$(TARGET_PATH)\src\$(KEYMANCORE).dll $(WIN32_TARGET_PATH)
|
||||
$(COPY) $(KEYMAN_ROOT)\core\build\x86\$(TARGET_PATH)\src\$(KEYMANCORE).pdb $(WIN32_TARGET_PATH)
|
||||
|
||||
xsd:
|
||||
$(COPY) $(KEYMAN_ROOT)\common\schemas\kps\kps.xsd $(DEVELOPER_PROGRAM)
|
||||
|
|
@ -69,7 +69,7 @@ clean: def-clean
|
|||
|
||||
signcode:
|
||||
$(SIGNCODE) /d "Keyman Developer" $(DEVELOPER_PROGRAM)\tike.exe
|
||||
$(SIGNCODE) /d "Keyman Core" $(DEVELOPER_PROGRAM)\keymancore-1.dll
|
||||
$(SIGNCODE) /d "Keyman Core" $(DEVELOPER_PROGRAM)\$(KEYMANCORE).dll
|
||||
# Sign the Sentry executables and libraries here
|
||||
$(SIGNCODE) /d "Keyman Developer" $(DEVELOPER_PROGRAM)\sentry.dll
|
||||
$(SIGNCODE) /d "Keyman Developer" $(DEVELOPER_PROGRAM)\sentry.x64.dll
|
||||
|
|
@ -81,7 +81,7 @@ wrap-symbols:
|
|||
|
||||
install:
|
||||
$(COPY) $(DEVELOPER_PROGRAM)\tike.exe "$(INSTALLPATH_KEYMANDEVELOPER)\tike.exe"
|
||||
$(COPY) $(DEVELOPER_PROGRAM)\keymancore-1.dll "$(INSTALLPATH_KEYMANDEVELOPER)\keymancore-1.dll"
|
||||
$(COPY) $(DEVELOPER_PROGRAM)\$(KEYMANCORE).dll "$(INSTALLPATH_KEYMANDEVELOPER)\$(KEYMANCORE).dll"
|
||||
|
||||
test-manifest:
|
||||
# test that linked manifest exists and correct
|
||||
|
|
|
|||
|
|
@ -98,13 +98,13 @@ end;
|
|||
|
||||
function TDebugCore.GetKMXPlatform: string;
|
||||
var
|
||||
p: pkm_core_cp;
|
||||
p: pkm_core_cu;
|
||||
status: km_core_status;
|
||||
begin
|
||||
status := km_core_state_option_lookup(
|
||||
FState,
|
||||
KM_CORE_OPT_ENVIRONMENT,
|
||||
pkm_core_cp(PWideChar(KM_CORE_KMX_ENV_PLATFORM)),
|
||||
pkm_core_cu(PWideChar(KM_CORE_KMX_ENV_PLATFORM)),
|
||||
p
|
||||
);
|
||||
if status <> KM_CORE_STATUS_OK then
|
||||
|
|
@ -117,8 +117,8 @@ var
|
|||
options: array[0..1] of km_core_option_item;
|
||||
status: km_core_status;
|
||||
begin
|
||||
options[0].key := pkm_core_cp(PWideChar(KM_CORE_KMX_ENV_PLATFORM));
|
||||
options[0].value := pkm_core_cp(PWideChar(Value));
|
||||
options[0].key := pkm_core_cu(PWideChar(KM_CORE_KMX_ENV_PLATFORM));
|
||||
options[0].value := pkm_core_cu(PWideChar(Value));
|
||||
options[0].scope := KM_CORE_OPT_ENVIRONMENT;
|
||||
options[1] := KM_CORE_OPTIONS_END;
|
||||
status := km_core_state_options_update(FState, @options[0]);
|
||||
|
|
@ -128,13 +128,13 @@ end;
|
|||
|
||||
function TDebugCore.GetOption(const name: string): string;
|
||||
var
|
||||
p: pkm_core_cp;
|
||||
p: pkm_core_cu;
|
||||
status: km_core_status;
|
||||
begin
|
||||
status := km_core_state_option_lookup(
|
||||
FState,
|
||||
KM_CORE_OPT_KEYBOARD,
|
||||
pkm_core_cp(PWideChar(name)),
|
||||
pkm_core_cu(PWideChar(name)),
|
||||
p
|
||||
);
|
||||
if status <> KM_CORE_STATUS_OK then
|
||||
|
|
@ -147,8 +147,8 @@ var
|
|||
options: array[0..1] of km_core_option_item;
|
||||
status: km_core_status;
|
||||
begin
|
||||
options[0].key := pkm_core_cp(PWideChar(Name));
|
||||
options[0].value := pkm_core_cp(PWideChar(Value));
|
||||
options[0].key := pkm_core_cu(PWideChar(Name));
|
||||
options[0].value := pkm_core_cu(PWideChar(Value));
|
||||
options[0].scope := KM_CORE_OPT_KEYBOARD;
|
||||
options[1] := KM_CORE_OPTIONS_END;
|
||||
status := km_core_state_options_update(FState, @options[0]);
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ type
|
|||
|
||||
km_core_usv = uint32_t; // UTF-32
|
||||
pkm_core_usv = ^km_core_usv;
|
||||
km_core_cp = WideChar;
|
||||
pkm_core_cp = ^km_core_cp;
|
||||
km_core_cu = WideChar;
|
||||
pkm_core_cu = ^km_core_cu;
|
||||
|
||||
km_core_context = record end;
|
||||
pkm_core_context = ^km_core_context;
|
||||
|
|
@ -81,7 +81,7 @@ const
|
|||
);
|
||||
|
||||
const
|
||||
keymancore = 'keymancore-1.dll';
|
||||
keymancore = 'keymancore-2.dll';
|
||||
|
||||
procedure km_core_context_items_dispose(
|
||||
context_items: pkm_core_context_item
|
||||
|
|
@ -114,8 +114,8 @@ type
|
|||
);
|
||||
|
||||
km_core_option_item = record
|
||||
key: pkm_core_cp;
|
||||
value: pkm_core_cp;
|
||||
key: pkm_core_cu;
|
||||
value: pkm_core_cu;
|
||||
scope: km_core_option_scope;
|
||||
end;
|
||||
|
||||
|
|
@ -220,8 +220,8 @@ function km_core_options_list_size(
|
|||
function km_core_state_option_lookup(
|
||||
state: pkm_core_state;
|
||||
scope: km_core_option_scope;
|
||||
key: pkm_core_cp;
|
||||
var value: pkm_core_cp
|
||||
key: pkm_core_cu;
|
||||
var value: pkm_core_cu
|
||||
): km_core_status; cdecl; external keymancore delayed;
|
||||
|
||||
function km_core_state_options_update(
|
||||
|
|
@ -237,8 +237,8 @@ function km_core_state_options_to_json(
|
|||
|
||||
type
|
||||
km_core_keyboard_attrs = record
|
||||
version_string: pkm_core_cp;
|
||||
id: pkm_core_cp;
|
||||
version_string: pkm_core_cu;
|
||||
id: pkm_core_cu;
|
||||
folder_path: km_core_path_name;
|
||||
default_optons: pkm_core_option_item
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ uses
|
|||
{$ALIGN 8}
|
||||
|
||||
///
|
||||
/// The maximum size of context in km_core_cp units for a single debug
|
||||
/// The maximum size of context in km_core_cu 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.
|
||||
///
|
||||
|
|
@ -54,7 +54,7 @@ pkm_core_state_debug_key_info = ^km_core_state_debug_key_info;
|
|||
|
||||
km_core_state_debug_kmx_option_info = record
|
||||
store: Pointer; // LPSTORE
|
||||
value: array[0..DEBUG_MAX_CONTEXT-1] of km_core_cp; // value to be saved into the store
|
||||
value: array[0..DEBUG_MAX_CONTEXT-1] of km_core_cu; // value to be saved into the store
|
||||
end;
|
||||
|
||||
pkm_core_state_debug_kmx_option_info = ^km_core_state_debug_kmx_option_info;
|
||||
|
|
@ -71,7 +71,7 @@ pkm_core_state_debug_kmx_option_info = ^km_core_state_debug_kmx_option_info;
|
|||
///
|
||||
|
||||
km_core_state_debug_kmx_info = record
|
||||
context: array [0..DEBUG_MAX_CONTEXT-1] of km_core_cp; // The context matched by the rule (? may not need this?) // TODO: rename to context_matched
|
||||
context: array [0..DEBUG_MAX_CONTEXT-1] of km_core_cu; // The context matched by the rule (? may not need this?) // TODO: rename to context_matched
|
||||
group: Pointer; // LPGROUP
|
||||
rule: Pointer; // LPKEY
|
||||
store_offsets: array [0..DEBUG_STORE_OFFSETS_SIZE-1] of uint16_t; // pairs--store, char position, terminated by 0xFFFF // TODO use a better structure here
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ work particularly well with C++, so it might flag some C++ symbols even though
|
|||
they aren't part of the API. This happens particularly with C++ template
|
||||
instantiations.
|
||||
|
||||
To work around this, we list the C++ symbols as `optional` that get flaged:
|
||||
To work around this, we list the C++ symbols as `optional` that get flagged:
|
||||
|
||||
```
|
||||
(c++|optional)"typeinfo name for std::codecvt_utf8_utf16<char16_t, 1114111ul, (std::codecvt_mode)0>@Base" 17.0.244
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ Architecture: amd64 arm64 armel armhf i386 loong64 mipsel mips64el ppc64el riscv
|
|||
Section: libdevel
|
||||
Depends:
|
||||
libicu-dev,
|
||||
libkeymancore1 (= ${binary:Version}),
|
||||
libkeymancore2 (= ${binary:Version}),
|
||||
${misc:Depends},
|
||||
Conflicts: libkmnkbp-dev
|
||||
Replaces: libkmnkbp-dev
|
||||
|
|
@ -138,7 +138,7 @@ Description: Development files for Keyman keyboard processing library
|
|||
.
|
||||
This package contains development headers and libraries.
|
||||
|
||||
Package: libkeymancore1
|
||||
Package: libkeymancore2
|
||||
Architecture: amd64 arm64 armel armhf i386 loong64 mipsel mips64el ppc64el riscv64
|
||||
Section: libs
|
||||
Pre-Depends:
|
||||
|
|
@ -148,8 +148,8 @@ Depends:
|
|||
${shlibs:Depends},
|
||||
Suggests:
|
||||
keyman,
|
||||
Conflicts: libkmnkbp0-0, libkeymancore
|
||||
Replaces: libkmnkbp0-0, libkeymancore
|
||||
Conflicts: libkmnkbp0-0, libkeymancore, libkeymancore1
|
||||
Replaces: libkmnkbp0-0, libkeymancore, libkeymancore1
|
||||
Multi-Arch: same
|
||||
Description: Keyman keyboard processing library
|
||||
Originally created in 1993 to type Lao on Windows, Keyman is now a free and
|
||||
|
|
@ -170,7 +170,7 @@ Package: ibus-keyman
|
|||
Architecture: amd64 arm64 armel armhf i386 loong64 mipsel mips64el ppc64el riscv64
|
||||
Depends:
|
||||
ibus (>= 1.3.7),
|
||||
libkeymancore1 (= ${binary:Version}),
|
||||
libkeymancore2 (= ${binary:Version}),
|
||||
keyman-system-service (= ${binary:Version}),
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
libkeymancore.so.1 libkeymancore1 #MINVER#
|
||||
libkeymancore.so.2 libkeymancore2 #MINVER#
|
||||
* Build-Depends-Package: libkeymancore-dev
|
||||
|
||||
(c++|optional)"typeinfo name for std::codecvt_utf8_utf16<char16_t, 1114111ul, (std::codecvt_mode)0>@Base" 17.0.244
|
||||
|
|
@ -8,7 +8,7 @@ libkeymancore.so.1 libkeymancore1 #MINVER#
|
|||
km_core_context_items_dispose@Base 17.0.195
|
||||
km_core_context_length@Base 17.0.195
|
||||
km_core_context_set@Base 17.0.195
|
||||
km_core_cp_dispose@Base 17.0.263
|
||||
km_core_cu_dispose@Base 18.0.31
|
||||
km_core_event@Base 17.0.195
|
||||
km_core_get_engine_attrs@Base 17.0.195
|
||||
km_core_keyboard_dispose@Base 17.0.195
|
||||
|
|
@ -219,9 +219,9 @@ static gchar *
|
|||
get_context_debug(IBusEngine *engine) {
|
||||
IBusKeymanEngine *keyman = (IBusKeymanEngine *)engine;
|
||||
|
||||
km_core_cp *buf = km_core_state_context_debug(keyman->state, KM_CORE_DEBUG_CONTEXT_CACHED);
|
||||
km_core_cu *buf = km_core_state_context_debug(keyman->state, KM_CORE_DEBUG_CONTEXT_CACHED);
|
||||
gchar *result = g_utf16_to_utf8((gunichar2 *)buf, -1, NULL, NULL, NULL);
|
||||
km_core_cp_dispose(buf);
|
||||
km_core_cu_dispose(buf);
|
||||
if(result) {
|
||||
return result;
|
||||
}
|
||||
|
|
@ -292,7 +292,7 @@ set_context_if_needed(IBusEngine *engine) {
|
|||
g_message("%s: new application context: |%s| (len:%u) cursor:%d anchor:%d", __FUNCTION__,
|
||||
application_context_utf8, context_end - context_start, cursor_pos, anchor_pos);
|
||||
|
||||
km_core_cp *application_context_utf16 = g_utf8_to_utf16(application_context_utf8, -1, NULL, NULL, NULL);
|
||||
km_core_cu *application_context_utf16 = g_utf8_to_utf16(application_context_utf8, -1, NULL, NULL, NULL);
|
||||
km_core_context_status result;
|
||||
result = km_core_state_context_set_if_needed(keyman->state, application_context_utf16);
|
||||
g_free(application_context_utf16);
|
||||
|
|
@ -326,7 +326,7 @@ ibus_keyman_engine_init(IBusKeymanEngine *keyman) {
|
|||
keyman->state = NULL;
|
||||
}
|
||||
|
||||
static km_core_cp* get_base_layout()
|
||||
static km_core_cu* get_base_layout()
|
||||
{
|
||||
return u"en-US";
|
||||
|
||||
|
|
@ -354,7 +354,7 @@ static km_core_cp* get_base_layout()
|
|||
lang = strdup("en-US");
|
||||
}
|
||||
g_message("lang is %s", lang);
|
||||
km_core_cp *cp = g_utf8_to_utf16(lang, -1, NULL, NULL, NULL);
|
||||
km_core_cu *cp = g_utf8_to_utf16(lang, -1, NULL, NULL, NULL);
|
||||
return cp;
|
||||
// g_free(lang);
|
||||
#endif
|
||||
|
|
@ -395,8 +395,8 @@ free_km_core_option_item(gpointer data) {
|
|||
return;
|
||||
|
||||
km_core_option_item *opt = (km_core_option_item *)data;
|
||||
g_free((km_core_cp *)opt->key);
|
||||
g_free((km_core_cp *)opt->value);
|
||||
g_free((km_core_cu *)opt->key);
|
||||
g_free((km_core_cu *)opt->value);
|
||||
g_free(opt);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -487,7 +487,7 @@ keyman_get_options_queue_fromdconf(gchar *package_id,
|
|||
g_message("Keyboard Option [%d], %s=%s", index, option_tokens[0], option_tokens[1]);
|
||||
km_core_option_item *opt = g_new0(km_core_option_item, 1);
|
||||
opt[0].scope = KM_CORE_OPT_KEYBOARD;
|
||||
km_core_cp *ocp = g_utf8_to_utf16(option_tokens[0], -1, NULL, NULL, NULL);
|
||||
km_core_cu *ocp = g_utf8_to_utf16(option_tokens[0], -1, NULL, NULL, NULL);
|
||||
opt[0].key = ocp;
|
||||
ocp = g_utf8_to_utf16 (option_tokens[1], -1, NULL, NULL, NULL);
|
||||
opt[0].value = ocp;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#import "AppDelegate.h"
|
||||
#import <KeymanEngine4Mac/KeymanEngine4Mac.h>
|
||||
#import <os/log.h>
|
||||
|
||||
static BOOL debugMode = YES;
|
||||
|
||||
|
|
@ -67,7 +68,9 @@ NSString *const kKMXFileKey = @"KMXFile";
|
|||
}
|
||||
|
||||
- (void)windowDidResize:(NSNotification *)notification {
|
||||
[self.oskView resizeOSKLayout];
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "AppDelegate windowDidResize");
|
||||
[self.oskView resizeOSKLayout];
|
||||
}
|
||||
|
||||
- (BOOL)createEventTap {
|
||||
|
|
@ -205,7 +208,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
|
|||
[alert addButtonWithTitle:@"OK"];
|
||||
[alert setMessageText:@"Invalid KMX file"];
|
||||
[alert setInformativeText:@"This KMX file contains some invalid code!"];
|
||||
[alert setAlertStyle:NSWarningAlertStyle];
|
||||
[alert setAlertStyle:NSAlertStyleWarning];
|
||||
[alert runModal];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
@implementation KMBarView
|
||||
|
||||
- (void)drawRect:(NSRect)rect {
|
||||
CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
|
||||
CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] CGContext];
|
||||
|
||||
NSRect rect1 = NSMakeRect(0, 0, rect.size.width*0.56, rect.size.height);
|
||||
NSRect rect2 = NSMakeRect(rect1.size.width, 0, rect.size.width*0.23, rect.size.height);
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@
|
|||
// NSLog(@"topFill origin x %f y %f size h %f w %f after raising to imgHeight %ld", topFill.origin.x, topFill.origin.y, topFill.size.height, topFill.size.width, imgOriginHeightDelta);
|
||||
// NSLog(@"botFill origin x %f y %f size h %f w %f after reducing by imgHeight %ld", botFill.origin.x, botFill.origin.y, botFill.size.height, botFill.size.width, imgOriginHeightDelta);
|
||||
[[NSColor whiteColor] setFill];
|
||||
NSRectFillUsingOperation(topFill, NSCompositeSourceOver);
|
||||
NSRectFillUsingOperation(topFill, NSCompositingOperationSourceOver);
|
||||
[[NSColor windowBackgroundColor] setFill];
|
||||
NSRectFillUsingOperation(botFill, NSCompositeSourceOver);
|
||||
NSRectFillUsingOperation(botFill, NSCompositingOperationSourceOver);
|
||||
}
|
||||
|
||||
- (BOOL)mouseDownCanMoveWindow {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
@implementation KMBarView
|
||||
|
||||
- (void)drawRect:(NSRect)rect {
|
||||
CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
|
||||
CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] CGContext];
|
||||
|
||||
NSRect rect1 = NSMakeRect(0, 0, rect.size.width*0.56, rect.size.height);
|
||||
NSRect rect2 = NSMakeRect(rect1.size.width, 0, rect.size.width*0.23, rect.size.height);
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@
|
|||
[textField setEditable:NO];
|
||||
[textField setBordered:NO];
|
||||
[textField setBackgroundColor:[NSColor clearColor]];
|
||||
[textField setAlignment:NSLeftTextAlignment];
|
||||
[textField setAlignment:NSTextAlignmentLeft];
|
||||
[textField setFont:[NSFont systemFontOfSize:tableView.rowHeight*0.5]];
|
||||
[textField setTextColor:[NSColor colorWithSRGBRed:0.0 green:0.0 blue:0.1 alpha:1.0]];
|
||||
[textField setStringValue:[info objectForKey:@"HeaderTitle"]];
|
||||
|
|
@ -471,7 +471,7 @@
|
|||
[failure setMessageText:[NSString localizedStringWithFormat:errorString, kmpFile.lastPathComponent]];
|
||||
|
||||
[failure setIcon:[[NSBundle mainBundle] imageForResource:@"logo.png"]];
|
||||
[failure setAlertStyle:NSWarningAlertStyle];
|
||||
[failure setAlertStyle:NSAlertStyleWarning];
|
||||
[failure beginSheetModalForWindow:self.window
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
|
||||
|
|
@ -534,7 +534,7 @@
|
|||
[_deleteAlertView setInformativeText:NSLocalizedString(@"info-cannot-undo-delete-keyboard", nil)];
|
||||
[_deleteAlertView addButtonWithTitle:NSLocalizedString(@"button-delete-keyboard", nil)];
|
||||
[_deleteAlertView addButtonWithTitle:NSLocalizedString(@"button-cancel-delete-keyboard", nil)];
|
||||
[_deleteAlertView setAlertStyle:NSWarningAlertStyle];
|
||||
[_deleteAlertView setAlertStyle:NSAlertStyleWarning];
|
||||
[_deleteAlertView setIcon:[[NSBundle mainBundle] imageForResource:@"logo.png"]];
|
||||
}
|
||||
|
||||
|
|
@ -547,7 +547,7 @@
|
|||
[_confirmKmpInstallAlertView addButtonWithTitle:NSLocalizedString(@"button-install-keyboard", nil)];
|
||||
[_confirmKmpInstallAlertView addButtonWithTitle:NSLocalizedString(@"button-cancel-install-keyboard", nil)];
|
||||
[_confirmKmpInstallAlertView setMessageText:NSLocalizedString(@"message-confirm-install-keyboard", nil)];
|
||||
[_confirmKmpInstallAlertView setAlertStyle:NSInformationalAlertStyle];
|
||||
[_confirmKmpInstallAlertView setAlertStyle:NSAlertStyleInformational];
|
||||
[_confirmKmpInstallAlertView setIcon:[[NSBundle mainBundle] imageForResource:@"logo.png"]];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -224,12 +224,7 @@ NSString* _keymanDataPath = nil;
|
|||
_downloadFilename = [NSString stringWithString:[value substringFromIndex:index+9]];
|
||||
else if ((index = [value rangeOfString:@"url="].location) != NSNotFound) {
|
||||
NSString *urlString = [NSString stringWithString:[value substringFromIndex:index+4]];
|
||||
if ([urlString respondsToSelector:@selector(stringByRemovingPercentEncoding)])
|
||||
urlString = [urlString stringByRemovingPercentEncoding];
|
||||
else if ([urlString respondsToSelector:@selector(stringByReplacingPercentEscapesUsingEncoding:)]) {
|
||||
// OS version prior to 10.9 - use this (now deprecated) method instead:
|
||||
urlString = [urlString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
urlString = [urlString stringByRemovingPercentEncoding];
|
||||
downloadUrl = [NSURL URLWithString:urlString];
|
||||
}
|
||||
}
|
||||
|
|
@ -1161,7 +1156,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
|
|||
[_downloadInfoView setMessageText:NSLocalizedString(@"message-keyboard-downloading", nil)];
|
||||
[_downloadInfoView setInformativeText:@""];
|
||||
[_downloadInfoView addButtonWithTitle:NSLocalizedString(@"button-cancel-downloading", nil)];
|
||||
[_downloadInfoView setAlertStyle:NSInformationalAlertStyle];
|
||||
[_downloadInfoView setAlertStyle:NSAlertStyleInformational];
|
||||
[_downloadInfoView setAccessoryView:self.progressIndicator];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ NSString* const kEasterEggKmxName = @"EnglishSpanish.kmx";
|
|||
- (CoreKeyOutput*) processEventWithKeymanEngine:(NSEvent *)event in:(id) sender {
|
||||
CoreKeyOutput* coreKeyOutput = nil;
|
||||
if (self.appDelegate.lowLevelEventTap != nil) {
|
||||
NSEvent *eventWithOriginalModifierFlags = [NSEvent keyEventWithType:event.type location:event.locationInWindow modifierFlags:self.appDelegate.currentModifierFlags timestamp:event.timestamp windowNumber:event.windowNumber context:event.context characters:event.characters charactersIgnoringModifiers:event.charactersIgnoringModifiers isARepeat:event.isARepeat keyCode:event.keyCode];
|
||||
NSEvent *eventWithOriginalModifierFlags = [NSEvent keyEventWithType:event.type location:event.locationInWindow modifierFlags:self.appDelegate.currentModifierFlags timestamp:event.timestamp windowNumber:event.windowNumber context:[NSGraphicsContext currentContext] characters:event.characters charactersIgnoringModifiers:event.charactersIgnoringModifiers isARepeat:event.isARepeat keyCode:event.keyCode];
|
||||
coreKeyOutput = [self.kme processEvent:eventWithOriginalModifierFlags];
|
||||
[self.appDelegate logDebugMessage:@"processEventWithKeymanEngine, using AppDelegate.currentModifierFlags %lu, instead of event.modifiers = %lu", (unsigned long)self.appDelegate.currentModifierFlags, (unsigned long)event.modifierFlags];
|
||||
}
|
||||
|
|
@ -223,7 +223,7 @@ NSString* const kEasterEggKmxName = @"EnglishSpanish.kmx";
|
|||
// mouse movement requires that the context be invalidated
|
||||
[self handleContextChangedByLowLevelEvent];
|
||||
|
||||
if (event.type == NSKeyDown) {
|
||||
if (event.type == NSEventTypeKeyDown) {
|
||||
// indicates that our generated backspace event(s) are consumed
|
||||
// and we can insert text that followed the backspace(s)
|
||||
if (event.keyCode == kKeymanEventKeyCode) {
|
||||
|
|
@ -253,7 +253,7 @@ NSString* const kEasterEggKmxName = @"EnglishSpanish.kmx";
|
|||
return NO; // let the client app handle all Command-key events.
|
||||
}
|
||||
|
||||
if (event.type == NSKeyDown) {
|
||||
if (event.type == NSEventTypeKeyDown) {
|
||||
[self reportContext:event forClient:sender];
|
||||
handled = [self handleEventWithKeymanEngine:event in: sender];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,14 +69,13 @@ const CGKeyCode kKeymanEventKeyCode = 0xFF;
|
|||
NSRunningApplication *app = NSWorkspace.sharedWorkspace.frontmostApplication;
|
||||
pid_t processId = app.processIdentifier;
|
||||
NSString *bundleId = app.bundleIdentifier;
|
||||
GetProcessForPID(processId, &psn);
|
||||
|
||||
[self.appDelegate logDebugMessage:@"sendKeymanKeyCodeForEvent keyCode %lu to app %@ with pid %d", (unsigned long)kKeymanEventKeyCode, bundleId, processId];
|
||||
|
||||
// use nil as source, as this generated event is not directly tied to the originating event
|
||||
CGEventRef keyDownEvent = CGEventCreateKeyboardEvent(nil, kKeymanEventKeyCode, true);
|
||||
|
||||
CGEventPostToPSN(&psn, keyDownEvent);
|
||||
CGEventPostToPid(processId, keyDownEvent);
|
||||
CFRelease(keyDownEvent);
|
||||
|
||||
// this is not a real keycode, so we do not need a key up event
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#import "OSKWindowController.h"
|
||||
#import "KMInputMethodAppDelegate.h"
|
||||
#import <os/log.h>
|
||||
|
||||
@interface OSKWindowController ()
|
||||
@property (nonatomic, strong) NSButton *helpButton;
|
||||
|
|
@ -29,6 +30,8 @@
|
|||
}
|
||||
|
||||
- (void)awakeFromNib {
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKWC awakeFromNib");
|
||||
// Keep the aspect ratio constant at its current value
|
||||
[self.window setAspectRatio:self.window.frame.size];
|
||||
NSSize size = self.window.frame.size;
|
||||
|
|
@ -43,7 +46,7 @@
|
|||
_helpButton = helpBtn;
|
||||
[_helpButton setTitle:@""];
|
||||
[_helpButton setBezelStyle:NSHelpButtonBezelStyle];
|
||||
[_helpButton setControlSize:NSMiniControlSize];
|
||||
[_helpButton setControlSize:NSControlSizeMini];
|
||||
[_helpButton setAction:@selector(helpAction:)];
|
||||
[_helpButton setEnabled:[self hasHelpDocumentation]];
|
||||
[self.window addViewToTitleBar:_helpButton positionX:NSWidth(self.window.frame) - NSWidth(_helpButton.frame) -10];
|
||||
|
|
@ -51,6 +54,8 @@
|
|||
}
|
||||
|
||||
- (void)windowDidLoad {
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKWC windowDidLoad");
|
||||
[super windowDidLoad];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:self.window];
|
||||
[self.oskView setKvk:[self.AppDelegate kvk]];
|
||||
|
|
@ -59,6 +64,8 @@
|
|||
}
|
||||
|
||||
- (void)windowDidResize:(NSNotification *)notification {
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKWC windowDidResize");
|
||||
[self.oskView resizeOSKLayout];
|
||||
}
|
||||
|
||||
|
|
@ -80,6 +87,8 @@
|
|||
}
|
||||
|
||||
- (void)resetOSK {
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKWC windowDidLoad");
|
||||
[self.oskView setKvk:[self.AppDelegate kvk]];
|
||||
[self.oskView resetOSK];
|
||||
if (_helpButton) {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9059" systemVersion="14F27" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9059"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22689"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="OSKWindowController">
|
||||
|
|
@ -13,16 +14,16 @@
|
|||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="Keyman" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||
<window title="Keyman" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="614" height="212"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1057"/>
|
||||
<view key="contentView" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="1" width="614" height="212"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
|
||||
<view key="contentView" clipsToBounds="YES" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="614" height="212"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="UaK-0H-MfR" customClass="OSKView">
|
||||
<customView clipsToBounds="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UaK-0H-MfR" customClass="OSKView">
|
||||
<rect key="frame" x="5" y="5" width="604" height="202"/>
|
||||
</customView>
|
||||
</subviews>
|
||||
|
|
|
|||
|
|
@ -8,16 +8,23 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <InputMethodKit/InputMethodKit.h>
|
||||
#import <os/log.h>
|
||||
|
||||
const NSString *kConnectionName = @"Keyman_Input_Connection";
|
||||
IMKServer *server;
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
NSString *identifier;
|
||||
os_log_t configLog = os_log_create("org.sil.keyman", "startup");
|
||||
|
||||
@autoreleasepool {
|
||||
identifier = [[NSBundle mainBundle] bundleIdentifier];
|
||||
server = [[IMKServer alloc] initWithName:(NSString *)kConnectionName bundleIdentifier:identifier];
|
||||
[NSBundle loadNibNamed:@"MainMenu" owner:[NSApplication sharedApplication]];
|
||||
|
||||
BOOL didLoadNib = [[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:[NSApplication sharedApplication] topLevelObjects: nil];
|
||||
|
||||
os_log_with_type(configLog, OS_LOG_TYPE_DEBUG, "main Did load MainMenu nib: %@", didLoadNib?@"YES":@"NO");
|
||||
|
||||
[[NSApplication sharedApplication] run];
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
-(NSString *)description
|
||||
{
|
||||
NSString* str = @"teststring";
|
||||
NSData* data = [self.textToInsert dataUsingEncoding:NSUTF16LittleEndianStringEncoding];
|
||||
|
||||
return [[NSString alloc] initWithFormat: @"codePointsToDeleteBeforeInsert: %li, textToInsert: '%@', optionsToPersist: %@, alert: %d, emitKeystroke: %d, capsLockState: %d ", self.codePointsToDeleteBeforeInsert, data, self.optionsToPersist, self.alert, self.emitKeystroke, self.capsLockState];
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ const int CORE_ENVIRONMENT_ARRAY_LENGTH = 6;
|
|||
NSString* deletedText = [self.coreHelper utf32CStringToString:actions->deleted_context];
|
||||
|
||||
CoreKeyOutput* coreKeyOutput = [[CoreKeyOutput alloc] init: actions->code_points_to_delete textToDelete:deletedText textToInsert:text optionsToPersist:options alert:actions->do_alert emitKeystroke:actions->emit_keystroke capsLockState:capsLock];
|
||||
|
||||
|
||||
return coreKeyOutput;
|
||||
}
|
||||
|
||||
|
|
@ -235,9 +235,9 @@ const int CORE_ENVIRONMENT_ARRAY_LENGTH = 6;
|
|||
}
|
||||
|
||||
-(NSString*)contextDebug {
|
||||
km_core_cp * context = km_core_state_context_debug(self.coreState, KM_CORE_DEBUG_CONTEXT_CACHED);
|
||||
km_core_cu * context = km_core_state_context_debug(self.coreState, KM_CORE_DEBUG_CONTEXT_CACHED);
|
||||
NSString *debugString = [self.coreHelper createNSStringFromUnicharString:context];
|
||||
km_core_cp_dispose(context);
|
||||
km_core_cu_dispose(context);
|
||||
|
||||
[self.coreHelper logDebugMessage:@"CoreWrapper contextDebug = %@", debugString];
|
||||
return debugString;
|
||||
|
|
@ -285,8 +285,8 @@ const int CORE_ENVIRONMENT_ARRAY_LENGTH = 6;
|
|||
return (result==KM_CORE_STATUS_OK);
|
||||
}
|
||||
|
||||
-(void)readCoreOptions: (km_core_cp const *) key {
|
||||
km_core_cp const * valueFromCore = nil;
|
||||
-(void)readCoreOptions: (km_core_cu const *) key {
|
||||
km_core_cu const * valueFromCore = nil;
|
||||
km_core_status result =
|
||||
km_core_state_option_lookup(self.coreState,
|
||||
KM_CORE_OPT_KEYBOARD,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#import "KeyLabel.h"
|
||||
#import "MacVKCodes.h"
|
||||
#import "TimerTarget.h"
|
||||
#import <os/log.h>
|
||||
|
||||
CGFloat lw = 1.0;
|
||||
CGFloat r = 7.0;
|
||||
|
|
@ -27,20 +28,22 @@ static CGFloat const kRelativeModifierLabelHeight = 0.30f;
|
|||
@property (nonatomic, assign) BOOL isCharacterKey;
|
||||
@property (nonatomic, strong) KeyLabel *label;
|
||||
@property (nonatomic, strong) NSTextField *caption;
|
||||
@property (nonatomic, strong) NSImageView *bitmapView;
|
||||
@property (nonatomic, strong) NSColor *bgColor1;
|
||||
@property (nonatomic, strong) NSColor *bgColor2;
|
||||
@property (nonatomic, strong) NSColor *bgColorRegularKey;
|
||||
@property (nonatomic, strong) NSColor *bgColorSpecialKey;
|
||||
@property (nonatomic, strong) NSTimer *keyEventTimer;
|
||||
@property (readwrite) NSInteger tag;
|
||||
@end
|
||||
|
||||
@implementation KeyView
|
||||
@synthesize tag;
|
||||
@synthesize bgColor1, bgColor2;
|
||||
@synthesize bgColorRegularKey, bgColorSpecialKey;
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame {
|
||||
os_log_t oskKeyLog = os_log_create("org.sil.keyman", "osk-key");
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
os_log_with_type(oskKeyLog, OS_LOG_TYPE_DEBUG, "KeyView initWithFrame: %{public}@, bounds: %{public}@, default clipsToBounds %{public}@", NSStringFromRect(frame), NSStringFromRect(self.bounds), self.clipsToBounds?@"YES":@"NO");
|
||||
self.clipsToBounds = true;
|
||||
CGSize size = frame.size;
|
||||
CGFloat x = size.width*0.05;
|
||||
NSRect labelFrame = NSMakeRect(x, 0, size.width -lw -2*x, size.height);
|
||||
|
|
@ -48,7 +51,7 @@ static CGFloat const kRelativeModifierLabelHeight = 0.30f;
|
|||
[_label setEditable:NO];
|
||||
[_label setBordered:NO];
|
||||
[_label setDrawsBackground:NO];
|
||||
[_label setAlignment:NSCenterTextAlignment];
|
||||
[_label setAlignment:NSTextAlignmentCenter];
|
||||
if ([_caption respondsToSelector:@selector(setLineBreakMode:)]) {
|
||||
[_label setLineBreakMode:NSLineBreakByClipping];
|
||||
} // There might be some problem not calling this, but it seems to be okay as far as I can tell
|
||||
|
|
@ -60,22 +63,26 @@ static CGFloat const kRelativeModifierLabelHeight = 0.30f;
|
|||
[_label setLineBreakMode:NSLineBreakByClipping];
|
||||
[self addSubview:_label];
|
||||
|
||||
bgColor1 = [self getOpaqueColorWithRed:209 green:211 blue:212];
|
||||
bgColor2 = [self getOpaqueColorWithRed:166 green:169 blue:172];
|
||||
bgColorRegularKey = [self getOpaqueColorWithRed:209 green:211 blue:212];
|
||||
bgColorSpecialKey = [self getOpaqueColorWithRed:166 green:169 blue:172];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)rect {
|
||||
os_log_t oskKeyLog = os_log_create("org.sil.keyman", "osk-key");
|
||||
os_log_with_type(oskKeyLog, OS_LOG_TYPE_DEBUG, "KeyView drawRect: %{public}@, bounds: %{public}@, keyCode: 0x%lx, caption: %{public}@, label: %{public}@", NSStringFromRect(rect), NSStringFromRect(self.bounds), self.keyCode, self.caption.stringValue, self.label.stringValue);
|
||||
|
||||
[[self getOpaqueColorWithRed:241 green:242 blue:242] setFill];
|
||||
NSRectFillUsingOperation(rect, NSCompositeSourceOver);
|
||||
NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver);
|
||||
|
||||
// Drawing code here.
|
||||
CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
|
||||
CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] CGContext];
|
||||
|
||||
CGContextSetLineJoin(context, kCGLineJoinRound);
|
||||
CGContextSetLineWidth(context, lw);
|
||||
CGContextSetStrokeColorWithColor(context, bgColor1.CGColor);
|
||||
CGContextSetStrokeColorWithColor(context, bgColorRegularKey.CGColor);
|
||||
|
||||
CGFloat x = rect.origin.x + lw;
|
||||
CGFloat y = rect.origin.y + lw;
|
||||
|
|
@ -100,10 +107,10 @@ static CGFloat const kRelativeModifierLabelHeight = 0.30f;
|
|||
CGContextClosePath(context);
|
||||
CGContextClip(context);
|
||||
|
||||
NSColor *bgColor = bgColor1;
|
||||
NSColor *bgColor = bgColorRegularKey;
|
||||
|
||||
if ([self isSpecialKey])
|
||||
bgColor = bgColor2;
|
||||
bgColor = bgColorSpecialKey;
|
||||
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
CGFloat gradientLocations[] = {0, 1};
|
||||
|
|
@ -238,7 +245,7 @@ static CGFloat const kRelativeModifierLabelHeight = 0.30f;
|
|||
[_caption setBordered:NO];
|
||||
[_caption setDrawsBackground:NO];
|
||||
//[_caption setBackgroundColor:[NSColor yellowColor]];
|
||||
[_caption setAlignment:NSLeftTextAlignment];
|
||||
[_caption setAlignment:NSTextAlignmentLeft];
|
||||
if ([_caption respondsToSelector:@selector(setLineBreakMode:)]) {
|
||||
[_caption setLineBreakMode:NSLineBreakByClipping];
|
||||
} // There might be some problem not calling this, but it seems to be okay as far as I can tell
|
||||
|
|
@ -325,26 +332,18 @@ static CGFloat const kRelativeModifierLabelHeight = 0.30f;
|
|||
- (void)setKeyPressed:(BOOL)keyPressed {
|
||||
_keyPressed = keyPressed;
|
||||
if (keyPressed) {
|
||||
bgColor1 = [self getOpaqueColorWithRed:109 green:111 blue:112];
|
||||
bgColor2 = [self getOpaqueColorWithRed:236 green:239 blue:242];
|
||||
bgColorRegularKey = [self getOpaqueColorWithRed:109 green:111 blue:112];
|
||||
bgColorSpecialKey = [self getOpaqueColorWithRed:236 green:239 blue:242];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
else {
|
||||
bgColor1 = [self getOpaqueColorWithRed:209 green:211 blue:212];
|
||||
bgColor2 = [self getOpaqueColorWithRed:166 green:169 blue:172];
|
||||
bgColorRegularKey = [self getOpaqueColorWithRed:209 green:211 blue:212];
|
||||
bgColorSpecialKey = [self getOpaqueColorWithRed:166 green:169 blue:172];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSColor *)getOpaqueColorWithRed:(NSUInteger) red green: (NSUInteger) green blue: (NSUInteger) blue {
|
||||
// RGB is what was in the code originally I can't tell any difference between that and SRGB for the
|
||||
// colors we're using in the OSK, but at the risk of causing an unintended change, I'm leaving it as
|
||||
// it was for versions of macOS that support colorWithRed:green:blue:
|
||||
if ([NSColor respondsToSelector:@selector(colorWithRed:green:blue:alpha:)]) {
|
||||
return [NSColor colorWithRed:red/255.0 green:green/255.0 blue:blue/255.0 alpha:1.0];
|
||||
}
|
||||
else {
|
||||
return [NSColor colorWithSRGBRed:red/255.0 green:green/255.0 blue:blue/255.0 alpha:1.0];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -7,12 +7,15 @@
|
|||
//
|
||||
|
||||
#import "OSKKey.h"
|
||||
#import <os/log.h>
|
||||
|
||||
@implementation OSKKey
|
||||
|
||||
- (id)initWithKeyCode:(NSUInteger)keyCode caption:(NSString *)caption scale:(CGFloat)scale {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
os_log_t oskKeyLog = os_log_create("org.sil.keyman", "osk-key");
|
||||
os_log_with_type(oskKeyLog, OS_LOG_TYPE_DEBUG, "OSKKey initWithKeyCode: 0x%lx, caption: %{public}@, scale: %f", keyCode, caption, scale);
|
||||
_keyCode = keyCode;
|
||||
|
||||
if (caption == nil)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#import "CoreHelper.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#import <os/log.h>
|
||||
|
||||
@interface OSKView()
|
||||
@property (nonatomic, strong) NSArray *oskLayout;
|
||||
|
|
@ -32,6 +33,8 @@
|
|||
@synthesize tag;
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame {
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView initWithFrame: %{public}@", NSStringFromRect(frame));
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
// Custom initialization
|
||||
|
|
@ -42,7 +45,10 @@
|
|||
}
|
||||
|
||||
- (void)drawRect:(NSRect)rect {
|
||||
CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView drawRect: %{public}@", NSStringFromRect(rect));
|
||||
|
||||
CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] CGContext];
|
||||
CGContextSetLineJoin(context, kCGLineJoinRound);
|
||||
CGContextSetLineWidth(context, 1.0);
|
||||
CGColorRef cgClearColor = CGColorGetConstantColor(kCGColorClear);
|
||||
|
|
@ -57,9 +63,10 @@
|
|||
CGContextAddRect(context, CGRectMake(1.0, 1.0, rect.size.width-1.0, rect.size.height-1.0));
|
||||
CGContextClip(context);
|
||||
|
||||
//TODO: gradient from clear to clear -- what does this do?
|
||||
NSColor *bgColor = [NSColor clearColor]; //[NSColor colorWithWhite:0.7 alpha:1.0];
|
||||
NSColor *bgColor2 = [NSColor clearColor]; //[NSColor colorWithWhite:0.5 alpha:1.0];
|
||||
|
||||
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
NSArray *gradientColors = [NSArray arrayWithObjects:(id)bgColor.CGColor, bgColor2.CGColor, nil];
|
||||
CGFloat gradientLocations[] = {0, 1};
|
||||
|
|
@ -97,6 +104,8 @@
|
|||
}
|
||||
|
||||
- (void)setKvk:(KVKFile *)kvk {
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView setKvk, forces keyboard to re-layout");
|
||||
_kvk = kvk;
|
||||
|
||||
// Force the keyboard to re-layout
|
||||
|
|
@ -107,6 +116,8 @@
|
|||
}
|
||||
|
||||
- (void)initOSKKeys {
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView initOSKKeys");
|
||||
CGFloat viewWidth = self.frame.size.width;
|
||||
CGFloat viewHeight = self.frame.size.height;
|
||||
CGFloat margin = 2.0;
|
||||
|
|
@ -141,6 +152,8 @@
|
|||
|
||||
- (NSArray *)oskLayout {
|
||||
if (_oskLayout == nil) {
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "oskLayout -> creating new arrays of OSKKey objects");
|
||||
NSArray *row1 = [NSArray arrayWithObjects:
|
||||
[[OSKKey alloc] initWithKeyCode:MVK_GRAVE caption:@"`" scale:1.0],
|
||||
[[OSKKey alloc] initWithKeyCode:MVK_1 caption:@"1" scale:1.0],
|
||||
|
|
@ -225,6 +238,8 @@
|
|||
|
||||
- (NSArray *)oskDefaultNKeys {
|
||||
if (_oskDefaultNKeys == nil) {
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "oskDefaultNKeys -> creating new arrays of default number OSKKey objects");
|
||||
NSMutableArray *defNKeys = [[NSMutableArray alloc] initWithCapacity:0];
|
||||
|
||||
// row 1
|
||||
|
|
@ -395,6 +410,8 @@
|
|||
}
|
||||
|
||||
- (void)resizeOSKLayout {
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView resizeOSKLayout, removing all superviews");
|
||||
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
[self initOSKKeys];
|
||||
}
|
||||
|
|
@ -402,9 +419,11 @@
|
|||
- (void)keyAction:(id)sender {
|
||||
KeyView *keyView = (KeyView *)sender;
|
||||
NSUInteger keyCode = [keyView.key keyCode];
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView keyAction keyCode: 0x%lx", keyCode);
|
||||
if (keyCode < 0x100) {
|
||||
ProcessSerialNumber psn;
|
||||
GetFrontProcess(&psn);
|
||||
NSRunningApplication *app = NSWorkspace.sharedWorkspace.frontmostApplication;
|
||||
pid_t processId = app.processIdentifier;
|
||||
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStatePrivate);
|
||||
CGEventRef keyDownEvent = CGEventCreateKeyboardEvent(source, (CGKeyCode)keyCode, true);
|
||||
CGEventRef keyUpEvent = CGEventCreateKeyboardEvent(source, (CGKeyCode)keyCode, false);
|
||||
|
|
@ -420,8 +439,8 @@
|
|||
CGEventSetFlags(keyDownEvent, CGEventGetFlags(keyDownEvent) | kCGEventFlagMaskControl);
|
||||
CGEventSetFlags(keyUpEvent, CGEventGetFlags(keyUpEvent) | kCGEventFlagMaskControl);
|
||||
}
|
||||
CGEventPostToPSN(&psn, keyDownEvent);
|
||||
CGEventPostToPSN(&psn, keyUpEvent);
|
||||
CGEventPostToPid(processId, keyDownEvent);
|
||||
CGEventPostToPid(processId, keyUpEvent);
|
||||
CFRelease(source);
|
||||
CFRelease(keyDownEvent);
|
||||
CFRelease(keyUpEvent);
|
||||
|
|
@ -440,12 +459,14 @@
|
|||
}
|
||||
|
||||
- (void)handleKeyEvent:(NSEvent *)event {
|
||||
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
|
||||
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView handleKeyEvent event.type: %lu", event.type);
|
||||
NSView *view = [self viewWithTag:event.keyCode|0x1000];
|
||||
if (view == nil || ![view isKindOfClass:[KeyView class]])
|
||||
return;
|
||||
|
||||
KeyView *keyView = (KeyView *)view;
|
||||
if (event.type == NSKeyDown)
|
||||
if (event.type == NSEventTypeKeyDown)
|
||||
[keyView setKeyPressed:YES];
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(setKeyPressedOff:) object:keyView];
|
||||
[self performSelector:@selector(setKeyPressedOff:) withObject:keyView afterDelay:0.1];
|
||||
|
|
@ -624,7 +645,7 @@
|
|||
}
|
||||
|
||||
- (void)setOskCtrlState:(BOOL)oskCtrlState {
|
||||
if (_oskCtrlState != oskCtrlState && !self.ctrlState) {
|
||||
if (_oskCtrlState != oskCtrlState && !self.ctrlState) {
|
||||
_oskCtrlState = oskCtrlState;
|
||||
KeyView *ctrlKeyL = (KeyView *)[self viewWithTag:MVK_LEFT_CTRL|0x1000];
|
||||
KeyView *ctrlKeyR = (KeyView *)[self viewWithTag:MVK_RIGHT_CTRL|0x1000];
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardDownloa
|
|||
context = this;
|
||||
|
||||
SentryAndroid.init(context, options -> {
|
||||
options.setEnableAutoSessionTracking(false);
|
||||
options.setRelease(com.firstvoices.keyboards.BuildConfig.VERSION_GIT_TAG);
|
||||
options.setEnvironment(com.firstvoices.keyboards.BuildConfig.VERSION_ENVIRONMENT);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
|
|||
if (DependencyUtil.libraryExists(LibraryType.SENTRY) && !Sentry.isEnabled()) {
|
||||
Log.d(TAG, "Initializing Sentry");
|
||||
SentryAndroid.init(getApplicationContext(), options -> {
|
||||
options.setEnableAutoSessionTracking(false);
|
||||
options.setRelease(com.firstvoices.keyboards.BuildConfig.VERSION_GIT_TAG);
|
||||
options.setEnvironment(com.firstvoices.keyboards.BuildConfig.VERSION_ENVIRONMENT);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ fv,fv_diitiidatx,Diidiitidq,BC Coast,fv_diitiidatx_kmw-9.0.js,9.1.3,nuk-Latn,Nuu
|
|||
fv,fv_gitsenimx,Gitsenimx̱,BC Coast,fv_gitsenimx_kmw-9.0.js,10.0.1,git,Gitxsan (Latin)
|
||||
fv,fv_hailzaqvla,Haiɫzaqvla,BC Coast,fv_hailzaqvla_kmw-9.0.js,9.5.1,hei,Heiltsuk (Latin)
|
||||
fv,fv_haisla,Haisla,BC Coast,fv_haisla.js,2.0.1,has-Latn,Haisla (Latin)
|
||||
fv,fv_halqemeylem,Halq'eméylem,BC Coast,fv_halqemeylem_kmw-9.0.js,9.1.3,hur-Latn,Halkomelem (Latin)
|
||||
fv,fv_halqemeylem,Halq'eméylem,BC Coast,fv_halqemeylem_kmw-9.0.js,9.2,hur-Latn,Halkomelem (Latin)
|
||||
fv,fv_henqeminem,Hǝn̓q̓ǝmin̓ǝm,BC Coast,fv_henqeminem_kmw-9.0.js,10.0.1,hur-Latn,Halkomelem (Latin)
|
||||
fv,fv_klahoose,Homalco-Klahoose-Sliammon,BC Coast,fv_klahoose_kmw-9.0.js,10.1,coo,Comox
|
||||
fv,fv_hulquminum,Hul’q’umi’num’,BC Coast,fv_hulquminum_kmw-9.0.js,9.1,hur-Latn,Halkomelem (Latin)
|
||||
fv,fv_hulquminum_combine,Hul̓q̓umin̓um̓,BC Coast,fv_hulquminum_combine_kmw-9.0.js,1.0,hur-Latn,Halkomelem (Latin)
|
||||
fv,fv_hulquminum_combine,Hul̓q̓umin̓um̓,BC Coast,fv_hulquminum_combine_kmw-9.0.js,1.1,hur-Latn,Halkomelem (Latin)
|
||||
fv,fv_kwakwala_liqwala,Kʷak̓ʷala,BC Coast,fv_kwakwala_liqwala_kmw-9.0.js,9.2.5,kwk-Latn,Kwakiutl (Latin)
|
||||
fv,fv_kwakwala,Kwak̕wala,BC Coast,fv_kwakwala_kmw-9.0.js,9.1.2,kwk-Latn,Kwakiutl (Latin)
|
||||
fv,fv_nexwslayemucen,Nəxʷsƛ̓ay̓əmúcən,BC Coast,fv_nexwslayemucen_kmw-9.0.js,9.2.1,clm-Latn,Clallam (Latin)
|
||||
|
|
@ -36,7 +36,8 @@ fv,fv_ktunaxa,Ktunaxa,BC Interior,fv_ktunaxa_kmw-9.0.js,9.1.3,kut-Latn,Kutenai (
|
|||
fv,fv_kwadacha_tsekene,Kwadacha Tsek’ene,BC Interior,fv_kwadacha_tsekene_kmw-9.0.js,1.0,sek-Latn,Sekani
|
||||
fv,fv_natwits,Nedut’en-Witsuwit'en,BC Interior,fv_natwits_kmw-9.0.js,9.1.3,caf-Latn,Southern Carrier (Latin)
|
||||
fv,fv_nlekepmxcin,Nłeʔkepmxcin,BC Interior,fv_nlekepmxcin_kmw-9.0.js,9.2.3,thp-Latn,Thompson (Latin)
|
||||
fv,fv_nlha7kapmxtsin,Nlha7kapmxtsin,BC Interior,fv_nlha7kapmxtsin_kmw-9.0.js,9.1.1,thp-Latn,Thompson (Latin)
|
||||
fv,fv_nlha7kapmxtsin,Nlha7kapmxtsin,BC Interior,fv_nlha7kapmxtsin_kmw-9.0.js,10.0,thp-Latn,Thompson (Latin)
|
||||
fv,fv_nlakapamuxcheen,Nlakapamuxcheen,BC Interior,fv_nlakapamuxcheen_kmw-9.0.js,1.0,thp,Thompson
|
||||
fv,fv_nsilxcen,Nsilxcən,BC Interior,fv_nsilxcen_kmw-9.0.js,9.3,oka,Okanagan
|
||||
fv,fv_secwepemctsin,Secwepemctsín,BC Interior,fv_secwepemctsin_kmw-9.0.js,9.2,shs-Latn,Shuswap (Latin)
|
||||
fv,fv_stlatlimxec,Sƛ̓aƛ̓imxəc,BC Interior,fv_stlatlimxec_kmw-9.0.js,9.2.3,lil-Latn,Lillooet (Latin)
|
||||
|
|
@ -44,7 +45,7 @@ fv,fv_statimcets,St̓át̓imcets,BC Interior,fv_statimcets_kmw-9.0.js,9.1.4,lil
|
|||
fv,fv_taltan,Tāłtān,BC Interior,fv_taltan_kmw-9.0.js,9.1.5,tht-Latn,Tahltan (Latin)
|
||||
fv,fv_tsekehne,Tsek'ehne,BC Interior,fv_tsekehne_kmw-9.0.js,9.1.2,sek-Latn,Sekani (Latin)
|
||||
fv,fv_tsilhqotin,Tŝilhqot'in,BC Interior,fv_tsilhqotin_kmw-9.0.js,9.1.3,clc-Latn,Chilcotin (Latin)
|
||||
fv,fv_southern_carrier,ᑐᑊᘁᗕᑋᗸ (Southern Carrier),BC Interior,fv_southern_carrier_kmw-9.0.js,10.0,caf-Cans,Southern Carrier (Unified Canadian Aboriginal Syllabics)
|
||||
fv,fv_southern_carrier,ᑐᑊᘁᗕᑋᗸ (Southern Carrier),BC Interior,fv_southern_carrier_kmw-9.0.js,10.0.1,caf-Cans,Southern Carrier (Unified Canadian Aboriginal Syllabics)
|
||||
fv,fv_anicinapemi8in,Anicinapemi8in/Anishinàbemiwin,Eastern Subarctic,fv_anicinapemi8in_kmw-9.0.js,9.1.1,alq-Latn,Algonquin (Latin)
|
||||
fv,fv_atikamekw,Atikamekw,Eastern Subarctic,fv_atikamekw_kmw-9.0.js,9.1.1,atj-Latn,Atikamekw (Latin)
|
||||
fv,fv_ilnu_innu_aimun,Ilnu-Innu Aimun,Eastern Subarctic,fv_ilnu_innu_aimun_kmw-9.0.js,9.1.1,moe-Latn,Montagnais (Latin)
|
||||
|
|
@ -54,7 +55,7 @@ fv,fv_northern_east_cree,ᐄᔨᔫ-ᐄᓅ ᐊᔨᒨᓐ (Northern East Cree),East
|
|||
fv,fv_severn_ojibwa,ᐊᓂᔑᓂᓂᒧᐎᐣ (Severn Ojibwa),Eastern Subarctic,fv_severn_ojibwa_kmw-9.0.js,9.3.1,ojs-Cans,Severn Ojibwa (Unified Canadian Aboriginal Syllabics)
|
||||
fv,fv_ojibwa,ᐊᓂᔑᓇᐯᒧᐎᓐ (Ojibwa),Eastern Subarctic,fv_ojibwa_kmw-9.0.js,9.3.1,ojb-Cans,Northwestern Ojibwa (Unified Canadian Aboriginal Syllabics)
|
||||
fv,fv_naskapi,ᓇᔅᑲᐱ (Naskapi),Eastern Subarctic,fv_naskapi_kmw-9.0.js,9.3.1,nsk-Cans,Naskapi (Unified Canadian Aboriginal Syllabics)
|
||||
sil,sil_euro_latin,English,European,european2-1.6.js,3.0.1,en,English
|
||||
sil,sil_euro_latin,English,European,european2-1.6.js,3.0.2,en,English
|
||||
basic,basic_kbdcan,Français,European,canadian_french-1.0.js,1.1.1,fr-CA,French (Canada)
|
||||
fv,fv_anishinaabemowin,Anishinaabemowin,Great Lakes - St. Lawrence,fv_anishinaabemowin_kmw-9.0.js,10.0.1,oj,Ojibwa
|
||||
fv,fv_bodewadminwen,Bodéwadminwen-Nishnabémwen,Great Lakes - St. Lawrence,fv_bodewadminwen_kmw-9.0.js,9.1.1,pot-Latn,Potawatomi (Latin)
|
||||
|
|
|
|||
|
|
|
@ -138,7 +138,8 @@ but makes the script easy to scan!
|
|||
# Defining build script parameters
|
||||
|
||||
The build script should use the `builder` functions and variables to process its
|
||||
command line and control its run.
|
||||
command line and control its run. See [`builder_describe`] for full details on
|
||||
how these parameters are defined.
|
||||
|
||||
Build scripts can define **targets**, **actions**, **options**, and
|
||||
**dependencies**, which are parameters passed in to the script when it is run by
|
||||
|
|
@ -179,6 +180,9 @@ a user or called by another script:
|
|||
Options can be used to provide additional data, by including `=<varname>` in
|
||||
their definition. Otherwise, they are treated as a boolean.
|
||||
|
||||
An option will be inherited by child scripts if you append a `+` to the option
|
||||
name.
|
||||
|
||||
* **dependencies**: these are other builder scripts which must be configured and
|
||||
built before the actions in this script can continue. Only `configure` and
|
||||
`build` actions are ever passed to dependency scripts; these actions will
|
||||
|
|
@ -424,6 +428,10 @@ a definition:
|
|||
builder_describe "Testing script" clean test+
|
||||
```
|
||||
|
||||
If an action is passed to a child script, but the child script does not support
|
||||
it, it will be ignored, although a builder debug message will be issued for
|
||||
safety.
|
||||
|
||||
**Options** are defined by including a `--` prefix.
|
||||
|
||||
Specification of options: `"--option[,-o][+][=var] [One line description]"`
|
||||
|
|
@ -440,10 +448,11 @@ may not be combined when invoking the script -- each must be passed separately.
|
|||
Ensure that you do not include a space after the comma.
|
||||
|
||||
If a `+` is appended (after the optional shorthand form, but before the
|
||||
default), then the option will be passed to child scripts. All child scripts
|
||||
_must_ accept this option, or they will fail. It is acceptable for the child
|
||||
script to declare the option but ignore it. However, the option will _not_ be
|
||||
passed to dependencies.
|
||||
variable), then the option will be passed to child scripts. Child scripts do not
|
||||
need to declare the option if they do not use it, but this will be noted as a
|
||||
builder debug message for safety; it is also acceptable for the child script to
|
||||
declare the option but ignore it. However, the option will _not_ be passed to
|
||||
dependencies.
|
||||
|
||||
By default, an option will be treated as a boolean. It can be tested with
|
||||
[`builder_has_option`]. If you need to pass additional data, then the
|
||||
|
|
|
|||
29
resources/build/minimum-versions.inc.sh
Normal file
29
resources/build/minimum-versions.inc.sh
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# Required minimum versions (also used as default version)
|
||||
# Minimum versions as of Keyman 18
|
||||
# (https://docs.google.com/document/d/1Uy3U2YXeA4rCEbUbT7O6QzUGJDZBeViFecL8fjUOLkE/edit?usp=sharing)
|
||||
|
||||
# shellcheck shell=bash disable=SC2034 # SC2034: X appears unused.
|
||||
|
||||
# Target operating system and platform versions
|
||||
KEYMAN_MIN_TARGET_VERSION_ANDROID=5 # Lollipop
|
||||
KEYMAN_MIN_TARGET_VERSION_IOS=12.2 # iOS 12.2
|
||||
KEYMAN_MIN_TARGET_VERSION_WINDOWS=10 # Windows 10
|
||||
KEYMAN_MIN_TARGET_VERSION_MAC=10.13 # MacOS 10.13 (High Sierra)
|
||||
KEYMAN_MIN_TARGET_VERSION_UBUNTU=20.04 # Ubuntu 20.04 Focal
|
||||
KEYMAN_MIN_TARGET_VERSION_CHROME=95.0 # Final version that runs on Android 5.0
|
||||
|
||||
# Dependency versions
|
||||
KEYMAN_MIN_VERSION_NODE_MAJOR=18
|
||||
KEYMAN_MIN_VERSION_NPM=10.5.1 # 10.5.0 has bug, discussed in #10350
|
||||
KEYMAN_MIN_VERSION_EMSCRIPTEN=3.1.44 # Warning: 3.1.45 is bad (#9529); newer versions work
|
||||
KEYMAN_MAX_VERSION_EMSCRIPTEN=3.1.58 # See #9529
|
||||
KEYMAN_MIN_VERSION_VISUAL_STUDIO=2019
|
||||
KEYMAN_MIN_VERSION_MESON=1.0.0
|
||||
|
||||
# Language and runtime versions
|
||||
KEYMAN_VERSION_JAVA=11 # We're using Java/OpenJDK 11
|
||||
KEYMAN_MIN_VERSION_CPP=17 # C++17
|
||||
KEYMAN_MIN_VERSION_ANDROID_SDK=21
|
||||
|
||||
# Default version used in Docker containers
|
||||
KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER=noble # Ubuntu 24.04 Noble
|
||||
|
|
@ -7,6 +7,7 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
|||
|
||||
builder_describe \
|
||||
"Tests dependency builds debug flag" \
|
||||
:child \
|
||||
configure build
|
||||
|
||||
function do_build() {
|
||||
|
|
@ -25,3 +26,5 @@ builder_is_dep_build || builder_die "FAIL: dep: builder_is_dep_build should be t
|
|||
! builder_is_child_build || builder_die "FAIL: dep: builder_is_child_build should be false"
|
||||
|
||||
builder_run_action build do_build
|
||||
|
||||
builder_run_child_actions configure build
|
||||
|
|
|
|||
27
resources/build/test/debug-deps/dep/child/build.sh
Executable file
27
resources/build/test/debug-deps/dep/child/build.sh
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env bash
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
. "${THIS_SCRIPT%/*}/../../../../../../resources/build/builder.inc.sh"
|
||||
# END STANDARD BUILD SCRIPT INCLUDE
|
||||
|
||||
builder_describe \
|
||||
"Tests dependency/child builds debug flag" \
|
||||
configure build
|
||||
|
||||
function do_build() {
|
||||
# Test the debug flag
|
||||
builder_is_debug_build || builder_die "FAIL: child/dep: expecting builder_is_debug_build to be true"
|
||||
echo "PASS: child/dep: builder_is_debug_build is true"
|
||||
|
||||
builder_has_option --debug || builder_die "FAIL: child/dep: expecting builder_has_option --debug to be true"
|
||||
echo "PASS: child/dep: builder_has_option --debug is true"
|
||||
}
|
||||
|
||||
builder_parse "$@"
|
||||
|
||||
# Sanity Check: verify that we are running as a dep AND as a child build
|
||||
builder_is_dep_build || builder_die "FAIL: dep/child: builder_is_dep_build should be true"
|
||||
builder_is_child_build || builder_die "FAIL: dep/child: builder_is_child_build should be false"
|
||||
|
||||
builder_run_action build do_build
|
||||
21
resources/build/test/ignored-flags/build.sh
Executable file
21
resources/build/test/ignored-flags/build.sh
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh"
|
||||
# END STANDARD BUILD SCRIPT INCLUDE
|
||||
|
||||
# Test builder_describe_outputs and dependencies
|
||||
|
||||
builder_describe "parent test module" \
|
||||
:child \
|
||||
test1 test2 \
|
||||
"--option1+ inheritable option" \
|
||||
"--option2+ second inheritable option"
|
||||
|
||||
builder_parse "$@"
|
||||
|
||||
builder_run_child_actions test1 test2
|
||||
|
||||
echo Done
|
||||
19
resources/build/test/ignored-flags/child/build.sh
Executable file
19
resources/build/test/ignored-flags/child/build.sh
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
echo "Params: $@"
|
||||
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder.inc.sh"
|
||||
# END STANDARD BUILD SCRIPT INCLUDE
|
||||
|
||||
# Test missing actions and options
|
||||
|
||||
project=child1
|
||||
|
||||
builder_describe "$project test module" test1 --option1
|
||||
|
||||
builder_parse "$@"
|
||||
|
||||
builder_run_action test1 echo "test1 action ran"
|
||||
14
resources/build/test/ignored-flags/test.sh
Executable file
14
resources/build/test/ignored-flags/test.sh
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -eu
|
||||
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
. "${THIS_SCRIPT%/*}/../../../../resources/build/build-utils.sh"
|
||||
# END STANDARD BUILD SCRIPT INCLUDE
|
||||
|
||||
cd "$THIS_SCRIPT_PATH"
|
||||
|
||||
echo "--- Build a child script which has ignored options and flags ---"
|
||||
./build.sh test1 test2 --option1 --option2
|
||||
|
|
@ -175,6 +175,7 @@ echo -e "${COLOR_BLUE}## Running dependency tests${COLOR_RESET}"
|
|||
"$THIS_SCRIPT_PATH/dependencies/test.sh"
|
||||
"$THIS_SCRIPT_PATH/trees/test.sh"
|
||||
"$THIS_SCRIPT_PATH/debug-deps/test.sh"
|
||||
"$THIS_SCRIPT_PATH/ignored-flags/test.sh"
|
||||
|
||||
echo -e "${COLOR_BLUE}## Test builder.inc.sh 'builder-style' script${COLOR_RESET}"
|
||||
./builder-invalid-script.test.sh || builder_die "FAIL: builder-invalid-script.test.sh returned failure code $?"
|
||||
|
|
@ -187,7 +188,7 @@ echo
|
|||
# builder_parse calls `exit 0` on a --help run, so running in a subshell
|
||||
echo -e "${COLOR_BLUE}## Testing --help${COLOR_RESET}"
|
||||
builder_parse --no-color --help
|
||||
) || builder_die "FAIL: builder-parse returned failure code $? unexpectedly"
|
||||
) || builder_die "FAIL: builder-parse unexpectedly returned failure code $?"
|
||||
|
||||
echo -e "${COLOR_GREEN}======================================================${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}All tests passed successfully${COLOR_RESET}"
|
||||
|
|
|
|||
|
|
@ -400,9 +400,19 @@ _builder_execute_child() {
|
|||
fi
|
||||
done
|
||||
|
||||
"$script" $action \
|
||||
# If the current build is a dependency build, pass the dependency state on to
|
||||
# the child build, so that we don't unnecessarily rebuild children (#11394)
|
||||
local dep_flag= dep_module=
|
||||
if builder_is_dep_build; then
|
||||
dep_flag=--builder-dep-parent
|
||||
dep_module="$builder_dep_parent"
|
||||
fi
|
||||
|
||||
"$script" \
|
||||
--builder-child \
|
||||
$_builder_build_deps \
|
||||
$dep_flag "$dep_module" \
|
||||
$action \
|
||||
${child_options[@]} \
|
||||
$builder_verbose \
|
||||
$builder_debug \
|
||||
|
|
@ -1205,7 +1215,6 @@ builder_parse() {
|
|||
if [[ $# -eq 0 ]]; then
|
||||
_builder_parameter_error "$0" parameter "$key"
|
||||
fi
|
||||
|
||||
exp+=("$1")
|
||||
fi
|
||||
else
|
||||
|
|
@ -1369,9 +1378,12 @@ _builder_parse_expanded_parameters() {
|
|||
# internal use parameter for dependency builds - identifier of parent script
|
||||
shift
|
||||
builder_dep_parent="$1"
|
||||
builder_echo setmark "dependency build, started by $builder_dep_parent"
|
||||
builder_echo grey "build.sh parameters: <${_params[@]}>"
|
||||
;;
|
||||
--builder-child)
|
||||
_builder_is_child=0
|
||||
builder_echo setmark "child build, parameters: <${_params[@]}>"
|
||||
;;
|
||||
--builder-report-dependencies)
|
||||
# internal reporting function, ignores all other parameters
|
||||
|
|
@ -1379,7 +1391,13 @@ _builder_parse_expanded_parameters() {
|
|||
;;
|
||||
*)
|
||||
# script does not recognize anything of action or target form at this point.
|
||||
_builder_parameter_error "$0" parameter "$key"
|
||||
if builder_is_child_build; then
|
||||
# For child builds, don't fail the build when pass inheritable
|
||||
# parameters (#11408)
|
||||
builder_echo_debug "Parameter '$key' is not supported, ignoring"
|
||||
else
|
||||
_builder_parameter_error "$0" parameter "$key"
|
||||
fi
|
||||
esac
|
||||
fi
|
||||
shift # past the processed argument
|
||||
|
|
@ -1409,13 +1427,10 @@ _builder_parse_expanded_parameters() {
|
|||
fi
|
||||
|
||||
if builder_is_dep_build; then
|
||||
builder_echo setmark "dependency build, started by $builder_dep_parent"
|
||||
builder_echo grey "build.sh parameters: <${_params[@]}>"
|
||||
if [[ -z ${_builder_deps_built+x} ]]; then
|
||||
builder_die "FATAL ERROR: Expected '_builder_deps_built' variable to be set"
|
||||
fi
|
||||
elif builder_is_child_build; then
|
||||
builder_echo setmark "child build, parameters: <${_params[@]}>"
|
||||
if [[ -z ${_builder_deps_built+x} ]]; then
|
||||
builder_die "FATAL ERROR: Expected '_builder_deps_built' variable to be set"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
"@keymanapp/web-utils": ["./common/web/utils"],
|
||||
"@keymanapp/lm-message-types": ["./common/web/lm-message-types"],
|
||||
"@keymanapp/keyman-version": ["./common/web/keyman-version"],
|
||||
"@keymanapp/ldml-keyboard-constants": [ "./core/include/ldml" ],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,10 +122,10 @@ export class PageIntegrationHandlers {
|
|||
// The following tests are needed to prevent the OSK from being hidden during normal input!
|
||||
let p=(e.target as HTMLElement).parentElement;
|
||||
if(typeof(p) != 'undefined' && p != null) {
|
||||
if(p.className.indexOf('kmw-key-') >= 0) return false;
|
||||
if(p.getAttribute('class')?.indexOf('kmw-key-') >= 0) return false;
|
||||
if(typeof(p.parentElement) != 'undefined' && p.parentElement != null) {
|
||||
p=p.parentElement;
|
||||
if(p.className.indexOf('kmw-key-') >= 0) return false;
|
||||
if(p.getAttribute('class')?.indexOf('kmw-key-') >= 0) return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -287,24 +287,43 @@ export default class ContextManager extends ContextManagerBase<BrowserConfigurat
|
|||
};
|
||||
|
||||
// Set element directionality (but only if element is empty)
|
||||
let Ltarg = target?.getElement();
|
||||
let focusedElement = target?.getElement();
|
||||
if(target instanceof DesignIFrame) {
|
||||
Ltarg = target.docRoot;
|
||||
focusedElement = target.docRoot;
|
||||
}
|
||||
if(Ltarg && Ltarg.ownerDocument && Ltarg instanceof Ltarg.ownerDocument.defaultView.HTMLElement) {
|
||||
_SetTargDir(Ltarg, this.activeKeyboard?.keyboard);
|
||||
if(focusedElement && focusedElement.ownerDocument && focusedElement instanceof focusedElement.ownerDocument.defaultView.HTMLElement) {
|
||||
_SetTargDir(focusedElement, this.activeKeyboard?.keyboard);
|
||||
}
|
||||
|
||||
if(target != originalTarget) {
|
||||
this.emit('targetchange', target);
|
||||
}
|
||||
|
||||
//Execute external (UI) code needed on focus if required
|
||||
if(sendEvents) {
|
||||
// //Execute external (UI) code needed on focus if required
|
||||
this.apiEvents.callEvent('controlfocused', {
|
||||
target: target?.getElement() || null,
|
||||
activeControl: previousTarget?.getElement()
|
||||
});
|
||||
let blurredElement = previousTarget?.getElement();
|
||||
if(previousTarget instanceof DesignIFrame) {
|
||||
blurredElement = previousTarget.docRoot;
|
||||
}
|
||||
|
||||
if(!focusedElement) {
|
||||
if(blurredElement) {
|
||||
this.apiEvents.callEvent('controlblurred', {
|
||||
target: blurredElement,
|
||||
event: null,
|
||||
isActivating: this.focusAssistant.maintainingFocus
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Note: indicates the previous control being blurred (as
|
||||
// `activeControl`). 'controlfocused' and 'controlblurred' are
|
||||
// treated as mutually exclusive, with the latter only happening
|
||||
// when nothing KMW-related is focused.
|
||||
this.apiEvents.callEvent('controlfocused', {
|
||||
target: focusedElement,
|
||||
activeControl: blurredElement
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ export default class HardwareEventKeyboard extends HardKeyboard {
|
|||
|
||||
// Prevent mapping element is readonly or tagged as kmw-disabled
|
||||
const el = target.getElement();
|
||||
if(el?.className?.indexOf('kmw-disabled') >= 0) {
|
||||
if(el?.getAttribute('class')?.indexOf('kmw-disabled') >= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@
|
|||
|
||||
<Component>
|
||||
<File Name="kmshell.exe" KeyPath="yes">
|
||||
<Shortcut Id="desktopKeyman" Advertise="yes" Directory="DesktopFolder" Name="Keyman" WorkingDirectory='INSTALLDIR' Icon="appicon.ico" IconIndex="0" />
|
||||
<Shortcut Id="startmenuKeyman" Advertise="yes" Directory="ProgramMenuDir" Name="Keyman" WorkingDirectory='INSTALLDIR' Icon="appicon.ico" IconIndex="0" />
|
||||
<Shortcut Id="startmenuKeymanConfiguration" Advertise="yes" Directory="ProgramMenuDir" Arguments="-c" Name="Keyman Configuration" WorkingDirectory='INSTALLDIR' Icon="KMSHELL.ico" IconIndex="0" />
|
||||
</File>
|
||||
|
|
|
|||
|
|
@ -904,6 +904,10 @@
|
|||
<!-- String Type: FormatString -->
|
||||
<!-- Introduced: 8.0.294.0 -->
|
||||
<string name="S_OSK_FontHelper_ChooseKeyboard" comment="OSK Font helper choose keyboard">សូមជ្រើសរើសក្ដារចុច Keyman មួយដើម្បីរកពុម្ពអក្សរដែលពាក់ព័ន្ធ</string>
|
||||
<!-- Context: OSK Font Helper -->
|
||||
<!-- String Type: FormatString -->
|
||||
<!-- Introduced: 17.0.312.0 -->
|
||||
<string name="S_OSK_FontHelper_NoFonts" comment="OSK Font helper no fonts found for keyboard">មិនឃើញមានពុម្ពអក្សរណាជាសំណូមពរសម្រាប់ក្តារចុច %1$s.</string>
|
||||
<!-- Context: Text Editor -->
|
||||
<!-- String Type: FormatString -->
|
||||
<!-- Introduced: 10.0.836.0 -->
|
||||
|
|
|
|||
|
|
@ -1189,7 +1189,7 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to
|
|||
<!-- Context: OSK Font Helper -->
|
||||
<!-- String Type: FormatString -->
|
||||
<!-- Introduced: 17.0.312.0 -->
|
||||
<string name="S_OSK_FontHelper_NoFonts" comment="OSK Font helper no fonts found for keyboard">No fonts have been found as suggestions for Keyboard %1$s.</string>
|
||||
<string name="S_OSK_FontHelper_NoFonts" comment="OSK Font helper no fonts found for keyboard">No fonts have been found as suggestions for keyboard %1$s.</string>
|
||||
|
||||
<!-- Context: Text Editor -->
|
||||
<!-- String Type: FormatString -->
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ BOOL SetupCoreEnvironment(km_core_option_item **core_environment) {
|
|||
|
||||
items[0].scope = KM_CORE_OPT_ENVIRONMENT;
|
||||
items[0].key = KM_CORE_KMX_ENV_BASELAYOUT;
|
||||
items[0].value = reinterpret_cast<km_core_cp*>(Globals::get_BaseKeyboardName());
|
||||
items[0].value = reinterpret_cast<km_core_cu*>(Globals::get_BaseKeyboardName());
|
||||
|
||||
items[1].scope = KM_CORE_OPT_ENVIRONMENT;
|
||||
items[1].key = KM_CORE_KMX_ENV_BASELAYOUTALT;
|
||||
items[1].value = reinterpret_cast<km_core_cp*>(Globals::get_BaseKeyboardNameAlt());
|
||||
items[1].value = reinterpret_cast<km_core_cu*>(Globals::get_BaseKeyboardNameAlt());
|
||||
|
||||
items[2].scope = KM_CORE_OPT_ENVIRONMENT;
|
||||
items[2].key = KM_CORE_KMX_ENV_SIMULATEALTGR;
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ ContextItemToAppContext(km_core_context_item *contextItems, PWSTR outBuf, DWORD
|
|||
buf[idx++] = static_cast<WCHAR> Uni_UTF32ToSurrogate1(km_core_context_it->character);
|
||||
buf[idx++] = static_cast<WCHAR> Uni_UTF32ToSurrogate2(km_core_context_it->character);
|
||||
} else {
|
||||
buf[idx++] = (km_core_cp)km_core_context_it->character;
|
||||
buf[idx++] = (km_core_cu)km_core_context_it->character;
|
||||
}
|
||||
break;
|
||||
case KM_CORE_CT_MARKER:
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ LogContext(km_core_state *lpCoreKeyboardState, uint8_t context_type) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
km_core_cp* buffer = km_core_state_context_debug(
|
||||
km_core_cu* buffer = km_core_state_context_debug(
|
||||
lpCoreKeyboardState,
|
||||
context_type == CONTEXT_CORE ? KM_CORE_DEBUG_CONTEXT_CACHED : KM_CORE_DEBUG_CONTEXT_INTERMEDIATE
|
||||
);
|
||||
|
|
@ -163,7 +163,7 @@ LogContext(km_core_state *lpCoreKeyboardState, uint8_t context_type) {
|
|||
|
||||
SendDebugMessageFormat(0, sdmKeyboard, 0, "%s: %ls", log_str_title, buffer);
|
||||
|
||||
km_core_cp_dispose(buffer);
|
||||
km_core_cu_dispose(buffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,15 +22,15 @@
|
|||
BOOL IntLoadKeyboardOptionsRegistrytoCore(LPCSTR key, LPINTKEYBOARDINFO kp, km_core_state* const state);
|
||||
void IntSaveKeyboardOptionCoretoRegistry(LPCSTR REGKey, LPINTKEYBOARDINFO kp, LPCWSTR key, LPCWSTR value);
|
||||
|
||||
static km_core_cp* CloneKeymanCoreCP(const km_core_cp* cp) {
|
||||
static km_core_cu* CloneKeymanCoreCP(const km_core_cu* cp) {
|
||||
LPCWSTR buf = reinterpret_cast<LPCWSTR>(cp);
|
||||
km_core_cp* clone = new km_core_cp[wcslen(buf) + 1];
|
||||
km_core_cu* clone = new km_core_cu[wcslen(buf) + 1];
|
||||
wcscpy_s(reinterpret_cast<LPWSTR>(clone), wcslen(buf) + 1, buf);
|
||||
return clone;
|
||||
}
|
||||
|
||||
static km_core_cp* CloneKeymanCoreCPFromWSTR(LPWSTR buf) {
|
||||
km_core_cp* clone = new km_core_cp[wcslen(buf) + 1];
|
||||
static km_core_cu* CloneKeymanCoreCPFromWSTR(LPWSTR buf) {
|
||||
km_core_cu* clone = new km_core_cu[wcslen(buf) + 1];
|
||||
wcscpy_s(reinterpret_cast<LPWSTR>(clone), wcslen(buf) + 1, buf);
|
||||
return clone;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ Process_Event_Core(PKEYMAN64THREADDATA _td) {
|
|||
WCHAR application_context[MAXCONTEXT];
|
||||
if (_td->app->ReadContext(application_context)) {
|
||||
km_core_context_status result;
|
||||
result = km_core_state_context_set_if_needed(_td->lpActiveKeyboard->lpCoreKeyboardState, reinterpret_cast<const km_core_cp *>(application_context));
|
||||
result = km_core_state_context_set_if_needed(_td->lpActiveKeyboard->lpCoreKeyboardState, reinterpret_cast<const km_core_cu *>(application_context));
|
||||
if (result == KM_CORE_CONTEXT_STATUS_ERROR || result == KM_CORE_CONTEXT_STATUS_INVALID_ARGUMENT) {
|
||||
SendDebugMessageFormat(0, sdmGlobal, 0, "Process_Event_Core: km_core_state_context_set_if_needed returned [%d]", result);
|
||||
}
|
||||
|
|
@ -127,13 +127,13 @@ BOOL ProcessHook()
|
|||
SendDebugMessageFormat(_td->state.msg.hwnd, sdmKeyboard, 0, "Key pressed: %s Context <unavailable>",
|
||||
Debug_VirtualKey(_td->state.vkey));
|
||||
} else {
|
||||
km_core_cp* debug_context = km_core_state_context_debug(
|
||||
km_core_cu* debug_context = km_core_state_context_debug(
|
||||
_td->lpActiveKeyboard->lpCoreKeyboardState,
|
||||
KM_CORE_DEBUG_CONTEXT_CACHED
|
||||
);
|
||||
SendDebugMessageFormat(_td->state.msg.hwnd, sdmKeyboard, 0, "Key pressed: %s Context '%ls'",
|
||||
Debug_VirtualKey(_td->state.vkey), debug_context);
|
||||
km_core_cp_dispose(debug_context);
|
||||
km_core_cu_dispose(debug_context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ TEST(KEYBOARDOPTIONS, SetupCoreEnvironment) {
|
|||
// These are taken from SetupCoreEnvironment in CoreEnvironment.cpp
|
||||
expected_items[0].scope = KM_CORE_OPT_ENVIRONMENT;
|
||||
expected_items[0].key = KM_CORE_KMX_ENV_BASELAYOUT;
|
||||
expected_items[0].value = reinterpret_cast<km_core_cp *>(Globals::get_BaseKeyboardName());
|
||||
expected_items[0].value = reinterpret_cast<km_core_cu *>(Globals::get_BaseKeyboardName());
|
||||
|
||||
expected_items[1].scope = KM_CORE_OPT_ENVIRONMENT;
|
||||
expected_items[1].key = KM_CORE_KMX_ENV_BASELAYOUTALT;
|
||||
expected_items[1].value = reinterpret_cast<km_core_cp *>(Globals::get_BaseKeyboardNameAlt());
|
||||
expected_items[1].value = reinterpret_cast<km_core_cu *>(Globals::get_BaseKeyboardNameAlt());
|
||||
|
||||
expected_items[2].scope = KM_CORE_OPT_ENVIRONMENT;
|
||||
expected_items[2].key = KM_CORE_KMX_ENV_SIMULATEALTGR;
|
||||
|
|
@ -38,7 +38,7 @@ TEST(KEYBOARDOPTIONS, SetupCoreEnvironment) {
|
|||
expected_items[3].value = KeyboardGivesCtrlRAltForRAlt() ? u"1" : u"0";
|
||||
|
||||
expected_items[4] = KM_CORE_OPTIONS_END;
|
||||
km_core_cp const* retValue = nullptr;
|
||||
km_core_cu const* retValue = nullptr;
|
||||
std::u16string value = u"";
|
||||
std::u16string expectedValue = u"";
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue