user32: Move IME window procedure to user32.

This commit is contained in:
Piotr Caban 2014-11-10 13:46:18 +01:00 committed by Alexandre Julliard
parent 5ce384e191
commit 3be5c16b4d
8 changed files with 146 additions and 102 deletions

View File

@ -37,6 +37,9 @@
WINE_DEFAULT_DEBUG_CHANNEL(imm); WINE_DEFAULT_DEBUG_CHANNEL(imm);
#define IMM_INIT_MAGIC 0x19650412
BOOL WINAPI User32InitializeImmEntryTable(DWORD);
#define MAKE_FUNCPTR(f) typeof(f) * p##f #define MAKE_FUNCPTR(f) typeof(f) * p##f
typedef struct _tagImmHkl{ typedef struct _tagImmHkl{
struct list entry; struct list entry;
@ -93,15 +96,6 @@ typedef struct _tagIMMThreadData {
static DWORD tlsIndex = 0; static DWORD tlsIndex = 0;
static struct list ImmHklList = LIST_INIT(ImmHklList); static struct list ImmHklList = LIST_INIT(ImmHklList);
/* MSIME messages */
static UINT WM_MSIME_SERVICE;
static UINT WM_MSIME_RECONVERTOPTIONS;
static UINT WM_MSIME_MOUSE;
static UINT WM_MSIME_RECONVERTREQUEST;
static UINT WM_MSIME_RECONVERT;
static UINT WM_MSIME_QUERYPOSITION;
static UINT WM_MSIME_DOCUMENTFEED;
static const WCHAR szwWineIMCProperty[] = {'W','i','n','e','I','m','m','H','I','M','C','P','r','o','p','e','r','t','y',0}; static const WCHAR szwWineIMCProperty[] = {'W','i','n','e','I','m','m','H','I','M','C','P','r','o','p','e','r','t','y',0};
static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0}; static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0};
@ -110,9 +104,6 @@ static const WCHAR szImeRegFmt[] = {'S','y','s','t','e','m','\\','C','u','r','r'
static const WCHAR szwIME[] = {'I','M','E',0}; static const WCHAR szwIME[] = {'I','M','E',0};
static LRESULT WINAPI DefIME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam);
#define is_himc_ime_unicode(p) (p->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE) #define is_himc_ime_unicode(p) (p->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE)
#define is_kbd_ime_unicode(p) (p->imeInfo.fdwProperty & IME_PROP_UNICODE) #define is_kbd_ime_unicode(p) (p->imeInfo.fdwProperty & IME_PROP_UNICODE)
@ -347,6 +338,12 @@ static ImmHkl *IMM_GetImmHkl(HKL hkl)
} }
#undef LOAD_FUNCPTR #undef LOAD_FUNCPTR
HWND WINAPI __wine_get_ui_window(HKL hkl)
{
ImmHkl *immHkl = IMM_GetImmHkl(hkl);
return immHkl->UIWnd;
}
static void IMM_FreeAllImmHkl(void) static void IMM_FreeAllImmHkl(void)
{ {
ImmHkl *ptr,*cursor2; ImmHkl *ptr,*cursor2;
@ -365,43 +362,20 @@ static void IMM_FreeAllImmHkl(void)
} }
} }
static void IMM_RegisterMessages(void)
{
WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
}
static void IMM_RegisterIMEClass(void)
{
WNDCLASSW wndClass;
ZeroMemory(&wndClass, sizeof(WNDCLASSW));
wndClass.style = CS_GLOBALCLASS;
wndClass.lpfnWndProc = (WNDPROC) DefIME_WindowProc;
wndClass.cbWndExtra = 2 * sizeof(LONG_PTR);
wndClass.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
wndClass.lpszClassName = szwIME;
RegisterClassW(&wndClass);
}
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved) BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
{ {
TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved); TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
switch (fdwReason) switch (fdwReason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
IMM_RegisterMessages();
tlsIndex = TlsAlloc(); tlsIndex = TlsAlloc();
if (tlsIndex == TLS_OUT_OF_INDEXES) if (tlsIndex == TLS_OUT_OF_INDEXES)
return FALSE; return FALSE;
IMM_RegisterIMEClass(); if (!User32InitializeImmEntryTable(IMM_INIT_MAGIC))
{
TlsFree(tlsIndex);
return FALSE;
}
break; break;
case DLL_THREAD_ATTACH: case DLL_THREAD_ATTACH:
break; break;
@ -413,7 +387,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
IMM_FreeThreadData(); IMM_FreeThreadData();
IMM_FreeAllImmHkl(); IMM_FreeAllImmHkl();
TlsFree(tlsIndex); TlsFree(tlsIndex);
UnregisterClassW(szwIME, NULL);
break; break;
} }
return TRUE; return TRUE;
@ -2940,53 +2913,3 @@ BOOL WINAPI ImmGetHotKey(DWORD hotkey, UINT *modifiers, UINT *key, HKL hkl)
FIXME("%x, %p, %p, %p: stub\n", hotkey, modifiers, key, hkl); FIXME("%x, %p, %p, %p: stub\n", hotkey, modifiers, key, hkl);
return FALSE; return FALSE;
} }
/*
* Window Proc for the Default IME window class
*/
static LRESULT WINAPI DefIME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
case WM_NCCREATE:
return TRUE;
case WM_IME_STARTCOMPOSITION:
case WM_IME_ENDCOMPOSITION:
case WM_IME_COMPOSITION:
case WM_IME_SETCONTEXT:
case WM_IME_NOTIFY:
case WM_IME_CONTROL:
case WM_IME_COMPOSITIONFULL:
case WM_IME_SELECT:
case WM_IME_CHAR:
case WM_IME_REQUEST:
case WM_IME_KEYDOWN:
case WM_IME_KEYUP:
{
ImmHkl *immHkl = IMM_GetImmHkl(GetKeyboardLayout(0));
if (immHkl->UIWnd)
return SendMessageW(immHkl->UIWnd,uMsg,wParam,lParam);
else
return FALSE;
}
default:
if ((uMsg == WM_MSIME_RECONVERTOPTIONS) ||
(uMsg == WM_MSIME_SERVICE) ||
(uMsg == WM_MSIME_MOUSE) ||
(uMsg == WM_MSIME_RECONVERTREQUEST) ||
(uMsg == WM_MSIME_RECONVERT) ||
(uMsg == WM_MSIME_QUERYPOSITION) ||
(uMsg == WM_MSIME_DOCUMENTFEED))
{
ImmHkl *immHkl = IMM_GetImmHkl(GetKeyboardLayout(0));
if (immHkl->UIWnd)
return SendMessageW(immHkl->UIWnd,uMsg,wParam,lParam);
else
return FALSE;
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
}

