Mercurial > sdl-ios-xcode
comparison EXCLUDE/GLTSF/src/TSF.cpp @ 4739:f51a9f01b508
Starting to implement ITextStoreACP.
It's very incomplete and will probably change quite a bit but it's a start.
ITextStoreACP is the minimum interface to be considered TSF-aware.
author | dewyatt |
---|---|
date | Mon, 21 Jun 2010 17:16:37 -0400 |
parents | 0c7c67d4e6ee |
children | abf528de6d2e |
comparison
equal
deleted
inserted
replaced
4738:381d402a5e90 | 4739:f51a9f01b508 |
---|---|
1 #include "TSF.hpp" | 1 #include "TSF.hpp" |
2 #include <stdexcept> | 2 #include <stdexcept> |
3 | 3 |
4 bool TSF::COM_Initialized = false; | 4 bool TSF::COM_Initialized = false; |
5 CComPtr<ITfThreadMgr> TSF::Thread_Manager; | 5 CComPtr<ITfThreadMgr> TSF::Thread_Manager; |
6 TfClientId TSF::Client_Id; | |
7 TSF::TSF_Text_Store *TSF::Text_Store = NULL; | |
6 | 8 |
7 void TSF::Initialize() | 9 void TSF::Initialize() |
8 { | 10 { |
9 if (!COM_Initialized) | 11 if (!COM_Initialized) |
10 { | 12 { |
17 if (!Thread_Manager) | 19 if (!Thread_Manager) |
18 { | 20 { |
19 if (FAILED(CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast<void **>(&Thread_Manager)))) | 21 if (FAILED(CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast<void **>(&Thread_Manager)))) |
20 throw std::runtime_error("Failed to create ITfThreadMgr instance"); | 22 throw std::runtime_error("Failed to create ITfThreadMgr instance"); |
21 | 23 |
22 TfClientId ClientId; | 24 if (FAILED(Thread_Manager->Activate(&Client_Id))) |
23 if (FAILED(Thread_Manager->Activate(&ClientId))) | |
24 throw std::runtime_error("ITfThreadMgr::Activate failed"); | 25 throw std::runtime_error("ITfThreadMgr::Activate failed"); |
26 | |
27 Text_Store = new TSF_Text_Store; | |
28 Text_Store->Initialize(); | |
25 } | 29 } |
26 } | 30 } |
27 | 31 |
28 void TSF::Finalize() | 32 void TSF::Finalize() |
29 { | 33 { |
36 { | 40 { |
37 CoUninitialize(); | 41 CoUninitialize(); |
38 COM_Initialized = false; | 42 COM_Initialized = false; |
39 } | 43 } |
40 } | 44 } |
45 | |
46 STDMETHODIMP TSF::TSF_Text_Store::QueryInterface(REFIID riid, void **ppvObject) | |
47 { | |
48 *ppvObject = NULL; | |
49 if (IID_IUnknown == riid || IID_ITextStoreACP == riid) | |
50 *ppvObject = static_cast<ITextStoreACP *>(this); | |
51 else if (IID_ITfContextOwnerCompositionSink == riid) | |
52 *ppvObject = static_cast<ITfContextOwnerCompositionSink *>(this); | |
53 | |
54 if (*ppvObject) | |
55 { | |
56 AddRef(); | |
57 return S_OK; | |
58 } | |
59 return E_NOINTERFACE; | |
60 } | |
61 | |
62 STDMETHODIMP_(ULONG) TSF::TSF_Text_Store::AddRef() | |
63 { | |
64 return ++my_Reference_Count; | |
65 } | |
66 | |
67 STDMETHODIMP_(ULONG) TSF::TSF_Text_Store::Release() | |
68 { | |
69 --my_Reference_Count; | |
70 if (0 != my_Reference_Count) | |
71 return my_Reference_Count; | |
72 | |
73 delete this; | |
74 return 0; | |
75 } | |
76 | |
77 STDMETHODIMP TSF::TSF_Text_Store::AdviseSink(REFIID riid, IUnknown *punk, DWORD dwMask) | |
78 { | |
79 if (!punk || IID_ITextStoreACPSink != riid) | |
80 return E_INVALIDARG; | |
81 | |
82 if (!my_Sink) | |
83 { | |
84 punk->QueryInterface(&my_Sink); | |
85 if (!my_Sink) | |
86 return E_UNEXPECTED; | |
87 } | |
88 else | |
89 { | |
90 CComPtr<IUnknown> Unknown_1, Unknown_2; | |
91 punk->QueryInterface(&Unknown_1); | |
92 my_Sink->QueryInterface(&Unknown_2); | |
93 if (Unknown_1 != Unknown_2) | |
94 return CONNECT_E_ADVISELIMIT; | |
95 } | |
96 my_Sink_Mask = dwMask; | |
97 return S_OK; | |
98 } | |
99 | |
100 STDMETHODIMP TSF::TSF_Text_Store::UnadviseSink(IUnknown *punk) | |
101 { | |
102 if (!punk) | |
103 return E_INVALIDARG; | |
104 | |
105 if (!my_Sink) | |
106 return CONNECT_E_NOCONNECTION; | |
107 | |
108 CComPtr<IUnknown> Unknown_1, Unknown_2; | |
109 punk->QueryInterface(&Unknown_1); | |
110 my_Sink->QueryInterface(&Unknown_2); | |
111 | |
112 if (Unknown_1 != Unknown_2) | |
113 return CONNECT_E_NOCONNECTION; | |
114 | |
115 my_Sink = NULL; | |
116 my_Sink_Mask = 0; | |
117 return S_OK; | |
118 } | |
119 | |
120 STDMETHODIMP TSF::TSF_Text_Store::RequestLock(DWORD dwLockFlags, HRESULT *phrSession) | |
121 { | |
122 if (!my_Sink) | |
123 return E_FAIL; | |
124 | |
125 if (!phrSession) | |
126 return E_INVALIDARG; | |
127 | |
128 if (my_Lock) | |
129 { | |
130 if (TS_LF_READ == (my_Lock & TS_LF_READWRITE) | |
131 && TS_LF_READWRITE == (dwLockFlags & TS_LF_READWRITE) | |
132 && !(dwLockFlags & TS_LF_SYNC)) | |
133 { | |
134 *phrSession = TS_S_ASYNC; | |
135 my_Lock_Queued = dwLockFlags & (~TS_LF_SYNC); | |
136 } | |
137 else | |
138 { | |
139 *phrSession = TS_E_SYNCHRONOUS; | |
140 return E_FAIL; | |
141 } | |
142 } | |
143 else | |
144 { | |
145 my_Lock = dwLockFlags & (~TS_LF_SYNC); | |
146 *phrSession = my_Sink->OnLockGranted(my_Lock); | |
147 while (my_Lock_Queued) | |
148 { | |
149 my_Lock = my_Lock_Queued; | |
150 my_Lock_Queued = 0; | |
151 my_Sink->OnLockGranted(my_Lock); | |
152 } | |
153 my_Lock = 0; | |
154 } | |
155 return S_OK; | |
156 } | |
157 | |
158 STDMETHODIMP TSF::TSF_Text_Store::GetStatus(TS_STATUS *pdcs) | |
159 { | |
160 if (!pdcs) | |
161 return E_INVALIDARG; | |
162 | |
163 pdcs->dwDynamicFlags = 0; | |
164 pdcs->dwStaticFlags = TS_SS_NOHIDDENTEXT; | |
165 return S_OK; | |
166 } | |
167 | |
168 STDMETHODIMP TSF::TSF_Text_Store::QueryInsert(LONG acpTestStart, LONG acpTestEnd, ULONG cch, LONG *pacpResultStart, LONG *pacpResultEnd) | |
169 { | |
170 if (acpTestStart < 0 || acpTestStart > acpTestEnd || !pacpResultStart || !pacpResultEnd) | |
171 return E_INVALIDARG; | |
172 | |
173 *pacpResultStart = acpTestStart; | |
174 *pacpResultEnd = acpTestStart + cch; | |
175 return S_OK; | |
176 } | |
177 | |
178 STDMETHODIMP TSF::TSF_Text_Store::GetSelection(ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched) | |
179 { | |
180 if (TS_LF_READ != (my_Lock & TS_LF_READ)) | |
181 return TS_E_NOLOCK; | |
182 | |
183 if (!ulCount || !pSelection || !pcFetched) | |
184 return E_INVALIDARG; | |
185 | |
186 *pcFetched = 0; | |
187 if (TS_DEFAULT_SELECTION != ulIndex && 0 != ulIndex) | |
188 return TS_E_NOSELECTION; | |
189 | |
190 if (my_Composition_View) | |
191 { | |
192 *pSelection = my_Composition_Selection; | |
193 } | |
194 else | |
195 { | |
196 //TODO | |
197 } | |
198 return S_OK; | |
199 } | |
200 | |
201 STDMETHODIMP TSF::TSF_Text_Store::SetSelection(ULONG ulCount, const TS_SELECTION_ACP *pSelection) | |
202 { | |
203 return E_NOTIMPL; | |
204 } | |
205 | |
206 STDMETHODIMP TSF::TSF_Text_Store::GetText(LONG acpStart, LONG acpEnd, WCHAR *pchPlain, ULONG cchPlainReq, ULONG *pcchPlainRet, TS_RUNINFO *prgRunInfo, ULONG cRunInfoReq, ULONG *pcRunInfoRet, LONG *pacpNext) | |
207 { | |
208 return E_NOTIMPL; | |
209 } | |
210 | |
211 STDMETHODIMP TSF::TSF_Text_Store::SetText(DWORD dwFlags, LONG acpStart, LONG acpEnd, const WCHAR *pchText, ULONG cch, TS_TEXTCHANGE *pChange) | |
212 { | |
213 return E_NOTIMPL; | |
214 } | |
215 | |
216 STDMETHODIMP TSF::TSF_Text_Store::GetFormattedText(LONG acpStart, LONG acpEnd, IDataObject **ppDataObject) | |
217 { | |
218 return E_NOTIMPL; | |
219 } | |
220 | |
221 STDMETHODIMP TSF::TSF_Text_Store::GetEmbedded(LONG acpPos, REFGUID rguidService, REFIID riid, IUnknown **ppunk) | |
222 { | |
223 return E_NOTIMPL; | |
224 } | |
225 | |
226 STDMETHODIMP TSF::TSF_Text_Store::QueryInsertEmbedded(const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable) | |
227 { | |
228 return E_NOTIMPL; | |
229 } | |
230 | |
231 STDMETHODIMP TSF::TSF_Text_Store::InsertEmbedded(DWORD dwFlags, LONG acpStart, LONG acpEnd, IDataObject *pDataObject, TS_TEXTCHANGE *pChange) | |
232 { | |
233 return E_NOTIMPL; | |
234 } | |
235 | |
236 STDMETHODIMP TSF::TSF_Text_Store::InsertTextAtSelection(DWORD dwFlags, const WCHAR *pchText, ULONG cch, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange) | |
237 { | |
238 return E_NOTIMPL; | |
239 } | |
240 | |
241 STDMETHODIMP TSF::TSF_Text_Store::InsertEmbeddedAtSelection(DWORD dwFlags, IDataObject *pDataObject, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange) | |
242 { | |
243 return E_NOTIMPL; | |
244 } | |
245 | |
246 STDMETHODIMP TSF::TSF_Text_Store::RequestSupportedAttrs(DWORD dwFlags, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs) | |
247 { | |
248 return E_NOTIMPL; | |
249 } | |
250 | |
251 STDMETHODIMP TSF::TSF_Text_Store::RequestAttrsAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags) | |
252 { | |
253 return E_NOTIMPL; | |
254 } | |
255 | |
256 STDMETHODIMP TSF::TSF_Text_Store::RequestAttrsTransitioningAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags) | |
257 { | |
258 return E_NOTIMPL; | |
259 } | |
260 | |
261 STDMETHODIMP TSF::TSF_Text_Store::FindNextAttrTransition(LONG acpStart, LONG acpHalt, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags, LONG *pacpNext, BOOL *pfFound, LONG *plFoundOffset) | |
262 { | |
263 return E_NOTIMPL; | |
264 } | |
265 | |
266 STDMETHODIMP TSF::TSF_Text_Store::RetrieveRequestedAttrs(ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched) | |
267 { | |
268 return E_NOTIMPL; | |
269 } | |
270 | |
271 STDMETHODIMP TSF::TSF_Text_Store::GetEndACP(LONG *pacp) | |
272 { | |
273 return E_NOTIMPL; | |
274 } | |
275 | |
276 STDMETHODIMP TSF::TSF_Text_Store::GetActiveView(TsViewCookie *pvcView) | |
277 { | |
278 return E_NOTIMPL; | |
279 } | |
280 | |
281 STDMETHODIMP TSF::TSF_Text_Store::GetACPFromPoint(TsViewCookie vcView, const POINT *ptScreen, DWORD dwFlags, LONG *pacp) | |
282 { | |
283 return E_NOTIMPL; | |
284 } | |
285 | |
286 STDMETHODIMP TSF::TSF_Text_Store::GetTextExt(TsViewCookie vcView, LONG acpStart, LONG acpEnd, RECT *prc, BOOL *pfClipped) | |
287 { | |
288 return E_NOTIMPL; | |
289 } | |
290 | |
291 STDMETHODIMP TSF::TSF_Text_Store::GetScreenExt(TsViewCookie vcView, RECT *prc) | |
292 { | |
293 return E_NOTIMPL; | |
294 } | |
295 | |
296 STDMETHODIMP TSF::TSF_Text_Store::GetWnd(TsViewCookie vcView, HWND *phwnd) | |
297 { | |
298 return E_NOTIMPL; | |
299 } | |
300 | |
301 STDMETHODIMP TSF::TSF_Text_Store::OnStartComposition(ITfCompositionView *pComposition, BOOL *pfOk) | |
302 { | |
303 *pfOk = FALSE; | |
304 return S_OK; | |
305 } | |
306 | |
307 STDMETHODIMP TSF::TSF_Text_Store::OnUpdateComposition(ITfCompositionView *pComposition, ITfRange *pRangeNew) | |
308 { | |
309 return E_NOTIMPL; | |
310 } | |
311 | |
312 STDMETHODIMP TSF::TSF_Text_Store::OnEndComposition(ITfCompositionView *pComposition) | |
313 { | |
314 return E_NOTIMPL; | |
315 } | |
316 | |
317 TSF::TSF_Text_Store::TSF_Text_Store() : my_Reference_Count(1), | |
318 my_Edit_Cookie(0), | |
319 my_Lock(0), | |
320 my_Lock_Queued(0) | |
321 { | |
322 | |
323 } | |
324 | |
325 TSF::TSF_Text_Store::~TSF_Text_Store() | |
326 { | |
327 | |
328 } | |
329 | |
330 void TSF::TSF_Text_Store::Initialize() | |
331 { | |
332 if (FAILED(Thread_Manager->CreateDocumentMgr(&my_Document_Manager))) | |
333 throw std::runtime_error("Failed to create document manager"); | |
334 | |
335 if (FAILED(my_Document_Manager->CreateContext(Client_Id, 0, static_cast<ITextStoreACP *>(this), &my_Context, &my_Edit_Cookie))) | |
336 throw std::runtime_error("Failed to create document context"); | |
337 | |
338 if (FAILED(my_Document_Manager->Push(my_Context))) | |
339 throw std::runtime_error("Failed to push context"); | |
340 } | |
341 | |
342 void TSF::TSF_Text_Store::Finalize() | |
343 { | |
344 | |
345 } |