xref: /reactos/dll/win32/imm32/guideline.c (revision 1734f297)
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 guidelines
5  * COPYRIGHT:   Copyright 2020-2021 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6  */
7 
8 #include "precomp.h"
9 
10 WINE_DEFAULT_DEBUG_CHANNEL(imm);
11 
12 // Win: ImmGetGuideLineWorker
13 DWORD APIENTRY
14 ImmGetGuideLineAW(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen, BOOL bAnsi)
15 {
16     PCLIENTIMC pClientImc;
17     LPINPUTCONTEXT pIC;
18     LPGUIDELINE pGuideLine;
19     DWORD cb, ret = 0;
20     LPVOID pvStr, pvPrivate;
21     BOOL bUsedDefault;
22     UINT uCodePage;
23 
24     pClientImc = ImmLockClientImc(hIMC);
25     if (IS_NULL_UNEXPECTEDLY(pClientImc))
26         return 0;
27 
28     uCodePage = pClientImc->uCodePage;
29 
30     pIC = ImmLockIMC(hIMC);
31     if (IS_NULL_UNEXPECTEDLY(pIC))
32     {
33         ImmUnlockClientImc(pClientImc);
34         return 0;
35     }
36 
37     pGuideLine = ImmLockIMCC(pIC->hGuideLine);
38     if (IS_NULL_UNEXPECTEDLY(pGuideLine))
39     {
40         ImmUnlockIMC(hIMC);
41         ImmUnlockClientImc(pClientImc);
42         return 0;
43     }
44 
45     if (dwIndex == GGL_LEVEL)
46     {
47         ret = pGuideLine->dwLevel;
48         goto Quit;
49     }
50 
51     if (dwIndex == GGL_INDEX)
52     {
53         ret = pGuideLine->dwIndex;
54         goto Quit;
55     }
56 
57     if (dwIndex == GGL_STRING)
58     {
59         pvStr = (LPBYTE)pGuideLine + pGuideLine->dwStrOffset;
60 
61         /* get size */
62         if (bAnsi)
63         {
64             if (pClientImc->dwFlags & CLIENTIMC_WIDE)
65             {
66                 cb = WideCharToMultiByte(uCodePage, 0, pvStr, pGuideLine->dwStrLen,
67                                          NULL, 0, NULL, &bUsedDefault);
68             }
69             else
70             {
71                 cb = pGuideLine->dwStrLen * sizeof(CHAR);
72             }
73         }
74         else
75         {
76             if (pClientImc->dwFlags & CLIENTIMC_WIDE)
77             {
78                 cb = pGuideLine->dwStrLen * sizeof(WCHAR);
79             }
80             else
81             {
82                 cb = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, pvStr, pGuideLine->dwStrLen,
83                                          NULL, 0) * sizeof(WCHAR);
84             }
85         }
86 
87         if (dwBufLen == 0 || cb == 0 || lpBuf == NULL || dwBufLen < cb)
88         {
89             ret = cb;
90             goto Quit;
91         }
92 
93         /* store to buffer */
94         if (bAnsi)
95         {
96             if (pClientImc->dwFlags & CLIENTIMC_WIDE)
97             {
98                 ret = WideCharToMultiByte(uCodePage, 0, pvStr, pGuideLine->dwStrLen,
99                                           lpBuf, dwBufLen, NULL, &bUsedDefault);
100                 goto Quit;
101             }
102         }
103         else
104         {
105             if (!(pClientImc->dwFlags & CLIENTIMC_WIDE))
106             {
107                 ret = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, pvStr, pGuideLine->dwStrLen,
108                                           lpBuf, dwBufLen) * sizeof(WCHAR);
109                 goto Quit;
110             }
111         }
112 
113         RtlCopyMemory(lpBuf, pvStr, cb);
114         ret = cb;
115         goto Quit;
116     }
117 
118     if (dwIndex == GGL_PRIVATE)
119     {
120         pvPrivate = (LPBYTE)pGuideLine + pGuideLine->dwPrivateOffset;
121 
122         /* get size */
123         if (bAnsi)
124         {
125             if ((pClientImc->dwFlags & CLIENTIMC_WIDE) &&
126                 pGuideLine->dwIndex == GL_ID_REVERSECONVERSION)
127             {
128                 cb = CandidateListWideToAnsi(pvPrivate, NULL, 0, uCodePage);
129             }
130             else
131             {
132                 cb = pGuideLine->dwPrivateSize;
133             }
134         }
135         else
136         {
137             if (!(pClientImc->dwFlags & CLIENTIMC_WIDE) &&
138                 pGuideLine->dwIndex == GL_ID_REVERSECONVERSION)
139             {
140                 cb = CandidateListAnsiToWide(pvPrivate, NULL, 0, uCodePage);
141             }
142             else
143             {
144                 cb = pGuideLine->dwPrivateSize;
145             }
146         }
147 
148         if (dwBufLen == 0 || cb == 0 || lpBuf == NULL || dwBufLen < cb)
149         {
150             ret = cb;
151             goto Quit;
152         }
153 
154         /* store to buffer */
155         if (bAnsi)
156         {
157             if ((pClientImc->dwFlags & CLIENTIMC_WIDE) &&
158                 pGuideLine->dwIndex == GL_ID_REVERSECONVERSION)
159             {
160                 ret = CandidateListWideToAnsi(pvPrivate, lpBuf, cb, uCodePage);
161                 goto Quit;
162             }
163         }
164         else
165         {
166             if (!(pClientImc->dwFlags & CLIENTIMC_WIDE) &&
167                 pGuideLine->dwIndex == GL_ID_REVERSECONVERSION)
168             {
169                 ret = CandidateListAnsiToWide(pvPrivate, lpBuf, cb, uCodePage);
170                 goto Quit;
171             }
172         }
173 
174         RtlCopyMemory(lpBuf, pvPrivate, cb);
175         ret = cb;
176         goto Quit;
177     }
178 
179 Quit:
180     ImmUnlockIMCC(pIC->hGuideLine);
181     ImmUnlockIMC(hIMC);
182     ImmUnlockClientImc(pClientImc);
183     TRACE("ret: 0x%X\n", ret);
184     return ret;
185 }
186 
187 /***********************************************************************
188  *		ImmGetGuideLineA (IMM32.@)
189  */
190 DWORD WINAPI ImmGetGuideLineA(HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
191 {
192     TRACE("(%p, %lu, %p, %lu)\n", hIMC, dwIndex, lpBuf, dwBufLen);
193     return ImmGetGuideLineAW(hIMC, dwIndex, lpBuf, dwBufLen, TRUE);
194 }
195 
196 /***********************************************************************
197  *		ImmGetGuideLineW (IMM32.@)
198  */
199 DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
200 {
201     TRACE("(%p, %lu, %p, %lu)\n", hIMC, dwIndex, lpBuf, dwBufLen);
202     return ImmGetGuideLineAW(hIMC, dwIndex, lpBuf, dwBufLen, FALSE);
203 }
204