View File

@ -110,3 +110,7 @@
@ stub ImmWINNLSEnableIME @ stub ImmWINNLSEnableIME
@ stub ImmWINNLSGetEnableStatus @ stub ImmWINNLSGetEnableStatus
@ stub ImmWINNLSGetIMEHotkey @ stub ImmWINNLSGetIMEHotkey
################################################################
# Wine internal extensions
@ stdcall __wine_get_ui_window(ptr)

View File

@ -447,6 +447,7 @@ static BOOL WINAPI register_builtins( INIT_ONCE *once, void *param, void **conte
register_builtin( &MENU_builtin_class ); register_builtin( &MENU_builtin_class );
register_builtin( &SCROLL_builtin_class ); register_builtin( &SCROLL_builtin_class );
register_builtin( &STATIC_builtin_class ); register_builtin( &STATIC_builtin_class );
register_builtin( &IME_builtin_class );
return TRUE; return TRUE;
} }

View File

@ -42,6 +42,7 @@ enum builtin_winprocs
WINPROC_MDICLIENT, WINPROC_MDICLIENT,
WINPROC_SCROLLBAR, WINPROC_SCROLLBAR,
WINPROC_STATIC, WINPROC_STATIC,
WINPROC_IME,
/* unicode-only procs */ /* unicode-only procs */
WINPROC_DESKTOP, WINPROC_DESKTOP,
WINPROC_ICONTITLE, WINPROC_ICONTITLE,
@ -78,7 +79,10 @@ extern const struct builtin_class_descr MENU_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr MESSAGE_builtin_class DECLSPEC_HIDDEN; extern const struct builtin_class_descr MESSAGE_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr SCROLL_builtin_class DECLSPEC_HIDDEN; extern const struct builtin_class_descr SCROLL_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr STATIC_builtin_class DECLSPEC_HIDDEN; extern const struct builtin_class_descr STATIC_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr IME_builtin_class DECLSPEC_HIDDEN;
extern LRESULT WINAPI ImeWndProcA(HWND,UINT,WPARAM,LPARAM);
extern LRESULT WINAPI ImeWndProcW(HWND,UINT,WPARAM,LPARAM);
extern LRESULT WINAPI DesktopWndProc(HWND,UINT,WPARAM,LPARAM) DECLSPEC_HIDDEN; extern LRESULT WINAPI DesktopWndProc(HWND,UINT,WPARAM,LPARAM) DECLSPEC_HIDDEN;
extern LRESULT WINAPI IconTitleWndProc(HWND,UINT,WPARAM,LPARAM) DECLSPEC_HIDDEN; extern LRESULT WINAPI IconTitleWndProc(HWND,UINT,WPARAM,LPARAM) DECLSPEC_HIDDEN;
extern LRESULT WINAPI PopupMenuWndProc(HWND,UINT,WPARAM,LPARAM) DECLSPEC_HIDDEN; extern LRESULT WINAPI PopupMenuWndProc(HWND,UINT,WPARAM,LPARAM) DECLSPEC_HIDDEN;

