winex11.drv: Connect to XIM server dynamically.
Kusanagi Kouichi
slash at ma.neweb.ne.jp
Sat Mar 29 01:23:34 CDT 2008
If I want to use XIM, I must start XIM server before wine.
Furthermore, if XIM server stops, wine can't use XIM again
even if XIM server restarts.
---
dlls/winex11.drv/window.c | 18 ++-
dlls/winex11.drv/x11drv.h | 5 +-
dlls/winex11.drv/x11drv_main.c | 5 +-
dlls/winex11.drv/xim.c | 267 ++++++++++++++++++++++++---------------
4 files changed, 182 insertions(+), 113 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index ffeed8e..1598e75 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1126,7 +1126,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;
@@ -1166,9 +1165,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 );
@@ -1487,9 +1483,19 @@ Window X11DRV_get_client_window( HWND hwnd )
XIC X11DRV_get_ic( HWND hwnd )
{
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
+ struct x11drv_thread_data *tdata;
+
+ if (!data)
+ return NULL;
+
+ if (data->xic)
+ return data->xic;
+
+ tdata = x11drv_thread_data();
+ if (!tdata->xim)
+ return NULL;
- if (!data) return 0;
- return data->xic;
+ return X11DRV_CreateIC(tdata->xim, data->whole_window, &data->xic);
}
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 52670e8..427e36c 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -274,8 +274,9 @@ extern Drawable get_glxdrawable(X11DRV_PDEVICE *physDev);
extern BOOL destroy_glxpixmap(Display *display, XID glxpixmap);
/* XIM support */
-extern XIC X11DRV_CreateIC(XIM xim, Display *display, Window win);
-extern XIM X11DRV_SetupXIM(Display *display, const char *input_style);
+extern char input_style[];
+extern XIC X11DRV_CreateIC(XIM xim, Window win, XIC *xic);
+extern BOOL X11DRV_SetupXIM(Display *display, XIM *xim);
extern void X11DRV_XIMLookupChars( const char *str, DWORD count );
extern void X11DRV_XDND_EnterEvent( HWND hWnd, XClientMessageEvent *event );
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index d445e64..f080f85 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -100,7 +100,7 @@ static int err_callback_result; /* error callback result */
static unsigned long err_serial; /* serial number of first request */
static int (*old_error_handler)( Display *, XErrorEvent * );
static int use_xim = 1;
-static char input_style[20];
+char input_style[20];
#define IS_OPTION_TRUE(ch) \
((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
@@ -651,7 +651,8 @@ struct x11drv_thread_data *x11drv_init_thread_data(void)
if (TRACE_ON(synchronous)) XSynchronize( data->display, True );
wine_tsx11_unlock();
- if (use_xim && !(data->xim = X11DRV_SetupXIM( data->display, input_style )))
+ data->xim = NULL;
+ if (use_xim && !X11DRV_SetupXIM( data->display, &data->xim ))
WARN("Input Method is not available\n");
set_queue_display_fd( data->display );
diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c
index ad28bc5..edca47c 100644
--- a/dlls/winex11.drv/xim.c
+++ b/dlls/winex11.drv/xim.c
@@ -52,8 +52,7 @@ typedef struct tagInputContextData
} InputContextData;
static HIMC root_context;
-static XIMStyle ximStyle = 0;
-static XIMStyle ximStyleRoot = 0;
+static XIMStyle ximStyle;
/* moved here from imm32 for dll separation */
static DWORD dwCompStringLength = 0;
@@ -290,7 +289,7 @@ static void XIMPreEditDoneCallback(XIC ic, XPointer client_data, XPointer call_d
dwPreeditPos = 0;
}
-static void XIMPreEditDrawCallback(XIM ic, XPointer client_data,
+static void XIMPreEditDrawCallback(XIC ic, XPointer client_data,
XIMPreeditDrawCallbackStruct *P_DR)
{
TRACE("PreEditDrawCallback %p\n",ic);
@@ -394,111 +393,135 @@ void X11DRV_ForceXIMReset(HWND hwnd)
}
}
-/***********************************************************************
-* X11DRV Ime creation
-*/
-XIM X11DRV_SetupXIM(Display *display, const char *input_style)
-{
- XIMStyle ximStyleRequest, ximStyleCallback, ximStyleNone;
- XIMStyles *ximStyles = NULL;
- INT i;
- XIM xim;
+static void X11DRV_OpenIM(Display *display, XPointer p, XPointer data);
- ximStyleRequest = STYLE_CALLBACK;
+static void X11DRV_DestroyIM(XIM xim, XPointer p, XPointer data)
+{
+ TRACE("xim = %p, p = %p\n", xim, p);
+ *(XIM *)p = NULL;
+ ximStyle = 0;
+ wine_tsx11_lock();
+ XRegisterIMInstantiateCallback(XDisplayOfIM(xim), NULL, NULL, NULL,
+ X11DRV_OpenIM, p);
+ wine_tsx11_unlock();
+}
- if (!strcasecmp(input_style, "offthespot"))
- ximStyleRequest = STYLE_OFFTHESPOT;
- else if (!strcasecmp(input_style, "overthespot"))
- ximStyleRequest = STYLE_OVERTHESPOT;
- else if (!strcasecmp(input_style, "root"))
- ximStyleRequest = STYLE_ROOT;
+static BOOL X11DRV_SelectStyle(XIM xim)
+{
+ static XIMStyle ximStyleRequest;
+ XIMStyle ximStyleCallback, ximStyleRoot, ximStyleNone;
+ XIMStyles *ximStyles;
+ INT i;
- wine_tsx11_lock();
+ if (ximStyle)
+ return TRUE;
- if(!XSupportsLocale())
+ if (!ximStyleRequest)
{
- WARN("X does not support locale.\n");
- goto err;
+ if (!strcasecmp(input_style, "offthespot"))
+ ximStyleRequest = STYLE_OFFTHESPOT;
+ else if (!strcasecmp(input_style, "overthespot"))
+ ximStyleRequest = STYLE_OVERTHESPOT;
+ else if (!strcasecmp(input_style, "root"))
+ ximStyleRequest = STYLE_ROOT;
+ else
+ ximStyleRequest = STYLE_CALLBACK;
}
- if(XSetLocaleModifiers("") == NULL)
+
+ if (XGetIMValues(xim, XNQueryInputStyle, &ximStyles, NULL))
{
- WARN("Could not set locale modifiers.\n");
- goto err;
+ WARN("Could not find supported input style.\n");
+ return FALSE;
}
- xim = XOpenIM(display, NULL, NULL, NULL);
- if (xim == NULL)
+ TRACE("ximStyles->count_styles = %d\n", ximStyles->count_styles);
+
+ ximStyleRoot = 0;
+ ximStyleNone = 0;
+ ximStyleCallback = 0;
+
+ for (i = 0; i < ximStyles->count_styles; ++i)
{
- WARN("Could not open input method.\n");
- goto err;
+ XIMStyle style = ximStyles->supported_styles[i];
+ TRACE("ximStyles[%d] = %s%s%s%s%s\n", i,
+ (style & XIMPreeditArea)? "XIMPreeditArea ": "",
+ (style & XIMPreeditCallbacks)? "XIMPreeditCallbacks ": "",
+ (style & XIMPreeditPosition)? "XIMPreeditPosition ": "",
+ (style & XIMPreeditNothing)? "XIMPreeditNothing ": "",
+ (style & XIMPreeditNone)? "XIMPreeditNone ": "");
+ if (!ximStyle && (style == ximStyleRequest))
+ {
+ ximStyle = ximStyleRequest;
+ TRACE("Setting Style: ximStyle = ximStyleRequest\n");
+ }
+
+ if (!ximStyleRoot && (style == STYLE_ROOT))
+ {
+ ximStyleRoot = STYLE_ROOT;
+ TRACE("Setting Style: ximStyleRoot = STYLE_ROOT\n");
+ }
+ else if (!ximStyleCallback && (style == STYLE_CALLBACK))
+ {
+ ximStyleCallback = STYLE_CALLBACK;
+ TRACE("Setting Style: ximStyleCallback = STYLE_CALLBACK\n");
+ }
+ else if (!ximStyleNone && (style == STYLE_NONE))
+ {
+ TRACE("Setting Style: ximStyleNone = STYLE_NONE\n");
+ ximStyleNone = STYLE_NONE;
+ }
}
+ XFree(ximStyles);
- TRACE("X display of IM = %p\n", XDisplayOfIM(xim));
- TRACE("Using %s locale of Input Method\n", XLocaleOfIM(xim));
+ if (ximStyle == 0)
+ ximStyle = ximStyleRoot;
+
+ if (ximStyle == 0)
+ ximStyle = ximStyleNone;
- XGetIMValues(xim, XNQueryInputStyle, &ximStyles, NULL);
- if (ximStyles == 0)
+ if (ximStyleCallback == 0)
{
- WARN("Could not find supported input style.\n");
+ TRACE("No callback style avalable\n");
+ ximStyleCallback = ximStyle;
}
- else
- {
- TRACE("ximStyles->count_styles = %d\n", ximStyles->count_styles);
- ximStyleRoot = 0;
- ximStyleNone = 0;
- ximStyleCallback = 0;
-
- for (i = 0; i < ximStyles->count_styles; ++i)
- {
- int style = ximStyles->supported_styles[i];
- TRACE("ximStyles[%d] = %s%s%s%s%s\n", i,
- (style&XIMPreeditArea)?"XIMPreeditArea ":"",
- (style&XIMPreeditCallbacks)?"XIMPreeditCallbacks ":"",
- (style&XIMPreeditPosition)?"XIMPreeditPosition ":"",
- (style&XIMPreeditNothing)?"XIMPreeditNothing ":"",
- (style&XIMPreeditNone)?"XIMPreeditNone ":"");
- if (!ximStyle && (ximStyles->supported_styles[i] ==
- ximStyleRequest))
- {
- ximStyle = ximStyleRequest;
- TRACE("Setting Style: ximStyle = ximStyleRequest\n");
- }
- else if (!ximStyleRoot &&(ximStyles->supported_styles[i] ==
- STYLE_ROOT))
- {
- ximStyleRoot = STYLE_ROOT;
- TRACE("Setting Style: ximStyleRoot = STYLE_ROOT\n");
- }
- else if (!ximStyleCallback &&(ximStyles->supported_styles[i] ==
- STYLE_CALLBACK))
- {
- ximStyleCallback = STYLE_CALLBACK;
- TRACE("Setting Style: ximStyleCallback = STYLE_CALLBACK\n");
- }
- else if (!ximStyleNone && (ximStyles->supported_styles[i] ==
- STYLE_NONE))
- {
- TRACE("Setting Style: ximStyleNone = STYLE_NONE\n");
- ximStyleNone = STYLE_NONE;
- }
- }
- XFree(ximStyles);
+ return TRUE;
+}
- if (ximStyle == 0)
- ximStyle = ximStyleRoot;
+static void X11DRV_OpenIM(Display *display, XPointer p, XPointer data)
+{
+ XIM xim;
+ XIMCallback destroy;
- if (ximStyle == 0)
- ximStyle = ximStyleNone;
+ wine_tsx11_lock();
+ xim = XOpenIM(display, NULL, NULL, NULL);
+ if (xim == NULL)
+ {
+ WARN("Could not open input method.\n");
+ wine_tsx11_unlock();
+ return;
+ }
- if (ximStyleCallback == 0)
- {
- TRACE("No callback style avalable\n");
- ximStyleCallback = ximStyle;
- }
+ if (!X11DRV_SelectStyle(xim))
+ {
+ XCloseIM(xim);
+ wine_tsx11_unlock();
+ return;
+ }
+ destroy.client_data = p;
+ destroy.callback = X11DRV_DestroyIM;
+ if (XSetIMValues(xim, XNDestroyCallback, &destroy, NULL))
+ {
+ WARN("Could not set destroy callback.\n");
}
+ *(XIM *)p = xim;
+ TRACE("xim = %p\n", xim);
+ TRACE("X display of IM = %p\n", XDisplayOfIM(xim));
+ TRACE("Using %s locale of Input Method\n", XLocaleOfIM(xim));
+
+ XUnregisterIMInstantiateCallback(display, NULL, NULL, NULL, X11DRV_OpenIM, p);
wine_tsx11_unlock();
if(!hImmDll)
@@ -513,26 +536,59 @@ XIM X11DRV_SetupXIM(Display *display, const char *input_style)
}
}
- return xim;
+ return;
+}
+
+/***********************************************************************
+* X11DRV Ime creation
+*/
+BOOL X11DRV_SetupXIM(Display *display, XIM *xim)
+{
+ BOOL ret = FALSE;
+
+ wine_tsx11_lock();
+
+ if(!XSupportsLocale())
+ {
+ WARN("X does not support locale.\n");
+ goto err;
+ }
+
+ if(XSetLocaleModifiers("") == NULL)
+ {
+ WARN("Could not set locale modifiers.\n");
+ goto err;
+ }
+
+ ret = XRegisterIMInstantiateCallback(display, NULL, NULL, NULL,
+ X11DRV_OpenIM, (XPointer)xim);
err:
wine_tsx11_unlock();
- return NULL;
+ return ret;
}
+static BOOL X11DRV_DestroyIC(XIC xic, XPointer p, XPointer data)
+{
+ TRACE("xic = %p, p = %p\n", xic, p);
+ *(XIC *)p = NULL;
+ return TRUE;
+}
-XIC X11DRV_CreateIC(XIM xim, Display *display, Window win)
+XIC X11DRV_CreateIC(XIM xim, Window win, XIC *p)
{
XPoint spot = {0};
XVaNestedList preedit = NULL;
XVaNestedList status = NULL;
XIC xic;
- XIMCallback P_StartCB;
- XIMCallback P_DoneCB;
- XIMCallback P_DrawCB;
- XIMCallback P_CaretCB;
+ XICCallback destroy = {(XPointer)p, X11DRV_DestroyIC};
+ XICCallback P_StartCB;
+ XICCallback P_DoneCB;
+ XICCallback P_DrawCB;
+ XICCallback P_CaretCB;
LANGID langid = PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale()));
+ TRACE("xim = %p\n", xim);
wine_tsx11_lock();
/* use complex and slow XIC initialization method only for CJK */
@@ -544,20 +600,22 @@ XIC X11DRV_CreateIC(XIM xim, Display *display, Window win)
XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
XNClientWindow, win,
XNFocusWindow, win,
+ XNDestroyCallback, &destroy,
NULL);
wine_tsx11_unlock();
+ *p = xic;
return xic;
}
/* create callbacks */
P_StartCB.client_data = NULL;
- P_StartCB.callback = (XIMProc)XIMPreEditStartCallback;
+ P_StartCB.callback = (XICProc)XIMPreEditStartCallback;
P_DoneCB.client_data = NULL;
- P_DoneCB.callback = (XIMProc)XIMPreEditDoneCallback;
+ P_DoneCB.callback = (XICProc)XIMPreEditDoneCallback;
P_DrawCB.client_data = NULL;
- P_DrawCB.callback = (XIMProc)XIMPreEditDrawCallback;
+ P_DrawCB.callback = (XICProc)XIMPreEditDrawCallback;
P_CaretCB.client_data = NULL;
- P_CaretCB.callback = (XIMProc)XIMPreEditCaretCallback;
+ P_CaretCB.callback = (XICProc)XIMPreEditCaretCallback;
if ((ximStyle & (XIMPreeditNothing | XIMPreeditNone)) == 0)
{
@@ -568,7 +626,6 @@ XIC X11DRV_CreateIC(XIM xim, Display *display, Window win)
XNPreeditDrawCallback, &P_DrawCB,
XNPreeditCaretCallback, &P_CaretCB,
NULL);
- TRACE("preedit = %p\n", preedit);
}
else
{
@@ -579,15 +636,14 @@ XIC X11DRV_CreateIC(XIM xim, Display *display, Window win)
XNPreeditCaretCallback, &P_CaretCB,
NULL);
- TRACE("preedit = %p\n", preedit);
}
+ TRACE("preedit = %p\n", preedit);
if ((ximStyle & (XIMStatusNothing | XIMStatusNone)) == 0)
{
- status = XVaCreateNestedList(0,
- NULL);
+ status = XVaCreateNestedList(0, NULL);
TRACE("status = %p\n", status);
- }
+ }
if (preedit != NULL && status != NULL)
{
@@ -597,8 +653,9 @@ XIC X11DRV_CreateIC(XIM xim, Display *display, Window win)
XNStatusAttributes, status,
XNClientWindow, win,
XNFocusWindow, win,
+ XNDestroyCallback, &destroy,
NULL);
- }
+ }
else if (preedit != NULL)
{
xic = XCreateIC(xim,
@@ -606,6 +663,7 @@ XIC X11DRV_CreateIC(XIM xim, Display *display, Window win)
XNPreeditAttributes, preedit,
XNClientWindow, win,
XNFocusWindow, win,
+ XNDestroyCallback, &destroy,
NULL);
}
else if (status != NULL)
@@ -615,6 +673,7 @@ XIC X11DRV_CreateIC(XIM xim, Display *display, Window win)
XNStatusAttributes, status,
XNClientWindow, win,
XNFocusWindow, win,
+ XNDestroyCallback, &destroy,
NULL);
}
else
@@ -623,10 +682,12 @@ XIC X11DRV_CreateIC(XIM xim, Display *display, Window win)
XNInputStyle, ximStyle,
XNClientWindow, win,
XNFocusWindow, win,
+ XNDestroyCallback, &destroy,
NULL);
}
TRACE("xic = %p\n", xic);
+ *p = xic;
if (preedit != NULL)
XFree(preedit);
--
1.5.4.5
More information about the wine-patches
mailing list