Commit 0a44a778 authored by Aric Stewart's avatar Aric Stewart Committed by Alexandre Julliard

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

parent 8be2adf3
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "ddk/imm.h" #include "ddk/imm.h"
#include "winnls.h" #include "winnls.h"
#include "winreg.h" #include "winreg.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(imm); WINE_DEFAULT_DEBUG_CHANNEL(imm);
...@@ -44,6 +45,35 @@ typedef struct tagIMCCInternal ...@@ -44,6 +45,35 @@ typedef struct tagIMCCInternal
DWORD dwSize; DWORD dwSize;
} IMCCInternal; } 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 typedef struct tagInputContextData
{ {
BOOL bInternalState; BOOL bInternalState;
...@@ -53,6 +83,8 @@ typedef struct tagInputContextData ...@@ -53,6 +83,8 @@ typedef struct tagInputContextData
DWORD dwLock; DWORD dwLock;
INPUTCONTEXT IMC; INPUTCONTEXT IMC;
ImmHkl *immKbd;
} InputContextData; } InputContextData;
typedef struct _tagTRANSMSG { typedef struct _tagTRANSMSG {
...@@ -67,6 +99,8 @@ static HANDLE hImeInst; ...@@ -67,6 +99,8 @@ static HANDLE hImeInst;
static const WCHAR WC_IMECLASSNAME[] = {'I','M','E',0}; static const WCHAR WC_IMECLASSNAME[] = {'I','M','E',0};
static ATOM atIMEClass = 0; static ATOM atIMEClass = 0;
static struct list ImmHklList = LIST_INIT(ImmHklList);
/* MSIME messages */ /* MSIME messages */
static UINT WM_MSIME_SERVICE; static UINT WM_MSIME_SERVICE;
static UINT WM_MSIME_RECONVERTOPTIONS; static UINT WM_MSIME_RECONVERTOPTIONS;
...@@ -86,6 +120,77 @@ static void ImmInternalPostIMEMessage(InputContextData*, UINT, WPARAM, LPARAM); ...@@ -86,6 +120,77 @@ static void ImmInternalPostIMEMessage(InputContextData*, UINT, WPARAM, LPARAM);
static void ImmInternalSetOpenStatus(BOOL fOpen); static void ImmInternalSetOpenStatus(BOOL fOpen);
static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len); 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) static VOID IMM_PostResult(InputContextData *data)
{ {
unsigned int i; unsigned int i;
...@@ -167,6 +272,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved) ...@@ -167,6 +272,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
hwndDefault = 0; hwndDefault = 0;
} }
IMM_Unregister(); IMM_Unregister();
IMM_FreeAllImmHkl();
break; break;
} }
return TRUE; return TRUE;
...@@ -610,10 +716,34 @@ HIMC WINAPI ImmCreateContext(void) ...@@ -610,10 +716,34 @@ HIMC WINAPI ImmCreateContext(void)
new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData)); 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 */ /* hCompStr is never NULL */
new_context->IMC.hCompStr = ImmCreateBlankCompStr(); new_context->IMC.hCompStr = ImmCreateBlankCompStr();
new_context->IMC.hMsgBuf = ImmCreateIMCC(1); 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; return (HIMC)new_context;
} }
...@@ -628,6 +758,10 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC) ...@@ -628,6 +758,10 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC)
if (hIMC) if (hIMC)
{ {
data->immKbd->uSelected --;
if (data->immKbd->hIME)
data->immKbd->pImeSelect(hIMC, FALSE);
ImmDestroyIMCC(data->IMC.hCompStr); ImmDestroyIMCC(data->IMC.hCompStr);
ImmDestroyIMCC(data->IMC.hCandInfo); ImmDestroyIMCC(data->IMC.hCandInfo);
ImmDestroyIMCC(data->IMC.hGuideLine); ImmDestroyIMCC(data->IMC.hGuideLine);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment