Commit 9672b791 authored by Aric Stewart's avatar Aric Stewart Committed by Alexandre Julliard

Use X11 XIM callbacks to enable full IME support.

Correct some timing issues with XIM input. Start to provide the framework for the MSIME messages.
parent 3defd321
...@@ -3,7 +3,7 @@ TOPOBJDIR = ../.. ...@@ -3,7 +3,7 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@ SRCDIR = @srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
MODULE = imm32.dll MODULE = imm32.dll
IMPORTS = user32 kernel32 IMPORTS = user32 gdi32 kernel32
ALTNAMES = imm.dll ALTNAMES = imm.dll
SPEC_SRCS16 = $(ALTNAMES:.dll=.spec) SPEC_SRCS16 = $(ALTNAMES:.dll=.spec)
......
...@@ -21,22 +21,23 @@ ...@@ -21,22 +21,23 @@
@ stdcall ImmGetCompositionFontW(long ptr) @ stdcall ImmGetCompositionFontW(long ptr)
@ stdcall ImmGetCompositionStringA (long long ptr long) @ stdcall ImmGetCompositionStringA (long long ptr long)
@ stdcall ImmGetCompositionStringW (long long ptr long) @ stdcall ImmGetCompositionStringW (long long ptr long)
@ stdcall ImmGetCompositionString (long long ptr long) ImmGetCompositionStringA
@ stdcall ImmGetCompositionWindow(long ptr) @ stdcall ImmGetCompositionWindow(long ptr)
@ stdcall ImmGetContext(long) @ stdcall ImmGetContext(long)
@ stdcall ImmGetConversionListA(long long str ptr long long) @ stdcall ImmGetConversionListA(long long str ptr long long)
@ stdcall ImmGetConversionListW(long long wstr ptr long long) @ stdcall ImmGetConversionListW(long long wstr ptr long long)
@ stdcall ImmGetConversionStatus(long ptr ptr) @ stdcall ImmGetConversionStatus(long ptr ptr)
@ stdcall ImmGetDefaultIMEWnd(long) @ stdcall ImmGetDefaultIMEWnd(long)
@ stdcall ImmGetDescriptionA(long str long) @ stdcall ImmGetDescriptionA(long ptr long)
@ stdcall ImmGetDescriptionW(long wstr long) @ stdcall ImmGetDescriptionW(long ptr long)
@ stdcall ImmGetGuideLineA(long long str long) @ stdcall ImmGetGuideLineA(long long ptr long)
@ stdcall ImmGetGuideLineW(long long wstr long) @ stdcall ImmGetGuideLineW(long long ptr long)
@ stub ImmGetHotKey @ stub ImmGetHotKey
@ stub ImmGetIMCCLockCount @ stub ImmGetIMCCLockCount
@ stub ImmGetIMCCSize @ stub ImmGetIMCCSize
@ stub ImmGetIMCLockCount @ stub ImmGetIMCLockCount
@ stdcall ImmGetIMEFileNameA(long str long) @ stdcall ImmGetIMEFileNameA(long ptr long)
@ stdcall ImmGetIMEFileNameW(long wstr long) @ stdcall ImmGetIMEFileNameW(long ptr long)
@ stdcall ImmGetOpenStatus(long) @ stdcall ImmGetOpenStatus(long)
@ stdcall ImmGetProperty(long long) @ stdcall ImmGetProperty(long long)
@ stdcall ImmGetRegisterWordStyleA(long long ptr) @ stdcall ImmGetRegisterWordStyleA(long long ptr)
......
...@@ -39,6 +39,7 @@ C_SRCS = \ ...@@ -39,6 +39,7 @@ C_SRCS = \
x11drv_main.c \ x11drv_main.c \
xdnd.c \ xdnd.c \
xfont.c \ xfont.c \
xim.c \
xrandr.c \ xrandr.c \
xrender.c \ xrender.c \
xvidmode.c xvidmode.c
......
...@@ -54,6 +54,8 @@ WINE_DECLARE_DEBUG_CHANNEL(clipboard); ...@@ -54,6 +54,8 @@ WINE_DECLARE_DEBUG_CHANNEL(clipboard);
/* X context to associate a hwnd to an X window */ /* X context to associate a hwnd to an X window */
extern XContext winContext; extern XContext winContext;
extern BOOL ximInComposeMode;
#define DndNotDnd -1 /* OffiX drag&drop */ #define DndNotDnd -1 /* OffiX drag&drop */
#define DndUnknown 0 #define DndUnknown 0
#define DndRawData 1 #define DndRawData 1
...@@ -532,6 +534,8 @@ static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event ) ...@@ -532,6 +534,8 @@ static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event )
TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] ); TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] );
if (event->detail == NotifyPointer) return; if (event->detail == NotifyPointer) return;
if (ximInComposeMode) return;
x11drv_thread_data()->last_focus = hwnd; x11drv_thread_data()->last_focus = hwnd;
if ((xic = X11DRV_get_ic( hwnd ))) if ((xic = X11DRV_get_ic( hwnd )))
{ {
......
...@@ -807,8 +807,8 @@ static const struct { ...@@ -807,8 +807,8 @@ static const struct {
{0x0424, "Slovenian keyboard layout", &main_key_SI, &main_key_scan_qwerty, &main_key_vkey_qwertz}, {0x0424, "Slovenian keyboard layout", &main_key_SI, &main_key_scan_qwerty, &main_key_vkey_qwertz},
{0x041a, "Croatian keyboard layout", &main_key_HR, &main_key_scan_qwerty, &main_key_vkey_qwertz}, {0x041a, "Croatian keyboard layout", &main_key_HR, &main_key_scan_qwerty, &main_key_vkey_qwertz},
{0x041a, "Croatian keyboard layout (specific)", &main_key_HR_jelly, &main_key_scan_qwerty, &main_key_vkey_qwerty}, {0x041a, "Croatian keyboard layout (specific)", &main_key_HR_jelly, &main_key_scan_qwerty, &main_key_vkey_qwerty},
{0x0411, "Japanese 106 keyboard layout", &main_key_JA_jp106, &main_key_scan_qwerty, &main_key_vkey_qwerty}, {0xe0010411, "Japanese 106 keyboard layout", &main_key_JA_jp106, &main_key_scan_qwerty, &main_key_vkey_qwerty},
{0x0411, "Japanese pc98x1 keyboard layout", &main_key_JA_pc98x1, &main_key_scan_qwerty, &main_key_vkey_qwerty}, {0xe0010411, "Japanese pc98x1 keyboard layout", &main_key_JA_pc98x1, &main_key_scan_qwerty, &main_key_vkey_qwerty},
{0x041b, "Slovak keyboard layout", &main_key_SK, &main_key_scan_qwerty, &main_key_vkey_qwerty}, {0x041b, "Slovak keyboard layout", &main_key_SK, &main_key_scan_qwerty, &main_key_vkey_qwerty},
{0x041b, "Slovak and Czech keyboard layout without dead keys", &main_key_SK_prog, &main_key_scan_qwerty, &main_key_vkey_qwerty}, {0x041b, "Slovak and Czech keyboard layout without dead keys", &main_key_SK_prog, &main_key_scan_qwerty, &main_key_vkey_qwerty},
{0x0405, "Czech keyboard layout", &main_key_CS, &main_key_scan_qwerty, &main_key_vkey_qwerty}, {0x0405, "Czech keyboard layout", &main_key_CS, &main_key_scan_qwerty, &main_key_vkey_qwerty},
...@@ -1113,7 +1113,16 @@ void X11DRV_KeyEvent( HWND hwnd, XKeyEvent *event ) ...@@ -1113,7 +1113,16 @@ void X11DRV_KeyEvent( HWND hwnd, XKeyEvent *event )
return; return;
} }
TRACE_(key)("state = %X\n", event->state); TRACE_(key)("state = %X nbyte = %d, status 0x%x\n", event->state, ascii_chars, status);
if (status == XBufferOverflow)
ERR("Buffer Overflow need %i!\n",ascii_chars);
if (status == XLookupChars)
{
X11DRV_XIMLookupChars( Str, ascii_chars );
return;
}
/* If XKB extensions are used, the state mask for AltGr will use the group /* If XKB extensions are used, the state mask for AltGr will use the group
index instead of the modifier mask. The group index is set in bits index instead of the modifier mask. The group index is set in bits
...@@ -1560,7 +1569,7 @@ HKL X11DRV_GetKeyboardLayout(DWORD dwThreadid) ...@@ -1560,7 +1569,7 @@ HKL X11DRV_GetKeyboardLayout(DWORD dwThreadid)
*/ */
langid = PRIMARYLANGID(LANGIDFROMLCID(layout)); langid = PRIMARYLANGID(LANGIDFROMLCID(layout));
if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN) if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN)
layout |= 0xe001 << 16; /* FIXME */ layout = 0xe001 << 16; /* FIXME */
return (HKL)layout; return (HKL)layout;
} }
......
...@@ -789,16 +789,6 @@ static Window create_whole_window( Display *display, WND *win ) ...@@ -789,16 +789,6 @@ static Window create_whole_window( Display *display, WND *win )
return 0; return 0;
} }
if (is_top_level)
{
XIM xim = x11drv_thread_data()->xim;
if (xim) data->xic = XCreateIC( xim,
XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
XNClientWindow, data->whole_window,
XNFocusWindow, data->whole_window,
0 );
}
/* non-maximized child must be at bottom of Z order */ /* non-maximized child must be at bottom of Z order */
if ((win->dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD) if ((win->dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
{ {
...@@ -809,7 +799,12 @@ static Window create_whole_window( Display *display, WND *win ) ...@@ -809,7 +799,12 @@ static Window create_whole_window( Display *display, WND *win )
wine_tsx11_unlock(); wine_tsx11_unlock();
if (is_top_level) X11DRV_set_wm_hints( display, win ); if (is_top_level)
{
XIM xim = x11drv_thread_data()->xim;
if (xim) data->xic = X11DRV_CreateIC( xim, display, data->whole_window );
X11DRV_set_wm_hints( display, win );
}
return data->whole_window; return data->whole_window;
} }
......
...@@ -234,6 +234,11 @@ extern void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev); ...@@ -234,6 +234,11 @@ extern void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev);
extern void X11DRV_OpenGL_Init(Display *display); extern void X11DRV_OpenGL_Init(Display *display);
extern XVisualInfo *X11DRV_setup_opengl_visual(Display *display); extern XVisualInfo *X11DRV_setup_opengl_visual(Display *display);
/* XIM support */
extern XIC X11DRV_CreateIC(XIM xim, Display *display, Window win);
extern XIM X11DRV_SetupXIM(Display *display, const char *input_style);
extern void X11DRV_XIMLookupChars( const char *str, DWORD count );
extern int X11DRV_XDND_Event(HWND hWnd, XClientMessageEvent *event); extern int X11DRV_XDND_Event(HWND hWnd, XClientMessageEvent *event);
/* exported dib functions for now */ /* exported dib functions for now */
......
...@@ -119,3 +119,6 @@ ...@@ -119,3 +119,6 @@
# X11 locks # X11 locks
@ cdecl -norelay wine_tsx11_lock() @ cdecl -norelay wine_tsx11_lock()
@ cdecl -norelay wine_tsx11_unlock() @ cdecl -norelay wine_tsx11_unlock()
# XIM
@ cdecl ForceXIMReset(long) X11DRV_ForceXIMReset
...@@ -104,6 +104,8 @@ static void *err_callback_arg; /* error callback argument */ ...@@ -104,6 +104,8 @@ static void *err_callback_arg; /* error callback argument */
static int err_callback_result; /* error callback result */ static int err_callback_result; /* error callback result */
static unsigned long err_serial; /* serial number of first request */ static unsigned long err_serial; /* serial number of first request */
static int (*old_error_handler)( Display *, XErrorEvent * ); static int (*old_error_handler)( Display *, XErrorEvent * );
static int use_xim = 1;
static char input_style[20];
#define IS_OPTION_TRUE(ch) \ #define IS_OPTION_TRUE(ch) \
((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1') ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
...@@ -308,6 +310,11 @@ static void setup_options(void) ...@@ -308,6 +310,11 @@ static void setup_options(void)
if (!get_config_key( hkey, appkey, "DesktopDoubleBuffered", buffer, sizeof(buffer) )) if (!get_config_key( hkey, appkey, "DesktopDoubleBuffered", buffer, sizeof(buffer) ))
desktop_dbl_buf = IS_OPTION_TRUE( buffer[0] ); desktop_dbl_buf = IS_OPTION_TRUE( buffer[0] );
if (!get_config_key( hkey, appkey, "UseXIM", buffer, sizeof(buffer) ))
use_xim = IS_OPTION_TRUE( buffer[0] );
get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
if (appkey) RegCloseKey( appkey ); if (appkey) RegCloseKey( appkey );
RegCloseKey( hkey ); RegCloseKey( hkey );
} }
...@@ -460,15 +467,8 @@ struct x11drv_thread_data *x11drv_init_thread_data(void) ...@@ -460,15 +467,8 @@ struct x11drv_thread_data *x11drv_init_thread_data(void)
MESSAGE( "x11drv: Can't open display: %s\n", XDisplayName(NULL) ); MESSAGE( "x11drv: Can't open display: %s\n", XDisplayName(NULL) );
ExitProcess(1); ExitProcess(1);
} }
fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
if ((data->xim = XOpenIM( data->display, NULL, NULL, NULL ))) fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
{
TRACE("X display of IM = %p\n", XDisplayOfIM(data->xim));
TRACE("Using %s locale of Input Method\n", XLocaleOfIM(data->xim));
}
else
WARN("Can't open input method\n");
#ifdef HAVE_XKB #ifdef HAVE_XKB
if (use_xkb) if (use_xkb)
...@@ -480,6 +480,10 @@ struct x11drv_thread_data *x11drv_init_thread_data(void) ...@@ -480,6 +480,10 @@ struct x11drv_thread_data *x11drv_init_thread_data(void)
if (synchronous) XSynchronize( data->display, True ); if (synchronous) XSynchronize( data->display, True );
wine_tsx11_unlock(); wine_tsx11_unlock();
if (use_xim && !(data->xim = X11DRV_SetupXIM( data->display, input_style )))
WARN("Input Method is not available\n");
if (wine_server_fd_to_handle( ConnectionNumber(data->display), GENERIC_READ | SYNCHRONIZE, if (wine_server_fd_to_handle( ConnectionNumber(data->display), GENERIC_READ | SYNCHRONIZE,
FALSE, &data->display_fd )) FALSE, &data->display_fd ))
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment