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
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"
|