Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502/* * PROJECT: ReactOS msctfime.ime * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) * PURPOSE: Input Context of msctfime.ime * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> */
#include "msctfime.h"
WINE_DEFAULT_DEBUG_CHANNEL(msctfime);
/*********************************************************************** * CInputContextOwner */
/// @unimplementedCInputContextOwner::CInputContextOwner(FN_IC_OWNER_CALLBACK fnCallback, LPVOID pCallbackPV){ m_dwCookie = -1; m_fnCallback = fnCallback; m_cRefs = 1; m_pCallbackPV = pCallbackPV;}
/// @implementedCInputContextOwner::~CInputContextOwner(){}
/// @implementedHRESULT CInputContextOwner::_Advise(IUnknown *pContext){ ITfSource *pSource = NULL;
m_pContext = NULL;
HRESULT hr = E_FAIL; if (SUCCEEDED(m_pContext->QueryInterface(IID_ITfSource, (LPVOID*)&pSource)) && SUCCEEDED(pSource->AdviseSink(IID_ITfContextOwner, static_cast<ITfContextOwner*>(this), &m_dwCookie))) { m_pContext = pContext; m_pContext->AddRef(); hr = S_OK; }
if (pSource) pSource->Release();
return hr;}
/// @implementedHRESULT CInputContextOwner::_Unadvise(){ ITfSource *pSource = NULL;
HRESULT hr = E_FAIL; if (m_pContext) { if (SUCCEEDED(m_pContext->QueryInterface(IID_ITfSource, (LPVOID*)&pSource)) && SUCCEEDED(pSource->UnadviseSink(m_dwCookie))) { hr = S_OK; } }
if (m_pContext) { m_pContext->Release(); m_pContext = NULL; }
if (pSource) pSource->Release();
return hr;}
/// @implementedSTDMETHODIMP CInputContextOwner::QueryInterface(REFIID riid, LPVOID* ppvObj){ static const QITAB c_tab[] = { QITABENT(CInputContextOwner, ITfContextOwner), QITABENT(CInputContextOwner, ITfMouseTrackerACP), { NULL } }; return ::QISearch(this, c_tab, riid, ppvObj);}
/// @implementedSTDMETHODIMP_(ULONG) CInputContextOwner::AddRef(){ return ++m_cRefs;}
/// @implementedSTDMETHODIMP_(ULONG) CInputContextOwner::Release(){ if (--m_cRefs == 0) { delete this; return 0; } return m_cRefs;}
/// @unimplementedSTDMETHODIMPCInputContextOwner::GetACPFromPoint( const POINT *ptScreen, DWORD dwFlags, LONG *pacp){ return E_NOTIMPL;}
/// @unimplementedSTDMETHODIMPCInputContextOwner::GetTextExt( LONG acpStart, LONG acpEnd, RECT *prc, BOOL *pfClipped){ return E_NOTIMPL;}
/// @implementedSTDMETHODIMP CInputContextOwner::GetScreenExt(RECT *prc){ return m_fnCallback(2, &prc, m_pCallbackPV);}
/// @implementedSTDMETHODIMP CInputContextOwner::GetStatus(TF_STATUS *pdcs){ return m_fnCallback(6, &pdcs, m_pCallbackPV);}
/// @unimplementedSTDMETHODIMP CInputContextOwner::GetWnd(HWND *phwnd){ return m_fnCallback(7, &phwnd, m_pCallbackPV);}
/// @unimplementedSTDMETHODIMP CInputContextOwner::GetAttribute(REFGUID rguidAttribute, VARIANT *pvarValue){ return E_NOTIMPL;}
struct MOUSE_SINK_ARGS{ ITfRangeACP *range; ITfMouseSink *pSink; DWORD *pdwCookie;};
/// @implementedSTDMETHODIMP CInputContextOwner::AdviseMouseSink( ITfRangeACP *range, ITfMouseSink *pSink, DWORD *pdwCookie){ MOUSE_SINK_ARGS args = { range, pSink, pdwCookie }; return m_fnCallback(9, &args, m_pCallbackPV);}
/// @implementedSTDMETHODIMP CInputContextOwner::UnadviseMouseSink(DWORD dwCookie){ return m_fnCallback(10, &dwCookie, m_pCallbackPV);}
/*********************************************************************** * CicInputContext */
/// @unimplementedCicInputContext::CicInputContext( _In_ TfClientId cliendId, _Inout_ PCIC_LIBTHREAD pLibThread, _In_ HIMC hIMC){ m_hIMC = hIMC; m_dwQueryPos = 0; m_cRefs = 1;}
/// @implementedSTDMETHODIMP CicInputContext::QueryInterface(REFIID riid, LPVOID* ppvObj){ static const QITAB c_tab[] = { QITABENT(CicInputContext, ITfCleanupContextSink), QITABENT(CicInputContext, ITfContextOwnerCompositionSink), { NULL } }; return ::QISearch(this, c_tab, riid, ppvObj);}
/// @implementedSTDMETHODIMP_(ULONG) CicInputContext::AddRef(){ return ::InterlockedIncrement(&m_cRefs);}
/// @implementedSTDMETHODIMP_(ULONG) CicInputContext::Release(){ if (::InterlockedDecrement(&m_cRefs) == 0) { delete this; return 0; } return m_cRefs;}
/// @implementedSTDMETHODIMPCicInputContext::OnStartComposition( ITfCompositionView *pComposition, BOOL *pfOk){ if ((m_cCompLocks <= 0) || m_bReconverting) { *pfOk = TRUE; ++m_cCompLocks; } else { *pfOk = FALSE; } return S_OK;}
/// @implementedSTDMETHODIMPCicInputContext::OnUpdateComposition( ITfCompositionView *pComposition, ITfRange *pRangeNew){ return S_OK;}
/// @implementedSTDMETHODIMPCicInputContext::OnEndComposition( ITfCompositionView *pComposition){ --m_cCompLocks; return S_OK;}
/// @implementedHRESULTCicInputContext::GetGuidAtom( _Inout_ CicIMCLock& imcLock, _In_ BYTE iAtom, _Out_opt_ LPDWORD pdwGuidAtom){ CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCompStr); if (FAILED(imeContext.m_hr)) return imeContext.m_hr;
HRESULT hr = E_FAIL; if (iAtom < m_cGuidAtoms) { *pdwGuidAtom = m_adwGuidAtoms[iAtom]; hr = S_OK; }
return hr;}
/// @unimplementedHRESULTCicInputContext::CreateInputContext( _Inout_ ITfThreadMgr *pThreadMgr, _Inout_ CicIMCLock& imcLock){ //FIXME return E_NOTIMPL;}
/// @unimplementedHRESULTCicInputContext::DestroyInputContext(){ ITfSourceSingle *pSource = NULL;
if (m_pContext && m_pContext->QueryInterface(IID_ITfSourceSingle, (void **)&pSource) == S_OK) pSource->UnadviseSingleSink(m_clientId, IID_ITfCleanupContextSink);
//FIXME: m_dwUnknown5
if (m_pTextEventSink) { m_pTextEventSink->_Unadvise(); m_pTextEventSink->Release(); m_pTextEventSink = NULL; }
if (m_pCompEventSink2) { m_pCompEventSink2->_Unadvise(); m_pCompEventSink2->Release(); m_pCompEventSink2 = NULL; }
if (m_pCompEventSink1) { m_pCompEventSink1->_Unadvise(); m_pCompEventSink1->Release(); m_pCompEventSink1 = NULL; }
if (m_pInputContextOwner) { m_pInputContextOwner->_Unadvise(); m_pInputContextOwner->Release(); m_pInputContextOwner = NULL; }
if (m_pDocumentMgr) m_pDocumentMgr->Pop(1);
if (m_pContext) { ClearCompartment(m_clientId, m_pContext, GUID_COMPARTMENT_CTFIME_CICINPUTCONTEXT, 0); m_pContext->Release(); m_pContext = NULL; }
if (m_pContextOwnerServices) { m_pContextOwnerServices->Release(); m_pContextOwnerServices = NULL; }
// FIXME: m_pICOwnerCallback
if (m_pDocumentMgr) { m_pDocumentMgr->Release(); m_pDocumentMgr = NULL; }
if (pSource) pSource->Release();
return S_OK;}
/// @implementedSTDMETHODIMPCicInputContext::OnCompositionTerminated(TfEditCookie ecWrite, ITfComposition *pComposition){ return S_OK;}
/// @implementedSTDMETHODIMPCicInputContext::OnCleanupContext( _In_ TfEditCookie ecWrite, _Inout_ ITfContext *pic){ TLS *pTLS = TLS::PeekTLS(); if (!pTLS || !pTLS->m_pProfile) return E_OUTOFMEMORY;
LANGID LangID; pTLS->m_pProfile->GetLangId(&LangID);
IMEINFO IMEInfo; WCHAR szPath[MAX_PATH]; if (Inquire(&IMEInfo, szPath, 0, (HKL)UlongToHandle(LangID)) != S_OK) return E_FAIL;
ITfProperty *pProp = NULL; if (!(IMEInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT)) return S_OK;
HRESULT hr = pic->GetProperty(GUID_PROP_COMPOSING, &pProp); if (FAILED(hr)) return S_OK;
IEnumTfRanges *pRanges = NULL; hr = pProp->EnumRanges(ecWrite, &pRanges, NULL); if (SUCCEEDED(hr)) { ITfRange *pRange = NULL; while (pRanges->Next(1, &pRange, 0) == S_OK) { VARIANT vari; V_VT(&vari) = VT_EMPTY; pProp->GetValue(ecWrite, pRange, &vari); if (V_VT(&vari) == VT_I4) { if (V_I4(&vari)) pProp->Clear(ecWrite, pRange); } pRange->Release(); pRange = NULL; } pRanges->Release(); } pProp->Release();
return S_OK;}
/// @unimplementedHRESULT CicInputContext::SetupDocFeedString(CicIMCLock& imcLock, UINT uCodePage){ return E_NOTIMPL;}
/// @unimplementedHRESULT CicInputContext::EscbClearDocFeedBuffer(CicIMCLock& imcLock, BOOL bFlag){ return E_NOTIMPL;}
/// @unimplementedHRESULT CicInputContext::EscbCompComplete(CicIMCLock& imcLock){ return E_NOTIMPL;}
/// @unimplementedHRESULT CicInputContext::EscbCompCancel(CicIMCLock& imcLock){ return E_NOTIMPL;}
/// @unimplementedHRESULT CicInputContext::OnSetCandidatePos(TLS *pTLS, CicIMCLock& imcLock){ return E_NOTIMPL;}
/// @unimplementedHRESULT CicInputContext::DelayedReconvertFuncCall(CicIMCLock& imcLock){ return E_NOTIMPL;}
/// @unimplementedHRESULTCicInputContext::MsImeMouseHandler( DWORD dwUnknown58, DWORD dwUnknown59, UINT keys, CicIMCLock& imcLock){ return E_NOTIMPL;}
/// @unimplementedHRESULTCicInputContext::SetupReconvertString( CicIMCLock& imcLock, ITfThreadMgr_P *pThreadMgr, UINT uCodePage, UINT uMsg, BOOL bUndo){ return E_NOTIMPL;}
void CicInputContext::ClearPrevCandidatePos(){ m_dwUnknown8 = 0; ZeroMemory(&m_rcCandidate1, sizeof(m_rcCandidate1)); ZeroMemory(&m_CandForm, sizeof(m_CandForm)); ZeroMemory(&m_rcCandidate2, sizeof(m_rcCandidate2)); m_dwQueryPos = 0;}
/// @unimplementedHRESULT CicInputContext::EndReconvertString(CicIMCLock& imcLock){ return E_NOTIMPL;}
/// @unimplementedBOOL CicInputContext::SetCompositionString( CicIMCLock& imcLock, ITfThreadMgr_P *pThreadMgr, DWORD dwIndex, LPCVOID lpComp, DWORD dwCompLen, LPCVOID lpRead, DWORD dwReadLen, UINT uCodePage){ return FALSE;}