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
ImmGetGuideLineAW(HIMC hIMC,DWORD dwIndex,LPVOID lpBuf,DWORD dwBufLen,BOOL bAnsi)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 */
ImmGetGuideLineA(HIMC hIMC,DWORD dwIndex,LPSTR lpBuf,DWORD dwBufLen)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 */
ImmGetGuideLineW(HIMC hIMC,DWORD dwIndex,LPWSTR lpBuf,DWORD dwBufLen)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