ReactOS  0.4.14-dev-52-g6116262
inputprocessor.c
Go to the documentation of this file.
1 /*
2  * Unit tests for ITfInputProcessor
3  *
4  * Copyright 2009 Aric Stewart, CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <stdio.h>
22 
23 #define COBJMACROS
24 #define CONST_VTABLE
25 #include "wine/test.h"
26 #include "winuser.h"
27 #include "initguid.h"
28 #include "shlwapi.h"
29 #include "shlguid.h"
30 #include "comcat.h"
31 #include "msctf.h"
32 #include "olectl.h"
33 
34 static ITfInputProcessorProfiles* g_ipp;
35 static LANGID gLangid;
39 static TfClientId cid = 0;
40 static TfClientId tid = 0;
41 
43 
44 #define SINK_UNEXPECTED 0
45 #define SINK_EXPECTED 1
46 #define SINK_FIRED 2
47 #define SINK_IGNORE 3
48 #define SINK_OPTIONAL 4
49 #define SINK_SAVE 5
50 
51 #define SINK_ACTION_MASK 0xff
52 #define SINK_OPTION_MASK 0xff00
53 #define SINK_EXPECTED_COUNT_MASK 0xff0000
54 
55 #define SINK_OPTION_TODO 0x0100
56 
57 #define FOCUS_IGNORE (ITfDocumentMgr*)0xffffffff
58 #define FOCUS_SAVE (ITfDocumentMgr*)0xfffffffe
59 
62 
87 
88 
89 static inline int expected_count(int *sink)
90 {
91  return (*sink & SINK_EXPECTED_COUNT_MASK)>>16;
92 }
93 
94 static inline void _sink_fire_ok(INT *sink, const CHAR* name)
95 {
96  int count;
97  int todo = *sink & SINK_OPTION_TODO;
98  int action = *sink & SINK_ACTION_MASK;
99 
101  winetest_trace("firing %s\n",name);
102 
103  switch (action)
104  {
105  case SINK_OPTIONAL:
106  case SINK_EXPECTED:
108  if (count > 1)
109  {
110  count --;
111  *sink = (*sink & ~SINK_EXPECTED_COUNT_MASK) + (count << 16);
112  return;
113  }
114  break;
115  case SINK_IGNORE:
116  winetest_trace("Ignoring %s\n",name);
117  return;
118  case SINK_SAVE:
119  count = expected_count(sink) + 1;
120  *sink = (*sink & ~SINK_EXPECTED_COUNT_MASK) + (count << 16);
121  return;
122  default:
124  winetest_ok(0, "Unexpected %s sink\n",name);
125  }
126  *sink = SINK_FIRED;
127 }
128 
129 #define sink_fire_ok(a,b) (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _sink_fire_ok(a,b)
130 
131 static inline void _sink_check_ok(INT *sink, const CHAR* name)
132 {
133  int action = *sink & SINK_ACTION_MASK;
134  int todo = *sink & SINK_OPTION_TODO;
135  int count = expected_count(sink);
136 
137  switch (action)
138  {
139  case SINK_OPTIONAL:
141  winetest_trace("optional sink %s not fired\n",name);
142  case SINK_FIRED:
143  break;
144  case SINK_IGNORE:
145  return;
146  case SINK_SAVE:
147  if (count == 0 && winetest_interactive)
148  winetest_trace("optional sink %s not fired\n",name);
149  break;
150  default:
152  winetest_ok(0, "%s not fired as expected, in state %x\n",name,*sink);
153  }
155 }
156 
157 #define sink_check_ok(a,b) (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _sink_check_ok(a,b)
158 
159 static inline void _sink_check_saved(INT *sink, ITfDocumentMgr *PrevFocus, ITfDocumentMgr *CurrentFocus, const CHAR* name)
160 {
161  int count = expected_count(sink);
163  if (PrevFocus != FOCUS_IGNORE && count != 0)
164  winetest_ok(PrevFocus == test_FirstPrevFocus, "%s expected prev focus %p got %p\n", name, PrevFocus, test_FirstPrevFocus);
165  if (CurrentFocus != FOCUS_IGNORE && count != 0)
166  winetest_ok(CurrentFocus == test_LastCurrentFocus, "%s expected current focus %p got %p\n", name, CurrentFocus, test_LastCurrentFocus);
169 }
170 
171 #define sink_check_saved(s,p,c,n) (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _sink_check_saved(s,p,c,n)
172 
173 /**********************************************************************
174  * ITextStoreACP
175  **********************************************************************/
176 typedef struct tagTextStoreACP
177 {
180 
181 } TextStoreACP;
182 
184 {
185  return CONTAINING_RECORD(iface, TextStoreACP, ITextStoreACP_iface);
186 }
187 
189 {
191 }
192 
194 {
195  *ppvOut = NULL;
196 
197  if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITextStoreACP))
198  {
199  *ppvOut = iface;
200  }
201 
202  if (*ppvOut)
203  {
204  ITextStoreACP_AddRef(iface);
205  return S_OK;
206  }
207 
208  return E_NOINTERFACE;
209 }
210 
212 {
214  return InterlockedIncrement(&This->refCount);
215 }
216 
218 {
220  ULONG ret;
221 
222  ret = InterlockedDecrement(&This->refCount);
223  if (ret == 0)
225  return ret;
226 }
227 
229  REFIID riid, IUnknown *punk, DWORD dwMask)
230 {
232  HRESULT hr;
233 
234  sink_fire_ok(&test_ACP_AdviseSink,"TextStoreACP_AdviseSink");
235 
236  if(ACPSink)
237  return S_OK;
238 
239  hr = IUnknown_QueryInterface(punk, &IID_ITextStoreACPSink, (void**)&ACPSink);
240  ok(SUCCEEDED(hr),"Unable to QueryInterface on sink\n");
241 
242  hr = ITextStoreACPSink_QueryInterface(ACPSink, &IID_ITextStoreACPServices, (void**)&services);
243  ok(hr == S_OK, "got 0x%08x\n", hr);
244  ITextStoreACPServices_Release(services);
245 
246  return S_OK;
247 }
248 
250  IUnknown *punk)
251 {
252  sink_fire_ok(&test_ACP_UnadviseSink,"TextStoreACP_UnadviseSink");
253  return S_OK;
254 }
255 
257  DWORD dwLockFlags, HRESULT *phrSession)
258 {
259  sink_fire_ok(&test_ACP_RequestLock,"TextStoreACP_RequestLock");
260  *phrSession = ITextStoreACPSink_OnLockGranted(ACPSink, dwLockFlags);
261  return S_OK;
262 }
264  TS_STATUS *pdcs)
265 {
266  sink_fire_ok(&test_ACP_GetStatus,"TextStoreACP_GetStatus");
268  return S_OK;
269 }
271  LONG acpTestStart, LONG acpTestEnd, ULONG cch, LONG *pacpResultStart,
272  LONG *pacpResultEnd)
273 {
274  trace("\n");
275  return S_OK;
276 }
278  ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched)
279 {
280  sink_fire_ok(&test_ACP_GetSelection,"TextStoreACP_GetSelection");
281 
282  pSelection->acpStart = 10;
283  pSelection->acpEnd = 20;
284  pSelection->style.fInterimChar = 0;
285  pSelection->style.ase = TS_AE_NONE;
286  *pcFetched = 1;
287 
288  return S_OK;
289 }
291  ULONG ulCount, const TS_SELECTION_ACP *pSelection)
292 {
293  sink_fire_ok(&test_ACP_SetSelection,"TextStoreACP_SetSelection");
294  return S_OK;
295 }
297  LONG acpStart, LONG acpEnd, WCHAR *pchPlain, ULONG cchPlainReq,
298  ULONG *pcchPlainRet, TS_RUNINFO *prgRunInfo, ULONG cRunInfoReq,
299  ULONG *pcRunInfoRet, LONG *pacpNext)
300 {
301  trace("\n");
302  return S_OK;
303 }
305  DWORD dwFlags, LONG acpStart, LONG acpEnd, const WCHAR *pchText,
306  ULONG cch, TS_TEXTCHANGE *pChange)
307 {
308  trace("\n");
309  return S_OK;
310 }
312  LONG acpStart, LONG acpEnd, IDataObject **ppDataObject)
313 {
314  trace("\n");
315  return S_OK;
316 }
318  LONG acpPos, REFGUID rguidService, REFIID riid, IUnknown **ppunk)
319 {
320  trace("\n");
321  return S_OK;
322 }
324  const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable)
325 {
326  trace("\n");
327  return S_OK;
328 }
330  DWORD dwFlags, LONG acpStart, LONG acpEnd, IDataObject *pDataObject,
331  TS_TEXTCHANGE *pChange)
332 {
333  trace("\n");
334  return S_OK;
335 }
337  DWORD dwFlags, const WCHAR *pchText, ULONG cch, LONG *pacpStart,
338  LONG *pacpEnd, TS_TEXTCHANGE *pChange)
339 {
340  sink_fire_ok(&test_ACP_InsertTextAtSelection,"TextStoreACP_InsertTextAtSelection");
341  return S_OK;
342 }
344  DWORD dwFlags, IDataObject *pDataObject, LONG *pacpStart, LONG *pacpEnd,
345  TS_TEXTCHANGE *pChange)
346 {
347  trace("\n");
348  return S_OK;
349 }
351  DWORD dwFlags, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs)
352 {
353  trace("\n");
354  return S_OK;
355 }
357  LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs,
358  DWORD dwFlags)
359 {
360  trace("\n");
361  return S_OK;
362 }
364  LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs,
365  DWORD dwFlags)
366 {
367  trace("\n");
368  return S_OK;
369 }
371  LONG acpStart, LONG acpHalt, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs,
372  DWORD dwFlags, LONG *pacpNext, BOOL *pfFound, LONG *plFoundOffset)
373 {
374  trace("\n");
375  return S_OK;
376 }
378  ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched)
379 {
380  trace("\n");
381  return S_OK;
382 }
384  LONG *pacp)
385 {
386  sink_fire_ok(&test_ACP_GetEndACP,"TextStoreACP_GetEndACP");
387  return S_OK;
388 }
390  TsViewCookie *pvcView)
391 {
392  trace("\n");
393  return S_OK;
394 }
396  TsViewCookie vcView, const POINT *ptScreen, DWORD dwFlags,
397  LONG *pacp)
398 {
399  trace("\n");
400  return S_OK;
401 }
403  TsViewCookie vcView, LONG acpStart, LONG acpEnd, RECT *prc,
404  BOOL *pfClipped)
405 {
406  trace("\n");
407  return S_OK;
408 }
410  TsViewCookie vcView, RECT *prc)
411 {
412  trace("\n");
413  return S_OK;
414 }
416  TsViewCookie vcView, HWND *phwnd)
417 {
418  trace("\n");
419  return S_OK;
420 }
421 
422 static const ITextStoreACPVtbl TextStoreACP_TextStoreACPVtbl =
423 {
427 
454 };
455 
457 {
459 
461  if (This == NULL)
462  return E_OUTOFMEMORY;
463 
464  This->ITextStoreACP_iface.lpVtbl = &TextStoreACP_TextStoreACPVtbl;
465  This->refCount = 1;
466 
467  *ppOut = (IUnknown*)&This->ITextStoreACP_iface;
468  return S_OK;
469 }
470 
471 /**********************************************************************
472  * ITfThreadMgrEventSink
473  **********************************************************************/
474 typedef struct tagThreadMgrEventSink
475 {
479 
481 {
482  return CONTAINING_RECORD(iface, ThreadMgrEventSink, ITfThreadMgrEventSink_iface);
483 }
484 
486 {
488 }
489 
491 {
492  *ppvOut = NULL;
493 
494  if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgrEventSink))
495  {
496  *ppvOut = iface;
497  }
498 
499  if (*ppvOut)
500  {
501  ITfThreadMgrEventSink_AddRef(iface);
502  return S_OK;
503  }
504 
505  return E_NOINTERFACE;
506 }
507 
509 {
511  ok (tmSinkRefCount == This->refCount,"ThreadMgrEventSink refcount off %i vs %i\n",This->refCount,tmSinkRefCount);
512  return InterlockedIncrement(&This->refCount);
513 }
514 
516 {
518  ULONG ret;
519 
520  ok (tmSinkRefCount == This->refCount,"ThreadMgrEventSink refcount off %i vs %i\n",This->refCount,tmSinkRefCount);
521  ret = InterlockedDecrement(&This->refCount);
522  if (ret == 0)
524  return ret;
525 }
526 
528 ITfDocumentMgr *pdim)
529 {
530  sink_fire_ok(&test_OnInitDocumentMgr,"ThreadMgrEventSink_OnInitDocumentMgr");
531  return S_OK;
532 }
533 
535 ITfDocumentMgr *pdim)
536 {
537  trace("\n");
538  return S_OK;
539 }
540 
542 ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus)
543 {
544  sink_fire_ok(&test_OnSetFocus,"ThreadMgrEventSink_OnSetFocus");
546  test_LastCurrentFocus = pdimFocus;
547  else if (test_CurrentFocus != FOCUS_IGNORE)
548  ok(pdimFocus == test_CurrentFocus,"Sink reports wrong focus\n");
549  if (test_PrevFocus == FOCUS_SAVE)
550  {
552  test_FirstPrevFocus = pdimPrevFocus;
553  }
554  else if (test_PrevFocus != FOCUS_IGNORE)
555  ok(pdimPrevFocus == test_PrevFocus,"Sink reports wrong previous focus\n");
556  return S_OK;
557 }
558 
560 ITfContext *pic)
561 {
562  HRESULT hr;
563  ITfDocumentMgr *docmgr;
564  ITfContext *test;
565 
566  hr = ITfContext_GetDocumentMgr(pic,&docmgr);
567  ok(SUCCEEDED(hr),"GetDocumentMgr failed\n");
568  test = (ITfContext*)0xdeadbeef;
569  hr = ITfDocumentMgr_GetTop(docmgr,&test);
570  ok(SUCCEEDED(hr),"GetTop failed\n");
571  ITfDocumentMgr_Release(docmgr);
572  ok(test == pic, "Wrong context is on top\n");
573  if (test)
574  ITfContext_Release(test);
575 
576  sink_fire_ok(&test_OnPushContext,"ThreadMgrEventSink_OnPushContext");
577  return S_OK;
578 }
579 
581 ITfContext *pic)
582 {
583  HRESULT hr;
584  ITfDocumentMgr *docmgr;
585  ITfContext *test;
586 
587  hr = ITfContext_GetDocumentMgr(pic,&docmgr);
588  ok(SUCCEEDED(hr),"GetDocumentMgr failed\n");
589  ITfDocumentMgr_Release(docmgr);
590  test = (ITfContext*)0xdeadbeef;
591  hr = ITfDocumentMgr_GetTop(docmgr,&test);
592  ok(SUCCEEDED(hr),"GetTop failed\n");
593  ok(test == pic, "Wrong context is on top\n");
594  if (test)
595  ITfContext_Release(test);
596 
597  sink_fire_ok(&test_OnPopContext,"ThreadMgrEventSink_OnPopContext");
598  return S_OK;
599 }
600 
601 static const ITfThreadMgrEventSinkVtbl ThreadMgrEventSink_ThreadMgrEventSinkVtbl =
602 {
606 
612 };
613 
615 {
617 
619  if (This == NULL)
620  return E_OUTOFMEMORY;
621 
622  This->ITfThreadMgrEventSink_iface.lpVtbl = &ThreadMgrEventSink_ThreadMgrEventSinkVtbl;
623  This->refCount = 1;
624 
625  *ppOut = (IUnknown*)&This->ITfThreadMgrEventSink_iface;
626  return S_OK;
627 }
628 
630 {
631  if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ITfKeyTraceEventSink, riid)) {
632  *ppv = iface;
633  return S_OK;
634  }
635 
636  *ppv = NULL;
637  return E_NOINTERFACE;
638 }
639 
641 {
642  return 2;
643 }
644 
646 {
647  return 1;
648 }
649 
652 {
653  ok(0, "unexpected call\n");
654  return E_NOTIMPL;
655 }
656 
659 {
660  ok(0, "unexpected call\n");
661  return E_NOTIMPL;
662 }
663 
664 static const ITfKeyTraceEventSinkVtbl TfKeyTraceEventSinkVtbl = {
670 };
671 
673 
675 {
676  if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ITfTransitoryExtensionSink, riid)) {
677  *ppv = iface;
678  return S_OK;
679  }
680 
681  *ppv = NULL;
682  return E_NOINTERFACE;
683 }
684 
686 {
687  return 2;
688 }
689 
691 {
692  return 1;
693 }
694 
696  TfEditCookie ecReadOnly, ITfRange *pResultRange, ITfRange *pCompositionRange, BOOL *pfDeleteResultRange)
697 {
698  ok(0, "unexpected call\n");
699  return E_NOTIMPL;
700 }
701 
702 static const ITfTransitoryExtensionSinkVtbl TfTransitoryExtensionSinkVtbl = {
707 };
708 
710 
711 /********************************************************************************************
712  * Stub text service for testing
713  ********************************************************************************************/
714 
717 static DWORD regid;
718 
719 typedef HRESULT (*LPFNCONSTRUCTOR)(IUnknown *pUnkOuter, IUnknown **ppvOut);
720 
721 typedef struct tagClassFactory
722 {
724  LONG ref;
726 } ClassFactory;
727 
729 {
730  return CONTAINING_RECORD(iface, ClassFactory, IClassFactory_iface);
731 }
732 
733 typedef struct tagTextService
734 {
737 } TextService;
738 
740 {
741  return CONTAINING_RECORD(iface, TextService, ITfTextInputProcessor_iface);
742 }
743 
745 {
747  TS_refCount--;
748 }
749 
751 {
752  *ppvOut = NULL;
754  {
755  IClassFactory_AddRef(iface);
756  *ppvOut = iface;
757  return S_OK;
758  }
759 
760  return E_NOINTERFACE;
761 }
762 
764 {
766  return InterlockedIncrement(&This->ref);
767 }
768 
770 {
773 
774  if (ret == 0)
776  return ret;
777 }
778 
780 {
782  HRESULT ret;
783  IUnknown *obj;
784 
785  ret = This->ctor(punkOuter, &obj);
786  if (FAILED(ret))
787  return ret;
788  ret = IUnknown_QueryInterface(obj, iid, ppvOut);
789  IUnknown_Release(obj);
790  return ret;
791 }
792 
794 {
795  if(fLock)
797  else
799 
800  return S_OK;
801 }
802 
803 static const IClassFactoryVtbl ClassFactoryVtbl = {
804  /* IUnknown */
808 
809  /* IClassFactory*/
812 };
813 
815 {
817  This->IClassFactory_iface.lpVtbl = &ClassFactoryVtbl;
818  This->ref = 1;
819  This->ctor = ctor;
820  *ppvOut = &This->IClassFactory_iface;
821  TS_refCount++;
822  return S_OK;
823 }
824 
826 {
828 }
829 
831 {
832  *ppvOut = NULL;
833 
834  if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfTextInputProcessor))
835  {
836  *ppvOut = iface;
837  }
838 
839  if (*ppvOut)
840  {
841  ITfTextInputProcessor_AddRef(iface);
842  return S_OK;
843  }
844 
845  return E_NOINTERFACE;
846 }
847 
849 {
851  return InterlockedIncrement(&This->refCount);
852 }
853 
855 {
857  ULONG ret;
858 
859  ret = InterlockedDecrement(&This->refCount);
860  if (ret == 0)
862  return ret;
863 }
864 
866  ITfThreadMgr *ptim, TfClientId id)
867 {
868  trace("TextService_Activate\n");
869  ok(test_ShouldActivate,"Activation came unexpectedly\n");
870  tid = id;
871  return S_OK;
872 }
873 
875 {
876  trace("TextService_Deactivate\n");
877  ok(test_ShouldDeactivate,"Deactivation came unexpectedly\n");
878  return S_OK;
879 }
880 
881 static const ITfTextInputProcessorVtbl TextService_TextInputProcessorVtbl=
882 {
886 
889 };
890 
892 {
893  TextService *This;
894  if (pUnkOuter)
895  return CLASS_E_NOAGGREGATION;
896 
898  if (This == NULL)
899  return E_OUTOFMEMORY;
900 
901  This->ITfTextInputProcessor_iface.lpVtbl = &TextService_TextInputProcessorVtbl;
902  This->refCount = 1;
903 
904  *ppOut = (IUnknown*)&This->ITfTextInputProcessor_iface;
905  return S_OK;
906 }
907 
909 {
911  return CoRegisterClassObject(rclsid, (IUnknown*) cf, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
912 }
913 
915 {
916  return CoRevokeClassObject(regid);
917 }
918 
919 /*
920  * The tests
921  */
922 
923 DEFINE_GUID(CLSID_FakeService, 0xEDE1A7AD,0x66DE,0x47E0,0xB6,0x20,0x3E,0x92,0xF8,0x24,0x6B,0xF3);
924 DEFINE_GUID(CLSID_TF_InputProcessorProfiles, 0x33c53a50,0xf456,0x4884,0xb0,0x49,0x85,0xfd,0x64,0x3e,0xcf,0xed);
925 DEFINE_GUID(CLSID_TF_CategoryMgr, 0xA4B544A1,0x438D,0x4B41,0x93,0x25,0x86,0x95,0x23,0xE2,0xD6,0xC7);
926 DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745c63,0xb2f0,0x4784,0x8b,0x67,0x5e,0x12,0xc8,0x70,0x1a,0x31);
927 DEFINE_GUID(GUID_TFCAT_TIP_SPEECH, 0xB5A73CD1,0x8355,0x426B,0xA1,0x61,0x25,0x98,0x08,0xF2,0x6B,0x14);
928 DEFINE_GUID(GUID_TFCAT_TIP_HANDWRITING, 0x246ecb87,0xc2f2,0x4abe,0x90,0x5b,0xc8,0xb3,0x8a,0xdd,0x2c,0x43);
929 DEFINE_GUID (GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, 0x046B8C80,0x1647,0x40F7,0x9B,0x21,0xB9,0x3B,0x81,0xAA,0xBC,0x1B);
930 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
931 DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529a9e6b,0x6587,0x4f23,0xab,0x9e,0x9c,0x7d,0x68,0x3e,0x3c,0x50);
932 DEFINE_GUID(CLSID_PreservedKey, 0xA0ED8E55,0xCD3B,0x4274,0xB2,0x95,0xF6,0xC9,0xBA,0x2B,0x84,0x72);
933 DEFINE_GUID(GUID_COMPARTMENT_KEYBOARD_DISABLED, 0x71a5b253,0x1951,0x466b,0x9f,0xbc,0x9c,0x88,0x08,0xfa,0x84,0xf2);
934 DEFINE_GUID(GUID_COMPARTMENT_KEYBOARD_OPENCLOSE, 0x58273aad,0x01bb,0x4164,0x95,0xc6,0x75,0x5b,0xa0,0xb5,0x16,0x2d);
935 DEFINE_GUID(GUID_COMPARTMENT_HANDWRITING_OPENCLOSE, 0xf9ae2c6b,0x1866,0x4361,0xaf,0x72,0x7a,0xa3,0x09,0x48,0x89,0x0e);
936 DEFINE_GUID(GUID_COMPARTMENT_SPEECH_DISABLED, 0x56c5c607,0x0703,0x4e59,0x8e,0x52,0xcb,0xc8,0x4e,0x8b,0xbe,0x35);
937 DEFINE_GUID(GUID_COMPARTMENT_SPEECH_OPENCLOSE, 0x544d6a63,0xe2e8,0x4752,0xbb,0xd1,0x00,0x09,0x60,0xbc,0xa0,0x83);
938 DEFINE_GUID(GUID_COMPARTMENT_SPEECH_GLOBALSTATE, 0x2a54fe8e,0x0d08,0x460c,0xa7,0x5d,0x87,0x03,0x5f,0xf4,0x36,0xc5);
939 DEFINE_GUID(GUID_COMPARTMENT_PERSISTMENUENABLED, 0x575f3783,0x70c8,0x47c8,0xae,0x5d,0x91,0xa0,0x1a,0x1f,0x75,0x92);
940 DEFINE_GUID(GUID_COMPARTMENT_EMPTYCONTEXT, 0xd7487dbf,0x804e,0x41c5,0x89,0x4d,0xad,0x96,0xfd,0x4e,0xea,0x13);
941 DEFINE_GUID(GUID_COMPARTMENT_TIPUISTATUS, 0x148ca3ec,0x0366,0x401c,0x8d,0x75,0xed,0x97,0x8d,0x85,0xfb,0xc9);
942 
943 static HRESULT initialize(void)
944 {
945  HRESULT hr;
946  HKEY hkey;
947 
949 
950  if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\CTF\\TIP", 0,
951  KEY_READ|KEY_WRITE, &hkey) != ERROR_SUCCESS)
952  {
953  skip("Not enough permission to register input processor\n");
954  return E_FAIL;
955  }
956  RegCloseKey(hkey);
957 
959  CLSCTX_INPROC_SERVER, &IID_ITfInputProcessorProfiles, (void**)&g_ipp);
960  if (SUCCEEDED(hr))
962  CLSCTX_INPROC_SERVER, &IID_ITfCategoryMgr, (void**)&g_cm);
963  if (SUCCEEDED(hr))
965  CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (void**)&g_tm);
966  return hr;
967 }
968 
969 static void cleanup(void)
970 {
971  if (g_ipp)
972  ITfInputProcessorProfiles_Release(g_ipp);
973  if (g_cm)
974  ITfCategoryMgr_Release(g_cm);
975  if (g_tm)
976  ITfThreadMgr_Release(g_tm);
977  CoUninitialize();
978 }
979 
980 static void test_Register(void)
981 {
982  HRESULT hr;
983 
984  static const WCHAR szDesc[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',0};
985  static const WCHAR szFile[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',' ','F','i','l','e',0};
986 
987  hr = ITfInputProcessorProfiles_GetCurrentLanguage(g_ipp,&gLangid);
988  ok(SUCCEEDED(hr),"Unable to get current language id\n");
989  trace("Current Language %x\n",gLangid);
990 
991  hr = RegisterTextService(&CLSID_FakeService);
992  ok(SUCCEEDED(hr),"Unable to register COM for TextService\n");
993  hr = ITfInputProcessorProfiles_Register(g_ipp, &CLSID_FakeService);
994  ok(SUCCEEDED(hr),"Unable to register text service(%x)\n",hr);
995  hr = ITfInputProcessorProfiles_AddLanguageProfile(g_ipp, &CLSID_FakeService, gLangid,
996  &CLSID_FakeService, szDesc, ARRAY_SIZE(szDesc), szFile, ARRAY_SIZE(szFile), 1);
997  ok(SUCCEEDED(hr),"Unable to add Language Profile (%x)\n",hr);
998 }
999 
1000 static void test_Unregister(void)
1001 {
1002  HRESULT hr;
1003  hr = ITfInputProcessorProfiles_Unregister(g_ipp, &CLSID_FakeService);
1004  ok(SUCCEEDED(hr),"Unable to unregister text service(%x)\n",hr);
1006 }
1007 
1009 {
1010  IEnumGUID *ppEnum;
1011  BOOL found = FALSE;
1012 
1013  if (SUCCEEDED(ITfInputProcessorProfiles_EnumInputProcessorInfo(g_ipp, &ppEnum)))
1014  {
1015  ULONG fetched;
1016  GUID g;
1017  while (IEnumGUID_Next(ppEnum, 1, &g, &fetched) == S_OK)
1018  {
1019  if(IsEqualGUID(&g,&CLSID_FakeService))
1020  found = TRUE;
1021  }
1022  IEnumGUID_Release(ppEnum);
1023  }
1024  ok(found,"Did not find registered text service\n");
1025 }
1026 
1027 static void test_EnumLanguageProfiles(void)
1028 {
1029  BOOL found = FALSE;
1030  IEnumTfLanguageProfiles *ppEnum;
1031  HRESULT hr;
1032 
1033  hr = ITfInputProcessorProfiles_EnumLanguageProfiles(g_ipp, gLangid, NULL);
1034  ok(hr == E_INVALIDARG, "EnumLanguageProfiles failed: %x\n", hr);
1035 
1036  if (SUCCEEDED(ITfInputProcessorProfiles_EnumLanguageProfiles(g_ipp,gLangid,&ppEnum)))
1037  {
1039  while (IEnumTfLanguageProfiles_Next(ppEnum,1,&profile,NULL)==S_OK)
1040  {
1041  if (IsEqualGUID(&profile.clsid,&CLSID_FakeService))
1042  {
1043  found = TRUE;
1044  ok(profile.langid == gLangid, "LangId Incorrect\n");
1046  broken(IsEqualGUID(&profile.catid,&GUID_NULL) /* Win8 */), "CatId Incorrect\n");
1047  ok(IsEqualGUID(&profile.guidProfile,&CLSID_FakeService), "guidProfile Incorrect\n");
1048  }
1049  }
1050  IEnumTfLanguageProfiles_Release(ppEnum);
1051  }
1052  ok(found,"Registered text service not found\n");
1053 }
1054 
1055 static void test_RegisterCategory(void)
1056 {
1057  HRESULT hr;
1058  hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService);
1059  ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n");
1060  hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService);
1061  ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n");
1062 }
1063 
1064 static void test_UnregisterCategory(void)
1065 {
1066  HRESULT hr;
1067  hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService);
1068  ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n");
1069  hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService);
1070  ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n");
1071 }
1072 
1073 static void test_FindClosestCategory(void)
1074 {
1075  GUID output;
1076  HRESULT hr;
1078 
1079  hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, NULL, 0);
1080  ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr);
1082 
1083  hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 1);
1084  ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr);
1085  ok(IsEqualGUID(&output,&GUID_NULL),"Wrong GUID\n");
1086 
1087  hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 3);
1088  ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr);
1089  ok(IsEqualGUID(&output,&GUID_TFCAT_TIP_KEYBOARD),"Wrong GUID\n");
1090 }
1091 
1092 static void test_Enable(void)
1093 {
1094  HRESULT hr;
1095  BOOL enabled = FALSE;
1096 
1097  hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, TRUE);
1098  ok(SUCCEEDED(hr),"Failed to enable text service\n");
1099  hr = ITfInputProcessorProfiles_IsEnabledLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, &enabled);
1100  ok(SUCCEEDED(hr),"Failed to get enabled state\n");
1101  ok(enabled == TRUE,"enabled state incorrect\n");
1102 }
1103 
1104 static void test_Disable(void)
1105 {
1106  HRESULT hr;
1107 
1108  trace("Disabling\n");
1109  hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, FALSE);
1110  ok(SUCCEEDED(hr),"Failed to disable text service\n");
1111 }
1112 
1113 static void test_ThreadMgrAdviseSinks(void)
1114 {
1115  ITfSource *source = NULL;
1116  HRESULT hr;
1117  IUnknown *sink;
1118 
1119  hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source);
1120  ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n");
1121  if (!source)
1122  return;
1123 
1125  ok(hr == S_OK, "got %08x\n", hr);
1126  if(FAILED(hr)) return;
1127 
1128  tmSinkRefCount = 1;
1129  tmSinkCookie = 0;
1130  hr = ITfSource_AdviseSink(source,&IID_ITfThreadMgrEventSink, sink, &tmSinkCookie);
1131  ok(hr == S_OK, "Failed to Advise Sink\n");
1132  ok(tmSinkCookie!=0,"Failed to get sink cookie\n");
1133 
1134  /* Advising the sink adds a ref, Releasing here lets the object be deleted
1135  when unadvised */
1136  tmSinkRefCount = 2;
1137  IUnknown_Release(sink);
1138 
1139  hr = ITfSource_AdviseSink(source, &IID_ITfKeyTraceEventSink, (IUnknown*)&TfKeyTraceEventSink,
1141  ok(hr == S_OK, "Failed to Advise Sink\n");
1142 
1143  ITfSource_Release(source);
1144 }
1145 
1147 {
1148  ITfSource *source = NULL;
1149  HRESULT hr;
1150 
1151  hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source);
1152  ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n");
1153  if (!source)
1154  return;
1155 
1156  tmSinkRefCount = 1;
1157  hr = ITfSource_UnadviseSink(source, tmSinkCookie);
1158  ok(hr == S_OK, "Failed to unadvise Sink\n");
1159 
1160  hr = ITfSource_UnadviseSink(source, key_trace_sink_cookie);
1161  ok(hr == S_OK, "Failed to unadvise Sink\n");
1162 
1163  ITfSource_Release(source);
1164 }
1165 
1167 {
1168  ITfSource *source;
1169  HRESULT hr;
1170 
1171  hr = ITfDocumentMgr_QueryInterface(g_dm, &IID_ITfSource, (void**)&source);
1172  ok(hr == S_OK,"Failed to get IID_ITfSource for DocumentMgr\n");
1173 
1174  dmSinkCookie = 0;
1175  hr = ITfSource_AdviseSink(source, &IID_ITfTransitoryExtensionSink, (IUnknown*)&TfTransitoryExtensionSink, &dmSinkCookie);
1176  ok(hr == S_OK,"Failed to Advise Sink\n");
1177 
1178  ITfSource_Release(source);
1179 }
1180 
1182 {
1183  ITfSource *source = NULL;
1184  HRESULT hr;
1185 
1186  hr = ITfDocumentMgr_QueryInterface(g_dm, &IID_ITfSource, (void**)&source);
1187  ok(hr == S_OK,"Failed to get IID_ITfSource for DocumentMgr\n");
1188 
1189  hr = ITfSource_UnadviseSink(source, dmSinkCookie);
1190  ok(hr == S_OK,"Failed to unadvise Sink\n");
1191  ITfSource_Release(source);
1192 }
1193 
1194 /**********************************************************************
1195  * ITfKeyEventSink
1196  **********************************************************************/
1197 typedef struct tagKeyEventSink
1198 {
1201 } KeyEventSink;
1202 
1204 {
1205  return CONTAINING_RECORD(iface, KeyEventSink, ITfKeyEventSink_iface);
1206 }
1207 
1209 {
1211 }
1212 
1214 {
1215  *ppvOut = NULL;
1216 
1217  if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfKeyEventSink))
1218  {
1219  *ppvOut = iface;
1220  }
1221 
1222  if (*ppvOut)
1223  {
1224  ITfKeyEventSink_AddRef(iface);
1225  return S_OK;
1226  }
1227 
1228  return E_NOINTERFACE;
1229 }
1230 
1232 {
1234  return InterlockedIncrement(&This->refCount);
1235 }
1236 
1238 {
1240  ULONG ret;
1241 
1242  ret = InterlockedDecrement(&This->refCount);
1243  if (ret == 0)
1245  return ret;
1246 }
1247 
1249  BOOL fForeground)
1250 {
1251  sink_fire_ok(&test_KEV_OnSetFocus,"KeyEventSink_OnSetFocus");
1252  return S_OK;
1253 }
1254 
1256  ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
1257 {
1258  trace("\n");
1259  return S_OK;
1260 }
1261 
1263  ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
1264 {
1265  trace("\n");
1266  return S_OK;
1267 }
1268 
1270  ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
1271 {
1272  trace("\n");
1273  return S_OK;
1274 }
1275 
1277  ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
1278 {
1279  trace("\n");
1280  return S_OK;
1281 }
1282 
1284  ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
1285 {
1286  trace("\n");
1287  return S_OK;
1288 }
1289 
1290 static const ITfKeyEventSinkVtbl KeyEventSink_KeyEventSinkVtbl =
1291 {
1295 
1302 };
1303 
1305 {
1306  KeyEventSink *This;
1307 
1309  if (This == NULL)
1310  return E_OUTOFMEMORY;
1311 
1312  This->ITfKeyEventSink_iface.lpVtbl = &KeyEventSink_KeyEventSinkVtbl;
1313  This->refCount = 1;
1314 
1315  *ppOut = &This->ITfKeyEventSink_iface;
1316  return S_OK;
1317 }
1318 
1319 
1320 static void test_KeystrokeMgr(void)
1321 {
1322  ITfKeystrokeMgr *keymgr= NULL;
1323  HRESULT hr;
1324  TF_PRESERVEDKEY tfpk;
1325  BOOL preserved;
1327 
1329 
1330  hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfKeystrokeMgr, (LPVOID*)&keymgr);
1331  ok(SUCCEEDED(hr),"Failed to get IID_ITfKeystrokeMgr for ThreadMgr\n");
1332 
1333  tfpk.uVKey = 'A';
1334  tfpk.uModifiers = TF_MOD_SHIFT;
1335 
1337  hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,tid,sink,TRUE);
1338  ok(SUCCEEDED(hr),"ITfKeystrokeMgr_AdviseKeyEventSink failed\n");
1339  sink_check_ok(&test_KEV_OnSetFocus,"KeyEventSink_OnSetFocus");
1340  hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,tid,sink,TRUE);
1341  ok(hr == CONNECT_E_ADVISELIMIT,"Wrong return, expected CONNECT_E_ADVISELIMIT\n");
1342  hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,cid,sink,TRUE);
1343  ok(hr == E_INVALIDARG,"Wrong return, expected E_INVALIDARG\n");
1344 
1345  hr =ITfKeystrokeMgr_PreserveKey(keymgr, 0, &CLSID_PreservedKey, &tfpk, NULL, 0);
1346  ok(hr==E_INVALIDARG,"ITfKeystrokeMgr_PreserveKey improperly succeeded\n");
1347 
1348  hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0);
1349  ok(SUCCEEDED(hr),"ITfKeystrokeMgr_PreserveKey failed\n");
1350 
1351  hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0);
1352  ok(hr == TF_E_ALREADY_EXISTS,"ITfKeystrokeMgr_PreserveKey improperly succeeded\n");
1353 
1354  preserved = FALSE;
1355  hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved);
1356  ok(hr == S_OK, "ITfKeystrokeMgr_IsPreservedKey failed\n");
1357  if (hr == S_OK) ok(preserved == TRUE,"misreporting preserved key\n");
1358 
1359  hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk);
1360  ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnpreserveKey failed\n");
1361 
1362  hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved);
1363  ok(hr == S_FALSE, "ITfKeystrokeMgr_IsPreservedKey failed\n");
1364  if (hr == S_FALSE) ok(preserved == FALSE,"misreporting preserved key\n");
1365 
1366  hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk);
1367  ok(hr==CONNECT_E_NOCONNECTION,"ITfKeystrokeMgr_UnpreserveKey improperly succeeded\n");
1368 
1369  hr = ITfKeystrokeMgr_UnadviseKeyEventSink(keymgr,tid);
1370  ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnadviseKeyEventSink failed\n");
1371 
1372  ITfKeystrokeMgr_Release(keymgr);
1373  ITfKeyEventSink_Release(sink);
1374 }
1375 
1376 static void test_Activate(void)
1377 {
1378  HRESULT hr;
1379 
1380  test_ShouldActivate = TRUE; /* Win7 */
1381  hr = ITfInputProcessorProfiles_ActivateLanguageProfile(g_ipp,&CLSID_FakeService,gLangid,&CLSID_FakeService);
1382  ok(SUCCEEDED(hr),"Failed to Activate text service\n");
1384 }
1385 
1386 
1388 {
1389  HRESULT hr;
1390  IEnumTfContexts* pEnum;
1391  BOOL found = FALSE;
1392 
1393  hr = ITfDocumentMgr_EnumContexts(dm,&pEnum);
1394  ok(SUCCEEDED(hr),"EnumContexts failed\n");
1395  if (SUCCEEDED(hr))
1396  {
1397  ULONG fetched;
1398  ITfContext *cxt;
1399  while (IEnumTfContexts_Next(pEnum, 1, &cxt, &fetched) == S_OK)
1400  {
1401  if (!search)
1402  found = TRUE;
1403  else if (search == cxt)
1404  found = TRUE;
1405  ITfContext_Release(cxt);
1406  }
1407  IEnumTfContexts_Release(pEnum);
1408  }
1409  if (search)
1410  ok(found,"Did not find proper ITfContext\n");
1411  else
1412  ok(!found,"Found an ITfContext we should should not have\n");
1413 }
1414 
1416 {
1417  HRESULT hr;
1418  IEnumTfDocumentMgrs* pEnum;
1419  BOOL found = FALSE;
1420  BOOL notfound = TRUE;
1421 
1422  hr = ITfThreadMgr_EnumDocumentMgrs(tm,&pEnum);
1423  ok(SUCCEEDED(hr),"EnumDocumentMgrs failed\n");
1424  if (SUCCEEDED(hr))
1425  {
1426  ULONG fetched;
1427  ITfDocumentMgr *dm;
1428  while (IEnumTfDocumentMgrs_Next(pEnum, 1, &dm, &fetched) == S_OK)
1429  {
1430  if (!search)
1431  found = TRUE;
1432  else if (search == dm)
1433  found = TRUE;
1434  if (absent && dm == absent)
1435  notfound = FALSE;
1436  ITfDocumentMgr_Release(dm);
1437  }
1438  IEnumTfDocumentMgrs_Release(pEnum);
1439  }
1440  if (search)
1441  ok(found,"Did not find proper ITfDocumentMgr\n");
1442  else
1443  ok(!found,"Found an ITfDocumentMgr we should should not have\n");
1444  if (absent)
1445  ok(notfound,"Found an ITfDocumentMgr we believe should be absent\n");
1446 }
1447 
1448 static inline int check_context_refcount(ITfContext *iface)
1449 {
1450  ITfContext_AddRef(iface);
1451  return ITfContext_Release(iface);
1452 }
1453 
1454 
1455 /**********************************************************************
1456  * ITfTextEditSink
1457  **********************************************************************/
1458 typedef struct tagTextEditSink
1459 {
1462 } TextEditSink;
1463 
1465 {
1466  return CONTAINING_RECORD(iface, TextEditSink, ITfTextEditSink_iface);
1467 }
1468 
1470 {
1472 }
1473 
1475 {
1476  *ppvOut = NULL;
1477 
1478  if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfTextEditSink))
1479  {
1480  *ppvOut = iface;
1481  }
1482 
1483  if (*ppvOut)
1484  {
1485  ITfTextEditSink_AddRef(iface);
1486  return S_OK;
1487  }
1488 
1489  return E_NOINTERFACE;
1490 }
1491 
1493 {
1495  return InterlockedIncrement(&This->refCount);
1496 }
1497 
1499 {
1501  ULONG ret;
1502 
1503  ret = InterlockedDecrement(&This->refCount);
1504  if (ret == 0)
1506  return ret;
1507 }
1508 
1510  ITfContext *pic, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord)
1511 {
1512  sink_fire_ok(&test_OnEndEdit,"TextEditSink_OnEndEdit");
1513  return S_OK;
1514 }
1515 
1516 static const ITfTextEditSinkVtbl TextEditSink_TextEditSinkVtbl =
1517 {
1521 
1523 };
1524 
1526 {
1527  TextEditSink *This;
1528 
1529  *ppOut = NULL;
1531  if (This == NULL)
1532  return E_OUTOFMEMORY;
1533 
1534  This->ITfTextEditSink_iface.lpVtbl = &TextEditSink_TextEditSinkVtbl;
1535  This->refCount = 1;
1536 
1537  *ppOut = &This->ITfTextEditSink_iface;
1538  return S_OK;
1539 }
1540 
1541 static void test_startSession(void)
1542 {
1543  HRESULT hr;
1544  DWORD cnt;
1545  DWORD editCookie;
1546  ITfDocumentMgr *dmtest;
1547  ITfContext *cxt,*cxt2,*cxt3,*cxtTest;
1548  ITextStoreACP *ts = NULL;
1549  TfClientId cid2 = 0;
1550  ITfThreadMgrEx *tmex;
1551 
1552  hr = ITfThreadMgr_Deactivate(g_tm);
1553  ok(hr == E_UNEXPECTED,"Deactivate should have failed with E_UNEXPECTED\n");
1554 
1556  hr = ITfThreadMgr_Activate(g_tm,&cid);
1557  ok(SUCCEEDED(hr),"Failed to Activate\n");
1558  ok(cid != tid,"TextService id mistakenly matches Client id\n");
1559 
1561  hr = ITfThreadMgr_Activate(g_tm,&cid2);
1562  ok(SUCCEEDED(hr),"Failed to Activate\n");
1563  ok(cid == cid2, "Second activate client ID does not match\n");
1564 
1565  hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfThreadMgrEx, (void **)&tmex);
1566  if (hr == S_OK)
1567  {
1568  hr = ITfThreadMgrEx_ActivateEx(tmex, &cid2, 0);
1569  ok(SUCCEEDED(hr), "Failed to Activate\n");
1570  ok(cid == cid2, "ActivateEx client ID does not match\n");
1571 
1572  ITfThreadMgrEx_Release(tmex);
1573  }
1574  else
1575  win_skip("ITfThreadMgrEx is not supported\n");
1576 
1577  hr = ITfThreadMgr_Deactivate(g_tm);
1578  ok(SUCCEEDED(hr), "Failed to Deactivate\n");
1579  hr = ITfThreadMgr_Deactivate(g_tm);
1580  ok(SUCCEEDED(hr), "Failed to Deactivate\n");
1581 
1583 
1584  hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&g_dm);
1585  ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n");
1586 
1588 
1589  hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&dmtest);
1590  ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n");
1591 
1592  test_EnumDocumentMgr(g_tm,dmtest,NULL);
1593 
1594  ITfDocumentMgr_Release(dmtest);
1595  test_EnumDocumentMgr(g_tm,g_dm,dmtest);
1596 
1597  hr = ITfThreadMgr_GetFocus(g_tm,&dmtest);
1598  ok(SUCCEEDED(hr),"GetFocus Failed\n");
1599  ok(dmtest == NULL,"Initial focus not null\n");
1600 
1602  test_PrevFocus = NULL;
1603  test_OnSetFocus = SINK_OPTIONAL; /* Doesn't always fire on Win7 */
1604  hr = ITfThreadMgr_SetFocus(g_tm,g_dm);
1605  ok(SUCCEEDED(hr),"SetFocus Failed\n");
1606  sink_check_ok(&test_OnSetFocus,"OnSetFocus");
1607 
1608  hr = ITfThreadMgr_GetFocus(g_tm,&dmtest);
1609  ok(SUCCEEDED(hr),"GetFocus Failed\n");
1610  ok(g_dm == dmtest,"Expected DocumentMgr not focused\n");
1611 
1612  ITfDocumentMgr_Release(g_dm);
1613 
1614  hr = ITfThreadMgr_GetFocus(g_tm,&dmtest);
1615  ok(SUCCEEDED(hr),"GetFocus Failed\n");
1616  ok(g_dm == dmtest,"Expected DocumentMgr not focused\n");
1617  ITfDocumentMgr_Release(dmtest);
1618 
1620  ok(SUCCEEDED(hr),"Constructor Failed\n");
1621  if (FAILED(hr)) return;
1622 
1623  hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, (IUnknown*)ts, &cxt, &editCookie);
1624  ok(SUCCEEDED(hr),"CreateContext Failed\n");
1625 
1626  hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt2, &editCookie);
1627  ok(SUCCEEDED(hr),"CreateContext Failed\n");
1628 
1629  hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt3, &editCookie);
1630  ok(SUCCEEDED(hr),"CreateContext Failed\n");
1631 
1633 
1634  hr = ITfContext_GetDocumentMgr(cxt,&dmtest);
1635  ok(hr == S_OK, "ITfContext_GetDocumentMgr failed with %x\n",hr);
1636  ok(dmtest == g_dm, "Wrong documentmgr\n");
1637  ITfDocumentMgr_Release(dmtest);
1638 
1639  cnt = check_context_refcount(cxt);
1643  hr = ITfDocumentMgr_Push(g_dm, cxt);
1644  ok(SUCCEEDED(hr),"Push Failed\n");
1645  ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
1646  sink_check_ok(&test_OnPushContext,"OnPushContext");
1647  sink_check_ok(&test_OnInitDocumentMgr,"OnInitDocumentMgr");
1648  sink_check_ok(&test_ACP_AdviseSink,"TextStoreACP_AdviseSink");
1649 
1650  test_EnumContexts(g_dm, cxt);
1651 
1652  hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
1653  ok(SUCCEEDED(hr),"GetTop Failed\n");
1654  ok(cxtTest == cxt, "Wrong context on top\n");
1655  ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
1656  cnt = ITfContext_Release(cxtTest);
1657 
1658  hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
1659  ok(SUCCEEDED(hr),"GetBase Failed\n");
1660  ok(cxtTest == cxt, "Wrong context on Base\n");
1661  ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
1662  ITfContext_Release(cxtTest);
1663 
1664  check_context_refcount(cxt2);
1666  hr = ITfDocumentMgr_Push(g_dm, cxt2);
1667  ok(SUCCEEDED(hr),"Push Failed\n");
1668  sink_check_ok(&test_OnPushContext,"OnPushContext");
1669 
1670  cnt = check_context_refcount(cxt2);
1671  hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
1672  ok(SUCCEEDED(hr),"GetTop Failed\n");
1673  ok(cxtTest == cxt2, "Wrong context on top\n");
1674  ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n");
1675  ITfContext_Release(cxtTest);
1676 
1677  cnt = check_context_refcount(cxt);
1678  hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
1679  ok(SUCCEEDED(hr),"GetBase Failed\n");
1680  ok(cxtTest == cxt, "Wrong context on Base\n");
1681  ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
1682  ITfContext_Release(cxtTest);
1683 
1684  cnt = check_context_refcount(cxt3);
1685  hr = ITfDocumentMgr_Push(g_dm, cxt3);
1686  ok(FAILED(hr),"Push Succeeded\n");
1687  ok(check_context_refcount(cxt3) == cnt, "Ref changed\n");
1688 
1689  cnt = check_context_refcount(cxt2);
1690  hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
1691  ok(SUCCEEDED(hr),"GetTop Failed\n");
1692  ok(cxtTest == cxt2, "Wrong context on top\n");
1693  ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n");
1694  ITfContext_Release(cxtTest);
1695 
1696  cnt = check_context_refcount(cxt);
1697  hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
1698  ok(SUCCEEDED(hr),"GetBase Failed\n");
1699  ok(cxtTest == cxt, "Wrong context on Base\n");
1700  ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
1701  ITfContext_Release(cxtTest);
1702 
1703  cnt = check_context_refcount(cxt2);
1705  hr = ITfDocumentMgr_Pop(g_dm, 0);
1706  ok(SUCCEEDED(hr),"Pop Failed\n");
1707  ok(check_context_refcount(cxt2) < cnt, "Ref count did not decrease\n");
1708  sink_check_ok(&test_OnPopContext,"OnPopContext");
1709 
1710  dmtest = (void *)0xfeedface;
1711  hr = ITfContext_GetDocumentMgr(cxt2,&dmtest);
1712  ok(hr == S_FALSE, "ITfContext_GetDocumentMgr wrong rc %x\n",hr);
1713  ok(dmtest == NULL,"returned documentmgr should be null\n");
1714 
1715  ITfContext_Release(cxt2);
1716 
1717  hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
1718  ok(SUCCEEDED(hr),"GetTop Failed\n");
1719  ok(cxtTest == cxt, "Wrong context on top\n");
1720  ITfContext_Release(cxtTest);
1721 
1722  hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
1723  ok(SUCCEEDED(hr),"GetBase Failed\n");
1724  ok(cxtTest == cxt, "Wrong context on base\n");
1725  ITfContext_Release(cxtTest);
1726 
1727  hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, (IUnknown*)ts, &cxt2, &editCookie);
1728  ok(hr == S_OK,"CreateContext Failed\n");
1729 
1732  hr = ITfDocumentMgr_Push(g_dm, cxt2);
1733  ok(hr == S_OK,"Push Failed\n");
1734  sink_check_ok(&test_OnPushContext,"OnPushContext");
1735  sink_check_ok(&test_ACP_AdviseSink,"TextStoreACP_AdviseSink");
1736 
1738  cnt = check_context_refcount(cxt2);
1740  hr = ITfDocumentMgr_Pop(g_dm, 0);
1741  ok(hr == S_OK,"Pop Failed\n");
1742  ok(check_context_refcount(cxt2) < cnt, "Ref count did not decrease\n");
1743  sink_check_ok(&test_OnPopContext,"OnPopContext");
1744  sink_check_ok(&test_ACP_UnadviseSink,"TextStoreACP_AdviseSink");
1745 
1746  hr = ITfDocumentMgr_Pop(g_dm, 0);
1747  ok(FAILED(hr),"Pop Succeeded\n");
1748 
1749  hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
1750  ok(SUCCEEDED(hr),"GetTop Failed\n");
1751  ok(cxtTest == cxt, "Wrong context on top\n");
1752  ITfContext_Release(cxtTest);
1753 
1754  hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
1755  ok(SUCCEEDED(hr),"GetBase Failed\n");
1756  ok(cxtTest == cxt, "Wrong context on base\n");
1757  ITfContext_Release(cxtTest);
1758 
1759  ITfContext_Release(cxt);
1760  ITfContext_Release(cxt2);
1761  ITfContext_Release(cxt3);
1762  ITextStoreACP_Release(ts);
1763 }
1764 
1765 static void test_endSession(void)
1766 {
1767  HRESULT hr;
1770  test_PrevFocus = g_dm;
1771  test_OnSetFocus = SINK_OPTIONAL; /* Doesn't fire on Win7 */
1772  hr = ITfThreadMgr_Deactivate(g_tm);
1773  ok(SUCCEEDED(hr),"Failed to Deactivate\n");
1774  sink_check_ok(&test_OnSetFocus,"OnSetFocus");
1776 }
1777 
1778 static void test_TfGuidAtom(void)
1779 {
1780  GUID gtest,g1;
1781  HRESULT hr;
1782  TfGuidAtom atom1,atom2;
1783  BOOL equal;
1784 
1785  CoCreateGuid(&gtest);
1786 
1787  /* msdn reports this should return E_INVALIDARG. However my test show it crashing (winxp)*/
1788  /*
1789  hr = ITfCategoryMgr_RegisterGUID(g_cm,&gtest,NULL);
1790  ok(hr==E_INVALIDARG,"ITfCategoryMgr_RegisterGUID should have failed\n");
1791  */
1792  hr = ITfCategoryMgr_RegisterGUID(g_cm,&gtest,&atom1);
1793  ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n");
1794  hr = ITfCategoryMgr_RegisterGUID(g_cm,&gtest,&atom2);
1795  ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n");
1796  ok(atom1 == atom2,"atoms do not match\n");
1797  hr = ITfCategoryMgr_GetGUID(g_cm,atom2,NULL);
1798  ok(hr==E_INVALIDARG,"ITfCategoryMgr_GetGUID should have failed\n");
1799  hr = ITfCategoryMgr_GetGUID(g_cm,atom2,&g1);
1800  ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n");
1801  ok(IsEqualGUID(&g1,&gtest),"guids do not match\n");
1802  hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,&gtest,NULL);
1803  ok(hr==E_INVALIDARG,"ITfCategoryMgr_IsEqualTfGuidAtom should have failed\n");
1804  hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,&gtest,&equal);
1805  ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n");
1806  ok(equal == TRUE,"Equal value invalid\n");
1807 
1808  /* show that cid and tid TfClientIds are also TfGuidAtoms */
1809  hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,tid,&CLSID_FakeService,&equal);
1810  ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n");
1811  ok(equal == TRUE,"Equal value invalid\n");
1812  hr = ITfCategoryMgr_GetGUID(g_cm,cid,&g1);
1813  ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n");
1814  ok(!IsEqualGUID(&g1,&GUID_NULL),"guid should not be NULL\n");
1815 }
1816 
1817 static void test_ClientId(void)
1818 {
1819  ITfClientId *pcid;
1820  TfClientId id1,id2;
1821  HRESULT hr;
1822  GUID g2;
1823 
1824  hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfClientId, (LPVOID*)&pcid);
1825  ok(SUCCEEDED(hr),"Unable to acquire ITfClientId interface\n");
1826 
1827  CoCreateGuid(&g2);
1828 
1829  hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id1);
1830  ok(SUCCEEDED(hr),"GetClientId failed\n");
1831  hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id2);
1832  ok(SUCCEEDED(hr),"GetClientId failed\n");
1833  ok(id1==id2,"Id's for GUID_NULL do not match\n");
1834  hr = ITfClientId_GetClientId(pcid,&CLSID_FakeService,&id2);
1835  ok(SUCCEEDED(hr),"GetClientId failed\n");
1836  ok(id2!=id1,"Id matches GUID_NULL\n");
1837  ok(id2==tid,"Id for CLSID_FakeService not matching tid\n");
1838  ok(id2!=cid,"Id for CLSID_FakeService matching cid\n");
1839  hr = ITfClientId_GetClientId(pcid,&g2,&id2);
1840  ok(SUCCEEDED(hr),"GetClientId failed\n");
1841  ok(id2!=id1,"Id matches GUID_NULL\n");
1842  ok(id2!=tid,"Id for random guid matching tid\n");
1843  ok(id2!=cid,"Id for random guid matching cid\n");
1844  ITfClientId_Release(pcid);
1845 }
1846 
1847 /**********************************************************************
1848  * ITfEditSession
1849  **********************************************************************/
1850 typedef struct tagEditSession
1851 {
1854 } EditSession;
1855 
1857 {
1858  return CONTAINING_RECORD(iface, EditSession, ITfEditSession_iface);
1859 }
1860 
1862 {
1864 }
1865 
1867 {
1868  *ppvOut = NULL;
1869 
1870  if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfEditSession))
1871  {
1872  *ppvOut = iface;
1873  }
1874 
1875  if (*ppvOut)
1876  {
1877  ITfEditSession_AddRef(iface);
1878  return S_OK;
1879  }
1880 
1881  return E_NOINTERFACE;
1882 }
1883 
1885 {
1887  return InterlockedIncrement(&This->refCount);
1888 }
1889 
1891 {
1893  ULONG ret;
1894 
1895  ret = InterlockedDecrement(&This->refCount);
1896  if (ret == 0)
1898  return ret;
1899 }
1900 
1902 {
1903  HRESULT hr;
1904  ITfInsertAtSelection *iis;
1905  ITfRange *range=NULL;
1906  static const WCHAR txt[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
1907 
1908  hr = ITfContext_QueryInterface(cxt, &IID_ITfInsertAtSelection , (LPVOID*)&iis);
1909  ok(SUCCEEDED(hr),"Failed to get ITfInsertAtSelection interface\n");
1911  hr = ITfInsertAtSelection_InsertTextAtSelection(iis, ec, 0, txt, 11, &range);
1912  ok(SUCCEEDED(hr),"ITfInsertAtSelection_InsertTextAtSelection failed %x\n",hr);
1913  sink_check_ok(&test_ACP_InsertTextAtSelection,"InsertTextAtSelection");
1914  ok(range != NULL,"No range returned\n");
1915  ITfRange_Release(range);
1916  ITfInsertAtSelection_Release(iis);
1917 }
1918 
1920 TfEditCookie ec)
1921 {
1922  ITfContext *cxt;
1923  ITfDocumentMgr *dm;
1924  ITfRange *range;
1925  TF_SELECTION selection;
1926  ULONG fetched;
1927  HRESULT hr;
1928 
1929  sink_fire_ok(&test_DoEditSession,"EditSession_DoEditSession");
1930  sink_check_ok(&test_ACP_RequestLock,"RequestLock");
1931 
1932  ITfThreadMgr_GetFocus(g_tm, &dm);
1933  ITfDocumentMgr_GetTop(dm,&cxt);
1934 
1935  hr = ITfContext_GetStart(cxt,ec,NULL);
1936  ok(hr == E_INVALIDARG,"Unexpected return code %x\n",hr);
1937 
1938  range = (ITfRange*)0xdeaddead;
1939  hr = ITfContext_GetStart(cxt,0xdeadcafe,&range);
1940  ok(hr == TF_E_NOLOCK,"Unexpected return code %x\n",hr);
1941  ok(range == NULL,"Range not set to NULL\n");
1942 
1943  hr = ITfContext_GetStart(cxt,ec,&range);
1944  ok(SUCCEEDED(hr),"Unexpected return code %x\n",hr);
1945  ok(range != NULL,"Range set to NULL\n");
1946 
1947  ITfRange_Release(range);
1948 
1949  hr = ITfContext_GetEnd(cxt,ec,NULL);
1950  ok(hr == E_INVALIDARG,"Unexpected return code %x\n",hr);
1951 
1952  range = (ITfRange*)0xdeaddead;
1953  hr = ITfContext_GetEnd(cxt,0xdeadcafe,&range);
1954  ok(hr == TF_E_NOLOCK,"Unexpected return code %x\n",hr);
1955  ok(range == NULL,"Range not set to NULL\n");
1956 
1958  hr = ITfContext_GetEnd(cxt,ec,&range);
1959  ok(SUCCEEDED(hr),"Unexpected return code %x\n",hr);
1960  ok(range != NULL,"Range set to NULL\n");
1961  sink_check_ok(&test_ACP_GetEndACP,"GetEndACP");
1962 
1963  ITfRange_Release(range);
1964 
1965  selection.range = NULL;
1967  hr = ITfContext_GetSelection(cxt, ec, TF_DEFAULT_SELECTION, 1, &selection, &fetched);
1968  ok(SUCCEEDED(hr),"ITfContext_GetSelection failed\n");
1969  ok(fetched == 1,"fetched incorrect\n");
1970  ok(selection.range != NULL,"NULL range\n");
1971  sink_check_ok(&test_ACP_GetSelection,"GetSelection");
1972  ITfRange_Release(selection.range);
1973 
1974  test_InsertAtSelection(ec, cxt);
1975 
1977  hr = ITfContext_GetEnd(cxt,ec,&range);
1978  ok(SUCCEEDED(hr),"Unexpected return code %x\n",hr);
1979  ok(range != NULL,"Range set to NULL\n");
1980  sink_check_ok(&test_ACP_GetEndACP,"GetEndACP");
1981 
1982  selection.range = range;
1983  selection.style.ase = TF_AE_NONE;
1984  selection.style.fInterimChar = FALSE;
1986  hr = ITfContext_SetSelection(cxt, ec, 1, &selection);
1987  ok(SUCCEEDED(hr),"ITfContext_SetSelection failed\n");
1988  sink_check_ok(&test_ACP_SetSelection,"SetSelection");
1989  ITfRange_Release(range);
1990 
1991  ITfContext_Release(cxt);
1992  ITfDocumentMgr_Release(dm);
1993  return 0xdeadcafe;
1994 }
1995 
1996 static const ITfEditSessionVtbl EditSession_EditSessionVtbl =
1997 {
2001 
2003 };
2004 
2006 {
2007  EditSession *This;
2008 
2009  *ppOut = NULL;
2011  if (This == NULL)
2012  return E_OUTOFMEMORY;
2013 
2014  This->ITfEditSession_iface.lpVtbl = &EditSession_EditSessionVtbl;
2015  This->refCount = 1;
2016 
2017  *ppOut = &This->ITfEditSession_iface;
2018  return S_OK;
2019 }
2020 
2021 static void test_TStoApplicationText(void)
2022 {
2023  HRESULT hr, hrSession;
2024  ITfEditSession *es;
2025  ITfContext *cxt;
2026  ITfDocumentMgr *dm;
2028  ITfSource *source = NULL;
2029  DWORD editSinkCookie = -1;
2030 
2031  ITfThreadMgr_GetFocus(g_tm, &dm);
2033  ITfDocumentMgr_GetTop(dm,&cxt);
2034 
2036  hr = ITfContext_QueryInterface(cxt,&IID_ITfSource,(LPVOID*)&source);
2037  ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for Context\n");
2038  if (source)
2039  {
2040  hr = ITfSource_AdviseSink(source, &IID_ITfTextEditSink, (LPVOID)sink, &editSinkCookie);
2041  ok(SUCCEEDED(hr),"Failed to advise Sink\n");
2042  ok(editSinkCookie != -1,"Failed to get sink cookie\n");
2043  }
2044 
2045  hrSession = 0xfeedface;
2046  /* Test no permissions flags */
2047  hr = ITfContext_RequestEditSession(cxt, tid, es, TF_ES_SYNC, &hrSession);
2048  ok(hr == E_INVALIDARG,"RequestEditSession should have failed with %x not %x\n",E_INVALIDARG,hr);
2049  ok(hrSession == E_FAIL,"hrSession should be %x not %x\n",E_FAIL,hrSession);
2050 
2052  hrSession = 0xfeedface;
2054  hr = ITfContext_RequestEditSession(cxt, tid, es, TF_ES_SYNC|TF_ES_READWRITE, &hrSession);
2055  ok(SUCCEEDED(hr),"ITfContext_RequestEditSession failed\n");
2056  ok(hrSession == TS_E_READONLY,"Unexpected hrSession (%x)\n",hrSession);
2057  sink_check_ok(&test_ACP_GetStatus,"GetStatus");
2058 
2059  /* signal a change to allow readwrite sessions */
2060  documentStatus = 0;
2062  ITextStoreACPSink_OnStatusChange(ACPSink,documentStatus);
2063  sink_check_ok(&test_ACP_RequestLock,"RequestLock");
2064 
2068  hrSession = 0xfeedface;
2070  hr = ITfContext_RequestEditSession(cxt, tid, es, TF_ES_SYNC|TF_ES_READWRITE, &hrSession);
2071  ok(SUCCEEDED(hr),"ITfContext_RequestEditSession failed\n");
2072  sink_check_ok(&test_OnEndEdit,"OnEndEdit");
2073  sink_check_ok(&test_DoEditSession,"DoEditSession");
2074  sink_check_ok(&test_ACP_GetStatus,"GetStatus");
2075  ok(hrSession == 0xdeadcafe,"Unexpected hrSession (%x)\n",hrSession);
2076 
2077  if (source)
2078  {
2079  hr = ITfSource_UnadviseSink(source, editSinkCookie);
2080  ok(SUCCEEDED(hr),"Failed to unadvise Sink\n");
2081  ITfSource_Release(source);
2082  }
2083  ITfTextEditSink_Release(sink);
2084  ITfContext_Release(cxt);
2085  ITfDocumentMgr_Release(dm);
2086  ITfEditSession_Release(es);
2087 }
2088 
2089 static void enum_compartments(ITfCompartmentMgr *cmpmgr, REFGUID present, REFGUID absent)
2090 {
2091  BOOL found,found2;
2092  IEnumGUID *ppEnum;
2093  found = FALSE;
2094  found2 = FALSE;
2095  if (SUCCEEDED(ITfCompartmentMgr_EnumCompartments(cmpmgr, &ppEnum)))
2096  {
2097  ULONG fetched;
2098  GUID g;
2099  while (IEnumGUID_Next(ppEnum, 1, &g, &fetched) == S_OK)
2100  {
2101  WCHAR str[50];
2102  CHAR strA[50];
2104  WideCharToMultiByte(CP_ACP,0,str,-1,strA,sizeof(strA),0,0);
2105  trace("found %s\n",strA);
2106  if (present && IsEqualGUID(present,&g))
2107  found = TRUE;
2108  if (absent && IsEqualGUID(absent, &g))
2109  found2 = TRUE;
2110  }
2111  IEnumGUID_Release(ppEnum);
2112  }
2113  if (present)
2114  ok(found,"Did not find compartment\n");
2115  if (absent)
2116  ok(!found2,"Found compartment that should be absent\n");
2117 }
2118 
2119 static void test_Compartments(void)
2120 {
2121  ITfContext *cxt;
2122  ITfDocumentMgr *dm;
2123  ITfCompartmentMgr *cmpmgr;
2125  HRESULT hr;
2126 
2127  ITfThreadMgr_GetFocus(g_tm, &dm);
2128  ITfDocumentMgr_GetTop(dm,&cxt);
2129 
2130  /* Global */
2131  hr = ITfThreadMgr_GetGlobalCompartment(g_tm, &cmpmgr);
2132  ok(SUCCEEDED(hr),"GetGlobalCompartment failed\n");
2133  hr = ITfCompartmentMgr_GetCompartment(cmpmgr, &GUID_COMPARTMENT_SPEECH_OPENCLOSE, &cmp);
2134  ok(SUCCEEDED(hr),"GetCompartment failed\n");
2135  ITfCompartment_Release(cmp);
2137  ITfCompartmentMgr_Release(cmpmgr);
2138 
2139  /* Thread */
2140  hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfCompartmentMgr, (LPVOID*)&cmpmgr);
2141  ok(SUCCEEDED(hr),"ThreadMgr QI for IID_ITfCompartmentMgr failed\n");
2142  hr = ITfCompartmentMgr_GetCompartment(cmpmgr, &CLSID_FakeService, &cmp);
2143  ok(SUCCEEDED(hr),"GetCompartment failed\n");
2144  enum_compartments(cmpmgr,&CLSID_FakeService,&GUID_COMPARTMENT_SPEECH_OPENCLOSE);
2145  ITfCompartmentMgr_ClearCompartment(cmpmgr,tid,&CLSID_FakeService);
2146  enum_compartments(cmpmgr,NULL,&CLSID_FakeService);
2147  ITfCompartmentMgr_Release(cmpmgr);
2148  ITfCompartment_Release(cmp);
2149 
2150  /* DocumentMgr */
2151  hr = ITfDocumentMgr_QueryInterface(dm, &IID_ITfCompartmentMgr, (LPVOID*)&cmpmgr);
2152  ok(SUCCEEDED(hr),"DocumentMgr QI for IID_ITfCompartmentMgr failed\n");
2153 
2154  hr = ITfCompartmentMgr_GetCompartment(cmpmgr, &GUID_COMPARTMENT_PERSISTMENUENABLED, &cmp);
2155  ok(SUCCEEDED(hr),"GetCompartment failed\n");
2157  ITfCompartmentMgr_Release(cmpmgr);
2158 
2159  /* Context */
2160  hr = ITfContext_QueryInterface(cxt, &IID_ITfCompartmentMgr, (LPVOID*)&cmpmgr);
2161  ok(SUCCEEDED(hr),"Context QI for IID_ITfCompartmentMgr failed\n");
2163  ITfCompartmentMgr_Release(cmpmgr);
2164 
2165  ITfContext_Release(cxt);
2166  ITfDocumentMgr_Release(dm);
2167 }
2168 
2169 static void processPendingMessages(void)
2170 {
2171  MSG msg;
2172  int diff = 200;
2173  int min_timeout = 100;
2174  DWORD time = GetTickCount() + diff;
2175 
2176  while (diff > 0)
2177  {
2178  if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT)
2179  break;
2180  while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE))
2181  {
2184  }
2185  diff = time - GetTickCount();
2186  }
2187 }
2188 
2189 static void test_AssociateFocus(void)
2190 {
2191  ITfDocumentMgr *dm1, *dm2, *olddm, *dmcheck, *dmorig;
2192  HWND wnd1, wnd2, wnd3;
2193  HRESULT hr;
2194 
2195  ITfThreadMgr_GetFocus(g_tm, &dmorig);
2197  test_PrevFocus = dmorig;
2198  test_OnSetFocus = SINK_OPTIONAL; /* Doesn't always fire on Win7 */
2200  hr = ITfThreadMgr_SetFocus(g_tm,NULL);
2201  ok(SUCCEEDED(hr),"ITfThreadMgr_SetFocus failed\n");
2202  sink_check_ok(&test_OnSetFocus,"OnSetFocus");
2204  ITfDocumentMgr_Release(dmorig);
2205 
2206  hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&dm1);
2207  ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n");
2208 
2209  hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&dm2);
2210  ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n");
2211 
2212  wnd1 = CreateWindowA("edit",NULL,WS_POPUP,0,0,200,60,NULL,NULL,NULL,NULL);
2213  ok(wnd1!=NULL,"Unable to create window 1\n");
2214  wnd2 = CreateWindowA("edit",NULL,WS_POPUP,0,65,200,60,NULL,NULL,NULL,NULL);
2215  ok(wnd2!=NULL,"Unable to create window 2\n");
2216  wnd3 = CreateWindowA("edit",NULL,WS_POPUP,0,130,200,60,NULL,NULL,NULL,NULL);
2217  ok(wnd3!=NULL,"Unable to create window 3\n");
2218 
2220 
2221  test_OnInitDocumentMgr = SINK_OPTIONAL; /* Vista and greater */
2222  test_OnPushContext = SINK_OPTIONAL; /* Vista and greater */
2223  test_OnSetFocus = SINK_OPTIONAL; /* Win7 */
2224  test_PrevFocus = NULL;
2226 
2227  ShowWindow(wnd1,SW_SHOWNORMAL);
2229  SetFocus(wnd1);
2230  sink_check_ok(&test_OnInitDocumentMgr,"OnInitDocumentMgr");
2231  sink_check_ok(&test_OnPushContext,"OnPushContext");
2232 
2233  test_OnSetFocus = SINK_OPTIONAL; /* Vista and greater */
2234  test_ACP_RequestLock = SINK_OPTIONAL; /* Win7 x64 */
2235  test_ACP_GetSelection = SINK_OPTIONAL; /* Win7 x64 */
2236  ITfThreadMgr_GetFocus(g_tm, &test_PrevFocus);
2237  test_CurrentFocus = FOCUS_IGNORE; /* This is a default system context */
2239  sink_check_ok(&test_OnSetFocus,"OnSetFocus");
2242 
2243  test_CurrentFocus = dm1;
2247  hr = ITfThreadMgr_AssociateFocus(g_tm,wnd1,dm1,&olddm);
2248  ok(SUCCEEDED(hr),"AssociateFocus failed\n");
2249  sink_check_ok(&test_OnSetFocus,"OnSetFocus");
2251 
2253 
2254  ITfThreadMgr_GetFocus(g_tm, &dmcheck);
2255  ok(dmcheck == dm1 || broken(dmcheck == dmorig /* Win7+ */), "Expected DocumentMgr not focused\n");
2256  ITfDocumentMgr_Release(dmcheck);
2257 
2258  /* We need to explicitly set focus on Win7+ */
2259  test_CurrentFocus = dm1;
2261  test_OnSetFocus = SINK_OPTIONAL; /* Doesn't always fire on Win7+ */
2262  ITfThreadMgr_SetFocus(g_tm, dm1);
2263  sink_check_ok(&test_OnSetFocus, "OnSetFocus");
2264 
2265  hr = ITfThreadMgr_AssociateFocus(g_tm,wnd2,dm2,&olddm);
2266  ok(SUCCEEDED(hr),"AssociateFocus failed\n");
2268  ITfThreadMgr_GetFocus(g_tm, &dmcheck);
2269  ok(dmcheck == dm1, "Expected DocumentMgr not focused\n");
2270  ITfDocumentMgr_Release(dmcheck);
2271 
2272  hr = ITfThreadMgr_AssociateFocus(g_tm,wnd3,dm2,&olddm);
2273  ok(SUCCEEDED(hr),"AssociateFocus failed\n");
2275  ITfThreadMgr_GetFocus(g_tm, &dmcheck);
2276  ok(dmcheck == dm1, "Expected DocumentMgr not focused\n");
2277  ITfDocumentMgr_Release(dmcheck);
2278 
2282  test_ShouldDeactivate = TRUE; /* win 8/10 */
2283  ShowWindow(wnd2,SW_SHOWNORMAL);
2284  SetFocus(wnd2);
2285  sink_check_saved(&test_OnSetFocus,dm1,dm2,"OnSetFocus");
2286  test_CurrentFocus = FOCUS_IGNORE; /* occasional wine race */
2287  test_PrevFocus = FOCUS_IGNORE; /* occasional wine race */
2288  test_OnSetFocus = SINK_IGNORE; /* occasional wine race */
2291 
2292  ShowWindow(wnd3,SW_SHOWNORMAL);
2293  SetFocus(wnd3);
2295 
2299  SetFocus(wnd1);
2301  sink_check_saved(&test_OnSetFocus,dm2,dm1,"OnSetFocus");
2302 
2303  hr = ITfThreadMgr_AssociateFocus(g_tm,wnd3,NULL,&olddm);
2304  ok(SUCCEEDED(hr),"AssociateFocus failed\n");
2305  ok(olddm == dm2, "incorrect old DocumentMgr returned\n");
2306  ITfDocumentMgr_Release(olddm);
2307 
2308  test_CurrentFocus = dmorig;
2309  test_PrevFocus = dm1;
2310  test_OnSetFocus = SINK_OPTIONAL; /* Doesn't always fire on Win7+ */
2312  ITfThreadMgr_SetFocus(g_tm,dmorig);
2313  sink_check_ok(&test_OnSetFocus,"OnSetFocus");
2314 
2318  SetFocus(wnd3);
2320  sink_check_saved(&test_OnSetFocus,dmorig,FOCUS_IGNORE,"OnSetFocus"); /* CurrentFocus NULL on XP, system default on Vista */
2321 
2322  hr = ITfThreadMgr_AssociateFocus(g_tm,wnd2,NULL,&olddm);
2323  ok(SUCCEEDED(hr),"AssociateFocus failed\n");
2324  ok(olddm == dm2, "incorrect old DocumentMgr returned\n");
2325  ITfDocumentMgr_Release(olddm);
2326  hr = ITfThreadMgr_AssociateFocus(g_tm,wnd1,NULL,&olddm);
2327  ok(SUCCEEDED(hr),"AssociateFocus failed\n");
2328  ok(olddm == dm1, "incorrect old DocumentMgr returned\n");
2329  ITfDocumentMgr_Release(olddm);
2330 
2331  test_OnSetFocus = SINK_IGNORE; /* OnSetFocus fires a couple of times on Win7 */
2334  SetFocus(wnd2);
2336  SetFocus(wnd1);
2339 
2340  ITfDocumentMgr_Release(dm1);
2341  ITfDocumentMgr_Release(dm2);
2342 
2343  test_CurrentFocus = dmorig;
2347  ITfThreadMgr_SetFocus(g_tm,dmorig);
2348  sink_check_ok(&test_OnSetFocus,"OnSetFocus");
2349 
2350  test_OnSetFocus = SINK_IGNORE; /* OnSetFocus fires a couple of times on Win7 */
2353  DestroyWindow(wnd1);
2354  DestroyWindow(wnd2);
2355  test_OnPopContext = SINK_OPTIONAL; /* Vista and greater */
2356  test_OnSetFocus = SINK_OPTIONAL; /* Vista and greater */
2357  ITfThreadMgr_GetFocus(g_tm, &test_PrevFocus);
2359  test_ShouldDeactivate = TRUE; /* Win7 */
2360  DestroyWindow(wnd3);
2362  sink_check_ok(&test_OnSetFocus,"OnSetFocus");
2363  sink_check_ok(&test_OnPopContext,"OnPopContext");
2364 }
2365 
2366 static void test_profile_mgr(void)
2367 {
2368  IEnumTfInputProcessorProfiles *enum_profiles;
2369  ITfInputProcessorProfileMgr *ipp_mgr;
2370  HRESULT hres;
2371 
2372  hres = ITfInputProcessorProfiles_QueryInterface(g_ipp, &IID_ITfInputProcessorProfileMgr, (void**)&ipp_mgr);
2373  if (hres != S_OK)
2374  {
2375  win_skip("ITfInputProcessorProfileMgr is not supported.\n");
2376  return;
2377  }
2378  ok(hres == S_OK, "Could not get ITfInputProcessorProfileMgr iface: %08x\n", hres);
2379 
2380  hres = ITfInputProcessorProfileMgr_EnumProfiles(ipp_mgr, 0, &enum_profiles);
2381  ok(hres == S_OK, "EnumProfiles failed: %08x\n", hres);
2382 
2383  IEnumTfInputProcessorProfiles_Release(enum_profiles);
2384 
2385  ITfInputProcessorProfileMgr_Release(ipp_mgr);
2386 }
2387 
2388 START_TEST(inputprocessor)
2389 {
2390  if (SUCCEEDED(initialize()))
2391  {
2392  test_Register();
2394  Sleep(2000); /* Win7 needs some time before the registrations become active */
2398  test_Enable();
2400  test_Activate();
2403  test_TfGuidAtom();
2404  test_ClientId();
2409  test_endSession();
2411  test_Disable();
2415  test_Unregister();
2416  test_profile_mgr();
2417 
2418  ITextStoreACPSink_Release(ACPSink);
2419  ITfDocumentMgr_Release(g_dm);
2420  }
2421  else
2422  skip("Unable to create InputProcessor\n");
2423  cleanup();
2424 }
TS_SELECTIONSTYLE style
Definition: textstor.idl:94
static void ClassFactory_Destructor(ClassFactory *This)
static IClassFactory * cf
static HRESULT WINAPI TfKeyTraceEventSink_OnKeyTraceDown(ITfKeyTraceEventSink *iface, WPARAM wparam, LPARAM lparam)
static ITfCategoryMgr * g_cm
static ULONG WINAPI TfKeyTraceEventSink_Release(ITfKeyTraceEventSink *iface)
static short search(int val, const short *table, int size)
Definition: msg711.c:255
static HRESULT WINAPI TextStoreACP_SetText(ITextStoreACP *iface, DWORD dwFlags, LONG acpStart, LONG acpEnd, const WCHAR *pchText, ULONG cch, TS_TEXTCHANGE *pChange)
static void enum_compartments(ITfCompartmentMgr *cmpmgr, REFGUID present, REFGUID absent)
static void TextStoreACP_Destructor(TextStoreACP *This)
#define HRESULT
Definition: msvc.h:9
struct tagKeyEventSink KeyEventSink
char strA[12]
Definition: clipboard.c:2028
DWORD dwDynamicFlags
Definition: textstor.idl:73
BOOL WINAPI TranslateMessage(_In_ const MSG *)
START_TEST(inputprocessor)
static HRESULT WINAPI TfKeyTraceEventSink_QueryInterface(ITfKeyTraceEventSink *iface, REFIID riid, void **ppv)
static void processPendingMessages(void)
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
ITextStoreACP ITextStoreACP_iface
#define E_NOINTERFACE
Definition: winerror.h:2364
static void test_ThreadMgrUnadviseSinks(void)
static HRESULT WINAPI TextService_QueryInterface(ITfTextInputProcessor *iface, REFIID iid, LPVOID *ppvOut)
static INT test_OnPopContext
#define ERROR_SUCCESS
Definition: deptool.c:10
static void test_EnumInputProcessorInfo(void)
#define WideCharToMultiByte
Definition: compat.h:101
static INT test_OnEndEdit
HRESULT hr
Definition: shlfolder.c:183
Definition: scsiwmi.h:51
static INT test_ACP_SetSelection
static void TextEditSink_Destructor(TextEditSink *This)
#define CONNECT_E_ADVISELIMIT
Definition: olectl.h:252
static HRESULT WINAPI TextStoreACP_GetEmbedded(ITextStoreACP *iface, LONG acpPos, REFGUID rguidService, REFIID riid, IUnknown **ppunk)
EXTERN_C const GUID GUID_COMPARTMENT_KEYBOARD_OPENCLOSE
Definition: msctf.idl:52
static void test_RegisterCategory(void)
static HRESULT WINAPI TextStoreACP_RequestSupportedAttrs(ITextStoreACP *iface, DWORD dwFlags, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs)
static HRESULT WINAPI TextStoreACP_GetEndACP(ITextStoreACP *iface, LONG *pacp)
DWORD TfEditCookie
Definition: msctf.idl:67
static HRESULT WINAPI TextStoreACP_SetSelection(ITextStoreACP *iface, ULONG ulCount, const TS_SELECTION_ACP *pSelection)
#define KEY_READ
Definition: nt_native.h:1023
static ThreadMgrEventSink * impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
static HRESULT WINAPI KeyEventSink_OnSetFocus(ITfKeyEventSink *iface, BOOL fForeground)
REFIID riid
Definition: precomp.h:44
EXTERN_C const GUID GUID_TFCAT_TIP_SPEECH
Definition: msctf.idl:63
#define REFCLSID
Definition: guiddef.h:117
#define CP_ACP
Definition: compat.h:99
static void test_DocumentMgrUnadviseSinks(void)
GLuint GLuint GLsizei count
Definition: gl.h:1545
static DWORD key_trace_sink_cookie
char CHAR
Definition: xmlstorage.h:175
static const ITfKeyEventSinkVtbl KeyEventSink_KeyEventSinkVtbl
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
static HRESULT WINAPI TextService_Deactivate(ITfTextInputProcessor *iface)
LPFNCONSTRUCTOR ctor
Definition: msctf.c:99
static HRESULT WINAPI ThreadMgrEventSink_OnPopContext(ITfThreadMgrEventSink *iface, ITfContext *pic)
#define CONNECT_E_NOCONNECTION
Definition: olectl.h:251
static ULONG WINAPI EditSession_Release(ITfEditSession *iface)
ITfTextInputProcessor ITfTextInputProcessor_iface
DEFINE_GUID(CLSID_FakeService, 0xEDE1A7AD, 0x66DE, 0x47E0, 0xB6, 0x20, 0x3E, 0x92, 0xF8, 0x24, 0x6B, 0xF3)
static TextEditSink * impl_from_ITfTextEditSink(ITfTextEditSink *iface)
static KeyEventSink * impl_from_ITfKeyEventSink(ITfKeyEventSink *iface)
static EditSession * impl_from_ITfEditSession(ITfEditSession *iface)
#define equal(x, y)
Definition: reader.cc:56
static HRESULT WINAPI TextStoreACP_RequestAttrsTransitioningAtPosition(ITextStoreACP *iface, LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags)
REFIID LPVOID * ppv
Definition: atlbase.h:39
EXTERN_C const GUID GUID_COMPARTMENT_SPEECH_OPENCLOSE
Definition: msctf.idl:55
static ULONG WINAPI KeyEventSink_Release(ITfKeyEventSink *iface)
BOOL todo
Definition: filedlg.c:313
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
static const ITfTransitoryExtensionSinkVtbl TfTransitoryExtensionSinkVtbl
struct tagClassFactory ClassFactory
static ITfTransitoryExtensionSink TfTransitoryExtensionSink
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3331
static void EditSession_Destructor(EditSession *This)
HWND WINAPI SetFocus(_In_opt_ HWND)
static HRESULT WINAPI EditSession_DoEditSession(ITfEditSession *iface, TfEditCookie ec)
static void ThreadMgrEventSink_Destructor(ThreadMgrEventSink *This)
static const ITfTextEditSinkVtbl TextEditSink_TextEditSinkVtbl
#define test
Definition: rosglue.h:37
UINT_PTR WPARAM
Definition: windef.h:207
WORD LANGID
Definition: typedefs.h:79
#define SINK_UNEXPECTED
static HRESULT WINAPI TextStoreACP_GetSelection(ITextStoreACP *iface, ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched)
int winetest_interactive
static HRESULT WINAPI TextEditSink_QueryInterface(ITfTextEditSink *iface, REFIID iid, LPVOID *ppvOut)
__u16 time
Definition: mkdosfs.c:366
static ULONG WINAPI TfTransitoryExtensionSink_Release(ITfTransitoryExtensionSink *iface)
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define cmp(status, error)
Definition: error.c:114
static HRESULT WINAPI KeyEventSink_OnKeyUp(ITfKeyEventSink *iface, ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
static ULONG WINAPI TfTransitoryExtensionSink_AddRef(ITfTransitoryExtensionSink *iface)
struct tagTextService TextService
static HRESULT KeyEventSink_Constructor(ITfKeyEventSink **ppOut)
LPFNCONSTRUCTOR ctor
Definition: msctf.c:85
#define E_FAIL
Definition: ddrawi.h:102
BOOL WINAPI DestroyWindow(_In_ HWND)
int32_t INT
Definition: typedefs.h:56
DWORD TsViewCookie
Definition: textstor.idl:111
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glext.h:7750
static BOOL test_ShouldDeactivate
static INT test_KEV_OnSetFocus
static void test_EnumLanguageProfiles(void)
WPARAM wParam
Definition: combotst.c:138
int selection
Definition: ctm.c:92
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
static HRESULT WINAPI TextStoreACP_GetText(ITextStoreACP *iface, LONG acpStart, LONG acpEnd, WCHAR *pchPlain, ULONG cchPlainReq, ULONG *pcchPlainRet, TS_RUNINFO *prgRunInfo, ULONG cRunInfoReq, ULONG *pcRunInfoRet, LONG *pacpNext)
static DWORD tmSinkCookie
static void KeyEventSink_Destructor(KeyEventSink *This)
static ULONG WINAPI TextStoreACP_Release(ITextStoreACP *iface)
static HRESULT WINAPI TextStoreACP_GetScreenExt(ITextStoreACP *iface, TsViewCookie vcView, RECT *prc)
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
#define SINK_SAVE
UINT uModifiers
Definition: msctf.idl:129
EXTERN_C const CLSID CLSID_TF_CategoryMgr
Definition: msctf.idl:47
static ITextStoreACPSink * ACPSink
static HRESULT WINAPI TextStoreACP_UnadviseSink(ITextStoreACP *iface, IUnknown *punk)
static void _sink_fire_ok(INT *sink, const CHAR *name)
static void test_TfGuidAtom(void)
static TfClientId cid
static const ITfTextInputProcessorVtbl TextService_TextInputProcessorVtbl
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static void test_Disable(void)
#define SINK_OPTIONAL
static HRESULT WINAPI TextService_Activate(ITfTextInputProcessor *iface, ITfThreadMgr *ptim, TfClientId id)
static void TextService_Destructor(TextService *This)
static UINT WPARAM LPARAM lparam
Definition: combo.c:716
EXTERN_C const GUID GUID_TFCAT_TIP_HANDWRITING
Definition: msctf.idl:64
static ULONG WINAPI EditSession_AddRef(ITfEditSession *iface)
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4216
static const IClassFactoryVtbl ClassFactoryVtbl
#define S_FALSE
Definition: winerror.h:2357
static HRESULT WINAPI ThreadMgrEventSink_OnPushContext(ITfThreadMgrEventSink *iface, ITfContext *pic)
static ITfDocumentMgr * test_LastCurrentFocus
static INT test_OnPushContext
#define E_INVALIDARG
Definition: ddrawi.h:101
static HRESULT TextEditSink_Constructor(ITfTextEditSink **ppOut)
const WCHAR * str
static void test_Enable(void)
static const char * ts(int t)
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:201
static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
static BOOL test_ShouldActivate
ITfThreadMgrEventSink ITfThreadMgrEventSink_iface
smooth NULL
Definition: ftsmooth.c:416
static HRESULT WINAPI ThreadMgrEventSink_OnInitDocumentMgr(ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim)
static void test_InsertAtSelection(TfEditCookie ec, ITfContext *cxt)
static HRESULT WINAPI TfTransitoryExtensionSink_QueryInterface(ITfTransitoryExtensionSink *iface, REFIID riid, void **ppv)
static INT test_ACP_AdviseSink
EXTERN_C const GUID GUID_COMPARTMENT_HANDWRITING_OPENCLOSE
Definition: msctf.idl:53
LONG_PTR LPARAM
Definition: windef.h:208
static HRESULT UnregisterTextService(void)
static HRESULT WINAPI ThreadMgrEventSink_OnSetFocus(ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus)
static void test_ClientId(void)
struct tagEditSession EditSession
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
EXTERN_C const CLSID CLSID_TF_InputProcessorProfiles
Definition: msctf.idl:45
#define SINK_FIRED
HRESULT WINAPI DECLSPEC_HOTPATCH CoRevokeClassObject(DWORD dwRegister)
Definition: compobj.c:1089
static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
LONG ref
Definition: msctf.c:98
static void cleanup(void)
static void test_TStoApplicationText(void)
static HRESULT WINAPI TextStoreACP_RetrieveRequestedAttrs(ITextStoreACP *iface, ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched)
static HRESULT WINAPI TextStoreACP_QueryInsert(ITextStoreACP *iface, LONG acpTestStart, LONG acpTestEnd, ULONG cch, LONG *pacpResultStart, LONG *pacpResultEnd)
static int check_context_refcount(ITfContext *iface)
static const ITextStoreACPVtbl TextStoreACP_TextStoreACPVtbl
#define KEY_WRITE
Definition: nt_native.h:1031
#define SINK_EXPECTED
static TextStoreACP * impl_from_ITextStoreACP(ITextStoreACP *iface)
#define todo_wine_if(is_todo)
Definition: test.h:155
static void _sink_check_saved(INT *sink, ITfDocumentMgr *PrevFocus, ITfDocumentMgr *CurrentFocus, const CHAR *name)
EXTERN_C const GUID GUID_COMPARTMENT_TIPUISTATUS
Definition: msctf.idl:59
GLboolean GLboolean g
Definition: glext.h:6204
static ITfDocumentMgr * test_CurrentFocus
void __winetest_cdecl winetest_trace(const char *msg,...)
static ITfKeyTraceEventSink TfKeyTraceEventSink
#define sink_check_saved(s, p, c, n)
HRESULT hres
Definition: protocol.c:465
static ITfThreadMgr * g_tm
static INT test_ACP_GetStatus
#define GetProcessHeap()
Definition: compat.h:395
static INT test_OnInitDocumentMgr
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static HRESULT ThreadMgrEventSink_Constructor(IUnknown **ppOut)
__wchar_t WCHAR
Definition: xmlstorage.h:180
void __winetest_cdecl winetest_ok(int condition, const char *msg,...)
#define SINK_OPTION_TODO
LONG HRESULT
Definition: typedefs.h:77
IClassFactory IClassFactory_iface
Definition: msctf.c:97
static HRESULT WINAPI TextStoreACP_InsertTextAtSelection(ITextStoreACP *iface, DWORD dwFlags, const WCHAR *pchText, ULONG cch, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange)
const GUID IID_IUnknown
static HRESULT WINAPI TextStoreACP_GetWnd(ITextStoreACP *iface, TsViewCookie vcView, HWND *phwnd)
struct tagThreadMgrEventSink ThreadMgrEventSink
#define SINK_EXPECTED_COUNT_MASK
#define WINAPI
Definition: msvc.h:8
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2343
static INT test_ACP_GetEndACP
static ULONG WINAPI KeyEventSink_AddRef(ITfKeyEventSink *iface)
static void test_Register(void)
EXTERN_C const CLSID CLSID_TF_ThreadMgr
Definition: msctf.idl:44
static const ITfEditSessionVtbl EditSession_EditSessionVtbl
#define sink_fire_ok(a, b)
static HRESULT WINAPI TextStoreACP_InsertEmbedded(ITextStoreACP *iface, DWORD dwFlags, LONG acpStart, LONG acpEnd, IDataObject *pDataObject, TS_TEXTCHANGE *pChange)
unsigned long DWORD
Definition: ntddk_ex.h:95
static void test_endSession(void)
static ULONG WINAPI TextService_Release(ITfTextInputProcessor *iface)
static void test_Unregister(void)
static HRESULT WINAPI KeyEventSink_OnTestKeyDown(ITfKeyEventSink *iface, ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
static HRESULT WINAPI TextStoreACP_FindNextAttrTransition(ITextStoreACP *iface, LONG acpStart, LONG acpHalt, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags, LONG *pacpNext, BOOL *pfFound, LONG *plFoundOffset)
static HRESULT RegisterTextService(REFCLSID rclsid)
static INT test_OnSetFocus
static HRESULT WINAPI TextStoreACP_GetFormattedText(ITextStoreACP *iface, LONG acpStart, LONG acpEnd, IDataObject **ppDataObject)
static void test_Compartments(void)
#define WAIT_TIMEOUT
Definition: dderror.h:14
static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
EXTERN_C const GUID GUID_COMPARTMENT_SPEECH_DISABLED
Definition: msctf.idl:54
static ULONG WINAPI TextEditSink_Release(ITfTextEditSink *iface)
HRESULT WINAPI CoCreateGuid(GUID *pguid)
Definition: compobj.c:2115
static INT test_ACP_GetSelection
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
static const ITfThreadMgrEventSinkVtbl ThreadMgrEventSink_ThreadMgrEventSinkVtbl
static INT test_DoEditSession
static ULONG WINAPI TextStoreACP_AddRef(ITextStoreACP *iface)
static HRESULT WINAPI KeyEventSink_QueryInterface(ITfKeyEventSink *iface, REFIID iid, LPVOID *ppvOut)
int ret
static TextService * impl_from_ITfTextInputProcessor(ITfTextInputProcessor *iface)
#define InterlockedDecrement
Definition: armddk.h:52
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static HRESULT ClassFactory_Constructor(LPFNCONSTRUCTOR ctor, LPVOID *ppvOut)
static void test_FindClosestCategory(void)
static HRESULT WINAPI TextStoreACP_QueryInterface(ITextStoreACP *iface, REFIID iid, LPVOID *ppvOut)
#define FOCUS_IGNORE
static ULONG WINAPI TextEditSink_AddRef(ITfTextEditSink *iface)
static INT test_ACP_UnadviseSink
#define GUID_NULL
Definition: ks.h:106
Definition: _list.h:228
static void test_EnumDocumentMgr(ITfThreadMgr *tm, ITfDocumentMgr *search, ITfDocumentMgr *absent)
EXTERN_C const GUID GUID_COMPARTMENT_EMPTYCONTEXT
Definition: msctf.idl:58
Definition: time.h:76
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
EXTERN_C const GUID GUID_COMPARTMENT_PERSISTMENUENABLED
Definition: msctf.idl:57
static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
static HRESULT WINAPI TfTransitoryExtensionSink_OnTransitoryExtensionUpdated(ITfTransitoryExtensionSink *iface, ITfContext *pic, TfEditCookie ecReadOnly, ITfRange *pResultRange, ITfRange *pCompositionRange, BOOL *pfDeleteResultRange)
static void test_KeystrokeMgr(void)
static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface)
DWORD TfGuidAtom
Definition: msctf.idl:69
#define broken(x)
Definition: _sntprintf.h:21
static HRESULT WINAPI KeyEventSink_OnTestKeyUp(ITfKeyEventSink *iface, ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
GLenum GLint * range
Definition: glext.h:7539
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3234
static HRESULT EditSession_Constructor(ITfEditSession **ppOut)
static HRESULT TextService_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
HRESULT WINAPI CoRegisterClassObject(REFCLSID rclsid, LPUNKNOWN pUnk, DWORD dwClsContext, DWORD flags, LPDWORD lpdwRegister)
Definition: compobj.c:2806
#define SINK_ACTION_MASK
ULONG ulIndex
Definition: symbols.c:92
static HRESULT WINAPI TextEditSink_OnEndEdit(ITfTextEditSink *iface, ITfContext *pic, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord)
#define S_OK
Definition: intsafe.h:59
static const ITfKeyTraceEventSinkVtbl TfKeyTraceEventSinkVtbl
#define SW_SHOWNORMAL
Definition: winuser.h:764
static ULONG WINAPI TfKeyTraceEventSink_AddRef(ITfKeyTraceEventSink *iface)
static DWORD tmSinkRefCount
const WCHAR * action
Definition: action.c:7783
#define InterlockedIncrement
Definition: armddk.h:53
static LANGID gLangid
static INT test_ACP_RequestLock
static INT test_ACP_InsertTextAtSelection
static HRESULT WINAPI ThreadMgrEventSink_OnUninitDocumentMgr(ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim)
static DWORD dmSinkCookie
static HRESULT WINAPI TextStoreACP_RequestLock(ITextStoreACP *iface, DWORD dwLockFlags, HRESULT *phrSession)
TsActiveSelEnd ase
Definition: textstor.idl:86
static void test_UnregisterCategory(void)
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:1991
static ITfDocumentMgr * test_PrevFocus
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
static HRESULT WINAPI TextStoreACP_GetStatus(ITextStoreACP *iface, TS_STATUS *pdcs)
#define ARRAY_SIZE(a)
Definition: main.h:24
static void test_profile_mgr(void)
static void test_EnumContexts(ITfDocumentMgr *dm, ITfContext *search)
#define QS_ALLINPUT
Definition: winuser.h:874
#define ok(value,...)
Definition: atltest.h:57
#define SINK_IGNORE
#define E_NOTIMPL
Definition: ddrawi.h:99
static HRESULT WINAPI TextStoreACP_QueryInsertEmbedded(ITextStoreACP *iface, const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable)
static ClassFactory * impl_from_IClassFactory(IClassFactory *iface)
EXTERN_C const GUID GUID_TFCAT_TIP_KEYBOARD
Definition: msctf.idl:62
static void test_startSession(void)
#define WS_POPUP
Definition: pedump.c:616
static int expected_count(int *sink)
static HRESULT WINAPI KeyEventSink_OnPreservedKey(ITfKeyEventSink *iface, ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID iid, LPVOID *ppvOut)
static DWORD documentStatus
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
ITfKeyEventSink ITfKeyEventSink_iface
#define sink_check_ok(a, b)
static HRESULT WINAPI TextStoreACP_InsertEmbeddedAtSelection(ITextStoreACP *iface, DWORD dwFlags, IDataObject *pDataObject, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange)
static ULONG WINAPI TextService_AddRef(ITfTextInputProcessor *iface)
static HRESULT WINAPI EditSession_QueryInterface(ITfEditSession *iface, REFIID iid, LPVOID *ppvOut)
EXTERN_C const GUID GUID_COMPARTMENT_KEYBOARD_DISABLED
Definition: msctf.idl:51
EXTERN_C const GUID GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER
Definition: msctf.idl:65
#define FOCUS_SAVE
#define E_UNEXPECTED
Definition: winerror.h:2456
#define skip(...)
Definition: atltest.h:64
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1897
#define msg(x)
Definition: auth_time.c:54
Definition: name.c:36
static HRESULT initialize(void)
struct tagTextEditSink TextEditSink
static void test_Activate(void)
unsigned int ULONG
Definition: retypes.h:1
GLenum GLuint id
Definition: glext.h:5579
static HRESULT WINAPI TextStoreACP_GetActiveView(ITextStoreACP *iface, TsViewCookie *pvcView)
static void test_ThreadMgrAdviseSinks(void)
#define profile
Definition: kernel32.h:12
static DWORD regid
DWORD TfClientId
Definition: msctf.idl:68
static void test_AssociateFocus(void)
ITfTextEditSink ITfTextEditSink_iface
const DWORD TS_SD_READONLY
Definition: textstor.idl:40
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
ITfEditSession ITfEditSession_iface
#define PM_REMOVE
Definition: winuser.h:1182
static HRESULT WINAPI TextStoreACP_AdviseSink(ITextStoreACP *iface, REFIID riid, IUnknown *punk, DWORD dwMask)
static ITfInputProcessorProfiles * g_ipp
static HRESULT WINAPI KeyEventSink_OnKeyDown(ITfKeyEventSink *iface, ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut)
static HRESULT WINAPI TextStoreACP_GetTextExt(ITextStoreACP *iface, TsViewCookie vcView, LONG acpStart, LONG acpEnd, RECT *prc, BOOL *pfClipped)
static void test_DocumentMgrAdviseSinks(void)
#define es
Definition: i386-dis.c:431
_Out_ LPRECT prc
Definition: ntgdi.h:1658
const GUID IID_IClassFactory
static HRESULT TextStoreACP_Constructor(IUnknown **ppOut)
static ITfDocumentMgr * test_FirstPrevFocus
static LONG TS_refCount
HRESULT(* LPFNCONSTRUCTOR)(IUnknown *pUnkOuter, IUnknown **ppvOut)
static HRESULT WINAPI TfKeyTraceEventSink_OnKeyTraceUp(ITfKeyTraceEventSink *iface, WPARAM wparam, LPARAM lparam)
#define win_skip
Definition: test.h:141
static TfClientId tid
LPARAM lParam
Definition: combotst.c:139
static ITfDocumentMgr * g_dm
#define HeapFree(x, y, z)
Definition: compat.h:394
static void _sink_check_ok(INT *sink, const CHAR *name)
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
struct tagTextStoreACP TextStoreACP
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppvOut)
static UINT WPARAM wparam
Definition: combo.c:716
static HRESULT WINAPI TextStoreACP_RequestAttrsAtPosition(ITextStoreACP *iface, LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags)
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
static HRESULT WINAPI TextStoreACP_GetACPFromPoint(ITextStoreACP *iface, TsViewCookie vcView, const POINT *ptScreen, DWORD dwFlags, LONG *pacp)
EXTERN_C const GUID GUID_COMPARTMENT_SPEECH_GLOBALSTATE
Definition: msctf.idl:56