Kusanagi Kouichi : winex11: Connect to XIM server dynamically.

Alexandre Julliard julliard at winehq.org
Fri Apr 11 06:27:07 CDT 2008


Module: wine
Branch: master
Commit: 185157cb6eb25bc5e75e9a260b593e98153d2255
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=185157cb6eb25bc5e75e9a260b593e98153d2255

Author: Kusanagi Kouichi <slash at ma.neweb.ne.jp>
Date:   Fri Apr  4 20:44:36 2008 +0900

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         |   63 ++++++++++++++++++++++++++++++++++++----
 4 files changed, 69 insertions(+), 19 deletions(-)

diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 4d5da02..cc4ff7d 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 d6b2b20..939872f 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 1c221bc..b9378c8 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 f389db7..d4df9f7 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:
+void X11DRV_SetupXIM(void)
+{
+    wine_tsx11_lock();
+    XRegisterIMInstantiateCallback(thread_display(), NULL, NULL, NULL, X11DRV_OpenIM, NULL);
     wine_tsx11_unlock();
-    return NULL;
 }
 
+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, Display *display, Window win)
+
+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);




More information about the wine-cvs mailing list