mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 09:50:07 +00:00
[MSCTFIME] Implement CtfImeSetActiveContextAlways (#6522)
Supporting TIPs... JIRA issue: CORE-19360 - Move code of functions.cpp into misc.cpp and delete functions.cpp. - Add implementation to CicBridge::GetDocumentManager, CicBridge::CreateInputContext, and CicBridge::SetActiveContextAlways methods. - Implement NotifyIME, CtfImeSetActiveContextAlways, and CtfImeCreateInputContext functions.
This commit is contained in:
parent
69b08be0e0
commit
980ebf0694
|
@ -1,12 +1,8 @@
|
||||||
|
|
||||||
include_directories(
|
|
||||||
${REACTOS_SOURCE_DIR}/win32ss/include)
|
|
||||||
|
|
||||||
spec2def(msctfime.ime msctfime.spec)
|
spec2def(msctfime.ime msctfime.spec)
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
bridge.cpp
|
bridge.cpp
|
||||||
functions.cpp
|
|
||||||
inputcontext.cpp
|
inputcontext.cpp
|
||||||
misc.cpp
|
misc.cpp
|
||||||
msctfime.cpp
|
msctfime.cpp
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS msctfime.ime
|
* PROJECT: ReactOS msctfime.ime
|
||||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||||
* PURPOSE: Bridge
|
* PURPOSE: The bridge of msctfime.ime
|
||||||
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -65,22 +65,19 @@ CicBridge::~CicBridge()
|
||||||
UnInitIMMX(pTLS);
|
UnInitIMMX(pTLS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CicBridge::GetDocumentManager(_Inout_ CicIMCCLock<CTFIMECONTEXT>& imeContext)
|
/// @implemented
|
||||||
|
ITfDocumentMgr*
|
||||||
|
CicBridge::GetDocumentManager(_Inout_ CicIMCCLock<CTFIMECONTEXT>& imeContext)
|
||||||
{
|
{
|
||||||
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
||||||
if (pCicIC)
|
if (!pCicIC)
|
||||||
{
|
return NULL;
|
||||||
m_pDocMgr = pCicIC->m_pDocumentMgr;
|
|
||||||
m_pDocMgr->AddRef();
|
pCicIC->m_pDocumentMgr->AddRef();
|
||||||
}
|
return pCicIC->m_pDocumentMgr;
|
||||||
else
|
|
||||||
{
|
|
||||||
m_pDocMgr->Release();
|
|
||||||
m_pDocMgr = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @unimplemented
|
/// @implemented
|
||||||
HRESULT
|
HRESULT
|
||||||
CicBridge::CreateInputContext(
|
CicBridge::CreateInputContext(
|
||||||
_Inout_ TLS *pTLS,
|
_Inout_ TLS *pTLS,
|
||||||
|
@ -100,45 +97,49 @@ CicBridge::CreateInputContext(
|
||||||
|
|
||||||
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
|
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
|
||||||
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
||||||
|
if (pCicIC)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
pCicIC = new(cicNoThrow) CicInputContext(m_cliendId, &m_LibThread, hIMC);
|
||||||
if (!pCicIC)
|
if (!pCicIC)
|
||||||
{
|
{
|
||||||
pCicIC = new(cicNoThrow) CicInputContext(m_cliendId, &m_LibThread, hIMC);
|
imeContext.unlock();
|
||||||
if (!pCicIC)
|
imcLock.unlock();
|
||||||
{
|
DestroyInputContext(pTLS, hIMC);
|
||||||
imeContext.unlock();
|
return E_OUTOFMEMORY;
|
||||||
imcLock.unlock();
|
|
||||||
DestroyInputContext(pTLS, hIMC);
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pTLS->m_pThreadMgr)
|
|
||||||
{
|
|
||||||
pCicIC->Release();
|
|
||||||
imeContext.unlock();
|
|
||||||
imcLock.unlock();
|
|
||||||
DestroyInputContext(pTLS, hIMC);
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
imeContext.get().m_pCicIC = pCicIC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pTLS->m_pThreadMgr)
|
||||||
|
{
|
||||||
|
pCicIC->Release();
|
||||||
|
imeContext.unlock();
|
||||||
|
imcLock.unlock();
|
||||||
|
DestroyInputContext(pTLS, hIMC);
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
imeContext.get().m_pCicIC = pCicIC;
|
||||||
|
|
||||||
HRESULT hr = pCicIC->CreateInputContext(pTLS->m_pThreadMgr, imcLock);
|
HRESULT hr = pCicIC->CreateInputContext(pTLS->m_pThreadMgr, imcLock);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
pCicIC->Release();
|
pCicIC->Release();
|
||||||
imeContext.get().m_pCicIC = NULL;
|
imeContext.get().m_pCicIC = NULL;
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
HWND hWnd = imcLock.get().hWnd;
|
||||||
|
if (hWnd && hWnd == ::GetFocus())
|
||||||
{
|
{
|
||||||
if (imcLock.get().hWnd && imcLock.get().hWnd == ::GetFocus())
|
ITfDocumentMgr *pDocMgr = GetDocumentManager(imeContext);
|
||||||
|
if (pDocMgr)
|
||||||
{
|
{
|
||||||
GetDocumentManager(imeContext);
|
SetAssociate(pTLS, hWnd, hIMC, pTLS->m_pThreadMgr, pDocMgr);
|
||||||
//FIXME
|
pDocMgr->Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return E_NOTIMPL;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @implemented
|
/// @implemented
|
||||||
|
@ -608,3 +609,83 @@ CicBridge::ConfigureRegisterWord(
|
||||||
pFunction->Release();
|
pFunction->Release();
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @unimplemented
|
||||||
|
void CicBridge::SetAssociate(
|
||||||
|
TLS *pTLS,
|
||||||
|
HWND hWnd,
|
||||||
|
HIMC hIMC,
|
||||||
|
ITfThreadMgr_P *pThreadMgr,
|
||||||
|
ITfDocumentMgr *pDocMgr)
|
||||||
|
{
|
||||||
|
//FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
CicBridge::SetActiveContextAlways(TLS *pTLS, HIMC hIMC, BOOL fActive, HWND hWnd, HKL hKL)
|
||||||
|
{
|
||||||
|
auto pThreadMgr = pTLS->m_pThreadMgr;
|
||||||
|
if (!pThreadMgr)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
if (fActive)
|
||||||
|
{
|
||||||
|
if (!hIMC)
|
||||||
|
{
|
||||||
|
SetAssociate(pTLS, hWnd, hIMC, pThreadMgr, m_pDocMgr);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
CicIMCLock imcLock(hIMC);
|
||||||
|
if (FAILED(imcLock.m_hr))
|
||||||
|
return imcLock.m_hr;
|
||||||
|
|
||||||
|
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
|
||||||
|
if (FAILED(imeContext.m_hr))
|
||||||
|
return imeContext.m_hr;
|
||||||
|
|
||||||
|
if (hIMC == ::ImmGetContext(hWnd))
|
||||||
|
{
|
||||||
|
ITfDocumentMgr *pDocMgr = GetDocumentManager(imeContext);
|
||||||
|
if (pDocMgr)
|
||||||
|
{
|
||||||
|
SetAssociate(pTLS, imcLock.get().hWnd, hIMC, pThreadMgr, pDocMgr);
|
||||||
|
pDocMgr->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hIMC && !IsEALang(LOWORD(hKL)))
|
||||||
|
{
|
||||||
|
CicIMCLock imcLock(hIMC);
|
||||||
|
if (FAILED(imcLock.m_hr))
|
||||||
|
return imcLock.m_hr;
|
||||||
|
|
||||||
|
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
|
||||||
|
if (FAILED(imeContext.m_hr))
|
||||||
|
return imeContext.m_hr;
|
||||||
|
|
||||||
|
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
||||||
|
if (!pCicIC->m_dwUnknown6_5[2] && !pCicIC->m_dwUnknown6_5[3])
|
||||||
|
::ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hIMC || (::GetFocus() != hWnd) || (hIMC != ::ImmGetContext(hWnd)))
|
||||||
|
SetAssociate(pTLS, hWnd, hIMC, pThreadMgr, m_pDocMgr);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @unimplemented
|
||||||
|
HRESULT CicBridge::Notify(
|
||||||
|
TLS *pTLS,
|
||||||
|
ITfThreadMgr *pThreadMgr,
|
||||||
|
HIMC hIMC,
|
||||||
|
DWORD dwAction,
|
||||||
|
DWORD dwIndex,
|
||||||
|
DWORD_PTR dwValue)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL; // FIXME
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS msctfime.ime
|
* PROJECT: ReactOS msctfime.ime
|
||||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||||
* PURPOSE: Bridge
|
* PURPOSE: The bridge of msctfime.ime
|
||||||
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ public:
|
||||||
CicInputContext *pCicIC);
|
CicInputContext *pCicIC);
|
||||||
|
|
||||||
void PostTransMsg(_In_ HWND hWnd, _In_ INT cTransMsgs, _In_ const TRANSMSG *pTransMsgs);
|
void PostTransMsg(_In_ HWND hWnd, _In_ INT cTransMsgs, _In_ const TRANSMSG *pTransMsgs);
|
||||||
void GetDocumentManager(_Inout_ CicIMCCLock<CTFIMECONTEXT>& imeContext);
|
ITfDocumentMgr* GetDocumentManager(_Inout_ CicIMCCLock<CTFIMECONTEXT>& imeContext);
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
ConfigureGeneral(_Inout_ TLS* pTLS,
|
ConfigureGeneral(_Inout_ TLS* pTLS,
|
||||||
|
@ -77,4 +77,21 @@ public:
|
||||||
_In_ HKL hKL,
|
_In_ HKL hKL,
|
||||||
_In_ HWND hWnd,
|
_In_ HWND hWnd,
|
||||||
_Inout_opt_ LPVOID lpData);
|
_Inout_opt_ LPVOID lpData);
|
||||||
|
|
||||||
|
HRESULT SetActiveContextAlways(TLS *pTLS, HIMC hIMC, BOOL fActive, HWND hWnd, HKL hKL);
|
||||||
|
|
||||||
|
void SetAssociate(
|
||||||
|
TLS *pTLS,
|
||||||
|
HWND hWnd,
|
||||||
|
HIMC hIMC,
|
||||||
|
ITfThreadMgr_P *pThreadMgr,
|
||||||
|
ITfDocumentMgr *pDocMgr);
|
||||||
|
|
||||||
|
HRESULT Notify(
|
||||||
|
TLS *pTLS,
|
||||||
|
ITfThreadMgr *pThreadMgr,
|
||||||
|
HIMC hIMC,
|
||||||
|
DWORD dwAction,
|
||||||
|
DWORD dwIndex,
|
||||||
|
DWORD_PTR dwValue);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,261 +0,0 @@
|
||||||
/*
|
|
||||||
* PROJECT: ReactOS msctfime.ime
|
|
||||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
|
||||||
* PURPOSE: The functionalities of msctfime.ime
|
|
||||||
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "msctfime.h"
|
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(msctfime);
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
CFunctionProviderBase::CFunctionProviderBase(_In_ TfClientId clientId)
|
|
||||||
{
|
|
||||||
m_clientId = clientId;
|
|
||||||
m_guid = GUID_NULL;
|
|
||||||
m_bstr = NULL;
|
|
||||||
m_cRefs = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
CFunctionProviderBase::~CFunctionProviderBase()
|
|
||||||
{
|
|
||||||
if (!DllShutdownInProgress())
|
|
||||||
::SysFreeString(m_bstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
BOOL
|
|
||||||
CFunctionProviderBase::Init(
|
|
||||||
_In_ REFGUID rguid,
|
|
||||||
_In_ LPCWSTR psz)
|
|
||||||
{
|
|
||||||
m_bstr = ::SysAllocString(psz);
|
|
||||||
m_guid = rguid;
|
|
||||||
return (m_bstr != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
STDMETHODIMP
|
|
||||||
CFunctionProviderBase::QueryInterface(
|
|
||||||
_In_ REFIID riid,
|
|
||||||
_Out_ LPVOID* ppvObj)
|
|
||||||
{
|
|
||||||
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfFunctionProvider))
|
|
||||||
{
|
|
||||||
*ppvObj = this;
|
|
||||||
AddRef();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
STDMETHODIMP_(ULONG) CFunctionProviderBase::AddRef()
|
|
||||||
{
|
|
||||||
return ::InterlockedIncrement(&m_cRefs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
STDMETHODIMP_(ULONG) CFunctionProviderBase::Release()
|
|
||||||
{
|
|
||||||
if (::InterlockedDecrement(&m_cRefs) == 0)
|
|
||||||
{
|
|
||||||
delete this;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return m_cRefs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
STDMETHODIMP CFunctionProviderBase::GetType(_Out_ GUID *guid)
|
|
||||||
{
|
|
||||||
*guid = m_guid;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
STDMETHODIMP CFunctionProviderBase::GetDescription(_Out_ BSTR *desc)
|
|
||||||
{
|
|
||||||
*desc = ::SysAllocString(m_bstr);
|
|
||||||
return (*desc ? S_OK : E_OUTOFMEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
CFunctionProvider::CFunctionProvider(_In_ TfClientId clientId) : CFunctionProviderBase(clientId)
|
|
||||||
{
|
|
||||||
Init(CLSID_CAImmLayer, L"MSCTFIME::Function Provider");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
STDMETHODIMP
|
|
||||||
CFunctionProvider::GetFunction(
|
|
||||||
_In_ REFGUID guid,
|
|
||||||
_In_ REFIID riid,
|
|
||||||
_Out_ IUnknown **func)
|
|
||||||
{
|
|
||||||
*func = NULL;
|
|
||||||
|
|
||||||
if (IsEqualGUID(guid, GUID_NULL) &&
|
|
||||||
IsEqualIID(riid, IID_IAImmFnDocFeed))
|
|
||||||
{
|
|
||||||
*func = new(cicNoThrow) CFnDocFeed();
|
|
||||||
if (*func)
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
|
|
||||||
CFnDocFeed::CFnDocFeed()
|
|
||||||
{
|
|
||||||
m_cRefs = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFnDocFeed::~CFnDocFeed()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
STDMETHODIMP CFnDocFeed::QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj)
|
|
||||||
{
|
|
||||||
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IAImmFnDocFeed))
|
|
||||||
{
|
|
||||||
*ppvObj = this;
|
|
||||||
AddRef();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
STDMETHODIMP_(ULONG) CFnDocFeed::AddRef()
|
|
||||||
{
|
|
||||||
return ::InterlockedIncrement(&m_cRefs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
STDMETHODIMP_(ULONG) CFnDocFeed::Release()
|
|
||||||
{
|
|
||||||
if (::InterlockedDecrement(&m_cRefs) == 0)
|
|
||||||
{
|
|
||||||
delete this;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return m_cRefs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
STDMETHODIMP CFnDocFeed::DocFeed()
|
|
||||||
{
|
|
||||||
TLS *pTLS = TLS::GetTLS();
|
|
||||||
if (!pTLS)
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
HIMC hIMC = GetActiveContext();
|
|
||||||
CicIMCLock imcLock(hIMC);
|
|
||||||
if (FAILED(imcLock.m_hr))
|
|
||||||
return imcLock.m_hr;
|
|
||||||
|
|
||||||
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
|
|
||||||
if (FAILED(imeContext.m_hr))
|
|
||||||
return imeContext.m_hr;
|
|
||||||
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
|
||||||
if (!pCicIC)
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
UINT uCodePage = CP_ACP;
|
|
||||||
pTLS->m_pProfile->GetCodePageA(&uCodePage);
|
|
||||||
pCicIC->SetupDocFeedString(imcLock, uCodePage);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
STDMETHODIMP CFnDocFeed::ClearDocFeedBuffer()
|
|
||||||
{
|
|
||||||
if (!TLS::GetTLS())
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
HIMC hIMC = GetActiveContext();
|
|
||||||
CicIMCLock imcLock(hIMC);
|
|
||||||
if (FAILED(imcLock.m_hr))
|
|
||||||
return imcLock.m_hr;
|
|
||||||
|
|
||||||
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
|
|
||||||
if (FAILED(imeContext.m_hr))
|
|
||||||
return imeContext.m_hr;
|
|
||||||
|
|
||||||
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
|
||||||
if (!pCicIC)
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
pCicIC->EscbClearDocFeedBuffer(imcLock, TRUE);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @unimplemented
|
|
||||||
STDMETHODIMP CFnDocFeed::StartReconvert()
|
|
||||||
{
|
|
||||||
TLS *pTLS = TLS::GetTLS();
|
|
||||||
if (!pTLS)
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
auto *pThreadMgr = pTLS->m_pThreadMgr;
|
|
||||||
if (!pThreadMgr)
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
HIMC hIMC = GetActiveContext();
|
|
||||||
CicIMCLock imcLock(hIMC);
|
|
||||||
if (FAILED(imcLock.m_hr))
|
|
||||||
return imcLock.m_hr;
|
|
||||||
|
|
||||||
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
|
|
||||||
if (FAILED(imeContext.m_hr))
|
|
||||||
return imeContext.m_hr;
|
|
||||||
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
|
||||||
if (!pCicIC)
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
UINT uCodePage = CP_ACP;
|
|
||||||
pTLS->m_pProfile->GetCodePageA(&uCodePage);
|
|
||||||
|
|
||||||
pCicIC->m_bReconverting = TRUE;
|
|
||||||
pCicIC->SetupReconvertString(imcLock, pThreadMgr, uCodePage, 0, 0);
|
|
||||||
pCicIC->EndReconvertString(imcLock);
|
|
||||||
pCicIC->m_bReconverting = FALSE;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
STDMETHODIMP CFnDocFeed::StartUndoCompositionString()
|
|
||||||
{
|
|
||||||
TLS *pTLS = TLS::GetTLS();
|
|
||||||
if (!pTLS)
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
auto *pThreadMgr = pTLS->m_pThreadMgr;
|
|
||||||
if (!pThreadMgr)
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
HIMC hIMC = GetActiveContext();
|
|
||||||
CicIMCLock imcLock(hIMC);
|
|
||||||
if (FAILED(imcLock.m_hr))
|
|
||||||
return imcLock.m_hr;
|
|
||||||
|
|
||||||
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
|
|
||||||
if (FAILED(imeContext.m_hr))
|
|
||||||
return imeContext.m_hr;
|
|
||||||
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
|
||||||
if (!pCicIC)
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
UINT uCodePage = CP_ACP;
|
|
||||||
pTLS->m_pProfile->GetCodePageA(&uCodePage);
|
|
||||||
|
|
||||||
pCicIC->SetupReconvertString(imcLock, pThreadMgr, uCodePage, 0, TRUE);
|
|
||||||
pCicIC->EndReconvertString(imcLock);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* PROJECT: ReactOS msctfime.ime
|
|
||||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
|
||||||
* PURPOSE: The functionalities of msctfime.ime
|
|
||||||
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
class CFunctionProviderBase : public ITfFunctionProvider
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
TfClientId m_clientId;
|
|
||||||
GUID m_guid;
|
|
||||||
BSTR m_bstr;
|
|
||||||
LONG m_cRefs;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CFunctionProviderBase(_In_ TfClientId clientId);
|
|
||||||
virtual ~CFunctionProviderBase();
|
|
||||||
|
|
||||||
// IUnknown interface
|
|
||||||
STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override;
|
|
||||||
STDMETHODIMP_(ULONG) AddRef() override;
|
|
||||||
STDMETHODIMP_(ULONG) Release() override;
|
|
||||||
|
|
||||||
// ITfFunctionProvider interface
|
|
||||||
STDMETHODIMP GetType(_Out_ GUID *guid) override;
|
|
||||||
STDMETHODIMP GetDescription(_Out_ BSTR *desc) override;
|
|
||||||
//STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) = 0;
|
|
||||||
|
|
||||||
BOOL Init(_In_ REFGUID rguid, _In_ LPCWSTR psz);
|
|
||||||
};
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
|
|
||||||
class CFunctionProvider : public CFunctionProviderBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CFunctionProvider(_In_ TfClientId clientId);
|
|
||||||
|
|
||||||
STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
|
|
||||||
class CFnDocFeed : public IAImmFnDocFeed
|
|
||||||
{
|
|
||||||
LONG m_cRefs;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CFnDocFeed();
|
|
||||||
virtual ~CFnDocFeed();
|
|
||||||
|
|
||||||
// IUnknown interface
|
|
||||||
STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override;
|
|
||||||
STDMETHODIMP_(ULONG) AddRef() override;
|
|
||||||
STDMETHODIMP_(ULONG) Release() override;
|
|
||||||
|
|
||||||
// IAImmFnDocFeed interface
|
|
||||||
STDMETHODIMP DocFeed() override;
|
|
||||||
STDMETHODIMP ClearDocFeedBuffer() override;
|
|
||||||
STDMETHODIMP StartReconvert() override;
|
|
||||||
STDMETHODIMP StartUndoCompositionString() override;
|
|
||||||
};
|
|
|
@ -9,6 +9,185 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(msctfime);
|
WINE_DEFAULT_DEBUG_CHANNEL(msctfime);
|
||||||
|
|
||||||
|
/// East-Asian language?
|
||||||
|
/// @implemented
|
||||||
|
BOOL IsEALang(LANGID LangID)
|
||||||
|
{
|
||||||
|
if (LangID == 0)
|
||||||
|
{
|
||||||
|
TLS *pTLS = TLS::GetTLS();
|
||||||
|
if (!pTLS || !pTLS->m_pProfile)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pTLS->m_pProfile->GetLangId(&LangID);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (PRIMARYLANGID(LangID))
|
||||||
|
{
|
||||||
|
case LANG_CHINESE:
|
||||||
|
case LANG_JAPANESE:
|
||||||
|
case LANG_KOREAN:
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef BOOLEAN (WINAPI *FN_DllShutdownInProgress)(VOID);
|
||||||
|
|
||||||
|
/// This function calls ntdll!RtlDllShutdownInProgress.
|
||||||
|
/// It can detect the system is shutting down or not.
|
||||||
|
/// @implemented
|
||||||
|
BOOLEAN DllShutdownInProgress(VOID)
|
||||||
|
{
|
||||||
|
HMODULE hNTDLL;
|
||||||
|
static FN_DllShutdownInProgress s_fnDllShutdownInProgress = NULL;
|
||||||
|
|
||||||
|
if (s_fnDllShutdownInProgress)
|
||||||
|
return s_fnDllShutdownInProgress();
|
||||||
|
|
||||||
|
hNTDLL = cicGetSystemModuleHandle(L"ntdll.dll", FALSE);
|
||||||
|
s_fnDllShutdownInProgress =
|
||||||
|
(FN_DllShutdownInProgress)GetProcAddress(hNTDLL, "RtlDllShutdownInProgress");
|
||||||
|
if (!s_fnDllShutdownInProgress)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return s_fnDllShutdownInProgress();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This function checks if the current user logon session is interactive.
|
||||||
|
/// @implemented
|
||||||
|
BOOL IsInteractiveUserLogon(VOID)
|
||||||
|
{
|
||||||
|
BOOL bOK, IsMember = FALSE;
|
||||||
|
PSID pSid;
|
||||||
|
SID_IDENTIFIER_AUTHORITY IdentAuth = { SECURITY_NT_AUTHORITY };
|
||||||
|
|
||||||
|
if (!AllocateAndInitializeSid(&IdentAuth, 1, SECURITY_INTERACTIVE_RID,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, &pSid))
|
||||||
|
{
|
||||||
|
ERR("Error: %ld\n", GetLastError());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bOK = CheckTokenMembership(NULL, pSid, &IsMember);
|
||||||
|
|
||||||
|
if (pSid)
|
||||||
|
FreeSid(pSid);
|
||||||
|
|
||||||
|
return bOK && IsMember;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the charset from a language ID.
|
||||||
|
/// @implemented
|
||||||
|
BYTE GetCharsetFromLangId(_In_ DWORD dwValue)
|
||||||
|
{
|
||||||
|
CHARSETINFO info;
|
||||||
|
if (!::TranslateCharsetInfo((DWORD*)(DWORD_PTR)dwValue, &info, TCI_SRCLOCALE))
|
||||||
|
return 0;
|
||||||
|
return info.ciCharset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the active input context.
|
||||||
|
/// @implemented
|
||||||
|
HIMC GetActiveContext(VOID)
|
||||||
|
{
|
||||||
|
HWND hwndFocus = ::GetFocus();
|
||||||
|
if (!hwndFocus)
|
||||||
|
hwndFocus = ::GetActiveWindow();
|
||||||
|
return ::ImmGetContext(hwndFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
ITfCategoryMgr *GetUIMCat(PCIC_LIBTHREAD pLibThread)
|
||||||
|
{
|
||||||
|
if (!pLibThread)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (pLibThread->m_pCategoryMgr)
|
||||||
|
return pLibThread->m_pCategoryMgr;
|
||||||
|
|
||||||
|
if (FAILED(cicCoCreateInstance(CLSID_TF_CategoryMgr, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
IID_ITfCategoryMgr, (void **)&pLibThread->m_pCategoryMgr)))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return pLibThread->m_pCategoryMgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
static HRESULT
|
||||||
|
LibEnumItemsInCategory(PCIC_LIBTHREAD pLibThread, REFGUID rguid, IEnumGUID **ppEnum)
|
||||||
|
{
|
||||||
|
ITfCategoryMgr *pCat = GetUIMCat(pLibThread);
|
||||||
|
if (!pCat)
|
||||||
|
return E_FAIL;
|
||||||
|
return pCat->EnumItemsInCategory(rguid, ppEnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
HRESULT InitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread)
|
||||||
|
{
|
||||||
|
if (!pLibThread)
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if (pLibThread->m_pDisplayAttrMgr)
|
||||||
|
{
|
||||||
|
pLibThread->m_pDisplayAttrMgr->Release();
|
||||||
|
pLibThread->m_pDisplayAttrMgr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(cicCoCreateInstance(CLSID_TF_DisplayAttributeMgr, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
IID_ITfDisplayAttributeMgr,
|
||||||
|
(void **)&pLibThread->m_pDisplayAttrMgr)))
|
||||||
|
{
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumGUID *pEnumGuid;
|
||||||
|
LibEnumItemsInCategory(pLibThread, GUID_TFCAT_DISPLAYATTRIBUTEPROPERTY, &pEnumGuid);
|
||||||
|
|
||||||
|
HRESULT hr = E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
::EnterCriticalSection(&g_csLock);
|
||||||
|
if (pEnumGuid && !g_pPropCache)
|
||||||
|
{
|
||||||
|
g_pPropCache = new(cicNoThrow) CDispAttrPropCache();
|
||||||
|
if (g_pPropCache)
|
||||||
|
{
|
||||||
|
g_pPropCache->Add(GUID_PROP_ATTRIBUTE);
|
||||||
|
GUID guid;
|
||||||
|
while (pEnumGuid->Next(1, &guid, NULL) == S_OK)
|
||||||
|
{
|
||||||
|
if (!IsEqualGUID(guid, GUID_PROP_ATTRIBUTE))
|
||||||
|
g_pPropCache->Add(guid);
|
||||||
|
}
|
||||||
|
hr = S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::LeaveCriticalSection(&g_csLock);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread)
|
||||||
|
{
|
||||||
|
if (!pLibThread)
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if (pLibThread->m_pDisplayAttrMgr)
|
||||||
|
{
|
||||||
|
pLibThread->m_pDisplayAttrMgr->Release();
|
||||||
|
pLibThread->m_pDisplayAttrMgr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
/// @implemented
|
/// @implemented
|
||||||
HRESULT
|
HRESULT
|
||||||
GetCompartment(
|
GetCompartment(
|
||||||
|
@ -179,11 +358,13 @@ static const MODEBIAS g_ModeBiasMap[] =
|
||||||
{ GUID_MODEBIAS_NONE, 0x00000000 },
|
{ GUID_MODEBIAS_NONE, 0x00000000 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
void CModeBias::SetModeBias(REFGUID rguid)
|
void CModeBias::SetModeBias(REFGUID rguid)
|
||||||
{
|
{
|
||||||
m_guid = rguid;
|
m_guid = rguid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
GUID CModeBias::ConvertModeBias(LONG bias)
|
GUID CModeBias::ConvertModeBias(LONG bias)
|
||||||
{
|
{
|
||||||
const GUID *pguid = &GUID_NULL;
|
const GUID *pguid = &GUID_NULL;
|
||||||
|
@ -199,6 +380,7 @@ GUID CModeBias::ConvertModeBias(LONG bias)
|
||||||
return *pguid;
|
return *pguid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
LONG CModeBias::ConvertModeBias(REFGUID guid)
|
LONG CModeBias::ConvertModeBias(REFGUID guid)
|
||||||
{
|
{
|
||||||
for (auto& item : g_ModeBiasMap)
|
for (auto& item : g_ModeBiasMap)
|
||||||
|
@ -211,25 +393,253 @@ LONG CModeBias::ConvertModeBias(REFGUID guid)
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
/// East-Asian language?
|
|
||||||
/// @implemented
|
/// @implemented
|
||||||
BOOL IsEALang(VOID)
|
CFunctionProviderBase::CFunctionProviderBase(_In_ TfClientId clientId)
|
||||||
|
{
|
||||||
|
m_clientId = clientId;
|
||||||
|
m_guid = GUID_NULL;
|
||||||
|
m_bstr = NULL;
|
||||||
|
m_cRefs = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
CFunctionProviderBase::~CFunctionProviderBase()
|
||||||
|
{
|
||||||
|
if (!DllShutdownInProgress())
|
||||||
|
::SysFreeString(m_bstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
BOOL
|
||||||
|
CFunctionProviderBase::Init(
|
||||||
|
_In_ REFGUID rguid,
|
||||||
|
_In_ LPCWSTR psz)
|
||||||
|
{
|
||||||
|
m_bstr = ::SysAllocString(psz);
|
||||||
|
m_guid = rguid;
|
||||||
|
return (m_bstr != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
STDMETHODIMP
|
||||||
|
CFunctionProviderBase::QueryInterface(
|
||||||
|
_In_ REFIID riid,
|
||||||
|
_Out_ LPVOID* ppvObj)
|
||||||
|
{
|
||||||
|
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfFunctionProvider))
|
||||||
|
{
|
||||||
|
*ppvObj = this;
|
||||||
|
AddRef();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
STDMETHODIMP_(ULONG) CFunctionProviderBase::AddRef()
|
||||||
|
{
|
||||||
|
return ::InterlockedIncrement(&m_cRefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
STDMETHODIMP_(ULONG) CFunctionProviderBase::Release()
|
||||||
|
{
|
||||||
|
if (::InterlockedDecrement(&m_cRefs) == 0)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return m_cRefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
STDMETHODIMP CFunctionProviderBase::GetType(_Out_ GUID *guid)
|
||||||
|
{
|
||||||
|
*guid = m_guid;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
STDMETHODIMP CFunctionProviderBase::GetDescription(_Out_ BSTR *desc)
|
||||||
|
{
|
||||||
|
*desc = ::SysAllocString(m_bstr);
|
||||||
|
return (*desc ? S_OK : E_OUTOFMEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
CFunctionProvider::CFunctionProvider(_In_ TfClientId clientId) : CFunctionProviderBase(clientId)
|
||||||
|
{
|
||||||
|
Init(CLSID_CAImmLayer, L"MSCTFIME::Function Provider");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
STDMETHODIMP
|
||||||
|
CFunctionProvider::GetFunction(
|
||||||
|
_In_ REFGUID guid,
|
||||||
|
_In_ REFIID riid,
|
||||||
|
_Out_ IUnknown **func)
|
||||||
|
{
|
||||||
|
*func = NULL;
|
||||||
|
|
||||||
|
if (IsEqualGUID(guid, GUID_NULL) &&
|
||||||
|
IsEqualIID(riid, IID_IAImmFnDocFeed))
|
||||||
|
{
|
||||||
|
*func = new(cicNoThrow) CFnDocFeed();
|
||||||
|
if (*func)
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
CFnDocFeed::CFnDocFeed()
|
||||||
|
{
|
||||||
|
m_cRefs = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFnDocFeed::~CFnDocFeed()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
STDMETHODIMP CFnDocFeed::QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj)
|
||||||
|
{
|
||||||
|
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IAImmFnDocFeed))
|
||||||
|
{
|
||||||
|
*ppvObj = this;
|
||||||
|
AddRef();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
STDMETHODIMP_(ULONG) CFnDocFeed::AddRef()
|
||||||
|
{
|
||||||
|
return ::InterlockedIncrement(&m_cRefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
STDMETHODIMP_(ULONG) CFnDocFeed::Release()
|
||||||
|
{
|
||||||
|
if (::InterlockedDecrement(&m_cRefs) == 0)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return m_cRefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
STDMETHODIMP CFnDocFeed::DocFeed()
|
||||||
{
|
{
|
||||||
TLS *pTLS = TLS::GetTLS();
|
TLS *pTLS = TLS::GetTLS();
|
||||||
if (!pTLS || !pTLS->m_pProfile)
|
if (!pTLS)
|
||||||
return FALSE;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
LANGID LangID;
|
HIMC hIMC = GetActiveContext();
|
||||||
pTLS->m_pProfile->GetLangId(&LangID);
|
CicIMCLock imcLock(hIMC);
|
||||||
|
if (FAILED(imcLock.m_hr))
|
||||||
|
return imcLock.m_hr;
|
||||||
|
|
||||||
switch (PRIMARYLANGID(LangID))
|
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
|
||||||
{
|
if (FAILED(imeContext.m_hr))
|
||||||
case LANG_CHINESE:
|
return imeContext.m_hr;
|
||||||
case LANG_JAPANESE:
|
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
||||||
case LANG_KOREAN:
|
if (!pCicIC)
|
||||||
return TRUE;
|
return E_FAIL;
|
||||||
|
|
||||||
default:
|
UINT uCodePage = CP_ACP;
|
||||||
return FALSE;
|
pTLS->m_pProfile->GetCodePageA(&uCodePage);
|
||||||
}
|
pCicIC->SetupDocFeedString(imcLock, uCodePage);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
STDMETHODIMP CFnDocFeed::ClearDocFeedBuffer()
|
||||||
|
{
|
||||||
|
if (!TLS::GetTLS())
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
HIMC hIMC = GetActiveContext();
|
||||||
|
CicIMCLock imcLock(hIMC);
|
||||||
|
if (FAILED(imcLock.m_hr))
|
||||||
|
return imcLock.m_hr;
|
||||||
|
|
||||||
|
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
|
||||||
|
if (FAILED(imeContext.m_hr))
|
||||||
|
return imeContext.m_hr;
|
||||||
|
|
||||||
|
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
||||||
|
if (!pCicIC)
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
pCicIC->EscbClearDocFeedBuffer(imcLock, TRUE);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @unimplemented
|
||||||
|
STDMETHODIMP CFnDocFeed::StartReconvert()
|
||||||
|
{
|
||||||
|
TLS *pTLS = TLS::GetTLS();
|
||||||
|
if (!pTLS)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
auto *pThreadMgr = pTLS->m_pThreadMgr;
|
||||||
|
if (!pThreadMgr)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
HIMC hIMC = GetActiveContext();
|
||||||
|
CicIMCLock imcLock(hIMC);
|
||||||
|
if (FAILED(imcLock.m_hr))
|
||||||
|
return imcLock.m_hr;
|
||||||
|
|
||||||
|
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
|
||||||
|
if (FAILED(imeContext.m_hr))
|
||||||
|
return imeContext.m_hr;
|
||||||
|
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
||||||
|
if (!pCicIC)
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
UINT uCodePage = CP_ACP;
|
||||||
|
pTLS->m_pProfile->GetCodePageA(&uCodePage);
|
||||||
|
|
||||||
|
pCicIC->m_bReconverting = TRUE;
|
||||||
|
pCicIC->SetupReconvertString(imcLock, pThreadMgr, uCodePage, 0, 0);
|
||||||
|
pCicIC->EndReconvertString(imcLock);
|
||||||
|
pCicIC->m_bReconverting = FALSE;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
STDMETHODIMP CFnDocFeed::StartUndoCompositionString()
|
||||||
|
{
|
||||||
|
TLS *pTLS = TLS::GetTLS();
|
||||||
|
if (!pTLS)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
auto *pThreadMgr = pTLS->m_pThreadMgr;
|
||||||
|
if (!pThreadMgr)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
HIMC hIMC = GetActiveContext();
|
||||||
|
CicIMCLock imcLock(hIMC);
|
||||||
|
if (FAILED(imcLock.m_hr))
|
||||||
|
return imcLock.m_hr;
|
||||||
|
|
||||||
|
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
|
||||||
|
if (FAILED(imeContext.m_hr))
|
||||||
|
return imeContext.m_hr;
|
||||||
|
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
||||||
|
if (!pCicIC)
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
UINT uCodePage = CP_ACP;
|
||||||
|
pTLS->m_pProfile->GetCodePageA(&uCodePage);
|
||||||
|
|
||||||
|
pCicIC->SetupReconvertString(imcLock, pThreadMgr, uCodePage, 0, TRUE);
|
||||||
|
pCicIC->EndReconvertString(imcLock);
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,17 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
BOOLEAN DllShutdownInProgress(VOID);
|
||||||
|
BOOL IsEALang(LANGID LangID);
|
||||||
|
BOOL IsInteractiveUserLogon(VOID);
|
||||||
|
BYTE GetCharsetFromLangId(_In_ DWORD dwValue);
|
||||||
|
HIMC GetActiveContext(VOID);
|
||||||
|
ITfCategoryMgr *GetUIMCat(PCIC_LIBTHREAD pLibThread);
|
||||||
|
HRESULT InitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread);
|
||||||
|
HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread);
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
GetCompartment(
|
GetCompartment(
|
||||||
IUnknown *pUnknown,
|
IUnknown *pUnknown,
|
||||||
|
@ -59,4 +70,59 @@ public:
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
BOOL IsEALang(VOID);
|
class CFunctionProviderBase : public ITfFunctionProvider
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
TfClientId m_clientId;
|
||||||
|
GUID m_guid;
|
||||||
|
BSTR m_bstr;
|
||||||
|
LONG m_cRefs;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CFunctionProviderBase(_In_ TfClientId clientId);
|
||||||
|
virtual ~CFunctionProviderBase();
|
||||||
|
|
||||||
|
// IUnknown interface
|
||||||
|
STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override;
|
||||||
|
STDMETHODIMP_(ULONG) AddRef() override;
|
||||||
|
STDMETHODIMP_(ULONG) Release() override;
|
||||||
|
|
||||||
|
// ITfFunctionProvider interface
|
||||||
|
STDMETHODIMP GetType(_Out_ GUID *guid) override;
|
||||||
|
STDMETHODIMP GetDescription(_Out_ BSTR *desc) override;
|
||||||
|
//STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) = 0;
|
||||||
|
|
||||||
|
BOOL Init(_In_ REFGUID rguid, _In_ LPCWSTR psz);
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
class CFunctionProvider : public CFunctionProviderBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CFunctionProvider(_In_ TfClientId clientId);
|
||||||
|
|
||||||
|
STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
class CFnDocFeed : public IAImmFnDocFeed
|
||||||
|
{
|
||||||
|
LONG m_cRefs;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CFnDocFeed();
|
||||||
|
virtual ~CFnDocFeed();
|
||||||
|
|
||||||
|
// IUnknown interface
|
||||||
|
STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override;
|
||||||
|
STDMETHODIMP_(ULONG) AddRef() override;
|
||||||
|
STDMETHODIMP_(ULONG) Release() override;
|
||||||
|
|
||||||
|
// IAImmFnDocFeed interface
|
||||||
|
STDMETHODIMP DocFeed() override;
|
||||||
|
STDMETHODIMP ClearDocFeedBuffer() override;
|
||||||
|
STDMETHODIMP StartReconvert() override;
|
||||||
|
STDMETHODIMP StartUndoCompositionString() override;
|
||||||
|
};
|
||||||
|
|
|
@ -6,12 +6,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "msctfime.h"
|
#include "msctfime.h"
|
||||||
#include <ndk/ldrfuncs.h> /* for RtlDllShutdownInProgress */
|
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(msctfime);
|
WINE_DEFAULT_DEBUG_CHANNEL(msctfime);
|
||||||
|
|
||||||
typedef CicArray<GUID> CDispAttrPropCache;
|
|
||||||
|
|
||||||
HINSTANCE g_hInst = NULL; /* The instance of this module */
|
HINSTANCE g_hInst = NULL; /* The instance of this module */
|
||||||
BOOL g_bWinLogon = FALSE;
|
BOOL g_bWinLogon = FALSE;
|
||||||
UINT g_uACP = CP_ACP;
|
UINT g_uACP = CP_ACP;
|
||||||
|
@ -25,148 +22,6 @@ EXTERN_C void __cxa_pure_virtual(void)
|
||||||
ERR("__cxa_pure_virtual\n");
|
ERR("__cxa_pure_virtual\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef BOOLEAN (WINAPI *FN_DllShutdownInProgress)(VOID);
|
|
||||||
|
|
||||||
/// This function calls ntdll!RtlDllShutdownInProgress.
|
|
||||||
/// It can detect the system is shutting down or not.
|
|
||||||
/// @implemented
|
|
||||||
EXTERN_C BOOLEAN WINAPI DllShutdownInProgress(VOID)
|
|
||||||
{
|
|
||||||
HMODULE hNTDLL;
|
|
||||||
static FN_DllShutdownInProgress s_fnDllShutdownInProgress = NULL;
|
|
||||||
|
|
||||||
if (s_fnDllShutdownInProgress)
|
|
||||||
return s_fnDllShutdownInProgress();
|
|
||||||
|
|
||||||
hNTDLL = cicGetSystemModuleHandle(L"ntdll.dll", FALSE);
|
|
||||||
s_fnDllShutdownInProgress =
|
|
||||||
(FN_DllShutdownInProgress)GetProcAddress(hNTDLL, "RtlDllShutdownInProgress");
|
|
||||||
if (!s_fnDllShutdownInProgress)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return s_fnDllShutdownInProgress();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This function checks if the current user logon session is interactive.
|
|
||||||
/// @implemented
|
|
||||||
static BOOL
|
|
||||||
IsInteractiveUserLogon(VOID)
|
|
||||||
{
|
|
||||||
BOOL bOK, IsMember = FALSE;
|
|
||||||
PSID pSid;
|
|
||||||
SID_IDENTIFIER_AUTHORITY IdentAuth = { SECURITY_NT_AUTHORITY };
|
|
||||||
|
|
||||||
if (!AllocateAndInitializeSid(&IdentAuth, 1, SECURITY_INTERACTIVE_RID,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, &pSid))
|
|
||||||
{
|
|
||||||
ERR("Error: %ld\n", GetLastError());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bOK = CheckTokenMembership(NULL, pSid, &IsMember);
|
|
||||||
|
|
||||||
if (pSid)
|
|
||||||
FreeSid(pSid);
|
|
||||||
|
|
||||||
return bOK && IsMember;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
ITfCategoryMgr *GetUIMCat(PCIC_LIBTHREAD pLibThread)
|
|
||||||
{
|
|
||||||
if (!pLibThread)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (pLibThread->m_pCategoryMgr)
|
|
||||||
return pLibThread->m_pCategoryMgr;
|
|
||||||
|
|
||||||
if (FAILED(cicCoCreateInstance(CLSID_TF_CategoryMgr, NULL, CLSCTX_INPROC_SERVER,
|
|
||||||
IID_ITfCategoryMgr, (void **)&pLibThread->m_pCategoryMgr)))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return pLibThread->m_pCategoryMgr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
HRESULT LibEnumItemsInCategory(PCIC_LIBTHREAD pLibThread, REFGUID rguid, IEnumGUID **ppEnum)
|
|
||||||
{
|
|
||||||
ITfCategoryMgr *pCat = GetUIMCat(pLibThread);
|
|
||||||
if (!pCat)
|
|
||||||
return E_FAIL;
|
|
||||||
return pCat->EnumItemsInCategory(rguid, ppEnum);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
HRESULT InitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread)
|
|
||||||
{
|
|
||||||
if (!pLibThread)
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
if (pLibThread->m_pDisplayAttrMgr)
|
|
||||||
{
|
|
||||||
pLibThread->m_pDisplayAttrMgr->Release();
|
|
||||||
pLibThread->m_pDisplayAttrMgr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(cicCoCreateInstance(CLSID_TF_DisplayAttributeMgr, NULL, CLSCTX_INPROC_SERVER,
|
|
||||||
IID_ITfDisplayAttributeMgr,
|
|
||||||
(void **)&pLibThread->m_pDisplayAttrMgr)))
|
|
||||||
{
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumGUID *pEnumGuid;
|
|
||||||
LibEnumItemsInCategory(pLibThread, GUID_TFCAT_DISPLAYATTRIBUTEPROPERTY, &pEnumGuid);
|
|
||||||
|
|
||||||
HRESULT hr = E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
::EnterCriticalSection(&g_csLock);
|
|
||||||
if (pEnumGuid && !g_pPropCache)
|
|
||||||
{
|
|
||||||
g_pPropCache = new(cicNoThrow) CDispAttrPropCache();
|
|
||||||
if (g_pPropCache)
|
|
||||||
{
|
|
||||||
g_pPropCache->Add(GUID_PROP_ATTRIBUTE);
|
|
||||||
GUID guid;
|
|
||||||
while (pEnumGuid->Next(1, &guid, NULL) == S_OK)
|
|
||||||
{
|
|
||||||
if (!IsEqualGUID(guid, GUID_PROP_ATTRIBUTE))
|
|
||||||
g_pPropCache->Add(guid);
|
|
||||||
}
|
|
||||||
hr = S_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
::LeaveCriticalSection(&g_csLock);
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @implemented
|
|
||||||
HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread)
|
|
||||||
{
|
|
||||||
if (!pLibThread)
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
if (pLibThread->m_pDisplayAttrMgr)
|
|
||||||
{
|
|
||||||
pLibThread->m_pDisplayAttrMgr->Release();
|
|
||||||
pLibThread->m_pDisplayAttrMgr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the charset from a language ID.
|
|
||||||
/// @implemented
|
|
||||||
BYTE GetCharsetFromLangId(_In_ DWORD dwValue)
|
|
||||||
{
|
|
||||||
CHARSETINFO info;
|
|
||||||
if (!::TranslateCharsetInfo((DWORD*)(DWORD_PTR)dwValue, &info, TCI_SRCLOCALE))
|
|
||||||
return 0;
|
|
||||||
return info.ciCharset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Selects or unselects the input context.
|
/// Selects or unselects the input context.
|
||||||
/// @implemented
|
/// @implemented
|
||||||
HRESULT
|
HRESULT
|
||||||
|
@ -236,8 +91,6 @@ InternalSelectEx(
|
||||||
return imcLock.m_hr;
|
return imcLock.m_hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLS;
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* ImeInquire (MSCTFIME.@)
|
* ImeInquire (MSCTFIME.@)
|
||||||
*
|
*
|
||||||
|
@ -245,6 +98,7 @@ class TLS;
|
||||||
*
|
*
|
||||||
* @implemented
|
* @implemented
|
||||||
* @see CtfImeInquireExW
|
* @see CtfImeInquireExW
|
||||||
|
* @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeInquire.html
|
||||||
*/
|
*/
|
||||||
EXTERN_C
|
EXTERN_C
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
|
@ -264,6 +118,7 @@ ImeInquire(
|
||||||
*
|
*
|
||||||
* @implemented
|
* @implemented
|
||||||
* @see ImmGetConversionListW
|
* @see ImmGetConversionListW
|
||||||
|
* @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeConversionList.html
|
||||||
*/
|
*/
|
||||||
EXTERN_C DWORD WINAPI
|
EXTERN_C DWORD WINAPI
|
||||||
ImeConversionList(
|
ImeConversionList(
|
||||||
|
@ -284,6 +139,7 @@ ImeConversionList(
|
||||||
*
|
*
|
||||||
* @implemented
|
* @implemented
|
||||||
* @see ImeUnregisterWord
|
* @see ImeUnregisterWord
|
||||||
|
* @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeRegisterWord.html
|
||||||
*/
|
*/
|
||||||
EXTERN_C BOOL WINAPI
|
EXTERN_C BOOL WINAPI
|
||||||
ImeRegisterWord(
|
ImeRegisterWord(
|
||||||
|
@ -302,6 +158,7 @@ ImeRegisterWord(
|
||||||
*
|
*
|
||||||
* @implemented
|
* @implemented
|
||||||
* @see ImeRegisterWord
|
* @see ImeRegisterWord
|
||||||
|
* @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeUnregisterWord.html
|
||||||
*/
|
*/
|
||||||
EXTERN_C BOOL WINAPI
|
EXTERN_C BOOL WINAPI
|
||||||
ImeUnregisterWord(
|
ImeUnregisterWord(
|
||||||
|
@ -320,6 +177,7 @@ ImeUnregisterWord(
|
||||||
*
|
*
|
||||||
* @implemented
|
* @implemented
|
||||||
* @see ImeRegisterWord
|
* @see ImeRegisterWord
|
||||||
|
* @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeGetRegisterWordStyle.html
|
||||||
*/
|
*/
|
||||||
EXTERN_C UINT WINAPI
|
EXTERN_C UINT WINAPI
|
||||||
ImeGetRegisterWordStyle(
|
ImeGetRegisterWordStyle(
|
||||||
|
@ -337,6 +195,7 @@ ImeGetRegisterWordStyle(
|
||||||
*
|
*
|
||||||
* @implemented
|
* @implemented
|
||||||
* @see ImeRegisterWord
|
* @see ImeRegisterWord
|
||||||
|
* @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeEnumRegisterWord.html
|
||||||
*/
|
*/
|
||||||
EXTERN_C UINT WINAPI
|
EXTERN_C UINT WINAPI
|
||||||
ImeEnumRegisterWord(
|
ImeEnumRegisterWord(
|
||||||
|
@ -351,6 +210,12 @@ ImeEnumRegisterWord(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* ImeConfigure (MSCTFIME.@)
|
||||||
|
*
|
||||||
|
* @implemented
|
||||||
|
* @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeConfigure.html
|
||||||
|
*/
|
||||||
EXTERN_C BOOL WINAPI
|
EXTERN_C BOOL WINAPI
|
||||||
ImeConfigure(
|
ImeConfigure(
|
||||||
_In_ HKL hKL,
|
_In_ HKL hKL,
|
||||||
|
@ -380,6 +245,7 @@ ImeConfigure(
|
||||||
* ImeDestroy (MSCTFIME.@)
|
* ImeDestroy (MSCTFIME.@)
|
||||||
*
|
*
|
||||||
* @implemented
|
* @implemented
|
||||||
|
* @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeDestroy.html
|
||||||
*/
|
*/
|
||||||
EXTERN_C BOOL WINAPI
|
EXTERN_C BOOL WINAPI
|
||||||
ImeDestroy(
|
ImeDestroy(
|
||||||
|
@ -410,6 +276,7 @@ ImeDestroy(
|
||||||
*
|
*
|
||||||
* @implemented
|
* @implemented
|
||||||
* @see CtfImeEscapeEx
|
* @see CtfImeEscapeEx
|
||||||
|
* @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeEscape.html
|
||||||
*/
|
*/
|
||||||
EXTERN_C LRESULT WINAPI
|
EXTERN_C LRESULT WINAPI
|
||||||
ImeEscape(
|
ImeEscape(
|
||||||
|
@ -439,6 +306,7 @@ ImeProcessKey(
|
||||||
*
|
*
|
||||||
* @implemented
|
* @implemented
|
||||||
* @see CtfImeSelectEx
|
* @see CtfImeSelectEx
|
||||||
|
* @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeSelect.html
|
||||||
*/
|
*/
|
||||||
EXTERN_C BOOL WINAPI
|
EXTERN_C BOOL WINAPI
|
||||||
ImeSelect(
|
ImeSelect(
|
||||||
|
@ -456,6 +324,7 @@ ImeSelect(
|
||||||
*
|
*
|
||||||
* @implemented
|
* @implemented
|
||||||
* @see CtfImeSetActiveContextAlways
|
* @see CtfImeSetActiveContextAlways
|
||||||
|
* @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeSetActiveContext.html
|
||||||
*/
|
*/
|
||||||
EXTERN_C BOOL WINAPI
|
EXTERN_C BOOL WINAPI
|
||||||
ImeSetActiveContext(
|
ImeSetActiveContext(
|
||||||
|
@ -480,6 +349,12 @@ ImeToAsciiEx(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* NotifyIME (MSCTFIME.@)
|
||||||
|
*
|
||||||
|
* @implemented
|
||||||
|
* @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/NotifyIME.html
|
||||||
|
*/
|
||||||
EXTERN_C BOOL WINAPI
|
EXTERN_C BOOL WINAPI
|
||||||
NotifyIME(
|
NotifyIME(
|
||||||
_In_ HIMC hIMC,
|
_In_ HIMC hIMC,
|
||||||
|
@ -487,8 +362,19 @@ NotifyIME(
|
||||||
_In_ DWORD dwIndex,
|
_In_ DWORD dwIndex,
|
||||||
_In_ DWORD_PTR dwValue)
|
_In_ DWORD_PTR dwValue)
|
||||||
{
|
{
|
||||||
FIXME("stub:(%p, 0x%lX, 0x%lX, %p)\n", hIMC, dwAction, dwIndex, dwValue);
|
TRACE("(%p, 0x%lX, 0x%lX, %p)\n", hIMC, dwAction, dwIndex, dwValue);
|
||||||
return FALSE;
|
|
||||||
|
TLS *pTLS = TLS::GetTLS();
|
||||||
|
if (!pTLS)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
auto pBridge = pTLS->m_pBridge;
|
||||||
|
auto pThreadMgr = pTLS->m_pThreadMgr;
|
||||||
|
if (!pBridge || !pThreadMgr)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
HRESULT hr = pBridge->Notify(pTLS, pThreadMgr, hIMC, dwAction, dwIndex, dwValue);
|
||||||
|
return (hr == S_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C BOOL WINAPI
|
EXTERN_C BOOL WINAPI
|
||||||
|
@ -704,11 +590,22 @@ CtfImeDestroyThreadMgr(VOID)
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* CtfImeCreateInputContext (MSCTFIME.@)
|
||||||
|
*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
EXTERN_C HRESULT WINAPI
|
EXTERN_C HRESULT WINAPI
|
||||||
CtfImeCreateInputContext(
|
CtfImeCreateInputContext(
|
||||||
_In_ HIMC hIMC)
|
_In_ HIMC hIMC)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
TRACE("(%p)\n", hIMC);
|
||||||
|
|
||||||
|
TLS *pTLS = TLS::GetTLS();
|
||||||
|
if (!pTLS || !pTLS->m_pBridge)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
return pTLS->m_pBridge->CreateInputContext(pTLS, hIMC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -729,6 +626,11 @@ CtfImeDestroyInputContext(
|
||||||
return pTLS->m_pBridge->DestroyInputContext(pTLS, hIMC);
|
return pTLS->m_pBridge->DestroyInputContext(pTLS, hIMC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* CtfImeSetActiveContextAlways (MSCTFIME.@)
|
||||||
|
*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
EXTERN_C HRESULT WINAPI
|
EXTERN_C HRESULT WINAPI
|
||||||
CtfImeSetActiveContextAlways(
|
CtfImeSetActiveContextAlways(
|
||||||
_In_ HIMC hIMC,
|
_In_ HIMC hIMC,
|
||||||
|
@ -736,10 +638,13 @@ CtfImeSetActiveContextAlways(
|
||||||
_In_ HWND hWnd,
|
_In_ HWND hWnd,
|
||||||
_In_ HKL hKL)
|
_In_ HKL hKL)
|
||||||
{
|
{
|
||||||
FIXME("stub:(%p, %d, %p, %p)\n", hIMC, fActive, hWnd, hKL);
|
TRACE("(%p, %d, %p, %p)\n", hIMC, fActive, hWnd, hKL);
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
TLS *pTLS = TLS::GetTLS();
|
||||||
|
if (!pTLS || !pTLS->m_pBridge)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
return pTLS->m_pBridge->SetActiveContextAlways(pTLS, hIMC, fActive, hWnd, hKL);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* CtfImeProcessCicHotkey (MSCTFIME.@)
|
* CtfImeProcessCicHotkey (MSCTFIME.@)
|
||||||
|
|
|
@ -35,18 +35,10 @@
|
||||||
|
|
||||||
#include <wine/debug.h>
|
#include <wine/debug.h>
|
||||||
|
|
||||||
EXTERN_C BOOLEAN WINAPI DllShutdownInProgress(VOID);
|
extern CRITICAL_SECTION g_csLock;
|
||||||
|
|
||||||
HRESULT InitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread);
|
typedef CicArray<GUID> CDispAttrPropCache;
|
||||||
HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread);
|
extern CDispAttrPropCache *g_pPropCache;
|
||||||
|
|
||||||
static inline HIMC GetActiveContext(VOID)
|
|
||||||
{
|
|
||||||
HWND hwndFocus = ::GetFocus();
|
|
||||||
if (!hwndFocus)
|
|
||||||
hwndFocus = ::GetActiveWindow();
|
|
||||||
return ::ImmGetContext(hwndFocus);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_GUID(GUID_COMPARTMENT_CTFIME_DIMFLAGS, 0xA94C5FD2, 0xC471, 0x4031, 0x95, 0x46, 0x70, 0x9C, 0x17, 0x30, 0x0C, 0xB9);
|
DEFINE_GUID(GUID_COMPARTMENT_CTFIME_DIMFLAGS, 0xA94C5FD2, 0xC471, 0x4031, 0x95, 0x46, 0x70, 0x9C, 0x17, 0x30, 0x0C, 0xB9);
|
||||||
DEFINE_GUID(GUID_COMPARTMENT_CTFIME_CICINPUTCONTEXT, 0x85A688F7, 0x6DC8, 0x4F17, 0xA8, 0x3A, 0xB1, 0x1C, 0x09, 0xCD, 0xD7, 0xBF);
|
DEFINE_GUID(GUID_COMPARTMENT_CTFIME_CICINPUTCONTEXT, 0x85A688F7, 0x6DC8, 0x4F17, 0xA8, 0x3A, 0xB1, 0x1C, 0x09, 0xCD, 0xD7, 0xBF);
|
||||||
|
@ -55,13 +47,11 @@ DEFINE_GUID(GUID_MODEBIAS_NUMERIC, 0x4021766C, 0xE872, 0x48FD,
|
||||||
DEFINE_GUID(GUID_MODEBIAS_URLHISTORY, 0x8B0E54D9, 0x63F2, 0x4C68, 0x84, 0xD4, 0x79, 0xAE, 0xE7, 0xA5, 0x9F, 0x09);
|
DEFINE_GUID(GUID_MODEBIAS_URLHISTORY, 0x8B0E54D9, 0x63F2, 0x4C68, 0x84, 0xD4, 0x79, 0xAE, 0xE7, 0xA5, 0x9F, 0x09);
|
||||||
DEFINE_GUID(GUID_MODEBIAS_DEFAULT, 0xF3DA8BD4, 0x0786, 0x49C2, 0x8C, 0x09, 0x68, 0x39, 0xD8, 0xB8, 0x4F, 0x58);
|
DEFINE_GUID(GUID_MODEBIAS_DEFAULT, 0xF3DA8BD4, 0x0786, 0x49C2, 0x8C, 0x09, 0x68, 0x39, 0xD8, 0xB8, 0x4F, 0x58);
|
||||||
DEFINE_GUID(GUID_PROP_MODEBIAS, 0x372E0716, 0x974F, 0x40AC, 0xA0, 0x88, 0x08, 0xCD, 0xC9, 0x2E, 0xBF, 0xBC);
|
DEFINE_GUID(GUID_PROP_MODEBIAS, 0x372E0716, 0x974F, 0x40AC, 0xA0, 0x88, 0x08, 0xCD, 0xC9, 0x2E, 0xBF, 0xBC);
|
||||||
|
|
||||||
#define GUID_MODEBIAS_NONE GUID_NULL
|
#define GUID_MODEBIAS_NONE GUID_NULL
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
#include "bridge.h"
|
#include "bridge.h"
|
||||||
#include "functions.h"
|
|
||||||
#include "inputcontext.h"
|
#include "inputcontext.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "profile.h"
|
#include "profile.h"
|
||||||
|
|
|
@ -11,6 +11,38 @@ WINE_DEFAULT_DEBUG_CHANNEL(msctfime);
|
||||||
|
|
||||||
DWORD TLS::s_dwTlsIndex = (DWORD)-1;
|
DWORD TLS::s_dwTlsIndex = (DWORD)-1;
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
BOOL TLS::Initialize()
|
||||||
|
{
|
||||||
|
s_dwTlsIndex = ::TlsAlloc();
|
||||||
|
return s_dwTlsIndex != (DWORD)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
VOID TLS::Uninitialize()
|
||||||
|
{
|
||||||
|
if (s_dwTlsIndex != (DWORD)-1)
|
||||||
|
{
|
||||||
|
::TlsFree(s_dwTlsIndex);
|
||||||
|
s_dwTlsIndex = (DWORD)-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
TLS* TLS::GetTLS()
|
||||||
|
{
|
||||||
|
if (s_dwTlsIndex == (DWORD)-1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return InternalAllocateTLS();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @implemented
|
||||||
|
TLS* TLS::PeekTLS()
|
||||||
|
{
|
||||||
|
return (TLS*)::TlsGetValue(TLS::s_dwTlsIndex);
|
||||||
|
}
|
||||||
|
|
||||||
/// @implemented
|
/// @implemented
|
||||||
TLS* TLS::InternalAllocateTLS()
|
TLS* TLS::InternalAllocateTLS()
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class TLS;
|
|
||||||
|
|
||||||
class CicBridge;
|
class CicBridge;
|
||||||
class CicProfile;
|
class CicProfile;
|
||||||
|
|
||||||
|
@ -29,45 +27,11 @@ public:
|
||||||
DWORD m_NonEAComposition;
|
DWORD m_NonEAComposition;
|
||||||
DWORD m_cWnds;
|
DWORD m_cWnds;
|
||||||
|
|
||||||
/**
|
static BOOL Initialize();
|
||||||
* @implemented
|
static VOID Uninitialize();
|
||||||
*/
|
|
||||||
static BOOL Initialize()
|
|
||||||
{
|
|
||||||
s_dwTlsIndex = ::TlsAlloc();
|
|
||||||
return s_dwTlsIndex != (DWORD)-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
static TLS* GetTLS();
|
||||||
* @implemented
|
static TLS* PeekTLS();
|
||||||
*/
|
|
||||||
static VOID Uninitialize()
|
|
||||||
{
|
|
||||||
if (s_dwTlsIndex != (DWORD)-1)
|
|
||||||
{
|
|
||||||
::TlsFree(s_dwTlsIndex);
|
|
||||||
s_dwTlsIndex = (DWORD)-1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
static TLS* GetTLS()
|
|
||||||
{
|
|
||||||
if (s_dwTlsIndex == (DWORD)-1)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return InternalAllocateTLS();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
static TLS* PeekTLS()
|
|
||||||
{
|
|
||||||
return (TLS*)::TlsGetValue(TLS::s_dwTlsIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static TLS* InternalAllocateTLS();
|
static TLS* InternalAllocateTLS();
|
||||||
static BOOL InternalDestroyTLS();
|
static BOOL InternalDestroyTLS();
|
||||||
|
|
|
@ -529,7 +529,7 @@ HRESULT UIComposition::CreateCompButtonWnd(HWND hwndParent, HIMC hIMC)
|
||||||
if (!pTLS || !pTLS->NonEACompositionEnabled())
|
if (!pTLS || !pTLS->NonEACompositionEnabled())
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
if (IsEALang())
|
if (IsEALang(0))
|
||||||
{
|
{
|
||||||
if (m_pCompButtonFrameWindow)
|
if (m_pCompButtonFrameWindow)
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,8 +44,6 @@ public:
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
class CCompFrameWindow;
|
|
||||||
|
|
||||||
class CCompFinalizeButton : public CUIFToolbarButton
|
class CCompFinalizeButton : public CUIFToolbarButton
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue