When ImmAssociateContext(hwnd, 0) is called, imm should be disabled. On Debian using uim or fcitx for korean, a program cannot receive KeyPress(VK_HANGUL) because the input method consumes the key. We should change input context to disable it in ImmAssociateContext.
Signed-off-by: Dongwan Kim kdw6485@gmail.com --- dlls/imm32/imm.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index 9d2a09f22be..bf243832168 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -111,6 +111,7 @@ static CRITICAL_SECTION_DEBUG critsect_debug = }; static CRITICAL_SECTION threaddata_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; static BOOL disable_ime; +static HIMC ( *wine_associate_input_context)(HWND, HIMC);
static inline BOOL is_himc_ime_unicode(const InputContextData *data) { @@ -598,6 +599,13 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC) } }
+ if(!wine_associate_input_context){ + HMODULE h = load_graphics_driver(); + wine_associate_input_context = (LPVOID)GetProcAddress(h, "wine_associate_input_context"); + FreeLibrary(h); + } + if(wine_associate_input_context) + wine_associate_input_context(hWnd, hIMC); if (!hIMC) return old;
Connecting to input method("@im=local") means applying no filter in X11. Change the input context of the window to local im when calling ImmAossciateContext to disable Imm.
Signed-off-by: Dongwan Kim kdw6485@gmail.com --- dlls/winex11.drv/winex11.drv.spec | 3 +++ dlls/winex11.drv/x11drv.h | 1 + dlls/winex11.drv/x11drv_main.c | 4 +++ dlls/winex11.drv/xim.c | 42 +++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+)
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec index 89b9323a6c5..ad10a58481e 100644 --- a/dlls/winex11.drv/winex11.drv.spec +++ b/dlls/winex11.drv/winex11.drv.spec @@ -52,6 +52,9 @@ # Desktop @ cdecl wine_create_desktop(long long) X11DRV_create_desktop
+# Imm +@ cdecl wine_associate_input_context(long ptr) X11DRV_ImmAssociateContext + # System tray @ cdecl wine_notify_icon(long ptr)
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index c23cd512eb9..30c7f10907d 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -809,6 +809,7 @@ extern struct x11drv_display_device_handler desktop_handler DECLSPEC_HIDDEN; extern BOOL X11DRV_InitXIM( const char *input_style ) DECLSPEC_HIDDEN; extern XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data) DECLSPEC_HIDDEN; extern void X11DRV_SetupXIM(void) DECLSPEC_HIDDEN; +extern void X11DRV_FreeXIM(void) DECLSPEC_HIDDEN; extern void X11DRV_XIMLookupChars( const char *str, DWORD count ) DECLSPEC_HIDDEN; extern void X11DRV_ForceXIMReset(HWND hwnd) DECLSPEC_HIDDEN; extern void X11DRV_SetPreeditState(HWND hwnd, BOOL fOpen) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 2fac560556b..448553f2288 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -732,7 +732,11 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) x11drv_module = hinst; ret = process_attach(); break; + case DLL_PROCESS_DETACH: + X11DRV_FreeXIM(); + break; } + return ret; }
diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index 44fe62e9006..a49ef6078b8 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -442,13 +442,55 @@ static void open_xim_callback( Display *display, XPointer ptr, XPointer data ) XUnregisterIMInstantiateCallback( display, NULL, NULL, NULL, open_xim_callback, NULL); }
+ +static XIM xim_local; +void setup_xim_local(Display* display) +{ + struct x11drv_thread_data *thread_data = x11drv_thread_data(); + char* prev = XSetLocaleModifiers("@im=local"); + open_xim(display); + xim_local = thread_data->xim; + XSetLocaleModifiers(prev); +} +HIMC X11DRV_ImmAssociateContext(HWND hwnd, HIMC hIMC) +{ + struct x11drv_win_data* data; + XIM xim; + if(!hwnd) + return 0; + data = get_win_data(hwnd); + + if(data->xic) { + + XDestroyIC(data->xic); + if(hIMC == NULL) + xim = xim_local; + else + xim = x11drv_thread_data()->xim; + + X11DRV_CreateIC(xim , data); + } + release_win_data(data); + return 0; + +} + void X11DRV_SetupXIM(void) { Display *display = thread_display();
+ if(!xim_local) + setup_xim_local(display); + if (!open_xim( display )) XRegisterIMInstantiateCallback( display, NULL, NULL, NULL, open_xim_callback, NULL ); } +void X11DRV_FreeXIM(void) +{ + /* close local im */ + XCloseIM(xim_local); + xim_local=0; +}
static BOOL X11DRV_DestroyIC(XIC xic, XPointer p, XPointer data) {