View File

@ -29,6 +29,7 @@
#include "winuser.h" #include "winuser.h"
#include "winnls.h" #include "winnls.h"
#include "winternl.h" #include "winternl.h"
#include "controls.h"
#include "user_private.h" #include "user_private.h"
#include "wine/unicode.h" #include "wine/unicode.h"
@ -36,6 +37,18 @@
WINE_DEFAULT_DEBUG_CHANNEL(win); WINE_DEFAULT_DEBUG_CHANNEL(win);
#define IMM_INIT_MAGIC 0x19650412
static HWND (WINAPI *imm_get_ui_window)(HKL);
/* MSIME messages */
static UINT WM_MSIME_SERVICE;
static UINT WM_MSIME_RECONVERTOPTIONS;
static UINT WM_MSIME_MOUSE;
static UINT WM_MSIME_RECONVERTREQUEST;
static UINT WM_MSIME_RECONVERT;
static UINT WM_MSIME_QUERYPOSITION;
static UINT WM_MSIME_DOCUMENTFEED;
/* USER signal proc flags and codes */ /* USER signal proc flags and codes */
/* See UserSignalProc for comments */ /* See UserSignalProc for comments */
#define USIG_FLAGS_WIN32 0x0001 #define USIG_FLAGS_WIN32 0x0001
@ -597,9 +610,31 @@ VOID WINAPI LoadLocalFonts(VOID)
/*********************************************************************** /***********************************************************************
* User32InitializeImmEntryTable * User32InitializeImmEntryTable
*/ */
BOOL WINAPI User32InitializeImmEntryTable(LPVOID ptr) BOOL WINAPI User32InitializeImmEntryTable(DWORD magic)
{ {
FIXME("(%p): stub\n", ptr); static const WCHAR imm32_dllW[] = {'i','m','m','3','2','.','d','l','l',0};
HMODULE imm32 = GetModuleHandleW(imm32_dllW);
TRACE("(%x)\n", magic);
if (!imm32 || magic != IMM_INIT_MAGIC)
return FALSE;
if (imm_get_ui_window)
return TRUE;
WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
/* this part is not compatible with native imm32.dll */
imm_get_ui_window = (void*)GetProcAddress(imm32, "__wine_get_ui_window");
if (!imm_get_ui_window)
FIXME("native imm32.dll not supported\n");
return TRUE; return TRUE;
} }
@ -694,3 +729,78 @@ BOOL WINAPI SetGestureConfig( HWND hwnd, DWORD reserved, UINT id, PGESTURECONFIG
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0; return 0;
} }
static const WCHAR imeW[] = {'I','M','E',0};
const struct builtin_class_descr IME_builtin_class =
{
imeW, /* name */
0, /* style */
WINPROC_IME, /* proc */
2*sizeof(LONG_PTR), /* extra */
IDC_ARROW, /* cursor */
0 /* brush */
};
static BOOL is_ime_ui_msg( UINT msg )
{
switch(msg) {
case WM_IME_STARTCOMPOSITION:
case WM_IME_ENDCOMPOSITION:
case WM_IME_COMPOSITION:
case WM_IME_SETCONTEXT:
case WM_IME_NOTIFY:
case WM_IME_CONTROL:
case WM_IME_COMPOSITIONFULL:
case WM_IME_SELECT:
case WM_IME_CHAR:
case WM_IME_REQUEST:
case WM_IME_KEYDOWN:
case WM_IME_KEYUP:
return TRUE;
default:
if ((msg == WM_MSIME_RECONVERTOPTIONS) ||
(msg == WM_MSIME_SERVICE) ||
(msg == WM_MSIME_MOUSE) ||
(msg == WM_MSIME_RECONVERTREQUEST) ||
(msg == WM_MSIME_RECONVERT) ||
(msg == WM_MSIME_QUERYPOSITION) ||
(msg == WM_MSIME_DOCUMENTFEED))
return TRUE;
return FALSE;
}
}
LRESULT WINAPI ImeWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
HWND uiwnd;
if (msg==WM_CREATE || msg==WM_NCCREATE)
return TRUE;
if (imm_get_ui_window && is_ime_ui_msg(msg))
{
if ((uiwnd = imm_get_ui_window(GetKeyboardLayout(0))))
return SendMessageA(uiwnd, msg, wParam, lParam);
return FALSE;
}
return DefWindowProcA(hwnd, msg, wParam, lParam);
}
LRESULT WINAPI ImeWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
HWND uiwnd;
if (msg==WM_CREATE || msg==WM_NCCREATE)
return TRUE;
if (imm_get_ui_window && is_ime_ui_msg(msg))
{
if ((uiwnd = imm_get_ui_window(GetKeyboardLayout(0))))
return SendMessageW(uiwnd, msg, wParam, lParam);
return FALSE;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}

