00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include "precomp.h"
00013
#pragma hdrstop
00014
00015 typedef struct tagSELECTCONTEXT_ENUM {
00016 HKL
hSelKL;
00017 HKL
hUnSelKL;
00018 }
SCE, *
PSCE;
00019
00020
00021 BOOL NotifyIMEProc(
00022 HIMC hImc,
00023 LPARAM lParam)
00024 {
00025 UserAssert(lParam == CPS_COMPLETE || lParam == CPS_CANCEL);
00026
ImmNotifyIME(hImc, NI_COMPOSITIONSTR, (
DWORD)lParam, 0);
00027
return TRUE;
00028 }
00029
00030
00031 BOOL SelectContextProc(
00032 HIMC hImc,
00033 PSCE psce)
00034 {
00035
SelectInputContext(psce->
hSelKL, psce->
hUnSelKL, hImc);
00036
return TRUE;
00037 }
00038
00039
00040 BOOL InquireIme(
00041
PIMEDPI pImeDpi)
00042 {
00043 WNDCLASS wc;
00044
BYTE ClassName[
IM_UI_CLASS_SIZE *
sizeof(WCHAR)];
00045
DWORD dwSystemInfoFlags;
00046 PIMEINFO pImeInfo = &pImeDpi->
ImeInfo;
00047
00048 dwSystemInfoFlags = (
NtUserGetThreadState(UserThreadStateIsWinlogonThread))
00049 ? IME_SYSINFO_WINLOGON : 0;
00050
00051
if (
GetClientInfo()->dwTIFlags &
TIF_16BIT)
00052 dwSystemInfoFlags |= IME_SYSINFO_WOW16;
00053
00054 (*pImeDpi->
pfn.
ImeInquire.w)(pImeInfo, (PVOID)ClassName, dwSystemInfoFlags);
00055
00056
00057
00058
00059
if (pImeInfo->dwPrivateDataSize == 0)
00060 pImeInfo->dwPrivateDataSize =
sizeof(
UINT);
00061
00062
if (pImeInfo->fdwProperty & ~(IME_PROP_ALL)) {
00063 RIPMSG0(RIP_WARNING,
"wrong property");
00064
return FALSE;
00065 }
00066
00067
if (pImeInfo->fdwConversionCaps & ~(IME_CMODE_ALL)) {
00068 RIPMSG0(RIP_WARNING,
"wrong conversion capabilities");
00069
return FALSE;
00070 }
00071
00072
if (pImeInfo->fdwSentenceCaps & ~(IME_SMODE_ALL)) {
00073 RIPMSG0(RIP_WARNING,
"wrong sentence capabilities");
00074
return FALSE;
00075 }
00076
00077
if (pImeInfo->fdwUICaps & ~(UI_CAP_ALL)) {
00078 RIPMSG0(RIP_WARNING,
"wrong UI capabilities");
00079
return FALSE;
00080 }
00081
00082
if (pImeInfo->fdwSCSCaps & ~(SCS_CAP_ALL)) {
00083 RIPMSG0(RIP_WARNING,
"wrong set comp string capabilities");
00084
return FALSE;
00085 }
00086
00087
if (pImeInfo->fdwSelectCaps & ~(SELECT_CAP_ALL)) {
00088 RIPMSG0(RIP_WARNING,
"wrong select capabilities");
00089
return FALSE;
00090 }
00091
00092
if (!(pImeInfo->fdwProperty & IME_PROP_UNICODE)) {
00093
00094
00095
00096
00097
00098
if (pImeDpi->
dwCodePage != GetACP() && pImeDpi->
dwCodePage != CP_ACP) {
00099
00100
00101 RIPMSG1(RIP_WARNING,
"incompatible codepage(%d) for ANSI IME", pImeDpi->
dwCodePage);
00102
return FALSE;
00103 }
00104
00105
00106
00107
00108 MultiByteToWideChar(
IMECodePage(pImeDpi),
00109 (
DWORD)MB_PRECOMPOSED,
00110 (LPSTR)ClassName,
00111 (
INT)-1,
00112 pImeDpi->
wszUIClass,
00113
IM_UI_CLASS_SIZE);
00114 }
else {
00115 RtlCopyMemory(pImeDpi->
wszUIClass, ClassName,
sizeof(ClassName));
00116 }
00117 pImeDpi->
wszUIClass[
IM_UI_CLASS_SIZE-1] =
L'\0';
00118
00119
if (!GetClassInfoW((HINSTANCE)pImeDpi->
hInst, pImeDpi->
wszUIClass, &wc)) {
00120 RIPMSG1(RIP_WARNING,
"UI class (%ws) not found in this IME", pImeDpi->
wszUIClass);
00121
return FALSE;
00122 }
else if (wc.cbWndExtra <
sizeof(
DWORD) * 2) {
00123 RIPMSG0(RIP_WARNING,
"UI class cbWndExtra problem");
00124
return FALSE;
00125 }
00126
00127
return TRUE;
00128 }
00129
00130
00131 BOOL LoadIME(
00132
PIMEINFOEX piiex,
00133
PIMEDPI pImeDpi)
00134 {
00135 WCHAR wszImeFile[
MAX_PATH];
00136
BOOL fSuccess;
00137
00138
GetSystemPathName(wszImeFile, piiex->
wszImeFile,
MAX_PATH);
00139
00140 pImeDpi->
hInst = LoadLibraryW(wszImeFile);
00141
00142
if (!pImeDpi->
hInst) {
00143 RIPMSG1(RIP_WARNING,
"LoadIME: LoadLibraryW(%ws) failed", wszImeFile);
00144
goto LoadIME_ErrOut;
00145 }
00146
00147
#define GET_IMEPROCT(x) \
00148
if (!(pImeDpi->pfn.##x.t = (PVOID) GetProcAddress(pImeDpi->hInst, #x))) { \
00149
RIPMSG1(RIP_WARNING, "LoadIME: " #x " not supported in %ws", wszImeFile); \
00150
goto LoadIME_ErrOut; }
00151
00152
#define GET_IMEPROC(x) \
00153
if (!(pImeDpi->pfn.##x = (PVOID) GetProcAddress(pImeDpi->hInst, #x))) { \
00154
RIPMSG1(RIP_WARNING, "LoadIME: " #x " not supported in %ws", wszImeFile); \
00155
goto LoadIME_ErrOut; }
00156
00157
GET_IMEPROCT(ImeInquire);
00158
GET_IMEPROCT(ImeConversionList);
00159
GET_IMEPROCT(ImeRegisterWord);
00160
GET_IMEPROCT(ImeUnregisterWord);
00161
GET_IMEPROCT(ImeGetRegisterWordStyle);
00162
GET_IMEPROCT(ImeEnumRegisterWord);
00163
GET_IMEPROC (ImeConfigure);
00164
GET_IMEPROC (ImeDestroy);
00165
GET_IMEPROC (ImeEscape);
00166
GET_IMEPROC (ImeProcessKey);
00167
GET_IMEPROC (ImeSelect);
00168
GET_IMEPROC (ImeSetActiveContext);
00169
GET_IMEPROC (ImeToAsciiEx);
00170
GET_IMEPROC (NotifyIME);
00171
GET_IMEPROC (ImeSetCompositionString);
00172
00173
00174 pImeDpi->
pfn.
ImeGetImeMenuItems = (PVOID)GetProcAddress(pImeDpi->
hInst,
"ImeGetImeMenuItems");
00175
00176
#undef GET_IMEPROCT
00177
#undef GET_IMEPROC
00178
00179
if (!
InquireIme(pImeDpi)) {
00180 RIPMSG0(RIP_WARNING,
"LoadIME: InquireIme failed");
00181 LoadIME_ErrOut:
00182 FreeLibrary(pImeDpi->
hInst);
00183 pImeDpi->
hInst =
NULL;
00184 fSuccess =
FALSE;
00185 }
00186
else {
00187 fSuccess =
TRUE;
00188 }
00189
00190
00191
00192
00193
00194
if (piiex->
fLoadFlag ==
IMEF_NONLOAD) {
00195
if (fSuccess) {
00196 RtlCopyMemory((
PBYTE)&piiex->
ImeInfo,
00197 (
PBYTE)&pImeDpi->
ImeInfo,
sizeof(IMEINFO));
00198 RtlCopyMemory((
PBYTE)piiex->
wszUIClass,
00199 (
PBYTE)pImeDpi->
wszUIClass,
sizeof(pImeDpi->
wszUIClass));
00200 piiex->
fLoadFlag =
IMEF_LOADED;
00201 }
00202
else {
00203 piiex->
fLoadFlag =
IMEF_LOADERROR;
00204 }
00205
NtUserSetImeInfoEx(piiex);
00206 }
00207
00208
return fSuccess;
00209 }
00210
00211
00212 VOID UnloadIME(
00213
PIMEDPI pImeDpi,
00214 BOOL fTerminateIme)
00215 {
00216
if (pImeDpi->
hInst ==
NULL) {
00217 RIPMSG0(RIP_WARNING,
"UnloadIME: No IME's hInst.");
00218
return;
00219 }
00220
00221
if (fTerminateIme) {
00222
00223
00224
00225 (*pImeDpi->
pfn.
ImeDestroy)(0);
00226 }
00227
00228 FreeLibrary(pImeDpi->
hInst);
00229 pImeDpi->
hInst =
NULL;
00230
00231
return;
00232 }
00233
00234 PIMEDPI LoadImeDpi(
00235 HKL hKL,
00236 BOOL fLock)
00237 {
00238
PIMEDPI pImeDpi, pImeDpiT;
00239
IMEINFOEX iiex;
00240
00241
00242
00243
00244
if (!
ImmGetImeInfoEx(&iiex,
ImeInfoExKeyboardLayout, &hKL)) {
00245 RIPMSG1(RIP_WARNING,
"LoadImeDpi: ImmGetImeInfoEx(%lx) failed", hKL);
00246
return NULL;
00247 }
00248
00249
00250
00251
00252
00253
if (iiex.
fLoadFlag ==
IMEF_LOADERROR)
00254
return NULL;
00255
00256
00257
00258
00259 pImeDpi = (
PIMEDPI)
ImmLocalAlloc(HEAP_ZERO_MEMORY,
sizeof(
IMEDPI));
00260
if (pImeDpi ==
NULL)
00261
return NULL;
00262
00263 pImeDpi->
hKL = hKL;
00264
00265
00266 {
00267 CHARSETINFO cs;
00268
if (TranslateCharsetInfo((
DWORD*)LOWORD(HandleToUlong(hKL)), &cs, TCI_SRCLOCALE)) {
00269 pImeDpi->
dwCodePage = cs.ciACP;
00270 }
00271
else {
00272 pImeDpi->
dwCodePage = CP_ACP;
00273 }
00274 }
00275
00276
00277
00278
00279
if (!
LoadIME(&iiex, pImeDpi)) {
00280
ImmLocalFree(pImeDpi);
00281
return NULL;
00282 }
00283
00284
00285
00286
00287 RtlEnterCriticalSection(&
gcsImeDpi);
00288
00289 pImeDpiT =
ImmGetImeDpi(hKL);
00290
00291
if (pImeDpiT ==
NULL) {
00292
if (fLock) {
00293
00294
00295
00296 pImeDpi->
cLock = 1;
00297 pImeDpi->
dwFlag |=
IMEDPI_UNLOCKUNLOAD;
00298 }
00299
00300
00301
00302
00303 pImeDpi->
pNext =
gpImeDpi;
00304
gpImeDpi = pImeDpi;
00305
00306 RtlLeaveCriticalSection(&
gcsImeDpi);
00307 }
00308
else {
00309
00310
if (!fLock) {
00311 pImeDpiT->
dwFlag &= ~
IMEDPI_UNLOCKUNLOAD;
00312 }
00313
00314
00315
00316
00317 RtlLeaveCriticalSection(&
gcsImeDpi);
00318
UnloadIME(pImeDpi,
FALSE);
00319
ImmLocalFree(pImeDpi);
00320 pImeDpi = pImeDpiT;
00321 }
00322
00323
return pImeDpi;
00324 }
00325
00326
00327 PIMEDPI FindOrLoadImeDpi(
00328 HKL hKL)
00329 {
00330
PIMEDPI pImeDpi;
00331
00332
00333
00334
00335
if (!
IS_IME_KBDLAYOUT(hKL))
00336
return (
PIMEDPI)
NULL;
00337
00338 pImeDpi =
ImmLockImeDpi(hKL);
00339
if (pImeDpi ==
NULL)
00340 pImeDpi =
LoadImeDpi(hKL,
TRUE);
00341
00342
return pImeDpi;
00343 }
00344
00345
00346 BOOL WINAPI
ImmLoadIME(
00347 HKL hKL)
00348 {
00349
PIMEDPI pImeDpi;
00350
00351
00352
00353
00354
if (!
IS_IME_KBDLAYOUT(hKL))
00355
return FALSE;
00356
00357 pImeDpi =
ImmGetImeDpi(hKL);
00358
if (pImeDpi ==
NULL)
00359 pImeDpi =
LoadImeDpi(hKL,
FALSE);
00360
00361
return (pImeDpi !=
NULL);
00362 }
00363
00364
00365 BOOL WINAPI
ImmUnloadIME(
00366 HKL hKL)
00367 {
00368
PIMEDPI pImeDpi, pImeDpiT;
00369
00370 RtlEnterCriticalSection(&
gcsImeDpi);
00371
00372 pImeDpi =
gpImeDpi;
00373
00374
while (pImeDpi !=
NULL && pImeDpi->
hKL != hKL)
00375 pImeDpi = pImeDpi->
pNext;
00376
00377
if (pImeDpi ==
NULL) {
00378 RtlLeaveCriticalSection(&
gcsImeDpi);
00379
return TRUE;
00380 }
00381
else if (pImeDpi->
cLock != 0) {
00382 pImeDpi->
dwFlag |=
IMEDPI_UNLOADED;
00383 RtlLeaveCriticalSection(&
gcsImeDpi);
00384
return FALSE;
00385 }
00386
00387
00388
00389
00390
if (
gpImeDpi == pImeDpi) {
00391
gpImeDpi = pImeDpi->
pNext;
00392 }
00393
else {
00394 pImeDpiT =
gpImeDpi;
00395
00396
while (pImeDpiT !=
NULL && pImeDpiT->
pNext != pImeDpi)
00397 pImeDpiT = pImeDpiT->
pNext;
00398
00399
if (pImeDpiT !=
NULL)
00400 pImeDpiT->
pNext = pImeDpi->
pNext;
00401 }
00402
00403
00404
00405
00406
UnloadIME(pImeDpi,
TRUE);
00407
00408
ImmLocalFree(pImeDpi);
00409
00410 RtlLeaveCriticalSection(&
gcsImeDpi);
00411
00412
return TRUE;
00413 }
00414
00415
00416 BOOL WINAPI
ImmFreeLayout(
00417 DWORD dwFlag)
00418 {
00419
PIMEDPI pImeDpi;
00420 HKL *phklRoot, hklCurrent;
00421 WCHAR pwszNonImeKLID[KL_NAMELENGTH];
00422
UINT nLayouts, uNonImeKLID = 0, i;
00423
00424 hklCurrent =
GetKeyboardLayout(0);
00425
00426
switch (dwFlag) {
00427
00428
case IFL_DEACTIVATEIME:
00429
00430
00431
00432
if (!
IS_IME_KBDLAYOUT(hklCurrent))
00433
return TRUE;
00434
00435
00436
00437
00438
00439 uNonImeKLID = (
UINT)LANGIDFROMLCID(GetSystemDefaultLCID());
00440
00441 nLayouts = GetKeyboardLayoutList(0,
NULL);
00442
00443
if (nLayouts != 0) {
00444 phklRoot =
ImmLocalAlloc(0, nLayouts *
sizeof(HKL));
00445
if (phklRoot ==
NULL)
00446
return FALSE;
00447
00448 nLayouts = GetKeyboardLayoutList(nLayouts, phklRoot);
00449
00450
for (i = 0; i < nLayouts &&
IS_IME_KBDLAYOUT(phklRoot[i]); i++) ;
00451
00452
if (i < nLayouts)
00453 uNonImeKLID = HandleToUlong(phklRoot[i]) & 0xffff;
00454
00455
ImmLocalFree(phklRoot);
00456 }
00457
00458 wsprintf(pwszNonImeKLID,
L"%08x", uNonImeKLID);
00459
00460
if (
LoadKeyboardLayoutW(pwszNonImeKLID, KLF_ACTIVATE) ==
NULL) {
00461 RIPMSG1(RIP_WARNING,
"ImmFreeLayout: LoadKeyboardLayoutW(%S, KLF_ACTIVATE) failed. Trying 00000409", pwszNonImeKLID);
00462
00463
00464
if (
LoadKeyboardLayoutW(
L"00000409", KLF_ACTIVATE | KLF_FAILSAFE) ==
NULL) {
00465 RIPMSG0(RIP_WARNING,
"LoadKeyboardLayoutW(00000409) failed either. will try NULL.");
00466 }
00467 }
00468
00469
break;
00470
00471
case IFL_UNLOADIME:
00472 RtlEnterCriticalSection(&
gcsImeDpi);
00473 UnloadImeDpiLoop:
00474
for (pImeDpi =
gpImeDpi; pImeDpi !=
NULL; pImeDpi = pImeDpi->
pNext) {
00475
if (
ImmUnloadIME(pImeDpi->
hKL))
00476
goto UnloadImeDpiLoop;
00477 }
00478 RtlLeaveCriticalSection(&
gcsImeDpi);
00479
break;
00480
00481
default:
00482 {
00483 HKL hklFlag = (HKL)LongToHandle( dwFlag );
00484
if (
IS_IME_KBDLAYOUT(hklFlag) && hklFlag != hklCurrent) {
00485
ImmUnloadIME(hklFlag);
00486 }
00487 }
00488
break;
00489 }
00490
00491
return TRUE;
00492 }
00493
00494
00495 BOOL WINAPI
ImmActivateLayout(
00496 HKL hSelKL)
00497 {
00498 HKL hUnSelKL;
00499 HWND hWndDefaultIme;
00500
SCE sce;
00501
DWORD dwCPS;
00502
PIMEDPI pImeDpi;
00503 BOOLEAN fOptimizeActivation =
TRUE;
00504
00505 hUnSelKL =
GetKeyboardLayout(0);
00506
00507 {
00508
PCLIENTINFO pClientInfo =
GetClientInfo();
00509
00510
if (pClientInfo->
CI_flags &
CI_INPUTCONTEXT_REINIT) {
00511 fOptimizeActivation =
FALSE;
00512 }
00513 }
00514
00515
00516
00517
00518
if (hUnSelKL == hSelKL && fOptimizeActivation)
00519
return TRUE;
00520
00521
ImmLoadIME(hSelKL);
00522
00523
if (hUnSelKL != hSelKL) {
00524 pImeDpi =
ImmLockImeDpi(hUnSelKL);
00525
if (pImeDpi !=
NULL) {
00526
00527
00528
00529
00530
00531
00532 dwCPS = (pImeDpi->
ImeInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT) ? CPS_COMPLETE : CPS_CANCEL;
00533
ImmUnlockImeDpi(pImeDpi);
00534
ImmEnumInputContext(0,
NotifyIMEProc, dwCPS);
00535 }
00536
00537 hWndDefaultIme =
ImmGetDefaultIMEWnd(
NULL);
00538
00539
if (
IsWindow(hWndDefaultIme))
00540
SendMessage(hWndDefaultIme, WM_IME_SELECT,
FALSE, (LPARAM)hUnSelKL);
00541
00542
00543
00544
00545
00546
NtUserSetThreadLayoutHandles(hSelKL, hUnSelKL);
00547 }
00548
00549
00550
00551
00552 sce.
hSelKL = hSelKL;
00553 sce.
hUnSelKL = hUnSelKL;
00554
ImmEnumInputContext(0, (IMCENUMPROC)
SelectContextProc, (LPARAM)&sce);
00555
00556
00557
00558
00559
if (
IsWindow(hWndDefaultIme))
00560
SendMessage(hWndDefaultIme, WM_IME_SELECT,
TRUE, (LPARAM)hSelKL);
00561
00562
return (
TRUE);
00563 }
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 BOOL WINAPI
ImmConfigureIMEA(
00576 HKL hKL,
00577 HWND hWnd,
00578 DWORD dwMode,
00579 LPVOID lpData)
00580 {
00581
PWND pWnd;
00582
PIMEDPI pImeDpi;
00583
BOOL fRet =
FALSE;
00584
00585
if ((pWnd =
ValidateHwnd(
hWnd)) == (
PWND)
NULL) {
00586 RIPMSG1(RIP_WARNING,
00587
"ImmConfigureIMEA: invalid window handle %x",
hWnd);
00588
return FALSE;
00589 }
00590
00591
if (!
TestWindowProcess(pWnd)) {
00592 RIPMSG1(RIP_WARNING,
00593
"ImmConfigureIMEA: hWnd=%lx belongs to different process!",
hWnd);
00594
return FALSE;
00595 }
00596
00597 pImeDpi =
FindOrLoadImeDpi(hKL);
00598
if (pImeDpi ==
NULL) {
00599 RIPMSG0(RIP_WARNING,
"ImmConfigureIMEA: no pImeDpi entry.");
00600
return FALSE;
00601 }
00602
00603
if (!(pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE) || lpData ==
NULL) {
00604
00605
00606
00607
00608
00609
SendMessage(
hWnd, WM_IME_SYSTEM, IMS_OPENPROPERTYWINDOW, 0
L);
00610 fRet = (*pImeDpi->
pfn.
ImeConfigure)(hKL,
hWnd, dwMode, lpData);
00611
00612
SendMessage(
hWnd, WM_IME_SYSTEM, IMS_CLOSEPROPERTYWINDOW, 0
L);
00613
ImmUnlockImeDpi(pImeDpi);
00614
return fRet;
00615 }
00616
00617
00618
00619
00620
00621
00622
switch (dwMode) {
00623
case IME_CONFIG_REGISTERWORD:
00624 {
00625 LPREGISTERWORDA lpRegisterWordA;
00626 REGISTERWORDW RegisterWordW;
00627
LPVOID lpBuffer;
00628 ULONG cbBuffer;
00629
INT i;
00630
00631 lpRegisterWordA = (LPREGISTERWORDA)lpData;
00632 cbBuffer = 0;
00633 lpBuffer =
NULL;
00634
00635
if (lpRegisterWordA->lpReading !=
NULL)
00636 cbBuffer +=
strlen(lpRegisterWordA->lpReading) + 1;
00637
00638
if (lpRegisterWordA->lpWord !=
NULL)
00639 cbBuffer +=
strlen(lpRegisterWordA->lpWord) + 1;
00640
00641
if (cbBuffer != 0) {
00642 cbBuffer *=
sizeof(WCHAR);
00643
if ((lpBuffer =
ImmLocalAlloc(0, cbBuffer)) ==
NULL) {
00644 RIPMSG0(RIP_WARNING,
"ImmConfigureIMEA: memory failure.");
00645
break;
00646 }
00647 }
00648
00649
if (lpRegisterWordA->lpReading !=
NULL) {
00650 RegisterWordW.lpReading = lpBuffer;
00651 i = MultiByteToWideChar(
IMECodePage(pImeDpi),
00652 (
DWORD)MB_PRECOMPOSED,
00653 (LPSTR)lpRegisterWordA->lpReading,
00654 (
INT)
strlen(lpRegisterWordA->lpReading),
00655 (LPWSTR)RegisterWordW.lpReading,
00656 (
INT)(cbBuffer/
sizeof(WCHAR)));
00657 RegisterWordW.lpReading[i] =
L'\0';
00658 cbBuffer -= (i *
sizeof(WCHAR));
00659 }
00660
else {
00661 RegisterWordW.lpReading =
NULL;
00662 }
00663
00664
if (lpRegisterWordA->lpWord !=
NULL) {
00665
if (RegisterWordW.lpReading !=
NULL)
00666 RegisterWordW.lpWord = &RegisterWordW.lpReading[i+1];
00667
else
00668 RegisterWordW.lpWord = lpBuffer;
00669 i = MultiByteToWideChar(
IMECodePage(pImeDpi),
00670 (
DWORD)MB_PRECOMPOSED,
00671 (LPSTR)lpRegisterWordA->lpWord,
00672 (
INT)
strlen(lpRegisterWordA->lpWord),
00673 (LPWSTR)RegisterWordW.lpWord,
00674 (
INT)(cbBuffer/
sizeof(WCHAR)));
00675 RegisterWordW.lpWord[i] =
L'\0';
00676 }
00677
else
00678 RegisterWordW.lpWord =
NULL;
00679
00680 fRet =
ImmConfigureIMEW(hKL,
hWnd, dwMode, &RegisterWordW);
00681
00682
if (lpBuffer !=
NULL)
00683
ImmLocalFree(lpBuffer);
00684
00685
break;
00686 }
00687
default:
00688 fRet =
ImmConfigureIMEW(hKL,
hWnd, dwMode, lpData);
00689
break;
00690 }
00691
00692
ImmUnlockImeDpi(pImeDpi);
00693
00694
return fRet;
00695 }
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 BOOL WINAPI
ImmConfigureIMEW(
00708 HKL hKL,
00709 HWND hWnd,
00710 DWORD dwMode,
00711 LPVOID lpData)
00712 {
00713
PWND pWnd;
00714
PIMEDPI pImeDpi;
00715
BOOL fRet =
FALSE;
00716
00717
if ((pWnd =
ValidateHwnd(
hWnd)) == (
PWND)
NULL) {
00718 RIPMSG1(RIP_WARNING,
00719
"ImmConfigureIMEA: invalid window handle %x",
hWnd);
00720
return FALSE;
00721 }
00722
00723
if (!
TestWindowProcess(pWnd)) {
00724 RIPMSG1(RIP_WARNING,
00725
"ImmConfigureIMEA: hWnd=%lx belongs to different process!",
hWnd);
00726
return FALSE;
00727 }
00728
00729 pImeDpi =
FindOrLoadImeDpi(hKL);
00730
if (pImeDpi ==
NULL) {
00731 RIPMSG0(RIP_WARNING,
"ImmConfigureIMEA: no pImeDpi entry.");
00732
return FALSE;
00733 }
00734
00735
if ((pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE) || lpData ==
NULL) {
00736
00737
00738
00739
00740
00741
SendMessage(
hWnd, WM_IME_SYSTEM, IMS_OPENPROPERTYWINDOW, 0
L);
00742 fRet = (*pImeDpi->
pfn.
ImeConfigure)(hKL,
hWnd, dwMode, lpData);
00743
00744
SendMessage(
hWnd, WM_IME_SYSTEM, IMS_CLOSEPROPERTYWINDOW, 0
L);
00745
ImmUnlockImeDpi(pImeDpi);
00746
return fRet;
00747 }
00748
00749
00750
00751
00752
00753
00754
switch (dwMode) {
00755
case IME_CONFIG_REGISTERWORD:
00756 {
00757 LPREGISTERWORDW lpRegisterWordW;
00758 REGISTERWORDA RegisterWordA;
00759
LPVOID lpBuffer;
00760 ULONG cbBuffer;
00761
BOOL bUDC;
00762
INT i;
00763
00764 lpRegisterWordW = (LPREGISTERWORDW)lpData;
00765 cbBuffer = 0;
00766 lpBuffer =
NULL;
00767
00768
if (lpRegisterWordW->lpReading !=
NULL)
00769 cbBuffer += wcslen(lpRegisterWordW->lpReading) + 1;
00770
00771
if (lpRegisterWordW->lpWord !=
NULL)
00772 cbBuffer += wcslen(lpRegisterWordW->lpWord) + 1;
00773
00774
if (cbBuffer != 0) {
00775 cbBuffer *=
sizeof(WCHAR);
00776
if ((lpBuffer =
ImmLocalAlloc(0, cbBuffer)) ==
NULL) {
00777 RIPMSG0(RIP_WARNING,
"ImmConfigureIMEW: memory failure.");
00778
break;
00779 }
00780 }
00781
00782
if (lpRegisterWordW->lpReading !=
NULL) {
00783 RegisterWordA.lpReading = lpBuffer;
00784 i = WideCharToMultiByte(
IMECodePage(pImeDpi),
00785 (
DWORD)0,
00786 (LPWSTR)lpRegisterWordW->lpReading,
00787 (
INT)wcslen(lpRegisterWordW->lpReading),
00788 (LPSTR)RegisterWordA.lpReading,
00789 (
INT)cbBuffer,
00790 (LPSTR)
NULL,
00791 (LPBOOL)&bUDC);
00792 RegisterWordA.lpReading[i] =
'\0';
00793 cbBuffer -= (i *
sizeof(
CHAR));
00794 }
00795
else {
00796 RegisterWordA.lpReading =
NULL;
00797 }
00798
00799
if (lpRegisterWordW->lpWord !=
NULL) {
00800
if (RegisterWordA.lpReading !=
NULL)
00801 RegisterWordA.lpWord = &RegisterWordA.lpReading[i+1];
00802
else
00803 RegisterWordA.lpWord = lpBuffer;
00804 i = WideCharToMultiByte(
IMECodePage(pImeDpi),
00805 (
DWORD)0,
00806 (LPWSTR)lpRegisterWordW->lpWord,
00807 (
INT)wcslen(lpRegisterWordW->lpWord),
00808 (LPSTR)RegisterWordA.lpWord,
00809 (
INT)cbBuffer,
00810 (LPSTR)
NULL,
00811 (LPBOOL)&bUDC);
00812 RegisterWordA.lpWord[i] =
'\0';
00813 }
00814
else
00815 RegisterWordA.lpWord =
NULL;
00816
00817 fRet =
ImmConfigureIMEA(hKL,
hWnd, dwMode, &RegisterWordA);
00818
00819
if (lpBuffer !=
NULL)
00820
ImmLocalFree(lpBuffer);
00821
00822
break;
00823 }
00824
default:
00825 fRet =
ImmConfigureIMEA(hKL,
hWnd, dwMode, lpData);
00826
break;
00827 }
00828
00829
ImmUnlockImeDpi(pImeDpi);
00830
00831
return fRet;
00832 }
00833
00834
00835 #define IME_T_EUDC_DIC_SIZE 80 // the Traditional Chinese EUDC dictionary
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 LRESULT WINAPI
ImmEscapeA(
00850 HKL hKL,
00851 HIMC hImc,
00852 UINT uSubFunc,
00853 LPVOID lpData)
00854 {
00855
PIMEDPI pImeDpi;
00856 LRESULT lRet = 0;
00857
00858 pImeDpi =
FindOrLoadImeDpi(hKL);
00859
if (pImeDpi ==
NULL) {
00860 RIPMSG0(RIP_WARNING,
"ImmEscapeA: no pImeDpi entry.");
00861
return lRet;
00862 }
00863
00864
if ((pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE) == 0 || lpData ==
NULL) {
00865
00866
00867
00868
00869 lRet = (*pImeDpi->
pfn.
ImeEscape)(hImc, uSubFunc, lpData);
00870
ImmUnlockImeDpi(pImeDpi);
00871
return lRet;
00872 }
00873
00874
00875
00876
00877
00878
switch (uSubFunc) {
00879
case IME_ESC_GET_EUDC_DICTIONARY:
00880
case IME_ESC_IME_NAME:
00881
case IME_ESC_GETHELPFILENAME:
00882 {
00883 WCHAR wszData[
IME_T_EUDC_DIC_SIZE];
00884
BOOL bUDC;
00885
INT i;
00886
00887 lRet =
ImmEscapeW(hKL, hImc, uSubFunc, (
LPVOID)wszData);
00888
00889
if (lRet != 0) {
00890
00891
try {
00892 i = WideCharToMultiByte(
IMECodePage(pImeDpi),
00893 (
DWORD)0,
00894 (LPWSTR)wszData,
00895 (
INT)wcslen(wszData),
00896 (LPSTR)lpData,
00897 (
INT)
IME_T_EUDC_DIC_SIZE,
00898 (LPSTR)
NULL,
00899 (LPBOOL)&bUDC);
00900 ((LPSTR)lpData)[i] =
'\0';
00901 }
00902 except (
EXCEPTION_EXECUTE_HANDLER) {
00903 lRet = 0;
00904 }
00905 }
00906
00907
break;
00908 }
00909
00910
case IME_ESC_SET_EUDC_DICTIONARY:
00911
case IME_ESC_HANJA_MODE:
00912 {
00913 WCHAR wszData[
IME_T_EUDC_DIC_SIZE];
00914
INT i;
00915
00916 i = MultiByteToWideChar(
IMECodePage(pImeDpi),
00917 (
DWORD)MB_PRECOMPOSED,
00918 (LPSTR)lpData,
00919 (
INT)
strlen(lpData),
00920 (LPWSTR)wszData,
00921 (
INT)
sizeof(wszData)/
sizeof(WCHAR));
00922 wszData[i] =
L'\0';
00923
00924 lRet =
ImmEscapeW(hKL, hImc, uSubFunc, (
LPVOID)wszData);
00925
00926
break;
00927 }
00928
00929
case IME_ESC_SEQUENCE_TO_INTERNAL:
00930 {
00931
CHAR szData[4];
00932 WCHAR wszData[4];
00933
INT i = 0;
00934
00935 lRet =
ImmEscapeW(hKL, hImc, uSubFunc, lpData);
00936
00937
if (HIWORD(lRet))
00938 wszData[i++] = HIWORD(lRet);
00939
00940
if (LOWORD(lRet))
00941 wszData[i++] = LOWORD(lRet);
00942
00943 i = WideCharToMultiByte(
IMECodePage(pImeDpi),
00944 (
DWORD)0,
00945 (LPWSTR)wszData,
00946 (
INT)i,
00947 (LPSTR)szData,
00948 (
INT)
sizeof(szData),
00949 (LPSTR)
NULL,
00950 (LPBOOL)
NULL);
00951
00952
switch (i) {
00953
case 1:
00954 lRet = MAKELONG(MAKEWORD(szData[0], 0), 0);
00955
break;
00956
00957
case 2:
00958 lRet = MAKELONG(MAKEWORD(szData[1], szData[0]), 0);
00959
break;
00960
00961
case 3:
00962 lRet = MAKELONG(MAKEWORD(szData[2], szData[1]), MAKEWORD(szData[0], 0));
00963
break;
00964
00965
case 4:
00966 lRet = MAKELONG(MAKEWORD(szData[3], szData[2]), MAKEWORD(szData[1], szData[0]));
00967
break;
00968
00969
default:
00970 lRet = 0;
00971
break;
00972 }
00973
00974
break;
00975 }
00976
default:
00977 lRet =
ImmEscapeW(hKL, hImc, uSubFunc, lpData);
00978
break;
00979 }
00980
00981
ImmUnlockImeDpi(pImeDpi);
00982
00983
return lRet;
00984 }
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999 LRESULT WINAPI
ImmEscapeW(
01000 HKL hKL,
01001 HIMC hImc,
01002 UINT uSubFunc,
01003 LPVOID lpData)
01004 {
01005
PIMEDPI pImeDpi;
01006 LRESULT lRet = 0;
01007
01008 pImeDpi =
FindOrLoadImeDpi(hKL);
01009
if (pImeDpi ==
NULL) {
01010 RIPMSG0(RIP_WARNING,
"ImmEscapeW: no pImeDpi entry.");
01011
return lRet;
01012 }
01013
01014
if ((pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE) || lpData ==
NULL) {
01015
01016
01017
01018
01019 lRet = (*pImeDpi->
pfn.
ImeEscape)(hImc, uSubFunc, lpData);
01020
ImmUnlockImeDpi(pImeDpi);
01021
return lRet;
01022 }
01023
01024
01025
01026
01027
01028
switch (uSubFunc) {
01029
case IME_ESC_GET_EUDC_DICTIONARY:
01030
case IME_ESC_IME_NAME:
01031
case IME_ESC_GETHELPFILENAME:
01032 {
01033
CHAR szData[
IME_T_EUDC_DIC_SIZE];
01034
INT i;
01035
01036 lRet =
ImmEscapeA(hKL, hImc, uSubFunc, (
LPVOID)szData);
01037
01038
if (lRet != 0) {
01039
01040
try {
01041 i = MultiByteToWideChar(
IMECodePage(pImeDpi),
01042 (
DWORD)MB_PRECOMPOSED,
01043 (LPSTR)szData,
01044 (
INT)
strlen(szData),
01045 (LPWSTR)lpData,
01046 (
INT)
IME_T_EUDC_DIC_SIZE);
01047 ((LPWSTR)lpData)[i] =
L'\0';
01048 }
01049 except (
EXCEPTION_EXECUTE_HANDLER) {
01050 lRet = 0;
01051 }
01052 }
01053
01054
break;
01055 }
01056
01057
case IME_ESC_SET_EUDC_DICTIONARY:
01058
case IME_ESC_HANJA_MODE:
01059 {
01060
CHAR szData[
IME_T_EUDC_DIC_SIZE];
01061
BOOL bUDC;
01062
INT i;
01063
01064 i = WideCharToMultiByte(
IMECodePage(pImeDpi),
01065 (
DWORD)0,
01066 (LPWSTR)lpData,
01067 (
INT)wcslen(lpData),
01068 (LPSTR)szData,
01069 (
INT)
sizeof(szData),
01070 (LPSTR)
NULL,
01071 (LPBOOL)&bUDC);
01072 szData[i] =
'\0';
01073
01074 lRet =
ImmEscapeA(hKL, hImc, uSubFunc, (
LPVOID)szData);
01075
01076
break;
01077 }
01078
01079
case IME_ESC_SEQUENCE_TO_INTERNAL:
01080 {
01081
CHAR szData[4];
01082 WCHAR wszData[4];
01083
INT i = 0;
01084
01085 lRet =
ImmEscapeA(hKL, hImc, uSubFunc, lpData);
01086
01087
if (
HIBYTE(LOWORD(lRet)))
01088 szData[i++] =
HIBYTE(LOWORD(lRet));
01089
01090
if (
LOBYTE(LOWORD(lRet)))
01091 szData[i++] =
LOBYTE(LOWORD(lRet));
01092
01093 i = MultiByteToWideChar(
IMECodePage(pImeDpi),
01094 (
DWORD)MB_PRECOMPOSED,
01095 (LPSTR)szData,
01096 i,
01097 (LPWSTR)wszData,
01098 (
INT)
sizeof(wszData)/
sizeof(WCHAR));
01099
01100
switch (i) {
01101
case 1:
01102 lRet = MAKELONG(wszData[0], 0);
01103
break;
01104
01105
case 2:
01106 lRet = MAKELONG(wszData[1], wszData[0]);
01107
break;
01108
01109
default:
01110 lRet = 0;
01111
break;
01112 }
01113
01114
break;
01115 }
01116
01117
default:
01118 lRet =
ImmEscapeA(hKL, hImc, uSubFunc, lpData);
01119
break;
01120 }
01121
01122
ImmUnlockImeDpi(pImeDpi);
01123
01124
return lRet;
01125 }
01126
01127
01128 BOOL WINAPI
ImmPenAuxInput(HWND hwndSender, LPVOID lpData)
01129 {
01130
PIMEDPI pImeDpi =
NULL;
01131 PCOPYDATASTRUCT lpCopyData = (PCOPYDATASTRUCT)lpData;
01132 PENINPUTDATA* lpPenInputData = (
LPVOID)lpCopyData->lpData;
01133 IMEPENDATA ImePenData;
01134 HWND hwnd;
01135 HIMC himc;
01136 HKL hkl;
01137
DWORD dwData = 0 ;
01138 LPDWORD lpdwData =
NULL;
01139
01140 UNREFERENCED_PARAMETER(hwndSender);
01141
01142
if (lpCopyData->dwData != LM_IMM_MAGIC || lpCopyData->cbData <
sizeof(PENINPUTDATA)) {
01143 RIPMSG0(RIP_WARNING,
"ImmPenAuxInput: invalid COPYDATASTRUCT signagure.");
01144
return FALSE;
01145 }
01146
01147
if (lpPenInputData->dwVersion != 0) {
01148 RIPMSG0(RIP_WARNING,
"ImmPenAuxInput: invalid Pendata version.");
01149
return FALSE;
01150 }
01151
01152 hwnd =
GetFocus();
01153 hkl =
GetKeyboardLayout(0);
01154
if (hwnd ==
NULL || hkl ==
NULL || (himc =
ImmGetContext(hwnd)) ==
NULL) {
01155 RIPMSG0(RIP_WARNING,
"ImmPenAuxInput: hwnd, hkl or himc cannot be aquired.");
01156
return FALSE;
01157 }
01158
01159
if ((pImeDpi =
FindOrLoadImeDpi(hkl)) ==
NULL) {
01160 RIPMSG0(RIP_WARNING,
"ImmPenAuxInput: IME DPI cannot be found.");
01161
return FALSE;
01162 }
01163
01164
do {
01165 dwData = IME_ESC_PENAUXDATA;
01166
if (!pImeDpi->
pfn.
ImeEscape(himc, IME_ESC_QUERY_SUPPORT, (
LPVOID)&dwData)) {
01167
01168
01169
01170 RIPMSG1(RIP_VERBOSE,
"ImmPenAuxInput: IME(hkl=%08x) does not support IME_ESC_PENDATA", hkl);
01171
break;
01172 }
01173
01174 dwData = 0;
01175
01176
01177
01178
01179
01180 RtlZeroMemory(&ImePenData,
sizeof ImePenData);
01181
01182 ImePenData.dwCount = lpPenInputData->cnt;
01183
01184
if (lpPenInputData->flags & ~(LMDATA_SYMBOL_DWORD | LMDATA_SKIP_WORD | LMDATA_SCORE_WORD)) {
01185 RIPMSG1(RIP_WARNING,
"ImmPenAuxInput: flag out of range (0x%08x)", lpPenInputData->flags);
01186 }
01187
01188
01189
01190
01191
01192
if (lpPenInputData->flags & LMDATA_SYMBOL_DWORD) {
01193
if (lpPenInputData->dwOffsetSymbols > lpCopyData->cbData ||
01194 lpPenInputData->dwOffsetSymbols + lpPenInputData->cnt *
sizeof(
DWORD) > lpCopyData->cbData) {
01195
01196
01197
01198 RIPMSG1(RIP_WARNING,
"ImmPenAuxInput: illegal dwOffsetSymbols (0x%x)", lpPenInputData->dwOffsetSymbols);
01199
break;
01200 }
01201 ImePenData.wd.lpSymbol = (
LPVOID)&lpPenInputData->ab[lpPenInputData->dwOffsetSymbols];
01202 ImePenData.dwFlags |= IME_PEN_SYMBOL;
01203
01204
01205
01206
01207
if ((pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE) == 0) {
01208
USHORT wCodePage = (
USHORT)
GetKeyboardLayoutCP(hkl);
01209
int i;
01210
01211 lpdwData =
ImmLocalAlloc(HEAP_ZERO_MEMORY,
sizeof *lpdwData * ImePenData.dwCount);
01212
if (lpdwData ==
NULL) {
01213 RIPMSG0(RIP_WARNING,
"ImmPenAuxInput: could not allocate lpdwData");
01214
break;
01215 }
01216
for (i = 0; i < (
int)ImePenData.dwCount; ++i) {
01217 LPSTR lpstr = (LPSTR)(lpdwData + i);
01218
01219
01220 WCSToMBEx(wCodePage,
01221 (LPCWSTR)(ImePenData.wd.lpSymbol + i), 1,
01222 &lpstr, 2,
01223
FALSE);
01224
ImmAssert(HIWORD(lpdwData[i]) == 0);
01225
01226
01227 lpdwData[i] |= (ImePenData.wd.lpSymbol[i] & ~0xffff);
01228 }
01229 ImePenData.wd.lpSymbol = lpdwData;
01230 }
01231
01232 }
01233
01234
if (lpPenInputData->flags & LMDATA_SKIP_WORD) {
01235
if (lpPenInputData->dwOffsetSkip > lpCopyData->cbData ||
01236 lpPenInputData->dwOffsetSkip + lpPenInputData->cnt *
sizeof(WORD) > lpCopyData->cbData) {
01237
01238
01239
01240 RIPMSG1(RIP_WARNING,
"ImmPenAuxInput: illegal dwOffsetSkip (0x%x)", lpPenInputData->dwOffsetSkip);
01241
break;
01242 }
01243 ImePenData.wd.lpSkip = (
LPVOID)&lpPenInputData->ab[lpPenInputData->dwOffsetSkip];
01244 ImePenData.dwFlags |= IME_PEN_SKIP;
01245 }
01246
01247
if (lpPenInputData->flags & LMDATA_SCORE_WORD) {
01248
if (lpPenInputData->dwOffsetScore > lpCopyData->cbData ||
01249 lpPenInputData->dwOffsetScore + lpPenInputData->cnt *
sizeof(WORD) > lpCopyData->cbData) {
01250
01251
01252
01253 RIPMSG1(RIP_WARNING,
"ImmPenAuxInput: illegal dwOffsetScore (0x%x)", lpPenInputData->dwOffsetScore);
01254
break;
01255 }
01256 ImePenData.wd.lpScore = (
LPVOID)&lpPenInputData->ab[lpPenInputData->dwOffsetScore];
01257 ImePenData.dwFlags |= IME_PEN_SCORE;
01258 }
01259 dwData = (
DWORD)pImeDpi->
pfn.
ImeEscape(himc, IME_ESC_PENAUXDATA, &ImePenData);
01260 }
while (
FALSE);
01261
01262
if (lpdwData) {
01263
ImmLocalFree(lpdwData);
01264 }
01265
01266
ImmAssert(pImeDpi);
01267
ImmUnlockImeDpi(pImeDpi);
01268
01269
return dwData;
01270 }
01271
01272 LRESULT WINAPI
ImmSendMessageToActiveDefImeWndW(
01273 UINT msg,
01274 WPARAM wParam,
01275 LPARAM lParam)
01276 {
01277 HWND hwndIme;
01278
01279
01280
01281
01282
if (
msg != WM_COPYDATA) {
01283
return 0;
01284 }
01285
01286 hwndIme =
NtUserQueryWindow((HWND)wParam, WindowActiveDefaultImeWindow);
01287
if (hwndIme ==
NULL) {
01288
return 0;
01289 }
01290
01291
return SendMessage(hwndIme,
msg, wParam, lParam);
01292 }
01293
01294 BOOL WINAPI
ImmNotifyIME(
01295 HIMC hImc,
01296 DWORD dwAction,
01297 DWORD dwIndex,
01298 DWORD dwValue)
01299 {
01300
PIMEDPI pImeDpi;
01301
BOOL bRet;
01302
01303
if (hImc !=
NULL_HIMC &&
01304
GetInputContextThread(hImc) != GetCurrentThreadId()) {
01305 RIPMSG1(RIP_WARNING,
01306
"ImmNotifyIME: Invalid input context access %lx.", hImc);
01307
return FALSE;
01308 }
01309
01310 pImeDpi =
ImmLockImeDpi(
GetKeyboardLayout(0));
01311
if (pImeDpi ==
NULL)
01312
return FALSE;
01313
01314 bRet = (*pImeDpi->
pfn.
NotifyIME)(hImc, dwAction, dwIndex, dwValue);
01315
01316
ImmUnlockImeDpi(pImeDpi);
01317
01318
return bRet;
01319 }