Aric Stewart : msctf: Add internal functions for managing active text services.
Alexandre Julliard
julliard at winehq.org
Fri May 8 08:06:28 CDT 2009
Module: wine
Branch: master
Commit: aaa15671f4f3025a01fc9c5ee35ef40314f97b67
URL: http://source.winehq.org/git/wine.git/?a=commit;h=aaa15671f4f3025a01fc9c5ee35ef40314f97b67
Author: Aric Stewart <aric at codeweavers.com>
Date: Thu May 7 14:27:29 2009 -0500
msctf: Add internal functions for managing active text services.
---
dlls/msctf/msctf.c | 179 +++++++++++++++++++++++++++++++++++++++++++
dlls/msctf/msctf_internal.h | 6 ++
2 files changed, 185 insertions(+), 0 deletions(-)
diff --git a/dlls/msctf/msctf.c b/dlls/msctf/msctf.c
index 711ae51..57cd477 100644
--- a/dlls/msctf/msctf.c
+++ b/dlls/msctf/msctf.c
@@ -26,6 +26,7 @@
#define COBJMACROS
#include "wine/debug.h"
+#include "wine/list.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
@@ -50,10 +51,25 @@ typedef struct
LPVOID data;
} CookieInternal;
+typedef struct {
+ TF_LANGUAGEPROFILE LanguageProfile;
+ ITfTextInputProcessor *pITfTextInputProcessor;
+ ITfThreadMgr *pITfThreadMgr;
+ TfClientId tid;
+} ActivatedTextService;
+
+typedef struct
+{
+ struct list entry;
+ ActivatedTextService *ats;
+} AtsEntry;
+
static CookieInternal *cookies;
static UINT id_last;
static UINT array_size;
+static struct list AtsList = LIST_INIT(AtsList);
+
DWORD tlsIndex = 0;
const WCHAR szwSystemTIPKey[] = {'S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\','C','T','F','\\','T','I','P',0};
@@ -264,6 +280,169 @@ DWORD enumerate_Cookie(DWORD magic, DWORD *index)
return 0x0;
}
+/*****************************************************************************
+ * Active Text Service Management
+ *****************************************************************************/
+static HRESULT activate_given_ts(ActivatedTextService *actsvr, ITfThreadMgr* tm)
+{
+ HRESULT hr;
+
+ /* Already Active? */
+ if (actsvr->pITfTextInputProcessor)
+ return S_OK;
+
+ hr = CoCreateInstance (&actsvr->LanguageProfile.clsid, NULL, CLSCTX_INPROC_SERVER,
+ &IID_ITfTextInputProcessor, (void**)&actsvr->pITfTextInputProcessor);
+ if (FAILED(hr)) return hr;
+
+ hr = ITfTextInputProcessor_Activate(actsvr->pITfTextInputProcessor, tm, actsvr->tid);
+ if (FAILED(hr))
+ {
+ ITfTextInputProcessor_Release(actsvr->pITfTextInputProcessor);
+ actsvr->pITfTextInputProcessor = NULL;
+ return hr;
+ }
+
+ actsvr->pITfThreadMgr = tm;
+ ITfThreadMgr_AddRef(tm);
+ return hr;
+}
+
+static HRESULT deactivate_given_ts(ActivatedTextService *actsvr)
+{
+ HRESULT hr = S_OK;
+
+ if (actsvr->pITfTextInputProcessor)
+ {
+ hr = ITfTextInputProcessor_Deactivate(actsvr->pITfTextInputProcessor);
+ ITfTextInputProcessor_Release(actsvr->pITfTextInputProcessor);
+ ITfThreadMgr_Release(actsvr->pITfThreadMgr);
+ actsvr->pITfTextInputProcessor = NULL;
+ actsvr->pITfThreadMgr = NULL;
+ }
+
+ return hr;
+}
+
+static void deactivate_remove_conflicting_ts(REFCLSID catid)
+{
+ AtsEntry *ats, *cursor2;
+
+ LIST_FOR_EACH_ENTRY_SAFE(ats, cursor2, &AtsList, AtsEntry, entry)
+ {
+ if (IsEqualCLSID(catid,&ats->ats->LanguageProfile.catid))
+ {
+ deactivate_given_ts(ats->ats);
+ list_remove(&ats->entry);
+ HeapFree(GetProcessHeap(),0,ats->ats);
+ HeapFree(GetProcessHeap(),0,ats);
+ /* we are guarenteeing there is only 1 */
+ break;
+ }
+ }
+}
+
+HRESULT add_active_textservice(TF_LANGUAGEPROFILE *lp)
+{
+ ActivatedTextService *actsvr;
+ ITfCategoryMgr *catmgr;
+ AtsEntry *entry;
+ ITfThreadMgr *tm = (ITfThreadMgr*)TlsGetValue(tlsIndex);
+ ITfClientId *clientid;
+
+ if (!tm) return E_UNEXPECTED;
+
+ actsvr = HeapAlloc(GetProcessHeap(),0,sizeof(ActivatedTextService));
+ if (!actsvr) return E_OUTOFMEMORY;
+
+ entry = HeapAlloc(GetProcessHeap(),0,sizeof(AtsEntry));
+
+ if (!entry)
+ {
+ HeapFree(GetProcessHeap(),0,actsvr);
+ return E_OUTOFMEMORY;
+ }
+
+ ITfThreadMgr_QueryInterface(tm,&IID_ITfClientId,(LPVOID)&clientid);
+ ITfClientId_GetClientId(clientid, &lp->clsid, &actsvr->tid);
+ ITfClientId_Release(clientid);
+
+ if (!actsvr->tid)
+ {
+ HeapFree(GetProcessHeap(),0,actsvr);
+ return E_OUTOFMEMORY;
+ }
+
+ actsvr->pITfTextInputProcessor = NULL;
+ actsvr->LanguageProfile = *lp;
+ actsvr->LanguageProfile.fActive = TRUE;
+
+ /* get TIP category */
+ if (SUCCEEDED(CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr)))
+ {
+ static const GUID *list[3] = {&GUID_TFCAT_TIP_SPEECH, &GUID_TFCAT_TIP_KEYBOARD, &GUID_TFCAT_TIP_HANDWRITING};
+
+ ITfCategoryMgr_FindClosestCategory(catmgr,
+ &actsvr->LanguageProfile.clsid, &actsvr->LanguageProfile.catid,
+ list, 3);
+
+ ITfCategoryMgr_Release(catmgr);
+ }
+ else
+ {
+ ERR("CategoryMgr construction failed\n");
+ actsvr->LanguageProfile.catid = GUID_NULL;
+ }
+
+ if (!IsEqualGUID(&actsvr->LanguageProfile.catid,&GUID_NULL))
+ deactivate_remove_conflicting_ts(&actsvr->LanguageProfile.catid);
+
+ entry->ats = actsvr;
+ list_add_head(&AtsList, &entry->entry);
+
+ return S_OK;
+}
+
+BOOL get_active_textservice(REFCLSID rclsid, TF_LANGUAGEPROFILE *profile)
+{
+ AtsEntry *ats;
+
+ LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry)
+ {
+ if (IsEqualCLSID(rclsid,&ats->ats->LanguageProfile.clsid))
+ {
+ if (profile)
+ *profile = ats->ats->LanguageProfile;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+HRESULT activate_textservices(ITfThreadMgr *tm)
+{
+ HRESULT hr = S_OK;
+ AtsEntry *ats;
+
+ LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry)
+ {
+ hr = activate_given_ts(ats->ats, tm);
+ if (FAILED(hr))
+ FIXME("Failed to activate text service\n");
+ }
+ return hr;
+}
+
+HRESULT deactivate_textservices(void)
+{
+ AtsEntry *ats;
+
+ LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry)
+ deactivate_given_ts(ats->ats);
+
+ return S_OK;
+}
+
/*************************************************************************
* MSCTF DllMain
*/
diff --git a/dlls/msctf/msctf_internal.h b/dlls/msctf/msctf_internal.h
index 826c09d..7bfc221 100644
--- a/dlls/msctf/msctf_internal.h
+++ b/dlls/msctf/msctf_internal.h
@@ -40,5 +40,11 @@ extern LPVOID get_Cookie_data(DWORD id);
extern LPVOID remove_Cookie(DWORD id);
extern DWORD enumerate_Cookie(DWORD magic, DWORD *index);
+/* activated text services functions */
+extern HRESULT add_active_textservice(TF_LANGUAGEPROFILE *lp);
+extern BOOL get_active_textservice(REFCLSID rclsid, TF_LANGUAGEPROFILE *lp);
+extern HRESULT activate_textservices(ITfThreadMgr *tm);
+extern HRESULT deactivate_textservices(void);
+
extern const WCHAR szwSystemTIPKey[];
#endif /* __WINE_MSCTF_I_H */
More information about the wine-cvs
mailing list