View File

@ -1107,7 +1107,6 @@ static void test_IME(void)
char module_name[MAX_PATH], *ptr; char module_name[MAX_PATH], *ptr;
MEMORY_BASIC_INFORMATION mbi; MEMORY_BASIC_INFORMATION mbi;
HMODULE imm32 = NULL;
WNDCLASSW wnd_classw; WNDCLASSW wnd_classw;
WNDCLASSA wnd_class; WNDCLASSA wnd_class;
SIZE_T size; SIZE_T size;
@ -1119,15 +1118,13 @@ static void test_IME(void)
return; return;
} }
todo_wine ok(GetModuleHandleA("imm32") != 0, "imm32.dll is not loaded\n"); ok(GetModuleHandleA("imm32") != 0, "imm32.dll is not loaded\n");
if (!GetModuleHandleA("imm32"))
imm32 = LoadLibraryA("imm32");
ret = GetClassInfoA(NULL, "IME", &wnd_class); ret = GetClassInfoA(NULL, "IME", &wnd_class);
ok(ret, "GetClassInfo failed: %d\n", GetLastError()); ok(ret, "GetClassInfo failed: %d\n", GetLastError());
size = VirtualQuery(wnd_class.lpfnWndProc, &mbi, sizeof(mbi)); size = VirtualQuery(wnd_class.lpfnWndProc, &mbi, sizeof(mbi));
todo_wine ok(size == sizeof(mbi), "VirtualQuery returned %ld\n", size); ok(size == sizeof(mbi), "VirtualQuery returned %ld\n", size);
if (size == sizeof(mbi)) { if (size == sizeof(mbi)) {
size = GetModuleFileNameA(mbi.AllocationBase, module_name, sizeof(module_name)); size = GetModuleFileNameA(mbi.AllocationBase, module_name, sizeof(module_name));
ok(size, "GetModuleFileName failed\n"); ok(size, "GetModuleFileName failed\n");
@ -1147,9 +1144,7 @@ static void test_IME(void)
for (ptr = module_name+size-1; ptr > module_name; ptr--) for (ptr = module_name+size-1; ptr > module_name; ptr--)
if (*ptr == '\\' || *ptr == '/') break; if (*ptr == '\\' || *ptr == '/') break;
if (*ptr == '\\' || *ptr=='/') ptr++; if (*ptr == '\\' || *ptr=='/') ptr++;
todo_wine ok(!lstrcmpiA(ptr, "user32.dll") || !lstrcmpiA(ptr, "ntdll.dll"), "IME window proc implemented in %s\n", ptr); ok(!lstrcmpiA(ptr, "user32.dll") || !lstrcmpiA(ptr, "ntdll.dll"), "IME window proc implemented in %s\n", ptr);
if (imm32) FreeLibrary(imm32);
} }
START_TEST(class) START_TEST(class)

