diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c index 67aab7c5a60..84ab597c381 100644 --- a/dll/win32/imm32/imm.c +++ b/dll/win32/imm32/imm.c @@ -2758,17 +2758,184 @@ UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen) return (UINT)cch; } +static DWORD APIENTRY +ImmGetGuideLineAW(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen, BOOL bAnsi) +{ + PCLIENTIMC pClientImc; + LPINPUTCONTEXT pIC; + LPGUIDELINE pGuideLine; + DWORD cb, ret = 0; + LPVOID pvStr, pvPrivate; + BOOL bUsedDefault; + + pClientImc = ImmLockClientImc(hIMC); + if (!pClientImc) + return 0; + + pIC = ImmLockIMC(hIMC); + if (!pIC) + { + ImmUnlockClientImc(pClientImc); + return 0; + } + + pGuideLine = ImmLockIMCC(pIC->hGuideLine); + if (!pGuideLine) + { + ImmUnlockIMC(hIMC); + ImmUnlockClientImc(pClientImc); + return 0; + } + + if (dwIndex == GGL_LEVEL) + { + ret = pGuideLine->dwLevel; + goto Quit; + } + + if (dwIndex == GGL_INDEX) + { + ret = pGuideLine->dwIndex; + goto Quit; + } + + if (dwIndex == GGL_STRING) + { + pvStr = (LPBYTE)pGuideLine + pGuideLine->dwStrOffset; + + /* get size */ + if (bAnsi) + { + if (pClientImc->dwFlags & CLIENTIMC_WIDE) + { + cb = WideCharToMultiByte(CP_ACP, 0, pvStr, pGuideLine->dwStrLen, + NULL, 0, NULL, &bUsedDefault); + } + else + { + cb = pGuideLine->dwStrLen * sizeof(CHAR); + } + } + else + { + if (pClientImc->dwFlags & CLIENTIMC_WIDE) + { + cb = pGuideLine->dwStrLen * sizeof(WCHAR); + } + else + { + cb = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pvStr, pGuideLine->dwStrLen, + NULL, 0) * sizeof(WCHAR); + } + } + + if (dwBufLen == 0 || cb == 0 || lpBuf == NULL || dwBufLen < cb) + { + ret = cb; + goto Quit; + } + + /* store to buffer */ + if (bAnsi) + { + if (pClientImc->dwFlags & CLIENTIMC_WIDE) + { + ret = WideCharToMultiByte(CP_ACP, 0, pvStr, pGuideLine->dwStrLen, + lpBuf, dwBufLen, NULL, &bUsedDefault); + goto Quit; + } + } + else + { + if (!(pClientImc->dwFlags & CLIENTIMC_WIDE)) + { + ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pvStr, pGuideLine->dwStrLen, + lpBuf, dwBufLen) * sizeof(WCHAR); + goto Quit; + } + } + + RtlCopyMemory(lpBuf, pvStr, cb); + ret = cb; + goto Quit; + } + + if (dwIndex == GGL_PRIVATE) + { + pvPrivate = (LPBYTE)pGuideLine + pGuideLine->dwPrivateOffset; + + /* get size */ + if (bAnsi) + { + if ((pClientImc->dwFlags & CLIENTIMC_WIDE) && + pGuideLine->dwIndex == GL_ID_REVERSECONVERSION) + { + cb = CandidateListWideToAnsi(pvPrivate, NULL, 0, CP_ACP); + } + else + { + cb = pGuideLine->dwPrivateSize; + } + } + else + { + if (!(pClientImc->dwFlags & CLIENTIMC_WIDE) && + pGuideLine->dwIndex == GL_ID_REVERSECONVERSION) + { + cb = CandidateListAnsiToWide(pvPrivate, NULL, 0, CP_ACP); + } + else + { + cb = pGuideLine->dwPrivateSize; + } + } + + if (dwBufLen == 0 || cb == 0 || lpBuf == NULL || dwBufLen < cb) + { + ret = cb; + goto Quit; + } + + /* store to buffer */ + if (bAnsi) + { + if ((pClientImc->dwFlags & CLIENTIMC_WIDE) && + pGuideLine->dwIndex == GL_ID_REVERSECONVERSION) + { + ret = CandidateListWideToAnsi(pvPrivate, lpBuf, cb, CP_ACP); + goto Quit; + } + } + else + { + if (!(pClientImc->dwFlags & CLIENTIMC_WIDE) && + pGuideLine->dwIndex == GL_ID_REVERSECONVERSION) + { + ret = CandidateListAnsiToWide(pvPrivate, lpBuf, cb, CP_ACP); + goto Quit; + } + } + + RtlCopyMemory(lpBuf, pvPrivate, cb); + ret = cb; + goto Quit; + } + +Quit: + ImmUnlockIMCC(pIC->hGuideLine); + ImmUnlockIMC(hIMC); + ImmUnlockClientImc(pClientImc); + return ret; +} + /*********************************************************************** * ImmGetGuideLineA (IMM32.@) */ DWORD WINAPI ImmGetGuideLineA( HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen) { - FIXME("(%p, %d, %s, %d): stub\n", - hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen - ); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + TRACE("(%p, %lu, %p, %lu)\n", hIMC, dwIndex, lpBuf, dwBufLen); + return ImmGetGuideLineAW(hIMC, dwIndex, lpBuf, dwBufLen, TRUE); } /*********************************************************************** @@ -2776,11 +2943,8 @@ DWORD WINAPI ImmGetGuideLineA( */ DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen) { - FIXME("(%p, %d, %s, %d): stub\n", - hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen - ); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + TRACE("(%p, %lu, %p, %lu)\n", hIMC, dwIndex, lpBuf, dwBufLen); + return ImmGetGuideLineAW(hIMC, dwIndex, lpBuf, dwBufLen, FALSE); } /***********************************************************************