diff --git a/release/c/cs_pinyin/HISTORY.md b/release/c/cs_pinyin/HISTORY.md new file mode 100644 index 0000000000..c33c55e1e1 --- /dev/null +++ b/release/c/cs_pinyin/HISTORY.md @@ -0,0 +1,11 @@ +CS Pinyin Change History +======================= + +1.4 (1 Aug 2024) +----------------- +* Improve IM window handling when using more than one application +* Improve multiple monitor support +* Add build script and reorganize files for Keyman 17 + +* Published under MIT license to keymanapp/keyboards GitHub repository + diff --git a/release/c/cs_pinyin/LICENSE.md b/release/c/cs_pinyin/LICENSE.md new file mode 100644 index 0000000000..a467b169c3 --- /dev/null +++ b/release/c/cs_pinyin/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2003-2024 SIL International + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/release/c/cs_pinyin/README.md b/release/c/cs_pinyin/README.md new file mode 100644 index 0000000000..981810b833 --- /dev/null +++ b/release/c/cs_pinyin/README.md @@ -0,0 +1,28 @@ +CS-Pinyin keyboard +================== + +Description +----------- + +This input method extension for Keyman Desktop provides input mapping for more +than 100,000 Han characters, multi-character words, proper names, and place name +abbreviations. Supported input conventions include Pinyin, RAD-RSC and 4-corner +index (4CI). + +Notes +----- + +The source/build.bat for this keyboard builds the Windows executables and DLLs +required to make this keyboard work, and places the binaries in the source +folder. The binaries must be checked in. + +build.bat requires VC++2019. + +Links +----- + + * Contact: support@keyman.com + +Supported Platforms +------------------- + * Windows diff --git a/release/c/cs_pinyin/cs_pinyin.kpj b/release/c/cs_pinyin/cs_pinyin.kpj new file mode 100644 index 0000000000..e623a6059a --- /dev/null +++ b/release/c/cs_pinyin/cs_pinyin.kpj @@ -0,0 +1,8 @@ + + + + 2.0 + True + True + + diff --git a/release/c/cs_pinyin/extra/CS-Pinyin.doc b/release/c/cs_pinyin/extra/CS-Pinyin.doc new file mode 100644 index 0000000000..af3b85b703 Binary files /dev/null and b/release/c/cs_pinyin/extra/CS-Pinyin.doc differ diff --git a/release/c/cs_pinyin/extra/CS-Pinyin/CS-Pinyin.cfg b/release/c/cs_pinyin/extra/CS-Pinyin/CS-Pinyin.cfg new file mode 100644 index 0000000000..dfb67c6df3 Binary files /dev/null and b/release/c/cs_pinyin/extra/CS-Pinyin/CS-Pinyin.cfg differ diff --git a/release/c/cs_pinyin/extra/CS-Pinyin/Make Full CFG.bat b/release/c/cs_pinyin/extra/CS-Pinyin/Make Full CFG.bat new file mode 100644 index 0000000000..ca32fea1c2 --- /dev/null +++ b/release/c/cs_pinyin/extra/CS-Pinyin/Make Full CFG.bat @@ -0,0 +1,8 @@ +copy /b "Part 1 - Header and Punctuation.txt" CS-Pinyin.cfg +copy /b CS-Pinyin.cfg + "Part 2 - Single characters.txt" +copy /b CS-Pinyin.cfg + "Part 3 - Binomes and Polynomes.txt" +copy /b CS-Pinyin.cfg + "Part 4 - Acronyms.txt" +copy /b CS-Pinyin.cfg + "Part 5 - RAD-RSC.txt" +copy /b CS-Pinyin.cfg + "Part 6 - 4CI.txt" + + diff --git a/release/c/cs_pinyin/extra/CS-Pinyin/Part 1 - Header and Punctuation.txt b/release/c/cs_pinyin/extra/CS-Pinyin/Part 1 - Header and Punctuation.txt new file mode 100644 index 0000000000..b1730380fd Binary files /dev/null and b/release/c/cs_pinyin/extra/CS-Pinyin/Part 1 - Header and Punctuation.txt differ diff --git a/release/c/cs_pinyin/extra/CS-Pinyin/Part 2 - Single characters.txt b/release/c/cs_pinyin/extra/CS-Pinyin/Part 2 - Single characters.txt new file mode 100644 index 0000000000..c76de054d3 Binary files /dev/null and b/release/c/cs_pinyin/extra/CS-Pinyin/Part 2 - Single characters.txt differ diff --git a/release/c/cs_pinyin/extra/CS-Pinyin/Part 3 - Binomes and Polynomes.txt b/release/c/cs_pinyin/extra/CS-Pinyin/Part 3 - Binomes and Polynomes.txt new file mode 100644 index 0000000000..69765926c6 Binary files /dev/null and b/release/c/cs_pinyin/extra/CS-Pinyin/Part 3 - Binomes and Polynomes.txt differ diff --git a/release/c/cs_pinyin/extra/CS-Pinyin/Part 4 - Acronyms.txt b/release/c/cs_pinyin/extra/CS-Pinyin/Part 4 - Acronyms.txt new file mode 100644 index 0000000000..5ffa3b534f Binary files /dev/null and b/release/c/cs_pinyin/extra/CS-Pinyin/Part 4 - Acronyms.txt differ diff --git a/release/c/cs_pinyin/extra/CS-Pinyin/Part 5 - RAD-RSC.txt b/release/c/cs_pinyin/extra/CS-Pinyin/Part 5 - RAD-RSC.txt new file mode 100644 index 0000000000..9f80a7980e Binary files /dev/null and b/release/c/cs_pinyin/extra/CS-Pinyin/Part 5 - RAD-RSC.txt differ diff --git a/release/c/cs_pinyin/extra/CS-Pinyin/Part 6 - 4CI.txt b/release/c/cs_pinyin/extra/CS-Pinyin/Part 6 - 4CI.txt new file mode 100644 index 0000000000..0a614847c0 Binary files /dev/null and b/release/c/cs_pinyin/extra/CS-Pinyin/Part 6 - 4CI.txt differ diff --git a/release/c/cs_pinyin/extra/CS-Pinyin/database.zip b/release/c/cs_pinyin/extra/CS-Pinyin/database.zip new file mode 100644 index 0000000000..7a3647dde6 Binary files /dev/null and b/release/c/cs_pinyin/extra/CS-Pinyin/database.zip differ diff --git a/release/c/cs_pinyin/extra/Simplified Chinese.doc b/release/c/cs_pinyin/extra/Simplified Chinese.doc new file mode 100644 index 0000000000..aafdea5244 Binary files /dev/null and b/release/c/cs_pinyin/extra/Simplified Chinese.doc differ diff --git a/release/c/cs_pinyin/extra/The Four Corner Index Lookup Method.doc b/release/c/cs_pinyin/extra/The Four Corner Index Lookup Method.doc new file mode 100644 index 0000000000..049d6f33a0 Binary files /dev/null and b/release/c/cs_pinyin/extra/The Four Corner Index Lookup Method.doc differ diff --git a/release/c/cs_pinyin/extra/cjkdict.zip b/release/c/cs_pinyin/extra/cjkdict.zip new file mode 100644 index 0000000000..e5c7902d05 Binary files /dev/null and b/release/c/cs_pinyin/extra/cjkdict.zip differ diff --git a/release/c/cs_pinyin/source/.gitignore b/release/c/cs_pinyin/source/.gitignore new file mode 100644 index 0000000000..5c2cec7580 --- /dev/null +++ b/release/c/cs_pinyin/source/.gitignore @@ -0,0 +1,2 @@ +.vs/ +**/*.vcxproj.user \ No newline at end of file diff --git a/release/c/cs_pinyin/source/KeymnIMX.dll b/release/c/cs_pinyin/source/KeymnIMX.dll new file mode 100644 index 0000000000..dc3bba15a0 Binary files /dev/null and b/release/c/cs_pinyin/source/KeymnIMX.dll differ diff --git a/release/c/cs_pinyin/source/KeymnIMX.x64.dll b/release/c/cs_pinyin/source/KeymnIMX.x64.dll new file mode 100644 index 0000000000..6f36a07edd Binary files /dev/null and b/release/c/cs_pinyin/source/KeymnIMX.x64.dll differ diff --git a/release/c/cs_pinyin/source/build.bat b/release/c/cs_pinyin/source/build.bat new file mode 100644 index 0000000000..4e3d9a7617 --- /dev/null +++ b/release/c/cs_pinyin/source/build.bat @@ -0,0 +1,15 @@ +@echo off + +if "%1" == "--debug" ( + set CONFIG=Debug +) else ( + set CONFIG=Release +) + +msbuild keymanimx/KeymanIMX.vcxproj /p:Platform=Win32 /p:Configuration=%CONFIG% +msbuild keymanimx/KeymanIMX.vcxproj /p:Platform=x64 /p:Configuration=%CONFIG% +msbuild imxconfig/imxconfig.vcxproj /p:Platform=Win32 /p:Configuration=%CONFIG% +msbuild imxreload/imxreload.vcxproj /p:Platform=Win32 /p:Configuration=%CONFIG% +copy ..\build\KeymanIMX\Win32\%CONFIG%\KeymnIMX.dll ..\source +copy ..\build\KeymanIMX\x64\%CONFIG%\KeymnIMX.x64.dll ..\source +copy ..\build\imxconfig\Win32\%CONFIG%\imxconfig.exe ..\source diff --git a/release/c/cs_pinyin/source/cs_pinyin.cfg b/release/c/cs_pinyin/source/cs_pinyin.cfg new file mode 100644 index 0000000000..dfb67c6df3 Binary files /dev/null and b/release/c/cs_pinyin/source/cs_pinyin.cfg differ diff --git a/release/c/cs_pinyin/source/cs_pinyin.cfx b/release/c/cs_pinyin/source/cs_pinyin.cfx new file mode 100644 index 0000000000..d3b19677a2 Binary files /dev/null and b/release/c/cs_pinyin/source/cs_pinyin.cfx differ diff --git a/release/c/cs_pinyin/source/cs_pinyin.kmn b/release/c/cs_pinyin/source/cs_pinyin.kmn new file mode 100644 index 0000000000..91ca8913d6 --- /dev/null +++ b/release/c/cs_pinyin/source/cs_pinyin.kmn @@ -0,0 +1,40 @@ +store(&VERSION) '9.0' +store(&HOTKEY) '[Ctrl Alt K_S]' +store(&BITMAP) 'images\CS-Pinyin Icon.bmp' + +store(&mnemoniclayout) '1' +store(©RIGHT) 'SIL International' +store(&NAME) 'Simplified Chinese' +store(&KEYBOARDVERSION) '1.4' + +begin Unicode > use(main) + +c Use an 8.3 name for compatibility with Win 9x +store(DLLFunction) "KeymnIMX.DLL:FindGlyph" + +store(VKeys) [K_ESC][' '][K_BKSP][K_PGUP][K_PGDN][K_LEFT][K_RIGHT][K_UP][K_DOWN][K_ENTER][K_HOME][K_END][K_F24] +store(NPKeys) [K_NP0][K_NP1][K_NP2][K_NP3][K_NP4][K_NP5][K_NP6][K_NP7][K_NP8][K_NP9][K_NPSTAR][K_NPPLUS][K_NPMINUS][K_NPDOT] + +store(FKeys) [K_F1][K_F2][K_F3][K_F4][K_F5][K_F6][K_F7][K_F8][K_F9][K_F10][K_F11][K_F12] +store(SFKeys) [SHIFT K_F1][SHIFT K_F2][SHIFT K_F3][SHIFT K_F4][SHIFT K_F5][SHIFT K_F6] \ + [SHIFT K_F7][SHIFT K_F8][SHIFT K_F9][SHIFT K_F10][SHIFT K_F11][SHIFT K_F12] +store(CFKeys) [CTRL K_F1][CTRL K_F2][CTRL K_F3][CTRL K_F4][CTRL K_F5][CTRL K_F6] \ + [CTRL K_F7][CTRL K_F8][CTRL K_F9][CTRL K_F10][CTRL K_F11][CTRL K_F12] + +group(main) using keys + +c any virtual keys that need to be processed must be explicitly matched + + any(VKeys) > call(DLLFunction) + + any(NPKeys) > call(DLLFunction) + +c enable the following lines to allow Function keys, with Shift or Ctrl modifiers +c to be passed to the IMX DLL. Comment them out otherwise. + + any(FKeys) > call(DLLFunction) + + any(SFKeys) > call(DLLFunction) + + any(CFKeys) > call(DLLFunction) + +c the configuration hotkey must also be explicitly matched + + [CTRL SHIFT '`'] > call(DLLFunction) + +c normal ASCII keys will match on the nomatch rule + nomatch > call(DLLFunction) diff --git a/release/c/cs_pinyin/source/cs_pinyin.kps b/release/c/cs_pinyin/source/cs_pinyin.kps new file mode 100644 index 0000000000..b9c0b78bdf --- /dev/null +++ b/release/c/cs_pinyin/source/cs_pinyin.kps @@ -0,0 +1,133 @@ + + + + 17.0.328.0 + 7.0 + + + + docs\readme.htm + images\CS-Pinyin Install.bmp + ..\LICENSE.md + docs\welcome.htm + + + + + + Simplified Chinese + + + + Using Simplified Chinese (PDF) + Using Simplified Chinese.pdf + + + psmelStartMenu + + + Welcome + CS-Pinyin ReadMe.html + + + psmelStartMenu + + + About the Four Corner Method + About the Four Corner Method.pdf + + + psmelStartMenu + + + + + Simplified Chinese + + © SIL International + SIL International + https://keyman.com/ + + + + ..\build\cs_pinyin.kmx + Keyboard CS-Pinyin + 0 + .kmx + + + images\CS-Pinyin Install.bmp + File CS-Pinyin Install.bmp + 0 + .bmp + + + docs\welcome.htm + File welcome.htm + 0 + .htm + + + docs\About the Four Corner Method.pdf + File About the Four Corner Method.pdf + 0 + .pdf + + + docs\Using Simplified Chinese.pdf + File Using Simplified Chinese.pdf + 0 + .pdf + + + cs_pinyin.cfx + File cs_pinyin.cfx + 0 + .cfx + + + ..\source\KeymnIMX.x64.dll + File KeymnIMX.x64.dll + 0 + .dll + + + ..\source\imxconfig.exe + File imxconfig.exe + 0 + .exe + + + ..\LICENSE.md + File LICENSE.md + 0 + .md + + + ..\source\KeymnIMX.dll + File KeymnIMX.dll + 0 + .dll + + + docs\readme.htm + File readme.htm + 0 + .htm + + + + + Simplified Chinese + cs_pinyin + 1.4 + + Chinese + + + + + + + + diff --git a/release/c/cs_pinyin/source/cs_pinyin.sln b/release/c/cs_pinyin/source/cs_pinyin.sln new file mode 100644 index 0000000000..1acd1d583c --- /dev/null +++ b/release/c/cs_pinyin/source/cs_pinyin.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31313.79 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeymanIMX", "keymanimx\KeymanIMX.vcxproj", "{F00D56AD-FFA9-4012-95D4-4ED8FA00DDEC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imxconfig", "imxconfig\imxconfig.vcxproj", "{4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imxreload", "imxreload\imxreload.vcxproj", "{838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F00D56AD-FFA9-4012-95D4-4ED8FA00DDEC}.Debug|Win32.ActiveCfg = Debug|Win32 + {F00D56AD-FFA9-4012-95D4-4ED8FA00DDEC}.Debug|Win32.Build.0 = Debug|Win32 + {F00D56AD-FFA9-4012-95D4-4ED8FA00DDEC}.Debug|x64.ActiveCfg = Debug|x64 + {F00D56AD-FFA9-4012-95D4-4ED8FA00DDEC}.Debug|x64.Build.0 = Debug|x64 + {F00D56AD-FFA9-4012-95D4-4ED8FA00DDEC}.Release|Win32.ActiveCfg = Release|Win32 + {F00D56AD-FFA9-4012-95D4-4ED8FA00DDEC}.Release|Win32.Build.0 = Release|Win32 + {F00D56AD-FFA9-4012-95D4-4ED8FA00DDEC}.Release|x64.ActiveCfg = Release|x64 + {F00D56AD-FFA9-4012-95D4-4ED8FA00DDEC}.Release|x64.Build.0 = Release|x64 + {4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}.Debug|Win32.ActiveCfg = Debug|Win32 + {4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}.Debug|Win32.Build.0 = Debug|Win32 + {4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}.Debug|x64.ActiveCfg = Debug|x64 + {4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}.Debug|x64.Build.0 = Debug|x64 + {4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}.Release|Win32.ActiveCfg = Release|Win32 + {4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}.Release|Win32.Build.0 = Release|Win32 + {4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}.Release|x64.ActiveCfg = Release|x64 + {4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}.Release|x64.Build.0 = Release|x64 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Debug|Win32.ActiveCfg = Debug|Win32 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Debug|Win32.Build.0 = Debug|Win32 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Debug|x64.ActiveCfg = Debug|x64 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Debug|x64.Build.0 = Debug|x64 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Release|Win32.ActiveCfg = Release|Win32 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Release|Win32.Build.0 = Release|Win32 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Release|x64.ActiveCfg = Release|x64 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A5469622-41A5-4208-B8F8-B7DD2821F94E} + EndGlobalSection +EndGlobal diff --git a/release/c/cs_pinyin/source/docs/About the Four Corner Method.pdf b/release/c/cs_pinyin/source/docs/About the Four Corner Method.pdf new file mode 100644 index 0000000000..f546fc66ba Binary files /dev/null and b/release/c/cs_pinyin/source/docs/About the Four Corner Method.pdf differ diff --git a/release/c/cs_pinyin/source/docs/CS-Pinyin.pdf b/release/c/cs_pinyin/source/docs/CS-Pinyin.pdf new file mode 100644 index 0000000000..5923814a0f Binary files /dev/null and b/release/c/cs_pinyin/source/docs/CS-Pinyin.pdf differ diff --git a/release/c/cs_pinyin/source/docs/The Four Corner Index Lookup Method.pdf b/release/c/cs_pinyin/source/docs/The Four Corner Index Lookup Method.pdf new file mode 100644 index 0000000000..f546fc66ba Binary files /dev/null and b/release/c/cs_pinyin/source/docs/The Four Corner Index Lookup Method.pdf differ diff --git a/release/c/cs_pinyin/source/docs/Using Simplified Chinese.pdf b/release/c/cs_pinyin/source/docs/Using Simplified Chinese.pdf new file mode 100644 index 0000000000..f0d6ce90e1 Binary files /dev/null and b/release/c/cs_pinyin/source/docs/Using Simplified Chinese.pdf differ diff --git a/release/c/cs_pinyin/source/docs/Using the CS-Pinyin IMX.pdf b/release/c/cs_pinyin/source/docs/Using the CS-Pinyin IMX.pdf new file mode 100644 index 0000000000..f0d6ce90e1 Binary files /dev/null and b/release/c/cs_pinyin/source/docs/Using the CS-Pinyin IMX.pdf differ diff --git a/release/c/cs_pinyin/source/docs/readme.htm b/release/c/cs_pinyin/source/docs/readme.htm new file mode 100644 index 0000000000..fc7b50af33 --- /dev/null +++ b/release/c/cs_pinyin/source/docs/readme.htm @@ -0,0 +1,53 @@ +Simplified Chinese Input Method + + + + +

Simplified Chinese

+

An Input Method for Keyman Desktop

+

Description

+

This input method extension for +Keyman Desktop provides input mapping for more than +100,000 Han characters, multi-character +words, proper names, and place name abbreviations. +Supported input conventions include Pinyin, +RAD-RSC and 4-corner index (4CI). +

+ +

Copyright

+ +

+This input method extension is copyright 2003-2024 +by SIL International, and can be freely redistributed, +but no part may be re-packaged, reverse-engineered, +or sold. Wordlists used in this input mapping +extension have been prepared by and are copyright +by Linguasoft. +

+ +

+For further information, refer to the user +documentation included (and installed) with the +package, visit the Keyman website +https://keyman.com/, or email us +at support@keyman.com. +

+ + diff --git a/release/c/cs_pinyin/source/docs/welcome.htm b/release/c/cs_pinyin/source/docs/welcome.htm new file mode 100644 index 0000000000..509b93f855 --- /dev/null +++ b/release/c/cs_pinyin/source/docs/welcome.htm @@ -0,0 +1,50 @@ + + +Simplified Chinese + + + + +

Simplified Chinese

+

An Input Method for Keyman Desktop

+ +

Description

+

This input method extension for Keyman Desktop provides input mapping +for more than 100,000 Han characters, multi-character words, proper names, +and place name abbreviations. Supported input conventions include Pinyin, +RAD-RSC and 4-corner index (4CI). +

+ +

How to use

+ + + +

Copyright

+ +

+This input method extension is copyright SIL International and is distributed under the MIT license. +Wordlists used in this input mapping extension have been prepared by and are copyright Linguasoft. +

+ + diff --git a/release/c/cs_pinyin/source/images/CS Logo Blue.bmp b/release/c/cs_pinyin/source/images/CS Logo Blue.bmp new file mode 100644 index 0000000000..33d009b036 Binary files /dev/null and b/release/c/cs_pinyin/source/images/CS Logo Blue.bmp differ diff --git a/release/c/cs_pinyin/source/images/CS Logo Red.bmp b/release/c/cs_pinyin/source/images/CS Logo Red.bmp new file mode 100644 index 0000000000..149f0f6015 Binary files /dev/null and b/release/c/cs_pinyin/source/images/CS Logo Red.bmp differ diff --git a/release/c/cs_pinyin/source/images/CS-Pinyin Icon.bmp b/release/c/cs_pinyin/source/images/CS-Pinyin Icon.bmp new file mode 100644 index 0000000000..8c2ae261ae Binary files /dev/null and b/release/c/cs_pinyin/source/images/CS-Pinyin Icon.bmp differ diff --git a/release/c/cs_pinyin/source/images/CS-Pinyin Install.bmp b/release/c/cs_pinyin/source/images/CS-Pinyin Install.bmp new file mode 100644 index 0000000000..d3bcb7fbac Binary files /dev/null and b/release/c/cs_pinyin/source/images/CS-Pinyin Install.bmp differ diff --git a/release/c/cs_pinyin/source/images/CS-Pinyin.bmp b/release/c/cs_pinyin/source/images/CS-Pinyin.bmp new file mode 100644 index 0000000000..149f0f6015 Binary files /dev/null and b/release/c/cs_pinyin/source/images/CS-Pinyin.bmp differ diff --git a/release/c/cs_pinyin/source/images/Direction_H.bmp b/release/c/cs_pinyin/source/images/Direction_H.bmp new file mode 100644 index 0000000000..d9902b67d5 Binary files /dev/null and b/release/c/cs_pinyin/source/images/Direction_H.bmp differ diff --git a/release/c/cs_pinyin/source/images/Direction_V.bmp b/release/c/cs_pinyin/source/images/Direction_V.bmp new file mode 100644 index 0000000000..4be2b3d633 Binary files /dev/null and b/release/c/cs_pinyin/source/images/Direction_V.bmp differ diff --git a/release/c/cs_pinyin/source/images/Image1.bmp b/release/c/cs_pinyin/source/images/Image1.bmp new file mode 100644 index 0000000000..194128c38c Binary files /dev/null and b/release/c/cs_pinyin/source/images/Image1.bmp differ diff --git a/release/c/cs_pinyin/source/images/Key.bmp b/release/c/cs_pinyin/source/images/Key.bmp new file mode 100644 index 0000000000..a0bc2999b9 Binary files /dev/null and b/release/c/cs_pinyin/source/images/Key.bmp differ diff --git a/release/c/cs_pinyin/source/images/T_green.bmp b/release/c/cs_pinyin/source/images/T_green.bmp new file mode 100644 index 0000000000..42e25ff4a1 Binary files /dev/null and b/release/c/cs_pinyin/source/images/T_green.bmp differ diff --git a/release/c/cs_pinyin/source/images/T_red.bmp b/release/c/cs_pinyin/source/images/T_red.bmp new file mode 100644 index 0000000000..2b74627563 Binary files /dev/null and b/release/c/cs_pinyin/source/images/T_red.bmp differ diff --git a/release/c/cs_pinyin/source/images/T_yellow.bmp b/release/c/cs_pinyin/source/images/T_yellow.bmp new file mode 100644 index 0000000000..2d7f0cb682 Binary files /dev/null and b/release/c/cs_pinyin/source/images/T_yellow.bmp differ diff --git a/release/c/cs_pinyin/source/images/down0.bmp b/release/c/cs_pinyin/source/images/down0.bmp new file mode 100644 index 0000000000..971885cf6e Binary files /dev/null and b/release/c/cs_pinyin/source/images/down0.bmp differ diff --git a/release/c/cs_pinyin/source/images/down1.bmp b/release/c/cs_pinyin/source/images/down1.bmp new file mode 100644 index 0000000000..19b2cad7f1 Binary files /dev/null and b/release/c/cs_pinyin/source/images/down1.bmp differ diff --git a/release/c/cs_pinyin/source/images/horizont.bmp b/release/c/cs_pinyin/source/images/horizont.bmp new file mode 100644 index 0000000000..1609ca8efd Binary files /dev/null and b/release/c/cs_pinyin/source/images/horizont.bmp differ diff --git a/release/c/cs_pinyin/source/images/left2.bmp b/release/c/cs_pinyin/source/images/left2.bmp new file mode 100644 index 0000000000..b2a9191b83 Binary files /dev/null and b/release/c/cs_pinyin/source/images/left2.bmp differ diff --git a/release/c/cs_pinyin/source/images/master/CS Logo Blue.psp b/release/c/cs_pinyin/source/images/master/CS Logo Blue.psp new file mode 100644 index 0000000000..3b2e2ae678 Binary files /dev/null and b/release/c/cs_pinyin/source/images/master/CS Logo Blue.psp differ diff --git a/release/c/cs_pinyin/source/images/master/CS Logo Red.psp b/release/c/cs_pinyin/source/images/master/CS Logo Red.psp new file mode 100644 index 0000000000..15a2599a38 Binary files /dev/null and b/release/c/cs_pinyin/source/images/master/CS Logo Red.psp differ diff --git a/release/c/cs_pinyin/source/images/master/CS-Pinyin Install.psp b/release/c/cs_pinyin/source/images/master/CS-Pinyin Install.psp new file mode 100644 index 0000000000..81c46a210c Binary files /dev/null and b/release/c/cs_pinyin/source/images/master/CS-Pinyin Install.psp differ diff --git a/release/c/cs_pinyin/source/images/master/CS-Pinyin.psp b/release/c/cs_pinyin/source/images/master/CS-Pinyin.psp new file mode 100644 index 0000000000..621184bb3e Binary files /dev/null and b/release/c/cs_pinyin/source/images/master/CS-Pinyin.psp differ diff --git a/release/c/cs_pinyin/source/images/master/Circle.psp b/release/c/cs_pinyin/source/images/master/Circle.psp new file mode 100644 index 0000000000..0357ee9650 Binary files /dev/null and b/release/c/cs_pinyin/source/images/master/Circle.psp differ diff --git a/release/c/cs_pinyin/source/images/right0.bmp b/release/c/cs_pinyin/source/images/right0.bmp new file mode 100644 index 0000000000..53578843a5 Binary files /dev/null and b/release/c/cs_pinyin/source/images/right0.bmp differ diff --git a/release/c/cs_pinyin/source/images/right1.bmp b/release/c/cs_pinyin/source/images/right1.bmp new file mode 100644 index 0000000000..86f506c3fa Binary files /dev/null and b/release/c/cs_pinyin/source/images/right1.bmp differ diff --git a/release/c/cs_pinyin/source/images/up0.bmp b/release/c/cs_pinyin/source/images/up0.bmp new file mode 100644 index 0000000000..b34eafc07c Binary files /dev/null and b/release/c/cs_pinyin/source/images/up0.bmp differ diff --git a/release/c/cs_pinyin/source/images/up1.bmp b/release/c/cs_pinyin/source/images/up1.bmp new file mode 100644 index 0000000000..100921108f Binary files /dev/null and b/release/c/cs_pinyin/source/images/up1.bmp differ diff --git a/release/c/cs_pinyin/source/images/vertical.bmp b/release/c/cs_pinyin/source/images/vertical.bmp new file mode 100644 index 0000000000..86cb794659 Binary files /dev/null and b/release/c/cs_pinyin/source/images/vertical.bmp differ diff --git a/release/c/cs_pinyin/source/imxconfig.exe b/release/c/cs_pinyin/source/imxconfig.exe new file mode 100644 index 0000000000..da7f15a447 Binary files /dev/null and b/release/c/cs_pinyin/source/imxconfig.exe differ diff --git a/release/c/cs_pinyin/source/imxconfig/Key.bmp b/release/c/cs_pinyin/source/imxconfig/Key.bmp new file mode 100644 index 0000000000..a0bc2999b9 Binary files /dev/null and b/release/c/cs_pinyin/source/imxconfig/Key.bmp differ diff --git a/release/c/cs_pinyin/source/imxconfig/icon1.ico b/release/c/cs_pinyin/source/imxconfig/icon1.ico new file mode 100644 index 0000000000..55b46264be Binary files /dev/null and b/release/c/cs_pinyin/source/imxconfig/icon1.ico differ diff --git a/release/c/cs_pinyin/source/imxconfig/imxconfig.cpp b/release/c/cs_pinyin/source/imxconfig/imxconfig.cpp new file mode 100644 index 0000000000..b228bc2f0c --- /dev/null +++ b/release/c/cs_pinyin/source/imxconfig/imxconfig.cpp @@ -0,0 +1,273 @@ +#include +#include +#include + +#include "resource.h" +#include "../keymanimx/keymanimx.h" + +#define MAXWAIT 60 + +PSTR CAPTION="Keyman IMX Configuration"; + +BOOL Vertical, EnableTracking; +UINT DisplayMode; +KEYBOARD Kbd={0}; + +char drive[_MAX_DRIVE],dir[_MAX_DIR]; + +void WriteRegSetting(PSTR text, int value) +{ + HKEY hkey; + if(RegCreateKeyEx(HKEY_CURRENT_USER, REGSZ_KeymanIMX, 0, NULL, NULL, KEY_ALL_ACCESS, NULL, &hkey, NULL) == ERROR_SUCCESS) + { + RegSetValueEx(hkey, text, 0, REG_DWORD, (PBYTE) &value, 4); + RegCloseKey(hkey); + } +} + +int ReadRegSetting(PSTR text, int dflt) +{ + HKEY hkey; + DWORD value, sz=4, tp=REG_DWORD; + + if(RegOpenKeyEx(HKEY_CURRENT_USER, REGSZ_KeymanIMX, + 0, KEY_ALL_ACCESS | KEY_WOW64_32KEY, &hkey) == ERROR_SUCCESS) + { + if(RegQueryValueEx(hkey, text, 0, &tp, (PBYTE) &value, &sz) == ERROR_SUCCESS) + dflt = value; + RegCloseKey(hkey); + } + return dflt; +} + +BOOL ReadConfiguration(void) +{ + char key[128]="IMX: "; + + Vertical = ReadRegSetting("IMX z",FALSE) ? TRUE : FALSE; + EnableTracking = ReadRegSetting("IMX track",TRUE) ? TRUE : FALSE; + DisplayMode = ReadRegSetting("IMX match",DM_LIMITED); + + if(*Kbd.h.name) + { + strcat_s(key, sizeof key, Kbd.h.name); + Kbd.h.dwOptions = ReadRegSetting(key,Kbd.h.dwOptions); + } + + return TRUE; +} + +BOOL SaveConfiguration(void) +{ + char key[128]="IMX: "; + + WriteRegSetting("IMX track", EnableTracking); + WriteRegSetting("IMX z", Vertical); + WriteRegSetting("IMX match", DisplayMode); + + if(*Kbd.h.name) + { + strcat_s(key, sizeof key, Kbd.h.name); + WriteRegSetting(key,Kbd.h.dwOptions); + } + return TRUE; +} + +INT_PTR CALLBACK IMXConfigProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + PSTR p=(PSTR)lParam; + int n, dMode, sMode, tMode, sBits=0, tBits=0, uBits=0, Unique, Duplicates; + int ctrlID[] = {IDC_KBDNAME,IDC_SELECTION,IDC_SELECT1,IDC_SELECT2,IDC_SELECT3, + IDC_SELECT4,IDC_TONES,IDC_TONE1,IDC_TONE2,IDC_TONE3,IDC_SELECTUNIQUE}; + + switch(msg) + { + case WM_INITDIALOG: + dMode = DisplayMode == DM_LIMITED ? IDC_MATCH1 : IDC_MATCH2; + CheckDlgButton(hwnd,IDC_VERTICAL,Vertical?BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwnd,IDC_HORIZONTAL,Vertical?BST_UNCHECKED:BST_CHECKED); + CheckDlgButton(hwnd,IDC_TRACK,EnableTracking?BST_CHECKED:BST_UNCHECKED); + CheckRadioButton(hwnd,IDC_MATCH1,IDC_MATCH2,dMode); + + // Set dialog buttons according to currently saved options + if(*Kbd.h.name) + { + char tkeys[32]="Tone keys"; + + for(n=0; n>2)) + { + case TM_NEVER: + tMode =IDC_TONE1; break; + case TM_ALWAYS: + tMode =IDC_TONE2; break; + case TM_OPTIONAL: + tMode =IDC_TONE3; break; + } + + Unique = (Kbd.h.dwOptions & SELECTIFUNIQUE) ? BST_CHECKED : BST_UNCHECKED; + Duplicates = (Kbd.h.dwOptions & SHOWDUPLICATES) ? BST_CHECKED : BST_UNCHECKED; + + CheckRadioButton(hwnd,IDC_SELECT1,IDC_SELECT4,sMode); + CheckRadioButton(hwnd,IDC_TONE1,IDC_TONE3,tMode); + CheckDlgButton(hwnd,IDC_SELECTUNIQUE,Unique); + CheckDlgButton(hwnd,IDC_SHOWDUPLICATES,Duplicates); + + // Set other constraints + if(Kbd.h.dwFKeys == 0) DisableDlgItem(hwnd,IDC_SELECT4); + } + else + { + for(n=0; nToneChar); + Kbd.h.dwOptions = pkbh->dwOptions; + Kbd.h.dwFKeys = pkbh->dwFKeys; + UnmapViewOfFile(pkbh); CloseHandle(hMapObject); + } + } + + ReadConfiguration(); + if(DialogBox(hInst,"CONFIGURE",NULL,IMXConfigProc)) SaveConfiguration(); + + return 0; +} diff --git a/release/c/cs_pinyin/source/imxconfig/imxconfig.rc b/release/c/cs_pinyin/source/imxconfig/imxconfig.rc new file mode 100644 index 0000000000..7646ae8c3a --- /dev/null +++ b/release/c/cs_pinyin/source/imxconfig/imxconfig.rc @@ -0,0 +1,190 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (Australia) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +CONFIGURE DIALOG DISCARDABLE 0, 0, 287, 159 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Keyman IMX Configuration" +FONT 8, "MS Sans Serif" +BEGIN + GROUPBOX "Display options",IDC_STATIC,7,7,216,56 + GROUPBOX "&Input matching",IDC_STATIC,13,16,76,36,WS_GROUP + CONTROL "First syllable",IDC_MATCH1,"Button",BS_AUTORADIOBUTTON | + WS_TABSTOP,21,27,59,10 + CONTROL "Start of string",IDC_MATCH2,"Button",BS_AUTORADIOBUTTON, + 21,38,59,10 + GROUPBOX "&Orientation",IDC_STATIC,92,16,61,36,WS_GROUP + CONTROL "Horizontal",IDC_HORIZONTAL,"Button",BS_AUTORADIOBUTTON | + WS_TABSTOP,100,27,47,10 + CONTROL "Vertical",IDC_VERTICAL,"Button",BS_AUTORADIOBUTTON,100, + 38,47,10 + GROUPBOX "&Cursor tracking",IDC_STATIC,156,16,61,36,WS_GROUP + CONTROL "&Enabled",IDC_TRACK,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,164,28,49,10 + GROUPBOX "Active keyboard options",IDC_ACTIVE1,7,58,216,92 + CTEXT "(Keyboard name)",IDC_KBDNAME,13,67,204,8,NOT WS_GROUP + GROUPBOX "&Selection",IDC_SELECTION,13,77,99,59,WS_GROUP + CONTROL "Keyboard (1-9)",IDC_SELECT1,"Button",BS_AUTORADIOBUTTON | + WS_TABSTOP,21,88,74,10 + CONTROL "Keypad (1-9)",IDC_SELECT2,"Button",BS_AUTORADIOBUTTON, + 21,99,75,10 + CONTROL "Either (1-9)",IDC_SELECT3,"Button",BS_AUTORADIOBUTTON, + 21,110,82,10 + CONTROL "Function keys (F1-F12)",IDC_SELECT4,"Button", + BS_AUTORADIOBUTTON,21,121,87,10 + GROUPBOX "&Tone keys",IDC_TONES,115,77,102,59,WS_GROUP + CONTROL "Never typed",IDC_TONE1,"Button",BS_AUTORADIOBUTTON | + WS_TABSTOP,124,88,64,10 + CONTROL "Must be typed",IDC_TONE2,"Button",BS_AUTORADIOBUTTON, + 124,99,64,10 + CONTROL "Optional",IDC_TONE3,"Button",BS_AUTORADIOBUTTON,124,110, + 64,10 + CONTROL "Auto-select if &unique",IDC_SELECTUNIQUE,"Button", + BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,21,137,80,10 + CONTROL "Show &duplicates",IDC_SHOWDUPLICATES,"Button", + BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_GROUP | WS_TABSTOP, + 124,137,68,10 + DEFPUSHBUTTON "OK",IDOK,230,14,50,14 + PUSHBUTTON "Cancel",IDCANCEL,230,35,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + "CONFIGURE", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 280 + TOPMARGIN, 7 + BOTTOMMARGIN, 152 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +LOGO ICON DISCARDABLE "icon1.ico" + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 6,0,161,0 + PRODUCTVERSION 6,0,161,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "0c0904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Tavultesoft\0" + VALUE "FileDescription", "KeymanIMX Configuration\0" + VALUE "FileVersion", "6.0.161.0\0" + VALUE "InternalName", "KeymanIMX Configuration\0" + VALUE "LegalCopyright", "Copyright © 2003 Tavultesoft\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "imxconfig\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "Tavultesoft KeymanIMX Configuration\0" + VALUE "ProductVersion", "6.0.161.0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0xc09, 1200 + END +END + +#endif // !_MAC + +#endif // English (Australia) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/release/c/cs_pinyin/source/imxconfig/imxconfig.sln b/release/c/cs_pinyin/source/imxconfig/imxconfig.sln new file mode 100644 index 0000000000..f6d2a9c5ef --- /dev/null +++ b/release/c/cs_pinyin/source/imxconfig/imxconfig.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imxconfig", "imxconfig.vcxproj", "{4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}.Debug|x86.ActiveCfg = Debug|Win32 + {4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}.Debug|x86.Build.0 = Debug|Win32 + {4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}.Release|x86.ActiveCfg = Release|Win32 + {4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/release/c/cs_pinyin/source/imxconfig/imxconfig.vcxproj b/release/c/cs_pinyin/source/imxconfig/imxconfig.vcxproj new file mode 100644 index 0000000000..1a1f593547 --- /dev/null +++ b/release/c/cs_pinyin/source/imxconfig/imxconfig.vcxproj @@ -0,0 +1,295 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {4F2ED8DE-8B20-46E4-96F5-F8DD0BF26504} + 10.0 + + + + Application + false + MultiByte + v142 + + + Application + false + MultiByte + v142 + + + Application + false + MultiByte + v142 + + + Application + false + MultiByte + v142 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + true + true + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + false + false + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/imxconfig.tlb + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + .\Debug/imxconfig.pch + $(outdir)\ + $(outdir)\ + $(outdir)\ + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + odbc32.lib;odbccp32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;%(AdditionalDependencies) + true + true + $(OutDir)$(TargetName).pdb + Windows + MachineX86 + false + + + true + .\Debug/imxconfig.bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/imxconfig.tlb + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + .\Debug/imxconfig.pch + $(outdir)\ + $(outdir)\ + $(outdir)\ + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + odbc32.lib;odbccp32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + true + $(OutDir)$(TargetName).pdb + Windows + + + true + .\Debug/imxconfig.bsc + + + + + + + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/imxconfig.tlb + + + + + MaxSpeed + OnlyExplicitInline + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Release/imxconfig.pch + $(outdir)\ + $(outdir)\ + $(outdir)\ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + odbc32.lib;odbccp32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;%(AdditionalDependencies) + true + $(OutDir)$(TargetName).pdb + Windows + MachineX86 + + + true + .\Release/imxconfig.bsc + + + + + Signing $(ProjectPath) + signtool sign /f "s:\tavultesoft\certificates\tavultesoft.pfx" /t "http://timestamp.verisign.com/scripts/timstamp.dll" /du "http://www.tavultesoft.com/" /v $(TargetPath) + $(TargetName);%(Outputs) + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/imxconfig.tlb + + + + + MaxSpeed + OnlyExplicitInline + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Release/imxconfig.pch + $(outdir)\ + $(outdir)\ + $(outdir)\ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + odbc32.lib;odbccp32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;%(AdditionalDependencies) + true + $(OutDir)$(TargetName).pdb + Windows + + + true + .\Release/imxconfig.bsc + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + + + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/release/c/cs_pinyin/source/imxconfig/imxconfig.vcxproj.filters b/release/c/cs_pinyin/source/imxconfig/imxconfig.vcxproj.filters new file mode 100644 index 0000000000..c0b832379d --- /dev/null +++ b/release/c/cs_pinyin/source/imxconfig/imxconfig.vcxproj.filters @@ -0,0 +1,40 @@ + + + + + {6da7e89f-d321-46c1-b511-283f60162c90} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {cc000632-2215-4a12-9526-300de206ce1a} + h;hpp;hxx;hm;inl + + + {a0eb051e-7826-4b33-b3f3-535092cc71d6} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + + + Header Files + + + + + Resource Files + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/release/c/cs_pinyin/source/imxconfig/resource.h b/release/c/cs_pinyin/source/imxconfig/resource.h new file mode 100644 index 0000000000..5f2f6aaeff --- /dev/null +++ b/release/c/cs_pinyin/source/imxconfig/resource.h @@ -0,0 +1,34 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by imxconfig.rc +// +#define IDD_DIALOG1 101 +#define IDC_HORIZONTAL 1000 +#define IDC_VERTICAL 1001 +#define IDC_TRACK 1002 +#define IDC_KBDNAME 1006 +#define IDC_SELECT1 1012 +#define IDC_SELECT2 1013 +#define IDC_SELECT3 1014 +#define IDC_SELECT4 1015 +#define IDC_TONE1 1017 +#define IDC_TONE2 1018 +#define IDC_TONE3 1019 +#define IDC_TONES 1020 +#define IDC_SELECTUNIQUE 1021 +#define IDC_SELECTION 1022 +#define IDC_ACTIVE1 1023 +#define IDC_SHOWDUPLICATES 1024 +#define IDC_MATCH1 1025 +#define IDC_MATCH2 1026 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 104 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1026 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/release/c/cs_pinyin/source/imxreload/Key.bmp b/release/c/cs_pinyin/source/imxreload/Key.bmp new file mode 100644 index 0000000000..a0bc2999b9 Binary files /dev/null and b/release/c/cs_pinyin/source/imxreload/Key.bmp differ diff --git a/release/c/cs_pinyin/source/imxreload/icon1.ico b/release/c/cs_pinyin/source/imxreload/icon1.ico new file mode 100644 index 0000000000..55b46264be Binary files /dev/null and b/release/c/cs_pinyin/source/imxreload/icon1.ico differ diff --git a/release/c/cs_pinyin/source/imxreload/imxreload.cpp b/release/c/cs_pinyin/source/imxreload/imxreload.cpp new file mode 100644 index 0000000000..d82d86b5af --- /dev/null +++ b/release/c/cs_pinyin/source/imxreload/imxreload.cpp @@ -0,0 +1,588 @@ +#include +#include +#include +#include + +#include "resource.h" +#include "../keymanimx/keymanimx.h" + +#define MAXWAIT 60 + +DWORD GetCRC32(LPVOID pv,UINT cb); + +PSTR CAPTION="Keyman IMX Configuration Compiler"; + +KBHEADER Keyboard={0}; +HWND hDlg; + +DWORD Index[MAXINDEX]; +PSTR IndexString=INDEXSTRING; +char CFGPath[MAX_PATH]={0}, CFXPath[MAX_PATH]={0}; + +int GetLogPixelsY() +{ + HDC hDC = GetDC(GetDesktopWindow()); + SetMapMode(hDC, MM_TEXT); + int lfpixelsy = GetDeviceCaps(hDC, LOGPIXELSY); + ReleaseDC(GetDesktopWindow(), hDC); + return lfpixelsy; +} + +void SetFont(LPLOGFONT plf, LPSTR name, int size, int style) +{ + plf->lfHeight = -MulDiv(size, GetLogPixelsY(), 72); + plf->lfWidth = 0; + plf->lfEscapement = 0; + plf->lfOrientation = 0; + plf->lfWeight = (style & FS_BOLD) ? FW_BOLD : FW_NORMAL; + plf->lfItalic = (style & FS_ITALIC) ? TRUE: FALSE; + plf->lfUnderline = FALSE; + plf->lfStrikeOut = FALSE; +// plf->lfCharSet = DEFAULT_CHARSET; //SHIFTJIS_CHARSET; + plf->lfCharSet = (style & FC_SYMBOL) ? SYMBOL_CHARSET : 0; + plf->lfOutPrecision = OUT_DEFAULT_PRECIS; + plf->lfClipPrecision = CLIP_DEFAULT_PRECIS; + plf->lfQuality = DEFAULT_QUALITY; + plf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; + strcpy_s(plf->lfFaceName, sizeof plf->lfFaceName, name); +} + +void AdjustFont(LPLOGFONT plf, PSTR q, PSTR sz, PSTR st) +{ + int n; + + if(!q) return; + + strncpy_s(plf->lfFaceName, sizeof plf->lfFaceName, q, LF_FACESIZE-1); + plf->lfFaceName[LF_FACESIZE-1] = 0; + if(sz) + { + if((n=atoi(sz)) <= 0) n = 10; + plf->lfHeight = -MulDiv(n, GetLogPixelsY(), 72); + } + if(st) + { + if((n=atoi(st)) < 0) n = 0; + plf->lfWeight = (n & FS_BOLD ? FW_BOLD : FW_NORMAL); + plf->lfItalic = (n & FS_ITALIC ? TRUE : FALSE); + plf->lfCharSet = (n & FC_SYMBOL ? SYMBOL_CHARSET : 0); + } +} + +BOOL unpackstr(PWCHAR p,PWCHAR pw,int pwlen) +{ + WCHAR qt=0, *pq; + int tlen=0; + + while(*p) + { + switch(*p) + { + case ' ': + p++; + break; + case 34: + case 39: + qt = *p++; + pq = wcschr(p,qt); + if((!pq) || (tlen+pq-p >= pwlen)) return FALSE; + wcsncpy_s(pw+tlen,pwlen-tlen,p,pq-p); + tlen += (int)(pq-p); + p = pq+1; + break; + case 'U': + case 'u': + p++; + if(*p != '+') return FALSE; + case 'X': + case 'x': + p++; + *(pw+tlen) = (WORD)wcstoul(p, &p, 16); + tlen++; + break; + case 'd': + case 'D': + p++; + *(pw+tlen) = (WORD)wcstoul(p, &p, 10); + tlen++; + break; + default: + return FALSE; + } + if(tlen >= pwlen-1) break; + } + *(pw+tlen) = 0; + return TRUE; +} + +void UpdateMeter(int x) +{ + SendDlgItemMessage(hDlg,IDC_RELOADPROGRESS,PBM_SETPOS,x,0); +} + +void SetMeterRange(int xmin,int xmax) +{ + SendDlgItemMessage(hDlg,IDC_RELOADPROGRESS,PBM_SETRANGE32,xmin,xmax); +} + +void SetMeterCaption(PSTR pLabel, PSTR pText) +{ + char buf[256]; + wsprintf(buf,"%s %s",pLabel,pText); + SetDlgItemText(hDlg,IDC_KBDNAME,buf); +} + +int ParseCFG(KBHEADER *kbi, char *cfgfile, int *psize, FILE *ftemp) +{ + FILE *fp, *ft0; + BOOL FGroups=FALSE, FRules=FALSE, FConfig=FALSE; + WCHAR wc1, wstr[512]; + PWSTR pinput, poutput, ptag; + int k, k1, n, nread=0, nrules=0, Config=CFG_NONE; + char q0, *p, *q, *sz, *st, str[512]; + PBYTE pBOM=(PBYTE)&str[0]; + TEMPRULE tmprule; + + // TODO: Consider doing all this in memory and avoiding temp files + tmpfile_s(&ft0); + + // Set defaults + strncpy_s(kbi->Flag, 5, "KCFX", 4); + kbi->dwCfxVersion = CFXVERSION; + kbi->nrules = 0; + kbi->gridx = CELL_X; + kbi->gridy = CELL_Y; + kbi->dwFKeys = 1; // allow use of function keys + kbi->dwOptions = SM_FKEYS | (TM_OPTIONAL<<2); // use function keys by default, optional tones + *kbi->ToneChar = 0; + kbi->cfgKey = MAKELONG(0xC0,0x11); //default configuration hotkey is LCtrl Shift Backquote + + // Set default font properties + SetFont(&kbi->lfMain, "Arial Unicode MS", 10, FS_NONE); + SetFont(&kbi->lfInput, "MS Sans Serif", 8, FS_BOLD); + SetFont(&kbi->lfTag, "MS Sans Serif", 8, FS_NONE); + + *psize = nrules = 0; + + // Open the CFG file, abort on error + if(fopen_s(&fp, cfgfile, "rb") != 0) return FALSE; + + // must determine whether or not the config file is Unicode + fread(pBOM,4,1,fp); + + if(*pBOM == '[') + { + Config = CFG_ANSI; fseek(fp,0,SEEK_SET); + } + else if((*pBOM == 0xEF) && (*(pBOM+1) == 0xBB) && (*(pBOM+2) == 0xBF)) + { + Config = CFG_UTF8; fseek(fp,3,SEEK_SET); + } + else if((*pBOM == 0xFF) && (*(pBOM+1) == 0xFE)) + { + Config = CFG_UNICODE; fseek(fp,2,SEEK_SET); + } + + else return FALSE; + + if(ftemp) + { + SetMeterRange(0,3*_filelength(_fileno(fp))); + SetMeterCaption("Parsing rules for ",kbi->name); + } + + do + { + if(Config == CFG_ANSI) + { + if(!fgets(str, 512, fp)) break; + MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, 512); + } + else if(Config == CFG_UTF8) + { + if(!fgets(str, 512, fp)) break; + MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, 512); + } + else + { + if(!fgetws(wstr, 512, fp)) break; + } + + if(wcschr(wstr, L'\r')) *wcschr(wstr, L'\r') = 0; + if(wcschr(wstr, L'\n')) *wcschr(wstr, L'\n') = 0; + + if(wstr[0] == L'#' || wstr[0] == 0) continue; + + if(wstr[0] == L'[') + { + FConfig = FALSE; FRules = FALSE; + if(!_wcsicmp(wstr, L"[config]")) FConfig = TRUE; + else if(!_wcsicmp(wstr, L"[rules]")) FRules = TRUE; + } + else if(FConfig) + { + WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, 512, NULL, NULL ); + + char *sp; + p = strtok_s(str, "= ", &sp); if(!p) continue; + q = strtok_s(NULL, ",\r\n", &sp); if(!q) continue; + sz = strtok_s(NULL, ",\r\n", &sp); + st = strtok_s(NULL, ",\r\n", &sp); + + if(!_stricmp(p, "Name")) // this must match, if a keyboard is selected. + strcpy_s(kbi->name, sizeof kbi->name, q); + else if(!_stricmp(p, "MainFont")) + AdjustFont( &kbi->lfMain, q, sz, st); + else if(!_stricmp(p, "InputFont")) + AdjustFont( &kbi->lfInput, q, sz, st); + else if(!_stricmp(p, "TagFont")) + AdjustFont( &kbi->lfTag, q, sz, st); + else if(!_stricmp(p, "Options")) + kbi->dwOptions = atoi(q); + else if(!_stricmp(p, "FKeys")) + kbi->dwFKeys = atoi(q); + else if(!_stricmp(p, "Wild") || !_stricmp(p,"WildCard")) + { + if(strchr(q,'?')) kbi->dwWild |= WC_QUERY; + if(strchr(q,'*')) kbi->dwWild |= WC_STAR; + if(strchr(q,'\'')) kbi->dwWild |= WC_QUOTE; + if(strchr(q,'-')) kbi->dwWild |= WC_DASH; + } + else if(!_stricmp(p, "Input")) + { + k = atoi(q); kbi->InputSize = min(max(k,16),100); + } + else if(!_stricmp(p, "Grid") || !_stricmp(p,"Cell")) + { + kbi->gridx = atoi(q); + if(sz) kbi->gridy = atoi(sz); + else kbi->gridy = kbi->gridx; + } + else if(!_stricmp(p, "ToneChar") || !_stricmp(p, "ToneChars")) + strcpy_s(kbi->ToneChar,sizeof kbi->ToneChar, q); + else if(!_stricmp(p,"CfgHotKey")) + kbi->cfgKey = MAKELONG(atoi(q),atoi(sz)); + } + else if(FRules) + { + // exit if just reading configuration parameters + if(ftemp == NULL) break; + + // parsing will not allow commas in strings at present + wchar_t *wp; + pinput = wcstok_s(wstr, L",\t", &wp); if(!pinput) continue; + poutput = wcstok_s(NULL, L",\t\n", &wp); if(!poutput) continue; + ptag = wcstok_s(NULL, L",\t\n", &wp); + + // copy the rules to a temporary file and determine the memory needed + ZeroMemory(&tmprule,sizeof tmprule); + if(!unpackstr(pinput,tmprule.input,sizeof(tmprule.input)/sizeof(WCHAR))) continue; + if(!unpackstr(poutput,tmprule.output,sizeof(tmprule.output)/sizeof(WCHAR))) continue; + *psize += (int)(2*(wcslen(tmprule.input) + wcslen(tmprule.output))); + if(ptag) + { + unpackstr(ptag,tmprule.tag,sizeof(tmprule.tag)/sizeof(WCHAR)); + *psize += 2*(int)wcslen(tmprule.tag); + } + fwrite(&tmprule,sizeof tmprule,1,ft0); + + nrules++; + + } + if(nrules % 10 == 0) UpdateMeter(ftell(fp)); + } while(TRUE); + + fclose(fp); + + kbi->nrules = nrules; + + // Now merge the rules and index them + if(ftemp) + { + k1=(int)strlen(IndexString); + SetMeterRange(-k1,2*k1); UpdateMeter(0); + SetMeterCaption("Sorting rules for ",kbi->name); + + // add all indexed rules + for(k=n=0; kdwStrings; + p1 = p0 + pk->cbStrings; + + + for(p=p0,n=0; pname, sizeof kbi->name, NULL, 0); + + // Read the Name configuration field, if any + if(!ParseCFG(kbi,CFGPath,&stsize,NULL)) + { + MessageBox(hwnd,"Invalid configuration file!",CAPTION,MB_ICONSTOP); + return FALSE; + } + + wsprintf(buf,"Reloading %s",kbi->name); + SetDlgItemText(hwnd,IDC_KBDNAME,buf); + EnableDlgItem(hwnd,IDC_KBDNAME); + EnableDlgItem(hwnd,IDC_RELOADPROGRESS); + DisableDlgItem(hwnd,IDOK); + DisableDlgItem(hwnd,IDCANCEL); + + wsprintf(buf,"Reloading %s failed!",kbi->name); + + _makepath_s(CFXPath, sizeof CFXPath, drive, dir, kbi->name, ".cfx"); + + // Build the temporary file + if(ParseCFG(kbi,CFGPath,&stsize,ftemp) && (kbi->nrules > 0)) + { + nrules = kbi->nrules; + + fseek(ftemp,0,SEEK_SET); + + kbi->dwIndex = sizeof(KBHEADER); + kbi->dwRules = kbi->dwIndex + (sizeof Index); + kbi->dwStrings = kbi->dwRules + (nrules+1)*sizeof(RULE); + kbi->cbStrings = stsize; + + totalsize = kbi->dwStrings + kbi->cbStrings; + + hFile = CreateFile(CFXPath,GENERIC_READ+GENERIC_WRITE,FILE_SHARE_READ+FILE_SHARE_WRITE,NULL, + OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); + + if(hFile != INVALID_HANDLE_VALUE) + { + // Create an un-named temporary file-mapping object (allow for checksum) + hMapObject = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,totalsize+4,NULL); + if(hMapObject != NULL) + { + SetMeterRange(-2*nrules,nrules); UpdateMeter(0); + SetMeterCaption("Compiling",kbi->name); + + + // Get a pointer to file-mapped shared memory + pbmm = (PBYTE)MapViewOfFile(hMapObject,FILE_MAP_WRITE,0,0,0); + if( pbmm != NULL ) + { + // Copy the loaded keyboard parameters to the memory mapped file + *(KBHEADER *)pbmm = *kbi; + + ip0 = (DWORD *)(pbmm + sizeof(KBHEADER)); + + // Copy the index + memcpy(ip0,&Index[0],sizeof Index); + + // Copy the rules + rp = rp0 = (RULE *)(pbmm + sizeof(KBHEADER) + (sizeof Index)); + pw = pw0 = (PWCHAR)(rp + nrules + 1); + + for(i=0; iilen = (BYTE)wcslen(tmprule.input); + rp->olen = (BYTE)wcslen(tmprule.output); + rp->tlen = (BYTE)wcslen(tmprule.tag); + rp->input = (DWORD)(pw-pw0); + wcscpy_s(pw0+rp->input, rp->ilen + 1, tmprule.input); pw += rp->ilen; + rp->output = (DWORD)(pw-pw0); + wcscpy_s(pw0+rp->output, rp->olen + 1, tmprule.output); pw += rp->olen; + rp->tag = (DWORD)(pw-pw0); + wcscpy_s(pw0+rp->tag, rp->tlen + 1, tmprule.tag); pw += rp->tlen; + if(!*tmprule.tag) rp->tag = rp->input; + } + + // And encrypt the string table + EncryptStrings((KBHEADER *)pbmm); + + // Calculate the checksum + dwChecksum = GetCRC32(pbmm,totalsize); + memcpy(pbmm+totalsize,&dwChecksum,4); + + // Unmap the memory object + UnmapViewOfFile(pbmm); + + wsprintf(buf,"%s recompiled, %d rules processed",kbi->name,kbi->nrules); + } + CloseHandle(hMapObject); + } + SetFileToCurrentTime(hFile); + CloseHandle(hFile); + } + } + + _rmtmp(); + + SetDlgItemText(hwnd,IDC_KBDNAME,buf); + + DisableDlgItem(hwnd,IDC_RELOADPROGRESS); + EnableDlgItem(hwnd,IDOK); + EnableDlgItem(hwnd,IDCANCEL); + + return (nrules > 0); +} + +INT_PTR CALLBACK IMXRebuildProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + hDlg = hwnd; + DisableDlgItem(hwnd,IDC_RELOADPROGRESS); + DisableDlgItem(hwnd,IDC_KBDNAME); + + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDOK: + RebuildAll(hwnd,&Keyboard); + break; + case IDCANCEL: + EndDialog(hwnd,0); + break; + } + break; + } + return FALSE; +} + +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int cmdShow) +{ + INITCOMMONCONTROLSEX Controls; + HANDLE hMutex=0; + + char buf[MAX_PATH]={0}; + + hMutex = CreateMutex(NULL,FALSE,"KeymanIMXRebuildMutex"); + if(hMutex == NULL || GetLastError() == ERROR_ALREADY_EXISTS) return 0; + + Controls.dwSize = sizeof(INITCOMMONCONTROLSEX); + Controls.dwICC = ICC_PROGRESS_CLASS; + InitCommonControlsEx(&Controls); + + DialogBox(hInst,"CONFIGURE",NULL,IMXRebuildProc); + + return 0; +} + + diff --git a/release/c/cs_pinyin/source/imxreload/imxreload.rc b/release/c/cs_pinyin/source/imxreload/imxreload.rc new file mode 100644 index 0000000000..04be835a29 --- /dev/null +++ b/release/c/cs_pinyin/source/imxreload/imxreload.rc @@ -0,0 +1,157 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (Australia) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +CONFIGURE DIALOG DISCARDABLE 0, 0, 205, 62 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Keyman IMX Configuration Compiler" +FONT 8, "MS Sans Serif" +BEGIN + CTEXT "Rebuilding ",IDC_KBDNAME,7,7,191,8, + WS_DISABLED | NOT WS_GROUP + CONTROL "Progress1",IDC_RELOADPROGRESS,"msctls_progress32", + PBS_SMOOTH | WS_DISABLED | WS_BORDER,14,20,177,11 + DEFPUSHBUTTON "Rebuild",IDOK,41,40,50,14 + PUSHBUTTON "Close",IDCANCEL,114,40,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + "CONFIGURE", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 198 + TOPMARGIN, 7 + BOTTOMMARGIN, 55 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +LOGO ICON DISCARDABLE "icon1.ico" + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 6,0,161,1 + PRODUCTVERSION 6,0,161,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "0c0904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Tavultesoft\0" + VALUE "FileDescription", "KeymanIMX Compiler\0" + VALUE "FileVersion", "6.0.161.1\0" + VALUE "InternalName", "KeymanIMX Compiler\0" + VALUE "LegalCopyright", "Copyright © 2003 Tavultesoft\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "imxreload\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "Tavultesoft KeymanIMX Compiler\0" + VALUE "ProductVersion", "6.0.161.1\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0xc09, 1200 + END +END + +#endif // !_MAC + +#endif // English (Australia) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/release/c/cs_pinyin/source/imxreload/imxreload.sln b/release/c/cs_pinyin/source/imxreload/imxreload.sln new file mode 100644 index 0000000000..c4a1f0f750 --- /dev/null +++ b/release/c/cs_pinyin/source/imxreload/imxreload.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imxreload", "imxreload.vcxproj", "{838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Debug|x64.ActiveCfg = Debug|x64 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Debug|x64.Build.0 = Debug|x64 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Debug|x86.ActiveCfg = Debug|Win32 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Debug|x86.Build.0 = Debug|Win32 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Release|x64.ActiveCfg = Release|x64 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Release|x64.Build.0 = Release|x64 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Release|x86.ActiveCfg = Release|Win32 + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/release/c/cs_pinyin/source/imxreload/imxreload.vcxproj b/release/c/cs_pinyin/source/imxreload/imxreload.vcxproj new file mode 100644 index 0000000000..6296bd19ad --- /dev/null +++ b/release/c/cs_pinyin/source/imxreload/imxreload.vcxproj @@ -0,0 +1,300 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {838D3D6C-F6E5-461E-ABF1-DC7053AC77D2} + 10.0 + + + + Application + false + MultiByte + v142 + + + Application + false + MultiByte + v142 + + + Application + false + MultiByte + v142 + + + Application + false + MultiByte + v142 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + true + true + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + false + false + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/imxreload.tlb + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + $(outdir)\imxreload.pch + $(outdir)\ + $(outdir)\ + $(outdir)\ + Level3 + true + EditAndContinue + StdCall + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + odbc32.lib;odbccp32.lib;comctl32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;%(AdditionalDependencies) + true + true + $(outdir)\$(MSBuildProjectName).pdb + Windows + MachineX86 + false + + + true + .\Debug/imxreload.bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/imxreload.tlb + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + $(outdir)\imxreload.pch + $(outdir)\ + $(outdir)\ + $(outdir)\ + Level3 + true + ProgramDatabase + StdCall + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + odbc32.lib;odbccp32.lib;comctl32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + true + $(outdir)\$(MSBuildProjectName).pdb + Windows + + + true + .\Debug/imxreload.bsc + + + + + + + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/imxreload.tlb + + + + + MaxSpeed + OnlyExplicitInline + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(outdir)\imxreload.pch + $(outdir)\ + $(outdir)\ + $(outdir)\ + Level3 + true + StdCall + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + odbc32.lib;odbccp32.lib;comctl32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;%(AdditionalDependencies) + true + $(outdir)\$(MSBuildProjectName).pdb + Windows + MachineX86 + + + true + .\Release/imxreload.bsc + + + + + Signing $(ProjectPath) + signtool sign /f "s:\tavultesoft\certificates\tavultesoft.pfx" /t "http://timestamp.verisign.com/scripts/timstamp.dll" /du "http://www.tavultesoft.com/" /v $(TargetPath) + $(TargetName);%(Outputs) + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/imxreload.tlb + + + + + MaxSpeed + OnlyExplicitInline + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(outdir)\imxreload.pch + $(outdir)\ + $(outdir)\ + $(outdir)\ + Level3 + true + StdCall + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + odbc32.lib;odbccp32.lib;comctl32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;%(AdditionalDependencies) + true + $(outdir)\$(MSBuildProjectName).pdb + Windows + + + true + .\Release/imxreload.bsc + + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + + + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/release/c/cs_pinyin/source/imxreload/imxreload.vcxproj.filters b/release/c/cs_pinyin/source/imxreload/imxreload.vcxproj.filters new file mode 100644 index 0000000000..aa644fc57c --- /dev/null +++ b/release/c/cs_pinyin/source/imxreload/imxreload.vcxproj.filters @@ -0,0 +1,43 @@ + + + + + {577d83e9-7cf8-4ab8-86a1-1138a859b171} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {a4e96bdb-b00a-4e7e-b775-98fb4291d586} + h;hpp;hxx;hm;inl + + + {f7385744-043f-4d65-a11f-54612ca8d94e} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + + + Header Files + + + + + Resource Files + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/release/c/cs_pinyin/source/imxreload/resource.h b/release/c/cs_pinyin/source/imxreload/resource.h new file mode 100644 index 0000000000..5a2649c5b2 --- /dev/null +++ b/release/c/cs_pinyin/source/imxreload/resource.h @@ -0,0 +1,36 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by imxreload.rc +// +#define IDD_DIALOG1 101 +#define IDC_HORIZONTAL 1000 +#define IDC_VERTICAL 1001 +#define IDC_TRACK 1002 +#define IDC_KBDNAME 1006 +#define IDC_RELOAD 1008 +#define IDC_RELOADPROGRESS 1010 +#define IDC_SELECT1 1012 +#define IDC_SELECT2 1013 +#define IDC_SELECT3 1014 +#define IDC_SELECT4 1015 +#define IDC_TONE1 1017 +#define IDC_TONE2 1018 +#define IDC_TONE3 1019 +#define IDC_TONES 1020 +#define IDC_SELECTUNIQUE 1021 +#define IDC_SELECTION 1022 +#define IDC_ACTIVE2 1023 +#define IDC_ACTIVE1 1024 +#define IDC_MATCH1 1025 +#define IDC_MATCH2 1026 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1026 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/release/c/cs_pinyin/source/keymanimx/KeymanIMX.cpp b/release/c/cs_pinyin/source/keymanimx/KeymanIMX.cpp new file mode 100644 index 0000000000..4e296229f6 --- /dev/null +++ b/release/c/cs_pinyin/source/keymanimx/KeymanIMX.cpp @@ -0,0 +1,2061 @@ +#define STRICT + +#include +#include +#include +#include "imxlib.h" +#include "keymanimx.h" + +#define WS_EX_NOACTIVATE 0x08000000L +#define WM_REDRAW (WM_USER+200) + +#define ELLIPSIS 0x2026 // ellipsis (Unicode) character + +//#define TESTING + +#ifdef TESTING +#define returnErr(value) {Log("Error at line ",__LINE__,GetLastError());return(value);} +char tdbg[256]; +void dbgLog(void) +{ + FILE *fp; + + if((fp=fopen("c:\\Windows\\Temp\\KeymanIMX.log", "at"))) + { + fprintf(fp, "%s\n",tdbg); + fclose(fp); + } +} + +// Overload the debug reporter to simplify use +void Log(char *s) +{ + wsprintf(tdbg, "%s\n",s); + dbgLog(); +} +void Log(char *s, char *t) +{ + wsprintf(tdbg, "%s %s\n",s,t); + dbgLog(); +} +void Log(char *s, char *t, int n) +{ + wsprintf(tdbg, "%s %s (%x)\n",s,t,n); + dbgLog(); +} +void Log(char *s, int n) +{ + wsprintf(tdbg, "%s %d (%x)\n",s,n,n); + dbgLog(); +} +void Log(char *s, int m, int n) +{ + wsprintf(tdbg, "%s %d (%x)\n",s,m,n); + dbgLog(); +} +void Log(PWCHAR s, PWCHAR t) +{ + char s1[48], t1[48]; + WideCharToMultiByte(CP_ACP,0,s,-1,s1,48,NULL,NULL); + WideCharToMultiByte(CP_ACP,0,t,-1,t1,48,NULL,NULL); + wsprintf(tdbg, "%s %s\n",s1,t1); + dbgLog(); +} +void Log(char *p, PWCHAR s, int n) +{ + char s1[48]; + WideCharToMultiByte(CP_ACP,0,s,n,s1,48,NULL,NULL); + wsprintf(tdbg, "%s %s\n",p,s1); + dbgLog(); +} + +#else +#define returnErr(value) {return (value);} +void Log(char *s){} +void Log(char *s, char *t){} +void Log(char *s, int n){} +void Log(char *s, int m, int n){} +void Log(PWCHAR s, PWCHAR t){} +void Log(char *p, PWCHAR s, int n){} +#endif + +thread_local UINT Error=ERR_UNKNOWN; +thread_local HWND hwnd=0, hwndChild=0; +HINSTANCE hDllInst=0; +thread_local UINT wm_keymanim_close = 0, wm_keymanim_contextchanged; +thread_local HBITMAP hbmp[MAXBMP]={0}; +thread_local BOOL EnableTracking=TRUE, Tracking=TRUE; +thread_local UINT DisplayMode=DM_LIMITED; +thread_local int CellStart[MAXACTIVERULES+1]={0}; +thread_local BOOL UserResize=TRUE, Vertical=FALSE, NumericMode=FALSE; + +thread_local POINTS IMPos={0,0}, IMSize={IM_WIDTH,IM_HEIGHT}, CellSize={CELL_X,CELL_Y}; +thread_local int IMBorders=IMBORDERS, CWBorders=CWBORDERS, InputSize=INPUTWIDTH, IMWidth=0; + +enum tagRect {RECT_UP=0,RECT_DOWN,RECT_TRACK,RECT_ORIENT,RECT_CONFIG,RECT_LOGO}; + +enum tagBmp {BMP_LOGO=0,BMP_VERT,BMP_HORIZ,BMP_CANT_TRACK,BMP_DONT_TRACK,BMP_TRACK, + BMP_LEFT0,BMP_LEFT1,BMP_RIGHT0,BMP_RIGHT1,BMP_UP0,BMP_UP1,BMP_DOWN0,BMP_DOWN1,BMP_CONFIG}; + +const PSTR rnBmp[MAXBMP] = {"LOGO","VERTICAL","HORIZONTAL","T_GRAY","T_RED","T_GREEN", + "LEFT0","LEFT1","RIGHT0","RIGHT1","UP0","UP1","DOWN0","DOWN1","CONFIG"}; + +thread_local int ScrollPos=0, MaxScrollBoxes=0, nCells, MaxCells=9; +thread_local RULE *ActiveRule[MAXACTIVERULES] = {NULL}; +thread_local KEYBOARD *Keyboards = NULL, *CurKbd = NULL; +thread_local WCHAR ContextBuf[16]={0}; +thread_local PSTR IndexString = INDEXSTRING; +thread_local BOOL MouseSelection=TRUE,CountAll=FALSE,ExtendMatch=FALSE; +thread_local int nKeyboards; + +LRESULT CALLBACK IMXWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK IMXChildWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +extern "C" BOOL __declspec(dllexport) WINAPI KeymanIMReloadConfig(PSTR KeyboardName); +void WriteRegSetting(PSTR text, int value); +int ReadRegSetting(PSTR text, int dflt); +void UnloadRules(PSTR KeyboardName); +BOOL LoadRules(PSTR KeyboardName); +void DeleteKeyboard(PSTR KeyboardName); +void CreateKeyboard(PSTR KeyboardName); +int FillActiveRules(WCHAR KeyChar); +BOOL IsHexString(PWSTR pContext, UINT lBuf, WCHAR wChar); +BOOL OutputUnicode(PWSTR pContext, UINT lBuf); +BOOL CompleteRule(RULE *r,int Mode); +BOOL GetIMDimensions(int nCells,PWCHAR pin); +BOOL ReadConfiguration(BOOL All); +BOOL SaveIMXPosition(void); +void SendKey(int vk); +BOOL IsRegistered(UINT keyID); +DWORD GetCRC32(LPVOID pv,UINT cb); + +/************************************************************************************************************ + * DLL entry functions + ************************************************************************************************************/ + +BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID lpvReserved) +{ + switch(fdwReason) + { + case DLL_PROCESS_ATTACH: + hDllInst = hInst; + break; + + case DLL_PROCESS_DETACH: + hDllInst = NULL; + break; + } + return TRUE; +} + +extern "C" BOOL __declspec(dllexport) WINAPI KeymanIMDestroy(PSTR KeyboardName) +{ + int n; + + for(n=0; nh.nrules == 0 && hwnd) (*KMDisplayIM)(hwnd,TRUE); + + return(TRUE); +} + +extern "C" BOOL __declspec(dllexport) WINAPI KeymanIMDeactivate(PSTR KeyboardName) +{ + + CurKbd = NULL; + + if(!PrepIM(TRUE)) return FALSE; + + SaveIMXPosition(); + (*KMHideIM)(); + + return TRUE; +} + +/************************************************************************************************************ + * Window management functions + ************************************************************************************************************/ + +// Calculate the cell and window dimensions for the IM window +// For the horizontal window, each cell wifth can change, +// but for the vertical window, only the window width varies +BOOL GetIMDimensions(int nCells,PWCHAR pin) +{ + HDC hDC; + int i, pwlen, CellWidth[MAXACTIVERULES]; + PWCHAR pw; + SIZE Size={0}; + char Index[4]; + + HFONT hfMain, hfInput, hfTag; + + // Create logical fonts + hfMain = CreateFontIndirect(&CurKbd->h.lfMain); + hfInput = CreateFontIndirect(&CurKbd->h.lfInput); + hfTag = CreateFontIndirect(&CurKbd->h.lfTag); + + // Set default cell widths + for(i=0; ipst+ActiveRule[i]->output; pwlen = ActiveRule[i]->olen; + GetTextExtentPoint32W(hDC, pw, pwlen, &Size); + CellWidth[i] = Size.cx + 2; // add whitespace of 2 px + } + + SelectObject(hDC, hfTag); + for(i=0; ipst+ActiveRule[i]->tag; + pwlen = ActiveRule[i]->tlen ? ActiveRule[i]->tlen : ActiveRule[i]->ilen; + if(pwlen >= MAXTAGLEN) + { + WCHAR tag[MAXTAGLEN]; + wcsncpy_s(tag, MAXTAGLEN, pw,MAXTAGLEN-1); tag[MAXTAGLEN-1] = ELLIPSIS; + GetTextExtentPoint32W(hDC, tag, MAXTAGLEN, &Size); + } + else + { + GetTextExtentPoint32W(hDC, pw, pwlen, &Size); + } + Size.cx += 8; // minimum whitespace of 4 px + if(Size.cx > CellWidth[i]) CellWidth[i] = Size.cx; + } + ReleaseDC(hwndChild,hDC); + + for(i=0; i IMWidth) IMWidth = CellWidth[i]+CWBorders; + } + } + + for(i=0, CellStart[0]=0; i MaxCells ? MaxCells : nCells); + GetIMDimensions(nCellsShown,ContextBuf); + + if(nCells > 0) + { + nCellsShown = (nCells > MaxCells ? MaxCells : nCells); + GetIMDimensions(nCellsShown,ContextBuf); + if(Vertical) + { + dx = IMWidth + IMBorders; + dy = (nCellsShown+1)*CellSize.y + 3*(IMBorders + CWBorders)/2; + } + else + { + dx = InputSize + IMBorders + CWBorders + CellStart[nCellsShown]; + dy = CellSize.y + IMBorders + CWBorders; + } + } + else + { + dx = InputSize + IMBorders + CWBorders; + dy = CellSize.y + IMBorders + CWBorders; + } + + Tracking = FALSE; + + // Don't attempt to track for a vertical selection window + if(EnableTracking && !Vertical) + { + GetCaretPos(&Caret); + hFocus = GetFocus(); + GetWindowRect(hFocus,&RectApp); + + if(Caret.x != 0 || Caret.y != 0) + { + Tracking = EnableTracking; + x = Caret.x+RectApp.left; + y = Caret.y+RectApp.top+24; + if(x + RectIM.right - RectIM.left > RectApp.right) x = RectApp.right - (RectIM.right - RectIM.left); + + if(y + RectIM.bottom - RectIM.top > RectApp.bottom) y = RectApp.top + Caret.y - (RectIM.bottom-RectIM.top); + + } + } + else + { // need to make sure the relative values are correct for the current monitor + hFocus = GetFocus(); + HMONITOR hMonitor = MonitorFromWindow(hFocus, MONITOR_DEFAULTTONEAREST); + if (hMonitor != NULL) { + MONITORINFO monitor_info; + monitor_info.cbSize = sizeof(monitor_info); + GetMonitorInfo(hMonitor, &monitor_info); // No error checking + x = monitor_info.rcMonitor.left + IMPos.x; + y = monitor_info.rcMonitor.top + IMPos.y; + } + else { // Default as if there is one monitor + x = IMPos.x; y = IMPos.y; + Log("UpdateIMXWindow monitor lookup fail "); + } + } + + UserResize = FALSE; + InvalidateRect(hwnd,NULL,TRUE); + SetWindowPos(hwnd,0,x,y,dx,dy,SWP_NOZORDER+SWP_NOACTIVATE); + UserResize = TRUE; +} + +LRESULT CALLBACK IMXWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + RECT rect, rectOuter; + POINT pts; + LRESULT lResult; + PAINTSTRUCT ps; + HBITMAP hOldBmp; + HDC hDC, hSrcDC; + HFONT hfInput, hfOld; + LPMINMAXINFO pMMI; + thread_local static RECT rp[6] = { {0} }; + + int i, x, y, x1, y1, x2, y2, dx, dy, n1, n2, PossibleCells; + + // Use default processing if no keyboard loaded + if(!PrepIM(FALSE) || !CurKbd) + { + switch(msg) + { + case WM_CREATE: + case WM_DESTROY: + break; + default: + return DefWindowProc(hwnd,msg,wParam,lParam); + } + } + + switch(msg) + { + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + pts.x = GET_X_LPARAM(lParam); pts.y = GET_Y_LPARAM(lParam); + GetWindowRect(hwnd,&rect); + x=rect.left; y = rect.top; + + // Process all button clicks on hotspots + if(ScrollPos > 0 && PtInRect(&rp[RECT_UP],pts)) + { + SendKey(VK_PRIOR); + } + else if(ScrollPos+MaxCells < nCells && PtInRect(&rp[RECT_DOWN],pts)) + { + SendKey(VK_NEXT); + } + else if(!Vertical && PtInRect(&rp[RECT_TRACK],pts)) // on tracking hotspot + { + EnableTracking = !EnableTracking; + WriteRegSetting("IMX track", EnableTracking ? 1 : 0); + } + else if(PtInRect(&rp[RECT_ORIENT],pts)) // on orientation hotspot + { + Vertical = !Vertical; + if(Vertical) EnableTracking = Tracking = FALSE; + WriteRegSetting("IMX z", Vertical ? 1 : 0); + WriteRegSetting("IMX track", EnableTracking ? 1 : 0); + } + else if(PtInRect(&rp[RECT_CONFIG],pts)) // on configuration hotspot + { + SendKey(VK_F24); // do not update IMX window + break; + } + else break; + + // Update the IMX window if any changes made + UpdateIMXWindow(); + break; + + case WM_USER_NCHITTEST: + + if(!Tracking) // Allow dragging except when tracking the insertion point + { + pts.x = GET_X_LPARAM(lParam); pts.y = GET_Y_LPARAM(lParam); + ScreenToClient(hwnd, &pts); + GetClientRect(hwnd, &rect); + rect.right = rect.left + InputSize; + if (PtInRect(&rect, pts)) { + return HTCAPTION; + } + // Alternate code: drag only with logo +// if(PtInRect(&rp[RECT_LOGO], pts)) return HTCAPTION; + } + break; + } + + // Handle standard IM functions -- such as window activation, etc. + if(IMDefWindowProc(hwnd, msg, wParam, lParam, &lResult)) return lResult; + + if(msg == wm_keymanim_contextchanged) PostMessage(hwndChild,WM_REDRAW,0,0); + + switch(msg) + { + case WM_CREATE: + + // Read saved IM window settings + ReadConfiguration(TRUE); + + // Centre the window if an error message is being displayed + if(Error != ERR_NONE) + { + IMPos.x = GetSystemMetrics(SM_CXSCREEN)/2 - 200; + IMPos.y = GetSystemMetrics(SM_CYSCREEN)/2 - 28; + } + + UserResize = FALSE; + SetWindowPos(hwnd,0,IMPos.x,IMPos.y,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER); + UserResize = TRUE; + + GetWindowRect(hwnd,&rectOuter); GetClientRect(hwnd, &rect); + IMBorders = ((rectOuter.right-rectOuter.left)-(rect.right-rect.left)); + + // Note that the actual child window dimensions will be set when the window is first displayed, + // except when no valid configuration is loaded + hwndChild = CreateWindowEx(WS_EX_CLIENTEDGE, "KM_IMXChild", "", + WS_BORDER | WS_CHILD | WS_VISIBLE, InputSize, 0, + rect.right-rect.left-InputSize,rect.bottom, hwnd, 0, hDllInst, NULL); + + GetWindowRect(hwndChild,&rectOuter); GetClientRect(hwndChild, &rect); //default is probably OK + CWBorders = ((rectOuter.right-rectOuter.left)-(rect.right-rect.left)); + + // Update the child window + PostMessage(hwndChild,WM_REDRAW,0,0); + + return 0; + + // set resizing limits, according to orientation of IM window + case WM_GETMINMAXINFO: + + pMMI=(LPMINMAXINFO)lParam; + + // Set the window width for error messages + if(Error != ERR_NONE || (CurKbd->h.nrules == 0)) + { + pMMI->ptMinTrackSize.x = pMMI->ptMaxTrackSize.x = InputSize + 12*CELL_X; + pMMI->ptMinTrackSize.y = pMMI->ptMaxTrackSize.y = CELL_Y + IMBorders + CWBorders; + } + + else if(Vertical) + { + pMMI->ptMinTrackSize.x = IMWidth+IMBorders; + pMMI->ptMaxTrackSize.x = max(InputSize,IMWidth) + IMBorders; //IMWidth+IMBorders; + pMMI->ptMinTrackSize.y = CellSize.y + 3*(IMBorders + CWBorders)/2; + pMMI->ptMaxTrackSize.y = pMMI->ptMinTrackSize.y + CellSize.y*MAXACTIVERULES; + } + else + { + pMMI->ptMaxTrackSize.x = InputSize; + for(i=1; i<=MAXACTIVERULES; i++) + { + if(CellStart[i]) + pMMI->ptMaxTrackSize.x = InputSize + CellStart[i]; + else + pMMI->ptMaxTrackSize.x += CellSize.x; + } + pMMI->ptMaxTrackSize.x += IMBorders + CWBorders + 2; + pMMI->ptMinTrackSize.x = InputSize + IMBorders + CWBorders; + pMMI->ptMinTrackSize.y = pMMI->ptMaxTrackSize.y = CellSize.y + IMBorders + CWBorders; + } + + return 0; + + case WM_SHOWWINDOW: + if(wParam) PostMessage(hwndChild,WM_REDRAW,0,0); + break; + + case WM_DESTROY: + return 0; + + case WM_MOVE: + if(!Tracking) + { + RECT IMrect; + if (!GetWindowRect(hwnd, &IMrect)) { + return 0; + } + // Get Absolute X and Y, as if top corner is (0, 0) + HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + if (hMonitor == NULL) { + return 0; + } + + MONITORINFO monitor_info; + monitor_info.cbSize = sizeof(monitor_info); + if (!GetMonitorInfo(hMonitor, &monitor_info)) { + return 0; + } + + long absoluteX = IMrect.left - monitor_info.rcMonitor.left; + long absoluteY = IMrect.top - monitor_info.rcMonitor.top; + + IMPos.x = (short)absoluteX; IMPos.y = (short)absoluteY; + + SaveIMXPosition(); + } + return 0; + + case WM_SIZE: + if(UserResize) + { + + GetWindowRect(hwnd, &rect); + IMSize.x = (short)(rect.right - rect.left); + IMSize.y = (short)(rect.bottom - rect.top); + + if(Vertical) + { + PossibleCells = (IMSize.y - CellSize.y)/CellSize.y; + } + else + { + PossibleCells = (IMSize.x - InputSize + CellSize.x)/CellSize.x; + } + + // Since SetWindowPos also sends a WM_SIZE, must only reset if non-zero + if(PossibleCells >= 2) + { + MaxCells = ((CurKbd->h.dwOptions & SELECTIONBITS)==SM_FKEYS ? 12 : 9); + MaxCells = min(MaxCells,PossibleCells); + WriteRegSetting("IMX cells", MaxCells); + ScrollPos = 0; // always reset scrolling when resizing + + } + } + + if(Vertical && (CurKbd->h.nrules > 0)) + MoveWindow(hwndChild,0,CellSize.y+(IMBorders+CWBorders)/2,IMWidth, GET_Y_LPARAM(lParam)-CellSize.y,TRUE); + else + MoveWindow(hwndChild,InputSize,0, GET_X_LPARAM(lParam)-InputSize, GET_Y_LPARAM(lParam),TRUE); + + // Refill cells if width changed + if(UserResize) FillActiveRules(0); + + GetIMDimensions(MaxCells,ContextBuf); + return 0; + + case WM_PAINT: + hDC = BeginPaint(hwnd, &ps); + + hfInput = CreateFontIndirect(&CurKbd->h.lfInput); + hfOld = (HFONT)SelectObject(hDC,hfInput); + + GetClientRect(hwnd, &rect); + SetBkMode(hDC, TRANSPARENT); + FillRect(hDC, &rect, GetSysColorBrush(COLOR_BTNFACE)); + + if(Vertical) // scroll up/down hotspots + { + x1 = rect.right-14; y1 = CellSize.y+(IMBorders+CWBorders)/2-17; + x2 = x1; y2 = y1+8; + dx = 13; dy = 8; + n1 = ScrollPos>0 ? BMP_UP1 : BMP_UP0; + n2 = ScrollPos+MaxCells0 ? BMP_LEFT1 : BMP_LEFT0; + n2 = ScrollPos+MaxCellsh.dwOptions & SELECTIONBITS) + { + case SM_DEFAULT: + case SM_ALLDIGITS: + KeyStroke = i + '1'; break; + case SM_KEYPAD: + KeyStroke = i + VK_NUMPAD1; break; + case SM_FKEYS: + KeyStroke = i + VK_F1; break; + } + + // Flag simulated keystroke as result of mouse and send keystroke + MouseSelection = TRUE; + SendKey(KeyStroke); + break; + } + } + return 0; + + case WM_NCHITTEST: + lResult = DefWindowProc(hwndChild, msg, wParam, lParam); + if(lResult != HTCLIENT && lResult != HTVSCROLL && lResult != HTHSCROLL) return HTNOWHERE; + + return lResult; + + case WM_MOUSEACTIVATE: + return MA_NOACTIVATE; + + case WM_SIZE: + case WM_REDRAW: // This is a user message, not a standard message + InvalidateRect(hwndChild, NULL, TRUE); + return 0; + + case WM_PAINT: + hDC = BeginPaint(hwndChild, &ps); + hfTag = CreateFontIndirect(&CurKbd->h.lfTag); + hfMain = CreateFontIndirect(&CurKbd->h.lfMain); + GetClientRect(hwndChild, &rect); + if(CurKbd->h.nrules>0) + { + hfOld = (HFONT) SelectObject(hDC, hfTag); + + for(i=0; ipst+ActiveRule[i]->tag; + pwlen = ActiveRule[i]->tlen ? ActiveRule[i]->tlen : ActiveRule[i]->ilen; + + // Use an ellipsis if tag is too long + if(pwlen >= MAXTAGLEN) + { + wcsncpy_s(tag, MAXTAGLEN, pw, MAXTAGLEN-1); + tag[MAXTAGLEN-1] = ELLIPSIS; + pw = tag; pwlen = MAXTAGLEN; + } + + SetTextAlign(hDC,TA_LEFT); + TextOut(hDC, x1, y1, Index, (i<9?1:2)); + + SetTextAlign(hDC,TA_CENTER); + TextOutW(hDC, x2, y2, pw, pwlen); + + SelectObject(hDC, hfMain); + SetTextAlign(hDC,TA_CENTER); SetTextColor(hDC,0); + + pw = CurKbd->pst+ActiveRule[i]->output; + pwlen = ActiveRule[i]->olen; + TextOutW(hDC, x3, y3, pw, pwlen); + } + + // Draw cell boundaries last, to write over text borders + SetTextColor(hDC,0); + for(i=0; ih.name); + TextOut(hDC,10,2,eMsg,(int)strlen(eMsg)); + TextOut(hDC,10,22,p2,(int)strlen(p2)); + SelectObject(hDC,hOldBrush); + } + DeleteObject(hBrush); + } + SelectObject(hDC,hfOld); + } + DeleteObject(hfDflt); + } + } + DeleteObject(hfMain); DeleteObject(hfTag); + EndPaint(hwndChild, &ps); + return 0; + } + + return DefWindowProc(hwndChild, msg, wParam, lParam); +} + +/************************************************************************************************************ + * IM Configuration + ************************************************************************************************************/ + +extern "C" BOOL __declspec(dllexport) WINAPI KeymanIMConfigure(PSTR KeyboardName, HWND hwndParent) +{ + + char *p, buf1[MAX_PATH]; + + Log("KeymanIMConfigure - ENTER"); + Log(KeyboardName); + + buf1[0] = '"'; + if(!(*KMGetKeyboardPath)(KeyboardName, buf1+1, MAX_PATH)) + { + Log("KeymanIMConfigure - fail to get path"); + return FALSE; + } + Log(buf1); + + + if((p=strrchr(buf1,'\\')) != NULL) + { + rsize_t bufLimit=(sizeof buf1) - (p+1-buf1); + strcpy_s(p+1, bufLimit, "imxconfig.exe\" "); strcat_s(p+1, bufLimit, KeyboardName); + Log(buf1); + STARTUPINFO si; + PROCESS_INFORMATION pi; + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + memset(&pi, 0, sizeof(pi)); + CreateProcess(NULL, buf1, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); + //WinExec(buf1,SW_SHOW); + return TRUE; + } + else + { + Log("KeymanIMConfigure - Fail to find \\"); + return FALSE; + } +} + +// Compare rule input string to context buffer +int cmpspecial(RULE *prule,PWCHAR pInput) +{ + PWCHAR pw1, pw1max, lastTone=NULL; + int matchMode=MM_NOMATCH; + + register PWCHAR pw2=pInput; + + if(!prule) return MM_NOMATCH; + + pw1 = CurKbd->pst+prule->input; + pw1max = pw1+prule->ilen; + + // The first character must match, no wild cards allowed + if(*pw2 != *pw1) return MM_NOMATCH; + + // Test first for alternate inputs (flagged by final |, no numeric mode allowed) + if(*(pw1+prule->ilen-1) == L'|' && wcschr(pw2,L'|') == NULL) + { + while(pw1 < pw1max) + { + pw2 = pInput; lastTone = NULL; + while(*pw2) + { + if(strchr(CurKbd->h.ToneChar,*pw1)) lastTone = pw1; + + if(*pw2 == *pw1 || ((*pw2 == '?') && ((CurKbd->h.dwWild&WC_QUERY) != 0))) + { + pw1++; pw2++; continue; + } + else if((*pw2 == '\'') && (lastTone == pw1) && ((CurKbd->h.dwWild&WC_QUOTE) != 0)) + { + pw1++; pw2++; continue; + } + else if((*pw1!=L'|') && strchr(CurKbd->h.ToneChar,*pw1)) + { + pw1++; continue; + } + else break; + } + + if(*pw2 == 0) + { + if(matchMode == MM_NOMATCH) matchMode = MM_START; + + if(*pw1 == L'|') matchMode = MM_PERFECT; + + if(*CurKbd->h.ToneChar != 0) + { + // Test if only trailing character is a tone character + if(strchr(CurKbd->h.ToneChar,*pw1) && (*(pw1+1) == L'|') + && (matchMode < MM_EXCEPTTONE)) matchMode = MM_EXCEPTTONE; + + // Test if first syllable matches, and the input matches the start of the rest + if(lastTone && (pw1 > lastTone) + && (matchMode < MM_MORETHANONE)) matchMode = MM_MORETHANONE; + } + } + if(matchMode == MM_PERFECT) break; + + else { + while(pw1 < pw1max) + { + if(*pw1++ == L'|') break; + } + } + } + return matchMode; + } + + // Test for standard, single input rules (with exceptions for numeric mode rules) + else while(*pw2) + { + if(strchr(CurKbd->h.ToneChar,*pw1)) lastTone = pw1; + + if(*pw2 == *pw1 || ((*pw2 == '?') && ((CurKbd->h.dwWild&WC_QUERY) != 0))) + { + pw1++; pw2++; continue; + } + else if((*pw2 == '\'') && (lastTone == pw1) && ((CurKbd->h.dwWild&WC_QUOTE) != 0)) + { + pw1++; pw2++; continue; + } + else if(!NumericMode && (pw1h.ToneChar,*pw1)) + { + pw1++; continue; + } + else + { + return MM_NOMATCH; // no match + } + } + + // Test for a complete match with the rule input (no trailing characters in rule input) + if(pw1 == pw1max) return MM_PERFECT; + + if(!NumericMode && (*CurKbd->h.ToneChar != 0)) + { + // Test if only trailing character is a tone character + if(strchr(CurKbd->h.ToneChar,*pw1) && (pw1+1==pw1max)) return MM_EXCEPTTONE; + + // Test if first syllable matches, and the input matches the start of the rest + if(lastTone && (pw1 > lastTone)) return MM_MORETHANONE; + } + + return MM_START; // matches start of rule input string +} + +// Select those rules that match the input string. Stop searching when the +// required number of rules has been filled, unless CountAll set (for End key) +int FillActiveRules(WCHAR KeyChar) +{ + int i, n, n0, n1, lBuf, Match; + WCHAR buf2[18]; + PWSTR p,p1; + PSTR q; + RULE *prule; + BOOL Matched=FALSE, SearchToEnd=CountAll; + + if(!CurKbd || (CurKbd->h.nrules == 0)) return (-1); + + // By default, just copy the entire string + wcscpy_s(buf2, _countof(buf2), ContextBuf); p = wcschr(buf2, 0); + + // Test if dashes are being used to select a particular output character + if(((CurKbd->h.dwWild & WC_DASH) != 0) && ((p1=wcsrchr(ContextBuf,L'-')) != NULL)) + { + if(*(p1+1) == 0) // and filter the string if last character in context is a dash + { + for(p=buf2,p1=ContextBuf; *p1; p1++) + { + if(*p1 != L'-') *p++ = *p1; + } + } + } + + // Append the current keystroke + if(KeyChar != 0) + { + if((KeyChar != L'-') || ((CurKbd->h.dwWild & WC_DASH) == 0)) *p++ = KeyChar; + } + *p = 0; + + CountAll = FALSE; + + lBuf = (int)wcslen(buf2); + + for(i=0; iindex+n); + n1 = *(CurKbd->index+n+1); + } + else + { + n = (int)strlen(IndexString); + n0 = *(CurKbd->index+n); + n1 = CurKbd->h.nrules; + } + + for(i=n0,n=0, prule=CurKbd->rules+n0; i MM_START) || (DisplayMode == DM_FULL) || ExtendMatch ) + { + if(n >= ScrollPos) + { + if(n-ScrollPos < MaxCells) ActiveRule[n-ScrollPos] = prule; + else if((n-ScrollPos > MaxCells) && !SearchToEnd) break; + } + n++; + } + } + } + + // Return the number of possible ActiveRules + return Matched ? n : (-1); +} + +BOOL InsertChar(WCHAR ch) +{ + WCHAR buf[2]={0}; + + buf[0] = ch; + (*KMSetOutput)(buf, 0); + return TRUE; +} + +BOOL CompleteRule(RULE *r,int Mode) +{ + int i,n,n1=0,n2=0,ncSelect; + WCHAR tOut[MAXOUTLEN+2]={0}; + PWCHAR p; + PCHAR pt=CurKbd->h.ToneChar; + + if(Mode & OM_TAG) + { + n = r->tlen ? r->tlen : r->ilen; + wcsncpy_s(tOut, _countof(tOut), CurKbd->pst+r->tag, min(n,MAXOUTLEN-1)); + wcscat_s(tOut, _countof(tOut), L" "); + } + else if(Mode & OM_BOTH) + { + wcsncpy_s(tOut, _countof(tOut), CurKbd->pst+r->output, min(r->olen,MAXOUTLEN-1)); + n = r->tlen ? r->tlen : r->ilen; + if(r->olen+n+4 < MAXOUTLEN) + { + wcscat_s(tOut, _countof(tOut), L" ("); + wcsncat_s(tOut, _countof(tOut), CurKbd->pst+r->tag, n); + wcscat_s(tOut, _countof(tOut), L") "); + } + } + else + { + if(((CurKbd->h.dwWild & WC_DASH) != 0) && ((p=wcsrchr(ContextBuf,L'-')) != NULL) + && (r->olen > 1) && (*(p+1) == 0)) + { + p = wcschr(ContextBuf,L'-') + 1; + for(ncSelect=0;*p==L'-' && ncSelectolen-1;p++,ncSelect++); + *tOut = *(CurKbd->pst+r->output + ncSelect); + } + else + { + wcsncpy_s(tOut, _countof(tOut), CurKbd->pst+r->output, min(r->olen,MAXOUTLEN-1)); + } + } + + (*KMSetOutput)(tOut, 0); + + for(i=0; ih.nrules == 0) + { + if(IsVisible) + (*KMHideIM)(); + else + (*KMDisplayIM)(hwnd,TRUE); + + return(FALSE); + } + + ReadConfiguration(TRUE); + + lBuf = (int)wcslen(ContextBuf); + sMode = (CurKbd->h.dwOptions & SELECTIONBITS); + tMode = (CurKbd->h.dwOptions & TONEBITS)>>2; + AutoSelect = (CurKbd->h.dwOptions & SELECTIFUNIQUE); + + // Save current wild card matching + ExtendMode = ExtendMatch; + + // Test if a simulated keystroke, and save special mode flags + outMode = MouseSelection; MouseSelection = FALSE; + + // Check first character (to allow 4-corner index selection for Han) + FirstChar = (char)(lBuf>0 ? *ContextBuf : KeyChar); + NumericMode = (strchr("0123456789#$!@%&*",FirstChar) != NULL); + + // Test first for configuration hotkey (or VK_F24 sent by click on hotspot) + if((KeyStroke == VK_F24) || ((KeyStroke == LOWORD(CurKbd->h.cfgKey)) && + ((shiftFlags & HK_MODIFIERS) == (unsigned)(HIWORD(CurKbd->h.cfgKey) & HK_MODIFIERS)))) + { + SaveIMXPosition(); + *ContextBuf = 0; + (*KMHideIM)(); + KeymanIMConfigure(CurKbd->h.name,hwndFocus); + return TRUE; + } + + // If tone characters must be entered, check if the current character is + // a matching tone character before testing for selection + if((lBuf > 0) && *CurKbd->h.ToneChar && KeyChar && !outMode + && (tMode != TM_NEVER) && (strchr(CurKbd->h.ToneChar,(char)KeyStroke) > 0)) + { + if(FillActiveRules(KeyChar) >= 0) SkipSelectionTesting = TRUE; + } + + // If numeric mode, then check that the digit does not form part of a valid input string + if((lBuf > 0) && NumericMode && (KeyChar != 0) && iswdigit(KeyStroke)) + { + if(FillActiveRules(KeyChar) >= 0) SkipSelectionTesting = TRUE; + } + + // Test next for rule completion + if(lBuf > 0 && !SkipSelectionTesting) + { + // Test selection by space first, then according to configured selection mode + if(KeyChar == VK_SPACE || KeyStroke == VK_RETURN) + { + // Check first if input string is U+xxxxx (direct Unicode, incl. surrogate pairs) + if(OutputUnicode(ContextBuf,lBuf)) return TRUE; + + // Otherwise space or return is same as selecting left most (or top) cell + nSelect = 1; + } + else + { + switch(sMode) + { + case SM_DEFAULT: + nSelect = (UINT)(KeyStroke-'1'+1); + break; + case SM_ALLDIGITS: + if(KeyStroke < VK_NUMPAD1) + nSelect = (UINT)(KeyChar-'1'+1); + else + nSelect = (UINT)(KeyStroke-VK_NUMPAD1+1); + break; + case SM_KEYPAD://must test shiftstate + nSelect = (UINT)(KeyStroke-VK_NUMPAD1+1); + break; + case SM_FKEYS: + nSelect = (UINT)(KeyStroke-VK_F1+1); + if(shiftFlags & HK_SHIFT) outMode = OM_TAG; + if(shiftFlags & HK_CTRL) outMode = OM_BOTH; + break; + } + } + + if(nSelect > 0) + { + nCells = FillActiveRules(0); // otherwise, re-fill the matching rules + if(nSelect <= nCells) // selection from menu by Fn key + { + if(ActiveRule[nSelect-1]) // use selected character + { + CompleteRule(ActiveRule[nSelect-1],outMode); + return TRUE; + } + } + } + } + + // Process non-printing characters next - first, for empty buffer + if(!isprint(KeyChar) && lBuf == 0) + { + switch(KeyStroke) + { + case VK_ESCAPE: + (*KMQueueAction)(QIT_CHAR, KeyStroke); + break; + + case VK_BACK: + (*KMQueueAction)(QIT_BACK, 0); + break; + + default: + (*KMQueueAction)(QIT_VKEYDOWN, KeyStroke); + (*KMQueueAction)(QIT_VKEYUP, KeyStroke); + } + + SaveIMXPosition(); + *ContextBuf = 0; + (*KMHideIM)(); + return TRUE; + } + + // then process non-printing characters when buffer non-empty + else if(!isprint(KeyChar) && lBuf > 0) + { + // drop buffer and close IMX window + if(KeyStroke == VK_ESCAPE || ((KeyStroke == VK_BACK) && (lBuf == 1))) + { + SaveIMXPosition(); + *ContextBuf = 0; + (*KMHideIM)(); + return TRUE; + } + + // translate number pad keys to characters + switch(KeyStroke) + { + case VK_MULTIPLY: + KeyChar = '*'; break; + + case VK_ADD: + KeyChar = '+'; break; + + case VK_SUBTRACT: + KeyChar = '-'; break; + + case VK_DECIMAL: + KeyChar = '.'; break; + + case VK_DIVIDE: + KeyChar = '/'; break; + } + + // adjust display according to cursor movement keys + switch(KeyStroke) + { + case VK_BACK: // drop the previously entered character + Refresh = TRUE; ScrollPos = 0; + pCB = wcschr(ContextBuf,0); + if(pCB > ContextBuf) *(pCB-1) = 0; + break; + + case VK_HOME: //scroll to first match + if(ActiveRule[0]) + { + ScrollPos = 0; Refresh = TRUE; + } + break; + + case VK_END: //scroll to last match + if(ActiveRule[0]) + { + Refresh = TRUE; ScrollPos = 0; CountAll = TRUE; + nCells = FillActiveRules(0); + ScrollPos = max(0,nCells-MaxCells); + } + break; + + case VK_LEFT: //scroll backward through the menu (Cursor Left/Up) + case VK_UP: + if(ActiveRule[0]) + { + Refresh = TRUE; + if(ScrollPos-1 >= 0) ScrollPos -= 1; else ScrollPos = 0; + } + break; + + case VK_RIGHT: //scroll forward through menu (Cursor Right/Down) + case VK_DOWN: + if(ActiveRule[1]) + { + Refresh = TRUE; + if(ScrollPos+1 < nCells) ScrollPos += 1; + } + break; + + case VK_NEXT: //scroll forward through menu (Page Down) + if(ActiveRule[MaxCells-1]) + { + Refresh = TRUE; + if(ScrollPos+MaxCells < nCells) ScrollPos += MaxCells; + } + break; + + case VK_PRIOR: //scroll backward through the menu (Page Up) + if(ActiveRule[0]) + { + Refresh = TRUE; + if(ScrollPos-MaxCells >= 0) ScrollPos -= MaxCells; else ScrollPos = 0; + } + break; + } + + if(Refresh) + { + nCells = FillActiveRules(0); DropCharacter = FALSE; + } + } + + // Check for wild card matching + if((CurKbd->h.dwWild & WC_STAR) && (KeyChar == '*') && (lBuf > 0)) + { + ExtendMatch = TRUE; + nCells = FillActiveRules(0); + DropCharacter = FALSE; + } + // Match the entered character plus the context with allowed sequences + else if(isprint(KeyChar) && (lBuf<(sizeof ContextBuf)/sizeof(WCHAR))) + { + if(IsHexString(ContextBuf,lBuf, KeyChar)) + { + pCB = wcschr(ContextBuf,0); *pCB++ = KeyChar; *pCB = 0; + DropCharacter = FALSE; + } + + else if(NumericMode || !(tMode == TM_NEVER && *CurKbd->h.ToneChar // always drop if no tone characters + && (strchr(CurKbd->h.ToneChar,(char)KeyChar)>0))) + { + ScrollPos = 0; ExtendMatch = FALSE; + switch((nCells=FillActiveRules(KeyChar))) + { + case (-1): + if(lBuf == 0) // empty context + { + InsertChar(KeyChar); // so don't do anything with IM window + return TRUE; + } + else + { + ExtendMatch = ExtendMode; + nCells=FillActiveRules(0); + DropCharacter = TRUE; + } + break; + + case 0: // no exact match, but starts a match + pCB = wcschr(ContextBuf,0); *pCB++ = KeyChar; *pCB = 0; + DropCharacter = FALSE; + break; + + case 1: // check if this is a unique and complete match + if(AutoSelect && ActiveRule[0]) + { + BOOL TrulyUnique=TRUE; + + if(!ExtendMatch && (DisplayMode!=DM_FULL)) + { + RULE *TempRule[MAXACTIVERULES]; + ExtendMatch = TRUE; + memcpy(TempRule,ActiveRule,MAXACTIVERULES*sizeof(RULE *)); + TrulyUnique = (FillActiveRules(KeyChar) == 1); + memcpy(ActiveRule,TempRule,MAXACTIVERULES*sizeof(RULE *)); + ExtendMatch = FALSE; + } + + if(TrulyUnique) + { + pCB = wcschr(ContextBuf,0); *pCB++ = KeyChar; *pCB = 0; + if(cmpspecial(ActiveRule[0],ContextBuf) > 1) + { + CompleteRule(ActiveRule[0],outMode); // send the result to the app, and hide IM window + return TRUE; + } + DropCharacter = FALSE; + break; + } + } // else fall through and add to context + + default: // multiple matches possible, so just extend the context + pCB = wcschr(ContextBuf,0); *pCB++ = KeyChar; *pCB = 0; + DropCharacter = FALSE; + } + } + } + + // Drop the character and beep if the IMX window is already open and it cannot be matched + if(DropCharacter) + { + ExtendMatch = ExtendMode; // restore wild card match + (*KMQueueAction)(QIT_BELL, 0); + return TRUE; + } + + // Show the IM window, then update its position and size + (*KMDisplayIM)(hwnd, TRUE); + UpdateIMXWindow(); + + return TRUE; +} + +void UnloadRules(PSTR KeyboardName) +{ + int nkbi; + KEYBOARD *kbi; + + if((nkbi=KeyboardIndex(KeyboardName)) == nKeyboards) return; + + if((kbi=&Keyboards[nkbi]) == NULL) return; + + // Unmap shared memory from the process's address space + if(kbi->BaseAddress) UnmapViewOfFile(kbi->BaseAddress); + + // Close the process's handle to the file-mapping object and backing file + if(kbi->hMapObject) CloseHandle(kbi->hMapObject); + if(kbi->hFile) CloseHandle(kbi->hFile); + + // Zero pointers and handles + kbi->h.nrules = 0; kbi->BaseAddress = NULL; + kbi->hFile = 0; kbi->hMapObject = 0; +} + +// Decrypt the string table +void DecryptStrings(KBHEADER *pk) +{ + BYTE *p0, *p1, *p; + int n; + + p0 = (BYTE *)pk + pk->dwStrings; + p1 = p0 + pk->cbStrings; + + for(p=p0,n=0; ph.nrules = 0; + + // Test first if the saved memory-mapped file image exists + wsprintf(mapfile, "keyman_imx_%s", KeyboardName); + + // Open mapping object (if already created by another application) + hMapObject = OpenFileMapping(FILE_MAP_WRITE,FALSE,mapfile); + if(hMapObject) + { + // Get a pointer to file-mapped shared memory + if((pbmm=(PBYTE)MapViewOfFile(hMapObject,FILE_MAP_WRITE,0,0,0)) == NULL ) + { + Error = ERR_SHARING; + CloseHandle(hMapObject); return FALSE; + } + pkbh = (KBHEADER *)pbmm; + } + + // Otherwise, create the file-mapping object from the backing file (*.CFX) + else + { + if(!(*KMGetKeyboardPath)(KeyboardName, buf1, MAX_PATH)) return FALSE; + _splitpath_s(buf1, drive, sizeof drive, dir, sizeof dir, NULL, 0, NULL, 0); + _makepath_s(buf1, sizeof buf1, drive, dir, KeyboardName, ".cfx"); + + hFile = CreateFile(buf1,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); + + // Return FALSE if the CFX is not found + if(hFile == INVALID_HANDLE_VALUE) + { + Error = ERR_CFGMISSING; return FALSE; + } + + Error = ERR_CFGINVALID; + dwFileSize[0] = GetFileSize(hFile,&dwFileSize[1]); + + // Create the named file-mapping object from the backing file + if((hMapObject=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,dwFileSize[1],dwFileSize[0],mapfile)) == NULL ) + { + CloseHandle(hFile); return FALSE; + } + + // Get a pointer to file-mapped shared memory + if((pbmm=(PBYTE)MapViewOfFile(hMapObject,FILE_MAP_WRITE,0,0,0)) != NULL ) + { + pkbh = (KBHEADER *)pbmm; + } + else + { + CloseHandle(hMapObject); CloseHandle(hFile); return FALSE; + } + + // Read the keyboard header and check the file type flag and version + ReadFile(hFile,pkbh,sizeof(KBHEADER),&nRead,NULL); + if(nRead < sizeof(KBHEADER) || memcmp(pkbh->Flag,"KCFX",4) != 0 + || pkbh->dwCfxVersion != CFXVERSION) + { + UnmapViewOfFile(pbmm); + CloseHandle(hMapObject); CloseHandle(hFile); return FALSE; + } + + // Check the file size + totalsize = pkbh->dwStrings + pkbh->cbStrings; + if(dwFileSize[0] < totalsize+4) + { + UnmapViewOfFile(pbmm); + CloseHandle(hMapObject); CloseHandle(hFile); return FALSE; + } + +/* + // If more than rule limit, test if Keyman is registered + if((pkbh->nrules > MAXRULESFREE) && + !(IsRegistered(KEY_KEYMAN) || IsRegistered(KEY_KEYMANDEVELOPER))) + { + Error = ERR_UNREGISTERED; UnmapViewOfFile(pbmm); + CloseHandle(hMapObject); CloseHandle(hFile); return FALSE; + } +*/ + + // Can read and decrypt file here + SetFilePointer(hFile,0,NULL,FILE_BEGIN); + ReadFile(hFile,pbmm,dwFileSize[0],&nRead,NULL); + + CloseHandle(hFile); hFile = NULL; + + // Check if file read correctly (verify checksum) + if(nRead >= dwFileSize[0]) + { + dwChecksum = GetCRC32(pbmm,totalsize); + if(memcmp(pbmm+totalsize,&dwChecksum,4) == 0) Error = ERR_NONE; + } + + if(Error == ERR_CFGINVALID) + { + UnmapViewOfFile(pbmm); CloseHandle(hMapObject); return FALSE; + } + + // Decrypt the string table + DecryptStrings(pkbh); + } + + // Copy the keyboard parameters (not the variables) + *(KBHEADER *)kbi = *pkbh; + + // Correct the table base addresses + kbi->BaseAddress = pbmm; + kbi->index = (DWORD *)(pbmm + pkbh->dwIndex); + kbi->rules = (RULE *)(pbmm + pkbh->dwRules); + kbi->pst = (PWCHAR)(pbmm + pkbh->dwStrings); + + // Save the file and mapping object handles for destruction on exit + kbi->hFile = hFile; + kbi->hMapObject = hMapObject; + + CellSize.x = kbi->h.gridx; CellSize.y = kbi->h.gridy; + + // Read saved options from registry + wsprintf(key,"IMX: %s",kbi->h.name); + kbi->h.dwOptions = ReadRegSetting(key,kbi->h.dwOptions); + + Error = ERR_NONE; + return TRUE; +} + +void DeleteKeyboard(PSTR KeyboardName) +{ + int nkbi; + KEYBOARD *kbi; + + if((nkbi=KeyboardIndex(KeyboardName)) == nKeyboards) return; + + kbi = &Keyboards[nkbi]; + memmove(kbi, kbi+1, sizeof(KEYBOARD)*(nKeyboards-nkbi-1)); + + if(--nKeyboards == 0) + { + delete Keyboards; + Keyboards = NULL; + } +} + +void CreateKeyboard(PSTR KeyboardName) +{ + int nkbi; + + if((nkbi=KeyboardIndex(KeyboardName)) == nKeyboards) + { + KEYBOARD *kb2 = new KEYBOARD[nKeyboards + 1]; + if(nKeyboards > 0) + { + memcpy(kb2, Keyboards, sizeof(KEYBOARD) * nKeyboards); + delete Keyboards; + } + Keyboards = kb2; + ZeroMemory(&Keyboards[nKeyboards],sizeof(KEYBOARD)); + strncpy_s(Keyboards[nKeyboards].h.name, sizeof Keyboards[nKeyboards].h.name, KeyboardName, 127); + nKeyboards++; + } +} + +void WriteRegSetting(PSTR text, int value) +{ + HKEY hkey; + if(RegCreateKeyEx(HKEY_CURRENT_USER, REGSZ_KeymanIMX, 0, NULL, NULL, KEY_ALL_ACCESS | KEY_WOW64_32KEY, NULL, &hkey, NULL) == ERROR_SUCCESS) + { + RegSetValueEx(hkey, text, 0, REG_DWORD, (PBYTE) &value, 4); + RegCloseKey(hkey); + } +} + +int ReadRegSetting(PSTR text, int dflt) +{ + HKEY hkey; + if(RegOpenKeyEx(HKEY_CURRENT_USER, REGSZ_KeymanIMX, + 0, KEY_ALL_ACCESS | KEY_WOW64_32KEY, &hkey) == ERROR_SUCCESS) + { + unsigned long value, sz = 4, tp = REG_DWORD; + if(RegQueryValueEx(hkey, text, 0, &tp, (PBYTE) &value, &sz) == ERROR_SUCCESS) + { + RegCloseKey(hkey); + return value; + } + RegCloseKey(hkey); + } + return dflt; +} + +// Read (or default) saved configuration parameters, and limit to safe values +BOOL ReadConfiguration(BOOL All) +{ + int xmax, ymax, dfltCells=9; + char key[128]; + + DisplayMode = ReadRegSetting("IMX match",DM_LIMITED); + Vertical = ReadRegSetting("IMX z",FALSE) ? TRUE : FALSE; + EnableTracking = ReadRegSetting("IMX track",TRUE) ? TRUE : FALSE; + Tracking = EnableTracking && (!Vertical); + + if(CurKbd) + { + wsprintf(key,"IMX: %s",CurKbd->h.name); + CurKbd->h.dwOptions = ReadRegSetting(key,0); + if((CurKbd->h.dwOptions & SELECTIONBITS) == SM_FKEYS) dfltCells = 12; + } + + if(All) + { + // Read position for non-tracking window (use by default when creating window) + IMPos.x = ReadRegSetting("IMX x",0); + IMPos.y = ReadRegSetting("IMX y",0); + + xmax = GetSystemMetrics(SM_CXSCREEN); + ymax = GetSystemMetrics(SM_CYSCREEN); + + if(Vertical) + { + if(IMPos.x > xmax - 8) IMPos.x = 0; + if(IMPos.y > ymax - 80) IMPos.y = ymax - 80; + } + else + { + if(IMPos.x > xmax - 40) IMPos.x = 0; + if(IMPos.y == 0 || IMPos.y > ymax - 8) IMPos.y = ymax - 80; + } + + MaxCells = ReadRegSetting("IMX cells",dfltCells); + MaxCells = min(max(MaxCells,2),dfltCells); + } + + return TRUE; +} + +BOOL SaveIMXPosition(void) +{ + RECT IMrect; + if(hwnd && !Tracking) + { + if (!GetWindowRect(hwnd, &IMrect)) { + return FALSE; + } + // Adjust for a mulitple monitor display + + HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + if (hMonitor == NULL) { + return FALSE; + } + + MONITORINFO monitor_info; + monitor_info.cbSize = sizeof(monitor_info); + if (!GetMonitorInfo(hMonitor, &monitor_info)) { + return FALSE; + } + + long absoluteX = IMrect.left - monitor_info.rcMonitor.left; + long absoluteY = IMrect.top - monitor_info.rcMonitor.top; + WriteRegSetting("IMX x", absoluteX); WriteRegSetting("IMX y", absoluteY); + + } + return TRUE; +} + +// Simulate a (virtual) key. Note that modified keys cannot be handled this way. +void SendKey(int vk) +{ + keybd_event(vk,0,0,0); keybd_event(vk,0,KEYEVENTF_KEYUP,0); +} + +// Check for existence of key - don't need to check validity, as Keyman will do that +/*BOOL IsRegistered(UINT regKeyID) +{ + HKEY hkey; + DWORD sz, tp = REG_BINARY; + BOOL Exists=FALSE; + PSTR pKey; + + switch(regKeyID) + { + case KEY_KEYMAN: + pKey = "SOFTWARE\\Tavultesoft\\Keyman\\6.0"; + break; + case KEY_KEYMANDEVELOPER: + pKey = "SOFTWARE\\Tavultesoft\\Keyman Developer\\6.0"; + break; + default: + return TRUE; + } + + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,pKey,0,KEY_READ,&hkey) == ERROR_SUCCESS) + { + if((RegQueryValueEx(hkey, "registration key", 0, &tp, NULL, &sz) == ERROR_SUCCESS) + && (tp == REG_BINARY)) Exists = TRUE; + if((RegQueryValueEx(hkey, "licence blob", 0, &tp, NULL, &sz) == ERROR_SUCCESS) + && (tp == REG_BINARY)) Exists = TRUE; + if((RegQueryValueEx(hkey, "evaluation", 0, &tp, NULL, &sz) == ERROR_SUCCESS) + && (tp == REG_BINARY)) Exists = TRUE; + RegCloseKey(hkey); + } + + if(!Exists && regKeyID == KEY_KEYMAN) + { + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Tavultesoft\\Keyman Engine\\7.0",0,KEY_READ,&hkey) == ERROR_SUCCESS) + { + Exists = TRUE; + RegCloseKey(hkey); + } + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Tavultesoft\\Keyman Engine\\8.0",0,KEY_READ,&hkey) == ERROR_SUCCESS) + { + Exists = TRUE; + RegCloseKey(hkey); + } + } + + return Exists; +}*/ + +BOOL IsHexString(PWSTR pContext, UINT lBuf, WCHAR wChar) +{ + switch(lBuf) + { + case 0: + return (wChar==L'U'); + case 1: + return (*pContext == L'U' && wChar == L'+'); + default: + if(*pContext != L'U' || *(pContext+1) != '+') return FALSE; + return (wcschr(L"0123456789abcdefABCDEF",wChar) > 0); + } +} + +BOOL OutputUnicode(PWSTR pContext,UINT lBuf) +{ + WCHAR tOut[4]={0}; + DWORD dwChar; + int i; + + if(lBuf < 4) return FALSE; + + if(*pContext != L'U' || *(pContext+1) != L'+') return FALSE; + + dwChar = wcstoul(pContext+2,NULL,16); + + if(dwChar < 0x10000) + { + tOut[0] = (WCHAR)dwChar; + } + else + { + tOut[0] = (WCHAR)Uni_UTF32ToSurrogate1(dwChar); + tOut[1] = (WCHAR)Uni_UTF32ToSurrogate2(dwChar); + } + + (*KMSetOutput)(tOut, 0); + + for(i=0; i + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (Australia) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS +#pragma code_page(1252) +#endif //_WIN32 + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 6,0,161,0 + PRODUCTVERSION 6,0,161,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "0c0904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Tavultesoft\0" + VALUE "FileDescription", "KeymanIMX\0" + VALUE "FileVersion", "6.0.161.0\0" + VALUE "InternalName", "KeymanIMX\0" + VALUE "LegalCopyright", "Copyright © 2003 Tavultesoft\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "KeymanIMX\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "Tavultesoft KeymanIMX\0" + VALUE "ProductVersion", "6.0.161.0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0xc09, 1200 + END +END + +#endif // !_MAC + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +LOGO BITMAP DISCARDABLE "../images/Key.bmp" +VERTICAL BITMAP DISCARDABLE "../images/Direction_V.bmp" +CONFIG BITMAP DISCARDABLE "../images/Direction_H.bmp" +T_GREEN BITMAP DISCARDABLE "../images/T_green.bmp" +T_RED BITMAP DISCARDABLE "../images/T_red.bmp" +T_GRAY BITMAP DISCARDABLE "../images/T_yellow.bmp" +LEFT1 BITMAP DISCARDABLE "../images/vertical.bmp" +LEFT0 BITMAP DISCARDABLE "../images/left2.bmp" +RIGHT1 BITMAP DISCARDABLE "../images/right1.bmp" +RIGHT0 BITMAP DISCARDABLE "../images/right0.bmp" +DOWN1 BITMAP DISCARDABLE "../images/down1.bmp" +DOWN0 BITMAP DISCARDABLE "../images/down0.bmp" +UP1 BITMAP DISCARDABLE "../images/up1.bmp" +UP0 BITMAP DISCARDABLE "../images/up0.bmp" +HORIZONTAL BITMAP DISCARDABLE "../images/horizont.bmp" +#endif // English (Australia) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/release/c/cs_pinyin/source/keymanimx/KeymanIMX.vcxproj b/release/c/cs_pinyin/source/keymanimx/KeymanIMX.vcxproj new file mode 100644 index 0000000000..56eb5ae510 --- /dev/null +++ b/release/c/cs_pinyin/source/keymanimx/KeymanIMX.vcxproj @@ -0,0 +1,340 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {F00D56AD-FFA9-4012-95D4-4ED8FA00DDEC} + KeymanIMX + 10.0.17763.0 + + + + DynamicLibrary + false + MultiByte + v142 + + + DynamicLibrary + false + MultiByte + v142 + + + DynamicLibrary + false + MultiByte + v142 + + + DynamicLibrary + false + MultiByte + v142 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + true + true + false + false + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + KeymnIMX.x64 + KeymnIMX + true + KeymnIMX + + + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + + + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + ..\..\build\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ + + + KeymnIMX.x64 + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/KeymanIMX.tlb + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KEYMANIMX_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + $(outdir)\KeymanIMX.pch + $(outdir)\ + $(outdir)\ + $(outdir)\ + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + odbc32.lib;odbccp32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;%(AdditionalDependencies) + true + .\KeymanIMX.def + true + $(OutDir)$(TargetName).pdb + $(OutDir)$(TargetName).lib + MachineX86 + false + + + true + .\Debug/KeymanIMX.bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/KeymanIMX.tlb + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KEYMANIMX_EXPORTS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + $(outdir)\KeymanIMX.pch + $(outdir)\ + $(outdir)\ + $(outdir)\ + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + odbc32.lib;odbccp32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + .\KeymanIMX.def + true + $(OutDir)$(TargetName).pdb + $(OutDir)$(TargetName).lib + + + true + .\Debug/KeymanIMX.bsc + + + + + + + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/KeymanIMX.tlb + + + + + MaxSpeed + OnlyExplicitInline + WIN32;NDEBUG;_WINDOWS;_USRDLL;KEYMANIMX_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreaded + true + Level3 + true + $(outdir)\ + $(outdir)\ + $(outdir)\ + $(outdir)\KeymanIMX.pch + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + odbc32.lib;odbccp32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;%(AdditionalDependencies) + true + .\KeymanIMX.def + MachineX86 + $(OutDir)$(TargetName).lib + $(OutDir)$(TargetName).pdb + + + true + .\Release/KeymanIMX.bsc + + + + + + + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/KeymanIMX.tlb + + + + + MaxSpeed + OnlyExplicitInline + WIN32;NDEBUG;_WINDOWS;_USRDLL;KEYMANIMX_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(outdir)\KeymanIMX.pch + $(outdir)\ + $(outdir)\ + $(outdir)\ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + odbc32.lib;odbccp32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;%(AdditionalDependencies) + true + + + $(OutDir)$(TargetName).pdb + $(OutDir)$(TargetName).lib + + + true + .\Release/KeymanIMX.bsc + + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/release/c/cs_pinyin/source/keymanimx/KeymanIMX.vcxproj.filters b/release/c/cs_pinyin/source/keymanimx/KeymanIMX.vcxproj.filters new file mode 100644 index 0000000000..22101d8c77 --- /dev/null +++ b/release/c/cs_pinyin/source/keymanimx/KeymanIMX.vcxproj.filters @@ -0,0 +1,100 @@ + + + + + {f4392622-ece5-41a9-a789-52cb0cde2de8} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {7105faa7-0424-40f3-ae5e-ae3a9d5f4115} + h;hpp;hxx;hm;inl + + + {15f7159a-5116-4def-8889-aa7d3f31b9c6} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Header Files + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/release/c/cs_pinyin/source/keymanimx/ReadMDB.cpp b/release/c/cs_pinyin/source/keymanimx/ReadMDB.cpp new file mode 100644 index 0000000000..8779e71c32 --- /dev/null +++ b/release/c/cs_pinyin/source/keymanimx/ReadMDB.cpp @@ -0,0 +1,42 @@ +#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \ +no_namespace rename("EOF", "EndOfFile") +// This code comes from : www.geocities.com/mokarrabin +#include +#include + +int ReadMDB(PSTR pDBPath,PSTR pUser,PSTR pPwd,PSTR pTable) + + + { + CoInitialize(NULL); + try + + + { + _RecordsetPtr pRst("ADODB.Recordset"); + // Connection String + _bstr_t strCnn("DRIVER={Microsoft Access Driver (*.mdb)};UID=admin;DBQ=GBOOK.mdb"); + // Open table + pRst->Open("SELECT * FROM ProductService where ProductService like '%samir%';", strCnn, adOpenStatic, adLockReadOnly, adCmdText); + + pRst->MoveFirst(); + + + while (!pRst->EndOfFile) { + cout<<(char*) ((_bstr_t) pRst->GetFields()->GetItem("ProductService")->GetValue())<MoveNext(); + } + pRst->Close(); + + } + catch (_com_error &e) + + + { + cout<<(char*) e.Description(); + } + ::CoUninitialize(); + +return TRUE; + } + \ No newline at end of file diff --git a/release/c/cs_pinyin/source/keymanimx/crc32.cpp b/release/c/cs_pinyin/source/keymanimx/crc32.cpp new file mode 100644 index 0000000000..2b6fbc543b --- /dev/null +++ b/release/c/cs_pinyin/source/keymanimx/crc32.cpp @@ -0,0 +1,72 @@ +/************************************************************************** + +Description: CRC32 algorithm + +Copyright (c) 2017 SIL International + +**************************************************************************/ + +#include + +// 32 bit CRC checksum calculation + +static const DWORD crc_t[] = { /* CRC polynomial 0xedb88320 */ +0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, +0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, +0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, +0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, +0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, +0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, +0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, +0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, +0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, +0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, +0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, +0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, +0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, +0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, +0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, +0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, +0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, +0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, +0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, +0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, +0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, +0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, +0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, +0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, +0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, +0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, +0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, +0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, +0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, +0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, +0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, +0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, +0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, +0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, +0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, +0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, +0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, +0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, +0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, +0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, +0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, +0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, +0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +#define UPDC32(octet, crc) (crc_t[((crc)^(octet)) & 0xff] ^ ((crc)>>8)) + +DWORD GetCRC32(LPVOID pv, UINT cb) +{ + register DWORD crc32; + register LPBYTE pb; + + for(pb=(LPBYTE)pv, crc32=0xFFFFFFFF; cb>0; cb--, pb++) + { + crc32 = UPDC32(*pb,crc32); + } + + return crc32; +} diff --git a/release/c/cs_pinyin/source/keymanimx/imxlib.cpp b/release/c/cs_pinyin/source/keymanimx/imxlib.cpp new file mode 100644 index 0000000000..b0952bf654 --- /dev/null +++ b/release/c/cs_pinyin/source/keymanimx/imxlib.cpp @@ -0,0 +1,236 @@ + +#define STRICT +#include +#include "imxlib.h" + +HMODULE hModuleKeyman32 = 0; +KMSetOutputProc KMSetOutput = NULL; +KMGetContextProc KMGetContext = NULL; +KMQueueActionProc KMQueueAction = NULL; +KMDisplayIMProc KMDisplayIM = NULL; +KMHideIMProc KMHideIM = NULL; +KMGetActiveKeyboardProc KMGetActiveKeyboard = NULL; +KMGetKeyboardPathProc KMGetKeyboardPath = NULL; + +thread_local BOOL FMoveWindow=FALSE, FSizeWindow=FALSE; + +extern BOOL Vertical; + +// I don't know why this is defined here??????????????? +BOOL WINAPI IntKMGetKeyboardPath(PSTR kbdname, PSTR buf, DWORD len) +{ + *kbdname = 0; + return FALSE; +} + +BOOL PrepIM(BOOL Reset) +{ + if(Reset) FMoveWindow = FSizeWindow = FALSE; // clear when initializing + + if(hModuleKeyman32 != 0) return TRUE; // already prepared +#ifdef _WIN64 + hModuleKeyman32 = GetModuleHandle("keyman64.dll"); +#else + hModuleKeyman32 = GetModuleHandle("keyman32.dll"); +#endif + if(hModuleKeyman32 == 0) + { + KMGetKeyboardPath = IntKMGetKeyboardPath; // I don't understand this????????? + return TRUE; + } + + KMSetOutput = (KMSetOutputProc) GetProcAddress(hModuleKeyman32, "KMSetOutput"); + if(!KMSetOutput) return FALSE; + + KMGetContext = (KMGetContextProc) GetProcAddress(hModuleKeyman32, "KMGetContext"); + if(!KMGetContext) return FALSE; + + KMQueueAction = (KMQueueActionProc) GetProcAddress(hModuleKeyman32, "KMQueueAction"); + if(!KMQueueAction) return FALSE; + + KMDisplayIM = (KMDisplayIMProc) GetProcAddress(hModuleKeyman32, "KMDisplayIM"); + if(!KMDisplayIM) return FALSE; + + KMHideIM = (KMHideIMProc) GetProcAddress(hModuleKeyman32, "KMHideIM"); + if(!KMHideIM) return FALSE; + + KMGetActiveKeyboard = (KMGetActiveKeyboardProc) GetProcAddress(hModuleKeyman32, "KMGetActiveKeyboard"); + if(!KMGetActiveKeyboard) return FALSE; + + KMGetKeyboardPath = (KMGetKeyboardPathProc) GetProcAddress(hModuleKeyman32, "KMGetKeyboardPath"); + if(!KMGetKeyboardPath) return FALSE; + + return TRUE; +} + +// IMDefWindowProc returns TRUE if the window procedure should just return lResult, +// and not process further. + +// The cursor control has been altered to only show sizing arrows for sizable edges, and +// return the normal pointer in all other cases, to correct behaviour when used with Word +HCURSOR GetHitTestCursor(HWND hwnd, LRESULT ht, LPRECT sizerect) +{ + LPSTR cr = NULL; + + memset(sizerect, 0, sizeof(RECT)); + + if(Vertical) switch(ht) + { + case HTBOTTOMLEFT: + case HTBOTTOMRIGHT: + case HTBOTTOM: + cr = IDC_SIZENS; + sizerect->bottom = 1; + break; + default: + cr = IDC_ARROW; + break; + } + else switch(ht) + { + case HTTOPRIGHT: + case HTBOTTOMRIGHT: + case HTRIGHT: + cr = IDC_SIZEWE; + sizerect->right = 1; + break; + default: + cr = IDC_ARROW; + break; + } + + return LoadCursor(NULL, cr); +} + +void Log(char *p, int n); + +BOOL IMDefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *lResult) +{ + thread_local static POINT FLastPoint; + thread_local static RECT sizerect; + thread_local static HCURSOR FHitTestCursor; + + RECT rect; + POINTS pt; + POINT pt2; + LRESULT ht; + + switch(msg) + { + case WM_CREATE: + PostMessage(hwnd, WM_NCACTIVATE, TRUE, 0); + return FALSE; + + case WM_NCACTIVATE: + *lResult = DefWindowProc(hwnd, msg, TRUE, lParam); + return TRUE; + + case WM_USER_NCHITTEST: + *lResult = DefWindowProc(hwnd, WM_NCHITTEST, wParam, lParam); + return TRUE; + + case WM_NCHITTEST: + *lResult = HTCLIENT; + + if(FMoveWindow || FSizeWindow) return TRUE; + + ht = DefWindowProc(hwnd, msg, wParam, lParam); + SetCursor(FHitTestCursor = GetHitTestCursor(hwnd, ht, &sizerect)); + return TRUE; //this is equivalent to returning HTCLIENT, which seems odd + + case WM_MOUSEACTIVATE: + *lResult = MA_NOACTIVATE; + return TRUE; + + case WM_LBUTTONDOWN: + pt = MAKEPOINTS(lParam); pt2.x = pt.x; pt2.y = pt.y; + ClientToScreen(hwnd, &pt2); + + FMoveWindow = FSizeWindow = FALSE; + + switch((ht=SendMessage(hwnd,WM_USER_NCHITTEST,0,MAKELONG(pt2.x,pt2.y)))) + { + case HTCAPTION: + *lResult = 0; + FMoveWindow = TRUE; + SetCapture(hwnd); + FLastPoint = pt2; + SetCursor(FHitTestCursor); + return TRUE; + + case HTTOP: + case HTTOPLEFT: + case HTTOPRIGHT: + case HTBOTTOM: + case HTBOTTOMLEFT: + case HTBOTTOMRIGHT: + case HTLEFT: + case HTRIGHT: + *lResult = 0; + FSizeWindow = TRUE; + SetCapture(hwnd); + FLastPoint = pt2; + SetCursor(FHitTestCursor); + return TRUE; + + default: + *lResult = 1; + return (ht != HTCLIENT); + } + + case WM_MOUSEMOVE: + + GetWindowRect(hwnd, &rect); + pt = MAKEPOINTS(lParam); pt2.x = pt.x; pt2.y = pt.y; + ClientToScreen(hwnd, &pt2); + + if(FMoveWindow) + { + MoveWindow(hwnd,rect.left+pt2.x-FLastPoint.x,rect.top+pt2.y-FLastPoint.y, + rect.right-rect.left,rect.bottom-rect.top,TRUE); + FLastPoint = pt2; + SetCursor(FHitTestCursor); + return TRUE; + } + else if(FSizeWindow) + { + POINT pt3 = pt2; pt3.x -= FLastPoint.x; pt3.y -= FLastPoint.y; + RECT r2; + r2.left = rect.left + pt3.x*sizerect.left; + r2.top = rect.top + pt3.y*sizerect.top; + r2.right = rect.right + pt3.x*sizerect.right; + r2.bottom = rect.bottom + pt3.y*sizerect.bottom; + if(r2.right - r2.left < 16) + { + r2.right = rect.right; r2.left = rect.left; + } + else FLastPoint.x = pt2.x; + if(r2.bottom - r2.top < 10) + { + r2.bottom = rect.bottom; r2.top = rect.top; + } + else FLastPoint.y = pt2.y; + + MoveWindow(hwnd,r2.left,r2.top,r2.right-r2.left,r2.bottom-r2.top,TRUE); + + SetCursor(FHitTestCursor); + return TRUE; + } + return SendMessage(hwnd, WM_USER_NCHITTEST, 0, MAKELONG(pt2.x, pt2.y)) != HTCLIENT; + + case WM_LBUTTONUP: +// if(FMoveWindow || FSizeWindow) +// { + FMoveWindow = FSizeWindow = FALSE; + ReleaseCapture(); + return TRUE; +// } + +// pt = MAKEPOINTS(lParam); pt2.x = pt.x; pt2.y = pt.y; +// ClientToScreen(hwnd, &pt2); + +// return SendMessage(hwnd, WM_USER_NCHITTEST, 0, MAKELONG(pt2.x, pt2.y)) != HTCLIENT; + } + + return FALSE; +} diff --git a/release/c/cs_pinyin/source/keymanimx/imxlib.h b/release/c/cs_pinyin/source/keymanimx/imxlib.h new file mode 100644 index 0000000000..0f79a46fff --- /dev/null +++ b/release/c/cs_pinyin/source/keymanimx/imxlib.h @@ -0,0 +1,36 @@ + +#ifndef _IMLIB_H +#define _IMLIB_H + +#define QIT_VKEYDOWN 0 +#define QIT_VKEYUP 1 +#define QIT_VSHIFTDOWN 2 +#define QIT_VSHIFTUP 3 +#define QIT_CHAR 4 +#define QIT_DEADKEY 5 +#define QIT_BELL 6 +#define QIT_BACK 7 + +#define WM_USER_NCHITTEST WM_USER+400 + +typedef BOOL (WINAPI *KMSetOutputProc)(PWSTR buf, DWORD backlen); +typedef BOOL (WINAPI *KMGetContextProc)(PWSTR buf, DWORD len); +typedef BOOL (WINAPI *KMQueueActionProc)(int action, DWORD dwData); +typedef BOOL (WINAPI *KMDisplayIMProc)(HWND hwnd, BOOL FStayOpen); +typedef BOOL (WINAPI *KMGetActiveKeyboardProc)(PSTR kbdname, DWORD len); +typedef BOOL (WINAPI *KMHideIMProc)(); +typedef BOOL (WINAPI *KMGetKeyboardPathProc)(PSTR kbdname, PSTR buf, DWORD len); + +extern HMODULE hModuleKeyman32; +extern KMSetOutputProc KMSetOutput; +extern KMGetContextProc KMGetContext; +extern KMQueueActionProc KMQueueAction; +extern KMDisplayIMProc KMDisplayIM; +extern KMHideIMProc KMHideIM; +extern KMGetActiveKeyboardProc KMGetActiveKeyboard; +extern KMGetKeyboardPathProc KMGetKeyboardPath; + +BOOL PrepIM(BOOL Reset); +BOOL IMDefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *lResult); + +#endif diff --git a/release/c/cs_pinyin/source/keymanimx/keymanimx.h b/release/c/cs_pinyin/source/keymanimx/keymanimx.h new file mode 100644 index 0000000000..afa89647a3 --- /dev/null +++ b/release/c/cs_pinyin/source/keymanimx/keymanimx.h @@ -0,0 +1,115 @@ +// Shared header for KeymanIMX, used also by imxconfig + +#define CFXVERSION 1001 // CFX file version + +#define MAXINDEX 72 // max number of characters that can be indexed + +#define MAXRULESFREE 6000 // max number of rules allowed for unregistered Keyman + +#define MAXOUTLEN 64 // required when passing strings to Keyman +#define MAXTAGLEN 15 // will be truncated with ellipsis if longer + +#define HK_LCTRL 1 // hot key shift state bit masks +#define HK_RCTRL 2 +#define HK_LALT 4 +#define HK_RALT 8 +#define HK_SHIFT 16 +#define HK_CTRL (HK_LCTRL+HK_RCTRL) +#define HK_ALT (HK_LALT+HK_RALT) +#define HK_MODIFIERS (HK_SHIFT+HK_CTRL+HK_ALT) + +#define OM_DEFAULT 0 // default output mode +#define OM_TAG 2 // output tag strings +#define OM_BOTH 4 // output both character and tag (parenthesized) + +#define DM_LIMITED 0 // limited display mode +#define DM_FULL 1 // full display mode + +#define WC_QUERY 1 // wild card options +#define WC_STAR 2 +#define WC_QUOTE 4 +#define WC_DASH 8 + +#define EnableDlgItem(hwnd,item) EnableWindow(GetDlgItem((hwnd),(item)),TRUE) +#define DisableDlgItem(hwnd,item) EnableWindow(GetDlgItem((hwnd),(item)),FALSE) +#define ShowDlgItem(hwnd,item) ShowWindow(GetDlgItem((hwnd),(item)),SW_SHOW) +#define HideDlgItem(hwnd,item) ShowWindow(GetDlgItem((hwnd),(item)),SW_HIDE) + +// First character of a string that can be indexed (count must be < MAXINDEX) +#define INDEXSTRING "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*" + +// Location for Registry settings +#define REGSZ_KeymanIMX "Software\\Keyman\\KeymanIMX\\10.0" + +struct RULE +{ + DWORD input,tag,output; + BYTE ilen,tlen,olen,frequency; +}; + +struct TEMPRULE +{ + WCHAR input[32],output[16],tag[32]; +}; + +// Structure to hold all constant parameters and default keyboard options +// dwIndex, dwRules, dwStrings are byte offsets into the memory mapped file +struct KBHEADER +{ + char Flag[4]; // must be KCFX + DWORD dwCfxVersion; // CFX file version + char name[128], ToneChar[16]; + int InputSize, gridx, gridy, nrules; + LOGFONT lfMain, lfInput, lfTag; + DWORD cfgKey, dwWild, dwFKeys, dwOptions; + DWORD dwIndex, dwRules, dwStrings, cbStrings; +}; + +// Structure to hold keyboard parameters, pointers, and local variables +struct KEYBOARD +{ + KBHEADER h; + HANDLE hFile, hMapObject; + LPVOID BaseAddress; // pointer to start of shared mapped memory + DWORD *index; // pointer to start of index (must be corrected for each instance) + RULE *rules; // pointer to start of rule table (ditto) + WCHAR *pst; // pointer to start of string table (ditto) +}; + +// Option bits +#define SELECTIONBITS 3 +#define TONEBITS 12 +#define SELECTIFUNIQUE 16 +#define SHOWDUPLICATES 32 + +enum tagConfig {CFG_NONE=0,CFG_ANSI,CFG_UNICODE,CFG_UTF8}; + +enum tagFontStyle {FS_NONE=0,FS_BOLD,FS_ITALIC,FS_ITALICBOLD,FC_SYMBOL}; + +enum tagSelectionMode {SM_DEFAULT=0,SM_KEYPAD,SM_ALLDIGITS,SM_FKEYS}; + +enum tagToneMode {TM_NEVER=0,TM_ALWAYS,TM_OPTIONAL}; + +enum tagFKeyMode {FK_NONE=0,FK_NORMAL,FK_SHIFT,FK_CTRL,FK_CTRLSHIFT}; + +enum tagMatchMode {MM_NOMATCH=0,MM_START,MM_EXCEPTTONE,MM_MORETHANONE,MM_PERFECT}; + +enum tagErrors {ERR_NONE,ERR_UNKNOWN,ERR_UNREGISTERED,ERR_SHARING,ERR_CFGMISSING,ERR_CFGINVALID}; + +enum tagRegKeys {KEY_KEYMAN=1,KEY_KEYMANDEVELOPER}; + +#define MAXACTIVERULES 12 + +// Default IM Window dimensions +#define IMBORDERS 8 +#define CWBORDERS 6 +#define INPUTWIDTH 42 // this is increased dynamically as needed +#define CELL_X 32 +#define CELL_Y 42 +#define IM_WIDTH (INPUTWIDTH+MAXACTIVERULES*CELL_X+IMBORDERS+CWBORDERS) +#define IM_HEIGHT (CELL_Y+IMBORDERS+CWBORDERS) +#define MAXBMP 15 + +// Surrogate pair output +#define Uni_UTF32ToSurrogate1(ch) (((ch) - 0x10000) / 0x400 + 0xD800) +#define Uni_UTF32ToSurrogate2(ch) (((ch) - 0x10000) % 0x400 + 0xDC00) diff --git a/release/c/cs_pinyin/source/keymanimx/resource.h b/release/c/cs_pinyin/source/keymanimx/resource.h new file mode 100644 index 0000000000..d06d30d124 --- /dev/null +++ b/release/c/cs_pinyin/source/keymanimx/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by KeymanIMX.rc +// +#define IDB_BITMAP1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 114 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1002 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/release/c/cs_pinyin/source/keymanimx/version.rc b/release/c/cs_pinyin/source/keymanimx/version.rc new file mode 100644 index 0000000000..36192bb371 --- /dev/null +++ b/release/c/cs_pinyin/source/keymanimx/version.rc @@ -0,0 +1,51 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" +///////////////////////////////////////////////////////////////////////////// +// English (Australia) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (Australia) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED +