diff -urN wine-20031212/dlls/x11drv/event.c wine-20031212-xim/dlls/x11drv/event.c
--- wine-20031212/dlls/x11drv/event.c	2003-12-05 13:45:50.000000000 +0900
+++ wine-20031212-xim/dlls/x11drv/event.c	2004-01-22 16:24:06.000000000 +0900
@@ -50,6 +50,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(event);
 WINE_DECLARE_DEBUG_CHANNEL(clipboard);
+WINE_DECLARE_DEBUG_CHANNEL(xim);
 
 /* X context to associate a hwnd to an X window */
 extern XContext winContext;
@@ -134,12 +135,13 @@
     wine_tsx11_lock();
     while ( XPending( data->display ) )
     {
-        Bool ignore;
+        //Bool ignore;
 
         XNextEvent( data->display, &event );
-        ignore = XFilterEvent( &event, None );
+        //ignore = XFilterEvent( &event, None );
         wine_tsx11_unlock();
-        if (!ignore) EVENT_ProcessEvent( &event );
+	//if (!ignore) EVENT_ProcessEvent( &event );
+	EVENT_ProcessEvent( &event );
         count++;
         wine_tsx11_lock();
     }
@@ -196,7 +198,17 @@
   HWND hWnd;
   Display *display = event->xany.display;
 
-  TRACE( "called.\n" );
+  wine_tsx11_lock();
+  if( event->type != KeyPress && event->type != KeyRelease
+      && XFilterEvent(event, None))
+  {
+    wine_tsx11_unlock();
+    TRACE_(xim)("Filtered event: %s(%d) window %08x\n",
+		event_names[event->type],
+		event->type, (unsigned int)event->xany.window);
+    return;
+  }
+  wine_tsx11_unlock();
 
   switch (event->type)
   {
diff -urN wine-20031212/dlls/x11drv/keyboard.c wine-20031212-xim/dlls/x11drv/keyboard.c
--- wine-20031212/dlls/x11drv/keyboard.c	2003-11-22 06:48:36.000000000 +0900
+++ wine-20031212-xim/dlls/x11drv/keyboard.c	2004-01-22 16:31:59.000000000 +0900
@@ -50,10 +50,12 @@
 #include "x11drv.h"
 #include "wine/unicode.h"
 #include "wine/debug.h"
+#include "heap.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(keyboard);
 WINE_DECLARE_DEBUG_CHANNEL(key);
 WINE_DECLARE_DEBUG_CHANNEL(dinput);
+WINE_DECLARE_DEBUG_CHANNEL(xim);
 
 static int min_keycode, max_keycode, keysyms_per_keycode;
 static WORD keyc2vkey[256], keyc2scan[256];
@@ -1077,6 +1079,123 @@
     KEYBOARD_UpdateOneState( VK_SHIFT, shift, time );
 }
 
+#define NALLOC 64
+static BOOL XIM_KeyEvent(HWND hwnd, XKeyEvent *event, Window client_window,
+			 XIC xic)
+{
+    static BOOL updatedXIMPos = 0;
+    BOOL done = FALSE;
+    struct x11drv_thread_data *data = NtCurrentTeb()->driver_data;
+
+    if (xic == NULL)
+    {
+        WARN_(xim)("Unable tp retrieve input context\n");
+	return FALSE;
+    }
+
+    TRACE_(xim)("hwnd %04x event_window(%08lx) client_window(%08lx)\n",
+				(unsigned int) hwnd, event->window, client_window);
+
+    wine_tsx11_lock();
+    if (!data->xim){
+        done = FALSE; /* No input method defined */
+    }
+    else if (XFilterEvent((XEvent *) event, client_window))
+    {
+        TRACE_(xim)("Filtered.\n");
+	if (!updatedXIMPos)
+	{
+	    POINT p;
+	    XPoint spot;
+	    XVaNestedList preedit_attr;
+	    GetCaretPos(&p);
+	    //ClientToScreen(hwnd, &p);
+	    spot.x = p.x;
+	    spot.y = p.y;
+	    spot.y += 14;   //FIXME: How to get the caret's height
+	    preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
+	    XSetICValues(xic, XNPreeditAttributes, preedit_attr, NULL);
+	    XFree(preedit_attr);
+	    /* use this variable to check whether we need to update XIM position */
+	    updatedXIMPos = 1;
+	}
+        done = TRUE;
+    }
+    else if (event->type == KeyPress)
+    {
+        KeySym keysym;
+        Status status;
+        int i, nbyte;
+	INT codepage;
+        DWORD dwOutput;
+        WCHAR wcOutput[NALLOC];
+        LPSTR bytes;
+        DWORD nalloc = NALLOC;
+
+        updatedXIMPos = 0;
+
+        bytes = HeapAlloc(GetProcessHeap(),0,NALLOC);
+
+	nbyte = XmbLookupString(xic, event, bytes, nalloc, &keysym, &status);
+        TRACE_(xim)("nbyte = %d, status = 0x%x\n", nbyte, status);
+
+        if (status == XBufferOverflow)
+        {
+	    nalloc = nbyte;
+            bytes = HeapReAlloc(GetProcessHeap(), 0, bytes, nbyte);
+            nbyte = XmbLookupString(xic, event, bytes, nalloc, &keysym, &status);
+            TRACE_(xim)("nbyte = %d, status = 0x%x\n", nbyte, status);
+        }
+
+        switch (status)
+        {
+        case XLookupBoth:
+            if (keysym < 128 || (keysym & 0xff00) == 0xff00)
+            {
+                TRACE_(xim)("keysym = 0x%x\n", (int)keysym);
+		break; /* Leave to the default handler */
+            }
+	    /* fall through */
+        case XLookupChars:
+            codepage = GetACP();
+            if (codepage == 932)
+            {
+                /*
+                 * Japanese is encoded with windows as SJIS (932) however
+                 * Under unix we use EUS (20932) So we need to translate
+                 * the input as 20932...
+                 */
+                dwOutput = MultiByteToWideChar(20932, 0, bytes, nbyte,
+					       wcOutput, sizeof(wcOutput));
+            }
+            else dwOutput = MultiByteToWideChar(codepage, 0, bytes, nbyte,
+						wcOutput, sizeof(wcOutput));
+
+	    for(i=0; i<dwOutput; i++)
+	    {
+	        TRACE_(xim)("sending wchar %04x\n", wcOutput[i]);
+		PostMessageW(hwnd, WM_IME_CHAR, wcOutput[i], 1);
+	    }
+            done = True;
+            break;
+
+        case XLookupKeySym:
+            TRACE_(xim)("XLookupKeySym\n");
+            break; /* Leave to the default handler */
+
+        case XLookupNone:
+            TRACE_(xim)("XLookupNone\n");
+            done = True; /* No further processing is necessary */
+            break;
+        }
+
+        HeapFree(GetProcessHeap(),0,bytes);
+    }
+    wine_tsx11_unlock();
+    return done;
+}
+
+
 /***********************************************************************
  *           X11DRV_KeyEvent
  *
@@ -1096,6 +1215,11 @@
     TRACE_(key)("type %d, window %lx, state 0x%04x, keycode 0x%04x\n",
 		event->type, event->window, event->state, event->keycode);
 
+    /* forward to XIM */
+    if (XIM_KeyEvent(GetFocus(), event, X11DRV_get_client_window(hwnd), xic)
+	&& event->type == KeyPress)
+	return;
+
     wine_tsx11_lock();
     if (xic)
         ascii_chars = XmbLookupString(xic, event, Str, sizeof(Str), &keysym, &status);
diff -urN wine-20031212/dlls/x11drv/window.c wine-20031212-xim/dlls/x11drv/window.c
--- wine-20031212/dlls/x11drv/window.c	2003-12-13 09:05:53.000000000 +0900
+++ wine-20031212-xim/dlls/x11drv/window.c	2004-01-22 16:24:06.000000000 +0900
@@ -790,7 +790,7 @@
         return 0;
     }
 
-    if (is_top_level)
+    /*if (is_top_level)
     {
         XIM xim = x11drv_thread_data()->xim;
         if (xim) data->xic = XCreateIC( xim,
@@ -798,7 +798,7 @@
                                         XNClientWindow, data->whole_window,
                                         XNFocusWindow, data->whole_window,
                                         0 );
-    }
+    }*/
 
     /* non-maximized child must be at bottom of Z order */
     if ((win->dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
@@ -843,8 +843,10 @@
                                          0, screen_depth,
                                          InputOutput, visual,
                                          CWEventMask | CWBitGravity | CWBackingStore, &attr );
-    if (data->client_window && is_client_window_mapped( win ))
+    if (data->client_window && is_client_window_mapped( win )) {
+        data->xic = XIM_DoCreateIC( data->client_window );
         XMapWindow( display, data->client_window );
+    }
     wine_tsx11_unlock();
     return data->client_window;
 }
