msctf: Implement TF_GetThreadMgr.
[wine] / dlls / msctf / inputprocessor.c
1 /*
2  *  ITfInputProcessorProfiles implementation
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 "config.h"
22
23 #include <stdarg.h>
24
25 #define COBJMACROS
26
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"
35
36 #include "wine/unicode.h"
37
38 #include "msctf.h"
39 #include "msctf_internal.h"
40
41 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
42
43 typedef struct tagInputProcessorProfiles {
44     const ITfInputProcessorProfilesVtbl *InputProcessorProfilesVtbl;
45     LONG refCount;
46
47     LANGID  currentLanguage;
48 } InputProcessorProfiles;
49
50 static void InputProcessorProfiles_Destructor(InputProcessorProfiles *This)
51 {
52     TRACE("destroying %p\n", This);
53     HeapFree(GetProcessHeap(),0,This);
54 }
55
56 static HRESULT WINAPI InputProcessorProfiles_QueryInterface(ITfInputProcessorProfiles *iface, REFIID iid, LPVOID *ppvOut)
57 {
58     InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
59     *ppvOut = NULL;
60
61     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfInputProcessorProfiles))
62     {
63         *ppvOut = This;
64     }
65
66     if (*ppvOut)
67     {
68         IUnknown_AddRef(iface);
69         return S_OK;
70     }
71
72     WARN("unsupported interface: %s\n", debugstr_guid(iid));
73     return E_NOINTERFACE;
74 }
75
76 static ULONG WINAPI InputProcessorProfiles_AddRef(ITfInputProcessorProfiles *iface)
77 {
78     InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
79     return InterlockedIncrement(&This->refCount);
80 }
81
82 static ULONG WINAPI InputProcessorProfiles_Release(ITfInputProcessorProfiles *iface)
83 {
84     InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
85     ULONG ret;
86
87     ret = InterlockedDecrement(&This->refCount);
88     if (ret == 0)
89         InputProcessorProfiles_Destructor(This);
90     return ret;
91 }
92
93 /*****************************************************
94  * ITfInputProcessorProfiles functions
95  *****************************************************/
96 static HRESULT WINAPI InputProcessorProfiles_Register(
97         ITfInputProcessorProfiles *iface, REFCLSID rclsid)
98 {
99     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
100     HKEY tipkey;
101     WCHAR buf[39];
102     static const WCHAR fmt[] = {'%','s','\\','%','s',0};
103     WCHAR fullkey[68];
104
105     TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
106
107     StringFromGUID2(rclsid, buf, 39);
108     sprintfW(fullkey,fmt,szwSystemTIPKey,buf);
109
110     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, NULL, 0,
111                     KEY_READ | KEY_WRITE, NULL, &tipkey, NULL) != ERROR_SUCCESS)
112         return E_FAIL;
113
114     RegCloseKey(tipkey);
115
116     return S_OK;
117 }
118
119 static HRESULT WINAPI InputProcessorProfiles_Unregister(
120         ITfInputProcessorProfiles *iface, REFCLSID rclsid)
121 {
122     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
123     FIXME("STUB:(%p)\n",This);
124     return E_NOTIMPL;
125 }
126
127 static HRESULT WINAPI InputProcessorProfiles_AddLanguageProfile(
128         ITfInputProcessorProfiles *iface, REFCLSID rclsid,
129         LANGID langid, REFGUID guidProfile, const WCHAR *pchDesc,
130         ULONG cchDesc, const WCHAR *pchIconFile, ULONG cchFile,
131         ULONG uIconIndex)
132 {
133     HKEY tipkey,fmtkey;
134     WCHAR buf[39];
135     WCHAR fullkey[100];
136     ULONG res;
137
138     static const WCHAR fmt[] = {'%','s','\\','%','s',0};
139     static const WCHAR fmt2[] = {'%','s','\\','0','x','%','0','8','x','\\','%','s',0};
140     static const WCHAR lngp[] = {'L','a','n','g','u','a','g','e','P','r','o','f','i','l','e',0};
141     static const WCHAR desc[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
142     static const WCHAR icnf[] = {'I','c','o','n','F','i','l','e',0};
143     static const WCHAR icni[] = {'I','c','o','n','I','n','d','e','x',0};
144
145     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
146
147     TRACE("(%p) %s %x %s %s %s %i\n",This,debugstr_guid(rclsid), langid,
148             debugstr_guid(guidProfile), debugstr_wn(pchDesc,cchDesc),
149             debugstr_wn(pchIconFile,cchFile),uIconIndex);
150
151     StringFromGUID2(rclsid, buf, 39);
152     sprintfW(fullkey,fmt,szwSystemTIPKey,buf);
153
154     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ | KEY_WRITE,
155                 &tipkey ) != ERROR_SUCCESS)
156         return E_FAIL;
157
158     StringFromGUID2(guidProfile, buf, 39);
159     sprintfW(fullkey,fmt2,lngp,langid,buf);
160
161     res = RegCreateKeyExW(tipkey,fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
162             NULL, &fmtkey, NULL);
163
164     if (!res)
165     {
166         RegSetValueExW(fmtkey, desc, 0, REG_SZ, (LPBYTE)pchDesc, cchDesc * sizeof(WCHAR));
167         RegSetValueExW(fmtkey, icnf, 0, REG_SZ, (LPBYTE)pchIconFile, cchFile * sizeof(WCHAR));
168         RegSetValueExW(fmtkey, icni, 0, REG_DWORD, (LPBYTE)&uIconIndex, sizeof(DWORD));
169         RegCloseKey(fmtkey);
170     }
171     RegCloseKey(tipkey);
172
173     if (!res)
174         return S_OK;
175     else
176         return E_FAIL;
177 }
178
179 static HRESULT WINAPI InputProcessorProfiles_RemoveLanguageProfile(
180         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
181         REFGUID guidProfile)
182 {
183     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
184     FIXME("STUB:(%p)\n",This);
185     return E_NOTIMPL;
186 }
187
188 static HRESULT WINAPI InputProcessorProfiles_EnumInputProcessorInfo(
189         ITfInputProcessorProfiles *iface, IEnumGUID **ppEnum)
190 {
191     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
192     FIXME("STUB:(%p)\n",This);
193     return E_NOTIMPL;
194 }
195
196 static HRESULT WINAPI InputProcessorProfiles_GetDefaultLanguageProfile(
197         ITfInputProcessorProfiles *iface, LANGID langid, REFGUID catid,
198         CLSID *pclsid, GUID *pguidProfile)
199 {
200     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
201     FIXME("STUB:(%p)\n",This);
202     return E_NOTIMPL;
203 }
204
205 static HRESULT WINAPI InputProcessorProfiles_SetDefaultLanguageProfile(
206         ITfInputProcessorProfiles *iface, LANGID langid, REFCLSID rclsid,
207         REFGUID guidProfiles)
208 {
209     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
210     FIXME("STUB:(%p)\n",This);
211     return E_NOTIMPL;
212 }
213
214 static HRESULT WINAPI InputProcessorProfiles_ActivateLanguageProfile(
215         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
216         REFGUID guidProfiles)
217 {
218     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
219     FIXME("STUB:(%p)\n",This);
220     return E_NOTIMPL;
221 }
222
223 static HRESULT WINAPI InputProcessorProfiles_GetActiveLanguageProfile(
224         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID *plangid,
225         GUID *pguidProfile)
226 {
227     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
228     FIXME("STUB:(%p)\n",This);
229     return E_NOTIMPL;
230 }
231
232 static HRESULT WINAPI InputProcessorProfiles_GetLanguageProfileDescription(
233         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
234         REFGUID guidProfile, BSTR *pbstrProfile)
235 {
236     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
237     FIXME("STUB:(%p)\n",This);
238     return E_NOTIMPL;
239 }
240
241 static HRESULT WINAPI InputProcessorProfiles_GetCurrentLanguage(
242         ITfInputProcessorProfiles *iface, LANGID *plangid)
243 {
244     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
245     TRACE("(%p) 0x%x\n",This,This->currentLanguage);
246
247     if (!plangid)
248         return E_INVALIDARG;
249
250     *plangid = This->currentLanguage;
251
252     return S_OK;
253 }
254
255 static HRESULT WINAPI InputProcessorProfiles_ChangeCurrentLanguage(
256         ITfInputProcessorProfiles *iface, LANGID langid)
257 {
258     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
259     FIXME("STUB:(%p)\n",This);
260     return E_NOTIMPL;
261 }
262
263 static HRESULT WINAPI InputProcessorProfiles_GetLanguageList(
264         ITfInputProcessorProfiles *iface, LANGID **ppLangId, ULONG *pulCount)
265 {
266     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
267     FIXME("STUB:(%p)\n",This);
268     return E_NOTIMPL;
269 }
270
271 static HRESULT WINAPI InputProcessorProfiles_EnumLanguageProfiles(
272         ITfInputProcessorProfiles *iface, LANGID langid,
273         IEnumTfLanguageProfiles **ppEnum)
274 {
275     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
276     FIXME("STUB:(%p)\n",This);
277     return E_NOTIMPL;
278 }
279
280 static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfile(
281         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
282         REFGUID guidProfile, BOOL fEnable)
283 {
284     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
285     FIXME("STUB:(%p)\n",This);
286     return E_NOTIMPL;
287 }
288
289 static HRESULT WINAPI InputProcessorProfiles_IsEnabledLanguageProfile(
290         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
291         REFGUID guidProfile, BOOL *pfEnable)
292 {
293     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
294     FIXME("STUB:(%p)\n",This);
295     return E_NOTIMPL;
296 }
297
298 static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfileByDefault(
299         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
300         REFGUID guidProfile, BOOL fEnable)
301 {
302     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
303     FIXME("STUB:(%p)\n",This);
304     return E_NOTIMPL;
305 }
306
307 static HRESULT WINAPI InputProcessorProfiles_SubstituteKeyboardLayout(
308         ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
309         REFGUID guidProfile, HKL hKL)
310 {
311     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
312     FIXME("STUB:(%p)\n",This);
313     return E_NOTIMPL;
314 }
315
316
317 static const ITfInputProcessorProfilesVtbl InputProcessorProfiles_InputProcessorProfilesVtbl =
318 {
319     InputProcessorProfiles_QueryInterface,
320     InputProcessorProfiles_AddRef,
321     InputProcessorProfiles_Release,
322
323     InputProcessorProfiles_Register,
324     InputProcessorProfiles_Unregister,
325     InputProcessorProfiles_AddLanguageProfile,
326     InputProcessorProfiles_RemoveLanguageProfile,
327     InputProcessorProfiles_EnumInputProcessorInfo,
328     InputProcessorProfiles_GetDefaultLanguageProfile,
329     InputProcessorProfiles_SetDefaultLanguageProfile,
330     InputProcessorProfiles_ActivateLanguageProfile,
331     InputProcessorProfiles_GetActiveLanguageProfile,
332     InputProcessorProfiles_GetLanguageProfileDescription,
333     InputProcessorProfiles_GetCurrentLanguage,
334     InputProcessorProfiles_ChangeCurrentLanguage,
335     InputProcessorProfiles_GetLanguageList,
336     InputProcessorProfiles_EnumLanguageProfiles,
337     InputProcessorProfiles_EnableLanguageProfile,
338     InputProcessorProfiles_IsEnabledLanguageProfile,
339     InputProcessorProfiles_EnableLanguageProfileByDefault,
340     InputProcessorProfiles_SubstituteKeyboardLayout
341 };
342
343 HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
344 {
345     InputProcessorProfiles *This;
346     if (pUnkOuter)
347         return CLASS_E_NOAGGREGATION;
348
349     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputProcessorProfiles));
350     if (This == NULL)
351         return E_OUTOFMEMORY;
352
353     This->InputProcessorProfilesVtbl= &InputProcessorProfiles_InputProcessorProfilesVtbl;
354     This->refCount = 1;
355     This->currentLanguage = GetUserDefaultLCID();
356
357     TRACE("returning %p\n", This);
358     *ppOut = (IUnknown *)This;
359     return S_OK;
360 }