|
|
//
// ics.cpp
//
#include "private.h"
#include "tim.h"
#include "dim.h"
#include "ic.h"
#include "emptyic.h"
#include "acp2anch.h"
#include "enumic.h"
//+---------------------------------------------------------------------------
//
// GetTop
//
//----------------------------------------------------------------------------
STDAPI CDocumentInputManager::GetTop(ITfContext **ppic) { return _GetContext(_iStack, ppic); }
//+---------------------------------------------------------------------------
//
// GetBase
//
//----------------------------------------------------------------------------
STDAPI CDocumentInputManager::GetBase(ITfContext **ppic) { return _GetContext(0, ppic); }
//+---------------------------------------------------------------------------
//
// _GetContext
//
//----------------------------------------------------------------------------
HRESULT CDocumentInputManager::_GetContext(int iStack, ITfContext **ppic) { if (ppic == NULL) return E_INVALIDARG;
*ppic = NULL;
if (_iStack == -1) { Assert(iStack == 0 || iStack == -1); // caller should be GetBottom or internal using _iStack...
if (!_peic) { _peic = new CEmptyInputContext(this);
if (_peic == NULL) return E_OUTOFMEMORY;
if (FAILED(_peic->Init())) { SafeReleaseClear(_peic); return E_FAIL; } }
*ppic = _peic; } else { Assert(iStack >= 0 && iStack <= _iStack); *ppic = _Stack[iStack]; } Assert(*ppic); (*ppic)->AddRef();
return S_OK; }
//+---------------------------------------------------------------------------
//
// CreateContext
//
//----------------------------------------------------------------------------
// this is a constant we removed before cicero ship, but office10 still uses it
// it can be ignored, but it must be accepted as legal
#define TF_PLAINTEXTTSI 0x1
STDAPI CDocumentInputManager::CreateContext(TfClientId tid, DWORD dwFlags, IUnknown *punk, ITfContext **ppic, TfEditCookie *pecTextStore) { CInputContext *pic; ITextStoreAnchor *ptsi; ITextStoreACP *ptsiACP; CThreadInputMgr *tim; ITfContextOwnerCompositionSink *pOwnerComposeSink; HRESULT hr;
if (pecTextStore != NULL) { *pecTextStore = TF_INVALID_EDIT_COOKIE; } if (ppic != NULL) { *ppic = NULL; }
if (ppic == NULL || pecTextStore == NULL) return E_INVALIDARG;
if (dwFlags & ~TF_PLAINTEXTTSI) return E_INVALIDARG;
if ((tim = CThreadInputMgr::_GetThis()) == NULL) return E_FAIL;
if (!tim->_IsValidTfClientId(tid)) return E_INVALIDARG;
ptsi = NULL; pOwnerComposeSink = NULL;
if (punk != NULL) { if (g_fNoITextStoreAnchor || punk->QueryInterface(IID_ITextStoreAnchor, (void **)&ptsi) != S_OK || ptsi == NULL) { if (punk->QueryInterface(IID_ITextStoreACP, (void **)&ptsiACP) != S_OK || ptsiACP == NULL) { ptsiACP = NULL; } else { ptsi = new CACPWrap(ptsiACP); ptsiACP->Release();
if (ptsi == NULL) return E_OUTOFMEMORY; } }
if (punk->QueryInterface(IID_ITfContextOwnerCompositionSink, (void **)&pOwnerComposeSink) != S_OK) { pOwnerComposeSink = NULL; } }
if ((pic = new CInputContext(tid)) == NULL) { hr = E_OUTOFMEMORY; goto Exit; }
if (pic->_Init(tim, this, ptsi, pOwnerComposeSink) != S_OK) { pic->Release(); hr = E_FAIL; goto Exit; }
*ppic = pic;
if (ptsi != NULL) { // caller is doing the ITextStore, so return a back door ec
*pecTextStore = BACKDOOR_EDIT_COOKIE; }
hr = S_OK;
Exit: SafeRelease(ptsi); SafeRelease(pOwnerComposeSink);
return hr; }
//+---------------------------------------------------------------------------
//
// Push
//
//----------------------------------------------------------------------------
STDAPI CDocumentInputManager::Push(ITfContext *pic) { CInputContext *pcic;
if (pic == NULL) return E_INVALIDARG;
if (_iStack == ICS_STACK_SIZE - 1) return TF_E_STACKFULL;
pcic = GetCInputContext(pic); if (!pcic) return E_INVALIDARG; if (_fPoppingStack) return E_UNEXPECTED;
// we don't need AddRef here, GetCInputContext did AddRef().
_Stack[++_iStack] = pcic;
pcic->_AdviseSinks();
// if it's the first push, we call a notification.
if (_iStack == 0) { CThreadInputMgr *tim; if ((tim = CThreadInputMgr::_GetThis()) == NULL) return E_FAIL;
tim->_NotifyCallbacks(TIM_INITDIM, this, NULL); }
pcic->_Pushed();
return S_OK; }
//+---------------------------------------------------------------------------
//
// Pop
//
//----------------------------------------------------------------------------
STDAPI CDocumentInputManager::Pop(DWORD dwFlags) { CThreadInputMgr *tim; if (dwFlags & ~TF_POPF_ALL) return E_INVALIDARG;
if (_iStack == -1) return E_FAIL;
if (_fPoppingStack) return E_UNEXPECTED;
if ((tim = CThreadInputMgr::_GetThis()) == NULL) return E_FAIL;
if (!(dwFlags & TF_POPF_ALL)) { if (!_iStack) return E_FAIL;
_Pop(tim); } else { while(_iStack >= 0) { _Pop(tim); }
// clear the focus if this guy has it
if (tim->_GetFocusDocInputMgr() == this) { tim->_SetFocus(NULL, TRUE); }
tim->_NotifyCallbacks(TIM_UNINITDIM, this, NULL); }
return S_OK; }
//+---------------------------------------------------------------------------
//
// _Pop
//
//----------------------------------------------------------------------------
BOOL CDocumentInputManager::_Pop(CThreadInputMgr *tim) { CInputContext *pic;
Assert(_iStack >= 0);
pic = _Stack[_iStack];
// don't let anyone mess with the stack while we adjust it
_fPoppingStack = TRUE;
// call _Popped() to release properties and compartments.
// must do this before _UnadviseSinks while the ITextStore
// has not yet been released
pic->_Popped();
pic->_UnadviseSinks(tim); pic->Release();
_fPoppingStack = FALSE;
_iStack--;
return TRUE; }
//+---------------------------------------------------------------------------
//
// EnumInputContexts
//
//----------------------------------------------------------------------------
STDAPI CDocumentInputManager::EnumContexts(IEnumTfContexts **ppEnum) { CEnumInputContexts *pEnum;
pEnum = new CEnumInputContexts(); if (!pEnum) return E_OUTOFMEMORY;
if (!pEnum->_Init(this)) { pEnum->Release(); return E_FAIL; }
*ppEnum = pEnum;
return S_OK; }
//+---------------------------------------------------------------------------
//
// _GetTopIC
//
//----------------------------------------------------------------------------
CInputContext *CDocumentInputManager::_GetTopIC() { if (_iStack == -1) return NULL;
return _Stack[_iStack]; }
|