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.

655 lines
23 KiB

  1. //
  2. // ic.h
  3. //
  4. #ifndef IC_H
  5. #define IC_H
  6. #include "private.h"
  7. #include "globals.h"
  8. #include "rprop.h"
  9. #include "editrec.h"
  10. #include "strary.h"
  11. #include "compart.h"
  12. #define TF_ES_INEDITSESSION 0x80000000
  13. #define TF_ES_INNOTIFY 0x40000000
  14. #define TF_ES_WRITE (TF_ES_READWRITE & ~TF_ES_READ)
  15. #define TF_ES_PROPERTY_WRITE (TF_ES_READ_PROPERTY_WRITE & ~TF_ES_READ)
  16. #define TF_ES_ALL_ACCESS_BITS (TF_ES_READWRITE | TF_ES_READ_PROPERTY_WRITE)
  17. #define IC_NUM_CONNECTIONPTS 5
  18. // these are indices into _rgSinks, must match CInputContext::_c_rgConnectionIIDs
  19. #define IC_SINK_ITfTextEditSink 0
  20. #define IC_SINK_ITfTextLayoutSink 1
  21. #define IC_SINK_ITfStatusSink 2
  22. #define IC_SINK_ITfStartReconversionNotifySink 3
  23. #define IC_SINK_ITfEditTransactionSink 4
  24. class CRange;
  25. class CProperty;
  26. class CThreadInputMgr;
  27. class CFunctionProvider;
  28. class CFunction;
  29. class CContextView;
  30. class CComposition;
  31. class CDocumentInputManager;
  32. class CInputContext;
  33. extern const IID IID_PRIV_CINPUTCONTEXT;
  34. #define LEFT_FILTERTIP 0
  35. #define RIGHT_FILTERTIP 1
  36. typedef struct _CLEANUPSINK
  37. {
  38. TfClientId tid;
  39. ITfCleanupContextSink *pSink;
  40. } CLEANUPSINK;
  41. //////////////////////////////////////////////////////////////////////////////
  42. //
  43. // QUEUE_ITEM structures
  44. //
  45. //////////////////////////////////////////////////////////////////////////////
  46. typedef enum { QI_ADDREF, QI_DISPATCH, QI_FREE } QiCallbackCode;
  47. struct _TS_QUEUE_ITEM;
  48. typedef HRESULT (*QI_CALLBACK)(CInputContext *pic, struct _TS_QUEUE_ITEM *pItem, QiCallbackCode qiCode);
  49. typedef struct _EDITSESSION
  50. {
  51. TfClientId tid;
  52. ITfEditSession *pes;
  53. } EDITSESSION;
  54. typedef struct _PSEUDO_EDITSESSION
  55. {
  56. ULONG uCode;
  57. void *pvState;
  58. } PSEUDO_EDITSESSION;
  59. class CAsyncQueueItem;
  60. typedef struct _ASYNCQUEUE_EDITSESSION
  61. {
  62. CAsyncQueueItem *paqi;
  63. } ASYNCQUEUE_EDITSESSION;
  64. typedef struct _TS_QUEUE_ITEM
  65. {
  66. QI_CALLBACK pfnCallback;
  67. DWORD dwFlags; // TF_ES_READWRITE | TF_ES_READ | TF_ES_WRITE | TF_ES_SYNC
  68. union
  69. {
  70. // state for edit sessions
  71. EDITSESSION es;
  72. PSEUDO_EDITSESSION pes;
  73. ASYNCQUEUE_EDITSESSION aqe;
  74. // other state...
  75. } state;
  76. } TS_QUEUE_ITEM;
  77. //
  78. // PSEUDO_EDITSESSION callback codes
  79. //
  80. #define PSEUDO_ESCB_TERMCOMPOSITION 0
  81. #define PSEUDO_ESCB_UPDATEKEYEVENTFILTER 1
  82. #define PSEUDO_ESCB_GROWRANGE 2
  83. #define PSEUDO_ESCB_BUILDOWNERRANGELIST 3
  84. #define PSEUDO_ESCB_SHIFTENDTORANGE 4
  85. #define PSEUDO_ESCB_GETSELECTION 5
  86. #define PSEUDO_ESCB_SERIALIZE_ACP 6
  87. #define PSEUDO_ESCB_SERIALIZE_ANCHOR 7
  88. #define PSEUDO_ESCB_UNSERIALIZE_ACP 8
  89. #define PSEUDO_ESCB_UNSERIALIZE_ANCHOR 9
  90. #define PSEUDO_ESCB_GETWHOLEDOCRANGE 10
  91. typedef struct _SERIALIZE_ANCHOR_PARAMS
  92. {
  93. CProperty *pProp;
  94. CRange *pRange;
  95. TF_PERSISTENT_PROPERTY_HEADER_ANCHOR *pHdr;
  96. IStream *pStream;
  97. } SERIALIZE_ANCHOR_PARAMS;
  98. typedef struct _UNSERIALIZE_ANCHOR_PARAMS
  99. {
  100. CProperty *pProp;
  101. const TF_PERSISTENT_PROPERTY_HEADER_ANCHOR *pHdr;
  102. IStream *pStream;
  103. ITfPersistentPropertyLoaderAnchor *pLoader;
  104. } UNSERIALIZE_ANCHOR_PARAMS;
  105. //////////////////////////////////////////////////////////////////////////////
  106. //
  107. // CAsyncQueueItem
  108. //
  109. //////////////////////////////////////////////////////////////////////////////
  110. class CAsyncQueueItem
  111. {
  112. public:
  113. CAsyncQueueItem(BOOL fSync = FALSE)
  114. {
  115. _item.pfnCallback = _EditSessionQiCallback;
  116. _item.dwFlags = TF_ES_READWRITE | (fSync ? TF_ES_SYNC : 0);
  117. _item.state.aqe.paqi = this;
  118. _cRef = 1;
  119. }
  120. virtual ~CAsyncQueueItem() {};
  121. static HRESULT _EditSessionQiCallback(CInputContext *pic, struct _TS_QUEUE_ITEM *pItem, QiCallbackCode qiCode);
  122. virtual HRESULT DoDispatch(CInputContext *pic) = 0;
  123. void _CheckReadOnly(CInputContext *pic);
  124. TS_QUEUE_ITEM *GetItem()
  125. {
  126. return &_item;
  127. }
  128. LONG _AddRef()
  129. {
  130. _cRef++;
  131. return _cRef;
  132. }
  133. LONG _Release()
  134. {
  135. LONG ret = --_cRef;
  136. if (!_cRef)
  137. delete this;
  138. return ret;
  139. }
  140. private:
  141. LONG _cRef;
  142. TS_QUEUE_ITEM _item;
  143. };
  144. //////////////////////////////////////////////////////////////////////////////
  145. //
  146. // CInputContext
  147. //
  148. //////////////////////////////////////////////////////////////////////////////
  149. class CInputContext : public ITfContext_P,
  150. public ITfQueryEmbedded,
  151. public ITfInsertAtSelection,
  152. public ITfContextOwnerServices,
  153. public ITfContextOwnerCompositionServices,
  154. public ITfSource,
  155. public ITfSourceSingle,
  156. public ITextStoreAnchorSink,
  157. public ITextStoreAnchorServices,
  158. public ITfMouseTracker,
  159. public IServiceProvider,
  160. public ITfContextRenderingMarkup,
  161. public CCompartmentMgr,
  162. public CComObjectRootImmx
  163. {
  164. public:
  165. CInputContext(TfClientId tid);
  166. ~CInputContext();
  167. BEGIN_COM_MAP_IMMX(CInputContext)
  168. COM_INTERFACE_ENTRY_IID(IID_PRIV_CINPUTCONTEXT, CInputContext)
  169. COM_INTERFACE_ENTRY(ITfContext)
  170. COM_INTERFACE_ENTRY(ITfContext_P)
  171. COM_INTERFACE_ENTRY(ITfQueryEmbedded)
  172. COM_INTERFACE_ENTRY(ITfInsertAtSelection)
  173. COM_INTERFACE_ENTRY(ITfContextComposition)
  174. COM_INTERFACE_ENTRY(ITfContextOwnerCompositionServices)
  175. COM_INTERFACE_ENTRY(ITfSource)
  176. COM_INTERFACE_ENTRY(ITfSourceSingle)
  177. COM_INTERFACE_ENTRY(ITextStoreAnchorSink)
  178. COM_INTERFACE_ENTRY(ITextStoreAnchorServices)
  179. COM_INTERFACE_ENTRY(ITfCompartmentMgr)
  180. COM_INTERFACE_ENTRY(ITfContextOwnerServices) // Issue: it would be nice if this was only avail w/ cicero def text store
  181. // COM_INTERFACE_ENTRY_FUNC
  182. COM_INTERFACE_ENTRY(ITfMouseTracker)
  183. COM_INTERFACE_ENTRY(IServiceProvider)
  184. COM_INTERFACE_ENTRY(ITfContextRenderingMarkup)
  185. END_COM_MAP_IMMX()
  186. IMMX_OBJECT_IUNKNOWN_FOR_ATL()
  187. //
  188. // ITfContext
  189. //
  190. STDMETHODIMP RequestEditSession(TfClientId tid, ITfEditSession *pes, DWORD dwFlags, HRESULT *phrSession);
  191. STDMETHODIMP InWriteSession(TfClientId tid, BOOL *pfWriteSession);
  192. STDMETHODIMP GetSelection(TfEditCookie ec, ULONG ulIndex, ULONG ulCount, TF_SELECTION *pSelection, ULONG *pcFetched);
  193. STDMETHODIMP SetSelection(TfEditCookie ec, ULONG ulCount, const TF_SELECTION *pSelection);
  194. STDMETHODIMP GetStart(TfEditCookie ec, ITfRange **ppStart);
  195. STDMETHODIMP GetEnd(TfEditCookie ec, ITfRange **ppEnd);
  196. STDMETHODIMP GetStatus(TS_STATUS *pdcs);
  197. STDMETHODIMP GetActiveView(ITfContextView **ppView);
  198. STDMETHODIMP EnumViews(IEnumTfContextViews **ppEnum);
  199. STDMETHODIMP GetProperty(REFGUID guidProp, ITfProperty **ppv);
  200. STDMETHODIMP GetAppProperty(REFGUID guidProp, ITfReadOnlyProperty **ppProp);
  201. STDMETHODIMP TrackProperties(const GUID **pguidProp, ULONG cProp, const GUID **pguidAppProp, ULONG cAppProp, ITfReadOnlyProperty **ppPropX);
  202. STDMETHODIMP EnumProperties(IEnumTfProperties **ppEnum);
  203. STDMETHODIMP GetDocumentMgr(ITfDocumentMgr **ppDoc);
  204. STDMETHODIMP CreateRangeBackup(TfEditCookie ec, ITfRange *pRange, ITfRangeBackup **ppBackup);
  205. // ITfQueryEmbedded
  206. STDMETHODIMP QueryInsertEmbedded(const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable);
  207. // ITfInsertAtSelection
  208. STDMETHODIMP InsertTextAtSelection(TfEditCookie ec, DWORD dwFlags, const WCHAR *pchText, LONG cch, ITfRange **ppRange);
  209. STDMETHODIMP InsertEmbeddedAtSelection(TfEditCookie ec, DWORD dwFlags, IDataObject *pDataObject, ITfRange **ppRange);
  210. // ITfContextOwnerServices
  211. STDMETHODIMP OnLayoutChange();
  212. //STDMETHODIMP OnStatusChange(); // use ITextStoreAnchorSink::OnStatusChange
  213. STDMETHODIMP OnAttributeChange(REFGUID rguidAttribute);
  214. STDMETHODIMP Serialize(ITfProperty *pProp, ITfRange *pRange, TF_PERSISTENT_PROPERTY_HEADER_ACP *pHdr, IStream *pStream);
  215. STDMETHODIMP Unserialize(ITfProperty *pProp, const TF_PERSISTENT_PROPERTY_HEADER_ACP *pHdr, IStream *pStream, ITfPersistentPropertyLoaderACP *pLoader);
  216. STDMETHODIMP ForceLoadProperty(ITfProperty *pProp);
  217. STDMETHODIMP CreateRange(LONG acpStart, LONG acpEnd, ITfRangeACP **ppRange);
  218. // ITfContextComposition
  219. STDMETHODIMP StartComposition(TfEditCookie ecWrite, ITfRange *pCompositionRange, ITfCompositionSink *pSink, ITfComposition **ppComposition);
  220. STDMETHODIMP EnumCompositions(IEnumITfCompositionView **ppEnum);
  221. STDMETHODIMP FindComposition(TfEditCookie ecRead, ITfRange *pTestRange, IEnumITfCompositionView **ppEnum);
  222. STDMETHODIMP TakeOwnership(TfEditCookie ecWrite, ITfCompositionView *pComposition, ITfCompositionSink *pSink, ITfComposition **ppComposition);
  223. // ITfContextOwnerCompositionServices
  224. STDMETHODIMP TerminateComposition(ITfCompositionView *pComposition);
  225. // ITfSource
  226. STDMETHODIMP AdviseSink(REFIID riid, IUnknown *punk, DWORD *pdwCookie);
  227. STDMETHODIMP UnadviseSink(DWORD dwCookie);
  228. // ITfSourceSingle
  229. STDMETHODIMP AdviseSingleSink(TfClientId tid, REFIID riid, IUnknown *punk);
  230. STDMETHODIMP UnadviseSingleSink(TfClientId tid, REFIID riid);
  231. // ITextStoreAnchorSink
  232. STDMETHODIMP OnTextChange(DWORD dwFlags, IAnchor *paStart, IAnchor *paEnd);
  233. STDMETHODIMP OnSelectionChange();
  234. STDMETHODIMP OnLayoutChange(TsLayoutCode lcode, TsViewCookie vcView);
  235. STDMETHODIMP OnStatusChange(DWORD dwFlags);
  236. STDMETHODIMP OnAttrsChange(IAnchor *paStart, IAnchor *paEnd, ULONG cAttrs, const TS_ATTRID *paAttrs);
  237. STDMETHODIMP OnLockGranted(DWORD dwLockFlags);
  238. STDMETHODIMP OnStartEditTransaction();
  239. STDMETHODIMP OnEndEditTransaction();
  240. // ITextStoreAnchorServices
  241. STDMETHODIMP Serialize(ITfProperty *pProp, ITfRange *pRange, TF_PERSISTENT_PROPERTY_HEADER_ANCHOR *pHdr, IStream *pStream);
  242. STDMETHODIMP Unserialize(ITfProperty *pProp, const TF_PERSISTENT_PROPERTY_HEADER_ANCHOR *pHdr, IStream *pStream, ITfPersistentPropertyLoaderAnchor *pLoader);
  243. STDMETHODIMP CreateRange(IAnchor *paStart, IAnchor *paEnd, ITfRangeAnchor **ppRange);
  244. // ITfMouseTracker
  245. STDMETHODIMP AdviseMouseSink(ITfRange *range, ITfMouseSink *pSink, DWORD *pdwCookie);
  246. STDMETHODIMP UnadviseMouseSink(DWORD dwCookie);
  247. // IServiceProvider
  248. STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppv);
  249. // ITfContextRenderingMarkup
  250. STDMETHODIMP GetRenderingMarkup(TfEditCookie ec, DWORD dwFlags, ITfRange *pRangeCover, IEnumTfRenderingMarkup **ppEnum);
  251. STDMETHODIMP FindNextRenderingMarkup(TfEditCookie ec, DWORD dwFlags, ITfRange *pRangeQuery, TfAnchor tfAnchorQuery,
  252. ITfRange **ppRangeFound, TF_RENDERINGMARKUP *ptfRenderingMarkup);
  253. // ITfContext_P
  254. STDMETHODIMP MapAppProperty(REFGUID guidAppProp, REFGUID guidProp);
  255. STDMETHODIMP EnableLockRequestPosting(BOOL fEnable);
  256. HRESULT _Init(CThreadInputMgr *tim, CDocumentInputManager *dm, ITextStoreAnchor *ptsi, ITfContextOwnerCompositionSink *pOwnerComposeSink);
  257. void _Pushed();
  258. void _Popped();
  259. void _AdviseSinks();
  260. void _UnadviseSinks(CThreadInputMgr *tim);
  261. void _UpdateKeyEventFilter();
  262. HRESULT _UpdateKeyEventFilterCallback(TfEditCookie ec);
  263. HRESULT _GetProperty(REFGUID rguidProp, CProperty **ppv);
  264. BOOL _NotifyEndEdit(void);
  265. CProperty *_FindProperty(REFGUID rguidProp)
  266. {
  267. TfGuidAtom ga;
  268. if (MyRegisterGUID(rguidProp, &ga) != S_OK)
  269. return NULL;
  270. return _FindProperty(ga);
  271. }
  272. CProperty *_FindProperty(TfGuidAtom gaProp);
  273. void _PropertyTextUpdate(DWORD dwFlags, IAnchor *paStart, IAnchor *paEnd);
  274. CProperty *_GetFirstProperty() { return _pPropList; }
  275. CProperty *_pPropList;
  276. BOOL _IsCiceroTSI() { return _fCiceroTSI; }
  277. ITextStoreAnchor *_GetTSI() { return _ptsi; }
  278. ITextStoreAnchor *_GetAATSI() { return _pMSAAState ? _pMSAAState->pAADoc : NULL; }
  279. BOOL _IsInEditSession() { return (_dwEditSessionFlags & TF_ES_INEDITSESSION); }
  280. BOOL _IsConnected() { return _dm ? TRUE : FALSE; }
  281. BOOL _IsValidEditCookie(TfEditCookie ec, DWORD dwFlags)
  282. {
  283. Assert(dwFlags & TF_ES_READ); // minimum access...
  284. if (ec == BACKDOOR_EDIT_COOKIE)
  285. {
  286. Assert(!(dwFlags & (TF_ES_WRITE | TF_ES_PROPERTY_WRITE))); // app is trying to use def ec with write operation
  287. return !(dwFlags & (TF_ES_WRITE | TF_ES_PROPERTY_WRITE)); // app can read anything it wants
  288. }
  289. Assert(_ec != TF_INVALID_EDIT_COOKIE); // must always return FALSE for TF_INVALID_EDIT_COOKIE...
  290. Assert(!(_dwEditSessionFlags & TF_ES_WRITE) || (_dwEditSessionFlags & TF_ES_PROPERTY_WRITE)); // write implies property write
  291. return (ec == _ec &&
  292. (_dwEditSessionFlags & TF_ES_INEDITSESSION) &&
  293. (!(dwFlags & TF_ES_WRITE) || (_dwEditSessionFlags & TF_ES_WRITE))) &&
  294. (!(dwFlags & TF_ES_PROPERTY_WRITE) || (_dwEditSessionFlags & TF_ES_PROPERTY_WRITE));
  295. }
  296. void _IncLastLockReleaseID() { _dwLastLockReleaseID++; /* Issue: handle wrap-around */ }
  297. DWORD _GetLastLockReleaseID() { return _dwLastLockReleaseID; }
  298. CDocumentInputManager *_GetDm() { return _dm; }
  299. CEditRecord *_GetEditRecord() { return _pEditRecord; }
  300. HRESULT _OnTextChangeInternal(DWORD dwFlags, IAnchor *paStart, IAnchor *paEnd, AnchorOwnership ao);
  301. CProperty *GetTextOwnerProperty();
  302. TfClientId _GetClientInEditSession(TfEditCookie ec) { return ec == BACKDOOR_EDIT_COOKIE ? g_gaApp : _tidInEditSession; }
  303. TfClientId _SetRawClientInEditSession(TfClientId tid)
  304. {
  305. TfClientId tidTmp = _tidInEditSession;
  306. _tidInEditSession = tid;
  307. return tidTmp;
  308. }
  309. CStructArray<GENERICSINK> *_GetTextEditSinks() { return &_rgSinks[IC_SINK_ITfTextEditSink]; }
  310. CStructArray<GENERICSINK> *_GetTextLayoutSinks() { return &_rgSinks[IC_SINK_ITfTextLayoutSink]; }
  311. CStructArray<GENERICSINK> *_GetStatusSinks() { return &_rgSinks[IC_SINK_ITfStatusSink]; }
  312. CStructArray<GENERICSINK> *_GetStartReconversionNotifySinks() { return &_rgSinks[IC_SINK_ITfStartReconversionNotifySink]; }
  313. CStructArray<GENERICSINK> *_GetEditTransactionSink() { return &_rgSinks[IC_SINK_ITfEditTransactionSink]; }
  314. CStructArray<CLEANUPSINK> *_GetCleanupSinks() { return &_rgCleanupSinks; }
  315. BOOL _AppSupportsCompositions() { return _pCompositionList != NULL; }
  316. CComposition *_GetCompositionList() { return _pCompositionList; }
  317. CComposition **_GetCompositionListPtr() { return &_pCompositionList; }
  318. ITfContextOwnerCompositionSink *_GetOwnerCompositionSink() { return _pOwnerComposeSink; }
  319. BOOL _DoesAppSupportCompositions() { return _pOwnerComposeSink != NULL; }
  320. BOOL _EnterCompositionOp()
  321. {
  322. return (_fInCompositionOp ? FALSE : (_fInCompositionOp = TRUE));
  323. }
  324. void _LeaveCompositionOp()
  325. {
  326. Assert(_fInCompositionOp);
  327. _fInCompositionOp = FALSE;
  328. }
  329. HRESULT _StartComposition(TfEditCookie ecWrite, IAnchor *paStart, IAnchor *paEnd, ITfCompositionSink *pSink, CComposition **ppComposition);
  330. HRESULT _TerminateCompositionWithLock(ITfCompositionView *pComposition, TfEditCookie ec);
  331. void _AbortCompositions();
  332. static void _PostponeLockRequestCallback(SYSTHREAD *psfn, CInputContext *pic);
  333. HRESULT _DoPseudoSyncEditSession(DWORD dwFlags, ULONG uCode, void *pvState, HRESULT *phrSession)
  334. {
  335. TS_QUEUE_ITEM item;
  336. item.pfnCallback = _PseudoSyncEditSessionQiCallback;
  337. item.dwFlags = dwFlags | TF_ES_SYNC;
  338. item.state.pes.uCode = uCode;
  339. item.state.pes.pvState = pvState;
  340. return _QueueItem(&item, FALSE, phrSession);
  341. }
  342. HRESULT _QueueItem(TS_QUEUE_ITEM *pItem, BOOL fForceAsync, HRESULT *phrSession);
  343. BOOL _ContextNeedsCleanup(const GUID *pCatId, LANGID langid, CStructArray<TfClientId> **pprgClientIds);
  344. void _CleanupContext(CStructArray<TfClientId> *prgClientIds);
  345. HRESULT GetMappedAppProperty(REFGUID guidProp, CProperty **ppProp);
  346. private:
  347. friend CThreadInputMgr;
  348. friend CRange;
  349. friend CProperty;
  350. friend CFunction;
  351. typedef struct _IAS_OBJ
  352. {
  353. enum { IAS_TEXT, IAS_DATAOBJ } type;
  354. union
  355. {
  356. struct
  357. {
  358. const WCHAR *pchText;
  359. LONG cch;
  360. } text;
  361. struct
  362. {
  363. IDataObject *pDataObject;
  364. } obj;
  365. } state;
  366. } IAS_OBJ;
  367. HRESULT _InsertXAtSelection(TfEditCookie ec, DWORD dwFlags, IAS_OBJ *pObj, ITfRange **ppRange);
  368. void _DoPostTextEditNotifications(CComposition *pComposition, TfEditCookie ec, DWORD dwFlags, ULONG cchInserted, IAnchor *paStart, IAnchor *paEnd, CRange *range);
  369. BOOL _InsertXAtSelectionAggressive(TfEditCookie ec, DWORD dwFlags, IAS_OBJ *pObj, IAnchor **ppaStart, IAnchor **ppaEnd);
  370. int _GetCleanupListIndex(TfClientId tid);
  371. HRESULT _UnadviseOwnerSink();
  372. HRESULT _GetStartOrEnd(TfEditCookie ec, BOOL fStart, ITfRange **ppStart);
  373. BOOL _SynchAppChanges(DWORD dwLockFlags);
  374. HRESULT _EmptyLockQueue(DWORD dwLockFlags, BOOL fAppChangesSent);
  375. void _AbortQueueItems();
  376. void _PostponeLockRequest(DWORD dwFlags);
  377. HRESULT _DispatchQueueItem(TS_QUEUE_ITEM *pItem)
  378. {
  379. return pItem->pfnCallback(this, pItem, QI_DISPATCH);
  380. }
  381. void _ReleaseQueueItem(TS_QUEUE_ITEM *pItem)
  382. {
  383. pItem->pfnCallback(this, pItem, QI_FREE);
  384. }
  385. void _AddRefQueueItem(TS_QUEUE_ITEM *pItem)
  386. {
  387. pItem->pfnCallback(this, pItem, QI_ADDREF);
  388. }
  389. HRESULT _DoEditSession(TfClientId tid, ITfEditSession *pes, DWORD dwFlags);
  390. static HRESULT _EditSessionQiCallback(CInputContext *pic, TS_QUEUE_ITEM *pItem, QiCallbackCode qiCode);
  391. static HRESULT _PseudoSyncEditSessionQiCallback(CInputContext *pic, TS_QUEUE_ITEM *pItem, QiCallbackCode qiCode);
  392. HRESULT _OnSelectionChangeInternal(BOOL fAppChange);
  393. HRESULT _OnLayoutChangeInternal(TsLayoutCode lcode, TsViewCookie vcView);
  394. HRESULT _OnStatusChangeInternal();
  395. void _MarkDirtyRanges(IAnchor *paStart, IAnchor *paEnd);
  396. TFPROPERTYSTYLE _GetPropStyle(REFGUID rguidProp);
  397. void _IncEditCookie()
  398. {
  399. _ec++;
  400. // avoid reserved values!
  401. if (_ec == 0)
  402. {
  403. _ec = EC_MIN;
  404. }
  405. }
  406. void _Dbg_AssertNoSyncQueueItems()
  407. {
  408. #ifdef DEBUG
  409. for (int i=0; i<_rgLockQueue.Count(); i++)
  410. {
  411. Assert((_rgLockQueue.GetPtr(i)->dwFlags & TF_ES_SYNC) == 0);
  412. }
  413. #endif // DEBUG
  414. }
  415. CDocumentInputManager *_dm;
  416. ITextStoreAnchor *_ptsi;
  417. BOOL _fCiceroTSI;
  418. DWORD _dwLastLockReleaseID;
  419. TfEditCookie _ec;
  420. int _cEditRef;
  421. DWORD _dwEditSessionFlags;
  422. BOOL _fLockHeld; // perf: redundant with _dwlt?
  423. DWORD _dwlt; // perf: only need 2 bits
  424. TfClientId _tidInEditSession;
  425. DWORD _dwPendingLockRequest; // perf: only need 2 bits
  426. CEditRecord *_pEditRecord;
  427. BOOL EnsureEditRecord()
  428. {
  429. if (!_pEditRecord)
  430. _pEditRecord = new CEditRecord(this);
  431. return _pEditRecord ? TRUE : FALSE;
  432. }
  433. BOOL _fLayoutChanged;
  434. BOOL _fStatusChanged; // perf: redundant w/ _dwStatusChangedFlags?
  435. DWORD _dwStatusChangedFlags;
  436. // array of TIP guidatom for both left and right side of the caret.
  437. TfGuidAtom _gaKeyEventFilterTIP[2];
  438. BOOL _fInvalidKeyEventFilterTIP;
  439. ITfContextKeyEventSink *_pICKbdSink;
  440. DWORD _dwSysFuncPrvCookie; // system function provider cookie
  441. //
  442. // TextOwner Property cache
  443. //
  444. CProperty *_pPropTextOwner;
  445. static const GUID *_c_rgPropStyle[];
  446. CStructArray<TS_QUEUE_ITEM> _rgLockQueue;
  447. static const IID *_c_rgConnectionIIDs[IC_NUM_CONNECTIONPTS];
  448. CStructArray<GENERICSINK> _rgSinks[IC_NUM_CONNECTIONPTS];
  449. CStructArray<CLEANUPSINK> _rgCleanupSinks;
  450. CStructArray<SPAN> _rgAppTextChanges;
  451. CComposition *_pCompositionList;
  452. CRange *_pOnChangeRanges; // ranges with ITfRangeChange sinks
  453. CContextView *_pActiveView;
  454. ITfContextOwnerCompositionSink *_pOwnerComposeSink; // may be NULL, be careful
  455. LONG _cRefEditTransaction;
  456. BOOL _fInCompositionOp : 1; // TRUE if we're inside a write modification to a composition (ceate, terminate, etc.)
  457. BOOL _fInUnserialize : 1; // TRUE if we're inside a property _Unserialize
  458. //
  459. // App Property Map
  460. //
  461. typedef struct _APPPROPMAP
  462. {
  463. GUID guidAppProp;
  464. GUID guidProp;
  465. } APPPROPMAP;
  466. CStructArray<APPPROPMAP> _rgAppPropMap;
  467. APPPROPMAP *FindMapAppProperty(REFGUID guidAppProp);
  468. //
  469. // disable PostThreadMessage for LoackRequest.
  470. //
  471. ULONG _nLockReqPostDisableRef;
  472. // aa stuff
  473. //
  474. void _InitMSAAHook(IAccServerDocMgr *pAAAdaptor);
  475. void _UninitMSAAHook(IAccServerDocMgr *pAAAdaptor);
  476. typedef struct
  477. {
  478. ITextStoreAnchor *ptsiOrg; // the original, unwrapped ptsi
  479. ITextStoreAnchor *pAADoc; // the wrapped ITextStoreAnchor passed to _pAAAdaptor
  480. } MSAA_STATE;
  481. MSAA_STATE *_pMSAAState; // use a struct since we rarely use msaa
  482. //
  483. // end aa stuff
  484. #ifdef DEBUG
  485. BOOL _dbg_fInOnLockGranted;
  486. #endif
  487. DBG_ID_DECLARE;
  488. };
  489. inline CInputContext *GetCInputContext(IUnknown *punk)
  490. {
  491. CInputContext *pic;
  492. punk->QueryInterface(IID_PRIV_CINPUTCONTEXT, (void **)&pic);
  493. return pic;
  494. }
  495. //+---------------------------------------------------------------------------
  496. //
  497. // SafeRequestLock
  498. //
  499. // ITextStoreAnchor::RequestLock wrapper.
  500. //
  501. // Normally each CInputContext holds a ref to a text store in its _ptsi member.
  502. // But, it's possible that some crazy tip will Pop the context inside a
  503. // RequestLock call, which releases and clears _ptsi. This will likely crash
  504. // the ptsi code, since after OnLockGranted, the object will be freed.
  505. // So we protect the app by AddRef'ing the ptsi before the RequestLock call.
  506. //----------------------------------------------------------------------------
  507. inline HRESULT SafeRequestLock(ITextStoreAnchor *ptsi, DWORD dwLockFlags, HRESULT *phrSession)
  508. {
  509. HRESULT hr;
  510. ptsi->AddRef(); // protect pointer in case someone Pops this context inside the RequestLock
  511. hr = ptsi->RequestLock(dwLockFlags, phrSession);
  512. ptsi->Release();
  513. return hr;
  514. }
  515. #endif // IC_H