00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include "precomp.h"
00013
#pragma hdrstop
00014
00015
00016
00017
extern DWORD ImmReconversionWorker(LPRECONVERTSTRING lpRecTo, LPRECONVERTSTRING lpRecFrom, BOOL bToAnsi, DWORD dwCodePage);
00018
00019
00020 int UnicodeToMultiByteSize(DWORD dwCodePage, LPCWSTR pwstr)
00021 {
00022
char dummy[2], *lpszDummy =
dummy;
00023
return WCSToMBEx((WORD)dwCodePage, pwstr, 1, &lpszDummy,
sizeof(WCHAR),
FALSE);
00024 }
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 LONG WINAPI
ImmGetCompositionStringA(
00037 HIMC hImc,
00038 DWORD dwIndex,
00039 LPVOID lpBuf,
00040 DWORD dwBufLen)
00041 {
00042
PCLIENTIMC pClientImc;
00043 PINPUTCONTEXT pInputContext;
00044 PCOMPOSITIONSTRING pCompStr;
00045
BOOL fAnsi;
00046 LONG lRet = 0;
00047
DWORD dwCodePage;
00048
00049
if (dwBufLen != 0 && lpBuf ==
NULL) {
00050 RIPMSG0(RIP_WARNING,
"ImmGetCompositionStringW: NULL lpBuf.");
00051
return lRet;
00052 }
00053
00054 pClientImc =
ImmLockClientImc(hImc);
00055
if (pClientImc ==
NULL) {
00056 RIPMSG1(RIP_WARNING,
00057
"ImmGetCompositionStringA: Invalid hImc %lx.", hImc);
00058
return lRet;
00059 }
00060
00061 fAnsi = !
TestICF(pClientImc,
IMCF_UNICODE);
00062 dwCodePage =
CImcCodePage(pClientImc);
00063
00064
ImmUnlockClientImc(pClientImc);
00065
00066 pInputContext =
ImmLockIMC(hImc);
00067
if (pInputContext ==
NULL) {
00068 RIPMSG1(RIP_WARNING,
"ImmGetCompositionStringA: Lock hImc %lx failed.", hImc);
00069
return lRet;
00070 }
00071
00072 pCompStr = (PCOMPOSITIONSTRING)
ImmLockIMCC(pInputContext->hCompStr);
00073
if (pCompStr ==
NULL) {
00074 RIPMSG1(RIP_WARNING,
"ImmGetCompositionStringA: Lock hCompStr %x failed",
00075 pInputContext->hCompStr);
00076
ImmUnlockIMC(hImc);
00077
return lRet;
00078 }
00079
00080 lRet =
InternalGetCompositionStringA(pCompStr, dwIndex,
00081 lpBuf, dwBufLen, fAnsi, dwCodePage);
00082
00083
ImmUnlockIMCC(pInputContext->hCompStr);
00084
ImmUnlockIMC(hImc);
00085
00086
return lRet;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 LONG WINAPI
ImmGetCompositionStringW(
00100 HIMC hImc,
00101 DWORD dwIndex,
00102 LPVOID lpBuf,
00103 DWORD dwBufLen)
00104 {
00105
PCLIENTIMC pClientImc;
00106 PINPUTCONTEXT pInputContext;
00107 PCOMPOSITIONSTRING pCompStr;
00108
BOOL fAnsi;
00109 LONG lRet = 0;
00110
DWORD dwCodePage;
00111
00112
if (dwBufLen != 0 && lpBuf ==
NULL) {
00113 RIPMSG0(RIP_WARNING,
"ImmGetCompositionStringW: NULL lpBuf.");
00114
return lRet;
00115 }
00116
00117 pClientImc =
ImmLockClientImc(hImc);
00118
if (pClientImc ==
NULL) {
00119 RIPMSG1(RIP_WARNING,
00120
"ImmGetCompositionStringW: Invalid hImc %lx.", hImc);
00121
return lRet;
00122 }
00123
00124 fAnsi = !
TestICF(pClientImc,
IMCF_UNICODE);
00125 dwCodePage =
CImcCodePage(pClientImc);
00126
00127
ImmUnlockClientImc(pClientImc);
00128
00129 pInputContext =
ImmLockIMC(hImc);
00130
if (pInputContext ==
NULL) {
00131 RIPMSG1(RIP_WARNING,
"ImmGetCompositionStringW: Lock hImc %lx failed.", hImc);
00132
return lRet;
00133 }
00134
00135 pCompStr = (PCOMPOSITIONSTRING)
ImmLockIMCC(pInputContext->hCompStr);
00136
if (pCompStr ==
NULL) {
00137 RIPMSG1(RIP_WARNING,
"ImmGetCompositionStringA: Lock hCompStr %x failed",
00138 pInputContext->hCompStr);
00139
ImmUnlockIMC(hImc);
00140
return lRet;
00141 }
00142
00143 lRet =
InternalGetCompositionStringW(pCompStr, dwIndex,
00144 lpBuf, dwBufLen, fAnsi, dwCodePage);
00145
00146
ImmUnlockIMCC(pInputContext->hCompStr);
00147
ImmUnlockIMC(hImc);
00148
00149
return lRet;
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 BOOL WINAPI
ImmSetCompositionStringA(
00163 HIMC hImc,
00164 DWORD dwIndex,
00165 LPVOID lpComp,
00166 DWORD dwCompLen,
00167 LPVOID lpRead,
00168 DWORD dwReadLen)
00169 {
00170
return ImmSetCompositionStringWorker(hImc, dwIndex, lpComp,
00171 dwCompLen, lpRead, dwReadLen,
TRUE);
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 BOOL WINAPI
ImmSetCompositionStringW(
00185 HIMC hImc,
00186 DWORD dwIndex,
00187 LPVOID lpComp,
00188 DWORD dwCompLen,
00189 LPVOID lpRead,
00190 DWORD dwReadLen)
00191 {
00192
return ImmSetCompositionStringWorker(hImc, dwIndex, lpComp,
00193 dwCompLen, lpRead, dwReadLen,
FALSE);
00194 }
00195
00196
00197 LONG
CompositionString(
00198 HIMC hImc,
00199 PINPUTCONTEXT *ppInputContext,
00200 PCOMPOSITIONSTRING *ppCompStr,
00201 BOOL fCheckSize)
00202 {
00203 PINPUTCONTEXT pInputContext;
00204 PCOMPOSITIONSTRING pCompStr;
00205
00206 pInputContext =
ImmLockIMC(hImc);
00207
if (!pInputContext) {
00208 RIPMSG1(RIP_WARNING,
"CompositionString: Lock hImc %lx failed.", hImc);
00209
return (LONG)IMM_ERROR_GENERAL;
00210 }
00211
00212
if (!pInputContext->hCompStr) {
00213
ImmUnlockIMC(hImc);
00214
return (LONG)IMM_ERROR_NODATA;
00215 }
00216
00217 pCompStr = (PCOMPOSITIONSTRING)
ImmLockIMCC(pInputContext->hCompStr);
00218
if (!pCompStr) {
00219 RIPMSG1(RIP_WARNING,
00220
"CompositionString: Lock hCompStr %lx failed.", pInputContext->hCompStr);
00221
ImmUnlockIMC(hImc);
00222
return (LONG)IMM_ERROR_GENERAL;
00223 }
00224
00225
if (fCheckSize && pCompStr->dwSize <
sizeof(COMPOSITIONSTRING)) {
00226 RIPMSG0(RIP_WARNING,
"CompositionString: no composition string.");
00227
ImmUnlockIMCC(pInputContext->hCompStr);
00228
ImmUnlockIMC(hImc);
00229
return (LONG)IMM_ERROR_NODATA;
00230 }
00231
00232 *ppInputContext = pInputContext;
00233 *ppCompStr = pCompStr;
00234
00235
return (1);
00236 }
00237
00238
00239 BOOL CheckAttribute(
00240 LPBYTE lpComp,
00241 DWORD dwCompLen,
00242 LPBYTE lpAttr,
00243 DWORD dwAttrLen,
00244 LPDWORD lpClause,
00245 DWORD dwClauseLen)
00246 {
00247
DWORD dwCnt;
00248
DWORD dwBound;
00249
BYTE bAttr;
00250
00251 UNREFERENCED_PARAMETER(dwClauseLen);
00252
00253
if (!lpClause) {
00254 RIPMSG0(RIP_WARNING,
"CheckAttribute: no Clause. Pass it to IME.");
00255
return (
TRUE);
00256 }
00257
00258
if (!lpAttr) {
00259 RIPMSG0(RIP_WARNING,
"CheckAttribute: no Attr. Not pass it to IME.");
00260
return (
FALSE);
00261 }
00262
00263
if (dwCompLen != dwAttrLen) {
00264 RIPMSG0(RIP_WARNING,
"CheckAttribute: wrong length. Not pass it to IME.");
00265
return (
FALSE);
00266 }
00267
00268
00269
00270
00271
while (*lpClause < dwCompLen) {
00272 dwBound = *(lpClause+1) - *lpClause;
00273 bAttr = *lpComp++;
00274
for (dwCnt = 1; dwCnt < dwBound; dwCnt++)
00275
if (bAttr != *lpComp++) {
00276 RIPMSG0(RIP_WARNING,
00277
"CheckAttribute: mismatch clause att. Not Pass it to IME");
00278
return (
FALSE);
00279 }
00280 lpClause++;
00281 }
00282
00283
return (
TRUE);
00284 }
00285
00286
00287 BOOL CheckClause(
00288 LPDWORD lpComp,
00289 DWORD dwCompLen,
00290 LPDWORD lpClause,
00291 DWORD dwClauseLen)
00292 {
00293
UINT nCnt;
00294
INT diff = 0;
00295
00296
if (!dwClauseLen || !dwCompLen) {
00297 RIPMSG0(RIP_WARNING,
"CheckClause: no Clause. Not Pass it to IME.");
00298
return (
FALSE);
00299 }
00300
00301
if (*lpComp || *lpClause) {
00302 RIPMSG0(RIP_WARNING,
"CheckClause: lpClause[0] have to be ZERO.");
00303
return (
FALSE);
00304 }
00305
00306
for (nCnt = 0; nCnt < (
UINT)(dwClauseLen/4); nCnt++)
00307 {
00308
if (*lpComp++ != *lpClause++)
00309 {
00310 diff++;
00311
if (dwCompLen > dwClauseLen)
00312 lpClause--;
00313
if (dwCompLen < dwClauseLen)
00314 lpComp--;
00315 }
00316
if (diff > 1)
00317
return (
FALSE);
00318 }
00319
00320
return (
TRUE);
00321 }
00322
00323
00324 LPBYTE
InternalSCS_SETSTR(
00325 LPCVOID lpCompRead,
00326 DWORD dwCompReadLen,
00327 LPVOID *lplpNewCompRead,
00328 DWORD *lpdwNewCompReadLen,
00329 BOOL fAnsi,
00330 DWORD dwCodePage)
00331 {
00332 LPBYTE lpBufRet;
00333
DWORD dwBufSize;
00334 LPSTR lpBufA;
00335 LPWSTR lpBufW;
00336
INT i;
00337
BOOL bUDC;
00338
00339
if (lpCompRead ==
NULL || dwCompReadLen == 0)
00340
return NULL;
00341
00342 dwBufSize = dwCompReadLen *
sizeof(WCHAR) * 2;
00343
00344 lpBufRet =
ImmLocalAlloc(0, dwBufSize);
00345
if (lpBufRet ==
NULL) {
00346 RIPMSG0(RIP_WARNING,
"InternalSCS_SETSTR: memory failure.");
00347
return NULL;
00348 }
00349
00350 lpBufW = (LPWSTR)lpBufRet;
00351 lpBufA = (LPSTR)(lpBufW + dwCompReadLen);
00352
00353
if (fAnsi) {
00354
00355 RtlCopyMemory(lpBufA, lpCompRead, dwCompReadLen);
00356
00357 i = MultiByteToWideChar(dwCodePage,
00358 (
DWORD)MB_PRECOMPOSED,
00359 (LPSTR)lpBufA,
00360 (
INT)dwCompReadLen,
00361 (LPWSTR)lpBufW,
00362 (
INT)dwCompReadLen);
00363
00364 *lplpNewCompRead = lpBufW;
00365 *lpdwNewCompReadLen = (
DWORD)(i *
sizeof(WCHAR));
00366 }
00367
else {
00368
00369 RtlCopyMemory(lpBufW, lpCompRead, dwCompReadLen);
00370
00371 i = WideCharToMultiByte(dwCodePage,
00372 (
DWORD)0,
00373 lpBufW,
00374 (
INT)dwCompReadLen/
sizeof(WCHAR),
00375 (LPSTR)lpBufA,
00376 (
INT)dwCompReadLen,
00377 (LPSTR)
NULL,
00378 (LPBOOL)&bUDC);
00379
00380 *lplpNewCompRead = lpBufA;
00381 *lpdwNewCompReadLen = (
DWORD)(i *
sizeof(
CHAR));
00382 }
00383
00384
return lpBufRet;
00385 }
00386
00387
00388 LPBYTE
InternalSCS_CHANGEATTR(
00389 HIMC hImc,
00390 LPCVOID lpCompRead,
00391 DWORD dwCompReadLen,
00392 DWORD dwIndex,
00393 LPVOID *lplpNewCompRead,
00394 DWORD *lpdwNewCompReadLen,
00395 BOOL fAnsi,
00396 DWORD dwCodePage)
00397 {
00398 LPBYTE lpBufRet;
00399 LPBYTE lpAttr, lpAttrA, lpAttrW;
00400
DWORD dwBufLenA, dwBufLenW;
00401 LPSTR lpStrBufA, lpBufA;
00402 LPWSTR lpStrBufW, lpBufW;
00403
CHAR c;
00404 WCHAR wc;
00405 ULONG MultiByteSize;
00406
00407
if (lpCompRead ==
NULL || dwCompReadLen == 0)
00408
return NULL;
00409
00410
if (fAnsi) {
00411
00412 dwBufLenA =
ImmGetCompositionStringA(hImc, dwIndex,
NULL, 0);
00413
00414 lpStrBufA =
ImmLocalAlloc(0, dwBufLenA);
00415
if (lpStrBufA ==
NULL) {
00416 RIPMSG0(RIP_WARNING,
"InternalSCS_CHANGEATTR: memory failure.");
00417
return NULL;
00418 }
00419
00420
ImmGetCompositionStringA(hImc, dwIndex, lpStrBufA, dwBufLenA);
00421
00422 lpBufRet =
ImmLocalAlloc(0, dwBufLenA);
00423
if (lpBufRet ==
NULL) {
00424 RIPMSG0(RIP_WARNING,
"InternalSCS_CHANGEATTR: memory failure.");
00425
ImmLocalFree(lpStrBufA);
00426
return NULL;
00427 }
00428
00429 lpBufA = lpStrBufA;
00430 lpAttrA = (LPBYTE)lpCompRead;
00431 lpAttr = lpBufRet;
00432
00433
while (dwBufLenA != 0 && (
c=*lpBufA++) != 0) {
00434
if (IsDBCSLeadByteEx(dwCodePage,
c)) {
00435
if (dwBufLenA >= 2) {
00436 *lpAttr++ = *lpAttrA++;
00437 dwBufLenA--;
00438 }
else {
00439 *lpAttr++ = *lpAttrA;
00440 }
00441 lpBufA++;
00442 }
else {
00443 *lpAttr++ = *lpAttrA;
00444 }
00445 lpAttrA++;
00446 dwBufLenA--;
00447 }
00448
00449
ImmLocalFree(lpStrBufA);
00450 }
00451
else {
00452
00453 dwBufLenW =
ImmGetCompositionStringW(hImc, dwIndex,
NULL, 0);
00454
00455 lpStrBufW =
ImmLocalAlloc(0, dwBufLenW);
00456
if (lpStrBufW ==
NULL) {
00457 RIPMSG0(RIP_WARNING,
"InternalSCS_CHANGEATTR: memory failure.");
00458
return NULL;
00459 }
00460
00461
ImmGetCompositionStringW(hImc, dwIndex, lpStrBufW, dwBufLenW);
00462
00463 lpBufRet =
ImmLocalAlloc(0, dwBufLenW);
00464
if (lpBufRet ==
NULL) {
00465 RIPMSG0(RIP_WARNING,
"InternalSCS_CHANGEATTR: memory failure.");
00466
ImmLocalFree(lpStrBufW);
00467
return NULL;
00468 }
00469
00470 lpBufW = lpStrBufW;
00471 lpAttrW = (LPBYTE)lpCompRead;
00472 lpAttr = lpBufRet;
00473
00474
while (dwBufLenW != 0 && (wc=*lpBufW++) !=
L'\0') {
00475 MultiByteSize =
UnicodeToMultiByteSize(dwCodePage, &wc);
00476
if (MultiByteSize == 2) {
00477 *lpAttr++ = *lpAttrW;
00478 }
00479 *lpAttr++ = *lpAttrW++;
00480 dwBufLenW -=
sizeof(WCHAR);
00481 }
00482
00483
ImmLocalFree(lpStrBufW);
00484 }
00485
00486 *lplpNewCompRead = lpBufRet;
00487 *lpdwNewCompReadLen = (
DWORD)(lpAttr - (
PBYTE)lpBufRet);
00488
00489
return lpBufRet;
00490 }
00491
00492
00493 LPBYTE
InternalSCS_CHANGECLAUSE(
00494 HIMC hImc,
00495 LPCVOID lpCompRead,
00496 DWORD dwCompReadLen,
00497 DWORD dwIndex,
00498 LPDWORD *lplpNewCompRead,
00499 DWORD *lpdwNewCompReadLen,
00500 BOOL fAnsi,
00501 DWORD dwCodePage)
00502 {
00503 LPDWORD lpdw, lpNewdw, lpBufRet;
00504
DWORD dwBufLenA, dwBufLenW;
00505 LPSTR lpStrBufA;
00506 LPWSTR lpStrBufW;
00507
INT i;
00508
00509
if (lpCompRead ==
NULL || dwCompReadLen == 0)
00510
return NULL;
00511
00512 lpdw = (LPDWORD)lpCompRead;
00513
00514 lpBufRet =
ImmLocalAlloc(0, dwCompReadLen);
00515
if (lpBufRet ==
NULL) {
00516 RIPMSG0(RIP_WARNING,
"InternalSCS_CHANGECLAUSE: memory failure.");
00517
return NULL;
00518 }
00519
00520
if (fAnsi) {
00521
00522 dwBufLenA =
ImmGetCompositionStringA(hImc, dwIndex,
NULL, 0);
00523
00524 lpStrBufA =
ImmLocalAlloc(0, dwBufLenA);
00525
if (lpStrBufA ==
NULL) {
00526 RIPMSG0(RIP_WARNING,
"InternalSCS_CHANGECLAUSE: memory failure.");
00527
ImmLocalFree(lpBufRet);
00528
return NULL;
00529 }
00530
00531
ImmGetCompositionStringA(hImc, dwIndex, lpStrBufA, dwBufLenA);
00532 }
00533
else {
00534
00535 dwBufLenW =
ImmGetCompositionStringW(hImc, dwIndex,
NULL, 0);
00536
00537 lpStrBufW =
ImmLocalAlloc(0, dwBufLenW);
00538
if (lpStrBufW ==
NULL) {
00539 RIPMSG0(RIP_WARNING,
"InternalSCS_CHANGECLAUSE: memory failure.");
00540
ImmLocalFree(lpBufRet);
00541
return NULL;
00542 }
00543
00544
ImmGetCompositionStringW(hImc, dwIndex, lpStrBufW, dwBufLenW);
00545 }
00546
00547 *lplpNewCompRead = lpNewdw = lpBufRet;
00548 *lpdwNewCompReadLen = dwCompReadLen;
00549
00550
for (i = 0; i < (
INT)(dwCompReadLen /
sizeof(
DWORD)); i++) {
00551 *lpNewdw++ = fAnsi ?
CalcCharacterPositionAtoW(*lpdw++, lpStrBufA, dwCodePage)
00552 :
CalcCharacterPositionWtoA(*lpdw++, lpStrBufW, dwCodePage);
00553 }
00554
00555
return (LPBYTE)lpBufRet;
00556 }
00557
00558
00559 LPBYTE
InternalSCS_RECONVERTSTRING(
00560 LPRECONVERTSTRING lpReconv,
00561 DWORD dwReconvLen,
00562 LPRECONVERTSTRING *lplpNewReconv,
00563 DWORD *lpdwNewReconvLen,
00564 BOOL fAnsi,
00565 DWORD dwCodePage)
00566 {
00567 LPRECONVERTSTRING lpNewReconv;
00568
DWORD dwBufSize;
00569
00570
if (lpReconv ==
NULL || dwReconvLen == 0)
00571
return NULL;
00572
00573
if (fAnsi) {
00574
00575 dwBufSize = (lpReconv->dwSize -
sizeof *lpReconv + 1) *
sizeof(WCHAR) +
sizeof *lpReconv;
00576 }
00577
else {
00578 dwBufSize = lpReconv->dwSize +
sizeof(
BYTE);
00579 }
00580 lpNewReconv =
ImmLocalAlloc(0, dwBufSize);
00581
if (lpNewReconv ==
NULL) {
00582 RIPMSG0(RIP_WARNING,
"InternalSCS_RECONVERTSTRING: memory failure.");
00583
return NULL;
00584 }
00585
00586 lpNewReconv->dwVersion = 0;
00587 lpNewReconv->dwSize= dwBufSize;
00588
00589 lpNewReconv->dwSize =
ImmReconversionWorker(lpNewReconv, lpReconv, !fAnsi, dwCodePage);
00590
if (lpNewReconv->dwSize == 0) {
00591
ImmLocalFree(lpNewReconv);
00592
return NULL;;
00593 }
00594 *lpdwNewReconvLen = lpNewReconv->dwSize;
00595 *lplpNewReconv = lpNewReconv;
00596
00597
return (LPBYTE)lpNewReconv;
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 BOOL ImmSetCompositionStringWorker(
00611 HIMC hImc,
00612 DWORD dwIndex,
00613 LPVOID lpComp,
00614 DWORD dwCompLen,
00615 LPVOID lpRead,
00616 DWORD dwReadLen,
00617 BOOL fAnsi)
00618 {
00619 PINPUTCONTEXT pInputContext;
00620 PCOMPOSITIONSTRING pCompStr;
00621
DWORD dwThreadId;
00622
PIMEDPI pImeDpi;
00623 LPBYTE lpCompBuf, lpReadBuf;
00624 LPBYTE lpNewComp =
NULL, lpNewRead =
NULL;
00625
DWORD dwNewCompLen, dwNewReadLen;
00626
BOOL fRet =
FALSE;
00627
BOOL fCheckSize =
TRUE;
00628
BOOL fNeedAWConversion;
00629 LPBYTE lpOrgComp, lpOrgRead;
00630
DWORD dwOrgCompLen, dwOrgReadLen;
00631
00632 dwThreadId =
GetInputContextThread(hImc);
00633
if (dwThreadId != GetCurrentThreadId()) {
00634 RIPMSG1(RIP_WARNING,
00635
"ImmSetCompositionString: Invalid input context access %lx.", hImc);
00636
return FALSE;
00637 }
00638
00639 pImeDpi =
ImmLockImeDpi(
GetKeyboardLayout(dwThreadId));
00640
if (pImeDpi ==
NULL)
00641
return FALSE;
00642
00643 lpCompBuf = lpReadBuf =
NULL;
00644
00645
00646 lpOrgComp = lpComp;
00647 lpOrgRead = lpRead;
00648 dwOrgCompLen = dwCompLen;
00649 dwOrgReadLen = dwReadLen;
00650
00651
00652
00653
00654
if (( fAnsi && !(pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE)) ||
00655 (!fAnsi && (pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE))) {
00656
00657
00658
00659 fNeedAWConversion =
FALSE;
00660
goto start_scs;
00661 }
00662 fNeedAWConversion =
TRUE;
00663
00664
switch (dwIndex) {
00665
case SCS_SETSTR:
00666
if ( lpComp &&
00667 (lpCompBuf =
InternalSCS_SETSTR(lpComp, dwCompLen,
00668 &lpNewComp, &dwNewCompLen, fAnsi,
IMECodePage(pImeDpi))) ==
NULL)
00669
goto callime_scs;
00670
if ( lpRead &&
00671 (lpReadBuf =
InternalSCS_SETSTR(lpRead, dwReadLen,
00672 &lpNewRead, &dwNewReadLen, fAnsi,
IMECodePage(pImeDpi))) ==
NULL)
00673
goto callime_scs;
00674
00675 fCheckSize =
FALSE;
00676
break;
00677
00678
case SCS_CHANGEATTR:
00679
if ( lpComp &&
00680 (lpCompBuf =
InternalSCS_CHANGEATTR(
00681 hImc, lpComp, dwCompLen, GCS_COMPSTR,
00682 &lpNewComp, &dwNewCompLen, fAnsi,
IMECodePage(pImeDpi))) ==
NULL)
00683
goto callime_scs;
00684
if ( lpRead &&
00685 (lpReadBuf =
InternalSCS_CHANGEATTR(
00686 hImc, lpRead, dwReadLen, GCS_COMPREADSTR,
00687 &lpNewRead, &dwNewReadLen, fAnsi,
IMECodePage(pImeDpi))) ==
NULL)
00688
goto callime_scs;
00689
break;
00690
00691
case SCS_CHANGECLAUSE:
00692
if ( lpComp &&
00693 (lpCompBuf =
InternalSCS_CHANGECLAUSE(
00694 hImc, lpComp, dwCompLen, GCS_COMPSTR,
00695 (LPDWORD *)&lpNewComp, &dwNewCompLen, fAnsi,
IMECodePage(pImeDpi))) ==
NULL)
00696
goto callime_scs;
00697
if ( lpRead &&
00698 (lpReadBuf =
InternalSCS_CHANGECLAUSE(
00699 hImc, lpRead, dwReadLen, GCS_COMPREADSTR,
00700 (LPDWORD *)&lpNewRead, &dwNewReadLen, fAnsi,
IMECodePage(pImeDpi))) ==
NULL)
00701
goto callime_scs;
00702
break;
00703
00704
case SCS_SETRECONVERTSTRING:
00705
case SCS_QUERYRECONVERTSTRING:
00706
if (lpComp &&
00707 (lpCompBuf =
InternalSCS_RECONVERTSTRING((LPRECONVERTSTRING)lpComp, dwCompLen,
00708 (LPRECONVERTSTRING *)&lpNewComp, &dwNewCompLen,
00709 fAnsi,
IMECodePage(pImeDpi))) ==
NULL)
00710
goto callime_scs;
00711
if (lpRead &&
00712 (lpReadBuf =
InternalSCS_RECONVERTSTRING((LPRECONVERTSTRING)lpRead, dwReadLen,
00713 (LPRECONVERTSTRING *)&lpNewRead, &dwNewReadLen,
00714 fAnsi,
IMECodePage(pImeDpi))) ==
NULL)
00715
goto callime_scs;
00716
00717 fCheckSize =
FALSE;
00718
break;
00719
00720
default:
00721
goto callime_scs;
00722 }
00723
00724
if (lpCompBuf !=
NULL) {
00725 lpComp = lpNewComp;
00726 dwCompLen = dwNewCompLen;
00727 }
00728
00729
if (lpReadBuf !=
NULL) {
00730 lpRead = lpNewRead;
00731 dwReadLen = dwNewReadLen;
00732 }
00733
00734 start_scs:
00735
00736
if (
CompositionString(hImc, &pInputContext, &pCompStr, fCheckSize) <= 0)
00737
goto callime_scs;
00738
00739
switch (dwIndex)
00740 {
00741
case SCS_SETSTR:
00742 fRet =
TRUE;
00743
break;
00744
00745
case SCS_CHANGEATTR:
00746
if ( lpComp &&
00747 !
CheckAttribute((LPBYTE)lpComp, dwCompLen,
00748 (LPBYTE)((LPBYTE)pCompStr + pCompStr->dwCompAttrOffset),
00749 pCompStr->dwCompAttrLen,
00750 (LPDWORD)((LPBYTE)pCompStr + pCompStr->dwCompClauseOffset),
00751 pCompStr->dwCompClauseLen))
break;
00752
00753
if ( lpRead &&
00754 !
CheckAttribute((LPBYTE)lpRead, dwReadLen,
00755 (LPBYTE)((LPBYTE)pCompStr + pCompStr->dwCompReadAttrOffset),
00756 pCompStr->dwCompReadAttrLen,
00757 (LPDWORD)((LPBYTE)pCompStr + pCompStr->dwCompReadClauseOffset),
00758 pCompStr->dwCompReadClauseLen))
break;
00759 fRet =
TRUE;
00760
break;
00761
00762
case SCS_CHANGECLAUSE:
00763
if ( lpComp &&
00764 !
CheckClause((LPDWORD)lpComp, dwCompLen,
00765 (LPDWORD)((LPBYTE)pCompStr + pCompStr->dwCompClauseOffset),
00766 pCompStr->dwCompClauseLen))
break;
00767
if ( lpRead &&
00768 !
CheckClause((LPDWORD)lpRead, dwReadLen,
00769 (LPDWORD)((LPBYTE)pCompStr + pCompStr->dwCompReadClauseOffset),
00770 pCompStr->dwCompReadClauseLen))
break;
00771 fRet =
TRUE;
00772
break;
00773
00774
case SCS_SETRECONVERTSTRING:
00775
case SCS_QUERYRECONVERTSTRING:
00776
if (pImeDpi->
ImeInfo.fdwSCSCaps & SCS_CAP_SETRECONVERTSTRING) {
00777 fRet =
TRUE;
00778 }
00779
break;
00780
00781
default:
00782
break;
00783 }
00784
00785
ImmUnlockIMCC(pInputContext->hCompStr);
00786
ImmUnlockIMC(hImc);
00787
00788 callime_scs:
00789
00790
if (fRet) {
00791 fRet = (*pImeDpi->
pfn.
ImeSetCompositionString)(hImc, dwIndex,
00792 lpComp, dwCompLen, lpRead, dwReadLen);
00793 }
00794
00795
00796
00797
00798
if (fNeedAWConversion) {
00799 LPBYTE lpCompBufBack =
NULL, lpReadBufBack =
NULL;
00800
00801
00802
00803
switch (dwIndex) {
00804
case SCS_QUERYRECONVERTSTRING:
00805
if (lpOrgComp &&
00806 (lpCompBufBack =
InternalSCS_RECONVERTSTRING((LPRECONVERTSTRING)lpComp, dwCompLen,
00807 (LPRECONVERTSTRING *)&lpNewComp, &dwNewCompLen,
00808 !fAnsi,
IMECodePage(pImeDpi)))) {
00809 RtlCopyMemory(lpOrgComp, lpNewComp, dwNewCompLen);
00810 }
00811
if (lpOrgRead &&
00812 (lpReadBufBack =
InternalSCS_RECONVERTSTRING(
00813 (LPRECONVERTSTRING)lpRead, dwReadLen,
00814 (LPRECONVERTSTRING *)&lpNewRead, &dwNewReadLen,
00815 !fAnsi,
IMECodePage(pImeDpi)))) {
00816 RtlCopyMemory(lpOrgRead, lpNewRead, dwNewReadLen);
00817 }
00818 }
00819
if (lpCompBufBack !=
NULL)
00820 LocalFree(lpCompBufBack);
00821
if (lpReadBufBack !=
NULL)
00822 LocalFree(lpReadBufBack);
00823 }
00824
00825
if (lpCompBuf !=
NULL)
00826
ImmLocalFree(lpCompBuf);
00827
if (lpReadBuf !=
NULL)
00828
ImmLocalFree(lpReadBuf);
00829
00830
ImmUnlockImeDpi(pImeDpi);
00831
00832
return fRet;
00833 }
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845 DWORD WINAPI
ImmGetCandidateListCountA(
00846 HIMC hImc,
00847 LPDWORD lpdwListCount)
00848 {
00849
return ImmGetCandidateListCountWorker(hImc, lpdwListCount,
TRUE);
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862 DWORD WINAPI
ImmGetCandidateListCountW(
00863 HIMC hImc,
00864 LPDWORD lpdwListCount)
00865 {
00866
return ImmGetCandidateListCountWorker(hImc, lpdwListCount,
FALSE);
00867 }
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879 DWORD ImmGetCandidateListCountWorker(
00880 HIMC hImc,
00881 LPDWORD lpdwListCount,
00882 BOOL fAnsi)
00883 {
00884
PCLIENTIMC pClientImc;
00885 PINPUTCONTEXT pInputContext;
00886 LPCANDIDATEINFO lpCandInfo;
00887
DWORD dwRet = 0;
00888
INT i;
00889
DWORD dwCodePage;
00890
00891
if (lpdwListCount) {
00892 *lpdwListCount = 0;
00893 }
else {
00894 RIPMSG0(RIP_WARNING,
"ImmGetCandidateListCount: NULL lpdwListCount.");
00895
return dwRet;
00896 }
00897
00898 pClientImc =
ImmLockClientImc(hImc);
00899
if (pClientImc ==
NULL) {
00900 RIPMSG1(RIP_WARNING,
"ImmGetCandidateListCount: Invalid hImc %lx.", hImc);
00901
goto GetCandListCntExit;
00902 }
00903 dwCodePage =
CImcCodePage(pClientImc);
00904
00905 pInputContext =
ImmLockIMC(hImc);
00906
if (pInputContext ==
NULL) {
00907 RIPMSG1(RIP_WARNING,
"ImmGetCandidateListCount: Lock hImc %lx failed.", hImc);
00908
goto GetCandListCntUnlockClientImc;
00909 }
00910
00911 lpCandInfo = (LPCANDIDATEINFO)
ImmLockIMCC(pInputContext->hCandInfo);
00912
if (!lpCandInfo) {
00913 RIPMSG1(RIP_WARNING,
00914
"ImmGetCandidateListCount: Lock hCandInfo %x failed.",
00915 pInputContext->hCandInfo);
00916
goto GetCandListCntUnlockIMC;
00917 }
00918
00919
if (lpCandInfo->dwSize <
sizeof(CANDIDATEINFO)) {
00920 RIPMSG0(RIP_WARNING,
"ImmGetCandidateListCount: no candidate list.");
00921
goto GetCandListCntUnlockIMC;
00922 }
00923
00924 *lpdwListCount = lpCandInfo->dwCount;
00925
00926
if (fAnsi &&
TestICF(pClientImc,
IMCF_UNICODE)) {
00927 LPCANDIDATELIST lpCandListW;
00928
00929 dwRet =
DWORD_ALIGN(
sizeof(CANDIDATEINFO))
00930 +
DWORD_ALIGN(lpCandInfo->dwPrivateSize);
00931
00932
for (i = 0; i < (
INT)lpCandInfo->dwCount; i++) {
00933 lpCandListW = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[i]);
00934 dwRet +=
InternalGetCandidateListWtoA(lpCandListW,
NULL, 0, dwCodePage);
00935 }
00936 }
00937
else if (!fAnsi && !
TestICF(pClientImc,
IMCF_UNICODE)) {
00938 LPCANDIDATELIST lpCandListA;
00939
00940 dwRet =
DWORD_ALIGN(
sizeof(CANDIDATEINFO))
00941 +
DWORD_ALIGN(lpCandInfo->dwPrivateSize);
00942
00943
for (i = 0; i < (
INT)lpCandInfo->dwCount; i++) {
00944 lpCandListA = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[i]);
00945 dwRet +=
InternalGetCandidateListAtoW(lpCandListA,
NULL, 0, dwCodePage);
00946 }
00947 }
00948
else {
00949 dwRet = lpCandInfo->dwSize;
00950 }
00951
00952
ImmUnlockIMCC(pInputContext->hCandInfo);
00953
00954 GetCandListCntUnlockIMC:
00955
ImmUnlockIMC(hImc);
00956
00957 GetCandListCntUnlockClientImc:
00958
ImmUnlockClientImc(pClientImc);
00959
00960 GetCandListCntExit:
00961
return dwRet;
00962 }
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974 DWORD WINAPI
ImmGetCandidateListA(
00975 HIMC hImc,
00976 DWORD dwIndex,
00977 LPCANDIDATELIST lpCandList,
00978 DWORD dwBufLen)
00979 {
00980
return ImmGetCandidateListWorker(hImc, dwIndex,
00981 lpCandList, dwBufLen,
TRUE);
00982 }
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994 DWORD WINAPI
ImmGetCandidateListW(
00995 HIMC hImc,
00996 DWORD dwIndex,
00997 LPCANDIDATELIST lpCandList,
00998 DWORD dwBufLen)
00999 {
01000
return ImmGetCandidateListWorker(hImc, dwIndex,
01001 lpCandList, dwBufLen,
FALSE);
01002 }
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014 DWORD ImmGetCandidateListWorker(
01015 HIMC hImc,
01016 DWORD dwIndex,
01017 LPCANDIDATELIST lpCandList,
01018 DWORD dwBufLen,
01019 BOOL fAnsi)
01020 {
01021
PCLIENTIMC pClientImc;
01022 PINPUTCONTEXT pInputContext;
01023 LPCANDIDATEINFO lpCandInfo;
01024 LPCANDIDATELIST lpCandListTemp;
01025
DWORD dwBufLenTemp;
01026
DWORD dwRet = 0;
01027
DWORD dwCodePage;
01028
01029 pClientImc =
ImmLockClientImc(hImc);
01030
if (pClientImc ==
NULL) {
01031 RIPMSG1(RIP_WARNING,
"ImmGetCandidateList: Invalid hImc %lx.", hImc);
01032
goto GetCandListExit;
01033
01034 }
01035
01036 dwCodePage =
CImcCodePage(pClientImc);
01037
01038 pInputContext =
ImmLockIMC(hImc);
01039
if (pInputContext ==
NULL) {
01040 RIPMSG1(RIP_WARNING,
"ImmGetCandidateList: Lock hImc %lx failed.", hImc);
01041
goto GetCandListUnlockClientImc;
01042 }
01043
01044 lpCandInfo = (LPCANDIDATEINFO)
ImmLockIMCC(pInputContext->hCandInfo);
01045
if (!lpCandInfo) {
01046 RIPMSG1(RIP_WARNING,
"ImmGetCandidateList: Lock hCandInfo %x failed",
01047 pInputContext->hCandInfo);
01048
goto GetCandListUnlockIMC;
01049 }
01050
01051
if (lpCandInfo->dwSize <
sizeof(CANDIDATEINFO)) {
01052 RIPMSG0(RIP_WARNING,
"ImmGetCandidateList: no candidate list.");
01053
goto GetCandListUnlockIMCC;
01054 }
01055
01056
01057
01058
01059
if (dwIndex >= lpCandInfo->dwCount) {
01060 RIPMSG0(RIP_WARNING,
"ImmGetCandidateList: dwIndex >= lpCandInfo->dwCount.");
01061
goto GetCandListUnlockIMCC;
01062 }
01063
01064 lpCandListTemp = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[dwIndex]);
01065
01066
if (fAnsi &&
TestICF(pClientImc,
IMCF_UNICODE)) {
01067
01068
01069
01070 dwBufLenTemp =
InternalGetCandidateListWtoA(lpCandListTemp,
NULL, 0, dwCodePage);
01071 }
01072
else if (!fAnsi && !
TestICF(pClientImc,
IMCF_UNICODE)) {
01073
01074
01075
01076 dwBufLenTemp =
InternalGetCandidateListAtoW(lpCandListTemp,
NULL, 0, dwCodePage);
01077 }
01078
else {
01079
01080
01081
01082 dwBufLenTemp = lpCandListTemp->dwSize;
01083 }
01084
01085
01086
01087
01088
if (dwBufLen == 0 || dwBufLenTemp == 0) {
01089 dwRet = dwBufLenTemp;
01090 }
01091
else if (!lpCandList) {
01092 RIPMSG0(RIP_WARNING,
"ImmGetCandidateList: Null lpCandList.");
01093 }
01094
else if (dwBufLen < dwBufLenTemp) {
01095 RIPMSG2(RIP_WARNING,
"ImmGetCandidateList: dwBufLen = %d too small, require = %d.",
01096 dwBufLen, dwBufLenTemp);
01097 }
else {
01098
if (fAnsi &&
TestICF(pClientImc,
IMCF_UNICODE)) {
01099 dwRet =
InternalGetCandidateListWtoA(lpCandListTemp, lpCandList, dwBufLenTemp, dwCodePage);
01100 }
01101
else if (!fAnsi && !
TestICF(pClientImc,
IMCF_UNICODE)) {
01102 dwRet =
InternalGetCandidateListAtoW(lpCandListTemp, lpCandList, dwBufLenTemp, dwCodePage);
01103 }
01104
else {
01105 RtlCopyMemory((LPBYTE)lpCandList, (LPBYTE)lpCandListTemp, dwBufLenTemp);
01106 dwRet = dwBufLenTemp;
01107 }
01108 }
01109
01110 GetCandListUnlockIMCC:
01111
ImmUnlockIMCC(pInputContext->hCandInfo);
01112
01113 GetCandListUnlockIMC:
01114
ImmUnlockIMC(hImc);
01115
01116 GetCandListUnlockClientImc:
01117
ImmUnlockClientImc(pClientImc);
01118
01119 GetCandListExit:
01120
return dwRet;
01121 }
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 DWORD WINAPI
ImmGetGuideLineA(
01134 HIMC hImc,
01135 DWORD dwIndex,
01136 LPSTR lpszBuf,
01137 DWORD dwBufLen)
01138 {
01139
return ImmGetGuideLineWorker(hImc, dwIndex,
01140 (LPBYTE)lpszBuf, dwBufLen,
TRUE);
01141 }
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153 DWORD WINAPI
ImmGetGuideLineW(
01154 HIMC hImc,
01155 DWORD dwIndex,
01156 LPWSTR lpwszBuf,
01157 DWORD dwBufLen)
01158 {
01159
return ImmGetGuideLineWorker(hImc, dwIndex,
01160 (LPBYTE)lpwszBuf, dwBufLen,
FALSE);
01161 }
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173 DWORD ImmGetGuideLineWorker(
01174 HIMC hImc,
01175 DWORD dwIndex,
01176 LPBYTE lpBuf,
01177 DWORD dwBufLen,
01178 BOOL fAnsi)
01179 {
01180
PCLIENTIMC pClientImc;
01181 PINPUTCONTEXT pInputContext;
01182 LPGUIDELINE lpGuideLine;
01183 LPBYTE lpBufTemp;
01184
DWORD dwRet = 0;
01185
DWORD dwBufLenNeeded;
01186
BOOL bUDC;
01187
DWORD dwCodePage;
01188
01189 pClientImc =
ImmLockClientImc(hImc);
01190
if (pClientImc ==
NULL) {
01191 RIPMSG1(RIP_WARNING,
"ImmGetGuideLine: Invalid hImc %lx.", hImc);
01192
goto GetGuideLineExit;
01193 }
01194 dwCodePage =
CImcCodePage(pClientImc);
01195
01196 pInputContext =
ImmLockIMC(hImc);
01197
if (pInputContext ==
NULL) {
01198 RIPMSG1(RIP_WARNING,
"ImmGetGuideLine: Lock hImc %lx failed.", hImc);
01199
goto GetGuideLineUnlockClientImc;
01200 }
01201
01202 lpGuideLine = (LPGUIDELINE)
ImmLockIMCC(pInputContext->hGuideLine);
01203
if (!lpGuideLine) {
01204 RIPMSG1(RIP_WARNING,
"ImmGetGuideLine: Lock hGuideLine %lx failed.",
01205 pInputContext->hGuideLine);
01206
goto GetGuideLineUnlockIMC;
01207 }
01208
01209
switch (dwIndex) {
01210
case GGL_LEVEL:
01211 dwRet = lpGuideLine->dwLevel;
01212
break;
01213
01214
case GGL_INDEX:
01215 dwRet = lpGuideLine->dwIndex;
01216
break;
01217
01218
case GGL_STRING:
01219
01220 lpBufTemp = (LPBYTE)lpGuideLine + lpGuideLine->dwStrOffset;
01221
01222
01223
01224
01225
if (fAnsi &&
TestICF(pClientImc,
IMCF_UNICODE)) {
01226 dwBufLenNeeded = WideCharToMultiByte(dwCodePage,
01227 (
DWORD)0,
01228 (LPWSTR)lpBufTemp,
01229 (
INT)lpGuideLine->dwStrLen,
01230 (LPSTR)
NULL,
01231 (
INT)0,
01232 (LPSTR)
NULL,
01233 (LPBOOL)&bUDC);
01234 }
01235
else if (!fAnsi && !
TestICF(pClientImc,
IMCF_UNICODE)) {
01236 dwBufLenNeeded = MultiByteToWideChar(dwCodePage,
01237 (
DWORD)MB_PRECOMPOSED,
01238 (LPSTR)lpBufTemp,
01239 (
INT)lpGuideLine->dwStrLen,
01240 (LPWSTR)
NULL,
01241 (
INT)0);
01242 dwBufLenNeeded *=
sizeof(WCHAR);
01243 }
01244
else {
01245 dwBufLenNeeded = lpGuideLine->dwStrLen;
01246
01247
01248
01249
if (
TestICF(pClientImc,
IMCF_UNICODE))
01250 dwBufLenNeeded *=
sizeof(WCHAR);
01251 }
01252
01253
01254
01255
01256
if (dwBufLen == 0 || dwBufLenNeeded == 0) {
01257 dwRet = dwBufLenNeeded;
01258
goto GetGuideLineUnlockIMCC;
01259 }
01260
01261
if (lpBuf ==
NULL || dwBufLen < dwBufLenNeeded)
01262
goto GetGuideLineUnlockIMCC;
01263
01264
if (fAnsi &&
TestICF(pClientImc,
IMCF_UNICODE)) {
01265 dwRet = WideCharToMultiByte(dwCodePage,
01266 (
DWORD)0,
01267 (LPWSTR)lpBufTemp,
01268 (
INT)lpGuideLine->dwStrLen,
01269 (LPSTR)lpBuf,
01270 (
INT)dwBufLen,
01271 (LPSTR)
NULL,
01272 (LPBOOL)&bUDC);
01273 }
01274
else if (!fAnsi && !
TestICF(pClientImc,
IMCF_UNICODE)) {
01275 dwRet = MultiByteToWideChar(dwCodePage,
01276 (
DWORD)MB_PRECOMPOSED,
01277 (LPSTR)lpBufTemp,
01278 (
INT)lpGuideLine->dwStrLen,
01279 (LPWSTR)lpBuf,
01280 (
INT)dwBufLen/
sizeof(WCHAR));
01281 dwRet *=
sizeof(WCHAR);
01282 }
01283
else {
01284 RtlCopyMemory(lpBuf, lpBufTemp, dwBufLenNeeded);
01285 dwRet = dwBufLenNeeded;
01286 }
01287
01288
break;
01289
01290
case GGL_PRIVATE:
01291
01292 lpBufTemp = (LPBYTE)lpGuideLine + lpGuideLine->dwPrivateOffset;
01293
01294
01295
01296
01297
01298
01299
if (fAnsi &&
TestICF(pClientImc,
IMCF_UNICODE) &&
01300 lpGuideLine->dwIndex == GL_ID_REVERSECONVERSION) {
01301 dwBufLenNeeded =
InternalGetCandidateListWtoA(
01302 (LPCANDIDATELIST)lpBufTemp, (LPCANDIDATELIST)
NULL, 0, dwCodePage);
01303 }
01304
else if (!fAnsi && !
TestICF(pClientImc,
IMCF_UNICODE) &&
01305 lpGuideLine->dwIndex == GL_ID_REVERSECONVERSION) {
01306 dwBufLenNeeded =
InternalGetCandidateListAtoW(
01307 (LPCANDIDATELIST)lpBufTemp, (LPCANDIDATELIST)
NULL, 0, dwCodePage);
01308 }
01309
else {
01310 dwBufLenNeeded = lpGuideLine->dwPrivateSize;
01311 }
01312
01313
01314
01315
01316
if (dwBufLen == 0 || dwBufLenNeeded == 0) {
01317 dwRet = dwBufLenNeeded;
01318
goto GetGuideLineUnlockIMCC;
01319 }
01320
01321
if (lpBuf ==
NULL || dwBufLen < dwBufLenNeeded)
01322
goto GetGuideLineUnlockIMCC;
01323
01324
if (fAnsi &&
TestICF(pClientImc,
IMCF_UNICODE) &&
01325 lpGuideLine->dwIndex == GL_ID_REVERSECONVERSION) {
01326 dwRet =
InternalGetCandidateListWtoA(
01327 (LPCANDIDATELIST)lpBufTemp, (LPCANDIDATELIST)lpBuf, dwBufLenNeeded, dwCodePage);
01328 }
01329
else if (!fAnsi && !
TestICF(pClientImc,
IMCF_UNICODE) &&
01330 lpGuideLine->dwIndex == GL_ID_REVERSECONVERSION) {
01331 dwRet =
InternalGetCandidateListAtoW(
01332 (LPCANDIDATELIST)lpBufTemp, (LPCANDIDATELIST)lpBuf, dwBufLenNeeded, dwCodePage);
01333 }
01334
else {
01335 RtlCopyMemory(lpBuf, lpBufTemp, dwBufLenNeeded);
01336 dwRet = dwBufLenNeeded;
01337 }
01338
01339
break;
01340
01341
default:
01342
break;
01343 }
01344
01345 GetGuideLineUnlockIMCC:
01346
ImmUnlockIMCC(pInputContext->hGuideLine);
01347
01348 GetGuideLineUnlockIMC:
01349
ImmUnlockIMC(hImc);
01350
01351 GetGuideLineUnlockClientImc:
01352
ImmUnlockClientImc(pClientImc);
01353
01354 GetGuideLineExit:
01355
return dwRet;
01356 }
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368 BOOL WINAPI
ImmGetConversionStatus(
01369 HIMC hImc,
01370 LPDWORD lpfdwConversion,
01371 LPDWORD lpfdwSentence)
01372 {
01373 PINPUTCONTEXT pInputContext;
01374
01375 pInputContext =
ImmLockIMC(hImc);
01376
if (pInputContext ==
NULL) {
01377 RIPMSG1(RIP_WARNING,
"ImmGetConversionStatus: Lock hImc %lx failed", hImc);
01378
return FALSE;
01379 }
01380
01381
if (lpfdwConversion !=
NULL)
01382 *lpfdwConversion = pInputContext->fdwConversion;
01383
01384
if (lpfdwSentence !=
NULL)
01385 *lpfdwSentence = pInputContext->fdwSentence;
01386
01387
ImmUnlockIMC(hImc);
01388
01389
return TRUE;
01390 }
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402 BOOL WINAPI
ImmSetConversionStatus(
01403 HIMC hImc,
01404 DWORD fdwConversion,
01405 DWORD fdwSentence)
01406 {
01407 PINPUTCONTEXT pInputContext;
01408
DWORD fdwOldConversion;
01409
DWORD fdwOldSentence;
01410
BOOL fConvModeChg;
01411
BOOL fSentenceChg;
01412 HWND
hWnd;
01413
DWORD dwOpenStatus;
01414
DWORD dwConversion;
01415
01416
if (
GetInputContextThread(hImc) != GetCurrentThreadId()) {
01417 RIPMSG1(RIP_WARNING,
01418
"ImmSetConversionStatus: Invalid input context access %lx.", hImc);
01419
return FALSE;
01420 }
01421
01422 pInputContext =
ImmLockIMC(hImc);
01423
if (pInputContext ==
NULL) {
01424 RIPMSG1(RIP_WARNING,
01425
"ImmSetConversionStatus: Lock hImc %lx failed", hImc);
01426
return FALSE;
01427 }
01428
01429 fConvModeChg =
FALSE;
01430 fSentenceChg =
FALSE;
01431
01432
if (pInputContext->fdwConversion != fdwConversion) {
01433
if ((fdwConversion & IME_CMODE_LANGUAGE) == IME_CMODE_KATAKANA) {
01434 RIPMSG0(RIP_WARNING,
"ImmSetConversionStatus: wrong fdwConversion");
01435 }
01436 fdwOldConversion = pInputContext->fdwConversion;
01437 pInputContext->fdwConversion = fdwConversion;
01438 fConvModeChg =
TRUE;
01439 }
01440
01441
if (pInputContext->fdwSentence != fdwSentence) {
01442 fdwOldSentence = pInputContext->fdwSentence;
01443 pInputContext->fdwSentence = fdwSentence;
01444 fSentenceChg =
TRUE;
01445 }
01446
01447
hWnd = pInputContext->hWnd;
01448
if ( fConvModeChg ) {
01449
01450 dwOpenStatus = (
DWORD)pInputContext->fOpen;
01451 dwConversion = pInputContext->fdwConversion;
01452 }
01453
01454
ImmUnlockIMC(hImc);
01455
01456
#ifdef LATER
01457
01458
#endif
01459
01460
01461
01462
01463
if (fConvModeChg) {
01464
MakeIMENotify(hImc,
hWnd, NI_CONTEXTUPDATED, fdwOldConversion,
01465 IMC_SETCONVERSIONMODE, IMN_SETCONVERSIONMODE, 0
L);
01466
01467
01468
01469
01470
NtUserNotifyIMEStatus(
hWnd, dwOpenStatus, dwConversion );
01471 }
01472
01473
01474
01475
01476
if (fSentenceChg) {
01477
MakeIMENotify(hImc,
hWnd, NI_CONTEXTUPDATED, fdwOldSentence,
01478 IMC_SETSENTENCEMODE, IMN_SETSENTENCEMODE, 0
L);
01479 }
01480
01481
return TRUE;
01482 }
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494 BOOL WINAPI
ImmGetOpenStatus(
01495 HIMC hImc)
01496 {
01497 PINPUTCONTEXT pInputContext;
01498
BOOL fOpen;
01499
01500
if (hImc ==
NULL_HIMC)
01501
return FALSE;
01502
01503 pInputContext =
ImmLockIMC(hImc);
01504
if (!pInputContext) {
01505 RIPMSG1(RIP_WARNING,
"ImmGetOpenStatus: Lock hImc %lx failed", hImc);
01506
return FALSE;
01507 }
01508
01509 fOpen = pInputContext->fOpen;
01510
ImmUnlockIMC(hImc);
01511
01512
return (fOpen);
01513 }
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525 BOOL WINAPI
ImmSetOpenStatus(
01526 HIMC hImc,
01527 BOOL fOpen)
01528 {
01529 PINPUTCONTEXT pInputContext;
01530 HWND
hWnd;
01531
DWORD dwOpenStatus;
01532
DWORD dwConversion;
01533
BOOL fOpenChg =
FALSE;
01534
01535
if (
GetInputContextThread(hImc) != GetCurrentThreadId()) {
01536 RIPMSG1(RIP_WARNING,
01537
"ImmSetOpenStatus: Invalid input context access %lx.", hImc);
01538
return FALSE;
01539 }
01540
01541 pInputContext =
ImmLockIMC(hImc);
01542
if (!pInputContext) {
01543 RIPMSG1(RIP_WARNING,
"ImmSetOpenStatus: Lock hImc %lx failed", hImc);
01544
return FALSE;
01545 }
01546
01547
if (pInputContext->fOpen != fOpen) {
01548 fOpenChg =
TRUE;
01549 pInputContext->fOpen = fOpen;
01550 }
01551
01552
if ( fOpenChg ) {
01553
hWnd = (HWND)pInputContext->hWnd;
01554 dwOpenStatus = (
DWORD)pInputContext->fOpen;
01555 dwConversion = (
DWORD)pInputContext->fdwConversion;
01556 }
01557
01558
ImmUnlockIMC(hImc);
01559
01560
01561
01562
01563
if (fOpenChg) {
01564
MakeIMENotify(hImc,
hWnd, NI_CONTEXTUPDATED, (
DWORD)0,
01565 IMC_SETOPENSTATUS, IMN_SETOPENSTATUS, 0
L);
01566
01567
NtUserNotifyIMEStatus(
hWnd, dwOpenStatus, dwConversion );
01568 }
01569
01570
return TRUE;
01571 }
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583 BOOL WINAPI
ImmGetCompositionFontA(
01584 HIMC hImc,
01585 LPLOGFONTA lpLogFontA)
01586 {
01587
PCLIENTIMC pClientImc;
01588 PINPUTCONTEXT pInputContext;
01589 LOGFONTW LogFontW;
01590
BOOL fUnicode, fRet;
01591
01592 pClientImc =
ImmLockClientImc(hImc);
01593
if (pClientImc ==
NULL) {
01594 RIPMSG1(RIP_WARNING,
"ImmGetCompositionFontA: Invalid hImc %lx.", hImc);
01595
return FALSE;
01596 }
01597
01598 fUnicode =
TestICF(pClientImc,
IMCF_UNICODE);
01599
01600
ImmUnlockClientImc(pClientImc);
01601
01602 pInputContext =
ImmLockIMC(hImc);
01603
if (pInputContext ==
NULL) {
01604 RIPMSG1(RIP_WARNING,
"ImmGetCompositionFontA: Lock hImc %lx failed.", hImc);
01605
return FALSE;
01606 }
01607
01608
if (fUnicode) {
01609
01610
ImmUnlockIMC(hImc);
01611
01612
if (
ImmGetCompositionFontW(hImc, &LogFontW)) {
01613
LFontWtoLFontA(&LogFontW, lpLogFontA);
01614
return (
TRUE);
01615 }
01616
01617
return FALSE;
01618 }
01619
01620
if ((pInputContext->fdwInit & INIT_LOGFONT) == INIT_LOGFONT) {
01621 *lpLogFontA = pInputContext->lfFont.A;
01622 fRet =
TRUE;
01623 }
01624
else {
01625 fRet =
FALSE;
01626 }
01627
01628
ImmUnlockIMC(hImc);
01629
01630
return fRet;
01631 }
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643 BOOL WINAPI
ImmGetCompositionFontW(
01644 HIMC hImc,
01645 LPLOGFONTW lpLogFontW)
01646 {
01647
PCLIENTIMC pClientImc;
01648 PINPUTCONTEXT pInputContext;
01649 LOGFONTA LogFontA;
01650
BOOL fUnicode, fRet;
01651
01652 pClientImc =
ImmLockClientImc(hImc);
01653
if (pClientImc ==
NULL) {
01654 RIPMSG1(RIP_WARNING,
"ImmGetCompositionFontW: Invalid hImc %lx.", hImc);
01655
return FALSE;
01656 }
01657
01658 fUnicode =
TestICF(pClientImc,
IMCF_UNICODE);
01659
01660
ImmUnlockClientImc(pClientImc);
01661
01662 pInputContext =
ImmLockIMC(hImc);
01663
if (!pInputContext) {
01664 RIPMSG1(RIP_WARNING,
"ImmGetCompositionFontW: Lock hImc %lx failed.", hImc);
01665
return (
FALSE);
01666 }
01667
01668
if (!fUnicode) {
01669
01670
ImmUnlockIMC(hImc);
01671
01672
if (
ImmGetCompositionFontA(hImc, &LogFontA)) {
01673
LFontAtoLFontW(&LogFontA, lpLogFontW);
01674
return (
TRUE);
01675 }
01676
01677
return FALSE;
01678 }
01679
01680
if ((pInputContext->fdwInit & INIT_LOGFONT) == INIT_LOGFONT) {
01681 *lpLogFontW = pInputContext->lfFont.W;
01682 fRet =
TRUE;
01683 }
01684
else {
01685 fRet =
FALSE;
01686 }
01687
01688
ImmUnlockIMC(hImc);
01689
01690
return fRet;
01691 }
01692
01693
01694 BOOL WINAPI
ImmSetCompositionFontA(
01695 HIMC hImc,
01696 LPLOGFONTA lpLogFontA)
01697 {
01698
PCLIENTIMC pClientImc;
01699 PINPUTCONTEXT pInputContext;
01700 LOGFONTW LogFontW;
01701 HWND
hWnd;
01702
BOOL fUnicode;
01703
01704
if (
GetInputContextThread(hImc) != GetCurrentThreadId()) {
01705 RIPMSG1(RIP_WARNING,
01706
"ImmSetCompositionFontA: Invalid input context access %lx.", hImc);
01707
return FALSE;
01708 }
01709
01710 pClientImc =
ImmLockClientImc(hImc);
01711
if (pClientImc ==
NULL) {
01712 RIPMSG1(RIP_WARNING,
"ImmSetCompositionFontA: Invalid hImc %lx.", hImc);
01713
return FALSE;
01714 }
01715
01716 fUnicode =
TestICF(pClientImc,
IMCF_UNICODE);
01717
01718
ImmUnlockClientImc(pClientImc);
01719
01720 pInputContext =
ImmLockIMC(hImc);
01721
if (!pInputContext) {
01722 RIPMSG1(RIP_WARNING,
"ImmSetCompositionFontA: Lock hImc %lx failed.", hImc);
01723
return (
FALSE);
01724 }
01725
01726
if (fUnicode) {
01727
01728
ImmUnlockIMC(hImc);
01729
01730
LFontAtoLFontW(lpLogFontA, &LogFontW);
01731
01732
return ImmSetCompositionFontW(hImc, &LogFontW);
01733 }
01734
01735
01736
01737
01738
01739
if ( (
GetClientInfo()->dwExpWinVer <
VER40) &&
01740 (PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) == LANG_JAPANESE) &&
01741 ! (pInputContext->fdw31Compat & F31COMPAT_MCWHIDDEN) &&
01742 (pInputContext->cfCompForm.dwStyle != CFS_DEFAULT) ) {
01743
01744 PostMessageA( pInputContext->hWnd, WM_IME_REPORT, IR_CHANGECONVERT, (LPARAM)
NULL);
01745 }
01746
01747 pInputContext->lfFont.A = *lpLogFontA;
01748 pInputContext->fdwInit |= INIT_LOGFONT;
01749
hWnd = pInputContext->hWnd;
01750
01751
ImmUnlockIMC(hImc);
01752
01753
01754
01755
01756
MakeIMENotify(hImc,
hWnd, NI_CONTEXTUPDATED, 0
L,
01757 IMC_SETCOMPOSITIONFONT, IMN_SETCOMPOSITIONFONT, 0
L);
01758
01759
01760
return TRUE;
01761 }
01762
01763
01764 BOOL WINAPI
ImmSetCompositionFontW(
01765 HIMC hImc,
01766 LPLOGFONTW lpLogFontW)
01767 {
01768
PCLIENTIMC pClientImc;
01769 PINPUTCONTEXT pInputContext;
01770 LOGFONTA LogFontA;
01771 HWND
hWnd;
01772
BOOL fUnicode;
01773
01774
if (
GetInputContextThread(hImc) != GetCurrentThreadId()) {
01775 RIPMSG1(RIP_WARNING,
01776
"ImmSetCompositionFontW: Invalid input context access %lx.", hImc);
01777
return FALSE;
01778 }
01779
01780 pClientImc =
ImmLockClientImc(hImc);
01781
if (pClientImc ==
NULL) {
01782 RIPMSG1(RIP_WARNING,
"ImmSetCompositionFontW: Invalid hImc %lx.", hImc);
01783
return (
FALSE);
01784 }
01785
01786 fUnicode =
TestICF(pClientImc,
IMCF_UNICODE);
01787
01788
ImmUnlockClientImc(pClientImc);
01789
01790 pInputContext =
ImmLockIMC(hImc);
01791
if (!pInputContext) {
01792 RIPMSG1(RIP_WARNING,
"ImmSetCompositionFontW: Lock hImc %lx failed.", hImc);
01793
return (
FALSE);
01794 }
01795
01796
if (!fUnicode) {
01797
01798
ImmUnlockIMC(hImc);
01799
01800
LFontWtoLFontA(lpLogFontW, &LogFontA);
01801
01802
return ImmSetCompositionFontA(hImc, &LogFontA);
01803 }
01804
01805
01806
01807
01808
01809
if ( (
GetClientInfo()->dwExpWinVer <
VER40) &&
01810 (PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) == LANG_JAPANESE) &&
01811 ! (pInputContext->fdw31Compat & F31COMPAT_MCWHIDDEN) &&
01812 (pInputContext->cfCompForm.dwStyle != CFS_DEFAULT) ) {
01813
01814 PostMessageW( pInputContext->hWnd, WM_IME_REPORT, IR_CHANGECONVERT, (LPARAM)
NULL);
01815 }
01816 pInputContext->lfFont.W = *lpLogFontW;
01817 pInputContext->fdwInit |= INIT_LOGFONT;
01818
hWnd = pInputContext->hWnd;
01819
01820
ImmUnlockIMC(hImc);
01821
01822
01823
01824
01825
MakeIMENotify(hImc,
hWnd, NI_CONTEXTUPDATED, 0
L,
01826 IMC_SETCOMPOSITIONFONT, IMN_SETCOMPOSITIONFONT, 0
L);
01827
01828
return TRUE;
01829 }
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841 DWORD WINAPI
ImmGetConversionListA(
01842 HKL hKL,
01843 HIMC hImc,
01844 LPCSTR lpszSrc,
01845 LPCANDIDATELIST lpCandListA,
01846 DWORD dwBufLen,
01847 UINT uFlag)
01848 {
01849
PIMEDPI pImeDpi;
01850
DWORD dwRet;
01851 LPWSTR lpwszSrc;
01852
DWORD dwBufTemp;
01853 LPCANDIDATELIST lpCandListW;
01854
INT i;
01855
DWORD dwCodePage;
01856
01857 pImeDpi =
FindOrLoadImeDpi(hKL);
01858
01859
if (pImeDpi ==
NULL) {
01860 RIPMSG1(RIP_WARNING,
01861
"ImmGetConversionListA: cannot find DPI entry for hkl=%lx", hKL);
01862
return (0);
01863 }
01864
01865 dwCodePage =
IMECodePage(pImeDpi);
01866
01867
if (!(pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE)) {
01868
01869
01870
01871 dwRet = (*pImeDpi->
pfn.
ImeConversionList.a)(hImc, lpszSrc,
01872 lpCandListA, dwBufLen, uFlag);
01873
ImmUnlockImeDpi(pImeDpi);
01874
return dwRet;
01875 }
01876
01877
ImmUnlockImeDpi(pImeDpi);
01878
01879
01880
01881
01882
if (lpszSrc !=
NULL) {
01883
01884 dwBufTemp = (
strlen(lpszSrc) + 1) *
sizeof(WCHAR);
01885
01886 lpwszSrc =
ImmLocalAlloc(0, dwBufTemp);
01887
if (lpwszSrc ==
NULL)
01888
return (0);
01889
01890 i = MultiByteToWideChar(dwCodePage,
01891 (
DWORD)MB_PRECOMPOSED,
01892 (LPSTR)lpszSrc,
01893 (
INT)
strlen(lpszSrc),
01894 (LPWSTR)lpwszSrc,
01895 (
INT)dwBufTemp/
sizeof(WCHAR));
01896
01897 lpwszSrc[i] =
'\0';
01898 }
01899
else {
01900 lpwszSrc =
NULL;
01901 }
01902
01903
01904
01905
01906 dwBufTemp =
ImmGetConversionListW(hKL, hImc, lpwszSrc,
NULL, 0, uFlag);
01907
01908
if (dwBufTemp == 0 || (lpCandListW =
ImmLocalAlloc(0, dwBufTemp)) ==
NULL) {
01909
if (lpwszSrc)
01910
ImmLocalFree(lpwszSrc);
01911
return (0);
01912 }
01913
01914
01915
01916
01917 dwBufTemp =
ImmGetConversionListW(hKL, hImc, lpwszSrc,
01918 lpCandListW, dwBufTemp, uFlag);
01919
01920
01921
01922
01923
if (dwBufTemp != 0) {
01924 dwBufTemp =
InternalGetCandidateListWtoA(lpCandListW,
NULL, 0, dwCodePage);
01925 }
01926
01927
if (dwBufLen == 0 || dwBufTemp == 0) {
01928
01929
01930
01931 dwRet = dwBufTemp;
01932 }
01933
else if (dwBufLen < dwBufTemp) {
01934
01935
01936
01937 dwRet = 0;
01938 }
01939
else {
01940
01941
01942
01943 dwRet =
InternalGetCandidateListWtoA(lpCandListW, lpCandListA, dwBufLen, dwCodePage);
01944 }
01945
01946
if (lpwszSrc)
01947
ImmLocalFree(lpwszSrc);
01948
ImmLocalFree(lpCandListW);
01949
01950
return dwRet;
01951
01952 }
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964 DWORD WINAPI
ImmGetConversionListW(
01965 HKL hKL,
01966 HIMC hImc,
01967 LPCWSTR lpwszSrc,
01968 LPCANDIDATELIST lpCandListW,
01969 DWORD dwBufLen,
01970 UINT uFlag)
01971 {
01972
PIMEDPI pImeDpi;
01973
DWORD dwRet;
01974 LPSTR lpszSrc;
01975
DWORD dwBufTemp;
01976 LPCANDIDATELIST lpCandListA;
01977
BOOL bUDC;
01978
INT i;
01979
DWORD dwCodePage;
01980
01981 pImeDpi =
FindOrLoadImeDpi(hKL);
01982
01983
if (pImeDpi ==
NULL) {
01984 RIPMSG1(RIP_WARNING,
01985
"ImmGetConversionListW: cannot find DPI entry for hkl=%lx", hKL);
01986
return (0);
01987 }
01988
01989 dwCodePage =
IMECodePage(pImeDpi);
01990
01991
if (pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE) {
01992
01993
01994
01995 dwRet = (*pImeDpi->
pfn.
ImeConversionList.w)(hImc, lpwszSrc,
01996 lpCandListW, dwBufLen, uFlag);
01997
ImmUnlockImeDpi(pImeDpi);
01998
return dwRet;
01999 }
02000
02001
ImmUnlockImeDpi(pImeDpi);
02002
02003
02004
02005
02006
if (lpwszSrc !=
NULL) {
02007
02008 dwBufTemp = (wcslen(lpwszSrc) + 1) *
sizeof(WCHAR);
02009
02010 lpszSrc =
ImmLocalAlloc(0, dwBufTemp);
02011
if (lpszSrc ==
NULL)
02012
return (0);
02013
02014 i = WideCharToMultiByte(dwCodePage,
02015 (
DWORD)0,
02016 lpwszSrc,
02017 (
INT)wcslen(lpwszSrc),
02018 (LPSTR)lpszSrc,
02019 (
INT)dwBufTemp,
02020 (LPSTR)
NULL,
02021 (LPBOOL)&bUDC);
02022
02023 lpszSrc[i] =
'\0';
02024 }
02025
else {
02026 lpszSrc =
NULL;
02027 }
02028
02029
02030
02031
02032 dwBufTemp =
ImmGetConversionListA(hKL, hImc, lpszSrc,
NULL, 0, uFlag);
02033
02034
if (dwBufTemp == 0 || (lpCandListA =
ImmLocalAlloc(0, dwBufTemp)) ==
NULL) {
02035
if (lpszSrc)
02036
ImmLocalFree(lpszSrc);
02037
02038
return (0);
02039 }
02040
02041
02042
02043
02044 dwBufTemp =
ImmGetConversionListA(hKL, hImc, lpszSrc,
02045 lpCandListA, dwBufTemp, uFlag);
02046
02047
02048
02049
02050
if (dwBufTemp != 0) {
02051 dwBufTemp =
InternalGetCandidateListAtoW(lpCandListA,
NULL, 0, dwCodePage);
02052 }
02053
02054
if (dwBufLen == 0 || dwBufTemp == 0) {
02055
02056
02057
02058 dwRet = dwBufTemp;
02059 }
02060
else if (dwBufLen < dwBufTemp) {
02061
02062
02063
02064 dwRet = 0;
02065 }
02066
else {
02067
02068
02069
02070 dwRet =
InternalGetCandidateListAtoW(lpCandListA, lpCandListW, dwBufLen, dwCodePage);
02071 }
02072
02073
if (lpszSrc)
02074
ImmLocalFree(lpszSrc);
02075
ImmLocalFree(lpCandListA);
02076
02077
return dwRet;
02078 }
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090 BOOL WINAPI
ImmGetStatusWindowPos(
02091 HIMC hImc,
02092 LPPOINT lpptPos)
02093 {
02094 PINPUTCONTEXT pInputContext;
02095
BOOL fStatusWndPosInited;
02096
02097 pInputContext =
ImmLockIMC(hImc);
02098
if (!pInputContext) {
02099 RIPMSG1(RIP_WARNING,
"ImmGetStatusWindowPos: Lock hImc %lx failed", hImc);
02100
return FALSE;
02101 }
02102
02103 fStatusWndPosInited = ((pInputContext->fdwInit & INIT_STATUSWNDPOS) == INIT_STATUSWNDPOS);
02104
ImmUnlockIMC(hImc);
02105
02106
if (fStatusWndPosInited) {
02107 *lpptPos = pInputContext->ptStatusWndPos;
02108
return TRUE;
02109 }
02110
02111
return FALSE;
02112 }
02113
02114
02115 BOOL WINAPI
ImmSetStatusWindowPos(
02116 HIMC hImc,
02117 LPPOINT lpptPos)
02118 {
02119 PINPUTCONTEXT pInputContext;
02120 HWND
hWnd;
02121
02122
if (
GetInputContextThread(hImc) != GetCurrentThreadId()) {
02123 RIPMSG1(RIP_WARNING,
02124
"ImmSetStatusWindowPos: Invalid input context access %lx.", hImc);
02125
return FALSE;
02126 }
02127
02128 pInputContext =
ImmLockIMC(hImc);
02129
if (!pInputContext) {
02130 RIPMSG1(RIP_WARNING,
"ImmSetStatusWindowPos: Lock hImc %lx failed", hImc);
02131
return (
FALSE);
02132 }
02133
02134 pInputContext->ptStatusWndPos = *lpptPos;
02135 pInputContext->fdwInit |= INIT_STATUSWNDPOS;
02136
02137
hWnd = pInputContext->hWnd;
02138
02139
ImmUnlockIMC(hImc);
02140
02141
02142
02143
02144
MakeIMENotify(hImc,
hWnd, NI_CONTEXTUPDATED, 0
L,
02145 IMC_SETSTATUSWINDOWPOS, IMN_SETSTATUSWINDOWPOS, 0
L);
02146
02147
return TRUE;
02148 }
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160 BOOL WINAPI
ImmGetCompositionWindow(
02161 HIMC hImc,
02162 LPCOMPOSITIONFORM lpCompForm)
02163 {
02164 PINPUTCONTEXT pInputContext;
02165
BOOL fCompFormInited;
02166
02167 pInputContext =
ImmLockIMC(hImc);
02168
if (!pInputContext) {
02169 RIPMSG1(RIP_WARNING,
"ImmGetCompositionWindow: Lock hImc %lx failed", hImc);
02170
return FALSE;
02171 }
02172
02173 fCompFormInited = ((pInputContext->fdwInit & INIT_COMPFORM) == INIT_COMPFORM);
02174
ImmUnlockIMC(hImc);
02175
02176
if (fCompFormInited) {
02177 *lpCompForm = pInputContext->cfCompForm;
02178
return TRUE;
02179 }
02180
02181
return FALSE;
02182 }
02183
02184
02185 BOOL WINAPI
ImmSetCompositionWindow(
02186 HIMC hImc,
02187 LPCOMPOSITIONFORM lpCompForm)
02188 {
02189 PINPUTCONTEXT pInputContext;
02190 HWND
hWnd;
02191
02192
if (
GetInputContextThread(hImc) != GetCurrentThreadId()) {
02193 RIPMSG1(RIP_WARNING,
02194
"ImmSetCompositionWindow: Invalid input context access %lx.", hImc);
02195
return FALSE;
02196 }
02197
02198 pInputContext =
ImmLockIMC(hImc);
02199
if (!pInputContext) {
02200 RIPMSG1(RIP_WARNING,
"ImmSetCompositionWindow: Lock hImc %lx failed", hImc);
02201
return FALSE;
02202 }
02203
02204 pInputContext->cfCompForm = *lpCompForm;
02205 pInputContext->fdwInit |= INIT_COMPFORM;
02206
02207
02208
02209
02210
02211
02212
if (pInputContext->fdw31Compat & F31COMPAT_CALLFROMWINNLS)
02213 pInputContext->fdw31Compat &= ~F31COMPAT_CALLFROMWINNLS;
02214
else
02215 pInputContext->fdw31Compat &= ~F31COMPAT_MCWHIDDEN;
02216
02217
hWnd = pInputContext->hWnd;
02218
02219
ImmUnlockIMC(hImc);
02220
02221
02222
02223
02224
MakeIMENotify(hImc,
hWnd, NI_CONTEXTUPDATED, 0
L,
02225 IMC_SETCOMPOSITIONWINDOW, IMN_SETCOMPOSITIONWINDOW, 0
L);
02226
02227
return TRUE;
02228 }
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240 BOOL WINAPI
ImmGetCandidateWindow(
02241 HIMC hImc,
02242 DWORD dwIndex,
02243 LPCANDIDATEFORM lpCandForm)
02244 {
02245 PINPUTCONTEXT pInputContext;
02246
02247 pInputContext =
ImmLockIMC(hImc);
02248
if (!pInputContext) {
02249 RIPMSG1(RIP_WARNING,
"ImmGetCandidateWindow: Lock hImc %lx failed", hImc);
02250
return FALSE;
02251 }
02252
02253
ImmUnlockIMC(hImc);
02254
02255
if (pInputContext->cfCandForm[dwIndex].dwIndex == -1) {
02256
ImmUnlockIMC(hImc);
02257
return (
FALSE);
02258 }
02259
02260 *lpCandForm = pInputContext->cfCandForm[dwIndex];
02261
ImmUnlockIMC(hImc);
02262
return TRUE;
02263 }
02264
02265
02266 BOOL WINAPI
ImmSetCandidateWindow(
02267 HIMC hImc,
02268 LPCANDIDATEFORM lpCandForm)
02269 {
02270 PINPUTCONTEXT pInputContext;
02271 HWND
hWnd;
02272
02273
if (lpCandForm->dwIndex >= 4)
02274
return (
FALSE);
02275
02276
if (
GetInputContextThread(hImc) != GetCurrentThreadId()) {
02277 RIPMSG1(RIP_WARNING,
02278
"ImmSetCandidateWindow: Invalid input context access %lx.", hImc);
02279
return FALSE;
02280 }
02281
02282 pInputContext =
ImmLockIMC(hImc);
02283
if (!pInputContext) {
02284 RIPMSG1(RIP_WARNING,
"ImmSetCandidateWindow: Lock hImc %lx failed", hImc);
02285
return FALSE;
02286 }
02287
02288 pInputContext->cfCandForm[lpCandForm->dwIndex] = *lpCandForm;
02289
02290
hWnd = pInputContext->hWnd;
02291
02292
ImmUnlockIMC(hImc);
02293
02294
02295
02296
02297
MakeIMENotify(hImc,
hWnd, NI_CONTEXTUPDATED, 0
L, IMC_SETCANDIDATEPOS,
02298 IMN_SETCANDIDATEPOS, (LPARAM)(0x01 << lpCandForm->dwIndex));
02299
02300
return TRUE;
02301 }
02302
02303
02304 #define GetCompInfoA(Component) \
02305
if (!dwBufLen) { \
02306 \
02307 dwBufLen = pCompStr->dw ## Component ## Len * sizeof(CHAR); \
02308 } else { \
02309 if (dwBufLen > pCompStr->dw ## Component ## Len * sizeof(CHAR)) { \
02310 dwBufLen = pCompStr->dw ## Component ## Len * sizeof(CHAR); \
02311 } \
02312 \
02313 RtlCopyMemory((LPBYTE)lpBuf, (LPBYTE)pCompStr + \
02314 pCompStr->dw ## Component ## Offset, dwBufLen); \
02315 }
02316
02317 #define GetCompInfoW(Component) \
02318
if (!dwBufLen) { \
02319 \
02320 dwBufLen = pCompStr->dw ## Component ## Len * sizeof(WCHAR); \
02321 } else { \
02322 if (dwBufLen > pCompStr->dw ## Component ## Len * sizeof(WCHAR)) { \
02323 dwBufLen = pCompStr->dw ## Component ## Len * sizeof(WCHAR); \
02324 } \
02325 \
02326 RtlCopyMemory((LPBYTE)lpBuf, (LPBYTE)pCompStr + \
02327 pCompStr->dw ## Component ## Offset, dwBufLen); \
02328 }
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339 LONG
InternalGetCompositionStringA(
02340 PCOMPOSITIONSTRING pCompStr,
02341 DWORD dwIndex,
02342 LPVOID lpBuf,
02343 DWORD dwBufLen,
02344 BOOL fAnsiImc,
02345 DWORD dwCodePage)
02346 {
02347
if (fAnsiImc) {
02348
02349
02350
02351
switch (dwIndex) {
02352
case GCS_COMPSTR:
02353
GetCompInfoA(CompStr);
02354
break;
02355
case GCS_COMPATTR:
02356
GetCompInfoA(CompAttr);
02357
break;
02358
case GCS_COMPREADSTR:
02359
GetCompInfoA(CompReadStr);
02360
break;
02361
case GCS_COMPREADATTR:
02362
GetCompInfoA(CompReadAttr);
02363
break;
02364
case GCS_COMPREADCLAUSE:
02365
GetCompInfoA(CompReadClause);
02366
break;
02367
case GCS_CURSORPOS:
02368 dwBufLen = (LONG)pCompStr->dwCursorPos;
02369
break;
02370
case GCS_DELTASTART:
02371 dwBufLen = (LONG)pCompStr->dwDeltaStart;
02372
break;
02373
case GCS_RESULTSTR:
02374
GetCompInfoA(ResultStr);
02375
break;
02376
case GCS_RESULTCLAUSE:
02377
GetCompInfoA(ResultClause);
02378
break;
02379
case GCS_RESULTREADSTR:
02380
GetCompInfoA(ResultReadStr);
02381
break;
02382
case GCS_RESULTREADCLAUSE:
02383
GetCompInfoA(ResultReadClause);
02384
break;
02385
case GCS_COMPCLAUSE:
02386
GetCompInfoA(CompClause);
02387
break;
02388
default:
02389 dwBufLen = (
DWORD)(LONG)IMM_ERROR_GENERAL;
02390
break;
02391 }
02392
02393
return (LONG)dwBufLen;
02394 }
02395
02396
02397
02398
02399
switch (dwIndex) {
02400
case GCS_COMPSTR:
02401
case GCS_COMPREADSTR:
02402
case GCS_RESULTSTR:
02403
case GCS_RESULTREADSTR:
02404 {
02405
DWORD dwStrSize;
02406 LPWSTR lpStrW;
02407
BOOL bUDC;
02408
02409
02410
02411
02412 dwStrSize =
InternalGetCompositionStringW(pCompStr, dwIndex,
02413
NULL, 0, fAnsiImc, dwCodePage);
02414
02415 lpStrW =
ImmLocalAlloc(HEAP_ZERO_MEMORY, dwStrSize +
sizeof(WCHAR));
02416
if (lpStrW ==
NULL) {
02417 RIPMSG0(RIP_WARNING,
"InternalGetCompositionStringA: memory failure.");
02418
return (LONG)IMM_ERROR_GENERAL;
02419 }
02420
02421 dwStrSize =
InternalGetCompositionStringW(pCompStr, dwIndex,
02422 lpStrW, dwStrSize, fAnsiImc, dwCodePage);
02423
02424 dwBufLen = WideCharToMultiByte(dwCodePage,
02425 (
DWORD)0,
02426 lpStrW,
02427 wcslen(lpStrW),
02428 (LPSTR)lpBuf,
02429 dwBufLen,
02430 (LPSTR)
NULL,
02431 (LPBOOL)&bUDC);
02432
02433
ImmLocalFree(lpStrW);
02434
break;
02435 }
02436
02437
case GCS_COMPATTR:
02438
case GCS_COMPREADATTR:
02439 {
02440
DWORD dwAttrLenW, dwIndexStr, dwStrSize;
02441
PBYTE lpAttrA, lpAttrW;
02442 LPSTR lpStrA, lpStrT;
02443
CHAR c;
02444
02445
02446
02447
02448
switch (dwIndex) {
02449
case GCS_COMPATTR:
02450 lpAttrW = (
PBYTE)pCompStr + pCompStr->dwCompAttrOffset;
02451 dwAttrLenW = pCompStr->dwCompAttrLen;
02452 dwIndexStr = GCS_COMPSTR;
02453
break;
02454
case GCS_COMPREADATTR:
02455 lpAttrW = (
PBYTE)pCompStr + pCompStr->dwCompReadAttrOffset;
02456 dwAttrLenW = pCompStr->dwCompReadAttrLen;
02457 dwIndexStr = GCS_COMPREADSTR;
02458
break;
02459 }
02460
02461
if (dwAttrLenW == 0) {
02462
02463
02464
02465
return 0;
02466 }
02467
02468 dwStrSize =
InternalGetCompositionStringA(pCompStr,
02469 dwIndexStr,
NULL, 0, fAnsiImc, dwCodePage);
02470
02471
if (dwStrSize == (
DWORD)(LONG)IMM_ERROR_GENERAL) {
02472 RIPMSG0(RIP_WARNING,
"InternalGetCompositionStringA: IMM_ERROR_GENERAL.");
02473
return (LONG)IMM_ERROR_GENERAL;
02474 }
02475
02476
02477
02478
02479
if (dwBufLen == 0 || dwStrSize == 0)
02480
return dwStrSize;
02481
02482 lpStrA =
ImmLocalAlloc(HEAP_ZERO_MEMORY, dwStrSize +
sizeof(
CHAR));
02483
if (lpStrA ==
NULL) {
02484 RIPMSG0(RIP_WARNING,
"InternalGetCompositionStringA: memory failure.");
02485
return (LONG)IMM_ERROR_GENERAL;
02486 }
02487
02488 dwStrSize =
InternalGetCompositionStringA(pCompStr,
02489 dwIndexStr, lpStrA, dwStrSize, fAnsiImc, dwCodePage);
02490
02491
if (dwStrSize == (LONG)IMM_ERROR_GENERAL) {
02492 RIPMSG0(RIP_WARNING,
"InternalGetCompositionStringA: IMM_ERROR_GENERAL.");
02493
ImmLocalFree(lpStrA);
02494
return (LONG)IMM_ERROR_GENERAL;
02495 }
02496
02497 lpStrT = lpStrA;
02498 lpAttrA = (
PBYTE)lpBuf;
02499
02500
while ((
c=*lpStrT++) !=
'\0' && dwBufLen != 0 && dwAttrLenW-- != 0) {
02501
if (IsDBCSLeadByteEx(dwCodePage,
c)) {
02502
if (dwBufLen >= 2) {
02503 *lpAttrA++ = *lpAttrW;
02504 *lpAttrA++ = *lpAttrW;
02505 dwBufLen--;
02506 }
02507
else {
02508 *lpAttrA++ = *lpAttrW;
02509 }
02510 lpStrT++;
02511 }
02512
else {
02513 *lpAttrA++ = *lpAttrW;
02514 }
02515 lpAttrW++;
02516 dwBufLen--;
02517 }
02518
02519 dwBufLen = (
DWORD)(lpAttrA - (
PBYTE)lpBuf);
02520
02521
ImmLocalFree(lpStrA);
02522
break;
02523 }
02524
02525
case GCS_COMPCLAUSE:
02526
case GCS_COMPREADCLAUSE:
02527
case GCS_RESULTCLAUSE:
02528
case GCS_RESULTREADCLAUSE:
02529 {
02530 LPWSTR lpStrW;
02531
DWORD dwClauseLen, dwBufLenA;
02532 LPDWORD lpdwSrc, lpdwDst;
02533
UINT i;
02534
02535
02536
02537
02538
switch (dwIndex) {
02539
case GCS_COMPCLAUSE:
02540 lpStrW = (LPWSTR)((
PBYTE)pCompStr + pCompStr->dwCompStrOffset);
02541 lpdwSrc = (LPDWORD)((
PBYTE)pCompStr + pCompStr->dwCompClauseOffset);
02542 dwClauseLen = pCompStr->dwCompClauseLen;
02543
break;
02544
case GCS_COMPREADCLAUSE:
02545 lpStrW = (LPWSTR)((
PBYTE)pCompStr + pCompStr->dwCompReadStrOffset);
02546 lpdwSrc = (LPDWORD)((
PBYTE)pCompStr + pCompStr->dwCompReadClauseOffset);
02547 dwClauseLen = pCompStr->dwCompReadClauseLen;
02548
break;
02549
case GCS_RESULTCLAUSE:
02550 lpStrW = (LPWSTR)((
PBYTE)pCompStr + pCompStr->dwResultStrOffset);
02551 lpdwSrc = (LPDWORD)((
PBYTE)pCompStr + pCompStr->dwResultClauseOffset);
02552 dwClauseLen = pCompStr->dwResultClauseLen;
02553
break;
02554
case GCS_RESULTREADCLAUSE:
02555 lpStrW = (LPWSTR)((
PBYTE)pCompStr + pCompStr->dwResultReadStrOffset);
02556 lpdwSrc = (LPDWORD)((
PBYTE)pCompStr + pCompStr->dwResultReadClauseOffset);
02557 dwClauseLen = pCompStr->dwResultReadClauseLen;
02558
break;
02559 }
02560
02561
02562
02563
02564
if (dwBufLen == 0 || (LONG)dwClauseLen < 0) {
02565 dwBufLen = dwClauseLen;
02566
break;
02567 }
02568
02569 lpdwDst = (LPDWORD)lpBuf;
02570 dwBufLenA = dwBufLen /
sizeof(
DWORD);
02571
02572
for (i = 0; i < dwClauseLen /
sizeof(
DWORD) && dwBufLenA != 0; i++) {
02573 *lpdwDst++ =
CalcCharacterPositionWtoA(*lpdwSrc++, lpStrW, dwCodePage);
02574 dwBufLenA--;
02575 }
02576
02577 dwBufLen = i *
sizeof(
DWORD);
02578
break;
02579 }
02580
02581
case GCS_CURSORPOS:
02582
case GCS_DELTASTART:
02583
02584
02585
02586
switch (dwIndex) {
02587
case GCS_CURSORPOS:
02588 dwBufLen = pCompStr->dwCursorPos;
02589
break;
02590
case GCS_DELTASTART:
02591 dwBufLen = pCompStr->dwDeltaStart;
02592
break;
02593 }
02594
02595
if ((LONG)dwBufLen > 0) {
02596 dwBufLen =
CalcCharacterPositionWtoA(dwBufLen,
02597 (LPWSTR)((
PBYTE)pCompStr + pCompStr->dwCompStrOffset),
02598 dwCodePage);
02599 }
02600
break;
02601
02602
default:
02603 dwBufLen = (
DWORD)(LONG)IMM_ERROR_GENERAL;
02604 }
02605
02606
return (LONG)dwBufLen;
02607 }
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619 LONG
InternalGetCompositionStringW(
02620 PCOMPOSITIONSTRING pCompStr,
02621 DWORD dwIndex,
02622 LPVOID lpBuf,
02623 DWORD dwBufLen,
02624 BOOL fAnsiImc,
02625 DWORD dwCodePage)
02626 {
02627
if (!fAnsiImc) {
02628
02629
02630
02631
switch (dwIndex) {
02632
case GCS_COMPSTR:
02633
GetCompInfoW(CompStr);
02634
break;
02635
case GCS_COMPATTR:
02636
GetCompInfoA(CompAttr);
02637
break;
02638
case GCS_COMPREADSTR:
02639
GetCompInfoW(CompReadStr);
02640
break;
02641
case GCS_COMPREADATTR:
02642
GetCompInfoA(CompReadAttr);
02643
break;
02644
case GCS_COMPREADCLAUSE:
02645
GetCompInfoA(CompReadClause);
02646
break;
02647
case GCS_CURSORPOS:
02648 dwBufLen = (LONG)pCompStr->dwCursorPos;
02649
break;
02650
case GCS_DELTASTART:
02651 dwBufLen = (LONG)pCompStr->dwDeltaStart;
02652
break;
02653
case GCS_RESULTSTR:
02654
GetCompInfoW(ResultStr);
02655
break;
02656
case GCS_RESULTCLAUSE:
02657
GetCompInfoA(ResultClause);
02658
break;
02659
case GCS_RESULTREADSTR:
02660
GetCompInfoW(ResultReadStr);
02661
break;
02662
case GCS_RESULTREADCLAUSE:
02663
GetCompInfoA(ResultReadClause);
02664
break;
02665
case GCS_COMPCLAUSE:
02666
GetCompInfoA(CompClause);
02667
break;
02668
default:
02669 dwBufLen = (
DWORD)IMM_ERROR_GENERAL;
02670
break;
02671 }
02672
02673
return (LONG)dwBufLen;
02674 }
02675
02676
02677
02678
02679
switch (dwIndex) {
02680
case GCS_COMPSTR:
02681
case GCS_COMPREADSTR:
02682
case GCS_RESULTSTR:
02683
case GCS_RESULTREADSTR:
02684 {
02685
DWORD dwStrSize;
02686 LPSTR lpStrA;
02687
02688
02689
02690
02691 dwStrSize =
InternalGetCompositionStringA(pCompStr, dwIndex,
02692
NULL, 0, fAnsiImc, dwCodePage);
02693
02694 lpStrA =
ImmLocalAlloc(HEAP_ZERO_MEMORY, dwStrSize +
sizeof(
CHAR));
02695
if (lpStrA ==
NULL) {
02696 RIPMSG0(RIP_WARNING,
"InternalGetCompositionStringW: memory failure.");
02697
return (LONG)IMM_ERROR_GENERAL;
02698 }
02699
02700 dwStrSize =
InternalGetCompositionStringA(pCompStr, dwIndex,
02701 lpStrA, dwStrSize, fAnsiImc, dwCodePage);
02702
02703 dwBufLen = MultiByteToWideChar(dwCodePage,
02704 (
DWORD)MB_PRECOMPOSED,
02705 lpStrA,
02706
strlen(lpStrA),
02707 (LPWSTR)lpBuf,
02708 (
INT)dwBufLen);
02709
02710 dwBufLen *=
sizeof(WCHAR);
02711
02712
ImmLocalFree(lpStrA);
02713
break;
02714 }
02715
02716
case GCS_COMPATTR:
02717
case GCS_COMPREADATTR:
02718 {
02719
DWORD dwAttrLenA, dwIndexStr, dwStrSize;
02720
PBYTE lpAttrA, lpAttrW;
02721 LPWSTR lpStrW, lpStrT;
02722 ULONG MultiByteSize;
02723 WCHAR wc;
02724
02725
02726
02727
02728
switch (dwIndex) {
02729
case GCS_COMPATTR:
02730 lpAttrA = (
PBYTE)pCompStr + pCompStr->dwCompAttrOffset;
02731 dwAttrLenA = pCompStr->dwCompAttrLen;
02732 dwIndexStr = GCS_COMPSTR;
02733
break;
02734
case GCS_COMPREADATTR:
02735 lpAttrA = (
PBYTE)pCompStr + pCompStr->dwCompReadAttrOffset;
02736 dwAttrLenA = pCompStr->dwCompReadAttrLen;
02737 dwIndexStr = GCS_COMPREADSTR;
02738
break;
02739 }
02740
02741
if (dwAttrLenA == 0) {
02742
02743
02744
02745
return 0;
02746 }
02747
02748 dwStrSize =
InternalGetCompositionStringW(pCompStr,
02749 dwIndexStr,
NULL, 0, fAnsiImc, dwCodePage);
02750
02751
if (dwStrSize == (
DWORD)(LONG)IMM_ERROR_GENERAL) {
02752 RIPMSG0(RIP_WARNING,
"InternalGetCompositionStringA: IMM_ERROR_GENERAL.");
02753
return (LONG)IMM_ERROR_GENERAL;
02754 }
02755
02756
02757
02758
02759
if (dwBufLen == 0 || dwStrSize == 0)
02760
return dwStrSize /
sizeof(WCHAR);
02761
02762 lpStrW =
ImmLocalAlloc(HEAP_ZERO_MEMORY, dwStrSize +
sizeof(WCHAR));
02763
if (lpStrW ==
NULL) {
02764 RIPMSG0(RIP_WARNING,
"InternalGetCompositionStringW: memory failure.");
02765
return (LONG)IMM_ERROR_GENERAL;
02766 }
02767
02768 dwStrSize =
InternalGetCompositionStringW(pCompStr,
02769 dwIndexStr, lpStrW, dwStrSize, fAnsiImc, dwCodePage);
02770
02771
if (dwStrSize == (LONG)IMM_ERROR_GENERAL) {
02772 RIPMSG0(RIP_WARNING,
"InternalGetCompositionStringA: IMM_ERROR_GENERAL.");
02773
ImmLocalFree(lpStrW);
02774
return (LONG)IMM_ERROR_GENERAL;
02775 }
02776
02777 lpStrT = lpStrW;
02778 lpAttrW = (
PBYTE)lpBuf;
02779
02780
while ((wc=*lpStrT++) !=
L'\0' && dwBufLen != 0 && dwAttrLenA-- != 0) {
02781 MultiByteSize =
UnicodeToMultiByteSize(dwCodePage, &wc);
02782
if (MultiByteSize == 2 && dwAttrLenA != 0) {
02783 *lpAttrW++ = *lpAttrA++;
02784 dwAttrLenA--;
02785 }
02786
else {
02787 *lpAttrW++ = *lpAttrA;
02788 }
02789 lpAttrA++;
02790 dwBufLen--;
02791 }
02792
02793 dwBufLen = (
DWORD)(lpAttrW - (
PBYTE)lpBuf);
02794
02795
ImmLocalFree(lpStrW);
02796
break;
02797 }
02798
02799
case GCS_COMPCLAUSE:
02800
case GCS_COMPREADCLAUSE:
02801
case GCS_RESULTCLAUSE:
02802
case GCS_RESULTREADCLAUSE:
02803 {
02804 LPSTR lpStrA;
02805
DWORD dwClauseLen, dwBufLenW;
02806 LPDWORD lpdwSrc, lpdwDst;
02807
UINT i;
02808
02809
02810
02811
02812
switch (dwIndex) {
02813
case GCS_COMPCLAUSE:
02814 lpStrA = (LPSTR)((
PBYTE)pCompStr + pCompStr->dwCompStrOffset);
02815 lpdwSrc = (LPDWORD)((
PBYTE)pCompStr + pCompStr->dwCompClauseOffset);
02816 dwClauseLen = pCompStr->dwCompClauseLen;
02817
break;
02818
case GCS_COMPREADCLAUSE:
02819 lpStrA = (LPSTR)((
PBYTE)pCompStr + pCompStr->dwCompReadStrOffset);
02820 lpdwSrc = (LPDWORD)((
PBYTE)pCompStr + pCompStr->dwCompReadClauseOffset);
02821 dwClauseLen = pCompStr->dwCompReadClauseLen;
02822
break;
02823
case GCS_RESULTCLAUSE:
02824 lpStrA = (LPSTR)((
PBYTE)pCompStr + pCompStr->dwResultStrOffset);
02825 lpdwSrc = (LPDWORD)((
PBYTE)pCompStr + pCompStr->dwResultClauseOffset);
02826 dwClauseLen = pCompStr->dwResultClauseLen;
02827
break;
02828
case GCS_RESULTREADCLAUSE:
02829 lpStrA = (LPSTR)((
PBYTE)pCompStr + pCompStr->dwResultReadStrOffset);
02830 lpdwSrc = (LPDWORD)((
PBYTE)pCompStr + pCompStr->dwResultReadClauseOffset);
02831 dwClauseLen = pCompStr->dwResultReadClauseLen;
02832
break;
02833 }
02834
02835
02836
02837
02838
02839
if (dwBufLen == 0 || (LONG)dwClauseLen < 0) {
02840 dwBufLen = dwClauseLen;
02841
break;
02842 }
02843
02844 lpdwDst = (LPDWORD)lpBuf;
02845 dwBufLenW = dwBufLen /
sizeof(
DWORD);
02846
02847
for (i = 0; i < dwClauseLen /
sizeof(
DWORD) && dwBufLenW != 0; i++) {
02848 *lpdwDst++ =
CalcCharacterPositionAtoW(*lpdwSrc++, lpStrA, dwCodePage);
02849 dwBufLenW--;
02850 }
02851
02852 dwBufLen = i *
sizeof(
DWORD);
02853
break;
02854 }
02855
02856
case GCS_CURSORPOS:
02857
case GCS_DELTASTART:
02858
02859
02860
02861
switch (dwIndex) {
02862
case GCS_CURSORPOS:
02863 dwBufLen = pCompStr->dwCursorPos;
02864
break;
02865
case GCS_DELTASTART:
02866 dwBufLen = pCompStr->dwDeltaStart;
02867
break;
02868 }
02869
02870
if ((LONG)dwBufLen > 0) {
02871 dwBufLen =
CalcCharacterPositionAtoW(dwBufLen,
02872 (LPSTR)((
PBYTE)pCompStr + pCompStr->dwCompStrOffset),
02873 dwCodePage);
02874 }
02875
break;
02876
02877
default:
02878 dwBufLen = (
DWORD)(LONG)IMM_ERROR_GENERAL;
02879 }
02880
02881
return (LONG)dwBufLen;
02882 }
02883
02884
02885 DWORD InternalGetCandidateListAtoW(
02886 LPCANDIDATELIST lpCandListA,
02887 LPCANDIDATELIST lpCandListW,
02888 DWORD dwBufLen,
02889 DWORD dwCodePage)
02890 {
02891 LPWSTR lpCandStrW;
02892 LPSTR lpCandStrA;
02893
INT i, j;
02894
DWORD dwCandListLen;
02895
02896 dwCandListLen =
sizeof(CANDIDATELIST);
02897
02898
02899
02900
02901
if (lpCandListA->dwCount > 0)
02902 dwCandListLen +=
sizeof(
DWORD) * (lpCandListA->dwCount - 1);
02903
02904
for (i = 0; i < (
INT)lpCandListA->dwCount; i++) {
02905
02906 lpCandStrA = (LPSTR)((LPBYTE)lpCandListA + lpCandListA->dwOffset[i]);
02907
02908 j = MultiByteToWideChar(dwCodePage,
02909 (
DWORD)MB_PRECOMPOSED,
02910 lpCandStrA,
02911 -1,
02912 (LPWSTR)
NULL,
02913 0);
02914
02915 dwCandListLen += (j *
sizeof(WCHAR));
02916 }
02917
02918 dwCandListLen =
DWORD_ALIGN(dwCandListLen);
02919
02920
if (dwBufLen == 0)
02921
return dwCandListLen;
02922
02923
if (dwBufLen < dwCandListLen) {
02924 RIPMSG0(RIP_WARNING,
"InternalGetCandidateListAtoW: dwBufLen too small.");
02925
return 0;
02926 }
02927
02928 lpCandListW->dwSize = dwBufLen;
02929 lpCandListW->dwStyle = lpCandListA->dwStyle;
02930 lpCandListW->dwCount = lpCandListA->dwCount;
02931 lpCandListW->dwSelection = lpCandListA->dwSelection;
02932 lpCandListW->dwPageStart = lpCandListA->dwPageStart;
02933 lpCandListW->dwPageSize = lpCandListA->dwPageSize;
02934 lpCandListW->dwOffset[0] =
sizeof(CANDIDATELIST);
02935
if (lpCandListW->dwCount > 0)
02936 lpCandListW->dwOffset[0] +=
sizeof(
DWORD) * (lpCandListW->dwCount - 1);
02937
02938 dwCandListLen = dwBufLen - lpCandListW->dwOffset[0];
02939
02940
for (i = 0; i < (
INT)lpCandListW->dwCount; i++) {
02941
02942 lpCandStrA = (LPSTR) ((LPBYTE)lpCandListA + lpCandListA->dwOffset[i]);
02943 lpCandStrW = (LPWSTR)((LPBYTE)lpCandListW + lpCandListW->dwOffset[i]);
02944
02945 j = MultiByteToWideChar(dwCodePage,
02946 (
DWORD)MB_PRECOMPOSED,
02947 lpCandStrA,
02948 -1,
02949 lpCandStrW,
02950 (
INT)dwCandListLen/
sizeof(WCHAR));
02951
02952 dwCandListLen -= (j *
sizeof(WCHAR));
02953
02954
if (i < (
INT)lpCandListW->dwCount - 1)
02955 lpCandListW->dwOffset[i+1] = lpCandListW->dwOffset[i] + j *
sizeof(WCHAR);
02956 }
02957
02958
return dwBufLen;
02959 }
02960
02961
02962 DWORD InternalGetCandidateListWtoA(
02963 LPCANDIDATELIST lpCandListW,
02964 LPCANDIDATELIST lpCandListA,
02965 DWORD dwBufLen,
02966 DWORD dwCodePage)
02967 {
02968 LPWSTR lpCandStrW;
02969 LPSTR lpCandStrA;
02970
INT i, j;
02971
DWORD dwCandListLen;
02972
BOOL bUDC;
02973
02974 dwCandListLen =
sizeof(CANDIDATELIST);
02975
02976
02977
02978
02979
if (lpCandListW->dwCount > 0)
02980 dwCandListLen +=
sizeof(
DWORD) * (lpCandListW->dwCount - 1);
02981
02982
for (i = 0; i < (
INT)lpCandListW->dwCount; i++) {
02983
02984 lpCandStrW = (LPWSTR)((LPBYTE)lpCandListW + lpCandListW->dwOffset[i]);
02985
02986 j = WideCharToMultiByte(dwCodePage,
02987 (
DWORD)0,
02988 lpCandStrW,
02989 -1,
02990 (LPSTR)
NULL,
02991 (
INT)0,
02992 (LPSTR)
NULL,
02993 (LPBOOL)&bUDC);
02994
02995 dwCandListLen += (j *
sizeof(
CHAR));
02996 }
02997
02998 dwCandListLen =
DWORD_ALIGN(dwCandListLen);
02999
03000
if (dwBufLen == 0)
03001
return dwCandListLen;
03002
03003
if (dwBufLen < dwCandListLen) {
03004 RIPMSG0(RIP_WARNING,
"InternalGetCandidateListWtoA: dwBufLen too small.");
03005
return 0;
03006 }
03007
03008 lpCandListA->dwSize = dwBufLen;
03009 lpCandListA->dwStyle = lpCandListW->dwStyle;
03010 lpCandListA->dwCount = lpCandListW->dwCount;
03011 lpCandListA->dwSelection = lpCandListW->dwSelection;
03012 lpCandListA->dwPageStart = lpCandListW->dwPageStart;
03013 lpCandListA->dwPageSize = lpCandListW->dwPageSize;
03014 lpCandListA->dwOffset[0] =
sizeof(CANDIDATELIST);
03015
if (lpCandListA->dwCount > 0)
03016 lpCandListA->dwOffset[0] +=
sizeof(
DWORD) * (lpCandListA->dwCount - 1);
03017
03018 dwCandListLen = dwBufLen - lpCandListA->dwOffset[0];
03019
03020
for (i = 0; i < (
INT)lpCandListA->dwCount; i++) {
03021
03022 lpCandStrA = (LPSTR) ((LPBYTE)lpCandListA + lpCandListA->dwOffset[i]);
03023 lpCandStrW = (LPWSTR)((LPBYTE)lpCandListW + lpCandListW->dwOffset[i]);
03024
03025 j = WideCharToMultiByte(dwCodePage,
03026 (
DWORD)0,
03027 lpCandStrW,
03028 -1,
03029 (LPSTR)lpCandStrA,
03030 (
INT)dwCandListLen,
03031 (LPSTR)
NULL,
03032 (LPBOOL)&bUDC);
03033
03034 dwCandListLen -= (j *
sizeof(
CHAR));
03035
03036
if (i < (
INT)lpCandListA->dwCount - 1)
03037 lpCandListA->dwOffset[i+1] = lpCandListA->dwOffset[i] + j *
sizeof(
CHAR);
03038 }
03039
03040
return dwBufLen;
03041 }
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052 DWORD CalcCharacterPositionAtoW(
03053 DWORD dwCharPosA,
03054 LPSTR lpszCharStr,
03055 DWORD dwCodePage)
03056 {
03057
DWORD dwCharPosW = 0;
03058
03059
while (dwCharPosA != 0) {
03060
if (IsDBCSLeadByteEx(dwCodePage, *lpszCharStr)) {
03061
if (dwCharPosA >= 2) {
03062 dwCharPosA -= 2;
03063 }
03064
else {
03065 dwCharPosA--;
03066 }
03067 lpszCharStr += 2;
03068 }
03069
else {
03070 dwCharPosA--;
03071 lpszCharStr++;
03072 }
03073 dwCharPosW++;
03074 }
03075
03076
return dwCharPosW;
03077 }
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089 DWORD CalcCharacterPositionWtoA(
03090 DWORD dwCharPosW,
03091 LPWSTR lpwszCharStr,
03092 DWORD dwCodePage)
03093 {
03094
DWORD dwCharPosA = 0;
03095 ULONG MultiByteSize;
03096
03097
while (dwCharPosW != 0) {
03098 MultiByteSize =
UnicodeToMultiByteSize(dwCodePage, lpwszCharStr);
03099
if (MultiByteSize == 2) {
03100 dwCharPosA += 2;
03101 }
03102
else {
03103 dwCharPosA++;
03104 }
03105 dwCharPosW--;
03106 lpwszCharStr++;
03107 }
03108
03109
return dwCharPosA;
03110 }
03111
03112
03113 VOID LFontAtoLFontW(
03114 LPLOGFONTA lpLogFontA,
03115 LPLOGFONTW lpLogFontW)
03116 {
03117
INT i;
03118
03119 RtlCopyMemory(lpLogFontW, lpLogFontA,
sizeof(LOGFONTA)-LF_FACESIZE);
03120
03121 i = MultiByteToWideChar(CP_ACP,
03122 MB_PRECOMPOSED,
03123 lpLogFontA->lfFaceName,
03124
strlen(lpLogFontA->lfFaceName),
03125 lpLogFontW->lfFaceName,
03126 LF_FACESIZE);
03127
03128 lpLogFontW->lfFaceName[i] =
L'\0';
03129
03130
return;
03131 }
03132
03133
03134 VOID LFontWtoLFontA(
03135 LPLOGFONTW lpLogFontW,
03136 LPLOGFONTA lpLogFontA)
03137 {
03138
INT i;
03139
BOOL bUDC;
03140
03141 RtlCopyMemory(lpLogFontA, lpLogFontW,
sizeof(LOGFONTA)-LF_FACESIZE);
03142
03143 i = WideCharToMultiByte(CP_ACP,
03144 0,
03145 lpLogFontW->lfFaceName,
03146 wcslen(lpLogFontW->lfFaceName),
03147 lpLogFontA->lfFaceName,
03148 LF_FACESIZE,
03149 (LPSTR)
NULL,
03150 &bUDC);
03151
03152 lpLogFontA->lfFaceName[i] =
'\0';
03153
03154
return;
03155 }
03156
03157
03158 BOOL MakeIMENotify(
03159 HIMC hImc,
03160 HWND hWnd,
03161 DWORD dwAction,
03162 DWORD dwIndex,
03163 DWORD dwValue,
03164 WPARAM wParam,
03165 LPARAM lParam)
03166 {
03167
PIMEDPI pImeDpi;
03168
DWORD dwThreadId;
03169
03170
#ifdef LATER
03171
03172
#endif
03173
03174
if (dwAction != 0 && (dwThreadId =
GetInputContextThread(hImc)) != 0) {
03175
03176 pImeDpi =
ImmLockImeDpi(
GetKeyboardLayout(dwThreadId));
03177
03178
if (pImeDpi !=
NULL) {
03179 (*pImeDpi->
pfn.
NotifyIME)(hImc, dwAction, dwIndex, dwValue);
03180
ImmUnlockImeDpi(pImeDpi);
03181 }
03182 }
03183
03184
if (
hWnd !=
NULL && wParam != 0)
03185
SendMessage(
hWnd, WM_IME_NOTIFY, wParam, lParam);
03186
03187
return TRUE;
03188 }
03189
03190
03191
03193
03195
03196 typedef enum {
FROM_IME,
FROM_APP}
REQ_CALLER;
03197
03199
03200
03201
03202
03203
03204
03206
03207 DWORD ImmGetReconvertTotalSize(DWORD dwSize, REQ_CALLER eCaller, BOOL bAnsiTarget)
03208 {
03209
if (dwSize <
sizeof(RECONVERTSTRING)) {
03210
return 0;
03211 }
03212
if (bAnsiTarget) {
03213 dwSize -=
sizeof(RECONVERTSTRING);
03214
if (eCaller ==
FROM_IME) {
03215 dwSize /= 2;
03216 }
else {
03217 dwSize *= 2;
03218 }
03219 dwSize +=
sizeof(RECONVERTSTRING);
03220 }
03221
return dwSize;
03222 }
03223
03224 DWORD ImmReconversionWorker(
03225 LPRECONVERTSTRING lpRecTo,
03226 LPRECONVERTSTRING lpRecFrom,
03227 BOOL bToAnsi,
03228 DWORD dwCodePage)
03229 {
03230
INT i;
03231
DWORD dwSize = 0;
03232
03233 UserAssert(lpRecTo);
03234 UserAssert(lpRecFrom);
03235
03236
if (lpRecFrom->dwVersion != 0 || lpRecTo->dwVersion != 0) {
03237 RIPMSG0(RIP_WARNING,
"ImmReconversionWorker: dwVersion in lpRecTo or lpRecFrom is incorrect.");
03238
return 0;
03239 }
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
if (bToAnsi) {
03251
03252 lpRecTo->dwStrOffset =
sizeof *lpRecTo;
03253 i = WideCharToMultiByte(dwCodePage,
03254 (
DWORD)0,
03255 (LPWSTR)((LPSTR)lpRecFrom + lpRecFrom->dwStrOffset),
03256 (
INT)lpRecFrom->dwStrLen,
03257 (LPSTR)lpRecTo + lpRecTo->dwStrOffset,
03258 (
INT)lpRecFrom->dwStrLen *
DBCS_CHARSIZE,
03259 (LPSTR)
NULL,
03260 (LPBOOL)
NULL);
03261 lpRecTo->dwCompStrOffset =
03262
CalcCharacterPositionWtoA(lpRecFrom->dwCompStrOffset /
sizeof(WCHAR),
03263 (LPWSTR)((LPBYTE)lpRecFrom + lpRecFrom->dwStrOffset),
03264 dwCodePage)
03265 *
sizeof(
CHAR);
03266
03267 lpRecTo->dwCompStrLen =
03268 (
CalcCharacterPositionWtoA(lpRecFrom->dwCompStrOffset /
sizeof(WCHAR) +
03269 lpRecFrom->dwCompStrLen,
03270 (LPWSTR)((LPBYTE)lpRecFrom + lpRecFrom->dwStrOffset),
03271 dwCodePage)
03272 *
sizeof(
CHAR))
03273 - lpRecTo->dwCompStrOffset;
03274
03275 lpRecTo->dwTargetStrOffset =
03276
CalcCharacterPositionWtoA(lpRecFrom->dwTargetStrOffset /
sizeof(WCHAR),
03277 (LPWSTR)((LPBYTE)lpRecFrom +
03278 lpRecFrom->dwStrOffset),
03279 dwCodePage)
03280 *
sizeof(
CHAR);
03281
03282 lpRecTo->dwTargetStrLen =
03283 (
CalcCharacterPositionWtoA(lpRecFrom->dwTargetStrOffset /
sizeof(WCHAR) +
03284 lpRecFrom->dwTargetStrLen,
03285 (LPWSTR)((LPBYTE)lpRecFrom + lpRecFrom->dwStrOffset),
03286 dwCodePage)
03287 *
sizeof(
CHAR))
03288 - lpRecTo->dwTargetStrOffset;
03289
03290 ((LPSTR)lpRecTo)[lpRecTo->dwStrOffset + i] =
'\0';
03291 lpRecTo->dwStrLen = i *
sizeof(
CHAR);
03292
03293 dwSize =
sizeof(RECONVERTSTRING) + ((i + 1) *
sizeof(
CHAR));
03294
03295 }
else {
03296
03297
03298 lpRecTo->dwStrOffset =
sizeof *lpRecTo;
03299 i = MultiByteToWideChar(dwCodePage,
03300 (
DWORD)MB_PRECOMPOSED,
03301 (LPSTR)lpRecFrom + lpRecFrom->dwStrOffset,
03302 (
INT)lpRecFrom->dwStrLen,
03303 (LPWSTR)((LPSTR)lpRecTo + lpRecTo->dwStrOffset),
03304 (
INT)lpRecFrom->dwStrLen);
03305
03306 lpRecTo->dwCompStrOffset =
03307
CalcCharacterPositionAtoW(lpRecFrom->dwCompStrOffset,
03308 (LPSTR)lpRecFrom + lpRecFrom->dwStrOffset,
03309 dwCodePage) *
sizeof(WCHAR);
03310
03311 lpRecTo->dwCompStrLen =
03312 ((
CalcCharacterPositionAtoW(lpRecFrom->dwCompStrOffset +
03313 lpRecFrom->dwCompStrLen,
03314 (LPSTR)lpRecFrom + lpRecFrom->dwStrOffset,
03315 dwCodePage) *
sizeof(WCHAR))
03316 - lpRecTo->dwCompStrOffset) /
sizeof(WCHAR);
03317
03318 lpRecTo->dwTargetStrOffset =
03319
CalcCharacterPositionAtoW(lpRecFrom->dwTargetStrOffset,
03320 (LPSTR)lpRecFrom + lpRecFrom->dwStrOffset,
03321 dwCodePage) *
sizeof(WCHAR);
03322
03323 lpRecTo->dwTargetStrLen =
03324 ((
CalcCharacterPositionAtoW(lpRecFrom->dwTargetStrOffset +
03325 lpRecFrom->dwTargetStrLen,
03326 (LPSTR)lpRecFrom + lpRecFrom->dwStrOffset,
03327 dwCodePage) *
sizeof(WCHAR))
03328 - lpRecTo->dwTargetStrOffset) /
sizeof(WCHAR);
03329
03330 lpRecTo->dwStrLen = i;
03331
if (lpRecTo->dwSize >= (
DWORD)(lpRecTo->dwStrOffset + (i + 1)*
sizeof(WCHAR))) {
03332 LPWSTR lpW = (LPWSTR)((LPSTR)lpRecTo + lpRecTo->dwStrOffset);
03333 lpW[i] =
L'\0';
03334 }
03335 dwSize =
sizeof(RECONVERTSTRING) + ((i + 1) *
sizeof(WCHAR));
03336 }
03337
return dwSize;
03338 }
03339
03341
03342
03343
03344
03345
03346
03348
03349 LRESULT
ImmRequestMessageWorker(HIMC hIMC,
PWND pwnd, WPARAM wParam, LPARAM lParam, BOOL bAnsiOrigin)
03350 {
03351
03352
static CONST
int nReqBufSize[][7] = {
03353 {
03354
sizeof(COMPOSITIONFORM),
03355
sizeof(CANDIDATEFORM),
03356
sizeof(LOGFONTW),
03357
sizeof(RECONVERTSTRING),
03358
sizeof(RECONVERTSTRING),
03359
sizeof(IMECHARPOSITION),
03360
sizeof(RECONVERTSTRING),
03361 },
03362 {
03363
sizeof(COMPOSITIONFORM),
03364
sizeof(CANDIDATEFORM),
03365
sizeof(LOGFONTA),
03366
sizeof(RECONVERTSTRING),
03367
sizeof(RECONVERTSTRING),
03368
sizeof(IMECHARPOSITION),
03369
sizeof(RECONVERTSTRING),
03370 }
03371 };
03372 LRESULT lRet = 0
L;
03373 CONST BOOLEAN bAnsiTarget = !!
TestWF(pwnd,
WFANSIPROC);
03374 LPBYTE lpReq = (LPBYTE)lParam;
03375 LPBYTE lpNew =
NULL;
03376
DWORD dwSaveCharPos;
03377
PCLIENTIMC pClientImc;
03378
DWORD dwCodePage;
03379
03380
#define SEND_MESSAGE(bAnsi) ((bAnsi) ? SendMessageA : SendMessageW)
03381
03383
03384
03385
03386
if (wParam == 0 || wParam > IMR_DOCUMENTFEED) {
03387 RIPMSG1(RIP_WARNING,
"ImmRequestMessageWorker: wParam(%lx) out of range.", wParam);
03388
return 0
L;
03389 }
03390
03391
03392 UserAssert(bAnsiOrigin == 0 || bAnsiOrigin == 1);
03393
03394
03395
if (lpReq && IsBadWritePtr(lpReq, nReqBufSize[bAnsiOrigin][wParam - 1])) {
03396 RIPMSG0(RIP_WARNING,
"ImmRequestMessageWorker: Bad pointer passed from IME to write");
03397
return 0
L;
03398 }
03399
03400
03401
03402
if (wParam == IMR_RECONVERTSTRING || wParam == IMR_DOCUMENTFEED) {
03403
03404
03405
03406
if (lpReq !=
NULL) {
03407 LPRECONVERTSTRING lpReconv = (LPRECONVERTSTRING)lParam;
03408
if (lpReconv->dwVersion != 0) {
03409 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING,
"Invalid version number: %d",
03410 lpReconv->dwVersion);
03411
return 0
L;
03412 }
03413
if (lpReconv->dwSize <
sizeof(RECONVERTSTRING)) {
03414 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING,
"Invalid dwSize: %d",
03415 lpReconv->dwSize);
03416
return 0
L;
03417 }
03418 }
03419 }
else if (wParam == IMR_CONFIRMRECONVERTSTRING) {
03420
03421
if (lpReq ==
NULL || ((LPRECONVERTSTRING)lpReq)->dwVersion != 0) {
03422 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING,
"Invalid argument or invalid version number");
03423
return 0
L;
03424 }
03425 }
else if (lpReq ==
NULL) {
03426 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING,
03427
"ImmRequestMessageWorker: lParam should not be NULL with this wParam(%lx).",
03428 wParam);
03429
return 0
L;
03430 }
03431
03433
03434 pClientImc =
ImmLockClientImc(hIMC);
03435
if (pClientImc !=
NULL) {
03436 dwCodePage =
CImcCodePage(pClientImc);
03437
ImmUnlockClientImc(pClientImc);
03438 }
03439
else {
03440 dwCodePage = CP_ACP;
03441 }
03442
03443
03444
switch (wParam) {
03445
case IMR_CONFIRMRECONVERTSTRING:
03446
case IMR_RECONVERTSTRING:
03447
case IMR_DOCUMENTFEED:
03448
if (bAnsiOrigin != bAnsiTarget) {
03449
if (lpReq !=
NULL) {
03450
03451
DWORD dwSize =
ImmGetReconvertTotalSize(((LPRECONVERTSTRING)lpReq)->dwSize,
FROM_IME, bAnsiTarget);
03452 LPRECONVERTSTRING lpReconv;
03453
03454 lpNew =
ImmLocalAlloc(0, dwSize +
sizeof(WCHAR));
03455
if (lpNew ==
NULL) {
03456 RIPMSG0(RIP_WARNING,
"ImmRequestMessageWorker: failed to allocate a buffer for reconversion.");
03457
return 0
L;
03458 }
03459 lpReconv = (LPRECONVERTSTRING)lpNew;
03460
03461 lpReconv->dwVersion = 0;
03462 lpReconv->dwSize = dwSize;
03463
03464
03465
03466
03467
if (wParam == IMR_CONFIRMRECONVERTSTRING) {
03468
ImmReconversionWorker(lpReconv, (LPRECONVERTSTRING)lParam, bAnsiTarget, dwCodePage);
03469 }
03470 }
03471 }
03472
break;
03473
03474
case IMR_COMPOSITIONFONT:
03475 UserAssert(lpReq !=
NULL);
03476
if (bAnsiOrigin != bAnsiTarget) {
03477
if (bAnsiTarget) {
03478 lpNew =
ImmLocalAlloc(0,
sizeof(LOGFONTA));
03479 }
else {
03480 lpNew =
ImmLocalAlloc(0,
sizeof(LOGFONTW));
03481 }
03482
if (lpNew ==
NULL) {
03483 RIPMSG0(RIP_WARNING,
"ImmRequestMessageWorker: IMR_COMPOSITIONFONT: failed to allocate memory for A/W conversion.");
03484
return 0
L;
03485 }
03486 }
03487
break;
03488
03489
case IMR_QUERYCHARPOSITION:
03490 UserAssert(lpReq !=
NULL);
03491
if (bAnsiOrigin != bAnsiTarget) {
03492
#define lpIMEPOS ((LPIMECHARPOSITION)lParam)
03493
LPVOID lpstr;
03494
DWORD dwLen;
03495
03496 dwSaveCharPos =
lpIMEPOS->dwCharPos;
03497
03498 dwLen = (!bAnsiOrigin ?
ImmGetCompositionStringW :
ImmGetCompositionStringA)(hIMC, GCS_COMPSTR, 0, 0);
03499
if (dwLen == 0) {
03500 RIPMSG0(RIP_WARNING,
"ImmRequestMessageWorker: IMR_QUERYCHARPOSITION no compositiong string.");
03501
return 0
L;
03502 }
03503
03504 lpstr =
ImmLocalAlloc(0, (dwLen + 1) * (!bAnsiOrigin ?
sizeof(WCHAR) :
sizeof(
CHAR)));
03505
if (lpstr ==
NULL) {
03506 RIPMSG0(RIP_WARNING,
"ImmRequestMessageWorker: IMR_QUERYCHARPOSITION: failed to allocate memory for A/W conversion.");
03507
return 0
L;
03508 }
03509
03510 (!bAnsiOrigin ?
ImmGetCompositionStringW :
ImmGetCompositionStringA)(hIMC, GCS_COMPSTR, lpstr, dwLen);
03511
if (bAnsiTarget) {
03512
lpIMEPOS->dwCharPos =
CalcCharacterPositionWtoA(
lpIMEPOS->dwCharPos, lpstr, dwCodePage);
03513 }
else {
03514
lpIMEPOS->dwCharPos =
CalcCharacterPositionAtoW(
lpIMEPOS->dwCharPos, lpstr, dwCodePage);
03515 }
03516
03517
ImmLocalFree(lpstr);
03518 }
03519
break;
03520
03521
default:
03522 UserAssert(lpReq !=
NULL);
03523
break;
03524 }
03525
03526
if (lpNew) {
03527
03528 lpReq = lpNew;
03529 }
03530
03532 lRet =
SEND_MESSAGE(bAnsiTarget)(
HW(pwnd), WM_IME_REQUEST, wParam, (LPARAM)lpReq);
03534
03535
03536
if (bAnsiOrigin != bAnsiTarget) {
03537
switch (wParam) {
03538
case IMR_RECONVERTSTRING:
03539
case IMR_DOCUMENTFEED:
03540
03541
if (lRet != 0) {
03542
03543 lRet =
ImmGetReconvertTotalSize((
DWORD)lRet,
FROM_APP, bAnsiTarget);
03544
if (lRet <
sizeof(RECONVERTSTRING)) {
03545 RIPMSG1(RIP_WARNING,
"ImmRequestMessageWorker: return value from application %d is invalid.", lRet);
03546 lRet = 0;
03547 }
else if (lpReq) {
03548
03549
if (!
ImmReconversionWorker((LPRECONVERTSTRING)lParam, (LPRECONVERTSTRING)lpReq, bAnsiOrigin, dwCodePage)) {
03550 lRet = 0;
03551 }
03552 }
03553 }
03554
break;
03555
case IMR_COMPOSITIONFONT:
03556
if (bAnsiOrigin) {
03557
LFontWtoLFontA((LPLOGFONTW)lpNew, (LPLOGFONTA)lParam);
03558 }
else {
03559
LFontAtoLFontW((LPLOGFONTA)lpNew, (LPLOGFONTW)lParam);
03560 }
03561
break;
03562
case IMR_QUERYCHARPOSITION:
03563 UserAssert((
LPVOID)lParam !=
NULL);
03564
lpIMEPOS->dwCharPos = dwSaveCharPos;
03565
#undef lpIMEPOS
03566
break;
03567
default:
03568
break;
03569 }
03570
03571 }
03572
if (lpNew) {
03573
03574
ImmLocalFree(lpNew);
03575 }
03576
return lRet;
03577 }
03578
03579
03580
03581
03582
03583
03584
03585
03586 LRESULT
ImmRequestMessageAorW(HIMC hIMC, WPARAM wParam, LPARAM lParam, BOOL bAnsiOrigin)
03587 {
03588 LPINPUTCONTEXT lpInputContext;
03589
PWND pwnd;
03590 LRESULT lRet = 0
L;
03591
DWORD dwThreadId =
GetInputContextThread(hIMC);
03592
03593
if (dwThreadId != GetCurrentThreadId()) {
03594 RIPMSG1(RIP_WARNING,
03595
"ImmRequestMessageAorW:: Invalid input context access %lx.", hIMC);
03596
return lRet;
03597 }
03598
03599
if (hIMC ==
NULL || (lpInputContext =
ImmLockIMC(hIMC)) ==
NULL) {
03600 RIPMSG1(RIP_WARNING,
"ImmRequestMessage: Invalid hImc %lx.", hIMC);
03601
return 0
L;
03602 }
03603
03604
03605
if ((pwnd =
ValidateHwnd(lpInputContext->hWnd)) ==
NULL) {
03606 RIPMSG1(RIP_WARNING,
"ImmRequestMessage: Invalid hWnd %lx.", lpInputContext->hWnd);
03607 }
else {
03608
03609
if (
PtiCurrent() !=
GETPTI(pwnd)) {
03610 RIPMSG0(RIP_WARNING,
"ImmRequestMessage: IME Attempt to send IMR_ message to different thread.");
03611 }
else {
03612 lRet =
ImmRequestMessageWorker(hIMC, pwnd, wParam, lParam, bAnsiOrigin);
03613 }
03614 }
03615
03616
ImmUnlockIMC(hIMC);
03617
03618
return lRet;
03619 }
03620
03621 LRESULT WINAPI
ImmRequestMessageA(HIMC hIMC, WPARAM wParam, LPARAM lParam)
03622 {
03623
return ImmRequestMessageAorW(hIMC, wParam, lParam,
TRUE );
03624 }
03625
03626 LRESULT WINAPI
ImmRequestMessageW(HIMC hIMC, WPARAM wParam, LPARAM lParam)
03627 {
03628
return ImmRequestMessageAorW(hIMC, wParam, lParam,
FALSE );
03629 }