[MSCTF] Sync with Wine Staging 3.3. CORE-14434
[reactos.git] / dll / win32 / msctf / msctf.c
index 759fe7e..a19eaa1 100644 (file)
 #define COBJMACROS
 
 #include "wine/debug.h"
-#include "wine/list.h"
 #include "windef.h"
 #include "winbase.h"
 #include "winreg.h"
 #include "shlwapi.h"
 #include "shlguid.h"
 #include "comcat.h"
+#include "olectl.h"
+#include "rpcproxy.h"
 #include "msctf.h"
+#include "inputscope.h"
 
 #include "msctf_internal.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
 
-static LONG MSCTF_refCount;
-
 static HINSTANCE MSCTF_hinstance;
 
 typedef struct
@@ -53,7 +53,7 @@ typedef struct
 typedef struct {
     TF_LANGUAGEPROFILE      LanguageProfile;
     ITfTextInputProcessor   *pITfTextInputProcessor;
-    ITfThreadMgr            *pITfThreadMgr;
+    ITfThreadMgrEx          *pITfThreadMgrEx;
     ITfKeyEventSink         *pITfKeyEventSink;
     TfClientId              tid;
 } ActivatedTextService;
@@ -94,16 +94,20 @@ static const struct {
 
 typedef struct tagClassFactory
 {
-    const IClassFactoryVtbl *vtbl;
+    IClassFactory IClassFactory_iface;
     LONG   ref;
     LPFNCONSTRUCTOR ctor;
 } ClassFactory;
 
+static inline ClassFactory *impl_from_IClassFactory(IClassFactory *iface)
+{
+    return CONTAINING_RECORD(iface, ClassFactory, IClassFactory_iface);
+}
+
 static void ClassFactory_Destructor(ClassFactory *This)
 {
     TRACE("Destroying class factory %p\n", This);
     HeapFree(GetProcessHeap(),0,This);
-    MSCTF_refCount--;
 }
 
 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppvOut)
