From 185157cb6eb25bc5e75e9a260b593e98153d2255 Mon Sep 17 00:00:00 2001 From: Kusanagi Kouichi Date: Fri, 4 Apr 2008 20:44:36 +0900 Subject: [PATCH] winex11: Connect to XIM server dynamically. --- dlls/winex11.drv/window.c | 9 ++--- dlls/winex11.drv/x11drv.h | 14 +++---- dlls/winex11.drv/x11drv_main.c | 2 +- dlls/winex11.drv/xim.c | 69 +++++++++++++++++++++++++++++----- 4 files changed, 72 insertions(+), 22 deletions(-) diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 4d5da02f147..cc4ff7d0d85 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1040,7 +1040,6 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat { int cx, cy, mask; XSetWindowAttributes attr; - XIM xim; WCHAR text[1024]; HRGN hrgn; @@ -1080,9 +1079,6 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat return 0; } - xim = x11drv_thread_data()->xim; - if (xim) data->xic = X11DRV_CreateIC( xim, display, data->whole_window ); - set_initial_wm_hints( display, data ); X11DRV_set_wm_hints( display, data ); @@ -1404,9 +1400,12 @@ Window X11DRV_get_client_window( HWND hwnd ) XIC X11DRV_get_ic( HWND hwnd ) { struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); + XIM xim; if (!data) return 0; - return data->xic; + if (data->xic) return data->xic; + if (!(xim = x11drv_thread_data()->xim)) return 0; + return X11DRV_CreateIC( xim, data ); } diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index d6b2b204c3a..939872f3203 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -273,13 +273,6 @@ extern void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev); extern Drawable get_glxdrawable(X11DRV_PDEVICE *physDev); extern BOOL destroy_glxpixmap(Display *display, XID glxpixmap); -/* XIM support */ -extern BOOL X11DRV_InitXIM( const char *input_style ); -extern XIC X11DRV_CreateIC(XIM xim, Display *display, Window win); -extern XIM X11DRV_SetupXIM(Display *display); -extern void X11DRV_XIMLookupChars( const char *str, DWORD count ); -extern void X11DRV_ForceXIMReset(HWND hwnd); - /* IME support */ extern void IME_RegisterClasses(HINSTANCE hImeInst); extern void IME_UnregisterClasses(HINSTANCE hImeInst); @@ -772,6 +765,13 @@ LPDDHALMODEINFO X11DRV_Settings_SetHandlers(const char *name, extern void X11DRV_DDHAL_SwitchMode(DWORD dwModeIndex, LPVOID fb_addr, LPVIDMEM fb_mem); +/* XIM support */ +extern BOOL X11DRV_InitXIM( const char *input_style ); +extern XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data); +extern void X11DRV_SetupXIM(void); +extern void X11DRV_XIMLookupChars( const char *str, DWORD count ); +extern void X11DRV_ForceXIMReset(HWND hwnd); + /* FIXME: private functions imported from user32 */ extern LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode ); extern void WIN_invalidate_dce( HWND hwnd, const RECT *rect ); diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 1c221bc90c6..b9378c89146 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -653,7 +653,7 @@ struct x11drv_thread_data *x11drv_init_thread_data(void) set_queue_display_fd( data->display ); TlsSetValue( thread_data_tls_index, data ); - if (use_xim) data->xim = X11DRV_SetupXIM( data->display ); + if (use_xim) X11DRV_SetupXIM(); X11DRV_SetCursor( NULL ); return data; diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index f389db718e6..d4df9f79a57 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -358,15 +358,31 @@ BOOL X11DRV_InitXIM( const char *input_style ) } +static void X11DRV_OpenIM(Display *display, XPointer p, XPointer data); + +static void X11DRV_DestroyIM(XIM xim, XPointer p, XPointer data) +{ + struct x11drv_thread_data *thread_data = x11drv_thread_data(); + + TRACE("xim = %p, p = %p\n", xim, p); + thread_data->xim = NULL; + ximStyle = 0; + wine_tsx11_lock(); + XRegisterIMInstantiateCallback( thread_data->display, NULL, NULL, NULL, X11DRV_OpenIM, NULL ); + wine_tsx11_unlock(); +} + /*********************************************************************** * X11DRV Ime creation */ -XIM X11DRV_SetupXIM( Display *display ) +static void X11DRV_OpenIM(Display *display, XPointer ptr, XPointer data) { + struct x11drv_thread_data *thread_data = x11drv_thread_data(); XIMStyle ximStyleCallback, ximStyleNone; XIMStyles *ximStyles = NULL; INT i; XIM xim; + XIMCallback destroy; wine_tsx11_lock(); @@ -374,9 +390,18 @@ XIM X11DRV_SetupXIM( Display *display ) if (xim == NULL) { WARN("Could not open input method.\n"); - goto err; + wine_tsx11_unlock(); + return; } + destroy.client_data = NULL; + destroy.callback = X11DRV_DestroyIM; + if (XSetIMValues(xim, XNDestroyCallback, &destroy, NULL)) + { + WARN("Could not set destroy callback.\n"); + } + + TRACE("xim = %p\n", xim); TRACE("X display of IM = %p\n", XDisplayOfIM(xim)); TRACE("Using %s locale of Input Method\n", XLocaleOfIM(xim)); @@ -384,6 +409,9 @@ XIM X11DRV_SetupXIM( Display *display ) if (ximStyles == 0) { WARN("Could not find supported input style.\n"); + XCloseIM(xim); + wine_tsx11_unlock(); + return; } else { @@ -443,29 +471,45 @@ XIM X11DRV_SetupXIM( Display *display ) } + thread_data->xim = xim; + XUnregisterIMInstantiateCallback(display, NULL, NULL, NULL, X11DRV_OpenIM, NULL); wine_tsx11_unlock(); IME_XIMPresent(TRUE); IME_UpdateAssociation(NULL); - - return xim; - -err: - wine_tsx11_unlock(); - return NULL; } -XIC X11DRV_CreateIC(XIM xim, Display *display, Window win) +void X11DRV_SetupXIM(void) +{ + wine_tsx11_lock(); + XRegisterIMInstantiateCallback(thread_display(), NULL, NULL, NULL, X11DRV_OpenIM, NULL); + wine_tsx11_unlock(); +} + +static BOOL X11DRV_DestroyIC(XIC xic, XPointer p, XPointer data) +{ + struct x11drv_win_data *win_data = (struct x11drv_win_data *)p; + TRACE("xic = %p, win = %lx\n", xic, win_data->whole_window); + win_data->xic = NULL; + return TRUE; +} + + +XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data) { XPoint spot = {0}; XVaNestedList preedit = NULL; XVaNestedList status = NULL; XIC xic; + XICCallback destroy = {(XPointer)data, X11DRV_DestroyIC}; XIMCallback P_StartCB; XIMCallback P_DoneCB; XIMCallback P_DrawCB; XIMCallback P_CaretCB; LANGID langid = PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())); + Window win = data->whole_window; + + TRACE("xim = %p\n", xim); wine_tsx11_lock(); @@ -478,8 +522,10 @@ XIC X11DRV_CreateIC(XIM xim, Display *display, Window win) XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, XNFocusWindow, win, + XNDestroyCallback, &destroy, NULL); wine_tsx11_unlock(); + data->xic = xic; return xic; } @@ -531,6 +577,7 @@ XIC X11DRV_CreateIC(XIM xim, Display *display, Window win) XNStatusAttributes, status, XNClientWindow, win, XNFocusWindow, win, + XNDestroyCallback, &destroy, NULL); } else if (preedit != NULL) @@ -540,6 +587,7 @@ XIC X11DRV_CreateIC(XIM xim, Display *display, Window win) XNPreeditAttributes, preedit, XNClientWindow, win, XNFocusWindow, win, + XNDestroyCallback, &destroy, NULL); } else if (status != NULL) @@ -549,6 +597,7 @@ XIC X11DRV_CreateIC(XIM xim, Display *display, Window win) XNStatusAttributes, status, XNClientWindow, win, XNFocusWindow, win, + XNDestroyCallback, &destroy, NULL); } else @@ -557,10 +606,12 @@ XIC X11DRV_CreateIC(XIM xim, Display *display, Window win) XNInputStyle, ximStyle, XNClientWindow, win, XNFocusWindow, win, + XNDestroyCallback, &destroy, NULL); } TRACE("xic = %p\n", xic); + data->xic = xic; if (preedit != NULL) XFree(preedit);