Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

897 lines
22 KiB

/*++
Copyright (c) 2001, Microsoft Corporation
Module Name:
wrapper.cpp
Abstract:
This file implements the IME entry.
Author:
Revision History:
Notes:
--*/
#include "private.h"
#include "globals.h"
#include "tls.h"
#include "cic.h"
#include "uiwndhd.h"
#include "delay.h"
#include "profile.h"
extern "C" {
DWORD WINAPI ImeConversionList(
HIMC hIMC,
LPCTSTR lpszSrc,
LPCANDIDATELIST lpCandList,
DWORD dwBufLen,
UINT uFlag)
{
DebugMsg(TF_ERROR, TEXT("ImeConversionList. Not support."));
Assert(0);
return 0;
}
BOOL WINAPI ImeConfigure(
HKL hKL, // hKL of this IME
HWND hAppWnd, // the owner window
DWORD dwMode, // mode of dialog
LPVOID lpData) // the data depend on each mode
{
TLS* ptls = TLS::GetTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeConfigure. ptls==NULL."));
return FALSE;
}
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeConfigure. cic==NULL."));
return FALSE;
}
ITfThreadMgr_P* ptim_P = ptls->GetTIM();
if (ptim_P == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeConfigure. ptim_P==NULL."));
return FALSE;
}
if (dwMode & IME_CONFIG_GENERAL)
{
return cic->ConfigureGeneral(ptls, ptim_P, hKL, hAppWnd) == S_OK ? TRUE : FALSE;
}
else if (dwMode & IME_CONFIG_REGISTERWORD)
{
return cic->ConfigureRegisterWord(ptls, ptim_P, hKL, hAppWnd, (REGISTERWORDW*)lpData) == S_OK ? TRUE : FALSE;
}
else
{
DebugMsg(TF_ERROR, TEXT("ImeConfigure(%x). Not support."), dwMode);
Assert(0);
}
return FALSE;
}
BOOL WINAPI ImeDestroy(
UINT uReserved)
{
TLS* ptls = TLS::ReferenceTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeDestroy. ptls==NULL."));
return FALSE;
}
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeDestroy. cic==NULL."));
return FALSE;
}
ITfThreadMgr_P* ptim_P = ptls->GetTIM();
if (ptim_P == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeDestroy. ptim_P==NULL."));
return FALSE;
}
if (ptls->GetSystemInfoFlags() & IME_SYSINFO_WINLOGON)
{
DebugMsg(TF_FUNC, TEXT("ImeDestroy. dwSystemInfoFlags=IME_SYSINFO_WINLOGON."));
return TRUE;
}
else
{
HRESULT hr = cic->DeactivateIMMX(ptls, ptim_P);
if (hr == S_OK)
{
return cic->UnInitIMMX(ptls);
}
}
return FALSE;
}
LRESULT WINAPI ImeEscape(
HIMC hIMC,
UINT uSubFunc,
LPVOID lpData)
{
DebugMsg(TF_ERROR, TEXT("ImeEscape. Never called when Cicero unaware support."));
Assert(0);
return FALSE;
}
BOOL WINAPI ImeInquire(
LPIMEINFO lpImeInfo, // IME specific data report to IMM
LPTSTR lpszWndCls, // the class name of UI
DWORD dwSystemInfoFlags)
{
DebugMsg(TF_ERROR, TEXT("ImeInquire. Never called when Cicero unaware support."));
Assert(0);
return FALSE;
}
BOOL WINAPI ImeProcessKey(
HIMC hIMC,
UINT uVirtKey,
LPARAM lParam,
CONST LPBYTE lpbKeyState)
{
TLS* ptls = TLS::GetTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeProcessKey. ptls==NULL."));
return FALSE;
}
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeProcessKey. cic==NULL."));
return FALSE;
}
ITfThreadMgr_P* ptim_P = ptls->GetTIM();
if (ptim_P == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeProcessKey. ptim_P==NULL."));
return FALSE;
}
if (ptls->IsCTFAware())
{
Interface<ITfDocumentMgr> pdimFocus;
ptim_P->GetFocus(pdimFocus);
if ((ITfDocumentMgr*)pdimFocus)
{
//
// Check if it is our dim or app dim.
// if it is app dim, it is Cicero aware app.
//
//
if (!cic->IsOwnDim((ITfDocumentMgr*)pdimFocus))
return FALSE;
}
DebugMsg(TF_ERROR, TEXT("ImeProcessKey. why IsCTFAware?"));
}
if (ptls->IsAIMMAware())
{
// This is AIMM aware application.
//
// check imc->hWnd is filtered or not.
//
if (MsimtfIsGuidMapEnable(hIMC, NULL))
return FALSE;
DebugMsg(TF_ERROR, TEXT("ImeProcessKey. why IsAIMMAware?"));
}
//
// #476089
//
// MSCTF.DLL handles Alt+VKDBE and pass it to KeyStrokeManager if focus DIM
// is available. So msctfime does not have to handle this.
//
// MSCTF!HandleDBEKeys() in hotkey.cpp checks
// - if it is Japanese layout.
// - if ptim->_GetFocusDocInputMgr() is not NULL.
// - if ALT is down.
//
// Alt+VK_DBE_xxx key comes here even if IME does not have
// IME_PROP_NEED_ALTKEY.
//
if ((HIWORD(lParam) & KF_ALTDOWN) &&
(LOWORD(GetKeyboardLayout(0)) == 0x411))
{
if (IsVKDBEKey(uVirtKey))
return FALSE;
}
return cic->ProcessKey(ptls, ptim_P, hIMC, uVirtKey, lParam, lpbKeyState);
}
BOOL WINAPI CtfImeProcessCicHotkey(
HIMC hIMC,
UINT uVirtKey,
LPARAM lParam)
{
TLS* ptls = TLS::GetTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeProcessCicHotkey. ptls==NULL."));
return FALSE;
}
Interface<ITfThreadMgr> ptim;
Interface<ITfThreadMgr_P> ptim_P;
HRESULT hr;
//
// ITfThreadMgr is per thread instance.
//
hr = TF_GetThreadMgr(ptim);
if (hr != S_OK)
{
DebugMsg(TF_ERROR, TEXT("CtfImeProcessCicHotkey. TF_GetThreadMgr failed"));
Assert(0); // couldn't create tim!
return FALSE;
}
hr = ptim->QueryInterface(IID_ITfThreadMgr_P, (void **)ptim_P);
if (hr != S_OK)
{
DebugMsg(TF_ERROR, TEXT("CtfImeProcessCicHotkey. IID_ITfThreadMgr_P==NULL"));
Assert(0); // couldn't find ITfThreadMgr_P
return FALSE;
}
if (!CtfImmIsCiceroStartedInThread()) {
DebugMsg(TF_ERROR, TEXT("CicBridge::ProcessCicHotkey. StopImm32HotkeyHandler returns Error."));
return FALSE;
}
BOOL bHandled;
hr = ptim_P->CallImm32HotkeyHanlder((WPARAM)uVirtKey, lParam, &bHandled);
if (FAILED(hr)) {
DebugMsg(TF_ERROR, TEXT("CtfImeProcessCicHotkey. CallImm32HotkeyHandler returns Error."));
return FALSE;
}
return bHandled;
}
BOOL WINAPI ImeSelect(
HIMC hIMC,
BOOL fSelect)
{
DebugMsg(TF_ERROR, TEXT("ImeSelect. Never called when Cicero unaware support."));
Assert(0);
return FALSE;
}
BOOL WINAPI ImeSetActiveContext(
HIMC hIMC,
BOOL fOn)
{
DebugMsg(TF_ERROR, TEXT("ImeSetActiveContext. Never called when Cicero unaware support."));
Assert(0);
return FALSE;
}
BOOL WINAPI ImeSetCompositionString(
HIMC hIMC,
DWORD dwIndex,
LPVOID lpComp,
DWORD dwCompLen,
LPVOID lpRead,
DWORD dwReadLen)
{
TLS* ptls = TLS::GetTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeSetCompositionString. ptls==NULL."));
return FALSE;
}
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeSetCompositionString. cic==NULL."));
return FALSE;
}
ITfThreadMgr_P* ptim_P = ptls->GetTIM();
if (ptim_P == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeSetCompositionString. ptim_P==NULL."));
return FALSE;
}
return cic->SetCompositionString(ptls, ptim_P, hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
}
UINT WINAPI ImeToAsciiEx(
UINT uVirtKey,
UINT uScanCode,
CONST LPBYTE lpbKeyState,
LPTRANSMSGLIST lpTransBuf,
UINT fuState,
HIMC hIMC)
{
UINT uNum = 0;
HRESULT hr;
TLS* ptls = TLS::GetTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeToAsciiEx. ptls==NULL."));
return 0;
}
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeToAsciiEx. cic==NULL."));
return 0;
}
ITfThreadMgr_P* ptim_P = ptls->GetTIM();
if (ptim_P == NULL)
{
DebugMsg(TF_ERROR, TEXT("ImeToAsciiEx. ptim_P==NULL."));
return 0;
}
hr = cic->ToAsciiEx(ptls, ptim_P, uVirtKey, uScanCode, lpbKeyState, lpTransBuf, fuState, hIMC, &uNum);
if (hr != S_OK)
{
uNum = 0;
}
return uNum;
}
BOOL WINAPI NotifyIME(
HIMC hIMC,
DWORD dwAction,
DWORD dwIndex,
DWORD dwValue)
{
TLS* ptls = TLS::GetTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("NotifyIME. ptls==NULL."));
return FALSE;
}
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("NotifyIME. cic==NULL."));
return FALSE;
}
ITfThreadMgr_P* ptim_P = ptls->GetTIM();
if (ptim_P == NULL)
{
DebugMsg(TF_ERROR, TEXT("NotifyIME. ptim_P==NULL."));
return FALSE;
}
return cic->Notify(ptls, ptim_P, hIMC, dwAction, dwIndex, dwValue) == S_OK ? TRUE : FALSE;
}
BOOL WINAPI ImeRegisterWord(
LPCTSTR lpszReading,
DWORD dwStyle,
LPCTSTR lpszString)
{
DebugMsg(TF_ERROR, TEXT("ImeRegisterWord. Not support."));
Assert(0);
return FALSE;
}
BOOL WINAPI ImeUnregisterWord(
LPCTSTR lpszReading,
DWORD dwStyle,
LPCTSTR lpszString)
{
DebugMsg(TF_ERROR, TEXT("ImeUnregisterWord. Not support."));
Assert(0);
return FALSE;
}
UINT WINAPI ImeGetRegisterWordStyle(
UINT nItem,
LPSTYLEBUF lpStyleBuf)
{
DebugMsg(TF_ERROR, TEXT("ImeGetRegisterWordStyle. Not support."));
Assert(0);
return FALSE;
}
UINT WINAPI ImeEnumRegisterWord(
REGISTERWORDENUMPROC lpfnRegisterWordEnumProc,
LPCTSTR lpszReading,
DWORD dwStyle,
LPCTSTR lpszString,
LPVOID lpData)
{
DebugMsg(TF_ERROR, TEXT("ImeEnumRegisterWord. Not support."));
Assert(0);
return FALSE;
}
LRESULT CALLBACK UIWndProc(
HWND hUIWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
return CIMEUIWindowHandler::ImeUIWndProcWorker(hUIWnd, uMsg, wParam, lParam);
}
//
// Cicero IME extended entry
//
HRESULT WINAPI CtfImeInquireExW(
LPIMEINFO lpImeInfo, // IME specific data report to IMM
LPWSTR lpszWndCls, // the class name of UI
DWORD dwSystemInfoFlags,
HKL hKL)
{
TLS* ptls = TLS::GetTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeInquireExW. ptls==NULL."));
return E_OUTOFMEMORY;
}
DebugMsg(TF_FUNC, TEXT("CtfImeInquireExW. hKL=%lx, dwSystemInfoFlags=%lx."), hKL, dwSystemInfoFlags);
//
// Bug#524962 - Won't support CUAS in case of unauthorized user.
//
if (!IsInteractiveUserLogon())
{
g_bWinLogon = TRUE;
dwSystemInfoFlags |= IME_SYSINFO_WINLOGON;
}
ptls->SetSystemInfoFlags(dwSystemInfoFlags);
#if 0
//
// Even this is WinLogon process, never return error code to imm32.
// Once imm32 receives error code with some hKL,
// This hKL is marked IMEF_LOADERROR then all desktop doesn't load this IME.
//
if (ptls->GetSystemInfoFlags() & IME_SYSINFO_WINLOGON)
{
return E_NOTIMPL;
}
#endif
return Inquire(lpImeInfo, lpszWndCls, dwSystemInfoFlags, hKL);
}
HRESULT WINAPI CtfImeCreateThreadMgr()
{
TLS* ptls = TLS::GetTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeCreateThreadMgr. ptls==NULL."));
return E_OUTOFMEMORY;
}
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
cic = new CicBridge;
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeCreateThreadMgr. cic==NULL."));
return E_OUTOFMEMORY;
}
ptls->SetCicBridge(cic);
}
HRESULT hr;
if (g_bWinLogon || (ptls->GetSystemInfoFlags() & IME_SYSINFO_WINLOGON))
{
DebugMsg(TF_FUNC, TEXT("CtfImeCreateThreadMgr. dwSystemInfoFlags=IME_SYSINFO_WINLOGON."));
hr = S_OK;
}
else
{
hr = cic->InitIMMX(ptls);
if (SUCCEEDED(hr))
{
ITfThreadMgr_P* ptim_P = ptls->GetTIM();
if (ptim_P == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeCreateThreadMgr. ptim_P==NULL."));
return E_OUTOFMEMORY;
}
hr = cic->ActivateIMMX(ptls, ptim_P);
if (FAILED(hr))
{
DebugMsg(TF_ERROR, TEXT("CtfImeCreateThreadMgr. cic->ActivateIMMX==NULL."));
cic->UnInitIMMX(ptls);
}
}
}
return hr;
}
HRESULT WINAPI CtfImeDestroyThreadMgr()
{
TLS* ptls = TLS::ReferenceTLS(); // Should not allocate TLS. ie. TLS::GetTLS
// DllMain -> ImeDestroy -> DeactivateIMMX -> Deactivate
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeDestroyThreadMgr. ptls==NULL."));
return E_OUTOFMEMORY;
}
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
cic = new CicBridge;
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeDestroyThreadMgr. cic==NULL."));
return E_OUTOFMEMORY;
}
ptls->SetCicBridge(cic);
}
ITfThreadMgr_P* ptim_P = ptls->GetTIM();
if (ptim_P == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeDestroyThreadMgr. ptim_P==NULL."));
return E_OUTOFMEMORY;
}
if (ptls->GetSystemInfoFlags() & IME_SYSINFO_WINLOGON)
{
DebugMsg(TF_FUNC, TEXT("CtfImeDestroyThreadMgr. dwSystemInfoFlags=IME_SYSINFO_WINLOGON."));
return S_OK;
}
else
{
HRESULT hr = cic->DeactivateIMMX(ptls, ptim_P);
if (hr == S_OK)
{
cic->UnInitIMMX(ptls);
}
return hr;
}
}
HRESULT WINAPI CtfImeCreateInputContext(
HIMC hImc)
{
TLS* ptls = TLS::GetTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeCreateInputContext. ptls==NULL."));
return E_OUTOFMEMORY;
}
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeCreateInputContext. cic==NULL."));
return E_OUTOFMEMORY;
}
return cic->CreateInputContext(ptls, hImc);
}
HRESULT WINAPI CtfImeDestroyInputContext(
HIMC hImc)
{
TLS* ptls = TLS::ReferenceTLS(); // Should not allocate TLS. ie. TLS::GetTLS
// IMM32::ImmDllInitialize -> IMM32::DestroyInputContext
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeDestroyInputContext. ptls==NULL."));
return E_OUTOFMEMORY;
}
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeDestroyInputContext. cic==NULL."));
return E_OUTOFMEMORY;
}
return cic->DestroyInputContext(ptls, hImc);
}
HRESULT InternalSelectEx(
HIMC hImc,
BOOL fSelect,
HKL hKL)
{
DebugMsg(TF_FUNC, TEXT("InternalSelectEx(hImc=%x, fSelect=%x, hKL=%x)"), hImc, fSelect, hKL);
HRESULT hr;
IMCLock imc(hImc);
if (FAILED(hr = imc.GetResult()))
{
DebugMsg(TF_ERROR, TEXT("InternalSelectEx. imc==NULL"));
return hr;
}
LANGID langid = LANGIDFROMLCID(PtrToUlong(hKL));
//
// Chinese Legacy IME hack code for near caret IME.
//
if (PRIMARYLANGID(langid) == LANG_CHINESE)
{
imc->cfCandForm[0].dwStyle = CFS_DEFAULT;
imc->cfCandForm[0].dwIndex = (DWORD)-1;
}
if (fSelect)
{
if (! imc.ClearCand()) {
return E_FAIL;
}
if ((imc->fdwInit & INIT_CONVERSION) == 0) {
DWORD fdwConvForLang = (imc->fdwConversion & IME_CMODE_SOFTKBD); // = IME_CMODE_ALPHANUMERIC
if (langid)
{
switch(PRIMARYLANGID(langid))
{
case LANG_JAPANESE:
//
// Roman-FullShape-Native is a major convmode to
// initialize.
//
fdwConvForLang |= IME_CMODE_ROMAN |
IME_CMODE_FULLSHAPE |
IME_CMODE_NATIVE;
break;
case LANG_KOREAN:
// IME_CMODE_ALPHANUMERIC
break;
#ifdef CICERO_4428
case LANG_CHINESE:
switch(SUBLANGID(langid))
{
case SUBLANG_CHINESE_TRADITIONAL:
// IME_CMODE_ALPHANUMERIC
break;
default:
fdwConvForLang |= IME_CMODE_NATIVE;
break;
}
break;
#endif
default:
fdwConvForLang |= IME_CMODE_NATIVE;
break;
}
}
imc->fdwConversion |= fdwConvForLang;
imc->fdwInit |= INIT_CONVERSION;
}
//
// Also, initialize extended fdwSentence flag.
//
imc->fdwSentence |= IME_SMODE_PHRASEPREDICT;
if ((imc->fdwInit & INIT_LOGFONT) == 0) {
HDC hDC;
HGDIOBJ hSysFont;
hDC = ::GetDC(imc->hWnd);
hSysFont = ::GetCurrentObject(hDC, OBJ_FONT);
LOGFONTW font;
::GetObjectW(hSysFont, sizeof(LOGFONTW), &font);
::ReleaseDC(NULL, hDC);
memcpy(&imc->lfFont.W, &font, sizeof(LOGFONTW));
imc->fdwInit |= INIT_LOGFONT;
}
// if this IME is run under Chicago Simplified Chinese version
imc->lfFont.W.lfCharSet = GetCharsetFromLangId(langid);
imc.InitContext();
}
else { // being unselected
//
// Reset INIT_GUID_ATOM flag here.
//
imc->fdwInit &= ~INIT_GUID_ATOM;
}
return hr;
}
HRESULT WINAPI CtfImeSelectEx(
HIMC hIMC,
BOOL fSelect,
HKL hKL)
{
TLS* ptls = TLS::ReferenceTLS(); // Should not allocate TLS. ie. TLS::GetTLS
// IMM32::ImmDllInitialize -> IMM32::DestroyInputContext
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeSelectEx. ptls==NULL."));
return E_OUTOFMEMORY;
}
//
// This is only related hIMC content.
// Even no cic object, hIMC should be updated.
//
InternalSelectEx(hIMC, fSelect, hKL);
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeSelectEx. cic==NULL."));
return E_OUTOFMEMORY;
}
ITfThreadMgr_P* ptim_P = ptls->GetTIM();
if (ptim_P == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeSelectEx. ptim_P==NULL."));
return E_OUTOFMEMORY;
}
return cic->SelectEx(ptls, ptim_P, hIMC, fSelect, hKL);
}
HRESULT WINAPI CtfImeSetActiveContextAlways(
HIMC hIMC,
BOOL fOn,
HWND hWnd,
HKL hKL)
{
TLS* ptls = TLS::GetTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeSetActiveContextAlways. ptls==NULL."));
return E_OUTOFMEMORY;
}
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeSetActiveContextAlways. cic==NULL."));
return E_OUTOFMEMORY;
}
return cic->SetActiveContextAlways(ptls, hIMC, fOn, hWnd, hKL);
}
LRESULT WINAPI CtfImeEscapeEx(
HIMC hIMC,
UINT uSubFunc,
LPVOID lpData,
HKL hKL)
{
if (LOWORD(HandleToUlong(hKL)) == MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT))
{
TLS* ptls = TLS::GetTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeEscapeEx. ptls==NULL."));
return FALSE;
}
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeEscapeEx. cic==NULL."));
return FALSE;
}
return cic->EscapeKorean(ptls, hIMC, uSubFunc, lpData);
}
return FALSE;
}
HRESULT WINAPI CtfImeGetGuidAtom(
HIMC hIMC,
BYTE bAttr,
TfGuidAtom* pAtom)
{
TLS* ptls = TLS::GetTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeGetGuidAtom. ptls==NULL."));
return E_OUTOFMEMORY;
}
CicBridge* cic = ptls->GetCicBridge();
if (cic == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeGetGuidAtom. cic==NULL."));
return E_OUTOFMEMORY;
}
return cic->GetGuidAtom(ptls, hIMC, bAttr, pAtom);
}
BOOL WINAPI CtfImeIsGuidMapEnable(
HIMC hIMC)
{
HRESULT hr;
IMCLock imc(hIMC);
if (FAILED(hr=imc.GetResult()))
{
DebugMsg(TF_ERROR, TEXT("CtfImeIsGuidMapEnable. imc==NULL"));
return FALSE;
}
return (imc->fdwInit & INIT_GUID_ATOM) ? TRUE : FALSE;
}
HRESULT WINAPI CtfImeThreadDetach()
{
ImeDestroy(0);
return S_OK;
}
BOOL WINAPI CtfImeIsIME(
HKL hkl)
{
if (IS_IME_KBDLAYOUT(hkl))
return TRUE;
TLS* ptls = TLS::GetTLS();
if (ptls == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeIsIME. ptls==NULL."));
return FALSE;
}
CicProfile* pProfile = ptls->GetCicProfile();
if (pProfile == NULL)
{
DebugMsg(TF_ERROR, TEXT("CtfImeIsIME. pProfile==NULL."));
return FALSE;
}
return (pProfile->IsIME(hkl) == S_OK) ? TRUE : FALSE;
}
} // extern "C"