@@ -121,13 +125,13 @@ static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID r
 
 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
 {
-    ClassFactory *This = (ClassFactory *)iface;
+    ClassFactory *This = impl_from_IClassFactory(iface);
     return InterlockedIncrement(&This->ref);
 }
 
 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
 {
-    ClassFactory *This = (ClassFactory *)iface;
+    ClassFactory *This = impl_from_IClassFactory(iface);
     ULONG ret = InterlockedDecrement(&This->ref);
 
     if (ret == 0)
@@ -137,7 +141,7 @@ static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
 
 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID iid, LPVOID *ppvOut)
 {
-    ClassFactory *This = (ClassFactory *)iface;
+    ClassFactory *This = impl_from_IClassFactory(iface);
     HRESULT ret;
     IUnknown *obj;
 
@@ -152,15 +156,10 @@ static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown
 
 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
 {
-    ClassFactory *This = (ClassFactory *)iface;
+    ClassFactory *This = impl_from_IClassFactory(iface);
 
     TRACE("(%p)->(%x)\n", This, fLock);
 
-    if(fLock)
-        InterlockedIncrement(&MSCTF_refCount);
-    else
-        InterlockedDecrement(&MSCTF_refCount);
-
     return S_OK;
 }
 
@@ -178,12 +177,11 @@ static const IClassFactoryVtbl ClassFactoryVtbl = {
 static HRESULT ClassFactory_Constructor(LPFNCONSTRUCTOR ctor, LPVOID *ppvOut)
 {
     ClassFactory *This = HeapAlloc(GetProcessHeap(),0,sizeof(ClassFactory));
-    This->vtbl = &ClassFactoryVtbl;
+    This->IClassFactory_iface.lpVtbl = &ClassFactoryVtbl;
     This->ref = 1;
     This->ctor = ctor;
-    *ppvOut = This;
+    *ppvOut = &This->IClassFactory_iface;
     TRACE("Created class factory %p\n", This);
-    MSCTF_refCount++;
     return S_OK;
 }
 
@@ -192,7 +190,7 @@ static HRESULT ClassFactory_Constructor(LPFNCONSTRUCTOR ctor, LPVOID *ppvOut)
  */
 DWORD generate_Cookie(DWORD magic, LPVOID data)
 {
-    int i;
+    UINT i;
 
     /* try to reuse IDs if possible */
     for (i = 0; i < id_last; i++)
@@ -276,7 +274,7 @@ LPVOID remove_Cookie(DWORD id)
 
 DWORD enumerate_Cookie(DWORD magic, DWORD *index)
 {
-    int i;
+    unsigned int i;
     for (i = *index; i < id_last; i++)
         if (cookies[i].id != 0 && cookies[i].magic == magic)
         {
@@ -286,10 +284,58 @@ DWORD enumerate_Cookie(DWORD magic, DWORD *index)
     return 0x0;
 }
 
+HRESULT advise_sink(struct list *sink_list, REFIID riid, DWORD cookie_magic, IUnknown *unk, DWORD *cookie)
+{
+    Sink *sink;
+
+    sink = HeapAlloc(GetProcessHeap(), 0, sizeof(*sink));
+    if (!sink)
+        return E_OUTOFMEMORY;
+
+    if (FAILED(IUnknown_QueryInterface(unk, riid, (void**)&sink->interfaces.pIUnknown)))
+    {
+        HeapFree(GetProcessHeap(), 0, sink);
+        return CONNECT_E_CANNOTCONNECT;
+    }
+
+    list_add_head(sink_list, &sink->entry);
+    *cookie = generate_Cookie(cookie_magic, sink);
+    TRACE("cookie %x\n", *cookie);
+    return S_OK;
+}
+
+static void free_sink(Sink *sink)
+{
+    list_remove(&sink->entry);
+    IUnknown_Release(sink->interfaces.pIUnknown);
+    HeapFree(GetProcessHeap(), 0, sink);
+}
+
+HRESULT unadvise_sink(DWORD cookie)
+{
+    Sink *sink;
+
+    sink = remove_Cookie(cookie);
+    if (!sink)
+        return CONNECT_E_NOCONNECTION;
+
+    free_sink(sink);
+    return S_OK;
+}
+
+void free_sinks(struct list *sink_list)
+{
+    while(!list_empty(sink_list))
+    {
+        Sink* sink = LIST_ENTRY(sink_list->next, Sink, entry);
+        free_sink(sink);
+    }
+}
+
 /*****************************************************************************
  * Active Text Service Management
  *****************************************************************************/
-static HRESULT activate_given_ts(ActivatedTextService *actsvr, ITfThreadMgrtm)
+static HRESULT activate_given_ts(ActivatedTextService *actsvr, ITfThreadMgrEx *tm)
 {
     HRESULT hr;
 
@@ -301,7 +347,7 @@ static HRESULT activate_given_ts(ActivatedTextService *actsvr, ITfThreadMgr* tm)
         &IID_ITfTextInputProcessor, (void**)&actsvr->pITfTextInputProcessor);
     if (FAILED(hr)) return hr;
 
-    hr = ITfTextInputProcessor_Activate(actsvr->pITfTextInputProcessor, tm, actsvr->tid);
+    hr = ITfTextInputProcessor_Activate(actsvr->pITfTextInputProcessor, (ITfThreadMgr *)tm, actsvr->tid);
     if (FAILED(hr))
     {
         ITfTextInputProcessor_Release(actsvr->pITfTextInputProcessor);
@@ -309,8 +355,8 @@ static HRESULT activate_given_ts(ActivatedTextService *actsvr, ITfThreadMgr* tm)
         return hr;
     }
 
-    actsvr->pITfThreadMgr = tm;
-    ITfThreadMgr_AddRef(tm);
+    actsvr->pITfThreadMgrEx = tm;
+    ITfThreadMgrEx_AddRef(tm);
     return hr;
 }
 
@@ -322,9 +368,9 @@ static HRESULT deactivate_given_ts(ActivatedTextService *actsvr)
     {
         hr = ITfTextInputProcessor_Deactivate(actsvr->pITfTextInputProcessor);
         ITfTextInputProcessor_Release(actsvr->pITfTextInputProcessor);
-        ITfThreadMgr_Release(actsvr->pITfThreadMgr);
+        ITfThreadMgrEx_Release(actsvr->pITfThreadMgrEx);
         actsvr->pITfTextInputProcessor = NULL;
-        actsvr->pITfThreadMgr = NULL;
+        actsvr->pITfThreadMgrEx = NULL;
     }
 
     return hr;
@@ -342,7 +388,7 @@ static void deactivate_remove_conflicting_ts(REFCLSID catid)
             list_remove(&ats->entry);
             HeapFree(GetProcessHeap(),0,ats->ats);
             HeapFree(GetProcessHeap(),0,ats);
-            /* we are guarenteeing there is only 1 */
+            /* we are guaranteeing there is only 1 */
             break;
         }
     }
@@ -353,7 +399,7 @@ HRESULT add_active_textservice(TF_LANGUAGEPROFILE *lp)
     ActivatedTextService *actsvr;
     ITfCategoryMgr *catmgr;
     AtsEntry *entry;
-    ITfThreadMgr *tm = TlsGetValue(tlsIndex);
+    ITfThreadMgrEx *tm = TlsGetValue(tlsIndex);
     ITfClientId *clientid;
 
     if (!tm) return E_UNEXPECTED;
@@ -361,7 +407,7 @@ HRESULT add_active_textservice(TF_LANGUAGEPROFILE *lp)
     actsvr = HeapAlloc(GetProcessHeap(),0,sizeof(ActivatedTextService));
     if (!actsvr) return E_OUTOFMEMORY;
 
-    ITfThreadMgr_QueryInterface(tm,&IID_ITfClientId,(LPVOID)&clientid);
+    ITfThreadMgrEx_QueryInterface(tm, &IID_ITfClientId, (void **)&clientid);
     ITfClientId_GetClientId(clientid, &lp->clsid, &actsvr->tid);
     ITfClientId_Release(clientid);
 
@@ -373,7 +419,6 @@ HRESULT add_active_textservice(TF_LANGUAGEPROFILE *lp)
 
     actsvr->pITfTextInputProcessor = NULL;
     actsvr->LanguageProfile = *lp;
-    actsvr->LanguageProfile.fActive = TRUE;
     actsvr->pITfKeyEventSink = NULL;
 
     /* get TIP category */
@@ -429,7 +474,7 @@ BOOL get_active_textservice(REFCLSID rclsid, TF_LANGUAGEPROFILE *profile)
     return FALSE;
 }
 
