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