diff --git a/windows/src/developer/kmconvert/importkeyboard_pas/Keyman.Developer.System.ImportKeyboardDLL.pas b/windows/src/developer/kmconvert/Keyman.Developer.System.ImportKeyboardDLL.pas
similarity index 87%
rename from windows/src/developer/kmconvert/importkeyboard_pas/Keyman.Developer.System.ImportKeyboardDLL.pas
rename to windows/src/developer/kmconvert/Keyman.Developer.System.ImportKeyboardDLL.pas
index eb0bbb52eb..bcbcf9dcb4 100644
--- a/windows/src/developer/kmconvert/importkeyboard_pas/Keyman.Developer.System.ImportKeyboardDLL.pas
+++ b/windows/src/developer/kmconvert/Keyman.Developer.System.ImportKeyboardDLL.pas
@@ -17,7 +17,7 @@ type
FKMN: string;
FKVKS: string;
public
- constructor Create(const inputHKL: string);
+ constructor Create(const inputHKL, nameFormatString: string);
procedure Execute;
property InputHKL: string read FInputHKL;
property KMN: string read FKMN;
@@ -37,8 +37,11 @@ uses
System.Win.Registry,
ScanCodeMap,
+ Unicode,
+ VisualKeyboard,
VKeys;
+
type
TKBDShiftState = (
Base = 0, // 0
@@ -53,6 +56,20 @@ type
ShftXxxx = 9 //Shft or Xxxx // 9
);
+const
+ KBDShiftStateToVisualKeyboardShiftState: array[TKBDShiftState] of WORD = (
+ KVKS_NORMAL, //Base = 0,
+ KVKS_SHIFT, //Shft = 1,
+ KVKS_CTRL, //Ctrl = 2,
+ KVKS_SHIFT or KVKS_CTRL, //ShftCtrl = 3,
+ KVKS_ALT, //Menu = 4,
+ KVKS_SHIFT or KVKS_ALT, //ShftMenu = 5,
+ KVKS_RALT, //MenuCtrl = 6,
+ KVKS_SHIFT or KVKS_RALT, //ShftMenuCtrl = 7,
+ $FFFF, //Xxxx = 8,
+ $FFFF //ShftXxxx = 9
+ );
+
{ TDeadKey }
type
@@ -97,6 +114,7 @@ type
procedure SetShiftState(shiftState: TKBDShiftState; value: string; isDeadKey, capsLock: Boolean);
function GetShiftStateName(capsLock: UINT; caps: Boolean; ss: TKBDShiftState): string;
function LayoutRow: string;
+ procedure AddKeysToVisualKeyboard(vk: TVisualKeyboard);
property VK: UINT read FVK;
property SC: UINT read FSC;
@@ -131,6 +149,7 @@ type
procedure ClearKeyboardBuffer(vk: UINT; sc: UINT; hkl: HKL);
procedure ScanKeyboard(hkl: HKL);
function WriteOutputKMNFile: string;
+ function WriteOutputKVKSFile: string;
public
constructor Create(inputHKL, layoutFile, layoutText: string);
destructor Destroy; override;
@@ -390,20 +409,29 @@ begin
end;
end;
+ // We don't add Shift+Space, Ctrl+Space as they are not
+ // useful
+ if (st = #$20) and (FVK = VK_SPACE) and (ss <> Base) then
+ isvalid := False;
+
if isvalid then
begin
// It's some characters; put 'em in there.
- Result := Result + Format('+ [%s%s] > ', [
- GetShiftStateName(capslock, caps, ss),
- GetVKeyName
- ]);
+ Result := Result + Format('+ [%s%s] >', [GetShiftStateName(capslock, caps, ss), GetVKeyName]);
- for ich := 1 to st.Length do
+ ich := 1;
+ while ich <= st.Length do
begin
- //TODO: Support surrogate pairs
- Result := Result + 'U+' + IntToHexLC(Ord(st[ich]), 4);
- if ich < st.Length then
- Result := Result + ' ';
+ if (ich < st.Length) and Uni_IsSurrogate1(st[ich]) and Uni_IsSurrogate2(st[ich+1]) then
+ begin
+ Result := Result + ' U+' + IntToHexLC(Uni_SurrogateToUTF32(st[ich], st[ich+1]), 6);
+ Inc(ich, 2);
+ end
+ else
+ begin
+ Result := Result + ' U+' + IntToHexLC(Ord(st[ich]), 4);
+ Inc(ich);
+ end;
end;
Result := Result + #13#10;
@@ -413,6 +441,64 @@ begin
end;
end;
+procedure TVirtualKey.AddKeysToVisualKeyboard(vk: TVisualKeyboard);
+var
+ ss: TKBDShiftState;
+ st: string;
+ ich: Integer;
+ isvalid: Boolean;
+ vkk: TVisualKeyboardKey;
+begin
+ for ss := Low(TKBDShiftState) to Loader.MaxShiftState do
+ begin
+ if (ss = Menu) or (ss = ShftMenu) then
+ begin
+ // Alt and Shift+Alt don't work, so skip them
+ Continue;
+ end;
+
+ st := GetShiftState(ss, False);
+ if st.Length = 0 then
+ begin
+ // No character assigned here
+ end
+ else if FRGFDeadKey[ss, False] then
+ begin
+ // It's a dead key
+ vkk := TVisualKeyboardKey.Create;
+ vkk.VKey := FVK;
+ vkk.Text := st[1];
+ vkk.Flags := [kvkkUnicode];
+ vkk.Shift := KBDShiftStateToVisualKeyboardShiftState[ss];
+ vk.Keys.Add(vkk);
+ end
+ else
+ begin
+ isvalid := True;
+ for ich := 1 to st.Length do
+ begin
+ if (st[ich] < #$20) or (st[ich] = #$7F) then
+ begin
+ isvalid := False;
+ Break;
+ end;
+ end;
+
+ if isvalid then
+ begin
+ // It's some characters; put 'em in there.
+ vkk := TVisualKeyboardKey.Create;
+ vkk.VKey := FVK;
+ vkk.Text := st;
+ vkk.Flags := [kvkkUnicode];
+ vkk.Shift := KBDShiftStateToVisualKeyboardShiftState[ss];
+ vk.Keys.Add(vkk);
+ end;
+ end;
+ end;
+end;
+
+
(* public class Loader
{
@@ -741,6 +827,8 @@ begin
end;
procedure TLoader.Main(var KMN, KVKS: string);
+type
+ PHKL = ^HKL;
var
cKeyboards: Cardinal;
rghkl: array of HKL;
@@ -751,6 +839,8 @@ begin
cKeyboards := GetKeyboardLayoutList(0, rghkl);
SetLength(rghkl, cKeyboards);
+ GetKeyboardLayoutList(cKeyboards, rghkl);
+
hkl := LoadKeyboardLayout(inputHKL, KLF_NOTELLSHELL);
if hkl = 0 then
raise EImportKeyboardDLL.CreateFmt('The keyboard %s could not be loaded (error %d, %s)',
@@ -768,7 +858,7 @@ begin
end;
KMN := WriteOutputKMNFile;
- //WriteOutputKVKSFile(KVKS);
+ KVKS := WriteOutputKVKSFile;
end;
function TLoader.WriteOutputKMNFile: string;
@@ -793,7 +883,6 @@ begin
outFile.Add('c '#13#10);
outFile.Add('store(&Version) "10.0"');
outFile.Add(Format('store(&Name) "%s"', [layoutText]));
- outFile.Add('store(&Copyright) "(C) 2018 SIL International"');
outFile.Add('store(&Targets) "windows macosx linux web"');
outFile.Add('');
outFile.Add('begin Unicode > use(main)'#13#10);
@@ -819,6 +908,7 @@ begin
sbDKTo := Format('store(dkt%s)', [IntToHexLC(Ord(dk.DeadCharacter), 4)]);
for id := 0 to dk.Count - 1 do
begin
+ // Surrogate pairs not supported in kbd.dll
sbDKFrom := sbDKFrom + ' U+'+IntToHexLC(Ord(dk.GetBaseCharacter(id)), 4);
sbDKTo := sbDKTo + ' U+'+IntToHexLC(Ord(dk.GetCombinedCharacter(id)), 4);
end;
@@ -837,12 +927,38 @@ begin
end;
end;
+function TLoader.WriteOutputKVKSFile: string;
+var
+ iKey: UINT;
+ vk: TVisualKeyboard;
+ ss: TStringStream;
+begin
+ vk := TVisualKeyboard.Create;
+ ss := TStringStream.Create('', TEncoding.UTF8);
+ try
+ for iKey := 0 to Length(rgKey) - 1 do
+ begin
+ if (rgKey[iKey] <> nil) and rgKey[iKey].IsKeymanUsedKey and not rgKey[iKey].IsEmpty then
+ begin
+ rgKey[iKey].AddKeysToVisualKeyboard(vk);
+ end;
+ end;
+
+ vk.SaveToStream(ss, kvksfXML);
+
+ Result := ss.DataString;
+ finally
+ vk.Free;
+ ss.Free;
+ end;
+end;
+
{ TImportKeyboardDLL }
const
CRootKey = 'System\CurrentControlSet\Control\Keyboard Layouts';
-constructor TImportKeyboardDLL.Create(const inputHKL: string);
+constructor TImportKeyboardDLL.Create(const inputHKL, nameFormatString: string);
var
r: TRegistry;
begin
@@ -861,6 +977,8 @@ begin
FLayoutFile := r.ReadString('Layout File');
FLayoutText := r.ReadString('Layout Text');
+ if nameFormatString <> ''
+ then FLayoutText := Format(nameFormatString, [FLayoutText]);
finally
r.Free;
end;
diff --git a/windows/src/developer/kmconvert/Keyman.Developer.System.ImportWindowsKeyboard.pas b/windows/src/developer/kmconvert/Keyman.Developer.System.ImportWindowsKeyboard.pas
index 8b260c2c34..6fa6d6ab5e 100644
--- a/windows/src/developer/kmconvert/Keyman.Developer.System.ImportWindowsKeyboard.pas
+++ b/windows/src/developer/kmconvert/Keyman.Developer.System.ImportWindowsKeyboard.pas
@@ -21,7 +21,7 @@ type
FBCP47Tags: string;
FCopyright: string;
function LoadKLIDDetails: Boolean;
- function ImportKeyboard(const DestinationFilename, Name: string): Boolean;
+ function ImportKeyboard(const DestinationFilename, DestinationKVKSFilename, Name: string): Boolean;
function GenerateIcon(const IconFilename: string): Boolean;
procedure SetAuthor(const Value: string);
procedure SetCopyright(const Value: string);
@@ -31,6 +31,8 @@ type
procedure SetNameTemplate(const Value: string);
procedure SetSourceKLID(const Value: string);
procedure SetVersion(const Value: string);
+ procedure InjectSystemStores(const KeyboardFilename, OSKFilename,
+ IconFilename: string);
public
function Execute: Boolean; overload;
@@ -47,13 +49,16 @@ type
implementation
uses
- System.Win.Registry,
+ System.Classes,
System.SysUtils,
+ System.Win.Registry,
Winapi.Windows,
+ Keyman.Developer.System.ImportKeyboardDLL,
+ KeyboardParser,
+ kmxfileconsts,
RegistryKeys,
- UKeymanTargets,
- utilexecute;
+ UKeymanTargets;
{ TImportWindowsKeyboard }
@@ -162,7 +167,7 @@ begin
// Run importkeyboard into destination file; this replaces the keyboard template
// file that has been generated
- if not ImportKeyboard(FTemplate.KeyboardFilename, FTemplate.Name) then
+ if not ImportKeyboard(FTemplate.KeyboardFilename, FTemplate.OSKFilename, FTemplate.Name) then
Exit(Fail('Unable to run importkeyboard on '+FSourceKLID));
// Replace .ico with a new one based on the language id
@@ -170,12 +175,8 @@ begin
if not GenerateIcon(FTemplate.IconFilename) then
Exit(Fail('Unable to generate an icon for '+FTemplate.KeyboardFilename));
- // Load the source .kmn and add bitmap field
- // importkeyboard interop assumption, adding at line 12 is okay (technically, by .kmn format
- // we can add at any line, but line 12 is nice because it is in the middle of the system
- // stores generated by importkeyboard.
-
- // Save final kmn file
+ // Load the source .kmn and add bitmap, copyright, visualkeyboard fields
+ InjectSystemStores(FTemplate.KeyboardFilename, FTemplate.OSKFilename, FTemplate.IconFilename);
// Create .kpj
//FTemplate.SaveProjectFile; <-- already done
@@ -186,25 +187,75 @@ begin
Result := True;
end;
-function TImportWindowsKeyboard.ImportKeyboard(const DestinationFilename, Name: string): Boolean;
+procedure TImportWindowsKeyboard.InjectSystemStores(const KeyboardFilename, OSKFilename, IconFilename: string);
var
- AppLogText: string;
- AppExitCode: Integer;
+ kp: TKeyboardParser;
+ sl: TStringList;
begin
- if not TUtilExecute.Console(
- Format('"%s\importkeyboard.exe" "%s" "%s" "%s"',
- [ExtractFileDir(ParamStr(0)),
- FSourceKLID,
- DestinationFilename,
- Name]),
- GetCurrentDir,
- AppLogText,
- AppExitCode) then
- Exit(False);
+ kp := TKeyboardParser.Create;
+ try
+ kp.FileName := KeyboardFilename;
+ kp.LoadFromFile(KeyboardFilename);
+ kp.Features.Add(kfIcon);
+ kp.Features.Add(kfOSK);
+ kp.SetSystemStoreValue(ssVisualKeyboard, ExtractFileName(OSKFilename));
+ kp.SetSystemStoreValue(ssBitmap, ExtractFilename(IconFilename));
+ kp.SetSystemStoreValue(ssCopyright, FCopyright);
+ if FAuthor <> '' then
+ kp.InitialComment := kp.InitialComment + 'Run by: ' + FAuthor + #13#10;
- writeln(AppLogText);
+ sl := TStringList.Create;
+ try
+ sl.Text := kp.KeyboardText;
+ sl.SaveToFile(KeyboardFilename, TEncoding.UTF8);
+ finally
+ sl.Free;
+ end;
+ finally
+ kp.Free;
+ end;
+end;
- Exit(AppExitCode = 0);
+function TImportWindowsKeyboard.ImportKeyboard(const DestinationFilename, DestinationKVKSFilename, Name: string): Boolean;
+var
+ ik: TImportKeyboardDLL;
+ sl: TStringList;
+ ss: TStringStream;
+begin
+ ik := TImportKeyboardDLL.Create(FSourceKLID, Name);
+ try
+ try
+ ik.Execute;
+ except
+ on E:EImportKeyboardDLL do
+ begin
+ writeln(E.Message);
+ Exit(False);
+ end;
+ end;
+
+ // Still need a BOM for .kmn ... for now
+ sl := TStringList.Create;
+ try
+ sl.Text := ik.KMN;
+ sl.SaveToFile(DestinationFilename, TEncoding.UTF8);
+ finally
+ sl.Free;
+ end;
+
+ // No BOM for .kvks
+ ss := TStringStream.Create(ik.KVKS, TEncoding.UTF8);
+ try
+ ss.SaveToFile(DestinationKVKSFilename);
+ finally
+ ss.Free;
+ end;
+
+ finally
+ ik.Free;
+ end;
+
+ Result := True;
end;
function TImportWindowsKeyboard.GenerateIcon(
diff --git a/windows/src/developer/kmconvert/importkeyboard_pas/Keyman.Developer.System.ImportKeyboardMain.pas b/windows/src/developer/kmconvert/importkeyboard_pas/Keyman.Developer.System.ImportKeyboardMain.pas
deleted file mode 100644
index 7623ea7308..0000000000
--- a/windows/src/developer/kmconvert/importkeyboard_pas/Keyman.Developer.System.ImportKeyboardMain.pas
+++ /dev/null
@@ -1,115 +0,0 @@
-unit Keyman.Developer.System.ImportKeyboardMain;
-
-interface
-
-procedure Run;
-
-implementation
-
-uses
- System.Classes,
- System.SysUtils,
- System.Win.Registry,
- Winapi.Windows,
-
- Keyman.Developer.System.ImportKeyboardDLL;
-
-procedure ShowKeyboardList; forward;
-
-const
- CRootKey = 'System\CurrentControlSet\Control\Keyboard Layouts';
-
-procedure Run;
-var
- inputHKL, outputFileName: string;
- ikd: TImportKeyboardDLL;
- sl: TStringList;
- ss: TStringStream;
-begin
- if ParamCount = 0 then
- begin
- writeln('Usage: importkeyboard /list | hkl [output.kmn] ');
- writeln(' /list shows a list of keyboards available on your system.');
- writeln(' hkl should be an 8 hex digit Keyboard ID. See /list to enumerate these.');
- writeln(' If output.kmn is not specified, the filename of the source keyboard will be used; e.g. 00000409 will produce kbdus.kmn');
- Exit;
- end;
-
- if SameText(ParamStr(1), '/list') then
- begin
- ShowKeyboardList;
- Exit;
- end;
-
- inputHKL := ParamStr(1);
- if ParamCount > 1 then
- outputFileName := ParamStr(2);
-
- ikd := TImportKeyboardDLL.Create(inputHKL); //, outputFileName, '');
- try
- if outputFileName = '' then
- outputFileName := ikd.RecommendedOutputKMNFileName;
- writeln('Importing Windows system keyboard '+ikd.InputHKL+' to Keyman keyboard '+outputFileName);
-
- ikd.Execute;
-
- // Still need a BOM for .kmn ... for now
- sl := TStringList.Create;
- try
- sl.Text := ikd.KMN;
- sl.SaveToFile(outputFileName, TEncoding.UTF8);
- finally
- sl.Free;
- end;
-
- // No BOM for .kvks
-// ss := TStringStream.Create(ikd.KVKS, TEncoding.UTF8);
-// try
-// ss.SaveToFile(ChangeFileExt(outputFileName, '.kvks'));
-// finally
-// ss.Free;
-// end;
- finally
- ikd.Free;
- end;
-
-end;
-
-procedure ShowKeyboardList;
-var
- r: TRegistry;
- keyboardIds: TStringList;
- keyboardId: string;
- layoutFile: string;
- layoutText: string;
-begin
- r := TRegistry.Create;
- keyboardIds := TStringList.Create;
- try
- r.RootKey := HKEY_LOCAL_MACHINE;
- if r.OpenKeyReadOnly(CRootKey) then //TODO Use RegistryKeys
- begin
- r.GetKeyNames(keyboardIds);
- for keyboardId in keyboardIds do
- begin
- if r.OpenKeyReadOnly('\' + CRootKey + '\' + keyboardId) then
- begin
- if not r.ValueExists('keyman install') then
- begin
- layoutFile := r.ReadString('layout file');
- layoutText := r.ReadString('layout text');
- if (layoutFile <> '') and (layoutText <> '') then
- begin
- writeln(' ' + keyboardId + #9 + layoutFile + #9 + layoutText);
- end;
- end;
- end;
- end;
- end;
- finally
- r.Free;
- keyboardIds.Free;
- end;
-end;
-
-end.
diff --git a/windows/src/developer/kmconvert/importkeyboard_pas/importkeyboard.dpr b/windows/src/developer/kmconvert/importkeyboard_pas/importkeyboard.dpr
deleted file mode 100644
index f268b238b8..0000000000
--- a/windows/src/developer/kmconvert/importkeyboard_pas/importkeyboard.dpr
+++ /dev/null
@@ -1,21 +0,0 @@
-program importkeyboard;
-
-{$APPTYPE CONSOLE}
-
-{$R *.res}
-
-uses
- System.SysUtils,
- Keyman.Developer.System.ImportKeyboardDLL in 'Keyman.Developer.System.ImportKeyboardDLL.pas',
- VKeys in '..\..\..\global\delphi\general\VKeys.pas',
- ScanCodeMap in '..\..\..\global\delphi\general\ScanCodeMap.pas',
- Keyman.Developer.System.ImportKeyboardMain in 'Keyman.Developer.System.ImportKeyboardMain.pas';
-
-begin
- try
- Run;
- except
- on E: Exception do
- Writeln(E.ClassName, ': ', E.Message);
- end;
-end.
diff --git a/windows/src/developer/kmconvert/importkeyboard_pas/importkeyboard.dproj b/windows/src/developer/kmconvert/importkeyboard_pas/importkeyboard.dproj
deleted file mode 100644
index 03fb3d15e4..0000000000
--- a/windows/src/developer/kmconvert/importkeyboard_pas/importkeyboard.dproj
+++ /dev/null
@@ -1,596 +0,0 @@
-
-
- {6AED868A-E3B2-4A0E-9A3F-94F76052C85E}
- 18.4
- None
- importkeyboard.dpr
- True
- Debug
- Win32
- 1
- Console
-
-
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Cfg_1
- true
- true
-
-
- true
- Base
- true
-
-
- .\$(Platform)\$(Config)
- .\$(Platform)\$(Config)
- false
- false
- false
- false
- false
- RESTComponents;FireDAC;FireDACSqliteDriver;soaprtl;FireDACIBDriver;soapmidas;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;$(DCC_UsePackage)
- System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
- importkeyboard
-
-
- $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png
- $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png
- $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png
- $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png
- $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png
- $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png
- $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png
- $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png
- $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png
-
-
- DBXSqliteDriver;bindcompdbx;IndyIPCommon;DBXInterBaseDriver;IndyIPServer;IndySystem;tethering;fmxFireDAC;bindcompfmx;FireDACPgDriver;inetdb;DbxCommonDriver;fmx;fmxdae;xmlrtl;fmxobj;rtl;DbxClientDriver;CustomIPTransport;dbexpress;IndyCore;bindcomp;dsnap;IndyIPClient;dbxcds;bindengine;DBXMySQLDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;IndyProtocols;FireDACCommonODBC;fmxase;$(DCC_UsePackage)
- true
-
-
- DBXSqliteDriver;bindcompdbx;IndyIPCommon;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;svnui;mbColorLibD10;dsnapcon;FireDACADSDriver;scFontCombo;DCPdelphi2009;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;vcltouch;JvCore;vcldb;bindcompfmx;svn;FireDACPgDriver;inetdb;CEF4Delphi;DbxCommonDriver;fmx;fmxdae;xmlrtl;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;IndyIPClient;bindcompvcl;EmbeddedWebBrowser_XE;VCLRESTComponents;dbxcds;VclSmp;JvDocking;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;IndyProtocols;keyman_components;FireDACCommonODBC;fmxase;$(DCC_UsePackage)
- Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
- Debug
- CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
- 1033
- true
- $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
- $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
-
-
- DBXSqliteDriver;bindcompdbx;IndyIPCommon;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;vcltouch;vcldb;bindcompfmx;FireDACPgDriver;inetdb;DbxCommonDriver;fmx;fmxdae;xmlrtl;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;IndyIPClient;bindcompvcl;VCLRESTComponents;dbxcds;VclSmp;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;IndyProtocols;FireDACCommonODBC;fmxase;$(DCC_UsePackage)
- true
- $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
- $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
-
-
- DEBUG;$(DCC_Define)
- true
- false
- true
- true
- true
-
-
- false
-
-
- false
- RELEASE;$(DCC_Define)
- 0
- 0
-
-
-
- MainSource
-
-
-
-
-
-
- Cfg_2
- Base
-
-
- Base
-
-
- Cfg_1
- Base
-
-
-
- Delphi.Personality.12
- Application
-
-
-
- importkeyboard.dpr
-
-
-
-
-
- true
-
-
-
-
- true
-
-
-
-
- true
-
-
-
-
- true
-
-
-
-
- importkeyboard.exe
- true
-
-
-
-
- 1
-
-
- Contents\MacOS
- 1
-
-
- Contents\MacOS
- 0
-
-
-
-
- classes
- 1
-
-
-
-
- library\lib\armeabi-v7a
- 1
-
-
-
-
- library\lib\armeabi
- 1
-
-
-
-
- library\lib\mips
- 1
-
-
-
-
- library\lib\armeabi-v7a
- 1
-
-
-
-
- res\drawable
- 1
-
-
-
-
- res\values
- 1
-
-
-
-
- res\drawable
- 1
-
-
-
-
- res\drawable-xxhdpi
- 1
-
-
-
-
- res\drawable-ldpi
- 1
-
-
-
-
- res\drawable-mdpi
- 1
-
-
-
-
- res\drawable-hdpi
- 1
-
-
-
-
- res\drawable-xhdpi
- 1
-
-
-
-
- res\drawable-small
- 1
-
-
-
-
- res\drawable-normal
- 1
-
-
-
-
- res\drawable-large
- 1
-
-
-
-
- res\drawable-xlarge
- 1
-
-
-
-
- 1
-
-
- Contents\MacOS
- 1
-
-
- 0
-
-
-
-
- Contents\MacOS
- 1
- .framework
-
-
- 0
-
-
-
-
- 1
- .dylib
-
-
- 1
- .dylib
-
-
- 1
- .dylib
-
-
- Contents\MacOS
- 1
- .dylib
-
-
- 0
- .dll;.bpl
-
-
-
-
- 1
- .dylib
-
-
- 1
- .dylib
-
-
- 1
- .dylib
-
-
- Contents\MacOS
- 1
- .dylib
-
-
- 0
- .bpl
-
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- Contents\Resources\StartUp\
- 0
-
-
- 0
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
-
-
- ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
- 1
-
-
- ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
- 1
-
-
-
-
- 1
-
-
- 1
-
-
-
-
- ..\
- 1
-
-
- ..\
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- ..\
- 1
-
-
-
-
- Contents
- 1
-
-
-
-
- Contents\Resources
- 1
-
-
-
-
- library\lib\armeabi-v7a
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- Contents\MacOS
- 1
-
-
- 0
-
-
-
-
- 1
-
-
- 1
-
-
-
-
- Assets
- 1
-
-
- Assets
- 1
-
-
-
-
- Assets
- 1
-
-
- Assets
- 1
-
-
-
-
-
-
-
-
-
-
-
-
- False
- False
- True
- False
-
-
- 12
-
-
-
-
-
diff --git a/windows/src/developer/kmconvert/importkeyboard_pas/importkeyboard.res b/windows/src/developer/kmconvert/importkeyboard_pas/importkeyboard.res
deleted file mode 100644
index 743599575b..0000000000
Binary files a/windows/src/developer/kmconvert/importkeyboard_pas/importkeyboard.res and /dev/null differ
diff --git a/windows/src/developer/kmconvert/kmconvert.dpr b/windows/src/developer/kmconvert/kmconvert.dpr
index 91482ae3c2..80c4560295 100644
--- a/windows/src/developer/kmconvert/kmconvert.dpr
+++ b/windows/src/developer/kmconvert/kmconvert.dpr
@@ -88,7 +88,9 @@ uses
CompilePackageInstaller in '..\..\global\delphi\general\CompilePackageInstaller.pas',
kmpinffile in '..\..\global\delphi\general\kmpinffile.pas',
UMD5Hash in '..\..\global\delphi\general\UMD5Hash.pas',
- Keyman.Developer.System.KMConvertParameters in 'Keyman.Developer.System.KMConvertParameters.pas';
+ Keyman.Developer.System.KMConvertParameters in 'Keyman.Developer.System.KMConvertParameters.pas',
+ Keyman.Developer.System.ImportKeyboardDLL in 'Keyman.Developer.System.ImportKeyboardDLL.pas',
+ ScanCodeMap in '..\..\global\delphi\general\ScanCodeMap.pas';
begin
try
diff --git a/windows/src/developer/kmconvert/kmconvert.dproj b/windows/src/developer/kmconvert/kmconvert.dproj
index db09c576fa..de086186dc 100644
--- a/windows/src/developer/kmconvert/kmconvert.dproj
+++ b/windows/src/developer/kmconvert/kmconvert.dproj
@@ -180,6 +180,8 @@
+
+
Cfg_2
Base
diff --git a/windows/src/global/delphi/visualkeyboard/VisualKeyboardLoaderXML.pas b/windows/src/global/delphi/visualkeyboard/VisualKeyboardLoaderXML.pas
index 973ef588fd..3e6957a107 100644
--- a/windows/src/global/delphi/visualkeyboard/VisualKeyboardLoaderXML.pas
+++ b/windows/src/global/delphi/visualkeyboard/VisualKeyboardLoaderXML.pas
@@ -152,7 +152,7 @@ begin
FKbd.Clear;
doc := TXMLDocument.Create(nil);
- doc.LoadFromStream(Stream);
+ doc.LoadFromStream(Stream, xetUTF_8);
header := FindNode('header');
if not Assigned(header) then