-HRESULT activate_textservices(ITfThreadMgr *tm)
+HRESULT activate_textservices(ITfThreadMgrEx *tm)
 {
     HRESULT hr = S_OK;
     AtsEntry *ats;
@@ -520,6 +565,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad)
             tlsIndex = TlsAlloc();
             break;
         case DLL_PROCESS_DETACH:
+            if (fImpLoad) break;
             TlsFree(tlsIndex);
             break;
     }
@@ -531,7 +577,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad)
  */
 HRESULT WINAPI DllCanUnloadNow(void)
 {
-    return MSCTF_refCount ? S_FALSE : S_OK;
+    return S_FALSE;
 }
 
 /***********************************************************************
@@ -553,6 +599,22 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID *ppvOut)
     return CLASS_E_CLASSNOTAVAILABLE;
 }
 
+/***********************************************************************
+ *             DllRegisterServer (MSCTF.@)
+ */
+HRESULT WINAPI DllRegisterServer(void)
+{
+    return __wine_register_resources( MSCTF_hinstance );
+}
+
+/***********************************************************************
+ *             DllUnregisterServer (MSCTF.@)
+ */
+HRESULT WINAPI DllUnregisterServer(void)
+{
+    return __wine_unregister_resources( MSCTF_hinstance );
+}
+
 /***********************************************************************
  *              TF_CreateThreadMgr (MSCTF.@)
  */
@@ -579,7 +641,7 @@ HRESULT WINAPI TF_GetThreadMgr(ITfThreadMgr **pptim)
 /***********************************************************************
  *              SetInputScope(MSCTF.@)
  */
-HRESULT WINAPI SetInputScope(HWND hwnd, INT inputscope)
+HRESULT WINAPI SetInputScope(HWND hwnd, InputScope inputscope)
 {
     FIXME("STUB: %p %i\n",hwnd,inputscope);
     return S_OK;
@@ -588,16 +650,16 @@ HRESULT WINAPI SetInputScope(HWND hwnd, INT inputscope)
 /***********************************************************************
  *              SetInputScopes(MSCTF.@)
  */
-HRESULT WINAPI SetInputScopes(HWND hwnd, const INT *pInputScopes,
+HRESULT WINAPI SetInputScopes(HWND hwnd, const InputScope *pInputScopes,
                               UINT cInputScopes, WCHAR **ppszPhraseList,
                               UINT cPhrases, WCHAR *pszRegExp, WCHAR *pszSRGS)
 {
-    int i;
+    UINT i;
     FIXME("STUB: %p ... %s %s\n",hwnd, debugstr_w(pszRegExp), debugstr_w(pszSRGS));
     for (i = 0; i < cInputScopes; i++)
-        TRACE("\tScope[%i] = %i\n",i,pInputScopes[i]);
+        TRACE("\tScope[%u] = %i\n",i,pInputScopes[i]);
     for (i = 0; i < cPhrases; i++)
-        TRACE("\tPhrase[%i] = %s\n",i,debugstr_w(ppszPhraseList[i]));
+        TRACE("\tPhrase[%u] = %s\n",i,debugstr_w(ppszPhraseList[i]));
 
     return S_OK;
 }
@@ -628,3 +690,20 @@ HRESULT WINAPI TF_CreateLangBarMgr(ITfLangBarMgr **pppbm)
     TRACE("\n");
     return LangBarMgr_Constructor(NULL,(IUnknown**)pppbm);
 }
+
+HRESULT WINAPI TF_CreateLangBarItemMgr(ITfLangBarItemMgr **pplbim)
+{
+    FIXME("stub %p\n", pplbim);
+    *pplbim = NULL;
+
+    return E_NOTIMPL;
+}
+
+/***********************************************************************
+ *              TF_InitMlngInfo (MSCTF.@)
+ */
+HRESULT WINAPI TF_InitMlngInfo(void)
+{
+    FIXME("stub\n");
+    return S_OK;
+}