diff -urN wine-20040121/dlls/x11drv/event.c wine-20040121-xim-jp106/dlls/x11drv/event.c
--- wine-20040121/dlls/x11drv/event.c	2004-01-21 11:22:27.000000000 +0900
+++ wine-20040121-xim-jp106/dlls/x11drv/event.c	2004-01-23 20:38:14.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;
@@ -136,12 +137,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();
     }
@@ -198,7 +200,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-20040121/dlls/x11drv/keyboard.c wine-20040121-xim-jp106/dlls/x11drv/keyboard.c
--- wine-20040121/dlls/x11drv/keyboard.c	2004-01-21 11:22:27.000000000 +0900
+++ wine-20040121-xim-jp106/dlls/x11drv/keyboard.c	2004-01-23 20:38:14.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];
@@ -80,6 +82,20 @@
    0x56 /* the 102nd key (actually to the right of l-shift) */
 };
 
+static const WORD main_key_scan_jp106[MAIN_LEN] =
+{
+/* this is 106-key keyboard layout */
+ /* 1    2    3    4    5    6    7    8    9    0    -    ^    \ */
+   0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x90,0x7D,
+/*  q    w    e    r    t    y    u    i    o    p    @    [ */
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x91,0x1A,
+/*  a    s    d    f    g    h    j    k    l    ;    :    ] */
+   0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x92,0x1B,
+/*  z    x    c    v    b    n    m    ,    .    / */
+   0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
+   0x93 /* the 102nd key (actually to the right of l-shift) */
+};
+
 static const WORD main_key_scan_abnt_qwerty[MAIN_LEN] =
 {
  /* `    1    2    3    4    5    6    7    8    9    0    -    = */
@@ -145,6 +161,16 @@
    VK_OEM_102,VK_Y,VK_X,VK_C,VK_V,VK_B,VK_N,VK_M,VK_OEM_COMMA,VK_OEM_PERIOD,VK_OEM_2
 };
 
+static const WORD main_key_vkey_jp106[MAIN_LEN] =
+{
+/* NOTE: this layout must concur with the scan codes layout above */
+   VK_1,VK_2,VK_3,VK_4,VK_5,VK_6,VK_7,VK_8,VK_9,VK_0,VK_OEM_MINUS,VK_OEM_7,VK_OEM_5,
+   VK_Q,VK_W,VK_E,VK_R,VK_T,VK_Y,VK_U,VK_I,VK_O,VK_P,VK_OEM_3,VK_OEM_4,
+   VK_A,VK_S,VK_D,VK_F,VK_G,VK_H,VK_J,VK_K,VK_L,VK_OEM_PLUS,VK_OEM_1,VK_OEM_6,
+   VK_Z,VK_X,VK_C,VK_V,VK_B,VK_N,VK_M,VK_OEM_COMMA,VK_OEM_PERIOD,VK_OEM_2,
+   VK_OEM_102 /* the 102nd key (actually to the right of l-shift) */
+};
+
 static const WORD main_key_vkey_abnt_qwerty[MAIN_LEN] =
 {
 /* NOTE: this layout must concur with the scan codes layout above */
@@ -807,8 +833,8 @@
  {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 (specific)", &main_key_HR_jelly, &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},
- {0xe0010411, "Japanese pc98x1 keyboard layout", &main_key_JA_pc98x1, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0411, "Japanese 106 keyboard layout", &main_key_JA_jp106, &main_key_scan_jp106, &main_key_vkey_jp106},
+ {0x0411, "Japanese pc98x1 keyboard layout", &main_key_JA_pc98x1, &main_key_scan_jp106, &main_key_vkey_jp106},
  {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},
  {0x0405, "Czech keyboard layout", &main_key_CS, &main_key_scan_qwerty, &main_key_vkey_qwerty},
@@ -1077,6 +1103,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 +1239,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);
@@ -1113,16 +1261,7 @@
         return;
     }
 
-    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;
-    }
+    TRACE_(key)("state = %X\n", event->state);
 
     /* 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
@@ -1569,7 +1708,7 @@
      */
     langid = PRIMARYLANGID(LANGIDFROMLCID(layout));
     if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN)
