imm32: Begin to add basic framework for loading IMEs as dlls.
This commit is contained in:
parent
8be2adf398
commit
0a44a778f0
134
dlls/imm32/imm.c
134
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);
|
||||
|
|
Loading…
Reference in New Issue