Aric Stewart : imm32: Begin to add basic framework for loading IMEs as dlls .

Alexandre Julliard julliard at winehq.org
Tue Apr 1 06:51:34 CDT 2008


Module: wine
Branch: master
Commit: 0a44a778f00c5283347646083f682333c11bccf3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0a44a778f00c5283347646083f682333c11bccf3

Author: Aric Stewart <aric at codeweavers.com>
Date:   Mon Mar 31 09:15:29 2008 -0500

imm32: Begin to add basic framework for loading IMEs as dlls.

---

 dlls/imm32/imm.c |  134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 134 insertions(+), 0 deletions(-)

diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c
index 950fdc5..9173d1b 100644
--- a/dlls/imm32/imm.c
+++ b/dlls/imm32/imm.c
@@ -31,6 +31,7 @@
 #include "ddk/imm.h"
 #include "winnls.h"
 #include "winreg.h"
+#include "wine/list.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(imm);
 
@@ -44,6 +45,35 @@ typedef struct tagIMCCInternal
     DWORD dwSize;
 } IMCCInternal;
 
+#define MAKE_FUNCPTR(f) typeof(f) * p##f
+typedef struct _tagImmHkl{
+    struct list entry;
+    HKL         hkl;
+    HMODULE     hIME;
+    IMEINFO     imeInfo;
+    WCHAR       imeClassName[17]; /* 16 character max */
+    ULONG       uSelected;
+
+    /* Function Pointers */
+    MAKE_FUNCPTR(ImeInquire);
+    MAKE_FUNCPTR(ImeConfigure);
+    MAKE_FUNCPTR(ImeDestroy);
+    MAKE_FUNCPTR(ImeEscape);
+    MAKE_FUNCPTR(ImeSelect);
+    MAKE_FUNCPTR(ImeSetActiveContext);
+    MAKE_FUNCPTR(ImeToAsciiEx);
+    MAKE_FUNCPTR(NotifyIME);
+    MAKE_FUNCPTR(ImeRegisterWord);
+    MAKE_FUNCPTR(ImeUnregisterWord);
+    MAKE_FUNCPTR(ImeEnumRegisterWord);
+    MAKE_FUNCPTR(ImeSetCompositionString);
+    MAKE_FUNCPTR(ImeConversionList);
+    MAKE_FUNCPTR(ImeProcessKey);
+    MAKE_FUNCPTR(ImeGetRegisterWordStyle);
+    MAKE_FUNCPTR(ImeGetImeMenuItems);
+} ImmHkl;
+#undef MAKE_FUNCPTR
+
 typedef struct tagInputContextData
 {
         BOOL            bInternalState;
@@ -53,6 +83,8 @@ typedef struct tagInputContextData
 
         DWORD           dwLock;
         INPUTCONTEXT    IMC;
+
+        ImmHkl          *immKbd;
 } InputContextData;
 
 typedef struct _tagTRANSMSG {
@@ -67,6 +99,8 @@ static HANDLE hImeInst;
 static const WCHAR WC_IMECLASSNAME[] = {'I','M','E',0};
 static ATOM atIMEClass = 0;
 
+static struct list ImmHklList = LIST_INIT(ImmHklList);
+
 /* MSIME messages */
 static UINT WM_MSIME_SERVICE;
 static UINT WM_MSIME_RECONVERTOPTIONS;
@@ -86,6 +120,77 @@ static void ImmInternalPostIMEMessage(InputContextData*, UINT, WPARAM, LPARAM);
 static void ImmInternalSetOpenStatus(BOOL fOpen);
 static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len);
 