-        layout = 0xe001 << 16; /* FIXME */
+        layout |= 0xe001 << 16; /* FIXME */
 
     return (HKL)layout;
 }
diff -urN wine-20040121/dlls/x11drv/window.c wine-20040121-xim-jp106/dlls/x11drv/window.c
--- wine-20040121/dlls/x11drv/window.c	2004-01-21 11:22:26.000000000 +0900
+++ wine-20040121-xim-jp106/dlls/x11drv/window.c	2004-01-23 20:38:14.000000000 +0900
@@ -789,6 +789,16 @@
         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 */
     if ((win->dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
     {
@@ -799,12 +809,7 @@
 
     wine_tsx11_unlock();
 
-    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 );
-    }
+    if (is_top_level) X11DRV_set_wm_hints( display, win );
 
     return data->whole_window;
 }
@@ -837,8 +842,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;
 }
@@ -910,6 +917,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 );
@@ -920,11 +935,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-20040121/dlls/x11drv/x11drv.h wine-20040121-xim-jp106/dlls/x11drv/x11drv.h
--- wine-20040121/dlls/x11drv/x11drv.h	2004-01-21 11:22:26.000000000 +0900
+++ wine-20040121-xim-jp106/dlls/x11drv/x11drv.h	2004-01-23 20:38:14.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;
@@ -234,11 +237,6 @@
 extern void X11DRV_OpenGL_Init(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);
 
 /* exported dib functions for now */
diff -urN wine-20040121/dlls/x11drv/x11drv.spec wine-20040121-xim-jp106/dlls/x11drv/x11drv.spec
--- wine-20040121/dlls/x11drv/x11drv.spec	2004-01-21 11:22:26.000000000 +0900
+++ wine-20040121-xim-jp106/dlls/x11drv/x11drv.spec	2004-01-23 20:35:42.000000000 +0900
@@ -119,6 +119,3 @@
 # X11 locks
 @ cdecl -norelay wine_tsx11_lock()
 @ cdecl -norelay wine_tsx11_unlock()
-
-# XIM
-@ cdecl ForceXIMReset(long) X11DRV_ForceXIMReset
diff -urN wine-20040121/dlls/x11drv/x11drv_main.c wine-20040121-xim-jp106/dlls/x11drv/x11drv_main.c
--- wine-20040121/dlls/x11drv/x11drv_main.c	2004-01-21 11:22:26.000000000 +0900
+++ wine-20040121-xim-jp106/dlls/x11drv/x11drv_main.c	2004-01-23 20:38:14.000000000 +0900
@@ -61,10 +61,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 =
@@ -104,14 +106,15 @@
 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];
 
 #define IS_OPTION_TRUE(ch) \
     ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
 #define IS_OPTION_FALSE(ch) \
     ((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
 
+XIMStyle ximStyle = 0;
+XFontSet ximFontSet;
+
 /***********************************************************************
  *		ignore_error
  *
@@ -310,15 +313,177 @@
     if (!get_config_key( hkey, appkey, "DesktopDoubleBuffered", buffer, sizeof(buffer) ))
         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 );
     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
@@ -414,6 +579,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();
@@ -467,9 +633,16 @@
         MESSAGE( "x11drv: Can't open display: %s\n", XDisplayName(NULL) );
         ExitProcess(1);
     }
-
     fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
 
+    if ((data->xim = XOpenIM( data->display, NULL, NULL, NULL )))
+    {
+        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
     if (use_xkb)
     {
@@ -480,10 +653,6 @@
 
     if (synchronous) XSynchronize( data->display, True );
     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,
                                   FALSE, &data->display_fd ))
     {
@@ -494,6 +663,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;
@@ -554,3 +725,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-20040121/dlls/x11drv/xim.h wine-20040121-xim-jp106/dlls/x11drv/xim.h
--- wine-20040121/dlls/x11drv/xim.h	1970-01-01 09:00:00.000000000 +0900
+++ wine-20040121-xim-jp106/dlls/x11drv/xim.h	2004-01-23 20:38:14.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) */