View File

@ -322,18 +322,24 @@ static void thread_detach(void)
*/ */
BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
{ {
static const WCHAR imm32_dllW[] = {'i','m','m','3','2','.','d','l','l',0};
static HMODULE imm32_module;
BOOL ret = TRUE; BOOL ret = TRUE;
switch(reason) switch(reason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
user32_module = inst; user32_module = inst;
ret = process_attach(); ret = process_attach();
if(ret)
imm32_module = LoadLibraryW(imm32_dllW);
break; break;
case DLL_THREAD_DETACH: case DLL_THREAD_DETACH:
thread_detach(); thread_detach();
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
USER_unload_driver(); USER_unload_driver();
FreeLibrary(imm32_module);
DeleteCriticalSection(&user_section); DeleteCriticalSection(&user_section);
break; break;
} }

View File

@ -75,6 +75,7 @@ static WINDOWPROC winproc_array[MAX_WINPROCS] =
{ MDIClientWndProcA, MDIClientWndProcW }, /* WINPROC_MDICLIENT */ { MDIClientWndProcA, MDIClientWndProcW }, /* WINPROC_MDICLIENT */
{ ScrollBarWndProcA, ScrollBarWndProcW }, /* WINPROC_SCROLLBAR */ { ScrollBarWndProcA, ScrollBarWndProcW }, /* WINPROC_SCROLLBAR */
{ StaticWndProcA, StaticWndProcW }, /* WINPROC_STATIC */ { StaticWndProcA, StaticWndProcW }, /* WINPROC_STATIC */
{ ImeWndProcA, ImeWndProcW }, /* WINPROC_IME */
{ NULL, DesktopWndProc }, /* WINPROC_DESKTOP */ { NULL, DesktopWndProc }, /* WINPROC_DESKTOP */
{ NULL, IconTitleWndProc }, /* WINPROC_ICONTITLE */ { NULL, IconTitleWndProc }, /* WINPROC_ICONTITLE */
{ NULL, PopupMenuWndProc }, /* WINPROC_MENU */ { NULL, PopupMenuWndProc }, /* WINPROC_MENU */