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