+/* ImmHkl loading and freeing */
+#define LOAD_FUNCPTR(f) if((ptr->p##f = (LPVOID)GetProcAddress(ptr->hIME, #f)) == NULL){WARN("Can't find function %s in ime\n", #f);}
+static ImmHkl *IMM_GetImmHkl(HKL hkl)
+{
+    ImmHkl *ptr;
+    WCHAR filename[MAX_PATH];
+
+    TRACE("Seeking ime for keyboard 0x%x\n",(unsigned)hkl);
+
+    LIST_FOR_EACH_ENTRY(ptr, &ImmHklList, ImmHkl, entry)
+    {
+        if (ptr->hkl == hkl)
+            return ptr;
+    }
+    /* not found... create it */
+
+    ptr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ImmHkl));
+
+    ptr->hkl = hkl;
+    ImmGetIMEFileNameW(hkl, filename, MAX_PATH);
+    ptr->hIME = LoadLibraryW(filename);
+    if (ptr->hIME)
+    {
+        LOAD_FUNCPTR(ImeInquire);
+        LOAD_FUNCPTR(ImeDestroy);
+        LOAD_FUNCPTR(ImeSelect);
+        if (!ptr->pImeInquire || !ptr->pImeDestroy || !ptr->pImeSelect)
+        {
+            FreeLibrary(ptr->hIME);
+            ptr->hIME = NULL;
+        }
+        else
+        {
+            ptr->pImeInquire(&ptr->imeInfo, ptr->imeClassName, NULL);
+            LOAD_FUNCPTR(ImeConfigure);
+            LOAD_FUNCPTR(ImeEscape);
+            LOAD_FUNCPTR(ImeSetActiveContext);
+            LOAD_FUNCPTR(ImeToAsciiEx);
+            LOAD_FUNCPTR(NotifyIME);
+            LOAD_FUNCPTR(ImeRegisterWord);
+            LOAD_FUNCPTR(ImeUnregisterWord);
+            LOAD_FUNCPTR(ImeEnumRegisterWord);
+            LOAD_FUNCPTR(ImeSetCompositionString);
+            LOAD_FUNCPTR(ImeConversionList);
+            LOAD_FUNCPTR(ImeProcessKey);
+            LOAD_FUNCPTR(ImeGetRegisterWordStyle);
+            LOAD_FUNCPTR(ImeGetImeMenuItems);
+        }
+    }
+    list_add_head(&ImmHklList,&ptr->entry);
+
+    return ptr;
+}
+#undef LOAD_FUNCPTR
+
+static void IMM_FreeAllImmHkl(void)
+{
+    ImmHkl *ptr,*cursor2;
+
+    LIST_FOR_EACH_ENTRY_SAFE(ptr, cursor2, &ImmHklList, ImmHkl, entry);
+    {
+        list_remove(&ptr->entry);
+        if (ptr->hIME)
+        {
+            ptr->pImeDestroy(1);
+            FreeLibrary(ptr->hIME);
+        }
+        HeapFree(GetProcessHeap(),0,ptr);
+    }
+}
+
 static VOID IMM_PostResult(InputContextData *data)
 {
     unsigned int i;
@@ -167,6 +272,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
                 hwndDefault = 0;
             }
             IMM_Unregister();
+            IMM_FreeAllImmHkl();
             break;
     }
     return TRUE;
@@ -610,10 +716,34 @@ HIMC WINAPI ImmCreateContext(void)
 
     new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
 
+    /* Load the IME */
+    new_context->immKbd = IMM_GetImmHkl(GetKeyboardLayout(0));
+
+    /*
+     * Once we depend on the IME for all the processing like we should
+     * these will become hard errors and result in creation failures
+     */
+    if (!new_context->immKbd->hIME)
+        TRACE("IME dll could not be loaded\n");
+
     /* hCompStr is never NULL */
     new_context->IMC.hCompStr = ImmCreateBlankCompStr();
     new_context->IMC.hMsgBuf = ImmCreateIMCC(1);
 
+    /* Initialize the IME Private */
+    new_context->IMC.hPrivate = ImmCreateIMCC(new_context->immKbd->imeInfo.dwPrivateDataSize);
+
+    if (new_context->immKbd->hIME &&
+        !new_context->immKbd->pImeSelect(new_context, TRUE))
+    {
+        TRACE("Selection of IME failed\n");
+        ImmDestroyContext(new_context);
+        return 0;
+    }
+
+    new_context->immKbd->uSelected++;
+    TRACE("Created context 0x%x\n",(UINT)new_context);
+
     return (HIMC)new_context;
 }
 
@@ -628,6 +758,10 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC)
 
     if (hIMC)
     {
+        data->immKbd->uSelected --;
+        if (data->immKbd->hIME)
+            data->immKbd->pImeSelect(hIMC, FALSE);
+
         ImmDestroyIMCC(data->IMC.hCompStr);
         ImmDestroyIMCC(data->IMC.hCandInfo);
         ImmDestroyIMCC(data->IMC.hGuideLine);




More information about the wine-cvs mailing list