@@ -916,6 +918,14 @@
 
     if (!data) goto done;
 
+    if (data->client_window && data->xic)
+    {
+        wine_tsx11_lock();
+	XUnsetICFocus( data->xic );
+	XDestroyIC( data->xic );
+        wine_tsx11_unlock();
+    }
+
     if (data->whole_window)
     {
         TRACE( "win %p xwin %lx/%lx\n", hwnd, data->whole_window, data->client_window );
@@ -926,11 +936,11 @@
         XDeleteContext( display, data->whole_window, winContext );
         XDeleteContext( display, data->client_window, winContext );
         XDestroyWindow( display, data->whole_window );  /* this destroys client too */
-        if (data->xic)
+        /*if (data->xic)
         {
             XUnsetICFocus( data->xic );
             XDestroyIC( data->xic );
-        }
+	}*/
         destroy_icon_window( display, wndPtr );
         wine_tsx11_unlock();
     }
diff -urN wine-20031212/dlls/x11drv/x11drv.h wine-20031212-xim/dlls/x11drv/x11drv.h
--- wine-20031212/dlls/x11drv/x11drv.h	2003-12-05 06:54:13.000000000 +0900
+++ wine-20031212-xim/dlls/x11drv/x11drv.h	2004-01-22 16:24:06.000000000 +0900
@@ -104,6 +104,9 @@
     XRENDERINFO   xrender;
 } X11DRV_PDEVICE;
 
+extern XIMStyle ximStyle;
+extern XFontSet ximFontSet;
+extern XIC XIM_DoCreateIC(Window w);
 
   /* GCs used for B&W and color bitmap operations */
 extern GC BITMAP_monoGC, BITMAP_colorGC;
diff -urN wine-20031212/dlls/x11drv/x11drv_main.c wine-20031212-xim/dlls/x11drv/x11drv_main.c
--- wine-20031212/dlls/x11drv/x11drv_main.c	2003-12-05 09:11:48.000000000 +0900
+++ wine-20031212-xim/dlls/x11drv/x11drv_main.c	2004-01-22 16:27:17.000000000 +0900
@@ -62,10 +62,12 @@
 #include "xvidmode.h"
 #include "xrandr.h"
 #include "dga2.h"
+#include "xim.h"
 #include "wine/server.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
+WINE_DECLARE_DEBUG_CHANNEL(xim);
 
 static CRITICAL_SECTION X11DRV_CritSection;
 static CRITICAL_SECTION_DEBUG critsect_debug =
