Leaked source code of windows server 2003
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.

338 lines
7.6 KiB

  1. //
  2. // ics.cpp
  3. //
  4. #include "private.h"
  5. #include "tim.h"
  6. #include "dim.h"
  7. #include "ic.h"
  8. #include "emptyic.h"
  9. #include "acp2anch.h"
  10. #include "enumic.h"
  11. //+---------------------------------------------------------------------------
  12. //
  13. // GetTop
  14. //
  15. //----------------------------------------------------------------------------
  16. STDAPI CDocumentInputManager::GetTop(ITfContext **ppic)
  17. {
  18. return _GetContext(_iStack, ppic);
  19. }
  20. //+---------------------------------------------------------------------------
  21. //
  22. // GetBase
  23. //
  24. //----------------------------------------------------------------------------
  25. STDAPI CDocumentInputManager::GetBase(ITfContext **ppic)
  26. {
  27. return _GetContext(0, ppic);
  28. }
  29. //+---------------------------------------------------------------------------
  30. //
  31. // _GetContext
  32. //
  33. //----------------------------------------------------------------------------
  34. HRESULT CDocumentInputManager::_GetContext(int iStack, ITfContext **ppic)
  35. {
  36. if (ppic == NULL)
  37. return E_INVALIDARG;
  38. *ppic = NULL;
  39. if (_iStack == -1)
  40. {
  41. Assert(iStack == 0 || iStack == -1); // caller should be GetBottom or internal using _iStack...
  42. if (!_peic)
  43. {
  44. _peic = new CEmptyInputContext(this);
  45. if (_peic == NULL)
  46. return E_OUTOFMEMORY;
  47. if (FAILED(_peic->Init()))
  48. {
  49. SafeReleaseClear(_peic);
  50. return E_FAIL;
  51. }
  52. }
  53. *ppic = _peic;
  54. }
  55. else
  56. {
  57. Assert(iStack >= 0 && iStack <= _iStack);
  58. *ppic = _Stack[iStack];
  59. }
  60. Assert(*ppic);
  61. (*ppic)->AddRef();
  62. return S_OK;
  63. }
  64. //+---------------------------------------------------------------------------
  65. //
  66. // CreateContext
  67. //
  68. //----------------------------------------------------------------------------
  69. // this is a constant we removed before cicero ship, but office10 still uses it
  70. // it can be ignored, but it must be accepted as legal
  71. #define TF_PLAINTEXTTSI 0x1
  72. STDAPI CDocumentInputManager::CreateContext(TfClientId tid, DWORD dwFlags, IUnknown *punk, ITfContext **ppic, TfEditCookie *pecTextStore)
  73. {
  74. CInputContext *pic;
  75. ITextStoreAnchor *ptsi;
  76. ITextStoreACP *ptsiACP;
  77. CThreadInputMgr *tim;
  78. ITfContextOwnerCompositionSink *pOwnerComposeSink;
  79. HRESULT hr;
  80. if (pecTextStore != NULL)
  81. {
  82. *pecTextStore = TF_INVALID_EDIT_COOKIE;
  83. }
  84. if (ppic != NULL)
  85. {
  86. *ppic = NULL;
  87. }
  88. if (ppic == NULL || pecTextStore == NULL)
  89. return E_INVALIDARG;
  90. if (dwFlags & ~TF_PLAINTEXTTSI)
  91. return E_INVALIDARG;
  92. if ((tim = CThreadInputMgr::_GetThis()) == NULL)
  93. return E_FAIL;
  94. if (!tim->_IsValidTfClientId(tid))
  95. return E_INVALIDARG;
  96. ptsi = NULL;
  97. pOwnerComposeSink = NULL;
  98. if (punk != NULL)
  99. {
  100. if (g_fNoITextStoreAnchor ||
  101. punk->QueryInterface(IID_ITextStoreAnchor, (void **)&ptsi) != S_OK ||
  102. ptsi == NULL)
  103. {
  104. if (punk->QueryInterface(IID_ITextStoreACP, (void **)&ptsiACP) != S_OK || ptsiACP == NULL)
  105. {
  106. ptsiACP = NULL;
  107. }
  108. else
  109. {
  110. ptsi = new CACPWrap(ptsiACP);
  111. ptsiACP->Release();
  112. if (ptsi == NULL)
  113. return E_OUTOFMEMORY;
  114. }
  115. }
  116. if (punk->QueryInterface(IID_ITfContextOwnerCompositionSink, (void **)&pOwnerComposeSink) != S_OK)
  117. {
  118. pOwnerComposeSink = NULL;
  119. }
  120. }
  121. if ((pic = new CInputContext(tid)) == NULL)
  122. {
  123. hr = E_OUTOFMEMORY;
  124. goto Exit;
  125. }
  126. if (pic->_Init(tim, this, ptsi, pOwnerComposeSink) != S_OK)
  127. {
  128. pic->Release();
  129. hr = E_FAIL;
  130. goto Exit;
  131. }
  132. *ppic = pic;
  133. if (ptsi != NULL)
  134. {
  135. // caller is doing the ITextStore, so return a back door ec
  136. *pecTextStore = BACKDOOR_EDIT_COOKIE;
  137. }
  138. hr = S_OK;
  139. Exit:
  140. SafeRelease(ptsi);
  141. SafeRelease(pOwnerComposeSink);
  142. return hr;
  143. }
  144. //+---------------------------------------------------------------------------
  145. //
  146. // Push
  147. //
  148. //----------------------------------------------------------------------------
  149. STDAPI CDocumentInputManager::Push(ITfContext *pic)
  150. {
  151. CInputContext *pcic;
  152. if (pic == NULL)
  153. return E_INVALIDARG;
  154. if (_iStack == ICS_STACK_SIZE - 1)
  155. return TF_E_STACKFULL;
  156. pcic = GetCInputContext(pic);
  157. if (!pcic)
  158. return E_INVALIDARG;
  159. if (_fPoppingStack)
  160. return E_UNEXPECTED;
  161. // we don't need AddRef here, GetCInputContext did AddRef().
  162. _Stack[++_iStack] = pcic;
  163. pcic->_AdviseSinks();
  164. // if it's the first push, we call a notification.
  165. if (_iStack == 0)
  166. {
  167. CThreadInputMgr *tim;
  168. if ((tim = CThreadInputMgr::_GetThis()) == NULL)
  169. return E_FAIL;
  170. tim->_NotifyCallbacks(TIM_INITDIM, this, NULL);
  171. }
  172. pcic->_Pushed();
  173. return S_OK;
  174. }
  175. //+---------------------------------------------------------------------------
  176. //
  177. // Pop
  178. //
  179. //----------------------------------------------------------------------------
  180. STDAPI CDocumentInputManager::Pop(DWORD dwFlags)
  181. {
  182. CThreadInputMgr *tim;
  183. if (dwFlags & ~TF_POPF_ALL)
  184. return E_INVALIDARG;
  185. if (_iStack == -1)
  186. return E_FAIL;
  187. if (_fPoppingStack)
  188. return E_UNEXPECTED;
  189. if ((tim = CThreadInputMgr::_GetThis()) == NULL)
  190. return E_FAIL;
  191. if (!(dwFlags & TF_POPF_ALL))
  192. {
  193. if (!_iStack)
  194. return E_FAIL;
  195. _Pop(tim);
  196. }
  197. else
  198. {
  199. while(_iStack >= 0)
  200. {
  201. _Pop(tim);
  202. }
  203. // clear the focus if this guy has it
  204. if (tim->_GetFocusDocInputMgr() == this)
  205. {
  206. tim->_SetFocus(NULL, TRUE);
  207. }
  208. tim->_NotifyCallbacks(TIM_UNINITDIM, this, NULL);
  209. }
  210. return S_OK;
  211. }
  212. //+---------------------------------------------------------------------------
  213. //
  214. // _Pop
  215. //
  216. //----------------------------------------------------------------------------
  217. BOOL CDocumentInputManager::_Pop(CThreadInputMgr *tim)
  218. {
  219. CInputContext *pic;
  220. Assert(_iStack >= 0);
  221. pic = _Stack[_iStack];
  222. // don't let anyone mess with the stack while we adjust it
  223. _fPoppingStack = TRUE;
  224. // call _Popped() to release properties and compartments.
  225. // must do this before _UnadviseSinks while the ITextStore
  226. // has not yet been released
  227. pic->_Popped();
  228. pic->_UnadviseSinks(tim);
  229. pic->Release();
  230. _fPoppingStack = FALSE;
  231. _iStack--;
  232. return TRUE;
  233. }
  234. //+---------------------------------------------------------------------------
  235. //
  236. // EnumInputContexts
  237. //
  238. //----------------------------------------------------------------------------
  239. STDAPI CDocumentInputManager::EnumContexts(IEnumTfContexts **ppEnum)
  240. {
  241. CEnumInputContexts *pEnum;
  242. pEnum = new CEnumInputContexts();
  243. if (!pEnum)
  244. return E_OUTOFMEMORY;
  245. if (!pEnum->_Init(this))
  246. {
  247. pEnum->Release();
  248. return E_FAIL;
  249. }
  250. *ppEnum = pEnum;
  251. return S_OK;
  252. }
  253. //+---------------------------------------------------------------------------
  254. //
  255. // _GetTopIC
  256. //
  257. //----------------------------------------------------------------------------
  258. CInputContext *CDocumentInputManager::_GetTopIC()
  259. {
  260. if (_iStack == -1)
  261. return NULL;
  262. return _Stack[_iStack];
  263. }