Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527/* * PROJECT: ReactOS msctfime.ime * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) * PURPOSE: The sinks of msctfime.ime * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> */
#include "msctfime.h"
WINE_DEFAULT_DEBUG_CHANNEL(msctfime);
/// @implementedCCompartmentEventSink::CCompartmentEventSink(FN_EVENTSINK fnEventSink, LPVOID pUserData) : m_array() , m_cRefs(1) , m_fnEventSink(fnEventSink) , m_pUserData(pUserData){}
/// @implementedCCompartmentEventSink::~CCompartmentEventSink(){}
/// @implementedSTDMETHODIMP CCompartmentEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj){ static const QITAB c_tab[] = { QITABENT(CCompartmentEventSink, ITfCompartmentEventSink), { NULL } }; return ::QISearch(this, c_tab, riid, ppvObj);}
/// @implementedSTDMETHODIMP_(ULONG) CCompartmentEventSink::AddRef(){ return ::InterlockedIncrement(&m_cRefs);}
/// @implementedSTDMETHODIMP_(ULONG) CCompartmentEventSink::Release(){ if (::InterlockedDecrement(&m_cRefs) == 0) { delete this; return 0; } return m_cRefs;}
/// @implementedSTDMETHODIMP CCompartmentEventSink::OnChange(REFGUID rguid){ return m_fnEventSink(m_pUserData, rguid);}
/// @implementedHRESULTCCompartmentEventSink::_Advise(IUnknown *pUnknown, REFGUID rguid, BOOL bThread){ CESMAP *pCesMap = m_array.Append(1); if (!pCesMap) return E_OUTOFMEMORY;
ITfSource *pSource = NULL;
HRESULT hr = GetCompartment(pUnknown, rguid, &pCesMap->m_pComp, bThread); if (FAILED(hr)) { hr = pCesMap->m_pComp->QueryInterface(IID_ITfSource, (void **)&pSource); if (FAILED(hr)) { hr = pSource->AdviseSink(IID_ITfCompartmentEventSink, this, &pCesMap->m_dwCookie); if (FAILED(hr)) { if (pCesMap->m_pComp) { pCesMap->m_pComp->Release(); pCesMap->m_pComp = NULL; } m_array.Remove(m_array.size() - 1, 1); } else { hr = S_OK; } } }
if (pSource) pSource->Release();
return hr;}
/// @implementedHRESULT CCompartmentEventSink::_Unadvise(){ CESMAP *pCesMap = m_array.data(); size_t cItems = m_array.size(); if (!cItems) return S_OK;
do { ITfSource *pSource = NULL; HRESULT hr = pCesMap->m_pComp->QueryInterface(IID_ITfSource, (void **)&pSource); if (SUCCEEDED(hr)) pSource->UnadviseSink(pCesMap->m_dwCookie);
if (pCesMap->m_pComp) { pCesMap->m_pComp->Release(); pCesMap->m_pComp = NULL; }
if (pSource) pSource->Release();
++pCesMap; --cItems; } while (cItems);
return S_OK;}
/***********************************************************************/
/// @implementedCTextEventSink::CTextEventSink(FN_ENDEDIT fnEndEdit, LPVOID pCallbackPV){ m_cRefs = 1; m_pUnknown = NULL; m_dwEditSinkCookie = (DWORD)-1; m_dwLayoutSinkCookie = (DWORD)-1; m_fnLayoutChange = NULL; m_fnEndEdit = fnEndEdit; m_pCallbackPV = pCallbackPV;}
/// @implementedCTextEventSink::~CTextEventSink(){}
/// @implementedSTDMETHODIMP CTextEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj){ static const QITAB c_tab[] = { QITABENT(CTextEventSink, ITfTextEditSink), QITABENT(CTextEventSink, ITfTextLayoutSink), { NULL } }; return ::QISearch(this, c_tab, riid, ppvObj);}
/// @implementedSTDMETHODIMP_(ULONG) CTextEventSink::AddRef(){ return ::InterlockedIncrement(&m_cRefs);}
/// @implementedSTDMETHODIMP_(ULONG) CTextEventSink::Release(){ if (::InterlockedDecrement(&m_cRefs) == 0) { delete this; return 0; } return m_cRefs;}
struct TEXT_EVENT_SINK_END_EDIT{ TfEditCookie m_ecReadOnly; ITfEditRecord *m_pEditRecord; ITfContext *m_pContext;};
/// @implementedSTDMETHODIMP CTextEventSink::OnEndEdit( ITfContext *pic, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord){ TEXT_EVENT_SINK_END_EDIT Data = { ecReadOnly, pEditRecord, pic }; return m_fnEndEdit(1, m_pCallbackPV, (LPVOID)&Data);}
/// @implementedSTDMETHODIMP CTextEventSink::OnLayoutChange( ITfContext *pContext, TfLayoutCode lcode, ITfContextView *pContextView){ switch (lcode) { case TF_LC_CREATE: return m_fnLayoutChange(3, m_fnEndEdit, pContextView); case TF_LC_CHANGE: return m_fnLayoutChange(2, m_fnEndEdit, pContextView); case TF_LC_DESTROY: return m_fnLayoutChange(4, m_fnEndEdit, pContextView); default: return E_INVALIDARG; }}
/// @implementedHRESULT CTextEventSink::_Advise(IUnknown *pUnknown, UINT uFlags){ m_pUnknown = NULL; m_uFlags = uFlags;
ITfSource *pSource = NULL; HRESULT hr = pUnknown->QueryInterface(IID_ITfSource, (void**)&pSource); if (SUCCEEDED(hr)) { ITfTextEditSink *pSink = static_cast<ITfTextEditSink*>(this); if (uFlags & 1) hr = pSource->AdviseSink(IID_ITfTextEditSink, pSink, &m_dwEditSinkCookie); if (SUCCEEDED(hr) && (uFlags & 2)) hr = pSource->AdviseSink(IID_ITfTextLayoutSink, pSink, &m_dwLayoutSinkCookie);
if (SUCCEEDED(hr)) { m_pUnknown = pUnknown; pUnknown->AddRef(); } else { pSource->UnadviseSink(m_dwEditSinkCookie); } }
if (pSource) pSource->Release();
return hr;}
/// @implementedHRESULT CTextEventSink::_Unadvise(){ if (!m_pUnknown) return E_FAIL;
ITfSource *pSource = NULL; HRESULT hr = m_pUnknown->QueryInterface(IID_ITfSource, (void**)&pSource); if (SUCCEEDED(hr)) { if (m_uFlags & 1) hr = pSource->UnadviseSink(m_dwEditSinkCookie); if (m_uFlags & 2) hr = pSource->UnadviseSink(m_dwLayoutSinkCookie);
pSource->Release(); }
m_pUnknown->Release(); m_pUnknown = NULL;
return E_NOTIMPL;}
/***********************************************************************/
/// @implementedCThreadMgrEventSink::CThreadMgrEventSink( _In_ FN_INITDOCMGR fnInit, _In_ FN_PUSHPOP fnPushPop, _Inout_ LPVOID pvCallbackPV){ m_fnInit = fnInit; m_fnPushPop = fnPushPop; m_pCallbackPV = pvCallbackPV; m_cRefs = 1;}
/// @implementedSTDMETHODIMP CThreadMgrEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj){ static const QITAB c_tab[] = { QITABENT(CThreadMgrEventSink, ITfThreadMgrEventSink), { NULL } }; return ::QISearch(this, c_tab, riid, ppvObj);}
/// @implementedSTDMETHODIMP_(ULONG) CThreadMgrEventSink::AddRef(){ return ::InterlockedIncrement(&m_cRefs);}
/// @implementedSTDMETHODIMP_(ULONG) CThreadMgrEventSink::Release(){ if (::InterlockedDecrement(&m_cRefs) == 0) { delete this; return 0; } return m_cRefs;}
INT CALLBACKCThreadMgrEventSink::DIMCallback( UINT nCode, ITfDocumentMgr *pDocMgr1, ITfDocumentMgr *pDocMgr2, LPVOID pUserData){ return E_NOTIMPL;}
STDMETHODIMP CThreadMgrEventSink::OnInitDocumentMgr(ITfDocumentMgr *pdim){ if (!m_fnInit) return S_OK; return m_fnInit(0, pdim, NULL, m_pCallbackPV);}
STDMETHODIMP CThreadMgrEventSink::OnUninitDocumentMgr(ITfDocumentMgr *pdim){ if (!m_fnInit) return S_OK; return m_fnInit(1, pdim, NULL, m_pCallbackPV);}
STDMETHODIMPCThreadMgrEventSink::OnSetFocus(ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus){ if (!m_fnInit) return S_OK; return m_fnInit(2, pdimFocus, pdimPrevFocus, m_pCallbackPV);}
STDMETHODIMP CThreadMgrEventSink::OnPushContext(ITfContext *pic){ if (!m_fnPushPop) return S_OK; return m_fnPushPop(3, pic, m_pCallbackPV);}
STDMETHODIMP CThreadMgrEventSink::OnPopContext(ITfContext *pic){ if (!m_fnPushPop) return S_OK; return m_fnPushPop(4, pic, m_pCallbackPV);}
void CThreadMgrEventSink::SetCallbackPV(_Inout_ LPVOID pv){ if (!m_pCallbackPV) m_pCallbackPV = pv;}
HRESULT CThreadMgrEventSink::_Advise(ITfThreadMgr *pThreadMgr){ m_pThreadMgr = NULL;
HRESULT hr = E_FAIL; ITfSource *pSource = NULL; if (pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK && pSource->AdviseSink(IID_ITfThreadMgrEventSink, this, &m_dwCookie) == S_OK) { m_pThreadMgr = pThreadMgr; pThreadMgr->AddRef(); hr = S_OK; }
if (pSource) pSource->Release();
return hr;}
HRESULT CThreadMgrEventSink::_Unadvise(){ HRESULT hr = E_FAIL; ITfSource *pSource = NULL;
if (m_pThreadMgr) { if (m_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK && pSource->UnadviseSink(m_dwCookie) == S_OK) { hr = S_OK; }
if (pSource) pSource->Release(); }
if (m_pThreadMgr) { m_pThreadMgr->Release(); m_pThreadMgr = NULL; }
return hr;}
/***********************************************************************/
/// @implementedCActiveLanguageProfileNotifySink::CActiveLanguageProfileNotifySink( _In_ FN_COMPARE fnCompare, _Inout_opt_ void *pUserData){ m_dwConnection = (DWORD)-1; m_fnCompare = fnCompare; m_cRefs = 1; m_pUserData = pUserData;}
/// @implementedCActiveLanguageProfileNotifySink::~CActiveLanguageProfileNotifySink(){}
/// @implementedSTDMETHODIMP CActiveLanguageProfileNotifySink::QueryInterface(REFIID riid, LPVOID* ppvObj){ static const QITAB c_tab[] = { QITABENT(CActiveLanguageProfileNotifySink, ITfActiveLanguageProfileNotifySink), { NULL } }; return ::QISearch(this, c_tab, riid, ppvObj);}
/// @implementedSTDMETHODIMP_(ULONG) CActiveLanguageProfileNotifySink::AddRef(){ return ::InterlockedIncrement(&m_cRefs);}
/// @implementedSTDMETHODIMP_(ULONG) CActiveLanguageProfileNotifySink::Release(){ if (::InterlockedDecrement(&m_cRefs) == 0) { delete this; return 0; } return m_cRefs;}
/// @implementedSTDMETHODIMPCActiveLanguageProfileNotifySink::OnActivated( REFCLSID clsid, REFGUID guidProfile, BOOL fActivated){ if (!m_fnCompare) return 0;
return m_fnCompare(clsid, guidProfile, fActivated, m_pUserData);}
/// @implementedHRESULTCActiveLanguageProfileNotifySink::_Advise( ITfThreadMgr *pThreadMgr){ m_pThreadMgr = NULL;
ITfSource *pSource = NULL; HRESULT hr = pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource); if (FAILED(hr)) return E_FAIL;
hr = pSource->AdviseSink(IID_ITfActiveLanguageProfileNotifySink, this, &m_dwConnection); if (SUCCEEDED(hr)) { m_pThreadMgr = pThreadMgr; pThreadMgr->AddRef(); hr = S_OK; } else { hr = E_FAIL; }
if (pSource) pSource->Release();
return hr;}
/// @implementedHRESULTCActiveLanguageProfileNotifySink::_Unadvise(){ if (!m_pThreadMgr) return E_FAIL;
ITfSource *pSource = NULL; HRESULT hr = m_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource); if (SUCCEEDED(hr)) { hr = pSource->UnadviseSink(m_dwConnection); if (SUCCEEDED(hr)) hr = S_OK; }
if (pSource) pSource->Release();
if (m_pThreadMgr) { m_pThreadMgr->Release(); m_pThreadMgr = NULL; }
return hr;}