ReactOS  0.4.15-dev-4917-g934e521
compstr.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 composition strings of IMM32
5  * COPYRIGHT: Copyright 1998 Patrik Stridvall
6  * Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
7  * Copyright 2017 James Tabor <james.tabor@reactos.org>
8  * Copyright 2018 Amine Khaldi <amine.khaldi@reactos.org>
9  * Copyright 2020-2021 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
10  */
11 
12 #include "precomp.h"
13 
15 
18 {
19  LPINPUTCONTEXT pIC;
21 
22  *ppIC = NULL;
23  *ppCS = NULL;
24 
25  pIC = ImmLockIMC(hIMC);
26  if (!pIC)
27  return FALSE;
28 
29  pCS = ImmLockIMCC(pIC->hCompStr);
30  if (!pCS)
31  {
32  ImmUnlockIMC(hIMC);
33  return FALSE;
34  }
35 
36  *ppIC = pIC;
37  *ppCS = pCS;
38  return TRUE;
39 }
40 
41 static inline LONG APIENTRY
43 {
44  DWORD ret = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, psz, cb / sizeof(CHAR),
45  lpBuf, dwBufLen / sizeof(WCHAR));
46  if (lpBuf && (ret + 1) * sizeof(WCHAR) <= dwBufLen)
47  lpBuf[ret] = 0;
48  return ret * sizeof(WCHAR);
49 }
50 
51 static inline LONG APIENTRY
53 {
54  DWORD ret = WideCharToMultiByte(uCodePage, 0, psz, cb / sizeof(WCHAR),
55  lpBuf, dwBufLen / sizeof(CHAR), NULL, NULL);
56  if (lpBuf && (ret + 1) * sizeof(CHAR) <= dwBufLen)
57  lpBuf[ret] = 0;
58  return ret * sizeof(CHAR);
59 }
60 
61 static INT APIENTRY
63  INT str_len, LPBYTE dst, INT dst_len, UINT uCodePage)
64 {
65  INT rc;
66  INT i, j = 0, k = 0, len;
67 
68  if (!src_len)
69  return 0;
70 
71  str_len /= sizeof(WCHAR);
72  rc = WideCharToMultiByte(uCodePage, 0, text, str_len, NULL, 0, NULL, NULL);
73 
74  if (dst_len)
75  {
76  if (dst_len > rc)
77  dst_len = rc;
78 
79  for (i = 0; i < str_len; ++i, ++k)
80  {
81  len = WideCharToMultiByte(uCodePage, 0, &text[i], 1, NULL, 0, NULL, NULL);
82  for (; len > 0; --len)
83  {
84  dst[j++] = src[k];
85 
86  if (dst_len <= j)
87  goto end;
88  }
89  }
90 end:
91  rc = j;
92  }
93 
94  return rc * sizeof(BYTE);
95 }
96 
97 static INT APIENTRY
99  INT str_len, LPBYTE dst, INT dst_len, UINT uCodePage)
100 {
101  INT rc;
102  INT i, j = 0;
103 
104  if (!src_len)
105  return 0;
106 
107  str_len /= sizeof(CHAR);
108  rc = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, text, str_len, NULL, 0);
109 
110  if (dst_len)
111  {
112  if (dst_len > rc)
113  dst_len = rc;
114 
115  for (i = 0; i < str_len; ++i)
116  {
117  if (IsDBCSLeadByteEx(uCodePage, text[i]) && text[i + 1])
118  continue;
119 
120  dst[j++] = src[i];
121 
122  if (dst_len <= j)
123  break;
124  }
125 
126  rc = j;
127  }
128 
129  return rc * sizeof(BYTE);
130 }
131 
132 static INT APIENTRY
134  LPDWORD target, INT tlen, UINT uCodePage)
135 {
136  INT rc, i;
137 
138  if (!slen)
139  return 0;
140 
141  if (tlen)
142  {
143  if (tlen > slen)
144  tlen = slen;
145 
146  tlen /= sizeof(DWORD);
147 
148  for (i = 0; i < tlen; ++i)
149  {
150  target[i] = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, text, source[i], NULL, 0);
151  }
152 
153  rc = sizeof(DWORD) * i;
154  }
155  else
156  {
157  rc = slen;
158  }
159 
160  return rc;
161 }
162 
163 static INT APIENTRY
165  LPDWORD target, INT tlen, UINT uCodePage)
166 {
167  INT rc, i;
168 
169  if (!slen)
170  return 0;
171 
172  if (tlen)
173  {
174  if (tlen > slen)
175  tlen = slen;
176 
177  tlen /= sizeof(DWORD);
178 
179  for (i = 0; i < tlen; ++i)
180  {
181  target[i] = WideCharToMultiByte(uCodePage, 0, text, source[i], NULL, 0, NULL, NULL);
182  }
183 
184  rc = sizeof(DWORD) * i;
185  }
186  else
187  {
188  rc = slen;
189  }
190 
191  return rc;
192 }
193 
194 #define CS_StrA(pCS, Name) ((LPCSTR)(pCS) + (pCS)->dw##Name##Offset)
195 #define CS_StrW(pCS, Name) ((LPCWSTR)CS_StrA(pCS, Name))
196 #define CS_Attr(pCS, Name) ((const BYTE *)CS_StrA(pCS, Name))
197 #define CS_Clause(pCS, Name) ((const DWORD *)CS_StrA(pCS, Name))
198 #define CS_Size(pCS, Name) ((pCS)->dw##Name##Len)
199 #define CS_SizeA(pCS, Name) (CS_Size(pCS, Name) * sizeof(CHAR))
200 #define CS_SizeW(pCS, Name) (CS_Size(pCS, Name) * sizeof(WCHAR))
201 
202 #define CS_DoStr(pCS, Name, AorW) do { \
203  if (dwBufLen == 0) { \
204  dwBufLen = CS_Size##AorW((pCS), Name); \
205  } else { \
206  if (dwBufLen > CS_Size##AorW((pCS), Name)) \
207  dwBufLen = CS_Size##AorW((pCS), Name); \
208  RtlCopyMemory(lpBuf, CS_Str##AorW((pCS), Name), dwBufLen); \
209  } \
210 } while (0)
211 
212 #define CS_DoStrA(pCS, Name) CS_DoStr(pCS, Name, A)
213 #define CS_DoStrW(pCS, Name) CS_DoStr(pCS, Name, W)
214 #define CS_DoAttr CS_DoStrA
215 #define CS_DoClause CS_DoStrA
216 
217 // Win: InternalGetCompositionStringA
219 Imm32GetCompStrA(HIMC hIMC, const COMPOSITIONSTRING *pCS, DWORD dwIndex,
220  LPVOID lpBuf, DWORD dwBufLen, BOOL bAnsiClient, UINT uCodePage)
221 {
222  if (bAnsiClient)
223  {
224  switch (dwIndex)
225  {
226  case GCS_COMPREADSTR:
227  CS_DoStrA(pCS, CompReadStr);
228  break;
229 
230  case GCS_COMPREADATTR:
231  CS_DoAttr(pCS, CompReadAttr);
232  break;
233 
234  case GCS_COMPREADCLAUSE:
235  CS_DoClause(pCS, CompReadClause);
236  break;
237 
238  case GCS_COMPSTR:
239  CS_DoStrA(pCS, CompStr);
240  break;
241 
242  case GCS_COMPATTR:
243  CS_DoAttr(pCS, CompAttr);
244  break;
245 
246  case GCS_COMPCLAUSE:
247  CS_DoClause(pCS, CompClause);
248  break;
249 
250  case GCS_CURSORPOS:
251  dwBufLen = pCS->dwCursorPos;
252  break;
253 
254  case GCS_DELTASTART:
255  dwBufLen = pCS->dwDeltaStart;
256  break;
257 
258  case GCS_RESULTREADSTR:
259  CS_DoStrA(pCS, ResultReadStr);
260  break;
261 
263  CS_DoClause(pCS, ResultReadClause);
264  break;
265 
266  case GCS_RESULTSTR:
267  CS_DoStrA(pCS, ResultStr);
268  break;
269 
270  case GCS_RESULTCLAUSE:
271  CS_DoClause(pCS, ResultClause);
272  break;
273 
274  default:
275  FIXME("TODO:\n");
276  return IMM_ERROR_GENERAL;
277  }
278  }
279  else /* !bAnsiClient */
280  {
281  switch (dwIndex)
282  {
283  case GCS_COMPREADSTR:
284  dwBufLen = Imm32CompStrWideToAnsi(CS_StrW(pCS, CompReadStr),
285  CS_SizeW(pCS, CompReadStr),
286  lpBuf, dwBufLen, uCodePage);
287  break;
288 
289  case GCS_COMPREADATTR:
290  dwBufLen = Imm32CompAttrWideToAnsi(CS_Attr(pCS, CompReadAttr),
291  CS_Size(pCS, CompReadAttr),
292  CS_StrW(pCS, CompStr),
293  CS_SizeW(pCS, CompStr),
294  lpBuf, dwBufLen, uCodePage);
295  break;
296 
297  case GCS_COMPREADCLAUSE:
298  dwBufLen = Imm32CompClauseWideToAnsi(CS_Clause(pCS, CompReadClause),
299  CS_Size(pCS, CompReadClause),
300  CS_StrW(pCS, CompStr),
301  lpBuf, dwBufLen, uCodePage);
302  break;
303 
304  case GCS_COMPSTR:
305  dwBufLen = Imm32CompStrWideToAnsi(CS_StrW(pCS, CompStr),
306  CS_SizeW(pCS, CompStr),
307  lpBuf, dwBufLen, uCodePage);
308  break;
309 
310  case GCS_COMPATTR:
311  dwBufLen = Imm32CompAttrWideToAnsi(CS_Attr(pCS, CompAttr),
312  CS_Size(pCS, CompAttr),
313  CS_StrW(pCS, CompStr),
314  CS_SizeW(pCS, CompStr),
315  lpBuf, dwBufLen, uCodePage);
316  break;
317 
318  case GCS_COMPCLAUSE:
319  dwBufLen = Imm32CompClauseWideToAnsi(CS_Clause(pCS, CompClause),
320  CS_Size(pCS, CompClause),
321  CS_StrW(pCS, CompStr),
322  lpBuf, dwBufLen, uCodePage);
323  break;
324 
325  case GCS_CURSORPOS:
326  dwBufLen = IchAnsiFromWide(pCS->dwCursorPos, CS_StrW(pCS, CompStr), uCodePage);
327  break;
328 
329  case GCS_DELTASTART:
330  dwBufLen = IchAnsiFromWide(pCS->dwDeltaStart, CS_StrW(pCS, CompStr), uCodePage);
331  break;
332 
333  case GCS_RESULTREADSTR:
334  dwBufLen = Imm32CompStrWideToAnsi(CS_StrW(pCS, ResultReadStr),
335  CS_SizeW(pCS, ResultReadStr),
336  lpBuf, dwBufLen, uCodePage);
337  break;
338 
340  dwBufLen = Imm32CompClauseWideToAnsi(CS_Clause(pCS, ResultReadClause),
341  CS_Size(pCS, ResultReadClause),
342  CS_StrW(pCS, CompStr),
343  lpBuf, dwBufLen, uCodePage);
344  break;
345 
346  case GCS_RESULTSTR:
347  dwBufLen = Imm32CompStrWideToAnsi(CS_StrW(pCS, ResultStr),
348  CS_SizeW(pCS, ResultStr),
349  lpBuf, dwBufLen, uCodePage);
350  break;
351 
352  case GCS_RESULTCLAUSE:
353  dwBufLen = Imm32CompClauseWideToAnsi(CS_Clause(pCS, ResultClause),
354  CS_Size(pCS, ResultClause),
355  CS_StrW(pCS, CompStr),
356  lpBuf, dwBufLen, uCodePage);
357  break;
358 
359  default:
360  FIXME("TODO:\n");
361  return IMM_ERROR_GENERAL;
362  }
363  }
364 
365  return dwBufLen;
366 }
367 
368 // Win: InternalGetCompositionStringW
370 Imm32GetCompStrW(HIMC hIMC, const COMPOSITIONSTRING *pCS, DWORD dwIndex,
371  LPVOID lpBuf, DWORD dwBufLen, BOOL bAnsiClient, UINT uCodePage)
372 {
373  if (bAnsiClient)
374  {
375  switch (dwIndex)
376  {
377  case GCS_COMPREADSTR:
378  dwBufLen = Imm32CompStrAnsiToWide(CS_StrA(pCS, CompReadStr),
379  CS_SizeA(pCS, CompReadStr),
380  lpBuf, dwBufLen, uCodePage);
381  break;
382 
383  case GCS_COMPREADATTR:
384  dwBufLen = Imm32CompAttrAnsiToWide(CS_Attr(pCS, CompReadAttr),
385  CS_Size(pCS, CompReadAttr),
386  CS_StrA(pCS, CompStr), CS_SizeA(pCS, CompStr),
387  lpBuf, dwBufLen, uCodePage);
388  break;
389 
390  case GCS_COMPREADCLAUSE:
391  dwBufLen = Imm32CompClauseAnsiToWide(CS_Clause(pCS, CompReadClause),
392  CS_Size(pCS, CompReadClause),
393  CS_StrA(pCS, CompStr),
394  lpBuf, dwBufLen, uCodePage);
395  break;
396 
397  case GCS_COMPSTR:
398  dwBufLen = Imm32CompStrAnsiToWide(CS_StrA(pCS, CompStr),
399  CS_SizeA(pCS, CompStr),
400  lpBuf, dwBufLen, uCodePage);
401  break;
402 
403  case GCS_COMPATTR:
404  dwBufLen = Imm32CompAttrAnsiToWide(CS_Attr(pCS, CompAttr),
405  CS_Size(pCS, CompAttr),
406  CS_StrA(pCS, CompStr), CS_SizeA(pCS, CompStr),
407  lpBuf, dwBufLen, uCodePage);
408  break;
409 
410  case GCS_COMPCLAUSE:
411  dwBufLen = Imm32CompClauseAnsiToWide(CS_Clause(pCS, CompClause),
412  CS_Size(pCS, CompClause),
413  CS_StrA(pCS, CompStr),
414  lpBuf, dwBufLen, uCodePage);
415  break;
416 
417  case GCS_CURSORPOS:
418  dwBufLen = IchWideFromAnsi(pCS->dwCursorPos, CS_StrA(pCS, CompStr), uCodePage);
419  break;
420 
421  case GCS_DELTASTART:
422  dwBufLen = IchWideFromAnsi(pCS->dwDeltaStart, CS_StrA(pCS, CompStr), uCodePage);
423  break;
424 
425  case GCS_RESULTREADSTR:
426  dwBufLen = Imm32CompStrAnsiToWide(CS_StrA(pCS, ResultReadStr),
427  CS_SizeA(pCS, ResultReadStr),
428  lpBuf, dwBufLen, uCodePage);
429  break;
430 
432  dwBufLen = Imm32CompClauseAnsiToWide(CS_Clause(pCS, ResultReadClause),
433  CS_Size(pCS, ResultReadClause),
434  CS_StrA(pCS, CompStr),
435  lpBuf, dwBufLen, uCodePage);
436  break;
437 
438  case GCS_RESULTSTR:
439  dwBufLen = Imm32CompStrAnsiToWide(CS_StrA(pCS, ResultStr),
440  CS_SizeA(pCS, ResultStr),
441  lpBuf, dwBufLen, uCodePage);
442  break;
443 
444  case GCS_RESULTCLAUSE:
445  dwBufLen = Imm32CompClauseAnsiToWide(CS_Clause(pCS, ResultClause),
446  CS_Size(pCS, ResultClause),
447  CS_StrA(pCS, CompStr),
448  lpBuf, dwBufLen, uCodePage);
449  break;
450 
451  default:
452  FIXME("TODO:\n");
453  return IMM_ERROR_GENERAL;
454  }
455  }
456  else /* !bAnsiClient */
457  {
458  switch (dwIndex)
459  {
460  case GCS_COMPREADSTR:
461  CS_DoStrW(pCS, CompReadStr);
462  break;
463 
464  case GCS_COMPREADATTR:
465  CS_DoAttr(pCS, CompReadAttr);
466  break;
467 
468  case GCS_COMPREADCLAUSE:
469  CS_DoClause(pCS, CompReadClause);
470  break;
471 
472  case GCS_COMPSTR:
473  CS_DoStrW(pCS, CompStr);
474  break;
475 
476  case GCS_COMPATTR:
477  CS_DoAttr(pCS, CompAttr);
478  break;
479 
480  case GCS_COMPCLAUSE:
481  CS_DoClause(pCS, CompClause);
482  break;
483 
484  case GCS_CURSORPOS:
485  dwBufLen = pCS->dwCursorPos;
486  break;
487 
488  case GCS_DELTASTART:
489  dwBufLen = pCS->dwDeltaStart;
490  break;
491 
492  case GCS_RESULTREADSTR:
493  CS_DoStrW(pCS, ResultReadStr);
494  break;
495 
497  CS_DoClause(pCS, ResultReadClause);
498  break;
499 
500  case GCS_RESULTSTR:
501  CS_DoStrW(pCS, ResultStr);
502  break;
503 
504  case GCS_RESULTCLAUSE:
505  CS_DoClause(pCS, ResultClause);
506  break;
507 
508  default:
509  FIXME("TODO:\n");
510  return IMM_ERROR_GENERAL;
511  }
512  }
513 
514  return dwBufLen;
515 }
516 
517 // Win: ImmSetCompositionStringWorker
519 ImmSetCompositionStringAW(HIMC hIMC, DWORD dwIndex, LPVOID pComp, DWORD dwCompLen,
520  LPVOID pRead, DWORD dwReadLen, BOOL bAnsiAPI)
521 {
522  BOOL ret = FALSE, bAnsiClient;
523  LPVOID pCompNew = NULL, pReadNew = NULL;
524  DWORD dwThreadId, cbCompNew = 0, cbReadNew = 0;
525  LPINPUTCONTEXT pIC;
527  HKL hKL;
528  PIMEDPI pImeDpi;
529  UINT uCodePage;
530  LPRECONVERTSTRING pRS;
531 
534  return FALSE;
535 
537  pImeDpi = ImmLockImeDpi(hKL);
538  if (!pImeDpi)
539  return FALSE;
540 
541  uCodePage = pImeDpi->uCodePage;
542  bAnsiClient = !ImeDpi_IsUnicode(pImeDpi);
543 
544  switch (dwIndex)
545  {
546  case SCS_SETSTR: case SCS_CHANGEATTR: case SCS_CHANGECLAUSE:
547  break;
548 
551  break;
552  /* FALL THROUGH */
553  default:
554  ImmUnlockImeDpi(pImeDpi);
555  return FALSE;
556  }
557 
558  if (bAnsiAPI == bAnsiClient || (!pComp && !pRead))
559  {
560  ret = pImeDpi->ImeSetCompositionString(hIMC, dwIndex, pComp, dwCompLen,
561  pRead, dwReadLen);
562  ImmUnlockImeDpi(pImeDpi);
563  return ret;
564  }
565 
566  if (!Imm32OpenICAndCS(hIMC, &pIC, &pCS))
567  {
568  ImmUnlockImeDpi(pImeDpi);
569  return FALSE;
570  }
571 
572  /*
573  * This code is really too complicated. But I cannot simplify.
574  * It converts like (pComp, dwCompLen) --> (pCompNew, cbCompNew) and
575  * (pRead, dwReadLen) --> (pReadNew, cbReadNew).
576  * (1) Check bAnsiClient, (2) Get the size, (3) Allocate a buffer for conversion,
577  * (4) Store converted data into the buffer.
578  */
579  switch (dwIndex)
580  {
581  case SCS_SETSTR:
582  if (pComp)
583  {
584  if (bAnsiClient)
585  {
586  cbCompNew = Imm32CompStrWideToAnsi(pComp, dwCompLen, NULL, 0, uCodePage);
587  pCompNew = ImmLocalAlloc(0, cbCompNew);
588  if (!pCompNew)
589  goto Quit;
590 
591  Imm32CompStrWideToAnsi(pComp, dwCompLen, pCompNew, cbCompNew, uCodePage);
592  }
593  else
594  {
595  cbCompNew = Imm32CompStrAnsiToWide(pComp, dwCompLen, NULL, 0, uCodePage);
596  pCompNew = ImmLocalAlloc(0, cbCompNew);
597  if (!pCompNew)
598  goto Quit;
599 
600  Imm32CompStrAnsiToWide(pComp, dwCompLen, pCompNew, cbCompNew, uCodePage);
601  }
602  }
603 
604  if (pRead)
605  {
606  if (bAnsiClient)
607  {
608  cbReadNew = Imm32CompStrWideToAnsi(pRead, dwReadLen, NULL, 0, uCodePage);
609  pReadNew = ImmLocalAlloc(0, cbReadNew);
610  if (!pReadNew)
611  goto Quit;
612 
613  Imm32CompStrWideToAnsi(pRead, dwReadLen, pReadNew, cbReadNew, uCodePage);
614  }
615  else
616  {
617  cbReadNew = Imm32CompStrAnsiToWide(pRead, dwReadLen, NULL, 0, uCodePage);
618  pReadNew = ImmLocalAlloc(0, cbReadNew);
619  if (!pReadNew)
620  goto Quit;
621 
622  Imm32CompStrAnsiToWide(pRead, dwReadLen, pReadNew, cbReadNew, uCodePage);
623  }
624  }
625  break;
626 
627  case SCS_CHANGEATTR:
628  if (pComp)
629  {
630  if (bAnsiClient)
631  {
632  cbCompNew = Imm32CompAttrWideToAnsi(pComp, dwCompLen,
633  CS_StrW(pCS, CompStr),
634  CS_SizeW(pCS, CompStr),
635  NULL, 0, uCodePage);
636  pCompNew = ImmLocalAlloc(0, cbCompNew);
637  if (!pCompNew)
638  goto Quit;
639 
640  Imm32CompAttrWideToAnsi(pComp, dwCompLen,
641  CS_StrW(pCS, CompStr), CS_SizeW(pCS, CompStr),
642  pCompNew, cbCompNew, uCodePage);
643  }
644  else
645  {
646  cbCompNew = Imm32CompAttrAnsiToWide(pComp, dwCompLen,
647  CS_StrA(pCS, CompStr),
648  CS_SizeA(pCS, CompStr),
649  NULL, 0, uCodePage);
650  pCompNew = ImmLocalAlloc(0, cbCompNew);
651  if (!pCompNew)
652  goto Quit;
653 
654  Imm32CompAttrAnsiToWide(pComp, dwCompLen,
655  CS_StrA(pCS, CompStr), CS_SizeA(pCS, CompStr),
656  pCompNew, cbCompNew, uCodePage);
657  }
658  }
659 
660  if (pRead)
661  {
662  if (bAnsiClient)
663  {
664  cbReadNew = Imm32CompAttrWideToAnsi(pRead, dwReadLen,
665  CS_StrW(pCS, CompReadStr),
666  CS_SizeW(pCS, CompReadStr),
667  NULL, 0, uCodePage);
668  pReadNew = ImmLocalAlloc(0, cbReadNew);
669  if (!pReadNew)
670  goto Quit;
671 
672  Imm32CompAttrWideToAnsi(pRead, dwReadLen,
673  CS_StrW(pCS, CompReadStr), CS_SizeW(pCS, CompReadStr),
674  pReadNew, cbReadNew, uCodePage);
675  }
676  else
677  {
678  cbReadNew = Imm32CompAttrAnsiToWide(pRead, dwReadLen,
679  CS_StrA(pCS, CompReadStr),
680  CS_SizeA(pCS, CompReadStr),
681  NULL, 0, uCodePage);
682  pReadNew = ImmLocalAlloc(0, cbReadNew);
683  if (!pReadNew)
684  goto Quit;
685 
686  Imm32CompAttrAnsiToWide(pRead, dwReadLen,
687  CS_StrA(pCS, CompReadStr), CS_SizeA(pCS, CompReadStr),
688  pReadNew, cbReadNew, uCodePage);
689  }
690  }
691  break;
692 
693  case SCS_CHANGECLAUSE:
694  if (pComp)
695  {
696  if (bAnsiClient)
697  {
698  cbCompNew = Imm32CompClauseWideToAnsi(pComp, dwCompLen, CS_StrW(pCS, CompStr),
699  NULL, 0, uCodePage);
700  pCompNew = ImmLocalAlloc(0, cbCompNew);
701  if (!pCompNew)
702  goto Quit;
703 
704  Imm32CompClauseWideToAnsi(pComp, dwCompLen, CS_StrW(pCS, CompStr),
705  pCompNew, cbCompNew, uCodePage);
706  }
707  else
708  {
709  cbCompNew = Imm32CompClauseAnsiToWide(pComp, dwCompLen, CS_StrA(pCS, CompStr),
710  NULL, 0, uCodePage);
711  pCompNew = ImmLocalAlloc(0, cbCompNew);
712  if (!pCompNew)
713  goto Quit;
714 
715  Imm32CompClauseAnsiToWide(pComp, dwCompLen, CS_StrA(pCS, CompStr),
716  pCompNew, cbCompNew, uCodePage);
717  }
718  }
719 
720  if (pRead)
721  {
722  if (bAnsiClient)
723  {
724  cbReadNew = Imm32CompClauseWideToAnsi(pRead, dwReadLen, CS_StrW(pCS, CompReadStr),
725  NULL, 0, uCodePage);
726  pReadNew = ImmLocalAlloc(0, cbReadNew);
727  if (!pReadNew)
728  goto Quit;
729 
730  Imm32CompClauseWideToAnsi(pRead, dwReadLen,
731  CS_StrW(pCS, CompReadStr),
732  pReadNew, cbReadNew, uCodePage);
733  }
734  else
735  {
736  cbReadNew = Imm32CompClauseAnsiToWide(pRead, dwReadLen, CS_StrA(pCS, CompReadStr),
737  NULL, 0, uCodePage);
738  pReadNew = ImmLocalAlloc(0, cbReadNew);
739  if (!pReadNew)
740  goto Quit;
741 
742  Imm32CompClauseAnsiToWide(pRead, dwReadLen, CS_StrA(pCS, CompReadStr),
743  pReadNew, cbReadNew, uCodePage);
744  }
745  }
746  break;
747 
749  {
750  if (pComp)
751  {
752  if (bAnsiClient)
753  {
754  cbCompNew = Imm32ReconvertAnsiFromWide(NULL, pComp, uCodePage);
755  pCompNew = ImmLocalAlloc(0, cbCompNew);
756  if (!pCompNew)
757  goto Quit;
758 
759  pRS = pCompNew;
760  pRS->dwSize = cbCompNew;
761  pRS->dwVersion = 0;
762  Imm32ReconvertAnsiFromWide(pRS, pComp, uCodePage);
763  }
764  else
765  {
766  cbCompNew = Imm32ReconvertWideFromAnsi(NULL, pComp, uCodePage);
767  pCompNew = ImmLocalAlloc(0, cbCompNew);
768  if (!pCompNew)
769  goto Quit;
770 
771  pRS = pCompNew;
772  pRS->dwSize = cbCompNew;
773  pRS->dwVersion = 0;
774  Imm32ReconvertWideFromAnsi(pRS, pComp, uCodePage);
775  }
776  }
777 
778  if (pRead)
779  {
780  if (bAnsiClient)
781  {
782  cbReadNew = Imm32ReconvertAnsiFromWide(NULL, pRead, uCodePage);
783  pReadNew = ImmLocalAlloc(0, cbReadNew);
784  if (!pReadNew)
785  goto Quit;
786 
787  pRS = pReadNew;
788  pRS->dwSize = cbReadNew;
789  pRS->dwVersion = 0;
790  Imm32ReconvertAnsiFromWide(pRS, pRead, uCodePage);
791  }
792  else
793  {
794  cbReadNew = Imm32ReconvertWideFromAnsi(NULL, pRead, uCodePage);
795  pReadNew = ImmLocalAlloc(0, cbReadNew);
796  if (!pReadNew)
797  goto Quit;
798 
799  pRS = pReadNew;
800  pRS->dwSize = cbReadNew;
801  pRS->dwVersion = 0;
802  Imm32ReconvertWideFromAnsi(pRS, pRead, uCodePage);
803  }
804  }
805  break;
806  }
807  }
808 
809  ImmUnlockIMCC(pIC->hCompStr);
810  pCS = NULL;
811  ImmUnlockIMC(hIMC);
812  pIC = NULL;
813 
814  ret = pImeDpi->ImeSetCompositionString(hIMC, dwIndex, pCompNew, cbCompNew,
815  pReadNew, cbReadNew);
816 
817  if (dwIndex == SCS_QUERYRECONVERTSTRING)
818  {
819  if (pComp)
820  {
821  if (bAnsiClient)
822  ret = Imm32ReconvertWideFromAnsi(pComp, pCompNew, uCodePage);
823  else
824  ret = Imm32ReconvertAnsiFromWide(pComp, pCompNew, uCodePage);
825  }
826 
827  if (pRead)
828  {
829  if (bAnsiClient)
830  ret = Imm32ReconvertWideFromAnsi(pRead, pReadNew, uCodePage);
831  else
832  ret = Imm32ReconvertAnsiFromWide(pRead, pReadNew, uCodePage);
833  }
834  }
835 
836 Quit:
837  if (pCS)
838  ImmUnlockIMCC(pIC->hCompStr);
839  if (pIC)
840  ImmUnlockIMC(hIMC);
841  ImmLocalFree(pCompNew);
842  ImmLocalFree(pReadNew);
843  ImmUnlockImeDpi(pImeDpi);
844  return ret;
845 }
846 
847 /***********************************************************************
848  * ImmGetCompositionStringA (IMM32.@)
849  */
851 {
852  LONG ret = 0;
853  LPINPUTCONTEXT pIC;
854  PCLIENTIMC pClientImc;
856  BOOL bAnsiClient;
857  UINT uCodePage;
858 
859  TRACE("(%p, %lu, %p, %lu)\n", hIMC, dwIndex, lpBuf, dwBufLen);
860 
861  if (dwBufLen && !lpBuf)
862  return 0;
863 
864  pClientImc = ImmLockClientImc(hIMC);
865  if (!pClientImc)
866  return 0;
867 
868  bAnsiClient = !(pClientImc->dwFlags & CLIENTIMC_WIDE);
869  uCodePage = pClientImc->uCodePage;
870  ImmUnlockClientImc(pClientImc);
871 
872  pIC = ImmLockIMC(hIMC);
873  if (!pIC)
874  return 0;
875 
876  pCS = ImmLockIMCC(pIC->hCompStr);
877  if (!pCS)
878  {
879  ImmUnlockIMC(hIMC);
880  return 0;
881  }
882 
883  ret = Imm32GetCompStrA(hIMC, pCS, dwIndex, lpBuf, dwBufLen, bAnsiClient, uCodePage);
884  ImmUnlockIMCC(pIC->hCompStr);
885  ImmUnlockIMC(hIMC);
886  return ret;
887 }
888 
889 /***********************************************************************
890  * ImmGetCompositionStringW (IMM32.@)
891  */
893 {
894  LONG ret = 0;
895  LPINPUTCONTEXT pIC;
896  PCLIENTIMC pClientImc;
898  BOOL bAnsiClient;
899  UINT uCodePage;
900 
901  TRACE("(%p, %lu, %p, %lu)\n", hIMC, dwIndex, lpBuf, dwBufLen);
902 
903  if (dwBufLen && !lpBuf)
904  return 0;
905 
906  pClientImc = ImmLockClientImc(hIMC);
907  if (!pClientImc)
908  return 0;
909 
910  bAnsiClient = !(pClientImc->dwFlags & CLIENTIMC_WIDE);
911  uCodePage = pClientImc->uCodePage;
912  ImmUnlockClientImc(pClientImc);
913 
914  pIC = ImmLockIMC(hIMC);
915  if (!pIC)
916  return 0;
917 
918  pCS = ImmLockIMCC(pIC->hCompStr);
919  if (!pCS)
920  {
921  ImmUnlockIMC(hIMC);
922  return 0;
923  }
924 
925  ret = Imm32GetCompStrW(hIMC, pCS, dwIndex, lpBuf, dwBufLen, bAnsiClient, uCodePage);
926  ImmUnlockIMCC(pIC->hCompStr);
927  ImmUnlockIMC(hIMC);
928  return ret;
929 }
930 
931 /***********************************************************************
932  * ImmSetCompositionStringA (IMM32.@)
933  */
934 BOOL WINAPI
935 ImmSetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPVOID lpComp, DWORD dwCompLen,
936  LPVOID lpRead, DWORD dwReadLen)
937 {
938  TRACE("(%p, %lu, %p, %lu, %p, %lu)\n",
939  hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
940  return ImmSetCompositionStringAW(hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen, TRUE);
941 }
942 
943 /***********************************************************************
944  * ImmSetCompositionStringW (IMM32.@)
945  */
946 BOOL WINAPI
947 ImmSetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID lpComp, DWORD dwCompLen,
948  LPVOID lpRead, DWORD dwReadLen)
949 {
950  TRACE("(%p, %lu, %p, %lu, %p, %lu)\n",
951  hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
952  return ImmSetCompositionStringAW(hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen, FALSE);
953 }
VOID WINAPI ImmUnlockImeDpi(PIMEDPI pImeDpi)
Definition: ime.c:938
#define GCS_RESULTREADSTR
Definition: imm.h:372
static INT APIENTRY Imm32CompClauseWideToAnsi(const DWORD *source, INT slen, LPCWSTR text, LPDWORD target, INT tlen, UINT uCodePage)
Definition: compstr.c:164
UINT uCodePage
Definition: ntuser.h:1254
IMEINFO ImeInfo
Definition: ntuser.h:1253
LONG WINAPI ImmGetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
Definition: compstr.c:850
#define SCS_QUERYRECONVERTSTRING
Definition: imm.h:458
DWORD APIENTRY Imm32ReconvertAnsiFromWide(LPRECONVERTSTRING pDest, const RECONVERTSTRING *pSrc, UINT uCodePage)
Definition: utils.c:625
#define WideCharToMultiByte
Definition: compat.h:111
#define CS_SizeW(pCS, Name)
Definition: compstr.c:200
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
DWORD dwSize
Definition: imm.h:97
#define GCS_COMPREADSTR
Definition: imm.h:364
#define TRUE
Definition: types.h:120
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
Definition: imm.c:1023
const WCHAR * text
Definition: package.c:1743
BOOL WINAPI ImmSetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID lpComp, DWORD dwCompLen, LPVOID lpRead, DWORD dwReadLen)
Definition: compstr.c:947
#define CS_Clause(pCS, Name)
Definition: compstr.c:197
BOOL APIENTRY Imm32OpenICAndCS(HIMC hIMC, LPINPUTCONTEXT *ppIC, LPCOMPOSITIONSTRING *ppCS)
Definition: compstr.c:17
char CHAR
Definition: xmlstorage.h:175
LPVOID APIENTRY ImmLocalAlloc(DWORD dwFlags, DWORD dwBytes)
Definition: utils.c:355
#define SCS_CAP_SETRECONVERTSTRING
Definition: imm.h:405
#define MB_PRECOMPOSED
Definition: winnls.h:281
#define str_len
Definition: treelist.c:89
#define GCS_COMPCLAUSE
Definition: imm.h:369
LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
Definition: utils.c:1107
#define CS_DoStrW(pCS, Name)
Definition: compstr.c:213
static INT APIENTRY Imm32CompAttrAnsiToWide(const BYTE *src, INT src_len, LPCSTR text, INT str_len, LPBYTE dst, INT dst_len, UINT uCodePage)
Definition: compstr.c:98
char * LPSTR
Definition: xmlstorage.h:182
_In_ HCRYPTHASH _In_ BOOL _In_ DWORD _Inout_ DWORD _In_ DWORD dwBufLen
Definition: wincrypt.h:4245
DWORD dwVersion
Definition: imm.h:98
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:58
DWORD APIENTRY Imm32ReconvertWideFromAnsi(LPRECONVERTSTRING pDest, const RECONVERTSTRING *pSrc, UINT uCodePage)
Definition: utils.c:569
DWORD dwCursorPos
Definition: imm.h:180
static INT APIENTRY Imm32CompClauseAnsiToWide(const DWORD *source, INT slen, LPCSTR text, LPDWORD target, INT tlen, UINT uCodePage)
Definition: compstr.c:133
#define CLIENTIMC_WIDE
Definition: ntuser.h:1325
#define CS_DoAttr
Definition: compstr.c:214
BOOL WINAPI IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
Definition: nls.c:2248
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define CS_Attr(pCS, Name)
Definition: compstr.c:196
#define FIXME(fmt,...)
Definition: debug.h:111
PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
Definition: imm.c:909
const char * LPCSTR
Definition: xmlstorage.h:183
DWORD HIMC
Definition: dimm.idl:75
#define GCS_COMPATTR
Definition: imm.h:368
#define IMM_ERROR_GENERAL
Definition: imm.h:549
UINT uCodePage
Definition: ntuser.h:1308
#define GCS_DELTASTART
Definition: imm.h:371
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:459
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 GLint GLint j
Definition: glfuncs.h:250
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwDeltaStart
Definition: imm.h:181
LONG WINAPI ImmGetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
Definition: compstr.c:892
__wchar_t WCHAR
Definition: xmlstorage.h:180
DWORD_PTR NTAPI NtUserQueryInputContext(HIMC hIMC, DWORD dwType)
Definition: ime.c:1773
#define GCS_RESULTREADCLAUSE
Definition: imm.h:373
PIMEDPI WINAPI ImmLockImeDpi(HKL hKL)
Definition: ime.c:909
#define GCS_COMPREADCLAUSE
Definition: imm.h:366
#define WINAPI
Definition: msvc.h:6
LONG APIENTRY Imm32GetCompStrW(HIMC hIMC, const COMPOSITIONSTRING *pCS, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen, BOOL bAnsiClient, UINT uCodePage)
Definition: compstr.c:370
unsigned long DWORD
Definition: ntddk_ex.h:95
static LONG APIENTRY Imm32CompStrAnsiToWide(LPCSTR psz, DWORD cb, LPWSTR lpBuf, DWORD dwBufLen, UINT uCodePage)
Definition: compstr.c:42
#define GCS_COMPREADATTR
Definition: imm.h:365
#define ImeDpi_IsUnicode(pImeDpi)
Definition: precomp.h:116
static LONG APIENTRY Imm32CompStrWideToAnsi(LPCWSTR psz, DWORD cb, LPSTR lpBuf, DWORD dwBufLen, UINT uCodePage)
Definition: compstr.c:52
static INT APIENTRY Imm32CompAttrWideToAnsi(const BYTE *src, INT src_len, LPCWSTR text, INT str_len, LPBYTE dst, INT dst_len, UINT uCodePage)
Definition: compstr.c:62
#define CS_Size(pCS, Name)
Definition: compstr.c:198
GLuint GLuint end
Definition: gl.h:1545
#define ImmLocalFree(lpData)
Definition: precomp.h:89
BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
Definition: utils.c:1117
int ret
DWORD dwThreadId
Definition: fdebug.c:31
HIMCC hCompStr
Definition: immdev.h:52
LONG APIENTRY Imm32GetCompStrA(HIMC hIMC, const COMPOSITIONSTRING *pCS, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen, BOOL bAnsiClient, UINT uCodePage)
Definition: compstr.c:219
#define CS_DoStrA(pCS, Name)
Definition: compstr.c:212
BOOL APIENTRY ImmSetCompositionStringAW(HIMC hIMC, DWORD dwIndex, LPVOID pComp, DWORD dwCompLen, LPVOID pRead, DWORD dwReadLen, BOOL bAnsiAPI)
Definition: compstr.c:519
BOOL WINAPI ImmSetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPVOID lpComp, DWORD dwCompLen, LPVOID lpRead, DWORD dwReadLen)
Definition: compstr.c:935
LONG APIENTRY IchWideFromAnsi(LONG cchAnsi, LPCSTR pchAnsi, UINT uCodePage)
Definition: utils.c:210
GLenum GLsizei len
Definition: glext.h:6722
#define CS_StrW(pCS, Name)
Definition: compstr.c:195
LONG APIENTRY IchAnsiFromWide(LONG cchWide, LPCWSTR pchWide, UINT uCodePage)
Definition: utils.c:230
GLenum src
Definition: glext.h:6340
UINT_PTR HKL
Definition: msctf.idl:101
unsigned char BYTE
Definition: xxhash.c:193
#define GCS_CURSORPOS
Definition: imm.h:370
DWORD fdwSCSCaps
Definition: imm.h:162
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
GLenum GLenum dst
Definition: glext.h:6340
PKEYBOARD_LAYOUT GetKeyboardLayout()
Definition: utils.c:194
#define CS_SizeA(pCS, Name)
Definition: compstr.c:199
#define CS_DoClause
Definition: compstr.c:215
#define SCS_CHANGECLAUSE
Definition: imm.h:456
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define GCS_RESULTCLAUSE
Definition: imm.h:375
#define MultiByteToWideChar
Definition: compat.h:110
static HMODULE MODULEINFO DWORD cb
Definition: module.c:32
DWORD dwFlags
Definition: ntuser.h:1305
#define SCS_SETSTR
Definition: imm.h:454
uint32_t * LPDWORD
Definition: typedefs.h:59
#define SCS_SETRECONVERTSTRING
Definition: imm.h:457
#define GCS_RESULTSTR
Definition: imm.h:374
GLenum target
Definition: glext.h:7315
#define SCS_CHANGEATTR
Definition: imm.h:455
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define GCS_COMPSTR
Definition: imm.h:367
#define CHAR(Char)
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
Definition: imm.c:1032
int k
Definition: mpi.c:3369
#define APIENTRY
Definition: api.h:79
WINE_DEFAULT_DEBUG_CHANNEL(imm)
#define CS_StrA(pCS, Name)
Definition: compstr.c:194
VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
Definition: imm.c:954