push d1f5df181c120dbe494f7c89b454752c2e0dcc04
[wine/hacks.git] / dlls / msctf / threadmgr.c
blob76c1fd61afd74e1eee327c0deb0d359541a8fdfc
1 /*
2 * ITfThreadMgr implementation
4 * Copyright 2008 Aric Stewart, CodeWeavers
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.
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.
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
21 #include "config.h"
23 #include <stdarg.h>
25 #define COBJMACROS
27 #include "wine/debug.h"
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winreg.h"
31 #include "winuser.h"
32 #include "shlwapi.h"
33 #include "winerror.h"
34 #include "objbase.h"
36 #include "wine/unicode.h"
38 #include "msctf.h"
39 #include "msctf_internal.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
43 typedef struct tagACLMulti {
44 const ITfThreadMgrVtbl *ThreadMgrVtbl;
45 const ITfSourceVtbl *SourceVtbl;
46 LONG refCount;
48 ITfDocumentMgr *focus;
49 } ThreadMgr;
51 static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
53 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl));
56 static void ThreadMgr_Destructor(ThreadMgr *This)
58 TlsSetValue(tlsIndex,NULL);
59 TRACE("destroying %p\n", This);
60 if (This->focus)
61 ITfDocumentMgr_Release(This->focus);
62 HeapFree(GetProcessHeap(),0,This);
65 static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgr *iface, REFIID iid, LPVOID *ppvOut)
67 ThreadMgr *This = (ThreadMgr *)iface;
68 *ppvOut = NULL;
70 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgr))
72 *ppvOut = This;
74 else if (IsEqualIID(iid, &IID_ITfSource))
76 *ppvOut = &This->SourceVtbl;
79 if (*ppvOut)
81 IUnknown_AddRef(iface);
82 return S_OK;
85 WARN("unsupported interface: %s\n", debugstr_guid(iid));
86 return E_NOINTERFACE;
89 static ULONG WINAPI ThreadMgr_AddRef(ITfThreadMgr *iface)
91 ThreadMgr *This = (ThreadMgr *)iface;
92 return InterlockedIncrement(&This->refCount);
95 static ULONG WINAPI ThreadMgr_Release(ITfThreadMgr *iface)
97 ThreadMgr *This = (ThreadMgr *)iface;
98 ULONG ret;
100 ret = InterlockedDecrement(&This->refCount);
101 if (ret == 0)
102 ThreadMgr_Destructor(This);
103 return ret;
106 /*****************************************************
107 * ITfThreadMgr functions
108 *****************************************************/
110 static HRESULT WINAPI ThreadMgr_fnActivate( ITfThreadMgr* iface, TfClientId *ptid)
112 ThreadMgr *This = (ThreadMgr *)iface;
113 FIXME("STUB:(%p)\n",This);
114 return E_NOTIMPL;
117 static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface)
119 ThreadMgr *This = (ThreadMgr *)iface;
120 FIXME("STUB:(%p)\n",This);
121 return E_NOTIMPL;
124 static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr
125 **ppdim)
127 TRACE("(%p)\n",iface);
128 return DocumentMgr_Constructor(ppdim);
131 static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDocumentMgrs
132 **ppEnum)
134 ThreadMgr *This = (ThreadMgr *)iface;
135 FIXME("STUB:(%p)\n",This);
136 return E_NOTIMPL;
139 static HRESULT WINAPI ThreadMgr_GetFocus( ITfThreadMgr* iface, ITfDocumentMgr
140 **ppdimFocus)
142 ThreadMgr *This = (ThreadMgr *)iface;
143 TRACE("(%p)\n",This);
145 if (!ppdimFocus)
146 return E_INVALIDARG;
148 *ppdimFocus = This->focus;
150 TRACE("->%p\n",This->focus);
152 if (This->focus == NULL)
153 return S_FALSE;
155 ITfDocumentMgr_AddRef(This->focus);
157 return S_OK;
160 static HRESULT WINAPI ThreadMgr_SetFocus( ITfThreadMgr* iface, ITfDocumentMgr *pdimFocus)
162 ITfDocumentMgr *check;
163 ThreadMgr *This = (ThreadMgr *)iface;
165 TRACE("(%p) %p\n",This,pdimFocus);
167 if (!pdimFocus || FAILED(IUnknown_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
168 return E_INVALIDARG;
170 if (This->focus)
171 ITfDocumentMgr_Release(This->focus);
173 This->focus = check;
174 return S_OK;
177 static HRESULT WINAPI ThreadMgr_AssociateFocus( ITfThreadMgr* iface, HWND hwnd,
178 ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev)
180 ThreadMgr *This = (ThreadMgr *)iface;
181 FIXME("STUB:(%p)\n",This);
182 return E_NOTIMPL;
185 static HRESULT WINAPI ThreadMgr_IsThreadFocus( ITfThreadMgr* iface, BOOL *pfThreadFocus)
187 ThreadMgr *This = (ThreadMgr *)iface;
188 FIXME("STUB:(%p)\n",This);
189 return E_NOTIMPL;
192 static HRESULT WINAPI ThreadMgr_GetFunctionProvider( ITfThreadMgr* iface, REFCLSID clsid,
193 ITfFunctionProvider **ppFuncProv)
195 ThreadMgr *This = (ThreadMgr *)iface;
196 FIXME("STUB:(%p)\n",This);
197 return E_NOTIMPL;
200 static HRESULT WINAPI ThreadMgr_EnumFunctionProviders( ITfThreadMgr* iface,
201 IEnumTfFunctionProviders **ppEnum)
203 ThreadMgr *This = (ThreadMgr *)iface;
204 FIXME("STUB:(%p)\n",This);
205 return E_NOTIMPL;
208 static HRESULT WINAPI ThreadMgr_GetGlobalCompartment( ITfThreadMgr* iface,
209 ITfCompartmentMgr **ppCompMgr)
211 ThreadMgr *This = (ThreadMgr *)iface;
212 FIXME("STUB:(%p)\n",This);
213 return E_NOTIMPL;
216 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl =
218 ThreadMgr_QueryInterface,
219 ThreadMgr_AddRef,
220 ThreadMgr_Release,
222 ThreadMgr_fnActivate,
223 ThreadMgr_fnDeactivate,
224 ThreadMgr_CreateDocumentMgr,
225 ThreadMgr_EnumDocumentMgrs,
226 ThreadMgr_GetFocus,
227 ThreadMgr_SetFocus,
228 ThreadMgr_AssociateFocus,
229 ThreadMgr_IsThreadFocus,
230 ThreadMgr_GetFunctionProvider,
231 ThreadMgr_EnumFunctionProviders,
232 ThreadMgr_GetGlobalCompartment
236 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
238 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
239 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
242 static ULONG WINAPI Source_AddRef(ITfSource *iface)
244 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
245 return ThreadMgr_AddRef((ITfThreadMgr*)This);
248 static ULONG WINAPI Source_Release(ITfSource *iface)
250 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
251 return ThreadMgr_Release((ITfThreadMgr *)This);
254 /*****************************************************
255 * ITfSource functions
256 *****************************************************/
257 static WINAPI HRESULT ThreadMgrSource_AdviseSink(ITfSource *iface,
258 REFIID riid, IUnknown *punk, DWORD *pdwCookie)
260 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
261 FIXME("STUB:(%p)\n",This);
262 return E_NOTIMPL;
265 static WINAPI HRESULT ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
267 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
268 FIXME("STUB:(%p)\n",This);
269 return E_NOTIMPL;
272 static const ITfSourceVtbl ThreadMgr_SourceVtbl =
274 Source_QueryInterface,
275 Source_AddRef,
276 Source_Release,
278 ThreadMgrSource_AdviseSink,
279 ThreadMgrSource_UnadviseSink,
282 HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
284 ThreadMgr *This;
285 if (pUnkOuter)
286 return CLASS_E_NOAGGREGATION;
288 /* Only 1 ThreadMgr is created per thread */
289 This = TlsGetValue(tlsIndex);
290 if (This)
292 ThreadMgr_AddRef((ITfThreadMgr*)This);
293 *ppOut = (IUnknown*)This;
294 return S_OK;
297 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgr));
298 if (This == NULL)
299 return E_OUTOFMEMORY;
301 This->ThreadMgrVtbl= &ThreadMgr_ThreadMgrVtbl;
302 This->SourceVtbl = &ThreadMgr_SourceVtbl;
303 This->refCount = 1;
304 TlsSetValue(tlsIndex,This);
306 TRACE("returning %p\n", This);
307 *ppOut = (IUnknown *)This;
308 return S_OK;