@@ -111,6 +113,9 @@
 #define IS_OPTION_FALSE(ch) \
     ((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
 
+XIMStyle ximStyle = 0;
+XFontSet ximFontSet;
+
 /***********************************************************************
  *		ignore_error
  *
@@ -313,6 +318,173 @@
     RegCloseKey( hkey );
 }
 
+static BOOL X11DRV_SetupXIM(struct x11drv_thread_data *data)
+{
+    BOOL ximDisable;
+    XIMStyle ximStyleRequest, ximStyleRoot, ximStyleNone;
+    XIMStyles *ximStyles = NULL;
+    char buf[100];
+    int i;
+
+    char **list;    //FIXME
+    int count;
+    char * FontSet;
+
+    HKEY hkey, appkey = 0;
+
+    if (RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\InputMethod", 0, NULL,
+                         REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ))
+    {
+        ERR("Cannot create config registry key\n" );
+        ExitProcess(1);
+    }
+
+    /* open the app-specific key */
+
+    if (GetModuleFileNameA( 0, buf, MAX_PATH ))
+    {
+        HKEY tmpkey;
+        char *p, *appname = buf;
+        if ((p = strrchr( appname, '/' ))) appname = p + 1;
+        if ((p = strrchr( appname, '\\' ))) appname = p + 1;
+        strcat( appname, "\\InputMethod" );
+        if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\AppDefaults", &tmpkey ))
+        {
+            if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
+            RegCloseKey( tmpkey );
+        }
+    }
+
+    if (!get_config_key( hkey, appkey, "UseXIM", buf, sizeof(buf) ))
+    {
+        ximDisable = IS_OPTION_FALSE( buf[0] );
+    }
+    else
+        ximDisable=FALSE;
+    if(ximDisable)
+    {
+        MESSAGE("Disabled input method.\n");
+        return FALSE;
+    }
+
+    if (!get_config_key( hkey, appkey, "XIMFontSet", buf, sizeof(buf) ))
+    {
+	    FontSet = strdup( buf );
+    }
+    else
+        FontSet = "-misc-fixed-medium-r-normal--16-*-*-*-*-*";
+
+    wine_tsx11_lock();
+    ximFontSet = XCreateFontSet(data->display, FontSet, &list, &count, NULL);
+    wine_tsx11_unlock();
+
+    TRACE_(xim)("ximFontSet = 0x%x\n", (unsigned int) ximFontSet);
+    TRACE_(xim)("list = 0x%x, count = %d\n", (unsigned int) list, count);
+    if (list != NULL)
+    {
+        int i;
+
+	for (i = 0; i < count; ++i)
+	{
+	    TRACE_(xim)("list[%d] = %s\n", i, list[i]);
+	}
+	wine_tsx11_lock();
+	XFreeStringList(list);
+	wine_tsx11_unlock();
+    }
+
+    if (get_config_key( hkey, appkey, "InputStyle", buf, sizeof(buf) ))
+        sprintf(buf, "overthespot");
+
+    ximStyleRequest = STYLE_OVERTHESPOT;
+    if (strcasecmp(buf, "offthespot") == 0)
+        ximStyleRequest = STYLE_OFFTHESPOT;
+    else if (strcasecmp(buf, "overthespot") == 0)
+        ximStyleRequest = STYLE_OVERTHESPOT;
+    else if (strcasecmp(buf, "root") == 0)
+        ximStyleRequest = STYLE_ROOT;
+
+    wine_tsx11_lock();
+
+    if(!XSupportsLocale())
+    {
+        MESSAGE("X does not support locale.\n");
+        goto err;
+    }
+
+    if(XSetLocaleModifiers("") == NULL)
+    {
+        MESSAGE("Could not set locale modifiers.\n");
+	goto err;
+    }
+
+    data->xim = XOpenIM(data->display, NULL, NULL, NULL);
+    if (data->xim == NULL)
+    {
+        MESSAGE("Could not open input method.\n");
+        goto err;
+    }
+
+    XGetIMValues(data->xim, XNQueryInputStyle, &ximStyles, NULL);
+    if (ximStyles == 0)
+    {
+        MESSAGE("Could not find supported input style.\n");
+    }
+    else
+    {
+        TRACE_(xim)("ximStyles->count_styles = %d\n", ximStyles->count_styles);
+
+	ximStyleRoot = 0;
+	ximStyleNone = 0;
+
+	for (i = 0; i < ximStyles->count_styles; ++i)
+	{
+	    int style = ximStyles->supported_styles[i];
+	    TRACE_(xim)("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 (ximStyles->supported_styles[i] == ximStyleRequest)
+	    {
+	        ximStyle = ximStyleRequest;
+		TRACE_(xim)("Setting Style: ximStyleNone = ximStyleRequest\n");
+		break;
+	    }
+
+	    if (ximStyles->supported_styles[i] == STYLE_ROOT)
+	    {
+	        ximStyleRoot = STYLE_ROOT;
+		TRACE_(xim)("Setting Style: ximStyleNone = STYLE_ROOT\n");
+		break;
+	    }
+
+	    if (ximStyles->supported_styles[i] == STYLE_NONE)
+	    {
+	        TRACE_(xim)("Setting Style: ximStyleNone = STYLE_NONE\n");
+		ximStyleNone = STYLE_NONE;
+		break;
+	    }
+	}
+
+	XFree(ximStyles);
+
+	if (ximStyle == 0)
+	    ximStyle = ximStyleRoot;
+
+	if (ximStyle == 0)
+	    ximStyle = ximStyleNone;
+    }
+
+    wine_tsx11_unlock();
+    return TRUE;
+
+err:
+    wine_tsx11_unlock();
+    return FALSE;
+}
+
 
 /***********************************************************************
  *           X11DRV process initialisation routine
@@ -326,8 +498,6 @@
 
     /* Open display */
 
-    if (!XInitThreads()) ERR( "XInitThreads failed, trouble ahead\n" );
-
     if (!(display = XOpenDisplay( NULL )))
     {
         MESSAGE( "x11drv: Can't open display: %s\n", XDisplayName(NULL) );
@@ -410,6 +580,7 @@
     {
         CloseHandle( data->display_fd );
         wine_tsx11_lock();
+	if (data->xim) XCloseIM(data->xim);
         XCloseDisplay( data->display );
         /* if (data->xim) XCloseIM( data->xim ); */ /* crashes Xlib */
         wine_tsx11_unlock();
@@ -493,6 +664,8 @@
     data->cursor = None;
     data->cursor_window = None;
     data->last_focus = 0;
+    data->xim = 0;
+    X11DRV_SetupXIM(data);
     NtCurrentTeb()->driver_data = data;
     if (desktop_tid) AttachThreadInput( GetCurrentThreadId(), desktop_tid, TRUE );
     return data;
@@ -553,3 +726,81 @@
                     allow_exposures);
     wine_tsx11_unlock();
 }
+
+/***********************************************************************
+ *              XIM IC Functions (X11DRV.@)
+ *
+ */
+XIC XIM_DoCreateIC(Window w)
+{
+    XFontSet FSet = ximFontSet;
+    XPoint spot = {400,400};
+    XVaNestedList preedit = NULL;
+    XVaNestedList status = NULL;
+    XIC xic = NULL;
+    struct x11drv_thread_data *data = NtCurrentTeb()->driver_data;
+
+    TRACE_(xim)("xwin %08x, xim %08x\n",
+		(unsigned int)w, (unsigned int) data->xim);
+
+    if (data->xim == NULL)
+        return FALSE;
+
+    wine_tsx11_lock();
+    if ((ximStyle & (XIMPreeditNothing | XIMPreeditNone)) == 0)
+    {
+        preedit = XVaCreateNestedList(0,
+				      XNFontSet, FSet,
+				      XNSpotLocation, &spot,
+				      NULL);
+	TRACE_(xim)("preedit = 0x%x\n", (unsigned int) preedit);
+    }
+    if ((ximStyle & (XIMStatusNothing | XIMStatusNone)) == 0)
+    {
+        status = XVaCreateNestedList(0,
+				     XNFontSet, FSet, NULL);
+	TRACE_(xim)("status = 0x%x\n", (unsigned int) status);
+    }
+    if (preedit != NULL && status != NULL) {
+        xic = XCreateIC(data->xim,
+			XNClientWindow, w,
+			XNFocusWindow, w,
+			XNInputStyle, ximStyle,
+			XNPreeditAttributes, preedit,
+			XNStatusAttributes, status,
+			NULL);
+    } else if (preedit != NULL) {
+        xic = XCreateIC(data->xim,
+			XNClientWindow, w,
+			XNFocusWindow, w,
+			XNInputStyle, ximStyle,
+			XNPreeditAttributes, preedit,
+			NULL);
+    } else if (status != NULL) {
+        xic = XCreateIC(data->xim,
+			XNClientWindow, w,
+			XNFocusWindow, w,
+			XNInputStyle, ximStyle,
+			XNStatusAttributes, status,
+			NULL);
+    } else {
+        xic = XCreateIC(data->xim,
+			XNClientWindow, w,
+			XNFocusWindow, w,
+			XNInputStyle, ximStyle,
+			NULL);
+    }
+    TRACE_(xim)("xic = 0x%x\n", (unsigned int) xic);
+    if (preedit != NULL) {
+        XFree(preedit);
+    }
+    if (status != NULL) {
+        XFree(status);
+    }
+
+    XSetICFocus(xic);
+
+    wine_tsx11_unlock();
+
+    return(xic);
+}
diff -urN wine-20031212/dlls/x11drv/xim.h wine-20031212-xim/dlls/x11drv/xim.h
--- wine-20031212/dlls/x11drv/xim.h	1970-01-01 09:00:00.000000000 +0900
+++ wine-20031212-xim/dlls/x11drv/xim.h	2004-01-22 16:24:06.000000000 +0900
@@ -0,0 +1,30 @@
+/*
+ * xim.h 
+ * define some constant used in XIM
+ * 
+ * Copyright 2002  liuspider
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#if !defined(__WINE_XIM_H)
+	
+#define __WINE_XIM_H
+
+#define STYLE_OFFTHESPOT (XIMPreeditArea | XIMStatusArea)
+#define STYLE_OVERTHESPOT (XIMPreeditPosition | XIMStatusNothing)
+#define STYLE_ROOT (XIMPreeditNothing | XIMStatusNothing)
+#define STYLE_NONE (XIMPreeditNone | XIMStatusNone)
+
+#endif /* !defined(__WINE_XIM_H) */
