Module: wine Branch: master Commit: 0a44a778f00c5283347646083f682333c11bccf3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=0a44a778f00c5283347646083f...
Author: Aric Stewart aric@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);