mirror of
https://github.com/keymanapp/keyman.git
synced 2026-10-08 06:57:29 +00:00
chore(common/models): Merge branch 'refactor/common/models/suggestion-and-keep-init' into fix/common/models/suggestions-after-whitespace
This commit is contained in:
commit
3bad0d18da
79 changed files with 2870 additions and 2293 deletions
15
HISTORY.md
15
HISTORY.md
|
|
@ -1,5 +1,20 @@
|
|||
# Keyman Version History
|
||||
|
||||
## 14.0.154 alpha 2020-10-05
|
||||
|
||||
* fix(windows): Upgrading keyboards with transient profiles (#3637)
|
||||
* fix(windows): upgrading disabled keyboards (#3638)
|
||||
* fix(developer): coverity reports for compiler (#3640)
|
||||
* fix(windows): coverity reports for mcompile (#3641)
|
||||
* fix(windows): coverity reports for kmtip (#3642)
|
||||
* fix(windows): coverity reports for keyman32 (#3649)
|
||||
* chore: exclude parens if no scope in commit msg (#3653)
|
||||
|
||||
## 14.0.153 alpha 2020-10-02
|
||||
|
||||
* chore(deps): bump @actions/core from 1.2.2 to 1.2.6 in /resources/build/version (#3646)
|
||||
* fix(android/app): Switch system keyboard in KMPBrowserActivity (#3648)
|
||||
|
||||
## 14.0.152 alpha 2020-09-30
|
||||
|
||||
* fix(ios/engine): package installation language-picker improvements (#3623)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
14.0.153
|
||||
14.0.155
|
||||
|
|
@ -16,15 +16,18 @@ import android.webkit.WebChromeClient;
|
|||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.tavultesoft.kmea.KMManager;
|
||||
import com.tavultesoft.kmea.KeyboardEventHandler;
|
||||
import com.tavultesoft.kmea.util.KMPLink;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class KMPBrowserActivity extends AppCompatActivity {
|
||||
public class KMPBrowserActivity extends AppCompatActivity implements KeyboardEventHandler.OnKeyboardEventListener {
|
||||
private static final String TAG = "KMPBrowserActivity";
|
||||
|
||||
// URL for keyboard search web page presented to user when they add a keyboard in the app.
|
||||
|
|
@ -133,6 +136,8 @@ public class KMPBrowserActivity extends AppCompatActivity {
|
|||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
KMManager.addKeyboardEventListener(this);
|
||||
|
||||
if (webView != null) {
|
||||
webView.reload();
|
||||
}
|
||||
|
|
@ -141,6 +146,7 @@ public class KMPBrowserActivity extends AppCompatActivity {
|
|||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
KMManager.removeKeyboardEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -148,6 +154,32 @@ public class KMPBrowserActivity extends AppCompatActivity {
|
|||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyboardLoaded(KMManager.KeyboardType keyboardType) {
|
||||
// Mitigation for https://github.com/keymanapp/keyman/issues/1963
|
||||
// Due to latency, switch from Keyman system keyboard to another
|
||||
if (KMManager.getKMKeyboard(KMManager.KeyboardType.KEYBOARD_TYPE_SYSTEM) != null) {
|
||||
Toast.makeText(getApplicationContext(), getString(R.string.switching_keyboard),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
KMManager.advanceToNextInputMode();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyboardChanged(String newKeyboard) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyboardShown() {
|
||||
//
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyboardDismissed() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
|
|
|||
|
|
@ -112,6 +112,8 @@
|
|||
<!-- Context: Keyman Settings "Install Keyboard or Dictionary" menu -->
|
||||
<string name="add_language_subtext" comment="Additional information for adding another language">(from keyboard package)</string>
|
||||
|
||||
<!-- Context: Keyman Settings "Install from keyman.com" menu -->
|
||||
<string name="switching_keyboard" comment="Switching to another keyboard">Switching to another keyboard</string>
|
||||
|
||||
<!-- Context: Select Package and Select Languages menu -->
|
||||
<string name="title_select_keyboard_package_list" comment="Select a keyboard package to add languages">Select Keyboard Package</string>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/input-processor",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/input-processor",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"description": "The core text and prediction processing engine for KeymanWeb",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
},
|
||||
"homepage": "https://github.com/keymanapp/keyman#readme",
|
||||
"devDependencies": {
|
||||
"@keymanapp/resources-gosh": "^14.0.153",
|
||||
"@keymanapp/resources-gosh": "^14.0.155",
|
||||
"chai": "^4.2.0",
|
||||
"mocha": "^5.2.0",
|
||||
"typescript": "^3.8.3"
|
||||
|
|
@ -29,11 +29,11 @@
|
|||
"test": "gosh ./unit_tests/test.sh"
|
||||
},
|
||||
"dependencies": {
|
||||
"@keymanapp/keyboard-processor": "^14.0.153",
|
||||
"@keymanapp/lexical-model-layer": "^14.0.153",
|
||||
"@keymanapp/models-types": "^14.0.153",
|
||||
"@keymanapp/web-environment": "^14.0.153",
|
||||
"@keymanapp/web-utils": "^14.0.153",
|
||||
"@keymanapp/keyboard-processor": "^14.0.155",
|
||||
"@keymanapp/lexical-model-layer": "^14.0.155",
|
||||
"@keymanapp/models-types": "^14.0.155",
|
||||
"@keymanapp/web-environment": "^14.0.155",
|
||||
"@keymanapp/web-utils": "^14.0.155",
|
||||
"@types/node": "^11.9.4",
|
||||
"eventemitter3": "^4.0.0",
|
||||
"ts-node": "^8.0.2"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/keyboard-processor",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/keyboard-processor",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"description": "Core module for Keyman keyboard support in KeymanWeb.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
},
|
||||
"homepage": "https://github.com/keymanapp/keyman#readme",
|
||||
"devDependencies": {
|
||||
"@keymanapp/resources-gosh": "^14.0.153",
|
||||
"@keymanapp/resources-gosh": "^14.0.155",
|
||||
"chai": "^4.2.0",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha-teamcity-reporter": "^3.0.0",
|
||||
|
|
@ -31,9 +31,9 @@
|
|||
"mocha": "mocha"
|
||||
},
|
||||
"dependencies": {
|
||||
"@keymanapp/models-types": "^14.0.153",
|
||||
"@keymanapp/web-environment": "^14.0.153",
|
||||
"@keymanapp/web-utils": "^14.0.153",
|
||||
"@keymanapp/models-types": "^14.0.155",
|
||||
"@keymanapp/web-environment": "^14.0.155",
|
||||
"@keymanapp/web-utils": "^14.0.155",
|
||||
"@types/node": "^11.9.4",
|
||||
"ts-node": "^8.0.2"
|
||||
}
|
||||
|
|
|
|||
2
common/core/web/tools/recorder/package-lock.json
generated
2
common/core/web/tools/recorder/package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/recorder-core",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/recorder-core",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"description": "Core classes used to develop KeymanWeb test cases based on keystrokes",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
|
@ -17,10 +17,10 @@
|
|||
},
|
||||
"homepage": "https://github.com/keymanapp/keyman#readme",
|
||||
"dependencies": {
|
||||
"@keymanapp/keyboard-processor": "^14.0.153",
|
||||
"@keymanapp/models-types": "^14.0.153",
|
||||
"@keymanapp/web-environment": "^14.0.153",
|
||||
"@keymanapp/web-utils": "^14.0.153"
|
||||
"@keymanapp/keyboard-processor": "^14.0.155",
|
||||
"@keymanapp/models-types": "^14.0.155",
|
||||
"@keymanapp/web-environment": "^14.0.155",
|
||||
"@keymanapp/web-utils": "^14.0.155"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^3.8.3"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/web-sentry-manager",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/web-sentry-manager",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"description": "Common setup for KeymanWeb's Sentry-based error reporting",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
"typescript": "^3.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@keymanapp/web-environment": "^14.0.153",
|
||||
"@keymanapp/web-environment": "^14.0.155",
|
||||
"@sentry/browser": "^5.15.5"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
common/core/web/utils/package-lock.json
generated
2
common/core/web/utils/package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/web-utils",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/web-utils",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"description": "Common utility functions used throughout other Keyman packages",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
|
|
@ -20,8 +20,8 @@
|
|||
},
|
||||
"homepage": "https://github.com/keymanapp/keyman#readme",
|
||||
"devDependencies": {
|
||||
"@keymanapp/resources-gosh": "^14.0.153",
|
||||
"@keymanapp/web-environment": "^14.0.153",
|
||||
"@keymanapp/resources-gosh": "^14.0.155",
|
||||
"@keymanapp/web-environment": "^14.0.155",
|
||||
"@types/node": "^14.0.5",
|
||||
"typescript": "^3.8.3"
|
||||
}
|
||||
|
|
|
|||
2
common/models/templates/package-lock.json
generated
2
common/models/templates/package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/models-templates",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/models-templates",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"description": "Backing model implementations (templates) for Keyman's modelling layer",
|
||||
"keywords": [
|
||||
"lm",
|
||||
|
|
@ -42,8 +42,8 @@
|
|||
"url": "https://github.com/keymanapp/keyman/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@keymanapp/models-types": "^14.0.153",
|
||||
"@keymanapp/web-utils": "^14.0.153",
|
||||
"@keymanapp/models-types": "^14.0.155",
|
||||
"@keymanapp/web-utils": "^14.0.155",
|
||||
"@types/chai": "^4.2.11",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/node": "^14.0.4",
|
||||
|
|
@ -52,6 +52,6 @@
|
|||
"typescript": "^3.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@keymanapp/models-wordbreakers": "^14.0.153"
|
||||
"@keymanapp/models-wordbreakers": "^14.0.155"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,11 +71,15 @@ namespace models {
|
|||
export function transformToSuggestion(transform: Transform): Suggestion;
|
||||
export function transformToSuggestion(transform: Transform, p: number): Suggestion & {p: number};
|
||||
export function transformToSuggestion(transform: Transform, p?: number): Suggestion & {p?: number} {
|
||||
return {
|
||||
let suggestion: Suggestion & {p?: number} = {
|
||||
transform: transform,
|
||||
transformId: transform.id,
|
||||
displayAs: transform.insert,
|
||||
p: p
|
||||
displayAs: transform.insert
|
||||
};
|
||||
|
||||
if(p === 0 || p) {
|
||||
suggestion.p = p;
|
||||
}
|
||||
return suggestion;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/// <reference path="./trie-model.ts" />
|
||||
/// <reference path="./quote-behavior.ts" />
|
||||
|
||||
// Add all namespaces defined here to the global scope:
|
||||
if (typeof module != 'undefined' && typeof module.exports != 'undefined') {
|
||||
|
|
|
|||
46
common/models/templates/src/quote-behavior.ts
Normal file
46
common/models/templates/src/quote-behavior.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
namespace models {
|
||||
export enum QuoteBehavior {
|
||||
noQuotes = "no-quotes",
|
||||
useQuotes = "use-quotes",
|
||||
default = "default-quotes"
|
||||
}
|
||||
|
||||
// For an "enum/namespace merge". See https://www.typescriptlang.org/docs/handbook/declaration-merging.html#merging-namespaces-with-classes
|
||||
export namespace QuoteBehavior {
|
||||
/**
|
||||
* Applies the specified quote behavior to the provided `Transform`, mutating it as appropriate.
|
||||
* @param transform The Transform to be mutated
|
||||
* @param punctuation The active `LexicalModelPunctuation` settings
|
||||
* @param defaultTo The default quote behavior to use (in case the current value is `.default`)
|
||||
*/
|
||||
export function apply(behavior: QuoteBehavior, text: string, punctuation: LexicalModelPunctuation, defaultTo: QuoteBehavior): string {
|
||||
if(defaultTo == QuoteBehavior.default || !defaultTo) {
|
||||
throw "Specified quote behavior may be ambiguous - default behavior not specified (may not be .default)";
|
||||
}
|
||||
|
||||
if(behavior == QuoteBehavior.default) {
|
||||
behavior = defaultTo;
|
||||
}
|
||||
|
||||
switch(behavior) {
|
||||
case QuoteBehavior.noQuotes:
|
||||
return text;
|
||||
case QuoteBehavior.useQuotes:
|
||||
let {open, close} = punctuation.quotesForKeepSuggestion;
|
||||
|
||||
// TODO: Is this the right thing to do under RTL?
|
||||
// We need an extra pass over this section to validate it.
|
||||
if(punctuation.isRTL) {
|
||||
let temp = close;
|
||||
close = open;
|
||||
open = temp;
|
||||
}
|
||||
|
||||
// This part's simple enough, at least.
|
||||
return open + text + close;
|
||||
default:
|
||||
throw "Unsupported quote behavior state detected; implementation missing!";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
70
common/models/templates/test/test-common.js
Normal file
70
common/models/templates/test/test-common.js
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Unit tests for common utility functions/methods.
|
||||
*/
|
||||
|
||||
var assert = require('chai').assert;
|
||||
var models = require('../').models;
|
||||
|
||||
describe('Common utility functions', function() {
|
||||
// TODO: unit tests for other common utility functions
|
||||
|
||||
describe('transformToSuggestion', function() {
|
||||
it('p: undefined', function() {
|
||||
let suggestion = {
|
||||
transform: {
|
||||
insert: 'hello',
|
||||
deleteLeft: 0,
|
||||
id: 0
|
||||
},
|
||||
transformId: 0,
|
||||
displayAs: 'hello'
|
||||
};
|
||||
|
||||
assert.deepEqual(models.transformToSuggestion(suggestion.transform), suggestion);
|
||||
});
|
||||
|
||||
it('p: 0', function() {
|
||||
let suggestion = {
|
||||
transform: {
|
||||
insert: 'hello',
|
||||
deleteLeft: 0,
|
||||
id: 0
|
||||
},
|
||||
transformId: 0,
|
||||
displayAs: 'hello',
|
||||
p: 0
|
||||
};
|
||||
|
||||
assert.deepEqual(models.transformToSuggestion(suggestion.transform, 0), suggestion);
|
||||
});
|
||||
|
||||
it('p > 0', function() {
|
||||
let suggestion = {
|
||||
transform: {
|
||||
insert: 'hello',
|
||||
deleteLeft: 0,
|
||||
id: 0
|
||||
},
|
||||
transformId: 0,
|
||||
displayAs: 'hello',
|
||||
p: 0.5
|
||||
};
|
||||
|
||||
assert.deepEqual(models.transformToSuggestion(suggestion.transform, 0.5), suggestion);
|
||||
});
|
||||
|
||||
it('properly handles the transformId', function() {
|
||||
let suggestion = {
|
||||
transform: {
|
||||
insert: 'hello',
|
||||
deleteLeft: 0,
|
||||
id: 3
|
||||
},
|
||||
transformId: 3, // Ensures there isn't a separate ID seed in use.
|
||||
displayAs: 'hello'
|
||||
};
|
||||
|
||||
assert.deepEqual(models.transformToSuggestion(suggestion.transform), suggestion);
|
||||
});
|
||||
});
|
||||
});
|
||||
150
common/models/templates/test/test-quote-behavior.js
Normal file
150
common/models/templates/test/test-quote-behavior.js
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Unit tests for quote behaviors.
|
||||
*/
|
||||
|
||||
var assert = require('chai').assert;
|
||||
var QuoteBehavior = require('../').models.QuoteBehavior;
|
||||
|
||||
describe('Quote behaviors', function() {
|
||||
describe('Script directionality', function() {
|
||||
it('(default)', function() {
|
||||
let englishPunctuation = {
|
||||
quotesForKeepSuggestion: { open: `“`, close: `”`},
|
||||
insertAfterWord: " "
|
||||
}
|
||||
|
||||
var plainQuotedHello;
|
||||
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.useQuotes);
|
||||
assert.equal(plainQuotedHello, "“hello”");
|
||||
});
|
||||
|
||||
it('LTR', function() {
|
||||
let englishPunctuation = {
|
||||
quotesForKeepSuggestion: { open: `“`, close: `”`},
|
||||
insertAfterWord: " ",
|
||||
isRTL: false
|
||||
}
|
||||
|
||||
var plainQuotedHello;
|
||||
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.useQuotes);
|
||||
assert.equal(plainQuotedHello, "“hello”");
|
||||
});
|
||||
|
||||
it.skip('RTL', function() {
|
||||
// TODO:
|
||||
});
|
||||
});
|
||||
|
||||
describe('Application', function() {
|
||||
it('.useQuotes', function() {
|
||||
let englishPunctuation = {
|
||||
quotesForKeepSuggestion: { open: `“`, close: `”`},
|
||||
insertAfterWord: " "
|
||||
}
|
||||
|
||||
var plainQuotedHello;
|
||||
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.useQuotes);
|
||||
assert.equal(plainQuotedHello, "“hello”");
|
||||
|
||||
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.noQuotes);
|
||||
assert.equal(plainQuotedHello, "“hello”");
|
||||
|
||||
let angleQuotePunctuation = {
|
||||
quotesForKeepSuggestion: { open: `«`, close: `»`},
|
||||
insertAfterWord: " "
|
||||
}
|
||||
|
||||
var angleQuotedHello;
|
||||
angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", angleQuotePunctuation, QuoteBehavior.useQuotes);
|
||||
assert.equal(angleQuotedHello, "«hello»");
|
||||
|
||||
angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", angleQuotePunctuation, QuoteBehavior.noQuotes);
|
||||
assert.equal(angleQuotedHello, "«hello»");
|
||||
});
|
||||
|
||||
it('.noQuotes', function() {
|
||||
let englishPunctuation = {
|
||||
quotesForKeepSuggestion: { open: `“`, close: `”`},
|
||||
insertAfterWord: " "
|
||||
}
|
||||
|
||||
var plainQuotedHello;
|
||||
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", englishPunctuation, QuoteBehavior.useQuotes);
|
||||
assert.equal(plainQuotedHello, "hello");
|
||||
|
||||
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", englishPunctuation, QuoteBehavior.noQuotes);
|
||||
assert.equal(plainQuotedHello, "hello");
|
||||
|
||||
let angleQuotePunctuation = {
|
||||
quotesForKeepSuggestion: { open: `«`, close: `»`},
|
||||
insertAfterWord: " "
|
||||
}
|
||||
|
||||
var angleQuotedHello;
|
||||
angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", angleQuotePunctuation, QuoteBehavior.useQuotes);
|
||||
assert.equal(angleQuotedHello, "hello");
|
||||
|
||||
angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", angleQuotePunctuation, QuoteBehavior.noQuotes);
|
||||
assert.equal(angleQuotedHello, "hello");
|
||||
});
|
||||
|
||||
it('.default -> .useQuotes', function() {
|
||||
let englishPunctuation = {
|
||||
quotesForKeepSuggestion: { open: `“`, close: `”`},
|
||||
insertAfterWord: " "
|
||||
}
|
||||
|
||||
var plainQuotedHello;
|
||||
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.default, "hello", englishPunctuation, QuoteBehavior.useQuotes);
|
||||
assert.equal(plainQuotedHello, "“hello”");
|
||||
|
||||
let angleQuotePunctuation = {
|
||||
quotesForKeepSuggestion: { open: `«`, close: `»`},
|
||||
insertAfterWord: " "
|
||||
}
|
||||
|
||||
var angleQuotedHello;
|
||||
angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.default, "hello", angleQuotePunctuation, QuoteBehavior.useQuotes);
|
||||
assert.equal(angleQuotedHello, "«hello»");
|
||||
});
|
||||
|
||||
it('.default -> .noQuotes', function() {
|
||||
let englishPunctuation = {
|
||||
quotesForKeepSuggestion: { open: `“`, close: `”`},
|
||||
insertAfterWord: " "
|
||||
}
|
||||
|
||||
var plainQuotedHello;
|
||||
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.default, "hello", englishPunctuation, QuoteBehavior.noQuotes);
|
||||
assert.equal(plainQuotedHello, "hello");
|
||||
|
||||
let angleQuotePunctuation = {
|
||||
quotesForKeepSuggestion: { open: `«`, close: `»`},
|
||||
insertAfterWord: " "
|
||||
}
|
||||
|
||||
var angleQuotedHello;
|
||||
angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.default, "hello", angleQuotePunctuation, QuoteBehavior.noQuotes);
|
||||
assert.equal(angleQuotedHello, "hello");
|
||||
});
|
||||
|
||||
it('Error case: .default as fall-back behavior', function() {
|
||||
let englishPunctuation = {
|
||||
quotesForKeepSuggestion: { open: `“`, close: `”`},
|
||||
insertAfterWord: " "
|
||||
}
|
||||
|
||||
assert.throws(function() {
|
||||
QuoteBehavior.apply(QuoteBehavior.default, "hello", englishPunctuation, QuoteBehavior.default);
|
||||
});
|
||||
|
||||
assert.throws(function() {
|
||||
QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.default);
|
||||
});
|
||||
|
||||
assert.throws(function() {
|
||||
QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", englishPunctuation, QuoteBehavior.default);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
2
common/models/types/package-lock.json
generated
2
common/models/types/package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/models-types",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/models-types",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"description": "Type definitions in used in the modeling (lexical model/predictive text) component of Keyman.",
|
||||
"types": "./index.d.ts",
|
||||
"scripts": {
|
||||
|
|
|
|||
2
common/models/wordbreakers/package-lock.json
generated
2
common/models/wordbreakers/package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/models-wordbreakers",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/models-wordbreakers",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"description": "Word breakers bundled in the modeling layer",
|
||||
"keywords": [
|
||||
"lexical model",
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
"url": "https://github.com/keymanapp/keyman/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@keymanapp/models-types": "^14.0.153",
|
||||
"@keymanapp/models-types": "^14.0.155",
|
||||
"@types/chai": "^4.2.11",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"chai": "^4.2.0",
|
||||
|
|
|
|||
2
common/predictive-text/package-lock.json
generated
2
common/predictive-text/package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/lexical-model-layer",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/lexical-model-layer",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"description": "Keyman/Predictive Text integration layer",
|
||||
"main": "build/index.js",
|
||||
"scripts": {
|
||||
|
|
@ -21,8 +21,8 @@
|
|||
},
|
||||
"homepage": "https://github.com/keymanapp/keyman#readme",
|
||||
"devDependencies": {
|
||||
"@keymanapp/models-types": "^14.0.153",
|
||||
"@keymanapp/resources-gosh": "^14.0.153",
|
||||
"@keymanapp/models-types": "^14.0.155",
|
||||
"@keymanapp/resources-gosh": "^14.0.155",
|
||||
"@types/node": "^10.17.21",
|
||||
"chai": "^4.2.0",
|
||||
"karma": "^4.2.0",
|
||||
|
|
@ -46,10 +46,10 @@
|
|||
"typescript": "^3.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@keymanapp/models-templates": "^14.0.153",
|
||||
"@keymanapp/models-wordbreakers": "^14.0.153",
|
||||
"@keymanapp/web-environment": "^14.0.153",
|
||||
"@keymanapp/web-utils": "^14.0.153",
|
||||
"@keymanapp/models-templates": "^14.0.155",
|
||||
"@keymanapp/models-wordbreakers": "^14.0.155",
|
||||
"@keymanapp/web-environment": "^14.0.155",
|
||||
"@keymanapp/web-utils": "^14.0.155",
|
||||
"es6-shim": "^0.35.5",
|
||||
"string.prototype.codepointat": "^0.2.1",
|
||||
"string.prototype.startswith": "^0.2.0"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
* Integration tests for the model compositor with the trie model.
|
||||
*/
|
||||
|
||||
const { models } = require('../../build/intermediate');
|
||||
|
||||
var assert = require('chai').assert;
|
||||
var TrieModel = require('../../build/intermediate').models.TrieModel;
|
||||
var ModelCompositor = require('../../build/intermediate').ModelCompositor;
|
||||
|
|
@ -66,4 +68,70 @@ describe('ModelCompositor', function() {
|
|||
// 'the' should be the intended the result here.
|
||||
assert.isAbove(theSuggestion.p, thrSuggestion.p);
|
||||
});
|
||||
|
||||
// The nomenclature's a minor sneak-peek from child PRs.
|
||||
describe('toAnnotatedSuggestion', function() {
|
||||
let baseSuggestion = {
|
||||
transform: {
|
||||
insert: 'hello',
|
||||
deleteLeft: 0,
|
||||
id: 0
|
||||
},
|
||||
transformId: 0,
|
||||
displayAs: 'hello'
|
||||
};
|
||||
|
||||
let englishPunctuation = {
|
||||
quotesForKeepSuggestion: { open: `“`, close: `”`},
|
||||
insertAfterWord: ' '
|
||||
};
|
||||
|
||||
let angledPunctuation = {
|
||||
quotesForKeepSuggestion: { open: `«`, close: `»`},
|
||||
insertAfterWord: " "
|
||||
}
|
||||
|
||||
describe("'keep'", function() {
|
||||
let annotationTest = function(punctuation, displayText, quoteStyle) {
|
||||
let options = {
|
||||
punctuation: punctuation
|
||||
};
|
||||
|
||||
let model = new models.DummyModel(options);
|
||||
let compositor = new ModelCompositor(model);
|
||||
|
||||
var keep;
|
||||
if(quoteStyle) {
|
||||
keep = compositor.toAnnotatedKeepSuggestion(baseSuggestion, quoteStyle);
|
||||
} else {
|
||||
keep = compositor.toAnnotatedKeepSuggestion(baseSuggestion);
|
||||
}
|
||||
|
||||
// Make sure we didn't accidentally leak any mutations to the parameter.
|
||||
assert.notDeepEqual(keep, baseSuggestion);
|
||||
|
||||
assert.equal(keep.displayAs, displayText);
|
||||
assert.equal(keep.tag, 'keep');
|
||||
}
|
||||
|
||||
it('quoteBehavior: (.default)', function() {
|
||||
annotationTest(englishPunctuation, "“hello”");
|
||||
annotationTest(angledPunctuation, "«hello»");
|
||||
});
|
||||
|
||||
it('quoteBehavior: .useQuotes', function() {
|
||||
annotationTest(englishPunctuation, "“hello”", models.QuoteBehavior.useQuotes);
|
||||
annotationTest(angledPunctuation, "«hello»", models.QuoteBehavior.useQuotes);
|
||||
});
|
||||
|
||||
it('quoteBehavior: .noQuotes', function() {
|
||||
annotationTest(englishPunctuation, "hello", models.QuoteBehavior.noQuotes);
|
||||
annotationTest(angledPunctuation, "hello", models.QuoteBehavior.noQuotes);
|
||||
});
|
||||
|
||||
it.skip('RTL test', function() {
|
||||
// TODO:
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ class ModelCompositor {
|
|||
}
|
||||
|
||||
keepOption = models.transformToSuggestion(keepTransform, prediction.p);
|
||||
keepOption = this.toAnnotatedKeepSuggestion(keepOption, true);
|
||||
keepOption = this.toAnnotatedKeepSuggestion(keepOption, models.QuoteBehavior.noQuotes);
|
||||
} else {
|
||||
let existingSuggestion = suggestionDistribMap[displayText];
|
||||
if(existingSuggestion) {
|
||||
|
|
@ -296,25 +296,18 @@ class ModelCompositor {
|
|||
return suggestions;
|
||||
}
|
||||
|
||||
private toAnnotatedKeepSuggestion(suggestion: Suggestion & {p?: number}, noQuotes: boolean = false): Suggestion & {p?: number} {
|
||||
let { open, close } = this.punctuation.quotesForKeepSuggestion;
|
||||
|
||||
if(noQuotes) {
|
||||
open = '';
|
||||
close = '';
|
||||
} else if(this.punctuation.isRTL) {
|
||||
let temp = close;
|
||||
close = open;
|
||||
open = temp;
|
||||
}
|
||||
private toAnnotatedKeepSuggestion(suggestion: Suggestion & {p?: number},
|
||||
quoteBehavior: models.QuoteBehavior = models.QuoteBehavior.default): Suggestion & {p?: number} {
|
||||
// A method-internal 'import' of the enum.
|
||||
let QuoteBehavior = models.QuoteBehavior;
|
||||
|
||||
return {
|
||||
transform: suggestion.transform,
|
||||
transformId: suggestion.transformId,
|
||||
displayAs: open + suggestion.displayAs + close,
|
||||
displayAs: QuoteBehavior.apply(quoteBehavior, suggestion.displayAs, this.punctuation, QuoteBehavior.useQuotes),
|
||||
tag: 'keep',
|
||||
p: suggestion.p
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
2
developer/js/package-lock.json
generated
2
developer/js/package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/lexical-model-compiler",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/lexical-model-compiler",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"description": "Keyman Developer lexical model compiler",
|
||||
"keywords": [
|
||||
"keyboard",
|
||||
|
|
@ -37,14 +37,14 @@
|
|||
"node": ">=12.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@keymanapp/models-types": "^14.0.153",
|
||||
"@keymanapp/models-types": "^14.0.155",
|
||||
"commander": "^3.0.0",
|
||||
"typescript": "^3.8.3",
|
||||
"xml2js": "^0.4.19"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@keymanapp/models-templates": "^14.0.153",
|
||||
"@keymanapp/models-wordbreakers": "^14.0.153",
|
||||
"@keymanapp/models-templates": "^14.0.155",
|
||||
"@keymanapp/models-wordbreakers": "^14.0.155",
|
||||
"@types/chai": "^4.1.7",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^10.14.6",
|
||||
|
|
|
|||
|
|
@ -16,5 +16,5 @@
|
|||
"lerna",
|
||||
"typescript"
|
||||
],
|
||||
"version": "14.0.153"
|
||||
"version": "14.0.155"
|
||||
}
|
||||
|
|
|
|||
6
resources/build/version/package-lock.json
generated
6
resources/build/version/package-lock.json
generated
|
|
@ -5,9 +5,9 @@
|
|||
"requires": true,
|
||||
"dependencies": {
|
||||
"@actions/core": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.2.tgz",
|
||||
"integrity": "sha512-IbCx7oefq+Gi6FWbSs2Fnw8VkEI6Y4gvjrYprY3RV//ksq/KPMlClOerJ4jRosyal6zkUIc8R9fS/cpRMlGClg=="
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz",
|
||||
"integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA=="
|
||||
},
|
||||
"@actions/github": {
|
||||
"version": "2.1.0",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.2.2",
|
||||
"@actions/core": "^1.2.6",
|
||||
"@actions/github": "^2.1.0",
|
||||
"typescript": "^3.7.5",
|
||||
"yargs": "^15.1.0"
|
||||
|
|
|
|||
|
|
@ -96,7 +96,12 @@ function prepend_scope() {
|
|||
else
|
||||
postfix=""
|
||||
fi
|
||||
prefix="$TYPE($SCOPE): $EXTRA_WHITESPACE"
|
||||
|
||||
if [ -z "$SCOPE" ]; then
|
||||
prefix="$TYPE: $EXTRA_WHITESPACE"
|
||||
else
|
||||
prefix="$TYPE($SCOPE): $EXTRA_WHITESPACE"
|
||||
fi
|
||||
|
||||
# Reuse any existing message text, wrapping it in our conventional commit formatting before
|
||||
# presenting it to the user for any final edits.
|
||||
|
|
|
|||
2
resources/gosh/package-lock.json
generated
2
resources/gosh/package-lock.json
generated
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@keymanapp/resources-gosh",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"lockfileVersion": 1
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/resources-gosh",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"description": "Good Ol' Shell",
|
||||
"author": "Marc Durdin <marc@keyman.com> (https://github.com/mcdurdin)",
|
||||
"contributors": [
|
||||
|
|
|
|||
2
resources/web-environment/package-lock.json
generated
2
resources/web-environment/package-lock.json
generated
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@keymanapp/web-environment",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"lockfileVersion": 1
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@keymanapp/web-environment",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"description": "A compilation utility for passing select environment variables into our TS builds",
|
||||
"author": "Joshua Horton <joshua_horton@sil.org> (https://github.com/jahorton)",
|
||||
"homepage": "https://github.com/keymanapp/keyman",
|
||||
|
|
@ -17,6 +17,6 @@
|
|||
"url": "https://github.com/keymanapp/keyman/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@keymanapp/resources-gosh": "^14.0.153"
|
||||
"@keymanapp/resources-gosh": "^14.0.155"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
web/package-lock.json
generated
2
web/package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "keyman",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "keyman",
|
||||
"version": "14.0.153",
|
||||
"version": "14.0.155",
|
||||
"description": "Facilitates text input in any language.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
@ -18,8 +18,8 @@
|
|||
},
|
||||
"homepage": "https://github.com/keymanapp/keyman#readme",
|
||||
"devDependencies": {
|
||||
"@keymanapp/resources-gosh": "^14.0.153",
|
||||
"@keymanapp/web-sentry-manager": "^14.0.153",
|
||||
"@keymanapp/resources-gosh": "^14.0.155",
|
||||
"@keymanapp/web-sentry-manager": "^14.0.155",
|
||||
"@sentry/cli": "^1.52.3",
|
||||
"chai": "^4.2.0",
|
||||
"google-closure-compiler-java": "^20200224.0.0",
|
||||
|
|
@ -52,13 +52,13 @@
|
|||
"sentry-cli": "sentry-cli"
|
||||
},
|
||||
"dependencies": {
|
||||
"@keymanapp/input-processor": "^14.0.153",
|
||||
"@keymanapp/keyboard-processor": "^14.0.153",
|
||||
"@keymanapp/lexical-model-layer": "^14.0.153",
|
||||
"@keymanapp/models-types": "^14.0.153",
|
||||
"@keymanapp/recorder-core": "^14.0.153",
|
||||
"@keymanapp/web-environment": "^14.0.153",
|
||||
"@keymanapp/web-utils": "^14.0.153",
|
||||
"@keymanapp/input-processor": "^14.0.155",
|
||||
"@keymanapp/keyboard-processor": "^14.0.155",
|
||||
"@keymanapp/lexical-model-layer": "^14.0.155",
|
||||
"@keymanapp/models-types": "^14.0.155",
|
||||
"@keymanapp/recorder-core": "^14.0.155",
|
||||
"@keymanapp/web-environment": "^14.0.155",
|
||||
"@keymanapp/web-utils": "^14.0.155",
|
||||
"@types/node": "^11.9.4",
|
||||
"es6-shim": "^0.35.5",
|
||||
"eventemitter3": "^4.0.0",
|
||||
|
|
|
|||
|
|
@ -193,6 +193,11 @@ test-uiaccess:
|
|||
# * tar must be on path
|
||||
#
|
||||
|
||||
!ifndef COVBUILD
|
||||
test-coverity:
|
||||
echo Set variable COVBUILD to covbuild.exe
|
||||
exit 1
|
||||
!else
|
||||
test-coverity:
|
||||
cd $(ROOT)\src
|
||||
if exist cov-int rd /s/q cov-int
|
||||
|
|
@ -218,6 +223,7 @@ test-coverity-internal:
|
|||
$(MAKE) build
|
||||
cd $(ROOT)\src\engine\mcompile
|
||||
$(MAKE) build
|
||||
!endif
|
||||
|
||||
# Build a release
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ uses
|
|||
UImportOlderVersionKeyboards9Plus,
|
||||
UImportOlderKeyboardUtils,
|
||||
utilexecute,
|
||||
utilkmshell,
|
||||
utiltsf;
|
||||
|
||||
class procedure TImportOlderVersionKeyboards11To13.Execute; // I2361
|
||||
|
|
@ -52,7 +53,7 @@ end;
|
|||
type
|
||||
TUpgradeKeyboard = record
|
||||
KeyboardID: string;
|
||||
LangID: Integer;
|
||||
BCP47Code: string;
|
||||
end;
|
||||
TUpgradeKeyboardList = class(TList<TUpgradeKeyboard>);
|
||||
|
||||
|
|
@ -81,12 +82,9 @@ class procedure TImportOlderVersionKeyboards11To13.BackupCurrentUser;
|
|||
r.GetKeyNames(profiles);
|
||||
for profile in profiles do
|
||||
begin
|
||||
if r.OpenKeyReadOnly('\' + BuildKeyboardLanguageProfilesKey_LM(keyboard) + '\' + profile) and r.ValueExists(SRegValue_LanguageProfileLangID) then
|
||||
begin
|
||||
uk.KeyboardID := keyboard;
|
||||
uk.LangID := r.ReadInteger(SRegValue_LanguageProfileLangID);
|
||||
Result.Add(uk);
|
||||
end;
|
||||
uk.KeyboardID := keyboard;
|
||||
uk.BCP47Code := profile;
|
||||
Result.Add(uk);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
|
@ -101,19 +99,23 @@ var
|
|||
r: TRegistry;
|
||||
i: Integer;
|
||||
uks: TUpgradeKeyboardList;
|
||||
uk: TUpgradeKeyboard;
|
||||
begin
|
||||
// TODO: figure out Keyman "disabled" keyboards
|
||||
// TODO: figure out transient language registrations
|
||||
uks := LoadUpgradeKeyboards;
|
||||
r := TRegistry.Create;
|
||||
try
|
||||
if not r.OpenKey(SRegKey_Keyman_Temp_BackupProfiles, True) then
|
||||
Exit;
|
||||
|
||||
for i := 0 to uks.Count - 1 do
|
||||
i := 0;
|
||||
for uk in uks do
|
||||
begin
|
||||
r.WriteString(IntToStr(i), uks[i].KeyboardID+'='+IntToStr(uks[i].LangID));
|
||||
// For transient language codes, we will need to install using an assigned id
|
||||
// which may vary, so we will work from the BCP47 code.
|
||||
r.WriteString(IntToStr(i), uk.KeyboardID+'='+uk.BCP47Code);
|
||||
Inc(i);
|
||||
end;
|
||||
|
||||
finally
|
||||
r.Free;
|
||||
uks.Free;
|
||||
|
|
@ -170,6 +172,7 @@ begin
|
|||
keys.Free;
|
||||
end;
|
||||
|
||||
// The following code re-registers all the profiles
|
||||
kmcom.Refresh;
|
||||
(kmcom.Keyboards as IKeymanKeyboardsInstalled2).RefreshInstalledKeyboards;
|
||||
end;
|
||||
|
|
@ -180,6 +183,13 @@ var
|
|||
strings: TStringList;
|
||||
s: string;
|
||||
p: TArray<string>;
|
||||
BCP47Code, KeyboardID: string;
|
||||
LangID: Integer;
|
||||
kbd: IKeymanKeyboardInstalled;
|
||||
lang: IKeymanKeyboardLanguageInstalled2;
|
||||
TemporaryKeyboardID: WideString;
|
||||
RegistrationRequired: WordBool;
|
||||
i: Integer;
|
||||
begin
|
||||
r := TRegistry.Create;
|
||||
strings := TStringList.Create;
|
||||
|
|
@ -191,17 +201,94 @@ begin
|
|||
|
||||
for s in strings do
|
||||
begin
|
||||
// each string is saved in BackupCurrentUser and is keyboardid=langid
|
||||
// each string is saved in BackupCurrentUser and is keyboardid=bcp47
|
||||
p := r.ReadString(s).Split(['=']);
|
||||
kmcom.Keyboards[p[0]].Languages.InstallByLangID(StrToInt(p[1]));
|
||||
KeyboardID := p[0];
|
||||
BCP47Code := p[1];
|
||||
kbd := kmcom.Keyboards[KeyboardID];
|
||||
if not Assigned(kbd) then
|
||||
begin
|
||||
// Avoid errors if a package is uninstalled midway through
|
||||
Continue;
|
||||
end;
|
||||
|
||||
// Installing a language is a 2-step process. (We can assume that
|
||||
// the transient language codes have been installed correctly as Register
|
||||
// would have been called immediately prior to this.)
|
||||
lang := nil;
|
||||
BCP47Code := (kmcom as IKeymanBCP47Canonicalization).GetCanonicalTag(BCP47Code);
|
||||
for i := 0 to kbd.Languages.Count - 1 do
|
||||
begin
|
||||
if SameText(kbd.Languages[i].BCP47Code, BCP47Code) then
|
||||
begin
|
||||
lang := kbd.Languages[i] as IKeymanKeyboardLanguageInstalled2;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
|
||||
if lang = nil then
|
||||
begin
|
||||
// The BCP47 code was not in the list of languages; this could possibly
|
||||
// happen if we had registered a code that was canonicalized differently
|
||||
// in the past?
|
||||
lang := (kbd.Languages as IKeymanKeyboardLanguagesInstalled2).Add(BCP47Code) as IKeymanKeyboardLanguageInstalled2;
|
||||
if lang = nil then
|
||||
begin
|
||||
// This should never happen, because .Add only fails if the language
|
||||
// is already in the list, which we just searched through, or if the
|
||||
// BCP47Code is empty
|
||||
Continue;
|
||||
end;
|
||||
end;
|
||||
|
||||
if lang.IsInstalled then
|
||||
begin
|
||||
// Don't attempt to reinstall; this should not normally be the case but
|
||||
// if we canonicalize two languages which were previously installed into
|
||||
// a single code, then in theory this could happen.
|
||||
Continue;
|
||||
end;
|
||||
|
||||
if lang.FindInstallationLangID(LangID, TemporaryKeyboardID, RegistrationRequired, kifInstallTransientLanguage) then
|
||||
begin
|
||||
if RegistrationRequired then
|
||||
begin
|
||||
// This can happen for custom language codes. TODO: This is not ideal because of potential for multiple elevation prompts
|
||||
WaitForElevatedConfiguration(0, '-register-tip '+IntToHex(LangID,4)+' "'+KeyboardID+'" "'+lang.BCP47Code+'"');
|
||||
end;
|
||||
|
||||
lang.InstallTip(LangID, TemporaryKeyboardID);
|
||||
end;
|
||||
end;
|
||||
|
||||
r.CloseKey;
|
||||
r.DeleteKey(SRegKey_Keyman_Temp_BackupProfiles);
|
||||
|
||||
//
|
||||
// Reapply the loaded state for keyboards; this may cause TIPs to disappear again
|
||||
//
|
||||
|
||||
kmcom.Refresh;
|
||||
|
||||
if r.OpenKeyReadOnly('\' + SRegKey_ActiveKeyboards_CU) then
|
||||
begin
|
||||
strings.Clear;
|
||||
r.GetKeyNames(strings);
|
||||
for s in strings do
|
||||
begin
|
||||
kbd := kmcom.Keyboards[s];
|
||||
if Assigned(kbd) then
|
||||
kbd.Loaded := r.OpenKeyReadOnly('\' + SRegKey_ActiveKeyboards_CU + '\' + s) and r.ValueExists(SRegValue_KeymanID);
|
||||
end;
|
||||
end;
|
||||
|
||||
finally
|
||||
strings.Free;
|
||||
r.Free;
|
||||
end;
|
||||
|
||||
kmcom.Apply;
|
||||
kmcom.Refresh;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -172,18 +172,23 @@ BOOL NamedCodeConstants::LoadFile(const char *filename)
|
|||
|
||||
void NamedCodeConstants::reindex()
|
||||
{
|
||||
qsort(entries, nEntries, sizeof(NCCENTRY), sort_entries);
|
||||
if (entries != NULL) {
|
||||
qsort(entries, nEntries, sizeof(NCCENTRY), sort_entries);
|
||||
}
|
||||
|
||||
char c = '.', d;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 128; i++) chrindexes[i] = -1;
|
||||
for(i = 0; i < nEntries; i++)
|
||||
{
|
||||
d = toupper(entries[i].name[0]);
|
||||
if(d != c && d >= 32 && d <= 127)
|
||||
chrindexes[c = d] = i;
|
||||
}
|
||||
|
||||
if (entries != NULL) {
|
||||
for (i = 0; i < nEntries; i++)
|
||||
{
|
||||
d = toupper(entries[i].name[0]);
|
||||
if (d != c && d >= 32 && d <= 127)
|
||||
chrindexes[c = d] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int NamedCodeConstants::GetCode(const char *codename, DWORD *storeIndex)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
int WINAPI msgproc(int line, DWORD dwMsgCode, LPSTR szText)
|
||||
{
|
||||
printf("line %d error %x %s\n", line, dwMsgCode, szText);
|
||||
printf("line %d error %x %s\n", line, (unsigned int) dwMsgCode, szText);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
BOOL AddCompileString(LPSTR buf);
|
||||
BOOL AddCompileMessage(DWORD msg);
|
||||
|
||||
#define SetError(err) { if(AddCompileMessage(err)) return FALSE; }
|
||||
#define SetError(err) { if(AddCompileMessage(err) || (err & (CERR_MEMORY|CERR_FATAL))) return FALSE; }
|
||||
#define AddWarning(warn) { if(AddCompileMessage(warn)) return FALSE; }
|
||||
|
||||
extern BOOL FWarnDeprecatedCode;
|
||||
extern int currentLine;
|
||||
extern int currentLine;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ BOOL CheckKeyboardFinalVersion(PFILE_KEYBOARD fk) {
|
|||
fk->version = VERSION_60; // minimum version that we can be safe with
|
||||
}
|
||||
|
||||
wsprintf(buf, "The compiler has assigned a minimum engine version of %d.%d based on features used in this keyboard", (fk->version & 0xFF00) >> 8, fk->version & 0xFF);
|
||||
wsprintf(buf, "The compiler has assigned a minimum engine version of %d.%d based on features used in this keyboard", (int)((fk->version & 0xFF00) >> 8), (int)(fk->version & 0xFF));
|
||||
AddCompileString(buf);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char *file, i
|
|||
WCHAR windowinfo[1024];
|
||||
wsprintfW(windowinfo,
|
||||
DEBUG_PLATFORM_STRINGW TAB //"Platform" TAB
|
||||
L"%s" TAB //"Process" TAB
|
||||
L"%ls" TAB //"Process" TAB
|
||||
L"%x" TAB //"PID" TAB
|
||||
L"%x" TAB //"TID" TAB
|
||||
L"%x" TAB //"ShiftState" TAB
|
||||
|
|
@ -77,15 +77,15 @@ extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char *file, i
|
|||
L"%x" TAB //"FocusHWND" TAB
|
||||
L"%8x" TAB //"ActiveHKL" TAB
|
||||
L"%hs:%d" TAB //"SourceFile" TAB
|
||||
L"%s\n", //"Message"
|
||||
L"%ls\n", //"Message"
|
||||
sProcessName, //"Process" TAB
|
||||
pid, //"PID" TAB
|
||||
tid, //"TID" TAB
|
||||
shiftState, //"ShiftState" TAB
|
||||
actualShiftState, // ActualShiftState TAB
|
||||
tickCount, //"TickCount" TAB
|
||||
gti.hwndFocus, //"FocusHWND" TAB
|
||||
activeHKL, //"ActiveHKL" TAB
|
||||
(unsigned int) pid, //"PID" TAB
|
||||
(unsigned int) tid, //"TID" TAB
|
||||
(unsigned int) shiftState, //"ShiftState" TAB
|
||||
(unsigned int) actualShiftState, // ActualShiftState TAB
|
||||
(int) tickCount, //"TickCount" TAB
|
||||
PtrToInt(gti.hwndFocus), //"FocusHWND" TAB
|
||||
PtrToInt(activeHKL), //"ActiveHKL" TAB
|
||||
file, line, //"SourceFile" TAB
|
||||
msg); //"Message"
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ BOOL GetKeyboardFileName(LPSTR kbname, LPSTR buf, int nbuf)
|
|||
if(!_td) return FALSE;
|
||||
if(_td->ForceFileName[0])
|
||||
{
|
||||
strncpy_s(buf, nbuf, _td->ForceFileName, nbuf);
|
||||
strncpy_s(buf, nbuf, _td->ForceFileName, nbuf - 1);
|
||||
buf[nbuf-1] = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ BOOL LoadlpKeyboard(int i)
|
|||
if(_td->lpActiveKeyboard == &_td->lpKeyboards[i]) _td->lpActiveKeyboard = NULL; // I822 TSF not working
|
||||
|
||||
char buf[256];
|
||||
if(!GetKeyboardFileName(_td->lpKeyboards[i].Name, buf, 256)) return FALSE;
|
||||
if(!GetKeyboardFileName(_td->lpKeyboards[i].Name, buf, 255)) return FALSE;
|
||||
|
||||
if(!LoadKeyboard(buf, &_td->lpKeyboards[i].Keyboard)) return FALSE; // I5136
|
||||
|
||||
|
|
@ -205,11 +205,14 @@ BOOL LoadKeyboard(LPSTR fileName, LPKEYBOARD *lpKeyboard)
|
|||
CloseHandle(hFile);
|
||||
|
||||
PKEYMAN64THREADDATA _td = ThreadGlobals();
|
||||
if(!_td) return FALSE;
|
||||
if (!_td) {
|
||||
delete[] buf;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(*LPDWORD(filebase) != FILEID_COMPILED)
|
||||
{
|
||||
delete buf;
|
||||
delete[] buf;
|
||||
Err("Invalid file");
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,10 +246,17 @@ void DoCWMF(UINT msg)
|
|||
|
||||
void DoChangeWindowMessageFilter()
|
||||
{
|
||||
PChangeWindowMessageFilter = (BOOL (WINAPI *)(UINT,DWORD))GetProcAddress(LoadLibrary("user32"), "ChangeWindowMessageFilter");
|
||||
HMODULE hUser32 = LoadLibrary("user32");
|
||||
if (!hUser32)
|
||||
return;
|
||||
|
||||
if(!PChangeWindowMessageFilter)
|
||||
return;
|
||||
PChangeWindowMessageFilter = (BOOL (WINAPI *)(UINT,DWORD))GetProcAddress(hUser32, "ChangeWindowMessageFilter");
|
||||
|
||||
if (!PChangeWindowMessageFilter)
|
||||
{
|
||||
FreeLibrary(hUser32);
|
||||
return;
|
||||
}
|
||||
|
||||
DoCWMF(wm_keyman); // I3594
|
||||
DoCWMF(wm_keyman_keyevent);
|
||||
|
|
@ -263,6 +270,8 @@ void DoChangeWindowMessageFilter()
|
|||
DoCWMF(wm_keymanshift);
|
||||
DoCWMF(wm_keyman_control); // I4714
|
||||
DoCWMF(wm_keyman_control_internal); // I4714
|
||||
|
||||
FreeLibrary(hUser32);
|
||||
}
|
||||
|
||||
BOOL InitThread(HWND hwnd)
|
||||
|
|
@ -591,7 +600,7 @@ extern "C" BOOL _declspec(dllexport) WINAPI Keyman_ForceKeyboard(PCSTR FileName
|
|||
PKEYMAN64THREADDATA _td = ThreadGlobals();
|
||||
if(!_td) return FALSE;
|
||||
|
||||
strncpy(_td->ForceFileName, FileName, MAX_PATH);
|
||||
strncpy(_td->ForceFileName, FileName, MAX_PATH - 1);
|
||||
_td->ForceFileName[MAX_PATH-1] = 0;
|
||||
|
||||
if(_td->lpActiveKeyboard)
|
||||
|
|
@ -767,7 +776,7 @@ BOOL ConvertStringToGuid(WCHAR *buf, GUID *guid) // I3581
|
|||
}
|
||||
|
||||
void LoadBaseLayoutSettings() { // I4552 // I4583
|
||||
char underlyingLayout[16];
|
||||
char underlyingLayout[16] = "";
|
||||
wchar_t baseLayout[MAX_PATH];
|
||||
DWORD dwUnderlyingLayout = 0;
|
||||
|
||||
|
|
@ -776,7 +785,7 @@ void LoadBaseLayoutSettings() { // I4552 // I4583
|
|||
if(reg->OpenKeyReadOnly(REGSZ_KeymanCU)) {
|
||||
if(reg->ReadString(REGSZ_UnderlyingLayout, underlyingLayout, 15)) {
|
||||
dwUnderlyingLayout = strtoul(underlyingLayout, NULL, 16); // I4516 // I4581
|
||||
wsprintf(underlyingLayout, "%08x", dwUnderlyingLayout); // I3759 // I4581
|
||||
wsprintf(underlyingLayout, "%08x", (unsigned int) dwUnderlyingLayout); // I3759 // I4581
|
||||
} else {
|
||||
underlyingLayout[0] = 0;
|
||||
}
|
||||
|
|
@ -797,7 +806,7 @@ void LoadBaseLayoutSettings() { // I4552 // I4583
|
|||
|
||||
if(GetLocaleInfoW(LOWORD(dwUnderlyingLayout), LOCALE_SISO639LANGNAME, langName, _countof(langName)) > 0 &&
|
||||
GetLocaleInfoW(LOWORD(dwUnderlyingLayout), LOCALE_SISO3166CTRYNAME, countryName, _countof(countryName)) > 0) { // I4588 // I4786
|
||||
wsprintfW(baseLayoutAlt, L"%s-%s", langName, countryName);
|
||||
wsprintfW(baseLayoutAlt, L"%ls-%ls", langName, countryName);
|
||||
Globals::SetBaseKeyboardName(baseLayout, baseLayoutAlt);
|
||||
} else {
|
||||
Globals::SetBaseKeyboardName(baseLayout, L"en-US"); // I4786
|
||||
|
|
@ -864,7 +873,7 @@ void RefreshKeyboards(BOOL Initialising)
|
|||
char oldname[_MAX_FNAME];
|
||||
|
||||
PKEYMAN64THREADDATA _td = ThreadGlobals();
|
||||
if(_td->FInRefreshKeyboards) return;
|
||||
if(!_td || _td->FInRefreshKeyboards) return;
|
||||
_td->FInRefreshKeyboards = TRUE;
|
||||
|
||||
// Can happen when multiple top-level windows for one process
|
||||
|
|
@ -922,7 +931,7 @@ void RefreshKeyboards(BOOL Initialising)
|
|||
if(_td->lpKeyboards)
|
||||
{
|
||||
memcpy(kp, _td->lpKeyboards, sizeof(INTKEYBOARDINFO)*_td->nKeyboards);
|
||||
delete _td->lpKeyboards;
|
||||
delete[] _td->lpKeyboards;
|
||||
}
|
||||
_td->nKeyboards = nk + 1;
|
||||
_td->lpKeyboards = kp;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ private:
|
|||
|
||||
public:
|
||||
SharedBufferManager() {
|
||||
m_pSharedData = NULL;
|
||||
m_hMMF = OpenFileMapping(FILE_MAP_READ, FALSE, GLOBAL_SHAREDBUFFER_FILE_MAPPING_NAME);
|
||||
if (!m_hMMF) {
|
||||
DebugLastError("OpenFileMapping");
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ void Addin_Release()
|
|||
if(_td->Addins[i].Uninitialise) (*_td->Addins[i].Uninitialise)();
|
||||
FreeLibrary(_td->Addins[i].hAddin);
|
||||
}
|
||||
delete _td->Addins;
|
||||
delete[] _td->Addins;
|
||||
}
|
||||
_td->Addins = NULL;
|
||||
_td->nAddins = 0;
|
||||
|
|
@ -56,14 +56,14 @@ void ReadAddins(HKEY hkey)
|
|||
if(reg->OpenKeyReadOnly(hkey == HKEY_CURRENT_USER ? REGSZ_KeymanAddinsCU : REGSZ_KeymanAddinsLM))
|
||||
{
|
||||
int n = _td->nAddins;
|
||||
char buf[128], buf2[512];
|
||||
char buf[128];
|
||||
while(reg->GetValueNames(buf, 128, n))
|
||||
{
|
||||
Addin *a = new Addin[n+1];
|
||||
if(_td->Addins)
|
||||
{
|
||||
memcpy(a, _td->Addins, n * sizeof(Addin));
|
||||
delete _td->Addins;
|
||||
delete[] _td->Addins;
|
||||
}
|
||||
_td->Addins = a;
|
||||
_td->Addins[n].hAddin = 0;
|
||||
|
|
@ -74,17 +74,9 @@ void ReadAddins(HKEY hkey)
|
|||
_td->Addins[n].Uninitialise = NULL;
|
||||
_td->Addins[n].ShouldProcess = NULL;
|
||||
strcpy(_td->Addins[n].ClassName, buf);
|
||||
reg->ReadString(buf, buf2, 512);
|
||||
//char *p = strtok(buf2, ",");
|
||||
//if(p)
|
||||
//{
|
||||
_td->Addins[n].Application[0] = 0;
|
||||
//strcpy(Addins[n].Application, p);
|
||||
//p = strtok(NULL, ",");
|
||||
strcpy(_td->Addins[n].AddinName, buf2); //p);
|
||||
//SendDebugMessageFormat(GetFocus(), sdmGlobal, 0, "Addins: ReadAddins: App=%s Addin=%s %d", Addins[n].Application, Addins[n].AddinName, Addins[n].hAddin);
|
||||
n++;
|
||||
//}
|
||||
reg->ReadString(buf, _td->Addins[n].AddinName, 260);
|
||||
_td->Addins[n].Application[0] = 0;
|
||||
n++;
|
||||
}
|
||||
_td->nAddins = n;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -259,6 +259,9 @@ extern "C" __declspec(dllexport) BOOL WINAPI TIPProcessKey(WPARAM wParam, LPARAM
|
|||
AITIP::AITIP() {
|
||||
::AIWin2000Unicode(); // I3574
|
||||
|
||||
FIsDebugControlWindow = FALSE;
|
||||
useLegacy = FALSE;
|
||||
|
||||
WM_KEYMANDEBUG_CANDEBUG = RegisterWindowMessage("WM_KEYMANDEBUG_CANDEBUG");
|
||||
WM_KEYMANDEBUG_GETUNICODESTATUS = RegisterWindowMessage("WM_KEYMANDEBUG_GETUNICODESTATUS");
|
||||
WM_KEYMANDEBUG_GETCONTEXT = RegisterWindowMessage("WM_KEYMANDEBUG_GETCONTEXT");
|
||||
|
|
@ -548,7 +551,7 @@ BOOL AITIP::PostKeys() {
|
|||
SendDebugMessageFormat(0, sdmAIDefault, 0, "AITIP::PostKeys: no output");
|
||||
}
|
||||
|
||||
delete OutBuf; // I4272
|
||||
delete[] OutBuf; // I4272
|
||||
|
||||
QueueSize = 0;
|
||||
return TRUE;
|
||||
|
|
@ -643,7 +646,7 @@ void FillStoreOffsets(AIDEBUGINFO *di)
|
|||
if(n == MAXSTOREOFFSETS*2) break;
|
||||
}
|
||||
|
||||
if(n < MAXSTOREOFFSETS*2)
|
||||
if(n < MAXSTOREOFFSETS*2 - 1)
|
||||
for(p = di->Rule->dpOutput; *p; p = incxstr(p))
|
||||
{
|
||||
if(*p == UC_SENTINEL && *(p+1) == CODE_INDEX)
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ BOOL AIWin2000Unicode::PostKeys()
|
|||
|
||||
SendDebugMessageFormat(0, sdmAIDefault, 0, "App::PostKeys: sending input finished");
|
||||
|
||||
delete pInputs;
|
||||
delete[] pInputs;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ BOOL AppContext::CharIsSurrogatePair()
|
|||
|
||||
AppActionQueue::AppActionQueue()
|
||||
{
|
||||
memset(Queue, 0, sizeof(APPACTIONQUEUEITEM) * MAXACTIONQUEUE);
|
||||
ResetQueue();
|
||||
}
|
||||
|
||||
|
|
@ -192,4 +193,5 @@ BOOL AppActionQueue::QueueAction(int ItemType, DWORD dwData)
|
|||
AppIntegration::AppIntegration()
|
||||
{
|
||||
hwnd = NULL;
|
||||
FShiftFlags = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ static LPIMDLL AddIMDLL(LPINTKEYBOARDINFO lpkbi, LPSTR kbdpath, LPSTR dllfilenam
|
|||
|
||||
char drive[_MAX_DRIVE], dir[_MAX_DIR], fullname[_MAX_PATH], newdllname[_MAX_FNAME];
|
||||
|
||||
strcpy(fullname, kbdpath);
|
||||
strcpy_s(fullname, _countof(fullname), kbdpath);
|
||||
_splitpath_s(fullname, drive, _countof(drive), dir, _countof(dir), NULL, 0, NULL, 0); // I3547
|
||||
|
||||
#ifdef _WIN64
|
||||
|
|
@ -160,7 +160,7 @@ BOOL LoadDLLs(LPINTKEYBOARDINFO lpkbi)
|
|||
if(!q || !r)
|
||||
{
|
||||
s->dwSystemID = TSS_CALLDEFINITION_LOADFAILED;
|
||||
delete p;
|
||||
delete[] p;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ BOOL LoadDLLs(LPINTKEYBOARDINFO lpkbi)
|
|||
if(imd && AddIMDLLHook(imd, r, i, &s->dpString)) s->dwSystemID = TSS_CALLDEFINITION;
|
||||
else s->dwSystemID = TSS_CALLDEFINITION_LOADFAILED;
|
||||
|
||||
delete p;
|
||||
delete[] p;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -225,7 +225,7 @@ void CallDLL(LPINTKEYBOARDINFO lpkbi, DWORD storenum)
|
|||
{
|
||||
//SendDebugMessageFormat(0, sdmKeyboard, 0, "CallDll: Enter");
|
||||
|
||||
if(storenum < 0 || storenum >= lpkbi->Keyboard->cxStoreArray) return;
|
||||
if(storenum >= lpkbi->Keyboard->cxStoreArray) return;
|
||||
|
||||
LPSTORE s = &lpkbi->Keyboard->dpStoreArray[storenum];
|
||||
if(s->dwSystemID != TSS_CALLDEFINITION) return;
|
||||
|
|
|
|||
|
|
@ -201,35 +201,35 @@ void DebugMessage(LPMSG msg, WPARAM wParam) // I2908
|
|||
char ds[256];
|
||||
|
||||
if(msg->message == wm_keymankeydown)
|
||||
wsprintf(ds, "DebugMessage(%x, wm_keymankeydown: %s lParam: %X) [message flags: %x time: %d]", msg->hwnd,
|
||||
Debug_VirtualKey((WORD) msg->wParam), msg->lParam, wParam, msg->time);
|
||||
wsprintf(ds, "DebugMessage(%x, wm_keymankeydown: %s lParam: %X) [message flags: %x time: %d]", PtrToInt(msg->hwnd),
|
||||
Debug_VirtualKey((WORD) msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time);
|
||||
else if(msg->message == wm_keymankeyup)
|
||||
wsprintf(ds, "DebugMessage(%x, wm_keymankeyup: %s lParam: %X) [message flags: %x time: %d]", msg->hwnd,
|
||||
Debug_VirtualKey((WORD) msg->wParam), msg->lParam, wParam, msg->time);
|
||||
wsprintf(ds, "DebugMessage(%x, wm_keymankeyup: %s lParam: %X) [message flags: %x time: %d]", PtrToInt(msg->hwnd),
|
||||
Debug_VirtualKey((WORD) msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time);
|
||||
else if (msg->message == wm_keyman_keyevent)
|
||||
wsprintf(ds, "DebugMessage(%x, wm_keyman_keyevent: %s lParam: %X) [message flags: %x time: %d]", msg->hwnd,
|
||||
Debug_VirtualKey((WORD)msg->wParam), msg->lParam, wParam, msg->time);
|
||||
wsprintf(ds, "DebugMessage(%x, wm_keyman_keyevent: %s lParam: %X) [message flags: %x time: %d]", PtrToInt(msg->hwnd),
|
||||
Debug_VirtualKey((WORD)msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time);
|
||||
else if(msg->message == WM_KEYDOWN || msg->message == WM_KEYUP || msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSKEYUP)
|
||||
wsprintf(ds, "DebugMessage(%x, %s, wParam: %s, lParam: %X) [message flags: %x time: %d extra: %x]",
|
||||
msg->hwnd,
|
||||
PtrToInt(msg->hwnd),
|
||||
msgnames[msg->message-WM_KEYDOWN],
|
||||
Debug_VirtualKey((WORD) msg->wParam),
|
||||
msg->lParam,
|
||||
(unsigned int) msg->lParam,
|
||||
wParam,
|
||||
msg->time,
|
||||
GetMessageExtraInfo());
|
||||
(int) msg->time,
|
||||
(unsigned int) GetMessageExtraInfo());
|
||||
else if(msg->message >= WM_KEYDOWN && msg->message <= WM_UNICHAR)
|
||||
wsprintf(ds, "DebugMessage(%x, %s, wParam: '%c' (U+%04X), lParam: %X) [message flags: %x time: %d extra: %x]",
|
||||
msg->hwnd,
|
||||
PtrToInt(msg->hwnd),
|
||||
msgnames[msg->message-WM_KEYDOWN],
|
||||
msg->wParam,
|
||||
msg->wParam,
|
||||
msg->lParam,
|
||||
(unsigned int) msg->lParam,
|
||||
wParam,
|
||||
msg->time,
|
||||
GetMessageExtraInfo());
|
||||
(int) msg->time,
|
||||
(unsigned int) GetMessageExtraInfo());
|
||||
else
|
||||
wsprintf(ds, "%x: %d: wParam: %d, lParam: %X [message flags: %x time: %d]", msg->hwnd, msg->message, msg->wParam, msg->lParam, wParam, msg->time);
|
||||
wsprintf(ds, "%x: %d: wParam: %d, lParam: %X [message flags: %x time: %d]", PtrToInt(msg->hwnd), msg->message, msg->wParam, (unsigned int) msg->lParam, wParam, (int) msg->time);
|
||||
|
||||
SendDebugMessage(msg->hwnd, sdmMessage, 0, ds);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,6 +123,9 @@ BOOL OpenTSF(PKEYMAN64THREADDATA _td)
|
|||
BOOL CloseTSF()
|
||||
{
|
||||
PKEYMAN64THREADDATA _td = ThreadGlobals();
|
||||
if (!_td) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*if(_td->dwSinkCookie != (DWORD)-1 && _td->pSource) {
|
||||
_td->pSource->UnadviseSink(_td->dwSinkCookie);
|
||||
|
|
|
|||
|
|
@ -67,18 +67,21 @@ void do_keybd_event(LPINPUT pInputs, int *n, BYTE vk, BYTE scan, DWORD flags, UL
|
|||
switch(vk) {
|
||||
case VK_RCONTROL:
|
||||
flags |= KEYEVENTF_EXTENDEDKEY;
|
||||
/*fallthrough*/
|
||||
case VK_LCONTROL:
|
||||
vk = VK_CONTROL;
|
||||
break;
|
||||
|
||||
case VK_RMENU:
|
||||
flags |= KEYEVENTF_EXTENDEDKEY;
|
||||
/*fallthrough*/
|
||||
case VK_LMENU:
|
||||
vk = VK_MENU;
|
||||
break;
|
||||
|
||||
case VK_RSHIFT:
|
||||
scan = SCANCODE_RSHIFT; // from kbd.h
|
||||
/*fallthrough*/
|
||||
case VK_LSHIFT:
|
||||
vk = VK_SHIFT;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ void ResetKeyboardOption(LPINTKEYBOARDINFO kp, int nStoreToReset)
|
|||
{
|
||||
if(r.ValueExists(kp->Keyboard->dpStoreArray[nStoreToReset].dpName))
|
||||
{
|
||||
WCHAR val[255];
|
||||
WCHAR val[256];
|
||||
if(!r.ReadString(kp->Keyboard->dpStoreArray[nStoreToReset].dpName, val, sizeof(val) / sizeof(val[0]))) return;
|
||||
if(!val[0]) return;
|
||||
val[255] = 0;
|
||||
|
|
|
|||
|
|
@ -360,8 +360,8 @@ void ProcessWMKeyman(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
|
||||
SelectApplicationIntegration();
|
||||
if(!_td->app->IsWindowHandled(hwnd)) _td->app->HandleWindow(hwnd);
|
||||
_td->state.windowunicode = _td->app->IsUnicode();
|
||||
if(_td->app && !_td->app->IsWindowHandled(hwnd)) _td->app->HandleWindow(hwnd);
|
||||
_td->state.windowunicode = !_td->app || _td->app->IsUnicode();
|
||||
|
||||
if(IsFocusedThread())
|
||||
{
|
||||
|
|
@ -483,4 +483,4 @@ BOOL IsFocusedThread()
|
|||
}
|
||||
return gti.hwndFocus == GetFocus();
|
||||
//return GetCurrentThreadId() == GetWindowThreadProcessId(GetForegroundWindow(), NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -640,14 +640,14 @@ BOOL IsMatchingPlatform(LPSTORE s) // I3432
|
|||
if(!IsMatchingPlatformString(platform))
|
||||
{
|
||||
s->dwSystemID = TSS_PLATFORM_NOMATCH;
|
||||
delete t;
|
||||
delete[] t;
|
||||
return FALSE;
|
||||
}
|
||||
platform = wcstok_s(NULL, L" ", &context);
|
||||
}
|
||||
|
||||
s->dwSystemID = TSS_PLATFORM_MATCH;
|
||||
delete t;
|
||||
delete[] t;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,8 +104,8 @@ BOOL SelectKeyboard(DWORD KeymanID)
|
|||
ResetCapsLock();
|
||||
|
||||
SelectApplicationIntegration(); // I4287
|
||||
if(!_td->app->IsWindowHandled(hwnd)) _td->app->HandleWindow(hwnd);
|
||||
_td->state.windowunicode = _td->app->IsUnicode();
|
||||
if(_td->app && !_td->app->IsWindowHandled(hwnd)) _td->app->HandleWindow(hwnd);
|
||||
_td->state.windowunicode = !_td->app || _td->app->IsUnicode();
|
||||
|
||||
ActivateDLLs(_td->lpActiveKeyboard);
|
||||
|
||||
|
|
@ -180,14 +180,14 @@ void SelectKeyboardHKL(PKEYMAN64THREADDATA _td, DWORD hkl, BOOL foreground) {
|
|||
}
|
||||
|
||||
void PrepareLanguageSwitchString(UINT langid, HKL hkl, char *str) {
|
||||
wsprintf(str, "%d|%d|%d", GetCurrentThreadId(), langid, hkl); // I4285
|
||||
wsprintf(str, "%d|%d|%d", (int) GetCurrentThreadId(), langid, PtrToInt(hkl)); // I4285
|
||||
}
|
||||
|
||||
void PrepareLanguageSwitchString(UINT langid, GUID clsid, GUID guidProfile, char *str) {
|
||||
WCHAR clsidstr[40], profilestr[40];
|
||||
StringFromGUID2(clsid, clsidstr, _countof(clsidstr));
|
||||
StringFromGUID2(guidProfile, profilestr, _countof(profilestr));
|
||||
wsprintf(str, "%d|%d|%ws|%ws", GetCurrentThreadId(), langid, clsidstr, profilestr); // I4285
|
||||
wsprintf(str, "%d|%d|%ls|%ls", (int) GetCurrentThreadId(), langid, clsidstr, profilestr); // I4285
|
||||
}
|
||||
|
||||
void ReportActiveKeyboard(PKEYMAN64THREADDATA _td, WORD wCommand) { // I3933 // I3949
|
||||
|
|
|
|||
|
|
@ -61,6 +61,18 @@ private:
|
|||
public:
|
||||
|
||||
SerialKeyEventServer() {
|
||||
m_idThread = 0;
|
||||
m_hThread = NULL;
|
||||
m_hThreadExitEvent = NULL;
|
||||
memset(m_ModifierKeyboardState, 0, 256);
|
||||
m_hKeyEvent = NULL;
|
||||
m_hKeyMutex = NULL;
|
||||
m_hMMF = NULL;
|
||||
m_hwnd = NULL;
|
||||
m_nInputs = 0;
|
||||
m_pInputs = NULL;
|
||||
m_pSharedData = NULL;
|
||||
|
||||
// We create the file mapping and global data on the main thread but release it on the
|
||||
// local thread. This ensures that these objects are available for other processes to
|
||||
// open even if we haven't completed startup of the local thread.
|
||||
|
|
@ -102,6 +114,10 @@ public:
|
|||
DebugLastError("CloseHandle(m_hThreadExitEvent)");
|
||||
}
|
||||
}
|
||||
|
||||
// Normally, this is cleaned up by thread termination, but this
|
||||
// handles error conditions better
|
||||
CloseSharedData();
|
||||
}
|
||||
|
||||
virtual HWND GetWindow() const {
|
||||
|
|
@ -170,21 +186,25 @@ private:
|
|||
DebugLastError("CloseHandle(m_hKeyMutex)");
|
||||
bRet = FALSE;
|
||||
}
|
||||
m_hKeyMutex = NULL;
|
||||
|
||||
if (m_hKeyEvent != NULL && !CloseHandle(m_hKeyEvent)) {
|
||||
DebugLastError("CloseHandle(m_hKeyEvent)");
|
||||
bRet = FALSE;
|
||||
}
|
||||
m_hKeyEvent = NULL;
|
||||
|
||||
if (m_pSharedData != NULL && !UnmapViewOfFile((LPCVOID)m_pSharedData)) {
|
||||
DebugLastError("CloseHandle(m_pSharedData)");
|
||||
bRet = FALSE;
|
||||
}
|
||||
m_pSharedData = NULL;
|
||||
|
||||
if (m_hMMF != NULL && !CloseHandle(m_hMMF)) {
|
||||
DebugLastError("CloseHandle(m_hMMF)");
|
||||
bRet = FALSE;
|
||||
}
|
||||
m_hMMF = NULL;
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
|
@ -268,7 +288,8 @@ private:
|
|||
}
|
||||
|
||||
if (m_pInputs != NULL) {
|
||||
delete m_pInputs;
|
||||
delete[] m_pInputs;
|
||||
m_pInputs = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ void GetWindowsVersion(char *buf)
|
|||
if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1 )
|
||||
pos = "Microsoft Windows 7";
|
||||
|
||||
// TODO: Update this for Win8, Win10, etc
|
||||
|
||||
// Test for product type.
|
||||
|
||||
if ( osvi.wProductType == VER_NT_WORKSTATION )
|
||||
|
|
@ -77,16 +79,16 @@ void GetWindowsVersion(char *buf)
|
|||
if ( osvi.dwMajorVersion <= 4 )
|
||||
{
|
||||
wsprintf (verinfo, "version %d.%d %s (Build %d)",
|
||||
osvi.dwMajorVersion,
|
||||
osvi.dwMinorVersion,
|
||||
(int) osvi.dwMajorVersion,
|
||||
(int) osvi.dwMinorVersion,
|
||||
osvi.szCSDVersion,
|
||||
osvi.dwBuildNumber & 0xFFFF);
|
||||
(int)(osvi.dwBuildNumber & 0xFFFF));
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintf (verinfo, "version %s (Build %d)",
|
||||
osvi.szCSDVersion,
|
||||
osvi.dwBuildNumber & 0xFFFF);
|
||||
(int)(osvi.dwBuildNumber & 0xFFFF));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -121,6 +123,6 @@ void GetWindowsVersion(char *buf)
|
|||
break;
|
||||
}
|
||||
|
||||
wsprintf(buf, "Platform %s OS %s%s%s %s", pplatform, pos, pextra ? " " : "", pextra, verinfo);
|
||||
wsprintf(buf, "Platform %s OS %s %s %s", pplatform, pos, *pextra ? " " : "", pextra, verinfo);
|
||||
}
|
||||
#pragma warning(default: 4996)
|
||||
|
|
|
|||
|
|
@ -236,6 +236,23 @@ begin
|
|||
|
||||
LangID := LocaleNameToLCID(PWideChar(Locale), 0);
|
||||
|
||||
if (PRIMARYLANGID(LangID) = 0) and (
|
||||
(SUBLANGID(LangID) < 8) or
|
||||
(SUBLANGID(LangID) > 11)
|
||||
) then
|
||||
begin
|
||||
// LocaleNameToLCID can return a language code that is 'transient' but
|
||||
// outside of the supported range of $2000, $2400, $2800, $2C00. For
|
||||
// example, we have seen values of $3000, $3400, $3800.
|
||||
// Set-WinUserLanguageList refuses to play ball with these values, so we
|
||||
// reject them as invalid.
|
||||
//
|
||||
// This may be a bug in Windows? TODO: Investigate further and report to
|
||||
// Microsoft
|
||||
Exit(False);
|
||||
end;
|
||||
|
||||
|
||||
case LangID of
|
||||
LOCALE_CUSTOM_DEFAULT,
|
||||
LOCALE_CUSTOM_UNSPECIFIED,
|
||||
|
|
|
|||
|
|
@ -65,19 +65,19 @@ void InitDebugging() {
|
|||
VS_FIXEDFILEINFO *ffi;
|
||||
DWORD sz;
|
||||
UINT ffilen;
|
||||
char *buf = new char[1024], fname[260];
|
||||
char fname[260];
|
||||
|
||||
GetModuleFileName(GetModuleHandle("kmtip.dll"), fname, 260);
|
||||
sz = GetFileVersionInfoSize(fname, 0);
|
||||
if (sz > 0) {
|
||||
buf = new char[sz];
|
||||
char *buf = new char[sz];
|
||||
GetFileVersionInfo(fname, 0, sz, buf);
|
||||
VerQueryValue(buf, "\\", (void **)&ffi, &ffilen);
|
||||
|
||||
SendDebugMessageFormat(L"kmtip version: %d.%d.%d.%d",
|
||||
HIWORD(ffi->dwProductVersionMS), LOWORD(ffi->dwProductVersionMS),
|
||||
HIWORD(ffi->dwProductVersionLS), LOWORD(ffi->dwProductVersionLS));
|
||||
delete buf; // I2157
|
||||
delete[] buf; // I2157
|
||||
}
|
||||
else {
|
||||
SendDebugMessage(L"kmtip version: damaged");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
Name: inserttext
|
||||
Copyright: Copyright (C) SIL International.
|
||||
Documentation:
|
||||
|
|
@ -268,7 +268,7 @@ BOOL GetLeftOfSelection(TfEditCookie ec, ITfContext *pContext, WCHAR *buf, LONG
|
|||
if(ShouldDebug()) {
|
||||
char *p = debugstr(buf);
|
||||
Log(L"GetLeftOfSelection(%d) = %hs [%d fetched]", n, p, cFetched);
|
||||
delete p;
|
||||
delete[] p;
|
||||
}
|
||||
#ifdef DEBUG_PSEUDO // I3607
|
||||
DePseudofy(buf); // I3564
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ public:
|
|||
_fUpdate = fUpdate;
|
||||
_fPreserved = fPreserved; // I3588
|
||||
_dwDeepIntegration = dwDeepIntegration; // I4375
|
||||
_hr = S_FALSE;
|
||||
_ec = 0;
|
||||
}
|
||||
|
||||
// ITfEditSession
|
||||
|
|
@ -245,7 +247,7 @@ HRESULT WINAPI CKeymanEditSession::KeymanProcessOutput(int n, WCHAR *buf, int nb
|
|||
if (ShouldDebug()) {
|
||||
char *p = debugstr(buf);
|
||||
SendDebugMessageFormat(L"KeymanProcessOutput: fUpdate = %d, deleting %d, inserting %d '%hs'", _fUpdate, n, nbuf, p); // I4262
|
||||
delete p;
|
||||
delete[] p;
|
||||
}
|
||||
|
||||
if (_fUpdate) {
|
||||
|
|
|
|||
|
|
@ -79,6 +79,14 @@ CKMTipTextService::CKMTipTextService()
|
|||
// I3582
|
||||
_dwThreadMgrEventSinkCookie = TF_INVALID_COOKIE;
|
||||
|
||||
memset(&guidActiveProfile, 0, sizeof(GUID));
|
||||
_keystrokeSinkInitialized = FALSE;
|
||||
_hKeyman = NULL;
|
||||
_dwActiveLanguageProfileNotifySinkCookie = 0;
|
||||
_PreservedKeys = NULL;
|
||||
_cPreservedKeyCount = 0;
|
||||
_dwDeepIntegration = 0;
|
||||
|
||||
_cRef = 1;
|
||||
ThreadThis = this;
|
||||
}
|
||||
|
|
@ -283,4 +291,4 @@ STDAPI CKMTipTextService::Deactivate()
|
|||
_tfClientId = TF_CLIENTID_NULL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,16 +72,12 @@ BOOL CKMTipTextService::RegisterProfiles()
|
|||
|
||||
hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_ITfInputProcessorProfiles, (void**)&pInputProcessProfiles);
|
||||
if (hr != S_OK)
|
||||
if (hr != S_OK || pInputProcessProfiles == NULL)
|
||||
return FALSE;
|
||||
|
||||
hr = pInputProcessProfiles->Register(c_clsidKMTipTextService);
|
||||
if (hr != S_OK)
|
||||
goto Exit;
|
||||
|
||||
Exit:
|
||||
if(pInputProcessProfiles != NULL) // I2794
|
||||
pInputProcessProfiles->Release();
|
||||
pInputProcessProfiles->Release();
|
||||
|
||||
return (hr == S_OK);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -462,7 +462,7 @@ bool ImportRules(WCHAR *kbid, LPKEYBOARD kp, std::vector<DeadkeyMapping> *FDeadk
|
|||
Loader loader;
|
||||
|
||||
WCHAR inputHKL[12];
|
||||
wsprintf(inputHKL, L"%08.8x", wcstol(kbid, NULL, 16));
|
||||
wsprintf(inputHKL, L"%08.8x", (unsigned int) wcstol(kbid, NULL, 16));
|
||||
|
||||
int cKeyboards = GetKeyboardLayoutList(0, NULL);
|
||||
HKL *rghkl = new HKL[cKeyboards];
|
||||
|
|
@ -470,6 +470,7 @@ bool ImportRules(WCHAR *kbid, LPKEYBOARD kp, std::vector<DeadkeyMapping> *FDeadk
|
|||
HKL hkl = LoadKeyboardLayout(inputHKL, KLF_NOTELLSHELL);
|
||||
if(hkl == NULL) {
|
||||
puts("Sorry, that keyboard does not seem to be valid.");
|
||||
delete[] rghkl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -595,6 +596,8 @@ bool ImportRules(WCHAR *kbid, LPKEYBOARD kp, std::vector<DeadkeyMapping> *FDeadk
|
|||
UnloadKeyboardLayout(hkl);
|
||||
}
|
||||
|
||||
delete[] rghkl;
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Now that we've collected the key data, we need to
|
||||
// translate it to kmx and append to the existing keyboard
|
||||
|
|
|
|||
|
|
@ -40,26 +40,31 @@ BOOL LoadKeyboard(LPWSTR fileName, LPKEYBOARD *lpKeyboard) {
|
|||
|
||||
filebase = buf;
|
||||
|
||||
ReadFile(hFile, filebase, sz, &sz, NULL);
|
||||
if(!ReadFile(hFile, filebase, sz, &sz, NULL)) {
|
||||
Err(L"errReadFile");
|
||||
CloseHandle(hFile);
|
||||
delete[] buf;
|
||||
return FALSE;
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
|
||||
if(!VerifyKeyboard(filebase, sz)) {
|
||||
Err(L"errVerifyKeyboard");
|
||||
delete buf;
|
||||
delete[] buf;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
kbp = FixupKeyboard(buf, filebase, sz);
|
||||
if(!kbp) {
|
||||
Err(L"errFixupKeyboard");
|
||||
delete buf;
|
||||
delete[] buf;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(kbp->dwIdentifier != FILEID_COMPILED) {
|
||||
Err(L"errNotFileID");
|
||||
delete buf;
|
||||
return FALSE;
|
||||
if(kbp->dwIdentifier != FILEID_COMPILED) {
|
||||
Err(L"errNotFileID");
|
||||
delete[] buf;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*lpKeyboard = kbp;
|
||||
|
|
@ -93,7 +98,7 @@ LPKEYBOARD FixupKeyboard(PBYTE bufp, PBYTE base, DWORD dwFileSize) {
|
|||
}
|
||||
|
||||
for(gp = kbp->dpGroupArray, cgp = (PCOMP_GROUP) gp, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) {
|
||||
gp->dpName = StringOffset(base, cgp->dpName);
|
||||
gp->dpName = StringOffset(base, cgp->dpName);
|
||||
gp->dpKeyArray = (LPKEY) (base + cgp->dpKeyArray);
|
||||
if(cgp->dpMatch != NULL) gp->dpMatch = (PWSTR) (base + cgp->dpMatch);
|
||||
if(cgp->dpNoMatch != NULL) gp->dpNoMatch = (PWSTR) (base + cgp->dpNoMatch);
|
||||
|
|
@ -124,12 +129,12 @@ BOOL VerifyKeyboard(LPBYTE filebase, DWORD sz) {
|
|||
PCOMP_KEYBOARD ckbp = (PCOMP_KEYBOARD) filebase;
|
||||
PCOMP_STORE csp;
|
||||
|
||||
/* Check file version */
|
||||
/* Check file version */
|
||||
|
||||
if(ckbp->dwFileVersion < VERSION_MIN ||
|
||||
ckbp->dwFileVersion > VERSION_MAX) {
|
||||
/* Old or new version -- identify the desired program version */
|
||||
if(VerifyChecksum(filebase, sz)) {
|
||||
if(ckbp->dwFileVersion < VERSION_MIN ||
|
||||
ckbp->dwFileVersion > VERSION_MAX) {
|
||||
/* Old or new version -- identify the desired program version */
|
||||
if(VerifyChecksum(filebase, sz)) {
|
||||
for(csp = (PCOMP_STORE)(filebase + ckbp->dpStoreArray), i = 0; i < ckbp->cxStoreArray; i++, csp++) {
|
||||
if(csp->dwSystemID == TSS_COMPILEDVERSION) {
|
||||
wchar_t buf2[256];
|
||||
|
|
@ -144,12 +149,12 @@ BOOL VerifyKeyboard(LPBYTE filebase, DWORD sz) {
|
|||
}
|
||||
}
|
||||
Err(L"errWrongFileVersion");
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(!VerifyChecksum(filebase, sz)) {
|
||||
Err(L"errBadChecksum");
|
||||
return FALSE;
|
||||
|
||||
if(!VerifyChecksum(filebase, sz)) {
|
||||
Err(L"errBadChecksum");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -45,11 +45,11 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug)
|
|||
|
||||
// Calculate how much memory to allocate
|
||||
|
||||
size = sizeof(COMP_KEYBOARD) +
|
||||
fk->cxGroupArray * sizeof(COMP_GROUP) +
|
||||
size = sizeof(COMP_KEYBOARD) +
|
||||
fk->cxGroupArray * sizeof(COMP_GROUP) +
|
||||
fk->cxStoreArray * sizeof(COMP_STORE) +
|
||||
/*wcslen(fk->szName)*2 + 2 +
|
||||
wcslen(fk->szCopyright)*2 + 2 +
|
||||
/*wcslen(fk->szName)*2 + 2 +
|
||||
wcslen(fk->szCopyright)*2 + 2 +
|
||||
wcslen(fk->szLanguageName)*2 + 2 +
|
||||
wcslen(fk->szMessage)*2 + 2 +*/
|
||||
fk->dwBitmapSize;
|
||||
|
|
@ -62,7 +62,7 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug)
|
|||
size += wcslen(fkp->dpOutput)*2 + 2;
|
||||
size += wcslen(fkp->dpContext)*2 + 2;
|
||||
}
|
||||
|
||||
|
||||
if( fgp->dpMatch ) size += wcslen(fgp->dpMatch)*2 + 2;
|
||||
if( fgp->dpNoMatch ) size += wcslen(fgp->dpNoMatch)*2 + 2;
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug)
|
|||
ck->StartGroup[0] = fk->StartGroup[0];
|
||||
ck->StartGroup[1] = fk->StartGroup[1];
|
||||
ck->dwHotKey = fk->dwHotKey;
|
||||
|
||||
|
||||
ck->dwFlags = fk->dwFlags;
|
||||
|
||||
offset = sizeof(COMP_KEYBOARD);
|
||||
|
|
@ -168,12 +168,12 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug)
|
|||
offset += gp->cxKeyArray * sizeof(COMP_KEY);
|
||||
for(j = 0; j < gp->cxKeyArray; j++, kp++, fkp++) {
|
||||
kp->Key = fkp->Key;
|
||||
kp->Line = fkp->Line;
|
||||
kp->Line = fkp->Line;
|
||||
kp->ShiftFlags = fkp->ShiftFlags;
|
||||
kp->dpOutput = offset;
|
||||
wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fkp->dpOutput); // I3481 // I3641
|
||||
offset += wcslen(fkp->dpOutput)*2 + 2;
|
||||
|
||||
|
||||
|
||||
kp->dpContext = offset;
|
||||
wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fkp->dpContext); // I3481 // I3641
|
||||
|
|
@ -191,15 +191,23 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug)
|
|||
ck->dpBitmapOffset = 0;
|
||||
}
|
||||
|
||||
if(offset != size) return CERR_SomewhereIGotItWrong;
|
||||
if(offset != size)
|
||||
{
|
||||
delete[] buf;
|
||||
return CERR_SomewhereIGotItWrong;
|
||||
}
|
||||
|
||||
SetChecksum(buf, &ck->dwCheckSum, size);
|
||||
|
||||
WriteFile(hOutfile, buf, size, &offset, NULL);
|
||||
|
||||
if(offset != size) return CERR_UnableToWriteFully;
|
||||
if(offset != size)
|
||||
{
|
||||
delete[] buf;
|
||||
return CERR_UnableToWriteFully;
|
||||
}
|
||||
|
||||
delete buf;
|
||||
delete[] buf;
|
||||
|
||||
return CERR_None;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -261,11 +261,11 @@ const WCHAR cp1252[256] = {
|
|||
void InplaceUnicode(PWSTR p) {
|
||||
while(p && *p) {
|
||||
if(*p != UC_SENTINEL) {
|
||||
if(*p >= 0 && *p <= 0xFF) {
|
||||
if(*p <= 0xFF) {
|
||||
*p = cp1252[*p];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
p = incxstr(p);
|
||||
}
|
||||
}
|
||||
|
|
@ -276,7 +276,7 @@ BOOL ConvertKeyboardToUnicode(LPKEYBOARD kbd) {
|
|||
LPKEY kp;
|
||||
DWORD i, j;
|
||||
|
||||
if(kbd->StartGroup[BEGIN_UNICODE] >= 0 && kbd->StartGroup[BEGIN_UNICODE] < kbd->cxGroupArray) {
|
||||
if(kbd->StartGroup[BEGIN_UNICODE] < kbd->cxGroupArray) {
|
||||
// Keyboard is already Unicode
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
/*
|
||||
Name: mcompile
|
||||
Copyright: Copyright (C) SIL International.
|
||||
Documentation:
|
||||
Description:
|
||||
Documentation:
|
||||
Description:
|
||||
Create Date: 24 Apr 2014
|
||||
|
||||
Modified Date: 8 Apr 2015
|
||||
Authors: mcdurdin
|
||||
Related Files:
|
||||
Dependencies:
|
||||
Related Files:
|
||||
Dependencies:
|
||||
|
||||
Bugs:
|
||||
Todo:
|
||||
Notes:
|
||||
Bugs:
|
||||
Todo:
|
||||
Notes:
|
||||
History: 24 Apr 2014 - mcdurdin - I4174 - V9 - mcompile logs should be stored in diag folder
|
||||
16 Jun 2014 - mcdurdin - I4273 - V9.0 - Convert keyboards to Unicode before installing
|
||||
23 Jun 2014 - mcdurdin - I4279 - V9.0 - mcompile fails to start when converting keyboard to Unicode
|
||||
|
|
@ -82,7 +82,7 @@ int run(int argc, wchar_t * argv[])
|
|||
}
|
||||
|
||||
//DeleteReallocatedPointers(kmxfile); :TODO
|
||||
delete kmxfile;
|
||||
delete[] kmxfile;
|
||||
|
||||
return 0; // I4279
|
||||
}
|
||||
|
|
@ -92,11 +92,11 @@ int run(int argc, wchar_t * argv[])
|
|||
|
||||
wchar_t *infile = argv[n], *indll = argv[n+1], *kbid = argv[n+2], *outfile = argv[n+3];
|
||||
|
||||
wprintf(L"mcompile%s \"%s\" \"%s\" \"%s\" \"%s\"\n", bDeadkeyConversion ? L" -d":L"", infile, indll, kbid, outfile); // I4174
|
||||
wprintf(L"mcompile%ls \"%ls\" \"%ls\" \"%ls\" \"%ls\"\n", bDeadkeyConversion ? L" -d":L"", infile, indll, kbid, outfile); // I4174
|
||||
|
||||
// 1. Load the keyman keyboard file
|
||||
|
||||
// 2. For each key on the system layout, determine its output character and perform a
|
||||
// 2. For each key on the system layout, determine its output character and perform a
|
||||
// 1-1 replacement on the keyman keyboard of that character with the base VK + shift
|
||||
// state. This fixup will transform the char to a vk, which will avoid any issues
|
||||
// with the key.
|
||||
|
|
@ -107,8 +107,8 @@ int run(int argc, wchar_t * argv[])
|
|||
// rule for that deadkey, e.g. [K_LBRKT] > dk(c101)
|
||||
//
|
||||
// Next, update each rule that references the output from that deadkey to add an extra
|
||||
// context deadkey at the end of the context match, e.g. 'a' dk(c101) + [K_SPACE] > 'b'.
|
||||
// This will require a memory layout change for the .kmx file, plus fixups on the
|
||||
// context deadkey at the end of the context match, e.g. 'a' dk(c101) + [K_SPACE] > 'b'.
|
||||
// This will require a memory layout change for the .kmx file, plus fixups on the
|
||||
// context+output index offsets
|
||||
//
|
||||
// --> virtual character keys
|
||||
|
|
@ -117,7 +117,7 @@ int run(int argc, wchar_t * argv[])
|
|||
// switch the shift state from the VIRTUALCHARKEY to VIRTUALKEY, without changing any
|
||||
// other properties of the key.
|
||||
//
|
||||
|
||||
|
||||
// 3. Write the new keyman keyboard file
|
||||
|
||||
if(!LoadNewLibrary(indll)) {
|
||||
|
|
@ -167,7 +167,7 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCT
|
|||
//
|
||||
// TranslateKey
|
||||
//
|
||||
// For each key rule on the keyboard, remap its key to the
|
||||
// For each key rule on the keyboard, remap its key to the
|
||||
// correct shift state and key. Adjust the LCTRL+RALT -> RALT if necessary
|
||||
//
|
||||
void TranslateKey(LPKEY key, WORD vk, UINT shift, WCHAR ch) {
|
||||
|
|
@ -391,7 +391,7 @@ void ConvertDeadkey(LPKEYBOARD kbd, WORD vk, UINT shift, WCHAR deadkey) {
|
|||
|
||||
GetDeadkeys(deadkey, pdk = deadkeys); // returns array of [usvk, ch_out] pairs
|
||||
while(*pdk) {
|
||||
// Look up the ch
|
||||
// Look up the ch
|
||||
UINT vkUnderlying = VKUnderlyingLayoutToVKUS(*pdk);
|
||||
TranslateDeadkeyKeyboard(kbd, dkid, vkUnderlying, *(pdk+1), *(pdk+2));
|
||||
pdk+=3;
|
||||
|
|
@ -435,7 +435,7 @@ BOOL DoConvert(LPKEYBOARD kbd, LPWSTR kbid, BOOL bDeadkeyConversion) { // I455
|
|||
// Go through each possible key on the keyboard
|
||||
for(int i = 0; VKMap[i]; i++) { // I4651
|
||||
UINT vkUnderlying = VKUSToVKUnderlyingLayout(VKMap[i]);
|
||||
|
||||
|
||||
WCHAR ch = CharFromVK(vkUnderlying, VKShiftState[j], &DeadKey);
|
||||
|
||||
//LogError("--- VK_%d -> VK_%d [%c] dk=%d", VKMap[i], vkUnderlying, ch == 0 ? 32 : ch, DeadKey);
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@ uses
|
|||
Keyman.System.Standards.LangTagsRegistry,
|
||||
System.SysUtils;
|
||||
|
||||
// TODO: Make this a COM API function so we aren't shipping 3+MB of standards data multiple times
|
||||
|
||||
///
|
||||
///<summary>Find a language code with appropriate script and region subtags</summary>
|
||||
///<remarks>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ int keyman_sentry_init(bool is_keyman_developer, const char *logger) {
|
|||
|
||||
sentry_options_set_release(options, "release-" KEYMAN_VersionWithTag); // matches git tag
|
||||
sentry_options_set_environment(options, KEYMAN_Environment); // stable, beta, alpha, test, local
|
||||
|
||||
|
||||
// We don't currently need to set this, because it will be same path
|
||||
// as all our c++ executables.
|
||||
//sentry_options_set_handler_path(options, "path/to/crashpad_handler");
|
||||
|
|
@ -59,7 +59,7 @@ int keyman_sentry_init(bool is_keyman_developer, const char *logger) {
|
|||
if (RegOpenKeyExA(HKEY_CURRENT_USER, key, 0, KEY_READ, &hkey) == ERROR_SUCCESS) {
|
||||
DWORD dwType, dwValue, dwValueSize = 4;
|
||||
|
||||
g_report_exceptions =
|
||||
g_report_exceptions =
|
||||
RegQueryValueExA(hkey, REGSZ_AutomaticallyReportErrors, NULL, &dwType, (LPBYTE)&dwValue, &dwValueSize) != ERROR_SUCCESS || dwType != REG_DWORD || dwValue != 0;
|
||||
|
||||
dwValueSize = 4;
|
||||
|
|
@ -133,7 +133,7 @@ void keyman_sentry_report_exception(DWORD ExceptionCode, PVOID ExceptionAddress)
|
|||
const int FRAMES_TO_SKIP = 0;
|
||||
|
||||
char message[64];
|
||||
wsprintfA(message, "Exception %x at %p", ExceptionCode, ExceptionAddress);
|
||||
wsprintfA(message, "Exception %x at %p", (unsigned int) ExceptionCode, ExceptionAddress);
|
||||
|
||||
if (g_report_exceptions) {
|
||||
event = sentry_value_new_event();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue