ReactOS 0.4.16-dev-2615-g89221f5
win3.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS IMM32
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Implementing IMM32 Win3.x compatibility
5 * COPYRIGHT: Copyright 2020-2026 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#include "precomp.h"
9#include <ime.h>
10
12
13#ifdef IMM_WIN3_SUPPORT /* 3.x support */
14
15#define ALIGN_DWORD(len) (((len) + 3) & ~3)
16#define ALIGN_ASTR_SIZE(len) ALIGN_DWORD(2 * (len) + sizeof(ANSI_NULL))
17#define ALIGN_WSTR_SIZE(len) ALIGN_DWORD((len) * sizeof(WCHAR) + sizeof(UNICODE_NULL))
18
19/* Korean lead byte */
20#define KOR_LEAD_BYTE_FIRST ((BYTE)0xB0)
21#define KOR_LEAD_BYTE_LAST ((BYTE)0xC8)
22#define KOR_IS_LEAD_BYTE(ch) \
23 (KOR_LEAD_BYTE_FIRST <= (BYTE)(ch) && (BYTE)(ch) <= KOR_LEAD_BYTE_LAST)
24
25#define KOR_SCAN_CODE_SBCS 0xFFF10001 /* Korean single-byte character string */
26#define KOR_SCAN_CODE_DBCS 0xFFF20001 /* Korean double-byte character string */
27#define KOR_KEYDOWN_FLAGS 0xE0001
28#define KOR_INTERIM_FLAGS 0xF00001
29
30static inline INT Imm32WideToAnsi(PCWCH pchWide, INT cchWide, PSTR pszAnsi, INT cchAnsi)
31{
32 BOOL usedDefaultChar = FALSE;
33 INT len = WideCharToMultiByte(CP_ACP, 0, pchWide, cchWide, pszAnsi, cchAnsi,
34 NULL, &usedDefaultChar);
35 if (pszAnsi && len >= 0 && len < cchAnsi)
36 pszAnsi[len] = ANSI_NULL;
37 return len;
38}
39
40static inline INT Imm32AnsiToWide(PCCH pchAnsi, INT cchAnsi, PWSTR pszWide, INT cchWide)
41{
42 INT len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pchAnsi, cchAnsi, pszWide, cchWide);
43 if (pszWide && len >= 0 && len < cchWide)
44 pszWide[len] = UNICODE_NULL;
45 return len;
46}
47
48static DWORD Imm32CompStrWToStringA(const COMPOSITIONSTRING *pCS, PCHAR pch)
49{
50 BOOL bUsedDef;
51 PCWSTR pwch = (PCWSTR)((const BYTE*)pCS + pCS->dwResultStrOffset);
52 INT cchNeed = WideCharToMultiByte(CP_ACP, 0, pwch, pCS->dwResultStrLen,
53 pch, 0, NULL, &bUsedDef) + 1;
54 if (!pch)
55 return cchNeed;
57 pch, cchNeed, NULL, &bUsedDef);
58 pch[cch] = ANSI_NULL;
59 return cch + 1;
60}
61
62static DWORD Imm32CompStrWToStringW(const COMPOSITIONSTRING *pCS, PWCHAR pch)
63{
64 DWORD dwResultStrLen = pCS->dwResultStrLen;
65 if (pch)
66 {
67 DWORD cb = dwResultStrLen * sizeof(WCHAR);
68 RtlCopyMemory(pch, (const BYTE*)pCS + pCS->dwResultStrOffset, cb);
69 pch[dwResultStrLen] = UNICODE_NULL;
70 }
71 return (dwResultStrLen + 1) * sizeof(WCHAR);
72}
73
74static DWORD
75Imm32CompStrWToUndetW(
76 DWORD dwGCS,
77 const COMPOSITIONSTRING *pCS,
80{
81 const DWORD cbRequired =
82 sizeof(UNDETERMINESTRUCT) +
83 ALIGN_WSTR_SIZE(pCS->dwCompStrLen) +
85 ALIGN_WSTR_SIZE(pCS->dwResultStrLen) +
87 ALIGN_WSTR_SIZE(pCS->dwResultReadStrLen) +
89
90 if (!pDet)
91 return cbRequired;
92
93 if (dwSize < cbRequired)
94 return 0;
95
96 pDet->dwSize = cbRequired;
97
98 PBYTE pbDet = (PBYTE)pDet;
99 DWORD ib = sizeof(UNDETERMINESTRUCT);
100 const BYTE* pbCS = (const BYTE*)pCS;
101
102 if (dwGCS & GCS_COMPSTR)
103 {
104 pDet->uUndetTextPos = ib;
105 pDet->uUndetTextLen = pCS->dwCompStrLen;
106 DWORD cb = pCS->dwCompStrLen * sizeof(WCHAR);
107 RtlCopyMemory(pbDet + ib, pbCS + pCS->dwCompStrOffset, cb);
108 ((PWCHAR)(pbDet + ib))[pCS->dwCompStrLen] = UNICODE_NULL;
109
110 ib += ALIGN_WSTR_SIZE(pCS->dwCompStrLen);
111 }
112
113 if ((dwGCS & GCS_COMPATTR) || pCS->dwCompAttrLen)
114 {
115 pDet->uUndetAttrPos = ib;
116 RtlCopyMemory(pbDet + ib, pbCS + pCS->dwCompAttrOffset, pCS->dwCompAttrLen);
117
118 ib += ALIGN_DWORD(pCS->dwCompAttrLen);
119 }
120
121 if (dwGCS & GCS_CURSORPOS)
122 pDet->uCursorPos = pCS->dwCursorPos;
123
124 if (dwGCS & GCS_DELTASTART)
125 pDet->uDeltaStart = pCS->dwDeltaStart;
126
127 if (dwGCS & GCS_RESULTSTR)
128 {
129 pDet->uDetermineTextPos = ib;
131 DWORD cb = pCS->dwResultStrLen * sizeof(WCHAR);
132 RtlCopyMemory(pbDet + ib, pbCS + pCS->dwResultStrOffset, cb);
133 ((PWCHAR)(pbDet + ib))[pCS->dwResultStrLen] = UNICODE_NULL;
134
135 ib += ALIGN_WSTR_SIZE(pCS->dwResultStrLen);
136 }
137
138 if ((dwGCS & GCS_RESULTCLAUSE) && pCS->dwResultClauseLen)
139 {
140 pDet->uDetermineDelimPos = ib;
141 RtlCopyMemory(pbDet + ib, pbCS + pCS->dwResultClauseOffset, pCS->dwResultClauseLen);
142
143 ib += ALIGN_DWORD(pCS->dwResultClauseLen);
144 }
145
146 if (dwGCS & GCS_RESULTREADSTR)
147 {
148 pDet->uYomiTextPos = ib;
149 pDet->uYomiTextLen = pCS->dwResultReadStrLen;
150 DWORD cb = pCS->dwResultReadStrLen * sizeof(WCHAR);
151 RtlCopyMemory(pbDet + ib, pbCS + pCS->dwResultReadStrOffset, cb);
152 ((PWCHAR)(pbDet + ib))[pCS->dwResultReadStrLen] = UNICODE_NULL;
153
154 ib += ALIGN_WSTR_SIZE(pCS->dwResultReadStrLen);
155 }
156
157 if ((dwGCS & GCS_RESULTREADCLAUSE) && pCS->dwResultReadClauseLen)
158 {
159 pDet->uYomiDelimPos = ib;
160 RtlCopyMemory(pbDet + ib, pbCS + pCS->dwResultReadClauseOffset,
162
163 //ib += ALIGN_DWORD(pCS->dwResultReadClauseLen); // The last one (ineffective)
164 }
165
166 return cbRequired;
167}
168
169static DWORD
170Imm32CompStrWToUndetA(
171 DWORD dwGCS,
172 const COMPOSITIONSTRING *pCS,
175{
176 const DWORD cbRequired =
177 sizeof(UNDETERMINESTRUCT) +
178 ALIGN_ASTR_SIZE(pCS->dwCompStrLen) +
179 ALIGN_ASTR_SIZE(pCS->dwCompAttrLen) +
180 ALIGN_ASTR_SIZE(pCS->dwResultStrLen) +
182 ALIGN_ASTR_SIZE(pCS->dwResultReadStrLen) +
184
185 if (!pDet)
186 return cbRequired;
187
188 if (dwSize < cbRequired)
189 return 0;
190
191 pDet->dwSize = cbRequired;
192
193 DWORD ib = sizeof(UNDETERMINESTRUCT);
194 PBYTE pbDet = (PBYTE)pDet;
195 const BYTE* pbCS = (const BYTE*)pCS;
196 PCWSTR pCompStrW = (PCWSTR)(pbCS + pCS->dwCompStrOffset);
197 PCWSTR pResultStr = (PCWSTR)(pbCS + pCS->dwResultStrOffset);
198 PCWSTR pResultReadStr = (PCWSTR)(pbCS + pCS->dwResultReadStrOffset);
199
200 if (dwGCS & GCS_COMPSTR)
201 {
202 PSTR pchA = (PSTR)(pbDet + ib);
203 INT cchAnsi = Imm32WideToAnsi(pCompStrW, pCS->dwCompStrLen, pchA, cbRequired - ib);
204 pDet->uUndetTextPos = ib;
205 pDet->uUndetTextLen = cchAnsi;
206 (pbDet + ib)[cchAnsi] = ANSI_NULL;
207
208 ib += ALIGN_DWORD(cchAnsi + 1);
209
210 if ((dwGCS & GCS_COMPATTR) || pCS->dwCompAttrLen)
211 {
212 pDet->uUndetAttrPos = ib;
213
214 const BYTE *pSrcAttr = pbCS + pCS->dwCompAttrOffset;
215 PBYTE pDestAttr = pbDet + ib;
216
217 UINT ibIndex = 0;
218 for (UINT i = 0; i < pCS->dwCompAttrLen; ++i)
219 {
220 if (IsDBCSLeadByte(pchA[ibIndex]))
221 {
222 pDestAttr[ibIndex++] = pSrcAttr[i];
223 pDestAttr[ibIndex++] = pSrcAttr[i];
224 }
225 else
226 {
227 pDestAttr[ibIndex++] = pSrcAttr[i];
228 }
229 }
230
231 ib += ALIGN_DWORD(ibIndex);
232 }
233 }
234
235 if (dwGCS & GCS_CURSORPOS)
236 {
237 if (pCS->dwCursorPos == (DWORD)-1)
238 pDet->uCursorPos = (UINT)-1;
239 else
240 pDet->uCursorPos = IchAnsiFromWide(pCS->dwCursorPos, pCompStrW, CP_ACP);
241 }
242
243 if (dwGCS & GCS_DELTASTART)
244 {
245 if (pCS->dwDeltaStart == (DWORD)-1)
246 pDet->uDeltaStart = (UINT)-1;
247 else
248 pDet->uDeltaStart = IchAnsiFromWide(pCS->dwDeltaStart, pCompStrW, CP_ACP);
249 }
250
251 if (dwGCS & GCS_RESULTSTR)
252 {
253 INT cchAnsi = Imm32WideToAnsi(pResultStr, pCS->dwResultStrLen,
254 (PSTR)(pbDet + ib), cbRequired - ib);
255 pDet->uDetermineTextPos = ib;
256 pDet->uDetermineTextLen = cchAnsi;
257
258 ib += ALIGN_DWORD(cchAnsi + sizeof(ANSI_NULL));
259
260 if ((dwGCS & GCS_RESULTCLAUSE) && pCS->dwResultClauseLen)
261 {
262 pDet->uDetermineDelimPos = ib;
263 const DWORD *pSrcClause = (const DWORD *)(pbCS + pCS->dwResultClauseOffset);
264 PDWORD pDestClause = (PDWORD)(pbDet + ib);
265 DWORD nClauses = pCS->dwResultClauseLen / sizeof(DWORD);
266
267 for (DWORD i = 0; i < nClauses; ++i)
268 pDestClause[i] = IchAnsiFromWide(pSrcClause[i], pResultStr, CP_ACP);
269
270 ib += ALIGN_DWORD(pCS->dwResultClauseLen);
271 }
272 }
273
274 if (dwGCS & GCS_RESULTREADSTR)
275 {
276 INT cchAnsi = Imm32WideToAnsi(pResultReadStr, pCS->dwResultReadStrLen,
277 (PSTR)(pbDet + ib), cbRequired - ib);
278 pDet->uYomiTextPos = ib;
279 pDet->uYomiTextLen = cchAnsi;
280 ib += ALIGN_DWORD(cchAnsi + sizeof(ANSI_NULL));
281
282 if ((dwGCS & GCS_RESULTREADCLAUSE) && pCS->dwResultReadClauseLen)
283 {
284 pDet->uYomiDelimPos = ib;
285 const DWORD *pSrcClause = (const DWORD *)(pbCS + pCS->dwResultReadClauseOffset);
286 PDWORD pDestClause = (PDWORD)(pbDet + ib);
287 DWORD nClauses = pCS->dwResultReadClauseLen / sizeof(DWORD);
288 PCWSTR pReadW = (PCWSTR)(pbCS + pCS->dwResultReadStrOffset);
289
290 for (DWORD i = 0; i < nClauses; ++i)
291 pDestClause[i] = IchAnsiFromWide(pSrcClause[i], pReadW, CP_ACP);
292
293 //ib += ALIGN_DWORD(pCS->dwResultReadClauseLen); // The last one (ineffective)
294 }
295 }
296
297 return cbRequired;
298}
299
300static DWORD
301Imm32CompStrWToStringExW(
302 DWORD dwGCS,
303 const COMPOSITIONSTRING *pCS,
306{
307 const DWORD cbRequired =
308 sizeof(STRINGEXSTRUCT) +
309 ALIGN_WSTR_SIZE(pCS->dwResultStrLen) +
311 ALIGN_WSTR_SIZE(pCS->dwResultReadStrLen) +
313
314 if (!pSX)
315 return cbRequired;
316
317 if (dwSize < cbRequired)
318 return 0;
319
320 pSX->dwSize = dwSize;
321
322 DWORD ib = sizeof(STRINGEXSTRUCT);
323 PBYTE pBase = (PBYTE)pSX;
324 const BYTE* pbCS = (const BYTE*)pCS;
325
326 {
327 pSX->uDeterminePos = ib;
328 DWORD cbResultStr = pCS->dwResultStrLen * sizeof(WCHAR);
329 RtlCopyMemory(pBase + ib, pbCS + pCS->dwResultStrOffset, cbResultStr);
330 ((PWSTR)(pBase + ib))[pCS->dwResultStrLen] = UNICODE_NULL;
331
332 ib += ALIGN_WSTR_SIZE(pCS->dwResultStrLen);
333 }
334
335 if ((dwGCS & GCS_RESULTCLAUSE) && pCS->dwResultClauseLen)
336 {
337 pSX->uDetermineDelimPos = ib;
338 RtlCopyMemory(pBase + ib, pbCS + pCS->dwResultClauseOffset, pCS->dwResultClauseLen);
339
340 ib += ALIGN_DWORD(pCS->dwResultClauseLen);
341 }
342
343 {
344 pSX->uYomiPos = ib;
345 DWORD cbResultReadStr = pCS->dwResultReadStrLen * sizeof(WCHAR);
346 RtlCopyMemory(pBase + ib, pbCS + pCS->dwResultReadStrOffset, cbResultReadStr);
347 ((PWSTR)(pBase + ib))[pCS->dwResultReadStrLen] = UNICODE_NULL;
348
349 ib += ALIGN_WSTR_SIZE(pCS->dwResultReadStrLen);
350 }
351
352 if ((dwGCS & GCS_RESULTREADCLAUSE) && pCS->dwResultReadClauseLen)
353 {
354 pSX->uYomiDelimPos = ib;
355 RtlCopyMemory(pBase + ib, pbCS + pCS->dwResultReadClauseOffset,
357
358 //ib += ALIGN_DWORD(pCS->dwResultReadClauseLen); // The last one (ineffective)
359 }
360
361 return dwSize;
362}
363
364static DWORD
365Imm32CompStrWToStringExA(
366 DWORD dwGCS,
367 const COMPOSITIONSTRING *pCS,
370{
371 const DWORD cbRequired =
372 sizeof(STRINGEXSTRUCT) +
373 ALIGN_ASTR_SIZE(pCS->dwResultStrLen) +
375 ALIGN_ASTR_SIZE(pCS->dwResultReadStrLen) +
377
378 if (!pSX)
379 return cbRequired;
380
381 if (dwSize < cbRequired)
382 return 0;
383
384 pSX->dwSize = dwSize;
385
386 DWORD ib = sizeof(STRINGEXSTRUCT);
387 PBYTE pbSX = (PBYTE)pSX;
388 const BYTE* pbCS = (const BYTE*)pCS;
389 PCWSTR pResultStr = (PCWSTR)(pbCS + pCS->dwResultStrOffset);
390 PCWSTR pResultReadStr = (PCWSTR)(pbCS + pCS->dwResultReadStrOffset);
391
392 if (pCS->dwResultStrLen)
393 {
394 pSX->uDeterminePos = ib;
395 INT nAnsiResultLen = Imm32WideToAnsi(pResultStr, pCS->dwResultStrLen,
396 (PSTR)(pbSX + ib), dwSize - ib);
397 if (nAnsiResultLen <= 0)
398 return 0;
399
400 ib += ALIGN_DWORD(nAnsiResultLen + 1);
401
402 if ((dwGCS & GCS_RESULTCLAUSE) && pCS->dwResultClauseLen)
403 {
404 pSX->uDetermineDelimPos = ib;
405 const DWORD *pSrcClause = (const DWORD *)(pbCS + pCS->dwResultClauseOffset);
406 PDWORD pDestClause = (PDWORD)(pbSX + ib);
407 DWORD nClauses = pCS->dwResultClauseLen / sizeof(DWORD);
408 PCWSTR pResultW = (PCWSTR)(pbCS + pCS->dwResultStrOffset);
409
410 for (DWORD i = 0; i < nClauses; ++i)
411 pDestClause[i] = IchAnsiFromWide(pSrcClause[i], pResultW, CP_ACP);
412
413 ib += ALIGN_DWORD(pCS->dwResultClauseLen);
414 }
415 }
416
417 if (pCS->dwResultReadStrLen)
418 {
419 pSX->uYomiPos = ib;
420 INT nAnsiReadLen = Imm32WideToAnsi(pResultReadStr, pCS->dwResultReadStrLen,
421 (PSTR)(pbSX + ib), dwSize - ib);
422 if (nAnsiReadLen <= 0)
423 return 0;
424
425 ib += ALIGN_DWORD(nAnsiReadLen + 1);
426
427 if ((dwGCS & GCS_RESULTREADCLAUSE) && pCS->dwResultReadClauseLen)
428 {
429 pSX->uYomiDelimPos = ib;
430 const DWORD *pSrcClause = (const DWORD *)(pbCS + pCS->dwResultReadClauseOffset);
431 PDWORD pDestClause = (PDWORD)(pbSX + ib);
432 DWORD nClauses = pCS->dwResultReadClauseLen / sizeof(DWORD);
433 PCWSTR pReadW = (PCWSTR)(pbCS + pCS->dwResultReadStrOffset);
434
435 for (DWORD i = 0; i < nClauses; ++i)
436 pDestClause[i] = IchAnsiFromWide(pSrcClause[i], pReadW, CP_ACP);
437
438 //ib += ALIGN_DWORD(pCS->dwResultReadClauseLen); // The last one (ineffective)
439 }
440 }
441
442 return dwSize;
443}
444
445static DWORD
446Imm32CompStrAToUndetA(
447 DWORD dwGCS,
448 const COMPOSITIONSTRING *pCS,
451{
452 const DWORD cbRequired =
453 sizeof(UNDETERMINESTRUCT) +
454 ALIGN_DWORD(pCS->dwCompStrLen + sizeof(ANSI_NULL)) +
456 ALIGN_DWORD(pCS->dwResultStrLen + sizeof(ANSI_NULL)) +
460
461 if (!pDet)
462 return cbRequired;
463
464 if (dwSize < cbRequired)
465 return 0;
466
467 pDet->dwSize = dwSize;
468
469 DWORD ib = sizeof(UNDETERMINESTRUCT);
470 PBYTE pbDet = (PBYTE)pDet, pbCS = (PBYTE)pCS;
471
472 if (dwGCS & GCS_COMPSTR)
473 {
474 pDet->uUndetTextPos = ib;
475 pDet->uUndetTextLen = pCS->dwCompStrLen;
476 RtlCopyMemory(pbDet + ib, pbCS + pCS->dwCompStrOffset, pCS->dwCompStrLen);
477 pbDet[ib + pCS->dwCompStrLen] = ANSI_NULL;
478
479 ib += ALIGN_DWORD(pCS->dwCompStrLen + 1);
480
481 if (pCS->dwCompAttrLen)
482 dwGCS |= GCS_COMPATTR;
483 }
484
485 if (dwGCS & GCS_COMPATTR)
486 {
487 pDet->uUndetAttrPos = ib;
488 RtlCopyMemory(pbDet + ib, pbCS + pCS->dwCompAttrOffset, pCS->dwCompAttrLen);
489
490 ib += ALIGN_DWORD(pCS->dwCompAttrLen);
491 }
492
493 if (dwGCS & GCS_CURSORPOS)
494 pDet->uCursorPos = pCS->dwCursorPos;
495
496 if (dwGCS & GCS_DELTASTART)
497 pDet->uDeltaStart = pCS->dwDeltaStart;
498
499 if (dwGCS & GCS_RESULTSTR)
500 {
501 pDet->uDetermineTextPos = ib;
503 RtlCopyMemory(pbDet + ib, pbCS + pCS->dwResultStrOffset, pCS->dwResultStrLen);
504 pbDet[ib + pCS->dwResultStrLen] = ANSI_NULL;
505
506 ib += ALIGN_DWORD(pCS->dwResultStrLen + 1);
507 }
508
509 if ((dwGCS & GCS_RESULTCLAUSE) && pCS->dwResultClauseLen)
510 {
511 pDet->uDetermineDelimPos = ib;
512 RtlCopyMemory(pbDet + ib, pbCS + pCS->dwResultClauseOffset, pCS->dwResultClauseLen);
513
514 ib += ALIGN_DWORD(pCS->dwResultClauseLen);
515 }
516
517 if (dwGCS & GCS_RESULTREADSTR)
518 {
519 pDet->uYomiTextPos = ib;
520 pDet->uYomiTextLen = pCS->dwResultReadStrLen;
521 RtlCopyMemory(pbDet + ib, pbCS + pCS->dwResultReadStrOffset, pCS->dwResultReadStrLen);
522 pbDet[ib + pCS->dwResultReadStrLen] = ANSI_NULL;
523
524 ib += ALIGN_DWORD(pCS->dwResultReadStrLen + 1);
525 }
526
527 if ((dwGCS & GCS_RESULTREADCLAUSE) && pCS->dwResultReadClauseLen)
528 {
529 pDet->uYomiDelimPos = ib;
530 RtlCopyMemory(pbDet + ib, pbCS + pCS->dwResultReadClauseOffset,
532
533 //ib += ALIGN_DWORD(pCS->dwResultReadClauseLen); // The last one (ineffective)
534 }
535
536 return dwSize;
537}
538
539static DWORD
540Imm32CompStrAToUndetW(
541 DWORD dwGCS,
542 const COMPOSITIONSTRING *pCS,
543 PUNDETERMINESTRUCT pUndet,
545{
546 const DWORD cbRequired =
547 sizeof(UNDETERMINESTRUCT) +
550 ALIGN_WSTR_SIZE(pCS->dwResultStrLen) +
551 ALIGN_WSTR_SIZE(pCS->dwCompStrLen) +
552 ALIGN_WSTR_SIZE(pCS->dwResultReadStrLen) +
554
555 if (!pUndet)
556 return cbRequired;
557
558 if (dwSize < cbRequired)
559 return 0;
560
561 pUndet->dwSize = dwSize;
562
563 DWORD ib = sizeof(UNDETERMINESTRUCT);
564 PBYTE pbUndet = (PBYTE)pUndet;
565 const BYTE* pbCS = (const BYTE*)pCS;
566 PCSTR pCompStrA = (PCSTR)(pbCS + pCS->dwCompStrOffset);
567 PCSTR pResultStr = (PCSTR)(pbCS + pCS->dwResultStrOffset);
568 PCSTR pResultReadStr = (PCSTR)(pbCS + pCS->dwResultReadStrOffset);
569
570 if (dwGCS & GCS_COMPSTR)
571 {
572 INT nWideLen = Imm32AnsiToWide(pCompStrA, pCS->dwCompStrLen,
573 (PWSTR)(pbUndet + ib), (dwSize - ib) / sizeof(WCHAR));
574 if (nWideLen <= 0)
575 return 0;
576
577 pUndet->uUndetTextPos = ib;
578 pUndet->uUndetTextLen = nWideLen;
579
580 ib += ALIGN_DWORD((nWideLen + 1) * sizeof(WCHAR));
581
582 if ((dwGCS & GCS_COMPATTR) || pCS->dwCompAttrLen)
583 {
584 pUndet->uUndetAttrPos = ib;
585 const BYTE* pSrcAttr = pbCS + pCS->dwCompAttrOffset;
586 PBYTE pDestAttr = pbUndet + ib;
587 PCWSTR pWStr = (PCWSTR)(pbUndet + pUndet->uUndetTextPos);
588
589 for (UINT i = 0; i < pUndet->uUndetTextLen; ++i)
590 {
591 pDestAttr[i] = *pSrcAttr;
592 USHORT wChar = pWStr[i];
593 ULONG cbMultiByte = 0;
594 RtlUnicodeToMultiByteSize(&cbMultiByte, &wChar, sizeof(WCHAR));
595 pSrcAttr += (cbMultiByte == 2) ? 2 : 1;
596 }
597
598 ib += ALIGN_DWORD(pUndet->uUndetTextLen);
599 }
600 }
601
602 if (dwGCS & GCS_CURSORPOS)
603 {
604 if (pCS->dwCursorPos == (DWORD)-1)
605 pUndet->uCursorPos = (UINT)-1;
606 else
607 pUndet->uCursorPos = IchWideFromAnsi(pCS->dwCursorPos, pCompStrA, CP_ACP);
608 }
609
610 if (dwGCS & GCS_DELTASTART)
611 {
612 if (pCS->dwDeltaStart == (DWORD)-1)
613 pUndet->uDeltaStart = (UINT)-1;
614 else
615 pUndet->uDeltaStart = IchWideFromAnsi(pCS->dwDeltaStart, pCompStrA, CP_ACP);
616 }
617
618 if (dwGCS & GCS_RESULTSTR)
619 {
620 INT nWideLen = Imm32AnsiToWide(pResultStr, pCS->dwResultStrLen,
621 (PWSTR)(pbUndet + ib), (dwSize - ib) / sizeof(WCHAR));
622 if (nWideLen > 0)
623 {
624 pUndet->uDetermineTextPos = ib;
625 pUndet->uDetermineTextLen = nWideLen;
626
627 ib += ALIGN_DWORD((nWideLen + 1) * sizeof(WCHAR));
628
629 if ((dwGCS & GCS_RESULTCLAUSE) && pCS->dwResultClauseLen)
630 {
631 pUndet->uDetermineDelimPos = ib;
632 PDWORD pSrcClause = (PDWORD)(pbCS + pCS->dwResultClauseOffset);
633 PDWORD pDestClause = (PDWORD)(pbUndet + ib);
634 DWORD nClauses = pCS->dwResultClauseLen / sizeof(DWORD);
635
636 for (DWORD i = 0; i < nClauses; ++i)
637 pDestClause[i] = IchWideFromAnsi(pSrcClause[i], pResultStr, CP_ACP);
638
639 ib += ALIGN_DWORD(pCS->dwResultClauseLen);
640 }
641 }
642 }
643
644 if (dwGCS & GCS_RESULTREADSTR)
645 {
646 INT nWideLen = Imm32AnsiToWide(pResultReadStr, pCS->dwResultReadStrLen,
647 (PWSTR)(pbUndet + ib), (dwSize - ib) / sizeof(WCHAR));
648 if (nWideLen > 0)
649 {
650 pUndet->uYomiTextPos = ib;
651 pUndet->uYomiTextLen = nWideLen;
652
653 ib += ALIGN_DWORD((nWideLen + 1) * sizeof(WCHAR));
654
655 if ((dwGCS & GCS_RESULTREADCLAUSE) && pCS->dwResultReadClauseLen)
656 {
657 pUndet->uYomiDelimPos = ib;
658 PDWORD pSrcClause = (PDWORD)(pbCS + pCS->dwResultReadClauseOffset);
659 PDWORD pDestClause = (PDWORD)(pbUndet + ib);
660 DWORD nClauses = pCS->dwResultReadClauseLen / sizeof(DWORD);
661
662 for (DWORD i = 0; i < nClauses; ++i)
663 pDestClause[i] = IchWideFromAnsi(pSrcClause[i], pResultReadStr, CP_ACP);
664
665 //ib += ALIGN_DWORD(pCS->dwResultReadClauseLen); // The last one (ineffective)
666 }
667 }
668 }
669
670 return dwSize;
671}
672
673static DWORD
674Imm32CompStrAToStringExA(
675 DWORD dwGCS,
676 const COMPOSITIONSTRING *pCS,
679{
680 DWORD cbRequired =
681 sizeof(STRINGEXSTRUCT) +
682 ALIGN_DWORD(pCS->dwResultStrLen + sizeof(ANSI_NULL)) +
686
687 if (!pSX)
688 return cbRequired;
689
690 if (dwSize < cbRequired)
691 return 0;
692
693 pSX->dwSize = dwSize;
694
695 DWORD ib = sizeof(STRINGEXSTRUCT);
696 PBYTE pbSX = (PBYTE)pSX;
697 const BYTE* pbCS = (const BYTE*)pCS;
698
699 {
700 pSX->uDeterminePos = ib;
701 RtlCopyMemory(pbSX + ib, pbCS + pCS->dwResultStrOffset, pCS->dwResultStrLen);
702 pbSX[ib + pCS->dwResultStrLen] = ANSI_NULL;
703
704 ib += ALIGN_DWORD(pCS->dwResultStrLen + 1);
705 }
706
707 if ((dwGCS & GCS_RESULTCLAUSE) && pCS->dwResultClauseLen)
708 {
709 pSX->uDetermineDelimPos = ib;
710 RtlCopyMemory(pbSX + ib, pbCS + pCS->dwResultClauseOffset, pCS->dwResultClauseLen);
711
712 ib += ALIGN_DWORD(pCS->dwResultClauseLen);
713 }
714
715 {
716 pSX->uYomiPos = ib;
717 RtlCopyMemory(pbSX + ib, pbCS + pCS->dwResultReadStrOffset, pCS->dwResultReadStrLen);
718 pbSX[ib + pCS->dwResultReadStrLen] = ANSI_NULL;
719
720 ib += ALIGN_DWORD(pCS->dwResultReadStrLen + 1);
721 }
722
723 if ((dwGCS & GCS_RESULTREADCLAUSE) && pCS->dwResultReadClauseLen)
724 {
725 pSX->uYomiDelimPos = ib;
727
728 //ib += ALIGN_DWORD(pCS->dwResultReadClauseLen); // The last one (ineffective)
729 }
730
731 return dwSize;
732}
733
734static DWORD
735Imm32CompStrAToStringExW(
736 DWORD dwGCS,
737 const COMPOSITIONSTRING *pCS,
740{
741 const DWORD cbRequired =
742 sizeof(STRINGEXSTRUCT) +
743 ALIGN_WSTR_SIZE(pCS->dwResultStrLen) +
745 ALIGN_WSTR_SIZE(pCS->dwResultReadStrLen) +
747
748 if (pSX == NULL)
749 return cbRequired;
750
751 if (dwSize < cbRequired)
752 return 0;
753
754 pSX->dwSize = dwSize;
755
756 DWORD ib = sizeof(STRINGEXSTRUCT);
757 PBYTE pbSX = (PBYTE)pSX;
758 const BYTE* pbCS = (const BYTE*)pCS;
759 PCSTR pResultStr = (PCSTR)(pbCS + pCS->dwResultStrOffset);
760 PCSTR pResultReadStr = (PCSTR)(pbCS + pCS->dwResultReadStrOffset);
761
762 if (pCS->dwResultStrLen)
763 {
764 pSX->uDeterminePos = ib;
765 INT nWideResultLen = Imm32AnsiToWide(pResultStr, pCS->dwResultStrLen,
766 (PWSTR)(pbSX + ib), (dwSize - ib) / sizeof(WCHAR));
767 if (nWideResultLen <= 0)
768 return 0;
769
770 ib += ALIGN_DWORD((nWideResultLen + 1) * sizeof(WCHAR));
771
772 if ((dwGCS & GCS_RESULTCLAUSE) && pCS->dwResultClauseLen)
773 {
774 pSX->uDetermineDelimPos = ib;
775 const DWORD* pSrcClause = (const DWORD*)(pbCS + pCS->dwResultClauseOffset);
776 PDWORD pDestClause = (PDWORD)(pbSX + ib);
777 DWORD nClauses = pCS->dwResultClauseLen / sizeof(DWORD);
778
779 for (DWORD i = 0; i < nClauses; ++i)
780 {
781 pDestClause[i] = IchWideFromAnsi(pSrcClause[i],
782 (PCSTR)(pbCS + pCS->dwResultStrOffset), CP_ACP);
783 }
784
785 ib += ALIGN_DWORD(pCS->dwResultClauseLen);
786 }
787 }
788
789 if (pCS->dwResultReadStrLen)
790 {
791 pSX->uYomiPos = ib;
792 INT nWideReadLen = Imm32AnsiToWide(pResultReadStr, pCS->dwResultReadStrLen,
793 (PWSTR)(pbSX + ib), (dwSize - ib) / sizeof(WCHAR));
794 if (nWideReadLen <= 0)
795 return 0;
796
797 ib += ALIGN_DWORD((nWideReadLen + 1) * sizeof(WCHAR));
798
799 if ((dwGCS & GCS_RESULTREADCLAUSE) && pCS->dwResultReadClauseLen)
800 {
801 pSX->uYomiDelimPos = ib;
802 const DWORD* pSrcClause = (const DWORD*)(pbCS + pCS->dwResultReadClauseOffset);
803 PDWORD pDestClause = (PDWORD)(pbSX + ib);
804 DWORD nClauses = pCS->dwResultReadClauseLen / sizeof(DWORD);
805 for (DWORD i = 0; i < nClauses; ++i)
806 pDestClause[i] = IchWideFromAnsi(pSrcClause[i], pResultReadStr, CP_ACP);
807
808 //ib += ALIGN_DWORD(pCS->dwResultReadClauseLen); // The last one (ineffective)
809 }
810 }
811
812 return dwSize;
813}
814
815static DWORD Imm32CompStrAToStringA(const COMPOSITIONSTRING *pCS, PSTR pszString, DWORD dwSize)
816{
817 DWORD dwResultStrLen = pCS->dwResultStrLen;
818 if (!pszString)
819 return dwResultStrLen + 1;
820 if (dwSize < dwResultStrLen + 1)
821 return 0;
822 RtlCopyMemory(pszString, (const BYTE*)pCS + pCS->dwResultStrOffset, dwResultStrLen);
823 pszString[dwResultStrLen] = ANSI_NULL;
824 return dwResultStrLen + 1;
825}
826
827static DWORD Imm32CompStrAToStringW(const COMPOSITIONSTRING *pCS, PWSTR pszString, DWORD dwSize)
828{
829 PCSTR pch = (PCSTR)pCS + pCS->dwResultStrOffset;
830 INT cchWide = Imm32AnsiToWide(pch, pCS->dwResultStrLen, pszString, 0);
831 DWORD dwResultStrLen = (cchWide + 1) * sizeof(WCHAR);
832 if (!pszString)
833 return dwResultStrLen;
834 if (dwSize < dwResultStrLen)
835 return 0;
836 INT cch = Imm32AnsiToWide(pch, pCS->dwResultStrLen, pszString, cchWide);
837 if (cch < cchWide)
838 return 0;
839 pszString[cch] = UNICODE_NULL;
840 return (cch + 1) * sizeof(WCHAR);
841}
842
843static VOID Imm32CompStrAToCharA(HWND hWnd, const COMPOSITIONSTRING *pCS)
844{
845 PCSTR pch = (PCSTR)((const BYTE*)pCS + pCS->dwResultStrOffset);
846
847 BOOL bImeSupportDBCS = FALSE;
848 if (GetWin32ClientInfo()->dwExpWinVer >= 0x30A)
849 bImeSupportDBCS = (BOOL)SendMessageA(hWnd, WM_IME_REPORT, IR_DBCSCHAR, 0);
850
852
853 if (!*pch)
854 {
856 return;
857 }
858
859 PCSTR pNext;
860 for (; *pch; pch = pNext)
861 {
862 BYTE bFirst = (BYTE)(*pch);
863 pNext = CharNextA(pch);
864
865 if (!*pNext)
867
868 if (!IsDBCSLeadByte(bFirst))
869 {
870 PostMessageA(hWnd, WM_CHAR, bFirst, 1);
871 continue;
872 }
873
874 BYTE bSecond = pch[1];
875 if (bImeSupportDBCS)
876 {
877 WPARAM wParamDBCS = 0x80000000 | MAKEWORD(bSecond, bFirst);
878 PostMessageA(hWnd, WM_CHAR, wParamDBCS, 1);
879 }
880 else
881 {
882 PostMessageA(hWnd, WM_CHAR, bFirst, 1);
883 PostMessageA(hWnd, WM_CHAR, bSecond, 1);
884 }
885 }
886}
887
888static VOID Imm32CompStrAToCharW(HWND hWnd, const COMPOSITIONSTRING *pCS)
889{
890 PCSTR pCurrent = (PCSTR)((const BYTE*)pCS + pCS->dwResultStrOffset);
891
893
894 while (*pCurrent)
895 {
896 BYTE bTestChar = *pCurrent;
897 PCHAR pNext = CharNextA(pCurrent);
898
899 if (!*pNext)
901
902 WCHAR szWide[2] = L"";
903 INT nConverted = 0;
904 if (IsDBCSLeadByte(bTestChar))
905 nConverted = Imm32AnsiToWide(pCurrent, 2, szWide, _countof(szWide));
906 else
907 nConverted = Imm32AnsiToWide(pCurrent, 1, szWide, _countof(szWide));
908
909 if (nConverted > 0)
910 PostMessageW(hWnd, WM_CHAR, szWide[0], 1);
911
912 pCurrent = pNext;
913 }
914}
915
916static VOID Imm32CompStrWToCharA(HWND hWnd, const COMPOSITIONSTRING *pCS)
917{
918 PCWSTR pCurrent = (PCWSTR)((const BYTE*)pCS + pCS->dwResultStrOffset);
919
920 BOOL bSupportDBCSReport = FALSE;
921 if (GetWin32ClientInfo()->dwExpWinVer >= 0x30A)
922 bSupportDBCSReport = (BOOL)SendMessageA(hWnd, WM_IME_REPORT, IR_DBCSCHAR, 0);
923
925
926 PCWSTR pNext;
927 for (; *pCurrent; pCurrent = pNext)
928 {
929 pNext = CharNextW(pCurrent);
930 if (!*pNext)
932
933 CHAR szAnsi[3] = {0};
934 if (!Imm32WideToAnsi(pCurrent, 1, szAnsi, _countof(szAnsi)))
935 continue;
936
937 if (!IsDBCSLeadByte(szAnsi[0]))
938 {
939 PostMessageA(hWnd, WM_CHAR, (BYTE)szAnsi[0], 1);
940 continue;
941 }
942
943 if (bSupportDBCSReport)
944 {
945 WPARAM wParam = 0x80000000 | MAKEWORD(szAnsi[1], szAnsi[0]);
947 }
948 else
949 {
950 PostMessageA(hWnd, WM_CHAR, (BYTE)szAnsi[0], 1);
951 PostMessageA(hWnd, WM_CHAR, (BYTE)szAnsi[1], 1);
952 }
953 }
954}
955
956static VOID Imm32CompStrWToCharW(HWND hWnd, const COMPOSITIONSTRING *pCS)
957{
958 PCWSTR pCurrent = (PCWSTR)((const BYTE*)pCS + pCS->dwResultStrOffset);
959
961
962 PCWSTR pNext;
963 for (; *pCurrent; pCurrent = pNext)
964 {
965 pNext = CharNextW(pCurrent);
966
967 if (!*pNext)
969
970 PostMessageW(hWnd, WM_CHAR, *pCurrent, 1);
971 }
972}
973
974static INT
975Imm32JTransCompositionA(
976 const INPUTCONTEXTDX *pIC,
977 const COMPOSITIONSTRING *pCS,
978 const TRANSMSG *pCurrent,
979 PTRANSMSG pEntries)
980{
981 HWND hWnd = pIC->hWnd;
982 if (!IsWindow(hWnd))
983 return 0;
984
985 BOOL bIsUnicodeWnd = IsWindowUnicode(hWnd);
986 DWORD dwGCS = (DWORD)pCurrent->lParam;
987 INT cMessages = 0;
988 BOOL bUndeterminedProcessed = FALSE;
989 BOOL bResultProcessed = FALSE;
990 HGLOBAL hUndet = NULL;
991 DWORD cbUndet = 0;
992
994 {
995 if (!bIsUnicodeWnd)
996 {
997 cbUndet = Imm32CompStrAToUndetA(dwGCS, pCS, NULL, 0);
998 if (cbUndet)
999 {
1000 hUndet = GlobalAlloc(GHND | GMEM_SHARE, cbUndet);
1001 if (hUndet)
1002 {
1003 PUNDETERMINESTRUCT pUndet = GlobalLock(hUndet);
1004 if (pUndet)
1005 {
1006 cbUndet = Imm32CompStrAToUndetA(dwGCS, pCS, pUndet, cbUndet);
1007 GlobalUnlock(hUndet);
1008 if (cbUndet)
1009 {
1011 (LPARAM)hUndet) == 0)
1012 {
1013 bUndeterminedProcessed = TRUE;
1014 }
1015 }
1016 }
1017 }
1018 }
1019 }
1020 else
1021 {
1022 cbUndet = Imm32CompStrAToUndetW(dwGCS, pCS, NULL, 0);
1023 if (cbUndet)
1024 {
1025 hUndet = GlobalAlloc(GHND | GMEM_SHARE, cbUndet);
1026 if (hUndet)
1027 {
1028 PUNDETERMINESTRUCT pUndet = GlobalLock(hUndet);
1029 if (pUndet)
1030 {
1031 cbUndet = Imm32CompStrAToUndetW(dwGCS, pCS, pUndet, cbUndet);
1032 GlobalUnlock(hUndet);
1033 if (cbUndet)
1034 {
1036 (LPARAM)hUndet) == 0)
1037 {
1038 bUndeterminedProcessed = TRUE;
1039 }
1040 }
1041 }
1042 }
1043 }
1044 }
1045
1046 if (hUndet)
1047 GlobalFree(hUndet);
1048 if (bUndeterminedProcessed)
1049 return 0;
1050 }
1051
1052 HGLOBAL hEx, hStr;
1053 PVOID pEx = NULL, pStr = NULL;
1054 BOOL bExSuccess = FALSE, bStrSuccess = FALSE;
1055 LRESULT res;
1056 DWORD exSize, strSize;
1057
1058 if (dwGCS & GCS_RESULTSTR)
1059 {
1060 if (dwGCS & GCS_RESULTREADSTR)
1061 {
1062 exSize = bIsUnicodeWnd ? Imm32CompStrAToStringExW(dwGCS, pCS, NULL, 0)
1063 : Imm32CompStrAToStringExA(dwGCS, pCS, NULL, 0);
1064 if (exSize)
1065 {
1066 hEx = GlobalAlloc(GHND | GMEM_SHARE, exSize);
1067 if (hEx)
1068 {
1069 pEx = GlobalLock(hEx);
1070 if (pEx)
1071 {
1072 bExSuccess = bIsUnicodeWnd
1073 ? Imm32CompStrAToStringExW(dwGCS, pCS, pEx, exSize)
1074 : Imm32CompStrAToStringExA(dwGCS, pCS, pEx, exSize);
1075 GlobalUnlock(hEx);
1076 if (bExSuccess)
1077 {
1078 res = bIsUnicodeWnd
1081 if (res)
1082 {
1083 GlobalFree(hEx);
1084 bResultProcessed = TRUE;
1085 goto FINALIZE;
1086 }
1087 }
1088 }
1089 GlobalFree(hEx);
1090 }
1091 }
1092 }
1093
1094 strSize = bIsUnicodeWnd ? Imm32CompStrAToStringW(pCS, NULL, 0) : (pCS->dwResultStrLen + 1);
1095 if (strSize && strSize != (DWORD)-1)
1096 {
1097 hStr = GlobalAlloc(GHND | GMEM_SHARE, strSize);
1098 if (hStr)
1099 {
1100 pStr = GlobalLock(hStr);
1101 if (pStr)
1102 {
1103 bStrSuccess = bIsUnicodeWnd
1104 ? Imm32CompStrAToStringW(pCS, pStr, strSize)
1105 : Imm32CompStrAToStringA(pCS, pStr, strSize);
1106 GlobalUnlock(hStr);
1107 if (bStrSuccess)
1108 {
1109 res = bIsUnicodeWnd
1112 if (res)
1113 {
1114 GlobalFree(hStr);
1115 bResultProcessed = TRUE;
1116 goto FINALIZE;
1117 }
1118 }
1119 }
1120 GlobalFree(hStr);
1121 }
1122 }
1123
1124 if (bIsUnicodeWnd)
1125 Imm32CompStrAToCharW(hWnd, pCS);
1126 else
1127 Imm32CompStrAToCharA(hWnd, pCS);
1128
1129 bResultProcessed = TRUE;
1130 }
1131
1132FINALIZE:
1133 if (!bUndeterminedProcessed)
1134 {
1135 if (bResultProcessed)
1136 {
1137 if (dwGCS & GCS_COMPSTR)
1138 {
1139 pEntries->message = pCurrent->message;
1140 pEntries->wParam = pCurrent->wParam;
1141 pEntries->lParam =
1144 cMessages = 1;
1145 }
1146 }
1147 else
1148 {
1149 *pEntries = *pCurrent;
1150 cMessages = 1;
1151 }
1152 }
1153
1154 return cMessages;
1155}
1156
1157static INT
1158Imm32JTransCompositionW(
1159 const INPUTCONTEXTDX *pIC,
1160 const COMPOSITIONSTRING *pCS,
1161 const TRANSMSG *pCurrent,
1162 PTRANSMSG pEntries)
1163{
1164 HWND hWnd = pIC->hWnd;
1165 if (!IsWindow(hWnd))
1166 return 0;
1167
1168 BOOL bIsUnicodeWnd = IsWindowUnicode(hWnd);
1169 DWORD dwGCS = (DWORD)pCurrent->lParam;
1170 INT cMessages = 0;
1171 BOOL bUndeterminedProcessed = FALSE;
1172 BOOL bResultProcessed = FALSE;
1173
1174 if (pIC->dwUIFlags & _IME_UI_HIDDEN)
1175 {
1176 HGLOBAL hUndet = NULL;
1177 DWORD cbUndet = 0;
1178
1179 if (!bIsUnicodeWnd)
1180 {
1181 cbUndet = Imm32CompStrWToUndetA(dwGCS, pCS, NULL, 0);
1182 if (cbUndet)
1183 {
1184 hUndet = GlobalAlloc(GHND | GMEM_SHARE, cbUndet);
1185 if (hUndet)
1186 {
1187 PUNDETERMINESTRUCT pUndet = GlobalLock(hUndet);
1188 if (pUndet)
1189 {
1190 cbUndet = Imm32CompStrWToUndetA(dwGCS, pCS, pUndet, cbUndet);
1191 GlobalUnlock(hUndet);
1192 if (cbUndet)
1193 {
1195 (LPARAM)hUndet) == 0)
1196 {
1197 bUndeterminedProcessed = TRUE;
1198 }
1199 }
1200 }
1201 }
1202 }
1203 }
1204 else
1205 {
1206 cbUndet = Imm32CompStrWToUndetW(dwGCS, pCS, NULL, 0);
1207 if (cbUndet)
1208 {
1209 hUndet = GlobalAlloc(GHND | GMEM_SHARE, cbUndet);
1210 if (hUndet)
1211 {
1212 PUNDETERMINESTRUCT pUndet = GlobalLock(hUndet);
1213 if (pUndet)
1214 {
1215 cbUndet = Imm32CompStrWToUndetW(dwGCS, pCS, pUndet, cbUndet);
1216 GlobalUnlock(hUndet);
1217 if (cbUndet)
1218 {
1220 (LPARAM)hUndet) == 0)
1221 {
1222 bUndeterminedProcessed = TRUE;
1223 }
1224 }
1225 }
1226 }
1227 }
1228 }
1229
1230 if (hUndet)
1231 GlobalFree(hUndet);
1232 if (bUndeterminedProcessed)
1233 return 0;
1234 }
1235
1236 HGLOBAL hEx, hStr;
1237 PVOID pEx = NULL, pStr = NULL;
1238 BOOL bExSuccess = FALSE, bStrSuccess = FALSE;
1239 LRESULT res;
1240 DWORD exSize, strSize;
1241
1242 if (dwGCS & GCS_RESULTSTR)
1243 {
1244 if (dwGCS & GCS_RESULTREADSTR)
1245 {
1246 exSize = bIsUnicodeWnd
1247 ? Imm32CompStrWToStringExW(dwGCS, pCS, NULL, 0)
1248 : Imm32CompStrWToStringExA(dwGCS, pCS, NULL, 0);
1249 if (exSize)
1250 {
1251 hEx = GlobalAlloc(GHND | GMEM_SHARE, exSize);
1252 if (hEx)
1253 {
1254 pEx = GlobalLock(hEx);
1255 if (pEx)
1256 {
1257 bExSuccess = bIsUnicodeWnd
1258 ? Imm32CompStrWToStringExW(dwGCS, pCS, pEx, exSize)
1259 : Imm32CompStrWToStringExA(dwGCS, pCS, pEx, exSize);
1260 GlobalUnlock(hEx);
1261 if (bExSuccess)
1262 {
1263 res = bIsUnicodeWnd
1266 if (res)
1267 {
1268 GlobalFree(hEx);
1269 bResultProcessed = TRUE;
1270 goto FINALIZE;
1271 }
1272 }
1273 }
1274 GlobalFree(hEx);
1275 }
1276 }
1277 }
1278
1279 strSize = bIsUnicodeWnd
1280 ? Imm32CompStrWToStringW(pCS, NULL)
1281 : Imm32CompStrWToStringA(pCS, NULL);
1282 if (strSize && strSize != (DWORD)-1)
1283 {
1284 hStr = GlobalAlloc(GHND | GMEM_SHARE, strSize);
1285 if (hStr)
1286 {
1287 pStr = GlobalLock(hStr);
1288 if (pStr)
1289 {
1290 bStrSuccess = bIsUnicodeWnd ? Imm32CompStrWToStringW(pCS, pStr)
1291 : Imm32CompStrWToStringA(pCS, pStr);
1292 GlobalUnlock(hStr);
1293 if (bStrSuccess)
1294 {
1295 res = bIsUnicodeWnd
1298 if (res)
1299 {
1300 GlobalFree(hStr);
1301 bResultProcessed = TRUE;
1302 goto FINALIZE;
1303 }
1304 }
1305 }
1306 GlobalFree(hStr);
1307 }
1308 }
1309
1310 if (bIsUnicodeWnd)
1311 Imm32CompStrWToCharW(hWnd, pCS);
1312 else
1313 Imm32CompStrWToCharA(hWnd, pCS);
1314
1315 bResultProcessed = TRUE;
1316 }
1317
1318FINALIZE:
1319 if (!bUndeterminedProcessed)
1320 {
1321 if (bResultProcessed)
1322 {
1323 if (dwGCS & GCS_COMPSTR)
1324 {
1325 pEntries->message = pCurrent->message;
1326 pEntries->wParam = pCurrent->wParam;
1327 pEntries->lParam =
1330 cMessages = 1;
1331 }
1332 }
1333 else
1334 {
1335 *pEntries = *pCurrent;
1336 cMessages = 1;
1337 }
1338 }
1339
1340 return cMessages;
1341}
1342
1343/* Japanese */
1344static DWORD
1345WINNLSTranslateMessageJ(
1346 INT cEntries,
1347 PTRANSMSG pEntries,
1348 const INPUTCONTEXTDX *pIC,
1349 const COMPOSITIONSTRING *pCS,
1350 BOOL bAnsi)
1351{
1352 // Clone the message list with growing
1353 DWORD dwBufSize = (cEntries + 1) * sizeof(TRANSMSG);
1354 PTRANSMSG pBuf = ImmLocalAlloc(HEAP_ZERO_MEMORY, dwBufSize);
1355 if (!pBuf)
1356 return 0;
1357 RtlCopyMemory(pBuf, pEntries, cEntries * sizeof(TRANSMSG));
1358
1359 HWND hWnd = pIC->hWnd;
1360 HWND hwndIme = ImmGetDefaultIMEWnd(hWnd);
1361
1362 PTRANSMSG pCurrent = pBuf;
1363 if (pIC->dwUIFlags & _IME_UI_HIDDEN)
1364 {
1365 // Find WM_IME_ENDCOMPOSITION
1366 PTRANSMSG pEndComp = NULL;
1367 for (INT i = 0; i < cEntries; ++i)
1368 {
1369 if (pBuf[i].message == WM_IME_ENDCOMPOSITION)
1370 {
1371 pEndComp = &pBuf[i];
1372 break;
1373 }
1374 }
1375
1376 if (pEndComp)
1377 {
1378 // Move WM_IME_ENDCOMPOSITION to the end of the list
1379 PTRANSMSG pSrc = pEndComp + 1, pDest = pEndComp;
1380 for (INT iEntry = 0; iEntry < cEntries - 1 && pSrc->message != WM_NULL; ++iEntry)
1381 *pDest++ = *pSrc++;
1382
1383 pDest->message = WM_IME_ENDCOMPOSITION;
1384 pDest->wParam = pDest->lParam = 0;
1385 }
1386
1387 pCurrent = pBuf;
1388 }
1389
1390 DWORD dwResult;
1391 for (dwResult = 0; pCurrent->message != WM_NULL; ++pCurrent)
1392 {
1393 switch (pCurrent->message)
1394 {
1395 case WM_IME_STARTCOMPOSITION:
1396 if (!(pIC->dwUIFlags & _IME_UI_HIDDEN))
1397 {
1398 // Send IR_OPENCONVERT
1399 if (pIC->cfCompForm.dwStyle)
1401
1402 *pEntries++ = *pCurrent;
1403 ++dwResult;
1404 }
1405 break;
1406
1407 case WM_IME_ENDCOMPOSITION:
1408 if (!(pIC->dwUIFlags & _IME_UI_HIDDEN))
1409 {
1410 // Send IR_CLOSECONVERT
1411 if (pIC->cfCompForm.dwStyle)
1413
1414 *pEntries++ = *pCurrent;
1415 ++dwResult;
1416 }
1417 else
1418 {
1419 // Send IR_UNDETERMINE
1421 if (hMem)
1422 {
1423 if (IsWindowUnicode(hWnd))
1425 else
1427 GlobalFree(hMem);
1428 }
1429 }
1430 break;
1431
1432 case WM_IME_COMPOSITION:
1433 {
1434 INT cMessages;
1435 if (bAnsi)
1436 cMessages = Imm32JTransCompositionA(pIC, pCS, pCurrent, pEntries);
1437 else
1438 cMessages = Imm32JTransCompositionW(pIC, pCS, pCurrent, pEntries);
1439
1440 dwResult += cMessages;
1441 pEntries += cMessages;
1442
1443 // Send IR_CHANGECONVERT
1444 if (!(pIC->dwUIFlags & _IME_UI_HIDDEN) && pIC->cfCompForm.dwStyle)
1446 break;
1447 }
1448
1449 case WM_IME_NOTIFY:
1450 if (pCurrent->wParam == IMN_OPENCANDIDATE)
1451 {
1452 if (IsWindow(hWnd) && (pIC->dwUIFlags & _IME_UI_HIDDEN))
1453 {
1454 // Send IMC_SETCANDIDATEPOS
1455 CANDIDATEFORM CandForm;
1456 LPARAM lParam = pCurrent->lParam;
1457 for (DWORD iCandForm = 0; iCandForm < MAX_CANDIDATEFORM; ++iCandForm)
1458 {
1459 if (!(lParam & (1 << iCandForm)))
1460 continue;
1461
1462 CandForm.dwIndex = iCandForm;
1463 CandForm.dwStyle = CFS_EXCLUDE;
1464 CandForm.ptCurrentPos = pIC->cfCompForm.ptCurrentPos;
1465 CandForm.rcArea = pIC->cfCompForm.rcArea;
1467 (LPARAM)&CandForm);
1468 }
1469 }
1470 }
1471
1472 if (!(pIC->dwUIFlags & _IME_UI_HIDDEN))
1473 {
1474 *pEntries++ = *pCurrent;
1475 ++dwResult;
1476 }
1477 else
1478 {
1479 SendMessageW(hwndIme, pCurrent->message, pCurrent->wParam, pCurrent->lParam);
1480 }
1481 break;
1482
1483 default:
1484 *pEntries++ = *pCurrent;
1485 ++dwResult;
1486 break;
1487 }
1488 }
1489
1490 ImmLocalFree(pBuf);
1491 return dwResult;
1492}
1493
1494typedef LRESULT (WINAPI *FN_SendMessage)(HWND, UINT, WPARAM, LPARAM);
1495typedef BOOL (WINAPI *FN_PostMessage)(HWND, UINT, WPARAM, LPARAM);
1496
1497/* Korean */
1498static DWORD
1499WINNLSTranslateMessageK(
1500 INT cEntries,
1501 PTRANSMSG pEntries,
1502 const INPUTCONTEXTDX *pIC,
1503 const COMPOSITIONSTRING *pCS,
1504 BOOL bSrcIsAnsi)
1505{
1506 HWND hWnd = pIC->hWnd;
1507 HWND hwndIme = ImmGetDefaultIMEWnd(hWnd);
1508 BOOL bDestIsUnicode = IsWindowUnicode(hWnd);
1509 FN_PostMessage pPostMessage = bDestIsUnicode ? PostMessageW : PostMessageA;
1510 FN_SendMessage pSendMessage = bDestIsUnicode ? SendMessageW : SendMessageA;
1511 static WORD s_chKorean = 0; /* One or two Korean character(s) */
1512
1513 if (cEntries <= 0)
1514 return 0;
1515
1516 for (INT i = 0; i < cEntries; ++i)
1517 {
1518 UINT uMsg = pEntries[i].message;
1519 WPARAM wParam = pEntries[i].wParam;
1520 LPARAM lParam = pEntries[i].lParam;
1521
1522 switch (uMsg)
1523 {
1524 case WM_IME_COMPOSITION:
1525 if (lParam & GCS_RESULTSTR)
1526 {
1527 pPostMessage(hWnd, WM_IME_REPORT, IR_STRINGSTART, 0);
1528
1529 if (pCS->dwResultStrLen)
1530 {
1531 DWORD dwProcessedLen = 0;
1532 while (dwProcessedLen < pCS->dwResultStrLen)
1533 {
1534 LPARAM lKeyData = 1; /* WM_CHAR lParam */
1535 WCHAR szWide[2] = {0};
1536 CHAR szMBStr[4] = {0};
1537
1538 if (bSrcIsAnsi)
1539 {
1540 PSTR pResStr = (LPSTR)((BYTE*)pCS + pCS->dwResultStrOffset);
1541 BYTE bChar = pResStr[dwProcessedLen];
1542
1543 if (bDestIsUnicode)
1544 {
1545 INT cbMB = 1;
1546
1547 szMBStr[0] = bChar;
1548 if (IsDBCSLeadByte(bChar) &&
1549 dwProcessedLen + 1 < pCS->dwResultStrLen)
1550 {
1551 szMBStr[1] = pResStr[dwProcessedLen + 1];
1552 cbMB = 2;
1553 ++dwProcessedLen;
1554 }
1555 Imm32AnsiToWide(szMBStr, cbMB, szWide, _countof(szWide));
1556 PostMessageW(hWnd, WM_CHAR, szWide[0], 1);
1557 }
1558 else
1559 {
1560 if (IsDBCSLeadByte(bChar))
1561 {
1562 if (KOR_IS_LEAD_BYTE(bChar))
1563 lKeyData = KOR_SCAN_CODE_DBCS;
1564 else
1565 lKeyData = KOR_SCAN_CODE_SBCS;
1566
1567 PostMessageA(hWnd, WM_CHAR, bChar, lKeyData);
1568 ++dwProcessedLen;
1569 bChar = pResStr[dwProcessedLen];
1570 }
1571 PostMessageA(hWnd, WM_CHAR, bChar, lKeyData);
1572 }
1573 }
1574 else
1575 {
1576 PWSTR pResStrW = (PWSTR)((PBYTE)pCS + pCS->dwResultStrOffset);
1577 szWide[0] = pResStrW[dwProcessedLen];
1578
1579 if (bDestIsUnicode)
1580 {
1581 PostMessageW(hWnd, WM_CHAR, szWide[0], 1);
1582 }
1583 else
1584 {
1585 Imm32WideToAnsi(szWide, 1, szMBStr, _countof(szMBStr));
1586 BYTE bLead = (BYTE)szMBStr[0], bChar;
1587 if (IsDBCSLeadByte(bLead))
1588 {
1589 if (KOR_IS_LEAD_BYTE(bLead))
1590 lKeyData = KOR_SCAN_CODE_DBCS;
1591 else
1592 lKeyData = KOR_SCAN_CODE_SBCS;
1593
1594 PostMessageA(hWnd, WM_CHAR, bLead, lKeyData);
1595 bChar = szMBStr[1];
1596 }
1597 else
1598 {
1599 bChar = szMBStr[0];
1600 }
1601
1602 PostMessageA(hWnd, WM_CHAR, bChar, lKeyData);
1603 }
1604 }
1605 ++dwProcessedLen;
1606 }
1607 }
1608 pPostMessage(hWnd, WM_IME_REPORT, IR_STRINGEND, 0);
1609 }
1610
1611 if (wParam)
1612 {
1613 pPostMessage(hWnd, WM_IME_REPORT, IR_STRINGSTART, 0);
1614
1615 BYTE bFirst = HIBYTE(wParam), bSecond = LOBYTE(wParam);
1616 s_chKorean = MAKEWORD(bFirst, bSecond);
1617
1618 if (bSrcIsAnsi)
1619 {
1620 if (bDestIsUnicode)
1621 {
1622 CHAR szTmp[2] = { (CHAR)bFirst, (CHAR)bSecond };
1623 WCHAR wTmp[2];
1624 if (Imm32AnsiToWide(szTmp, 2, wTmp, _countof(wTmp)))
1625 PostMessageW(hWnd, WM_INTERIM, wTmp[0], KOR_INTERIM_FLAGS);
1626 }
1627 else
1628 {
1629 PostMessageA(hWnd, WM_INTERIM, bFirst, KOR_INTERIM_FLAGS);
1630 PostMessageA(hWnd, WM_INTERIM, bSecond, KOR_INTERIM_FLAGS);
1631 }
1632 }
1633 else
1634 {
1635 if (bDestIsUnicode)
1636 {
1637 PostMessageW(hWnd, WM_INTERIM, wParam, KOR_INTERIM_FLAGS);
1638 }
1639 else
1640 {
1641 WCHAR wTmp[2] = { (WCHAR)wParam, 0 };
1642 CHAR szTmp[2];
1643 Imm32WideToAnsi(wTmp, 1, szTmp, _countof(szTmp));
1644 PostMessageA(hWnd, WM_INTERIM, (BYTE)szTmp[0], KOR_INTERIM_FLAGS);
1645 PostMessageA(hWnd, WM_INTERIM, (BYTE)szTmp[1], KOR_INTERIM_FLAGS);
1646 }
1647 }
1648
1649 if (bDestIsUnicode)
1651 else
1653
1654 pSendMessage(hwndIme, WM_IME_ENDCOMPOSITION, 0, 0);
1655 }
1656 else
1657 {
1658 pPostMessage(hWnd, WM_IME_REPORT, IR_STRINGSTART, 0);
1659 if (bSrcIsAnsi)
1660 {
1661 if (bDestIsUnicode)
1662 {
1663 CHAR szTmp[2];
1664 szTmp[0] = LOBYTE(s_chKorean);
1665 szTmp[1] = HIBYTE(s_chKorean);
1666 WCHAR wTmp[2];
1667 if (Imm32AnsiToWide(szTmp, 2, wTmp, _countof(wTmp)))
1668 PostMessageW(hWnd, WM_CHAR, wTmp[0], KOR_SCAN_CODE_SBCS);
1670 PostMessageW(hWnd, WM_KEYDOWN, VK_BACK, KOR_KEYDOWN_FLAGS);
1671 }
1672 else
1673 {
1674 PostMessageA(hWnd, WM_CHAR, LOBYTE(s_chKorean), KOR_SCAN_CODE_SBCS);
1675 PostMessageA(hWnd, WM_CHAR, HIBYTE(s_chKorean), KOR_SCAN_CODE_SBCS);
1677 PostMessageA(hWnd, WM_KEYDOWN, VK_BACK, KOR_KEYDOWN_FLAGS);
1678 }
1679 }
1680 else
1681 {
1682 if (bDestIsUnicode)
1683 {
1684 PostMessageW(hWnd, WM_CHAR, (WCHAR)s_chKorean, KOR_SCAN_CODE_SBCS);
1686 PostMessageW(hWnd, WM_KEYDOWN, VK_BACK, KOR_KEYDOWN_FLAGS);
1687 }
1688 else
1689 {
1690 CHAR szTmp[2];
1691 WCHAR wTmp[2] = { (WCHAR)s_chKorean, 0 };
1692 Imm32WideToAnsi(wTmp, 1, szTmp, _countof(szTmp));
1693 PostMessageA(hWnd, WM_CHAR, (BYTE)szTmp[0], KOR_SCAN_CODE_SBCS);
1694 PostMessageA(hWnd, WM_CHAR, (BYTE)szTmp[1], KOR_SCAN_CODE_SBCS);
1696 PostMessageA(hWnd, WM_KEYDOWN, VK_BACK, KOR_KEYDOWN_FLAGS);
1697 }
1698 }
1699 }
1700 break;
1701
1702 case WM_IMEKEYDOWN:
1703 pPostMessage(hWnd, WM_KEYDOWN, (WPARAM)LOWORD(wParam), lParam);
1704 break;
1705
1706 case WM_IMEKEYUP:
1707 pPostMessage(hWnd, WM_KEYUP, (WPARAM)LOWORD(wParam), lParam);
1708 break;
1709
1710 default:
1711 pSendMessage(hwndIme, uMsg, wParam, lParam);
1712 break;
1713 }
1714 }
1715
1716 return 0;
1717}
1718
1719#endif /* def IMM_WIN3_SUPPORT */
1720
1721/* This function is used in ImmGenerateMessage and ImmTranslateMessage */
1722DWORD
1725 _Inout_ PTRANSMSG pEntries,
1726 _In_ HIMC hIMC,
1727 _In_ BOOL bAnsi,
1728 _In_ WORD wLang)
1729{
1730#ifdef IMM_WIN3_SUPPORT
1732 if (!pIC)
1733 return 0;
1734
1735 PCOMPOSITIONSTRING pCompStr = ImmLockIMCC(pIC->hCompStr);
1736 if (!pCompStr)
1737 {
1738 ImmUnlockIMC(hIMC);
1739 return 0;
1740 }
1741
1742 DWORD ret;
1743 if (wLang == LANG_KOREAN)
1744 ret = WINNLSTranslateMessageK(cEntries, pEntries, pIC, pCompStr, bAnsi);
1745 else if (wLang == LANG_JAPANESE)
1746 ret = WINNLSTranslateMessageJ(cEntries, pEntries, pIC, pCompStr, bAnsi);
1747 else
1748 ret = 0;
1749
1750 ImmUnlockIMCC(pIC->hCompStr);
1751 ImmUnlockIMC(hIMC);
1752 return ret;
1753#else
1754 return 0;
1755#endif
1756}
char szTmp[518]
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define CHAR(Char)
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
DWORD HIMC
Definition: dimm.idl:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CP_ACP
Definition: compat.h:109
HANDLE HWND
Definition: compat.h:19
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
BOOL WINAPI IsDBCSLeadByte(BYTE testchar)
Definition: locale.c:2126
LPSTR WINAPI CharNextA(const char *ptr)
Definition: string.c:1107
LPWSTR WINAPI CharNextW(const WCHAR *x)
Definition: string.c:1121
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ALIGN_DWORD(size)
Definition: fontpidl.cpp:14
GLuint res
Definition: glext.h:9613
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define IR_UNDETERMINE
Definition: ime.h:133
#define WM_IME_REPORT
Definition: ime.h:122
#define IR_DBCSCHAR
Definition: ime.h:132
#define IR_STRING
Definition: ime.h:131
#define WM_INTERIM
Definition: ime.h:140
#define WM_IMEKEYUP
Definition: ime.h:143
#define WM_IMEKEYDOWN
Definition: ime.h:142
#define IR_CHANGECONVERT
Definition: ime.h:127
#define IR_STRINGSTART
Definition: ime.h:124
#define IR_STRINGEND
Definition: ime.h:125
struct tagUNDETERMINESTRUCT UNDETERMINESTRUCT
#define IR_CLOSECONVERT
Definition: ime.h:128
struct tagSTRINGEXSTRUCT STRINGEXSTRUCT
#define IR_OPENCONVERT
Definition: ime.h:126
#define IR_STRINGEX
Definition: ime.h:134
#define _IME_UI_HIDDEN
Definition: imm32_undoc.h:214
struct INPUTCONTEXTDX * PINPUTCONTEXTDX
#define IMC_SETCANDIDATEPOS
Definition: imm.h:149
#define GCS_COMPATTR
Definition: imm.h:228
#define GCS_RESULTSTR
Definition: imm.h:234
#define GCS_DELTASTART
Definition: imm.h:231
#define GCS_RESULTCLAUSE
Definition: imm.h:235
#define GCS_RESULTREADSTR
Definition: imm.h:232
#define IMN_OPENCANDIDATE
Definition: imm.h:376
#define GCS_COMPSTR
Definition: imm.h:227
#define GCS_CURSORPOS
Definition: imm.h:230
#define CFS_EXCLUDE
Definition: imm.h:328
HWND WINAPI ImmGetDefaultIMEWnd(_In_opt_ HWND hWnd)
Definition: ime.c:441
#define GCS_RESULTREADCLAUSE
Definition: imm.h:233
BOOL WINAPI ImmUnlockIMCC(_In_ HIMCC imcc)
Definition: utils.c:613
LPINPUTCONTEXT WINAPI ImmLockIMC(_In_ HIMC hIMC)
Definition: imm.c:1080
BOOL WINAPI ImmUnlockIMC(_In_ HIMC hIMC)
Definition: imm.c:1090
LPVOID WINAPI ImmLockIMCC(_In_ HIMCC imcc)
Definition: utils.c:602
#define GetWin32ClientInfo()
Definition: ntuser.h:352
static ERESOURCE GlobalLock
Definition: sys_arch.c:8
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
if(dx< 0)
Definition: linetemp.h:194
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
#define pch(ap)
Definition: match.c:418
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
unsigned int UINT
Definition: ndis.h:50
_Use_decl_annotations_ NTSTATUS NTAPI RtlUnicodeToMultiByteSize(_Out_ PULONG MbSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize)
Definition: nlsboot.c:145
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
CONST WCHAR * PCWCH
Definition: ntbasedef.h:423
#define UNICODE_NULL
#define ANSI_NULL
CONST CHAR * PCCH
Definition: ntbasedef.h:404
#define LRESULT
Definition: ole.h:14
#define LOWORD(l)
Definition: pedump.c:82
BYTE * PBYTE
Definition: pedump.c:66
short WCHAR
Definition: pedump.c:58
DWORD * PDWORD
Definition: pedump.c:68
unsigned short USHORT
Definition: pedump.c:61
char CHAR
Definition: pedump.c:57
#define LANG_JAPANESE
Definition: nls.h:76
#define LANG_KOREAN
Definition: nls.h:84
_In_ UINT _In_ UINT cch
Definition: shellapi.h:432
#define _countof(array)
Definition: sndvol32.h:70
DWORD dwIndex
Definition: dimm.idl:79
DWORD dwStyle
Definition: dimm.idl:80
POINT ptCurrentPos
Definition: dimm.idl:81
RECT rcArea
Definition: dimm.idl:82
LPARAM lParam
Definition: imm32.c:68
WPARAM wParam
Definition: imm32.c:67
UINT message
Definition: imm32.c:66
Definition: tftpd.h:60
DWORD dwResultStrOffset
Definition: immdev.h:70
DWORD dwCompStrOffset
Definition: immdev.h:60
DWORD dwCompStrLen
Definition: immdev.h:59
DWORD dwResultReadStrOffset
Definition: immdev.h:66
DWORD dwDeltaStart
Definition: immdev.h:62
DWORD dwCompAttrLen
Definition: immdev.h:55
DWORD dwResultClauseLen
Definition: immdev.h:67
DWORD dwResultStrLen
Definition: immdev.h:69
DWORD dwCompAttrOffset
Definition: immdev.h:56
DWORD dwResultClauseOffset
Definition: immdev.h:68
DWORD dwResultReadStrLen
Definition: immdev.h:65
DWORD dwResultReadClauseLen
Definition: immdev.h:63
DWORD dwResultReadClauseOffset
Definition: immdev.h:64
UINT uYomiPos
Definition: ime.h:166
UINT uDeterminePos
Definition: ime.h:164
UINT uDetermineDelimPos
Definition: ime.h:165
DWORD dwSize
Definition: ime.h:163
UINT uYomiDelimPos
Definition: ime.h:167
UINT uDetermineDelimPos
Definition: ime.h:156
UINT uYomiTextPos
Definition: ime.h:158
UINT uUndetAttrPos
Definition: ime.h:151
UINT uYomiDelimPos
Definition: ime.h:159
UINT uDetermineTextPos
Definition: ime.h:155
UINT uUndetTextPos
Definition: ime.h:150
UINT uDetermineTextLen
Definition: ime.h:154
UINT uDeltaStart
Definition: ime.h:153
UINT uYomiTextLen
Definition: ime.h:157
UINT uUndetTextLen
Definition: ime.h:149
uint16_t * PWSTR
Definition: typedefs.h:56
char * PSTR
Definition: typedefs.h:51
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define MAKEWORD(a, b)
Definition: typedefs.h:248
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
LONG IchAnsiFromWide(LONG cchWide, LPCWSTR pchWide, UINT uCodePage)
Definition: utils.c:140
#define ImmLocalFree(lpData)
Definition: precomp.h:102
LONG IchWideFromAnsi(LONG cchAnsi, LPCSTR pchAnsi, UINT uCodePage)
Definition: utils.c:120
#define MAX_CANDIDATEFORM
Definition: precomp.h:79
LPVOID ImmLocalAlloc(_In_ DWORD dwFlags, _In_ DWORD dwBytes)
Definition: utils.c:275
DWORD WINNLSTranslateMessage(_In_ INT cEntries, _Inout_ PTRANSMSG pEntries, _In_ HIMC hIMC, _In_ BOOL bAnsi, _In_ WORD wLang)
Definition: win3.c:1723
#define GHND
Definition: winbase.h:321
#define GMEM_SHARE
Definition: winbase.h:329
#define WINAPI
Definition: msvc.h:6
_In_ UINT _In_ UINT cEntries
Definition: wingdi.h:4067
#define MB_PRECOMPOSED
Definition: winnls.h:299
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define WM_KEYUP
Definition: winuser.h:1744
#define WM_IME_NOTIFY
Definition: winuser.h:1858
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI IsWindowUnicode(_In_ HWND)
#define WM_NULL
Definition: winuser.h:1635
#define VK_BACK
Definition: winuser.h:2234
#define WM_CHAR
Definition: winuser.h:1745
#define WM_IME_CONTROL
Definition: winuser.h:1859
#define WM_KEYDOWN
Definition: winuser.h:1743
BOOL WINAPI PostMessageA(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
unsigned char BYTE
Definition: xxhash.c:193